1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """The molecule, residue, and spin tree view GUI elements."""
24
25
26
27 import wx
28
29
30 import dep_check
31 from graphics import fetch_icon
32 from gui.components.menu import build_menu_item
33 from gui.message import Question
34 from gui.string_conv import gui_to_str
35 from gui.uf_objects import Uf_storage; uf_store = Uf_storage()
36 from pipe_control.mol_res_spin import get_molecule_ids, molecule_loop, residue_loop, return_molecule, return_residue, return_spin, spin_loop
37 from pipe_control.pipes import cdp_name, get_pipe
38 from pipe_control.selection import is_mol_selected, is_res_selected, is_spin_selected
39 from status import Status; status = Status()
40
41
42
43 MENU_MOLECULE_MOLECULE_COPY = wx.NewId()
44 MENU_MOLECULE_MOLECULE_DELETE = wx.NewId()
45 MENU_MOLECULE_MOLECULE_DESELECT = wx.NewId()
46 MENU_MOLECULE_MOLECULE_NAME = wx.NewId()
47 MENU_MOLECULE_MOLECULE_SELECT = wx.NewId()
48 MENU_MOLECULE_MOLECULE_TYPE = wx.NewId()
49 MENU_MOLECULE_RESIDUE_CREATE = wx.NewId()
50 MENU_RESIDUE_RESIDUE_COPY = wx.NewId()
51 MENU_RESIDUE_RESIDUE_DELETE = wx.NewId()
52 MENU_RESIDUE_RESIDUE_DESELECT = wx.NewId()
53 MENU_RESIDUE_RESIDUE_NAME = wx.NewId()
54 MENU_RESIDUE_RESIDUE_NUMBER = wx.NewId()
55 MENU_RESIDUE_RESIDUE_SELECT = wx.NewId()
56 MENU_RESIDUE_SPIN_ADD = wx.NewId()
57 MENU_RESIDUE_SPIN_CREATE_PSEUDO = wx.NewId()
58 MENU_ROOT_MOLECULE_CREATE = wx.NewId()
59 MENU_ROOT_LOAD_SPINS = wx.NewId()
60 MENU_SPIN_SPIN_COPY = wx.NewId()
61 MENU_SPIN_SPIN_DELETE = wx.NewId()
62 MENU_SPIN_SPIN_DESELECT = wx.NewId()
63 MENU_SPIN_SPIN_ELEMENT = wx.NewId()
64 MENU_SPIN_SPIN_NAME = wx.NewId()
65 MENU_SPIN_SPIN_NUMBER = wx.NewId()
66 MENU_SPIN_SPIN_SELECT = wx.NewId()
67
68
70 """The tree view class."""
71
72 - def __init__(self, gui, parent=None, id=None):
73 """Set up the tree GUI element.
74
75 @param gui: The gui object.
76 @type gui: wx object
77 @keyword parent: The parent GUI element that this is to be attached to.
78 @type parent: wx object
79 @keyword id: The ID number.
80 @type id: int
81 """
82
83
84 self.gui = gui
85 self.parent = parent
86
87
88 wx.Window.__init__(self, parent, id, style=wx.WANTS_CHARS)
89
90
91 self.icon_size = 22
92
93
94 self.tree = wx.TreeCtrl(parent=self, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TR_DEFAULT_STYLE)
95
96
97 self.tree_ids = {}
98
99
100 self.Bind(wx.EVT_SIZE, self._resize)
101
102
103 self.root = self.tree.AddRoot("Spin system information")
104 if dep_check.wx_classic:
105 self.tree.SetPyData(self.root, "root")
106 else:
107 self.tree.SetItemData(self.root, "root")
108
109
110 icon_list = wx.ImageList(self.icon_size, self.icon_size)
111
112
113 self.icon_mol_index = icon_list.Add(wx.Bitmap(fetch_icon("relax.molecule", "22x22"), wx.BITMAP_TYPE_ANY))
114 self.icon_mol_unfold_index = icon_list.Add(wx.Bitmap(fetch_icon("relax.molecule_unfolded", "22x22"), wx.BITMAP_TYPE_ANY))
115 self.icon_res_index = icon_list.Add(wx.Bitmap(fetch_icon("relax.residue", "22x22"), wx.BITMAP_TYPE_ANY))
116 self.icon_spin_index = icon_list.Add(wx.Bitmap(fetch_icon("relax.spin", "22x22"), wx.BITMAP_TYPE_ANY))
117
118
119 self.icon_mol_index_desel = icon_list.Add(wx.Bitmap(fetch_icon("relax.molecule_grey", "22x22"), wx.BITMAP_TYPE_ANY))
120 self.icon_mol_unfold_index_desel = icon_list.Add(wx.Bitmap(fetch_icon("relax.molecule_unfolded_grey", "22x22"), wx.BITMAP_TYPE_ANY))
121 self.icon_res_index_desel = icon_list.Add(wx.Bitmap(fetch_icon("relax.residue_grey", "22x22"), wx.BITMAP_TYPE_ANY))
122 self.icon_spin_index_desel = icon_list.Add(wx.Bitmap(fetch_icon("relax.spin_grey", "22x22"), wx.BITMAP_TYPE_ANY))
123
124
125 self.tree.SetImageList(icon_list)
126
127
128 self.icon_list = icon_list
129
130
131 self.update()
132
133
134 self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self._selection)
135 self.tree.Bind(wx.EVT_RIGHT_DOWN, self._right_click)
136
137
139 """Resize the tree element.
140
141 @param event: The wx event.
142 @type event: wx event
143 """
144
145
146 width, height = self.GetClientSize()
147
148
149 if dep_check.wx_classic:
150 self.tree.SetDimensions(0, 0, width, height)
151 else:
152 self.tree.SetSize(0, 0, width, height)
153
154
156 """Handle right clicks in the tree.
157
158 @param event: The wx event.
159 @type event: wx event
160 """
161
162
163 pos = event.GetPosition()
164
165
166 item, flags = self.tree.HitTest(pos)
167
168
169 if not item.IsOk():
170 self.info = None
171 elif dep_check.wx_classic:
172 self.info = self.tree.GetItemPyData(item)
173 else:
174 self.info = self.tree.GetItemData(item)
175
176
177 if self.info == None:
178 self.menu_default()
179
180
181 elif self.info == 'root':
182 self.menu_root()
183
184
185 elif self.info['type'] == 'mol':
186 self.menu_molecule()
187
188
189 elif self.info['type'] == 'res':
190 self.menu_residue()
191
192
193 elif self.info['type'] == 'spin':
194 self.menu_spin()
195
196
215
216
218 """Wrapper method.
219
220 @param event: The wx event.
221 @type event: wx event
222 """
223
224
225 uf_store['molecule.copy'](wx_parent=self.gui.spin_viewer, pipe_from=cdp_name(), mol_from=self.info['id'], pipe_to=cdp_name())
226
227
229 """Wrapper method.
230
231 @param event: The wx event.
232 @type event: wx event
233 """
234
235
236 msg = "Are you sure you would like to delete this molecule? This only affects the spin data, all structural data will remain. This operation cannot be undone."
237 if status.show_gui and Question(msg, parent=self.gui.spin_viewer, default=False, size=(400, 170)).ShowModal() == wx.ID_NO:
238 return
239
240
241 self.gui.interpreter.queue('molecule.delete', gui_to_str(self.info['id']))
242
243
245 """Wrapper method.
246
247 @param event: The wx event.
248 @type event: wx event
249 """
250
251
252 msg = "Are you sure you would like to deselect all spins of this molecule?"
253 if status.show_gui and Question(msg, parent=self.gui.spin_viewer, default=False).ShowModal() == wx.ID_NO:
254 return
255
256
257 self.gui.interpreter.queue('deselect.spin', spin_id=gui_to_str(self.info['id']), change_all=False)
258
259
261 """Wrapper method.
262
263 @param event: The wx event.
264 @type event: wx event
265 """
266
267
268 uf_store['molecule.name'](wx_parent=self.gui.spin_viewer, mol_id=self.info['id'])
269
270
289
290
292 """Wrapper method.
293
294 @param event: The wx event.
295 @type event: wx event
296 """
297
298
299 msg = "Are you sure you would like to select all spins of this molecule?"
300 if status.show_gui and Question(msg, parent=self.gui.spin_viewer, default=False).ShowModal() == wx.ID_NO:
301 return
302
303
304 self.gui.interpreter.queue('select.spin', spin_id=gui_to_str(self.info['id']), change_all=False)
305
306
308 """Wrapper method.
309
310 @param event: The wx event.
311 @type event: wx event
312 """
313
314
315 uf_store['residue.create'](wx_parent=self.gui.spin_viewer, mol_name=self.info['mol_name'])
316
317
319 """Wrapper method.
320
321 @param event: The wx event.
322 @type event: wx event
323 """
324
325
326 uf_store['residue.copy'](wx_parent=self.gui.spin_viewer, pipe_from=cdp_name(), res_from=self.info['id'], pipe_to=cdp_name())
327
328
330 """Wrapper method.
331
332 @param event: The wx event.
333 @type event: wx event
334 """
335
336
337 msg = "Are you sure you would like to delete this residue? This only affects the spin data, all structural data will remain. This operation cannot be undone."
338 if status.show_gui and Question(msg, parent=self.gui.spin_viewer, default=False, size=(400, 170)).ShowModal() == wx.ID_NO:
339 return
340
341
342 self.gui.interpreter.queue('residue.delete', gui_to_str(self.info['id']))
343
344
346 """Wrapper method.
347
348 @param event: The wx event.
349 @type event: wx event
350 """
351
352
353 msg = "Are you sure you would like to deselect all spins of this residue?"
354 if status.show_gui and Question(msg, parent=self.gui.spin_viewer, default=False).ShowModal() == wx.ID_NO:
355 return
356
357
358 self.gui.interpreter.queue('deselect.spin', spin_id=gui_to_str(self.info['id']), change_all=False)
359
360
362 """Wrapper method.
363
364 @param event: The wx event.
365 @type event: wx event
366 """
367
368
369 uf_store['residue.name'](wx_parent=self.gui.spin_viewer, res_id=self.info['id'])
370
371
373 """Wrapper method.
374
375 @param event: The wx event.
376 @type event: wx event
377 """
378
379
380 uf_store['residue.number'](wx_parent=self.gui.spin_viewer, res_id=self.info['id'])
381
382
384 """Wrapper method.
385
386 @param event: The wx event.
387 @type event: wx event
388 """
389
390
391 msg = "Are you sure you would like to select all spins of this residue?"
392 if status.show_gui and Question(msg, parent=self.gui.spin_viewer, default=False).ShowModal() == wx.ID_NO:
393 return
394
395
396 self.gui.interpreter.queue('select.spin', spin_id=gui_to_str(self.info['id']), change_all=False)
397
398
400 """Wrapper method.
401
402 @param event: The wx event.
403 @type event: wx event
404 """
405
406
407 uf_store['spin.create'](wx_parent=self.gui.spin_viewer, mol_name=self.info['mol_name'], res_num=self.info['res_num'], res_name=self.info['res_name'])
408
409
411 """Wrapper method.
412
413 @param event: The wx event.
414 @type event: wx event
415 """
416
417
418 uf_store['spin.create_pseudo'](wx_parent=self.gui.spin_viewer, res_id=self.info['id'])
419
420
422 """Wrapper method.
423
424 @param event: The wx event.
425 @type event: wx event
426 """
427
428
429 uf_store['molecule.create'](wx_parent=self.gui.spin_viewer)
430
431
433 """Wrapper method.
434
435 @param event: The wx event.
436 @type event: wx event
437 """
438
439
440 uf_store['spin.copy'](wx_parent=self.gui.spin_viewer, pipe_from=cdp_name(), spin_from=self.info['id'], pipe_to=cdp_name())
441
442
444 """Wrapper method.
445
446 @param event: The wx event.
447 @type event: wx event
448 """
449
450
451 msg = "Are you sure you would like to delete this spin? This only affects the spin data, all structural data will remain. This operation cannot be undone."
452 if status.show_gui and Question(msg, parent=self.gui.spin_viewer, default=False, size=(400, 170)).ShowModal() == wx.ID_NO:
453 return
454
455
456 self.gui.interpreter.queue('spin.delete', gui_to_str(self.info['id']))
457
458
460 """Wrapper method.
461
462 @param event: The wx event.
463 @type event: wx event
464 """
465
466
467 self.gui.interpreter.queue('deselect.spin', spin_id=gui_to_str(self.info['id']), change_all=False)
468
469
485
486
488 """Wrapper method.
489
490 @param event: The wx event.
491 @type event: wx event
492 """
493
494
495 uf_store['spin.name'](wx_parent=self.gui.spin_viewer, spin_id=self.info['id'])
496
497
499 """Wrapper method.
500
501 @param event: The wx event.
502 @type event: wx event
503 """
504
505
506 uf_store['spin.number'](wx_parent=self.gui.spin_viewer, spin_id=self.info['id'])
507
508
510 """Wrapper method.
511
512 @param event: The wx event.
513 @type event: wx event
514 """
515
516
517 self.gui.interpreter.queue('select.spin', spin_id=gui_to_str(self.info['id']), change_all=False)
518
519
521 """Get the python data structure associated with the current item.
522
523 @return: The dictionary of data.
524 @rtype: dict
525 """
526
527
528 item = self.tree.GetSelection()
529
530
531 if not item.IsOk():
532 return
533
534
535 if dep_check.wx_classic:
536 return self.tree.GetItemPyData(item)
537 else:
538 return self.tree.GetItemData(item)
539
540
561
562
564 """The right click molecule menu."""
565
566
567 items = []
568
569
570 menu = wx.Menu()
571
572
573 items.append(build_menu_item(menu, id=MENU_MOLECULE_MOLECULE_COPY, text="&Copy the molecule", icon=fetch_icon("oxygen.actions.list-add")))
574 items.append(build_menu_item(menu, id=MENU_MOLECULE_MOLECULE_DELETE, text="De&lete the molecule", icon=fetch_icon("oxygen.actions.list-remove")))
575 items.append(build_menu_item(menu, id=MENU_MOLECULE_MOLECULE_NAME, text="&Name the molecule", icon=fetch_icon("oxygen.actions.edit-rename")))
576 items.append(build_menu_item(menu, id=MENU_MOLECULE_MOLECULE_TYPE, text="Set the molecule &type", icon=fetch_icon("oxygen.actions.edit-rename")))
577 items.append(build_menu_item(menu, id=MENU_MOLECULE_RESIDUE_CREATE, text="Add a &residue", icon=fetch_icon("oxygen.actions.list-add-relax-blue")))
578
579
580 for item in items:
581 if status.exec_lock.locked():
582 item.Enable(False)
583
584
585 menu.AppendSeparator()
586
587
588 if self.info['select']:
589 item = build_menu_item(menu, id=MENU_MOLECULE_MOLECULE_DESELECT, text="&Deselect", icon=fetch_icon("relax.molecule_grey"))
590 else:
591 item = build_menu_item(menu, id=MENU_MOLECULE_MOLECULE_SELECT, text="&Select", icon=fetch_icon("relax.molecule"))
592 if status.exec_lock.locked():
593 item.Enable(False)
594
595
596 self.Bind(wx.EVT_MENU, self.action_molecule_molecule_copy, id=MENU_MOLECULE_MOLECULE_COPY)
597 self.Bind(wx.EVT_MENU, self.action_molecule_molecule_delete, id=MENU_MOLECULE_MOLECULE_DELETE)
598 self.Bind(wx.EVT_MENU, self.action_molecule_molecule_name, id=MENU_MOLECULE_MOLECULE_NAME)
599 self.Bind(wx.EVT_MENU, self.action_molecule_molecule_type, id=MENU_MOLECULE_MOLECULE_TYPE)
600 self.Bind(wx.EVT_MENU, self.action_molecule_residue_create, id=MENU_MOLECULE_RESIDUE_CREATE)
601 if self.info['select']:
602 self.Bind(wx.EVT_MENU, self.action_molecule_molecule_deselect, id=MENU_MOLECULE_MOLECULE_DESELECT)
603 else:
604 self.Bind(wx.EVT_MENU, self.action_molecule_molecule_select, id=MENU_MOLECULE_MOLECULE_SELECT)
605
606
607 if status.show_gui:
608 self.PopupMenu(menu)
609
610
611 menu.Destroy()
612
613
615 """The right click molecule menu."""
616
617
618 items = []
619
620
621 menu = wx.Menu()
622
623
624 items.append(build_menu_item(menu, id=MENU_RESIDUE_RESIDUE_COPY, text="&Copy the residue", icon=fetch_icon("oxygen.actions.list-add")))
625 items.append(build_menu_item(menu, id=MENU_RESIDUE_RESIDUE_DELETE, text="De&lete the residue", icon=fetch_icon("oxygen.actions.list-remove")))
626 items.append(build_menu_item(menu, id=MENU_RESIDUE_RESIDUE_NAME, text="&Name the residue", icon=fetch_icon("oxygen.actions.edit-rename")))
627 items.append(build_menu_item(menu, id=MENU_RESIDUE_RESIDUE_NUMBER, text="N&umber the residue", icon=fetch_icon("oxygen.actions.edit-rename")))
628 items.append(build_menu_item(menu, id=MENU_RESIDUE_SPIN_ADD, text="&Add a spin", icon=fetch_icon("oxygen.actions.list-add-relax-blue")))
629 items.append(build_menu_item(menu, id=MENU_RESIDUE_SPIN_CREATE_PSEUDO, text="Create a &pseudo-atom", icon=fetch_icon("oxygen.actions.list-add-relax-blue")))
630
631
632 for item in items:
633 if status.exec_lock.locked():
634 item.Enable(False)
635
636
637 menu.AppendSeparator()
638
639
640 if self.info['select']:
641 item = build_menu_item(menu, id=MENU_RESIDUE_RESIDUE_DESELECT, text="&Deselect", icon=fetch_icon("relax.residue_grey"))
642 else:
643 item = build_menu_item(menu, id=MENU_RESIDUE_RESIDUE_SELECT, text="&Select", icon=fetch_icon("relax.residue"))
644 if status.exec_lock.locked():
645 item.Enable(False)
646
647
648 self.Bind(wx.EVT_MENU, self.action_residue_residue_copy, id=MENU_RESIDUE_RESIDUE_COPY)
649 self.Bind(wx.EVT_MENU, self.action_residue_residue_delete, id=MENU_RESIDUE_RESIDUE_DELETE)
650 self.Bind(wx.EVT_MENU, self.action_residue_residue_name, id=MENU_RESIDUE_RESIDUE_NAME)
651 self.Bind(wx.EVT_MENU, self.action_residue_residue_number, id=MENU_RESIDUE_RESIDUE_NUMBER)
652 self.Bind(wx.EVT_MENU, self.action_residue_spin_add, id=MENU_RESIDUE_SPIN_ADD)
653 self.Bind(wx.EVT_MENU, self.action_residue_spin_create_pseudo, id=MENU_RESIDUE_SPIN_CREATE_PSEUDO)
654 if self.info['select']:
655 self.Bind(wx.EVT_MENU, self.action_residue_residue_deselect, id=MENU_RESIDUE_RESIDUE_DESELECT)
656 else:
657 self.Bind(wx.EVT_MENU, self.action_residue_residue_select, id=MENU_RESIDUE_RESIDUE_SELECT)
658
659
660 if status.show_gui:
661 self.PopupMenu(menu)
662
663
664 menu.Destroy()
665
666
668 """The right click root menu."""
669
670
671 items = []
672
673
674 menu = wx.Menu()
675
676
677 items.append(build_menu_item(menu, id=MENU_ROOT_MOLECULE_CREATE, text="&Add a molecule", icon=fetch_icon("oxygen.actions.list-add-relax-blue")))
678 items.append(build_menu_item(menu, id=MENU_ROOT_LOAD_SPINS, text="&Load spins", icon=fetch_icon("relax.spin", "16x16")))
679
680
681 for item in items:
682 if status.exec_lock.locked():
683 item.Enable(False)
684
685
686 self.Bind(wx.EVT_MENU, self.action_root_molecule_create, id=MENU_ROOT_MOLECULE_CREATE)
687 self.Bind(wx.EVT_MENU, self.gui.spin_viewer.load_spins_wizard, id=MENU_ROOT_LOAD_SPINS)
688
689
690 if status.show_gui:
691 self.PopupMenu(menu)
692
693
694 menu.Destroy()
695
696
698 """The right click spin menu."""
699
700
701 items = []
702
703
704 menu = wx.Menu()
705
706
707 items.append(build_menu_item(menu, id=MENU_SPIN_SPIN_COPY, text="&Copy the spin", icon=fetch_icon("oxygen.actions.list-add")))
708 items.append(build_menu_item(menu, id=MENU_SPIN_SPIN_DELETE, text="De&lete the spin", icon=fetch_icon("oxygen.actions.list-remove")))
709 items.append(build_menu_item(menu, id=MENU_SPIN_SPIN_ELEMENT, text="Set the element &type of the spin", icon=fetch_icon("oxygen.actions.edit-rename")))
710 items.append(build_menu_item(menu, id=MENU_SPIN_SPIN_NAME, text="&Name the spin", icon=fetch_icon("oxygen.actions.edit-rename")))
711 items.append(build_menu_item(menu, id=MENU_SPIN_SPIN_NUMBER, text="N&umber the spin", icon=fetch_icon("oxygen.actions.edit-rename")))
712
713
714 for item in items:
715 if status.exec_lock.locked():
716 item.Enable(False)
717
718
719 menu.AppendSeparator()
720
721
722 if self.info['select']:
723 item = build_menu_item(menu, id=MENU_SPIN_SPIN_DESELECT, text="&Deselect", icon=fetch_icon("relax.spin_grey"))
724 else:
725 item = build_menu_item(menu, id=MENU_SPIN_SPIN_SELECT, text="&Select", icon=fetch_icon("relax.spin"))
726 if status.exec_lock.locked():
727 item.Enable(False)
728
729
730 self.Bind(wx.EVT_MENU, self.action_spin_spin_copy, id=MENU_SPIN_SPIN_COPY)
731 self.Bind(wx.EVT_MENU, self.action_spin_spin_delete, id=MENU_SPIN_SPIN_DELETE)
732 self.Bind(wx.EVT_MENU, self.action_spin_spin_element, id=MENU_SPIN_SPIN_ELEMENT)
733 self.Bind(wx.EVT_MENU, self.action_spin_spin_name, id=MENU_SPIN_SPIN_NAME)
734 self.Bind(wx.EVT_MENU, self.action_spin_spin_number, id=MENU_SPIN_SPIN_NUMBER)
735 if self.info['select']:
736 self.Bind(wx.EVT_MENU, self.action_spin_spin_deselect, id=MENU_SPIN_SPIN_DESELECT)
737 else:
738 self.Bind(wx.EVT_MENU, self.action_spin_spin_select, id=MENU_SPIN_SPIN_SELECT)
739
740
741 if status.show_gui:
742 self.PopupMenu(menu)
743
744
745 menu.Destroy()
746
747
749 """Remove any molecules which have been deleted."""
750
751
752 mol_ids = get_molecule_ids()
753
754
755 prune_list = []
756 for key in self.tree_ids:
757
758 if dep_check.wx_classic:
759 info = self.tree.GetItemPyData(key)
760 else:
761 info = self.tree.GetItemData(key)
762
763
764 if info == None or 'id' not in info:
765 continue
766
767
768 if info['id'] not in mol_ids:
769 prune_list.append(key)
770
771
772 for key in prune_list:
773 self.tree.Delete(key)
774 self.tree_ids.pop(key)
775
776
778 """Remove any molecules which have been deleted.
779
780 @param mol_branch_id: The molecule branch ID of the wx.TreeCtrl object.
781 @type mol_branch_id: TreeItemId
782 @param mol_id: The molecule identification string.
783 @type mol_id: str
784 """
785
786
787 prune_list = []
788 for key in self.tree_ids[mol_branch_id]:
789
790 if dep_check.wx_classic:
791 info = self.tree.GetItemPyData(key)
792 else:
793 info = self.tree.GetItemData(key)
794
795
796 if info == None or 'id' not in info:
797 continue
798
799
800 res = return_residue(info['id'])
801
802
803 if res == None or res.name != info['res_name'] or res.num != info['res_num']:
804 prune_list.append(key)
805
806
807 for key in prune_list:
808 self.tree.Delete(key)
809 self.tree_ids[mol_branch_id].pop(key)
810
811
812 - def prune_spin(self, mol_branch_id, res_branch_id, res_id):
813 """Remove any spins which have been deleted.
814
815 @param mol_branch_id: The molecule branch ID of the wx.TreeCtrl object.
816 @type mol_branch_id: TreeItemId
817 @param res_branch_id: The residue branch ID of the wx.TreeCtrl object.
818 @type res_branch_id: TreeItemId
819 @param res_id: The residue identification string.
820 @type res_id: str
821 """
822
823
824 prune_list = []
825 for key in self.tree_ids[mol_branch_id][res_branch_id]:
826
827 if dep_check.wx_classic:
828 info = self.tree.GetItemPyData(key)
829 else:
830 info = self.tree.GetItemData(key)
831
832
833 if info == None or 'id' not in info:
834 continue
835
836
837 spin = return_spin(spin_id=info['id'])
838
839
840 if spin == None or spin.name != info['spin_name'] or spin.num != info['spin_num']:
841 prune_list.append(key)
842
843
844 for key in prune_list:
845 self.tree.Delete(key)
846 self.tree_ids[mol_branch_id][res_branch_id].pop(key)
847
848
850 """Set the molecule bitmaps.
851
852 @param mol_branch_id: The molecule branch ID of the wx.TreeCtrl object.
853 @type mol_branch_id: TreeItemId
854 @keyword select: The selection flag.
855 @type select: bool
856 """
857
858
859 if select:
860 bmp = self.icon_mol_index
861 bmp_unfold = self.icon_mol_unfold_index
862
863
864 else:
865 bmp = self.icon_mol_index_desel
866 bmp_unfold = self.icon_mol_unfold_index_desel
867
868
869 self.tree.SetItemImage(mol_branch_id, bmp, wx.TreeItemIcon_Normal)
870 self.tree.SetItemImage(mol_branch_id, bmp_unfold, wx.TreeItemIcon_Expanded)
871
872
874 """Set the residue bitmaps.
875
876 @param res_branch_id: The residue branch ID of the wx.TreeCtrl object.
877 @type res_branch_id: TreeItemId
878 @keyword select: The selection flag.
879 @type select: bool
880 """
881
882
883 if select:
884 bmp = self.icon_res_index
885
886
887 else:
888 bmp = self.icon_res_index_desel
889
890
891 self.tree.SetItemImage(res_branch_id, bmp, wx.TreeItemIcon_Normal & wx.TreeItemIcon_Expanded)
892
893
895 """Set the spin bitmaps.
896
897 @param spin_branch_id: The spin branch ID of the wx.TreeCtrl object.
898 @type spin_branch_id: TreeItemId
899 @keyword select: The selection flag.
900 @type select: bool
901 """
902
903
904 if select:
905 bmp = self.icon_spin_index
906
907
908 else:
909 bmp = self.icon_spin_index_desel
910
911
912 self.tree.SetItemImage(spin_branch_id, bmp, wx.TreeItemIcon_Normal & wx.TreeItemIcon_Expanded)
913
914
915 - def update(self, pipe_name=None):
916 """Update the tree view using the given data pipe."""
917
918
919 status.pipe_lock.acquire('spin viewer window')
920 status.spin_lock.acquire('spin viewer window')
921 try:
922
923 if not pipe_name:
924 pipe = cdp
925 else:
926 pipe = get_pipe(pipe_name)
927
928
929 if not pipe:
930 self.tree.DeleteChildren(self.root)
931 return
932
933
934 for mol, mol_id in molecule_loop(return_id=True):
935 self.update_mol(mol, mol_id)
936
937
938 self.prune_mol()
939
940
941 finally:
942 status.pipe_lock.release('spin viewer window')
943 status.spin_lock.release('spin viewer window')
944
945
947 """Update the given molecule in the tree.
948
949 @param mol: The molecule container.
950 @type mol: MoleculeContainer instance
951 @param mol_id: The molecule identification string.
952 @type mol_id: str
953 """
954
955
956 new_mol = True
957 for key in self.tree_ids:
958
959 if dep_check.wx_classic:
960 data = self.tree.GetItemPyData(key)
961 else:
962 data = self.tree.GetItemData(key)
963
964
965 if data == None or 'id' not in data:
966 continue
967
968
969 if mol_id == data['id']:
970 new_mol = False
971 mol_branch_id = key
972 break
973
974
975 if new_mol:
976
977 mol_branch_id = self.tree.AppendItem(self.root, "Molecule: %s" % mol.name)
978
979
980 data = {
981 'type': 'mol',
982 'mol_name': mol.name,
983 'id': mol_id,
984 'select': is_mol_selected(mol_id)
985 }
986 if dep_check.wx_classic:
987 self.tree.SetPyData(mol_branch_id, data)
988 else:
989 self.tree.SetItemData(mol_branch_id, data)
990
991
992 self.tree_ids[mol_branch_id] = {}
993
994
995 self.set_bitmap_mol(mol_branch_id, select=data['select'])
996
997
998 else:
999
1000 select = is_mol_selected(data['id'])
1001
1002
1003 if select != data['select']:
1004
1005 data['select'] = select
1006
1007
1008 self.set_bitmap_mol(mol_branch_id, select=data['select'])
1009
1010
1011 for res, res_id in residue_loop(mol_id, return_id=True):
1012 self.update_res(mol_branch_id, mol, res, res_id)
1013
1014
1015 if new_mol and data['select']:
1016 self.tree.Expand(mol_branch_id)
1017
1018
1019 self.prune_res(mol_branch_id, mol_id)
1020
1021
1022 self.tree.Expand(self.root)
1023
1024
1025 - def update_res(self, mol_branch_id, mol, res, res_id):
1026 """Update the given residue in the tree.
1027
1028 @param mol_branch_id: The molecule branch ID of the wx.TreeCtrl object.
1029 @type mol_branch_id: TreeItemId
1030 @param mol: The molecule container.
1031 @type mol: MoleculeContainer instance
1032 @param res: The residue container.
1033 @type res: ResidueContainer instance
1034 @param res_id: The residue identification string.
1035 @type res_id: str
1036 """
1037
1038
1039 new_res = True
1040 for key in self.tree_ids[mol_branch_id]:
1041
1042 if dep_check.wx_classic:
1043 data = self.tree.GetItemPyData(key)
1044 else:
1045 data = self.tree.GetItemData(key)
1046
1047
1048 if data == None or 'id' not in data:
1049 continue
1050
1051
1052 if res_id == data['id'] and res.name == data['res_name'] and res.num == data['res_num']:
1053 new_res = False
1054 res_branch_id = key
1055 break
1056
1057
1058 if new_res:
1059
1060 res_branch_id = self.tree.AppendItem(mol_branch_id, "Residue: %s %s" % (res.num, res.name))
1061
1062
1063 data = {
1064 'type': 'res',
1065 'mol_name': mol.name,
1066 'res_name': res.name,
1067 'res_num': res.num,
1068 'id': res_id,
1069 'select': is_res_selected(res_id)
1070 }
1071 if dep_check.wx_classic:
1072 self.tree.SetPyData(res_branch_id, data)
1073 else:
1074 self.tree.SetItemData(res_branch_id, data)
1075
1076
1077 self.tree_ids[mol_branch_id][res_branch_id] = {}
1078
1079
1080 self.set_bitmap_res(res_branch_id, select=data['select'])
1081
1082
1083 else:
1084
1085 select = is_res_selected(data['id'])
1086
1087
1088 if select != data['select']:
1089
1090 data['select'] = select
1091
1092
1093 self.set_bitmap_res(res_branch_id, select=data['select'])
1094
1095
1096 for spin, spin_id in spin_loop(res_id, return_id=True):
1097 self.update_spin(mol_branch_id, res_branch_id, mol, res, spin, spin_id)
1098
1099
1100 if new_res and data['select']:
1101 self.tree.Expand(res_branch_id)
1102
1103
1104 self.prune_spin(mol_branch_id, res_branch_id, res_id)
1105
1106
1107 - def update_spin(self, mol_branch_id, res_branch_id, mol, res, spin, spin_id):
1108 """Update the given spin in the tree.
1109
1110 @param mol_branch_id: The molecule branch ID of the wx.TreeCtrl object.
1111 @type mol_branch_id: TreeItemId
1112 @param res_branch_id: The residue branch ID of the wx.TreeCtrl object.
1113 @type res_branch_id: TreeItemId
1114 @param mol: The molecule container.
1115 @type mol: MoleculeContainer instance
1116 @param res: The residue container.
1117 @type res: ResidueContainer instance
1118 @param spin: The spin container.
1119 @type spin: SpinContainer instance
1120 @param spin_id: The spin identification string.
1121 @type spin_id: str
1122 """
1123
1124
1125 new_spin = True
1126 for key in self.tree_ids[mol_branch_id][res_branch_id]:
1127
1128 if dep_check.wx_classic:
1129 data = self.tree.GetItemPyData(key)
1130 else:
1131 data = self.tree.GetItemData(key)
1132
1133
1134 if data == None or 'id' not in data:
1135 continue
1136
1137
1138 if spin_id == data['id'] and spin.name == data['spin_name'] and spin.num == data['spin_num']:
1139 new_spin = False
1140 spin_branch_id = key
1141 break
1142
1143
1144 if new_spin:
1145
1146 spin_branch_id = self.tree.AppendItem(res_branch_id, "Spin: %s %s" % (spin.num, spin.name))
1147
1148
1149 data = {
1150 'type': 'spin',
1151 'mol_name': mol.name,
1152 'res_name': res.name,
1153 'res_num': res.num,
1154 'spin_name': spin.name,
1155 'spin_num': spin.num,
1156 'id': spin_id,
1157 'select': is_spin_selected(spin_id)
1158 }
1159 if dep_check.wx_classic:
1160 self.tree.SetPyData(spin_branch_id, data)
1161 else:
1162 self.tree.SetItemData(spin_branch_id, data)
1163
1164
1165 self.tree_ids[mol_branch_id][res_branch_id][spin_branch_id] = True
1166
1167
1168 self.set_bitmap_spin(spin_branch_id, select=data['select'])
1169
1170
1171 else:
1172
1173 select = is_spin_selected(data['id'])
1174
1175
1176 if select != data['select']:
1177
1178 data['select'] = select
1179
1180
1181 self.set_bitmap_spin(spin_branch_id, select=data['select'])
1182
1183
1184 if new_spin and data['select']:
1185 self.tree.Expand(spin_branch_id)
1186