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