1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """The spin viewer frame."""
24
25
26 import wx
27
28
29 from generic_fns.pipes import cdp_name, pipe_names
30 from graphics import WIZARD_IMAGE_PATH, fetch_icon
31 from status import Status; status = Status()
32 from relax_errors import RelaxNoPipeError
33
34
35 from gui.icons import relax_icons
36 from gui.misc import gui_raise
37 from gui.spin_viewer.splitter import Tree_splitter
38 from gui.string_conv import gui_to_str, str_to_gui
39 from gui.wizard import Wiz_page, Wiz_window
40 from gui.uf_objects import build_uf_menus, Uf_storage; uf_store = Uf_storage()
41
42
44 """A window element for the tree view."""
45
47 """Set up the relax prompt."""
48
49
50 self.gui = kwds.pop('parent')
51
52
53 kwds["style"] = wx.DEFAULT_FRAME_STYLE
54 if not status.debug and status.wx_info["os"] != 'darwin':
55 kwds["style"] = kwds["style"] | wx.MAXIMIZE
56 wx.Frame.__init__(self, *args, **kwds)
57
58
59 if not status.debug and status.wx_info["os"] != 'darwin':
60 self.Maximize()
61
62
63 self.SetIcons(relax_icons)
64
65
66 self.size_x = 1000
67 self.size_y = 750
68
69
70 sizer = self.setup_window()
71
72
73 self._create_menu()
74
75
76 self.toolbar()
77
78
79 splitter = Tree_splitter(self.gui, self, -1)
80 sizer.Add(splitter, 1, wx.EXPAND|wx.ALL, 0)
81
82
83 self.name = 'spin viewer'
84
85
87 """Activate or deactivate certain elements in response to the execution lock."""
88
89
90 enable = False
91 if not status.exec_lock.locked():
92 enable = True
93
94
95 for menu, label in self.menubar.GetMenus():
96
97 for item in menu.GetMenuItems():
98 wx.CallAfter(item.Enable, enable)
99
100
101 wx.CallAfter(self.bar.EnableTool, self.spin_loader_id, enable)
102
103
104 wx.CallAfter(self.pipe_name.Enable, enable)
105
106
108 """Build a menu for the window."""
109
110
111 self.menubar = wx.MenuBar()
112 if status.show_gui:
113 self.SetMenuBar(self.menubar)
114
115
116 self.menu_uf_ids = build_uf_menus(parent=self, menubar=self.menubar)
117
118
119 - def Show(self, show=True):
140
141
143 """Event handler for the refresh action (thread safe).
144
145 @keyword event: The wx event.
146 @type event: wx event
147 """
148
149
150 wx.CallAfter(self.refresh_safe)
151
152
154 """Refresh the spin viewer window."""
155
156
157 wx.BeginBusyCursor()
158
159
160 self.update_pipes()
161
162
163 self.tree_panel.update()
164
165
166 self.container.display(self.tree_panel.get_info())
167
168
169 if wx.IsBusy():
170 wx.EndBusyCursor()
171
172
174 """Event handler for the close window action.
175
176 @keyword event: The wx event.
177 @type event: wx event
178 """
179
180
181 status.observers.gui_uf.unregister(self.name)
182 status.observers.pipe_alteration.unregister(self.name)
183 status.observers.exec_lock.unregister(self.name)
184
185
186 self.Hide()
187
188
190 """The spin loading wizard.
191
192 @keyword event: The wx event.
193 @type event: wx event
194 """
195
196
197 if not cdp_name():
198 gui_raise(RelaxNoPipeError())
199 return
200
201
202 wx.BeginBusyCursor()
203
204
205 self.wizard = Wiz_window(parent=self, size_x=1000, size_y=800, title="Load spins")
206 self.page_indices = {}
207
208
209 self.page_method = Load_method_page(self.wizard)
210 self.page_indices['method'] = self.wizard.add_page(self.page_method, apply_button=True, skip_button=False)
211 self.wizard.set_seq_next_fn(self.page_indices['method'], self.wizard_page_after_load_method)
212
213
214 page = uf_store['sequence.read'].create_page(self.wizard)
215 self.page_indices['sequence.read'] = self.wizard.add_page(page, skip_button=True)
216 self.wizard.set_seq_next_fn(self.page_indices['sequence.read'], self.wizard_page_after_sequence_read)
217
218
219 page = uf_store['structure.read_pdb'].create_page(self.wizard)
220 self.page_indices['structure.read_pdb'] = self.wizard.add_page(page, skip_button=True)
221 self.wizard.set_seq_next_fn(self.page_indices['structure.read_pdb'], self.wizard_page_after_structure_read)
222
223
224 page = uf_store['structure.read_xyz'].create_page(self.wizard)
225 self.page_indices['structure.read_xyz'] = self.wizard.add_page(page, skip_button=True)
226 self.wizard.set_seq_next_fn(self.page_indices['structure.read_xyz'], self.wizard_page_after_structure_read)
227
228
229 page = uf_store['structure.load_spins'].create_page(self.wizard)
230 self.page_indices['structure.load_spins'] = self.wizard.add_page(page)
231
232
233 page = Finish_page(self.wizard)
234 self.page_indices['fin'] = self.wizard.add_page(page, apply_button=False, skip_button=False)
235
236
237 if wx.IsBusy():
238 wx.EndBusyCursor()
239
240
241 self.wizard.run()
242
243
245 """Set up the window.
246
247 @return: The sizer object.
248 @rtype: wx.Sizer instance
249 """
250
251
252 self.SetTitle("The spin viewer")
253
254
255 sizer = wx.BoxSizer(wx.VERTICAL)
256 self.SetSizer(sizer)
257
258
259 self.Bind(wx.EVT_CLOSE, self.handler_close)
260
261
262 self.SetSize((self.size_x, self.size_y))
263
264
265 return sizer
266
267
303
304
306 """Catch the user function call to properly specify the parent window.
307
308 @keyword event: The wx event.
309 @type event: wx event
310 """
311
312
313 uf_id = event.GetId()
314
315
316 name = uf_store.get_uf(uf_id)
317
318
319 uf_store[name](event=event, wx_parent=self)
320
321
369
370
372 """Set the page after the load method choice.
373
374 @return: The index of the next page.
375 @rtype: int
376 """
377
378
379 if self.page_method.selection == 'sequence':
380 return self.page_indices['sequence.read']
381
382
383 elif self.page_method.selection == 'new pdb':
384 return self.page_indices['structure.read_pdb']
385
386
387 elif self.page_method.selection == 'new xyz':
388 return self.page_indices['structure.read_xyz']
389
390
391 elif self.page_method.selection == 'preload':
392 return self.page_indices['structure.load_spins']
393
394
396 """Set the page after the sequence.read user function page.
397
398 @return: The index of the last page.
399 @rtype: int
400 """
401
402
403 return self.page_indices['fin']
404
405
407 """Set the page after the structure.read_* user function pages.
408
409 @return: The index of the structure.load_spins page.
410 @rtype: int
411 """
412
413
414 return self.page_indices['structure.load_spins']
415
416
417
418 -class Finish_page(Wiz_page):
419 """The terminating wizard page."""
420
421
422 image_path = WIZARD_IMAGE_PATH + 'spin.png'
423 main_text = 'The spin systems should now have been loaded into the relax data store.'
424 title = 'Spin loading complete'
425
426 - def add_contents(self, sizer):
427 """This blank method is needed so that the page shows and does nothing.
428
429 @param sizer: A sizer object.
430 @type sizer: wx.Sizer instance
431 """
432
433
434
435 -class Load_method_page(Wiz_page):
436 """The wizard page for specifying how to load spins."""
437
438
439 image_path = WIZARD_IMAGE_PATH + 'spin.png'
440 main_text = 'Select the method for loading spins into relax. Two options are possible: the first is to read sequence information out of a text file via the sequence.read user function; the second is to read in a 3D structure file via the structure.read_pdb user function and then to load the spins from this structure using the structure.load_spins user function.'
441 title = 'Spin loading'
442
443
444 - def add_contents(self, sizer):
445 """Add the specific GUI elements.
446
447 @param sizer: A sizer object.
448 @type sizer: wx.Sizer instance
449 """
450
451
452 msg = "Please specify by which method spins should be loaded into the relax data store:"
453 text = wx.StaticText(self, -1, msg)
454 text.Wrap(self._main_size)
455 sizer.Add(text, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 0)
456
457
458 sizer.AddStretchSpacer()
459
460
461 sizer2 = wx.BoxSizer(wx.HORIZONTAL)
462 sizer.Add(sizer2, 1, wx.ALL|wx.EXPAND, 0)
463
464
465 sizer.AddStretchSpacer()
466
467
468 sizer2.AddStretchSpacer()
469
470
471 sizer_radio = wx.BoxSizer(wx.VERTICAL)
472 sizer2.Add(sizer_radio, 1, wx.ALL|wx.EXPAND, 0)
473
474
475 self.preload_flag = False
476 if hasattr(cdp, 'structure') and not cdp.structure.empty():
477 self.preload_flag = True
478
479
480 if self.preload_flag:
481
482 self.radio_preload = wx.RadioButton(self, -1, "From a pre-loaded structure.", style=wx.RB_GROUP)
483 sizer_radio.Add(self.radio_preload, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 0)
484
485
486 sizer_radio.AddSpacer(20)
487
488
489 if self.preload_flag:
490 style = 0
491 else:
492 style = wx.RB_GROUP
493 self.radio_seq = wx.RadioButton(self, -1, "From a file containing sequence data.", style=style)
494 sizer_radio.Add(self.radio_seq, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 0)
495
496
497 sizer_radio.AddSpacer(20)
498
499
500 self.radio_new_pdb = wx.RadioButton(self, -1, "From a new PDB structure file.")
501 sizer_radio.Add(self.radio_new_pdb, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 0)
502
503
504 sizer_radio.AddSpacer(20)
505
506
507 self.radio_new_xyz = wx.RadioButton(self, -1, "From a new XYZ structure file.")
508 sizer_radio.Add(self.radio_new_xyz, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 0)
509
510
511 self.Bind(wx.EVT_RADIOBUTTON, self._on_select, self.radio_seq)
512 self.Bind(wx.EVT_RADIOBUTTON, self._on_select, self.radio_new_pdb)
513 self.Bind(wx.EVT_RADIOBUTTON, self._on_select, self.radio_new_xyz)
514 if self.preload_flag:
515 self.Bind(wx.EVT_RADIOBUTTON, self._on_select, self.radio_preload)
516
517
518 sizer2.AddStretchSpacer(3)
519
520
521 sizer.AddStretchSpacer()
522
523
524 if self.preload_flag:
525 self.selection = 'preload'
526 else:
527 self.selection = 'sequence'
528
529
530 - def _on_select(self, event=None):
531 """Handle the radio button switching.
532
533 @keyword event: The wx event.
534 @type event: wx event
535 """
536
537
538 button = event.GetEventObject()
539
540
541 if button == self.radio_seq:
542 self.selection = 'sequence'
543 elif button == self.radio_new_pdb:
544 self.selection = 'new pdb'
545 elif button == self.radio_new_xyz:
546 self.selection = 'new xyz'
547 elif self.preload_flag and button == self.radio_preload:
548 self.selection = 'preload'
549