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