1 | #GSASII - phase data display routines |
---|
2 | import wx |
---|
3 | import wx.grid as wg |
---|
4 | import matplotlib as mpl |
---|
5 | import math |
---|
6 | import time |
---|
7 | import cPickle |
---|
8 | import GSASIIpath |
---|
9 | import GSASIIlattice as G2lat |
---|
10 | import GSASIIspc as G2spc |
---|
11 | import GSASIIElem as G2elem |
---|
12 | import GSASIIplot as G2plt |
---|
13 | import GSASIIgrid as G2gd |
---|
14 | |
---|
15 | # trig functions in degrees |
---|
16 | sind = lambda x: math.sin(x*math.pi/180.) |
---|
17 | tand = lambda x: math.tan(x*math.pi/180.) |
---|
18 | cosd = lambda x: math.cos(x*math.pi/180.) |
---|
19 | asind = lambda x: 180.*math.asin(x)/math.pi |
---|
20 | |
---|
21 | def UpdatePhaseData(self,item,data,oldPage): |
---|
22 | Atoms = [] |
---|
23 | self.SelectedRow = 0 |
---|
24 | |
---|
25 | def BookResize(event): |
---|
26 | w,h = self.GetSize() |
---|
27 | self.dataDisplay.SetSize(wx.Size(w,h)) |
---|
28 | |
---|
29 | def FillGeneralGrid(): |
---|
30 | def SetLatticeParametersStyle(SGData,table): |
---|
31 | if SGData['SGLaue'] in ['m3','m3m']: |
---|
32 | table[4][2] = table[4][3] = table[4][1] |
---|
33 | General.SetCellStyle(4,2,"light grey",True) |
---|
34 | General.SetCellStyle(4,3,"light grey",True) |
---|
35 | table[4][4] = table[4][5] = table[4][6] = 90. |
---|
36 | General.SetCellStyle(4,4,"light grey",True) |
---|
37 | General.SetCellStyle(4,5,"light grey",True) |
---|
38 | General.SetCellStyle(4,6,"light grey",True) |
---|
39 | elif SGData['SGLaue'] in ['3R','3mR']: |
---|
40 | table[4][2] = table[4][3] = table[4][1] |
---|
41 | General.SetCellStyle(4,2,"light grey",True) |
---|
42 | General.SetCellStyle(4,3,"light grey",True) |
---|
43 | table[4][5] = table[4][6] = table[4][4] |
---|
44 | General.SetCellStyle(4,5,"light grey",True) |
---|
45 | General.SetCellStyle(4,6,"light grey",True) |
---|
46 | elif SGData['SGLaue'] in ['3','3m1','31m','6/m','6/mmm']: |
---|
47 | table[4][2] = table[4][1] |
---|
48 | General.SetCellStyle(4,2,"light grey",True) |
---|
49 | table[4][4] = table[4][5] = 90. |
---|
50 | table[4][6] = 120. |
---|
51 | General.SetCellStyle(4,4,"light grey",True) |
---|
52 | General.SetCellStyle(4,5,"light grey",True) |
---|
53 | General.SetCellStyle(4,6,"light grey",True) |
---|
54 | elif SGData['SGLaue'] in ['4/m','4/mmm']: |
---|
55 | table[4][2] = table[4][1] |
---|
56 | General.SetCellStyle(4,2,"light grey",True) |
---|
57 | table[4][4] = table[4][5] = table[4][6] = 90. |
---|
58 | General.SetCellStyle(4,4,"light grey",True) |
---|
59 | General.SetCellStyle(4,5,"light grey",True) |
---|
60 | General.SetCellStyle(4,6,"light grey",True) |
---|
61 | elif SGData['SGLaue'] in ['mmm']: |
---|
62 | table[4][4] = table[4][5] = table[4][6] = 90. |
---|
63 | General.SetCellStyle(4,4,"light grey",True) |
---|
64 | General.SetCellStyle(4,5,"light grey",True) |
---|
65 | General.SetCellStyle(4,6,"light grey",True) |
---|
66 | elif SGData['SGLaue'] in ['2/m']: |
---|
67 | if SGData['SGUniq'] == 'a': |
---|
68 | table[4][5]= table[4][6] = 90. |
---|
69 | General.SetCellStyle(4,5,"light grey",True) |
---|
70 | General.SetCellStyle(4,6,"light grey",True) |
---|
71 | if SGData['SGUniq'] == 'b': |
---|
72 | table[4][4]= table[4][6] = 90. |
---|
73 | General.SetCellStyle(4,4,"light grey",True) |
---|
74 | General.SetCellStyle(4,6,"light grey",True) |
---|
75 | if SGData['SGUniq'] == 'c': |
---|
76 | table[4][4]= table[4][5] = 90. |
---|
77 | General.SetCellStyle(4,4,"light grey",True) |
---|
78 | General.SetCellStyle(4,5,"light grey",True) |
---|
79 | |
---|
80 | def RefreshGeneralGrid(event): |
---|
81 | |
---|
82 | r,c = event.GetRow(),event.GetCol() |
---|
83 | generalData[0] = table[0][0] |
---|
84 | self.PatternTree.SetItemText(item,generalData[0]) |
---|
85 | generalData[1] = table[1][0] |
---|
86 | SpcGp = table[2][0] |
---|
87 | SGErr,SGData = G2spc.SpcGroup(SpcGp) |
---|
88 | if r == 2 and c == 0: |
---|
89 | if SGErr: |
---|
90 | text = [G2spc.SGErrors(SGErr)+'\nSpace Group set to previous'] |
---|
91 | table[2][0] = generalData[2]['SpGrp'] |
---|
92 | msg = 'Space Group Error' |
---|
93 | Style = wx.ICON_EXCLAMATION |
---|
94 | else: |
---|
95 | text = G2spc.SGPrint(SGData) |
---|
96 | generalData[2] = SGData |
---|
97 | msg = 'Space Group Information' |
---|
98 | Style = wx.ICON_INFORMATION |
---|
99 | Text = '' |
---|
100 | for line in text: |
---|
101 | Text += line+'\n' |
---|
102 | wx.MessageBox(Text,caption=msg,style=Style) |
---|
103 | General.SetCellValue(4,0,str(generalData[3][0])) |
---|
104 | for c in range(1,7): |
---|
105 | General.SetCellStyle(4,c,"white",False) |
---|
106 | generalData[3][c] = float(General.GetCellValue(4,c)) |
---|
107 | generalData[3][7] = G2lat.calc_V(G2lat.cell2A(generalData[3][1:7])) |
---|
108 | SetLatticeParametersStyle(SGData,table) |
---|
109 | generalData[4][1] = float(General.GetCellValue(5,1)) |
---|
110 | General.ForceRefresh() |
---|
111 | |
---|
112 | rowLabels = ['Phase name','Phase type','Space group', |
---|
113 | 'Lattice ',' parameters','Scale factor','Elements','No. per cell','Atom weight','','Bond radii','Angle radii'] |
---|
114 | generalData = data['General'] |
---|
115 | atomData = data['Atoms'] |
---|
116 | AtomTypes = [] |
---|
117 | NoAtoms = {} |
---|
118 | BondRadii = [] |
---|
119 | AngleRadii = [] |
---|
120 | AtomMass = [] |
---|
121 | colType = 1 |
---|
122 | colSS = 7 |
---|
123 | self.dataFrame.setSizePosLeft([600,350]) |
---|
124 | if generalData[1] =='macromolecular': |
---|
125 | colType = 4 |
---|
126 | colSS = 10 |
---|
127 | for atom in atomData: |
---|
128 | if AtomTypes.count(atom[colType]): |
---|
129 | NoAtoms[atom[colType]] += atom[colSS-1]*atom[colSS+1] |
---|
130 | else: |
---|
131 | Info = G2elem.GetAtomInfo(atom[colType]) |
---|
132 | AtomTypes.append(Info['Symbol']) |
---|
133 | BondRadii.append(Info['Drad']) |
---|
134 | AngleRadii.append(Info['Arad']) |
---|
135 | AtomMass.append(Info['Mass']) |
---|
136 | NoAtoms[atom[colType]] = atom[colSS-1]*atom[colSS+1] |
---|
137 | generalData[5:9] = [AtomTypes,NoAtoms,AtomMass,BondRadii,AngleRadii] |
---|
138 | colLabels = [] |
---|
139 | colLabels += ['' for i in range(max(8,len(generalData[5])))] |
---|
140 | table = [] |
---|
141 | table.append([generalData[0],'','','','','','','','']) #phase name |
---|
142 | table.append([generalData[1],'','','','','','','','']) #phase type |
---|
143 | E,SGData = G2spc.SpcGroup(generalData[2]['SpGrp']) |
---|
144 | table.append([SGData['SpGrp'],'','','','','','','','']) #space group symbol |
---|
145 | table.append(['refine','a ','b ','c ','alpha ','beta ','gamma','volume ']) |
---|
146 | table.append(generalData[3]) #lattice parameters |
---|
147 | table.append([generalData[4][0],generalData[4][1],'','','','','','']) #scale factor |
---|
148 | table.append(generalData[5]+['' for i in range(max(8,len(generalData[5])))]) #element list |
---|
149 | line = [] |
---|
150 | mass = 0. |
---|
151 | for i,elem in enumerate(generalData[5]): |
---|
152 | mass += generalData[6][elem]*generalData[7][i] |
---|
153 | line.append(generalData[6][elem]) |
---|
154 | Volume = generalData[3][7] |
---|
155 | table.append(line+['' for i in range(max(8,len(generalData[5])))]) #No. per cell |
---|
156 | table.append(generalData[7]+['' for i in range(max(8,len(generalData[5])))]) #At. wt. |
---|
157 | if generalData[1] == 'macromolecular' and mass > 0.0: |
---|
158 | table.append(['density',mass/(0.6022137*Volume),'Matthews coeff.',Volume/mass,'','','','','']) |
---|
159 | else: |
---|
160 | table.append(['density',mass/(0.6022137*Volume),'','','','','','','']) |
---|
161 | table.append(generalData[8]+['' for i in range(max(8,len(generalData[5])))]) |
---|
162 | table.append(generalData[9]+['' for i in range(max(8,len(generalData[5])))]) |
---|
163 | Types = [wg.GRID_VALUE_STRING for i in range(max(8,len(generalData[5])))] |
---|
164 | generalTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types) |
---|
165 | General.SetTable(generalTable, True) |
---|
166 | General.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshGeneralGrid) |
---|
167 | General.SetMargins(0,0) |
---|
168 | General.SetColSize(0,100) |
---|
169 | General.SetColLabelSize(0) |
---|
170 | for c in range(max(8,len(generalData[5]))): |
---|
171 | if c > 0: |
---|
172 | General.SetReadOnly(0,c,isReadOnly=True) |
---|
173 | General.SetReadOnly(1,c,isReadOnly=True) |
---|
174 | General.SetReadOnly(2,c,isReadOnly=True) |
---|
175 | General.SetReadOnly(3,c,isReadOnly=True) #unit cell labels |
---|
176 | General.SetCellAlignment(3,c,wx.ALIGN_RIGHT, wx.ALIGN_CENTRE) |
---|
177 | if c < 4: |
---|
178 | General.SetCellRenderer(4,c,wg.GridCellFloatRenderer(10,5)) |
---|
179 | General.SetCellEditor(4,c,wg.GridCellFloatEditor(10,5)) |
---|
180 | General.SetReadOnly(9,c,isReadOnly=True) |
---|
181 | else: |
---|
182 | General.SetCellRenderer(4,c,wg.GridCellFloatRenderer(10,3)) |
---|
183 | General.SetCellEditor(4,c,wg.GridCellFloatEditor(10,3)) |
---|
184 | for r in range(6,12): |
---|
185 | General.SetReadOnly(r,c,isReadOnly=True) |
---|
186 | General.SetReadOnly(4,7,isReadOnly=True) #cell volume - no edit |
---|
187 | General.SetCellEditor(1,0,wg.GridCellChoiceEditor(['nuclear','modulated', #phase type |
---|
188 | 'magnetic','macromolecular','Pawley'],False)) #- change only if no atoms |
---|
189 | if line: #no.of atoms not zero! |
---|
190 | General.SetReadOnly(1,0,isReadOnly=True) #can't change phase type |
---|
191 | General.SetCellRenderer(4,0,wg.GridCellBoolRenderer()) #lattice parameters |
---|
192 | General.SetCellEditor(4,0,wg.GridCellBoolEditor()) |
---|
193 | SetLatticeParametersStyle(SGData,table) |
---|
194 | General.SetCellRenderer(5,1,wg.GridCellFloatRenderer(10,4)) #scale factor |
---|
195 | General.SetCellEditor(5,1,wg.GridCellFloatEditor(10,4)) |
---|
196 | General.SetCellRenderer(5,0,wg.GridCellBoolRenderer()) |
---|
197 | General.SetCellEditor(5,0,wg.GridCellBoolEditor()) |
---|
198 | General.SetCellRenderer(9,1,wg.GridCellFloatRenderer(8,3)) |
---|
199 | General.SetCellRenderer(9,3,wg.GridCellFloatRenderer(8,3)) |
---|
200 | |
---|
201 | def FillAtomsGrid(): |
---|
202 | |
---|
203 | def RefreshAtomGrid(event): |
---|
204 | r,c = event.GetRow(),event.GetCol() |
---|
205 | if r < 0: #on col label! |
---|
206 | sel = -1 |
---|
207 | if Atoms.GetColLabelValue(c) == 'refine': |
---|
208 | choice = ['F - site fraction','X - coordinates','U - thermal parameters'] |
---|
209 | dlg = wx.MultiChoiceDialog(self,'Select','Refinement controls',choice) |
---|
210 | if dlg.ShowModal() == wx.ID_OK: |
---|
211 | sel = dlg.GetSelections() |
---|
212 | parms = '' |
---|
213 | for x in sel: |
---|
214 | parms += choice[x][0] |
---|
215 | elif Atoms.GetColLabelValue(c) == 'I/A': |
---|
216 | choice = ['Isotropic','Anisotropic'] |
---|
217 | dlg = wx.SingleChoiceDialog(self,'Select','Thermal Motion',choice) |
---|
218 | if dlg.ShowModal() == wx.ID_OK: |
---|
219 | sel = dlg.GetSelection() |
---|
220 | parms = choice[sel][0] |
---|
221 | if sel >= 0: |
---|
222 | for r in range(Atoms.GetNumberRows()): |
---|
223 | Atoms.SetCellValue(r,c,parms) |
---|
224 | elif c < 0: #picked atom row |
---|
225 | self.SelectedRow = r |
---|
226 | elif Atoms.GetColLabelValue(c) in ['x','y','z']: |
---|
227 | colLabel = Atoms.GetColLabelValue(c) |
---|
228 | if colLabel == 'x': |
---|
229 | XYZ = [atomData[r][c],atomData[r][c+1],atomData[r][c+2]] |
---|
230 | elif colLabel == 'y': |
---|
231 | XYZ = [atomData[r][c-1],atomData[r][c],atomData[r][c+1]] |
---|
232 | elif colLabel == 'z': |
---|
233 | XYZ = [atomData[r][c-2],atomData[r][c-1],atomData[r][c]] |
---|
234 | if None in XYZ: |
---|
235 | XYZ = [0,0,0] |
---|
236 | SScol = colLabels.index('site sym') |
---|
237 | Mulcol = colLabels.index('mult') |
---|
238 | E,SGData = G2spc.SpcGroup(generalData[2]['SpGrp']) |
---|
239 | Sytsym,Mult = G2spc.SytSym(XYZ,SGData) |
---|
240 | atomData[r][SScol] = Sytsym |
---|
241 | atomData[r][Mulcol] = Mult |
---|
242 | Atoms.ForceRefresh() |
---|
243 | |
---|
244 | def AtomTypeSelect(event): |
---|
245 | r,c = event.GetRow(),event.GetCol() |
---|
246 | if Atoms.GetColLabelValue(c) == 'Type': |
---|
247 | PE = G2elem.PickElement(self) |
---|
248 | if PE.ShowModal() == wx.ID_OK: |
---|
249 | atomData[r][c] = PE.Elem.strip() |
---|
250 | PE.Destroy() |
---|
251 | Atoms.ForceRefresh() |
---|
252 | else: |
---|
253 | event.Skip() |
---|
254 | |
---|
255 | generalData = data['General'] |
---|
256 | atomData = data['Atoms'] |
---|
257 | Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,X,XU,U,F,FX,FXU,FU", |
---|
258 | wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5', |
---|
259 | wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_STRING,wg.GRID_VALUE_NUMBER,wg.GRID_VALUE_CHOICE+":I,A", |
---|
260 | wg.GRID_VALUE_FLOAT+':10,4', |
---|
261 | wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4', |
---|
262 | wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4'] |
---|
263 | colLabels = ['Name','Type','refine','x','y','z','frac','site sym','mult','I/A','Uiso','U11','U22','U33','U12','U13','U23'] |
---|
264 | if generalData[1] == 'magnetic': |
---|
265 | colLabels += ['Mx','My','Mz'] |
---|
266 | Types[2] = wg.GRID_VALUE_CHOICE+": ,X,XU,U,M,MX,MXU,MU,F,FX,FXU,FU,FM,FMX,FMU," |
---|
267 | Types += [ |
---|
268 | wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,4'] |
---|
269 | elif generalData[1] == 'macromolecular': |
---|
270 | colLabels = ['res no','residue','chain'] + colLabels |
---|
271 | Types = [wg.GRID_VALUE_NUMBER, |
---|
272 | wg.GRID_VALUE_CHOICE+": ,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LEU,LYS,MET,PHE,PRO,SER,THR,TRP,TYR,VAL,MSE,HOH,UNK", |
---|
273 | wg.GRID_VALUE_STRING] + Types |
---|
274 | table = [] |
---|
275 | rowLabels = [] |
---|
276 | for i,atom in enumerate(atomData): |
---|
277 | table.append(atom) |
---|
278 | rowLabels.append(str(i+1)) |
---|
279 | atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types) |
---|
280 | Atoms.SetTable(atomTable, True) |
---|
281 | Atoms.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshAtomGrid) |
---|
282 | Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid) |
---|
283 | Atoms.Bind(wg.EVT_GRID_SELECT_CELL, AtomTypeSelect) |
---|
284 | Atoms.SetMargins(0,0) |
---|
285 | Atoms.AutoSizeColumns(True) |
---|
286 | colType = colLabels.index('Type') |
---|
287 | colSS = colLabels.index('site sym') |
---|
288 | colIA = colLabels.index('I/A') |
---|
289 | for row in range(Atoms.GetNumberRows()): |
---|
290 | Atoms.SetReadOnly(row,colSS,True) #site sym |
---|
291 | Atoms.SetReadOnly(row,colSS+1,True) #Mult |
---|
292 | if Atoms.GetCellValue(row,colIA) == 'I': |
---|
293 | for i in range(2,8): |
---|
294 | Atoms.SetCellRenderer(row,colIA+i,wg.GridCellStringRenderer()) |
---|
295 | Atoms.SetReadOnly(row,colIA+i,isReadOnly=True) |
---|
296 | Atoms.SetCellValue(row,colIA+i,'') |
---|
297 | elif Atoms.GetCellValue(row,colIA) == 'A': |
---|
298 | Atoms.SetCellRenderer(row,colIA+1,wg.GridCellStringRenderer()) |
---|
299 | Atoms.SetReadOnly(row,colIA+1,isReadOnly=True) |
---|
300 | Atoms.SetCellValue(row,colIA+1,'') |
---|
301 | |
---|
302 | def AtomAdd(event): |
---|
303 | atomData = data['Atoms'] |
---|
304 | generalData = data['General'] |
---|
305 | Ncol = Atoms.GetNumberCols() |
---|
306 | if generalData[1] == 'macromolecular': |
---|
307 | atomData.append([0,'UNK','','UNK','UNK','',0,0,0,0,'',0,'I',0.10,0,0,0,0,0,0]) |
---|
308 | elif generalData[1] == 'nuclear': |
---|
309 | atomData.append(['UNK','UNK','',0,0,0,0,'',0,'I',0.01,0,0,0,0,0,0]) |
---|
310 | event.StopPropagation() |
---|
311 | FillAtomsGrid() |
---|
312 | |
---|
313 | def AtomInsert(event): |
---|
314 | atomData = data['Atoms'] |
---|
315 | generalData = data['General'] |
---|
316 | Ncol = Atoms.GetNumberCols() |
---|
317 | if generalData[1][0] == 'macromolecular': |
---|
318 | atomData.append([0,'UNK','','UNK','UNK','',0,0,0,0,'',0,'I',0.10,0,0,0,0,0,0]) |
---|
319 | elif generalData[1][0] == 'nuclear': |
---|
320 | atomData.append(['UNK','UNK','',0,0,0,0,'',0,'I',0.01,0,0,0,0,0,0]) |
---|
321 | event.StopPropagation() |
---|
322 | FillAtomsGrid() |
---|
323 | |
---|
324 | def UpdateDrawing(): |
---|
325 | print 'Drawing' |
---|
326 | |
---|
327 | def FillPawleyReflectionsGrid(): |
---|
328 | |
---|
329 | print 'Pawley reflections' |
---|
330 | |
---|
331 | def OnPageChanged(event): |
---|
332 | page = event.GetSelection() |
---|
333 | text = self.dataDisplay.GetPageText(page) |
---|
334 | if text == 'Atoms': |
---|
335 | self.dataFrame.SetMenuBar(self.dataFrame.AtomsMenu) |
---|
336 | self.dataFrame.Bind(wx.EVT_MENU, AtomAdd, id=G2gd.wxID_ATOMSEDITADD) |
---|
337 | self.dataFrame.Bind(wx.EVT_MENU, AtomInsert, id=G2gd.wxID_ATOMSEDITINSERT) |
---|
338 | FillAtomsGrid() |
---|
339 | else: |
---|
340 | self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu) |
---|
341 | event.Skip() |
---|
342 | |
---|
343 | if self.dataDisplay: |
---|
344 | self.dataDisplay.Destroy() |
---|
345 | PhaseName = self.PatternTree.GetItemText(item) |
---|
346 | self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu) |
---|
347 | self.dataFrame.SetLabel('Phase Data for '+PhaseName) |
---|
348 | self.dataDisplay = G2gd.GSNoteBook(parent=self.dataFrame,size=self.dataFrame.GetClientSize()) |
---|
349 | |
---|
350 | General = G2gd.GSGrid(parent=self.dataDisplay) |
---|
351 | FillGeneralGrid() |
---|
352 | self.dataDisplay.AddPage(General,'General') |
---|
353 | |
---|
354 | GeneralData = data['General'] |
---|
355 | if GeneralData[3] == 'Pawley': |
---|
356 | PawleyRefl = G2gd.GSGrid(parent=self.dataDisplay) |
---|
357 | self.dataDisplay.AddPage(PawleyRefl,'Pawley reflections') |
---|
358 | FillPawleyReflectionsGrid() |
---|
359 | else: |
---|
360 | Atoms = G2gd.GSGrid(parent=self.dataDisplay) |
---|
361 | FillAtomsGrid() |
---|
362 | self.dataDisplay.AddPage(Atoms,'Atoms') |
---|
363 | |
---|
364 | Drawing = wx.Window(parent=self.dataDisplay) |
---|
365 | self.dataDisplay.AddPage(Drawing,'Drawing') |
---|
366 | |
---|
367 | self.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged) |
---|
368 | self.dataDisplay.SetSelection(oldPage) |
---|
369 | |
---|