1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22   
 23   
 24   
 25  """Module for the main relax menu bar.""" 
 26   
 27   
 28  import wx 
 29   
 30   
 31  from status import Status; status = Status() 
 32   
 33   
 34  from gui import paths 
 35  from gui.components.menu import build_menu_item 
 36  from gui.user_functions import User_functions 
 37   
 38   
 40      """The menu bar GUI class.""" 
 41   
 42       
 43      MENU_FILE_NEW = wx.NewId() 
 44      MENU_FILE_CLOSE = wx.NewId() 
 45      MENU_FILE_CLOSE_ALL = wx.NewId() 
 46      MENU_FILE_OPEN = wx.NewId() 
 47      MENU_FILE_SAVE = wx.NewId() 
 48      MENU_FILE_SAVE_AS = wx.NewId() 
 49      MENU_FILE_EXIT = wx.NewId() 
 50      MENU_VIEW_CONTROLLER = wx.NewId() 
 51      MENU_VIEW_SPIN_VIEW = wx.NewId() 
 52      MENU_VIEW_RESULTS = wx.NewId() 
 53      MENU_VIEW_PIPE_EDIT = wx.NewId() 
 54      MENU_VIEW_PROMPT = wx.NewId() 
 55      MENU_TOOLS_FORMAT = wx.NewId() 
 56      MENU_TOOLS_TEST_SUITE = wx.NewId() 
 57      MENU_TOOLS_TEST_SUITE_ALL = wx.NewId() 
 58      MENU_TOOLS_TEST_SUITE_SYS = wx.NewId() 
 59      MENU_TOOLS_TEST_SUITE_UNIT = wx.NewId() 
 60      MENU_TOOLS_TEST_SUITE_GUI = wx.NewId() 
 61      MENU_TOOLS_SYS_INFO = wx.NewId() 
 62      MENU_HELP_MANUAL = wx.NewId() 
 63      MENU_HELP_MAIL = wx.NewId() 
 64      MENU_HELP_REFS = wx.NewId() 
 65      MENU_HELP_GPL = wx.NewId() 
 66      MENU_HELP_ABOUT_GUI = wx.NewId() 
 67      MENU_HELP_ABOUT = wx.NewId() 
 68   
 70          """Build the menu bar.""" 
 71   
 72           
 73          self.gui = gui 
 74   
 75           
 76          self.menubar = wx.MenuBar() 
 77   
 78           
 79          menu = wx.Menu() 
 80          menu.AppendItem(build_menu_item(menu, id=self.MENU_FILE_NEW, text="&New analysis\tCtrl+N", icon=paths.icon_16x16.new)) 
 81          menu.AppendItem(build_menu_item(menu, id=self.MENU_FILE_CLOSE, text="&Close analysis", icon=paths.icon_16x16.document_close)) 
 82          menu.AppendItem(build_menu_item(menu, id=self.MENU_FILE_CLOSE_ALL, text="&Close all analyses", icon=paths.icon_16x16.dialog_close)) 
 83          menu.AppendSeparator() 
 84          menu.AppendItem(build_menu_item(menu, id=self.MENU_FILE_OPEN, text="&Open relax state\tCtrl+O", icon=paths.icon_16x16.document_open)) 
 85          menu.AppendItem(build_menu_item(menu, id=self.MENU_FILE_SAVE, text="S&ave relax state\tCtrl+S", icon=paths.icon_16x16.document_save)) 
 86          menu.AppendItem(build_menu_item(menu, id=self.MENU_FILE_SAVE_AS, text="Save as...\tCtrl+Shift+S", icon=paths.icon_16x16.document_save_as)) 
 87          menu.AppendSeparator() 
 88          menu.AppendItem(build_menu_item(menu, id=self.MENU_FILE_EXIT, text="E&xit\tCtrl+Q", icon=paths.icon_16x16.exit)) 
 89          self.menubar.Append(menu, "&File") 
 90   
 91           
 92          self.gui.Bind(wx.EVT_MENU, self.gui.analysis.menu_new, id=self.MENU_FILE_NEW) 
 93          self.gui.Bind(wx.EVT_MENU, self.gui.analysis.menu_close, id=self.MENU_FILE_CLOSE) 
 94          self.gui.Bind(wx.EVT_MENU, self.gui.analysis.menu_close_all, id=self.MENU_FILE_CLOSE_ALL) 
 95          self.gui.Bind(wx.EVT_MENU, self.gui.state_load, id=self.MENU_FILE_OPEN) 
 96          self.gui.Bind(wx.EVT_MENU, self.gui.action_state_save, id=self.MENU_FILE_SAVE) 
 97          self.gui.Bind(wx.EVT_MENU, self.gui.action_state_save_as, id=self.MENU_FILE_SAVE_AS) 
 98          self.gui.Bind(wx.EVT_MENU, self.gui.exit_gui, id=self.MENU_FILE_EXIT) 
 99   
100           
101          menu = wx.Menu() 
102          menu.AppendItem(build_menu_item(menu, id=self.MENU_VIEW_CONTROLLER, text="&Controller\tCtrl+Z", icon=paths.icon_16x16.preferences_system_performance)) 
103          menu.AppendItem(build_menu_item(menu, id=self.MENU_VIEW_SPIN_VIEW, text="&Spin view\tCtrl+T", icon=paths.icon_16x16.spin)) 
104          menu.AppendItem(build_menu_item(menu, id=self.MENU_VIEW_RESULTS, text="&Results viewer\tCtrl+R", icon=paths.icon_16x16.view_statistics)) 
105          menu.AppendItem(build_menu_item(menu, id=self.MENU_VIEW_PIPE_EDIT, text="&Data pipe editor\tCtrl+D", icon=paths.icon_16x16.pipe)) 
106          menu.AppendItem(build_menu_item(menu, id=self.MENU_VIEW_PROMPT, text="relax &prompt\tCtrl+P", icon=paths.icon_16x16.relax_prompt)) 
107          self.menubar.Append(menu, "&View") 
108   
109           
110          self.gui.Bind(wx.EVT_MENU, self.gui.show_controller, id=self.MENU_VIEW_CONTROLLER) 
111          self.gui.Bind(wx.EVT_MENU, self.gui.show_prompt, id=self.MENU_VIEW_PROMPT) 
112          self.gui.Bind(wx.EVT_MENU, self.gui.show_tree, id=self.MENU_VIEW_SPIN_VIEW) 
113          self.gui.Bind(wx.EVT_MENU, self.gui.show_results_viewer, id=self.MENU_VIEW_RESULTS) 
114          self.gui.Bind(wx.EVT_MENU, self.gui.show_pipe_editor, id=self.MENU_VIEW_PIPE_EDIT) 
115   
116           
117          self._user_functions() 
118   
119           
120          menu = wx.Menu() 
121          menu.AppendItem(build_menu_item(menu, id=self.MENU_TOOLS_FORMAT, text="&Free file format settings", icon=paths.icon_16x16.document_properties)) 
122          menu.AppendItem(build_menu_item(menu, id=self.MENU_TOOLS_SYS_INFO, text="System &information", icon=paths.icon_16x16.help_about)) 
123   
124           
125          test_suite_item = build_menu_item(menu, id=self.MENU_TOOLS_TEST_SUITE, text="&Test suite", icon=paths.icon_16x16.uf_script) 
126          sub_menu = wx.Menu() 
127          test_suite_item.SetSubMenu(sub_menu) 
128          sub_menu.AppendItem(build_menu_item(sub_menu, id=self.MENU_TOOLS_TEST_SUITE_ALL, text="&Full test suite", icon=paths.icon_16x16.uf_script)) 
129          sub_menu.AppendSeparator() 
130          sub_menu.AppendItem(build_menu_item(sub_menu, id=self.MENU_TOOLS_TEST_SUITE_SYS, text="&System tests", icon=paths.icon_16x16.uf_script)) 
131          sub_menu.AppendItem(build_menu_item(sub_menu, id=self.MENU_TOOLS_TEST_SUITE_UNIT, text="&Unit tests", icon=paths.icon_16x16.uf_script)) 
132          sub_menu.AppendItem(build_menu_item(sub_menu, id=self.MENU_TOOLS_TEST_SUITE_GUI, text="&GUI tests", icon=paths.icon_16x16.uf_script)) 
133          menu.AppendItem(test_suite_item) 
134          self.menubar.Append(menu, "&Tools") 
135   
136           
137          self.gui.Bind(wx.EVT_MENU, self.gui.free_file_format_settings, id=self.MENU_TOOLS_FORMAT) 
138          self.gui.Bind(wx.EVT_MENU, self._sys_info, id=self.MENU_TOOLS_SYS_INFO) 
139          self.gui.Bind(wx.EVT_MENU, self.gui.run_test_suite, id=self.MENU_TOOLS_TEST_SUITE_ALL) 
140          self.gui.Bind(wx.EVT_MENU, self.gui.run_test_suite_sys, id=self.MENU_TOOLS_TEST_SUITE_SYS) 
141          self.gui.Bind(wx.EVT_MENU, self.gui.run_test_suite_unit, id=self.MENU_TOOLS_TEST_SUITE_UNIT) 
142          self.gui.Bind(wx.EVT_MENU, self.gui.run_test_suite_gui, id=self.MENU_TOOLS_TEST_SUITE_GUI) 
143   
144           
145          menu = wx.Menu() 
146          menu.AppendItem(build_menu_item(menu, id=self.MENU_HELP_MANUAL, text="relax user &manual\tF1", icon=paths.icon_16x16.manual)) 
147          menu.AppendSeparator() 
148          menu.AppendItem(build_menu_item(menu, id=self.MENU_HELP_MAIL, text="Mailing list &contact (relax-users@gna.org)", icon=paths.icon_16x16.contact)) 
149          menu.AppendItem(build_menu_item(menu, id=self.MENU_HELP_REFS, text="&References", icon=paths.icon_16x16.ref)) 
150          menu.AppendSeparator() 
151          menu.AppendItem(build_menu_item(menu, id=self.MENU_HELP_GPL, text="&Licence", icon=paths.icon_16x16.gnu_head)) 
152          menu.AppendSeparator() 
153          menu.AppendItem(build_menu_item(menu, id=self.MENU_HELP_ABOUT_GUI, text="About relaxG&UI", icon=paths.icon_16x16.about_relaxgui)) 
154          menu.AppendItem(build_menu_item(menu, id=self.MENU_HELP_ABOUT, text="About rela&x", icon=paths.icon_16x16.about_relax)) 
155          self.menubar.Append(menu, "&Help") 
156   
157           
158          self.gui.Bind(wx.EVT_MENU, self.gui.relax_manual, id=self.MENU_HELP_MANUAL) 
159          self.gui.Bind(wx.EVT_MENU, self.gui.contact_relax, id=self.MENU_HELP_MAIL) 
160          self.gui.Bind(wx.EVT_MENU, self.gui.references, id=self.MENU_HELP_REFS) 
161          self.gui.Bind(wx.EVT_MENU, self._licence, id=self.MENU_HELP_GPL) 
162          self.gui.Bind(wx.EVT_MENU, self.gui.about_gui, id=self.MENU_HELP_ABOUT_GUI) 
163          self.gui.Bind(wx.EVT_MENU, self.gui.about_relax, id=self.MENU_HELP_ABOUT) 
164   
165           
166          if status.show_gui: 
167              self.gui.SetMenuBar(self.menubar) 
168   
169           
170          self.gui.Bind(wx.EVT_MENU_OPEN, self.update_menus) 
 171   
172   
174          """Build the menu.""" 
175   
176           
177          for item in entries: 
178               
179              menu_item = build_menu_item(menu, id=item[0], text=item[1], icon=item[2]) 
180   
181               
182              if len(item[4]): 
183                   
184                  sub_menu = wx.Menu() 
185   
186                   
187                  for sub_item in item[4]: 
188                       
189                      sub_menu_item = build_menu_item(sub_menu, id=sub_item[0], text=sub_item[1], icon=sub_item[2]) 
190                      sub_menu.AppendItem(sub_menu_item) 
191   
192                       
193                      self.gui.Bind(wx.EVT_MENU, sub_item[3], id=sub_item[0]) 
194   
195                   
196                  menu_item.SetSubMenu(sub_menu) 
197   
198               
199              else: 
200                   
201                  self.gui.Bind(wx.EVT_MENU, item[3], id=item[0]) 
202   
203               
204              menu.AppendItem(menu_item) 
 205   
206   
222   
223   
236   
237   
239          """Build the user function sub-menu.""" 
240   
241           
242          menu = wx.Menu() 
243   
244           
245          uf_menus = Uf_menus(parent=self.gui, menu=menu) 
246   
247           
248          title = "&User functions" 
249          self.menubar.Append(menu, title) 
250          self.menu_uf_id = self.menubar.FindMenu(title) 
 251   
252   
 290   
291   
292   
294      """A class for the creation of specialised menu entries for the user functions.""" 
295   
297          """Set up the menu entries. 
298   
299          @keyword parent:    The parent window. 
300          @type parent:       wx.Window instance 
301          @keyword menu:      The menu to add to. 
302          @type menu:         wx.Menu instance 
303          """ 
304   
305           
306          self.parent = parent 
307          self.menu = menu 
308   
309           
310          user_functions = User_functions(self.parent) 
311   
312           
313          self.uf_names = {} 
314          self.uf = {} 
315   
316           
317          id = self.add_class(name="bmrb", text="&bmrb", icon=paths.icon_16x16.bmrb) 
318          self.add_uf(parent_id=id, name="bmrb.citation", text="&citation", fn=user_functions.bmrb.citation) 
319   
320          id = self.add_class(name="bruker", text="&bruker", icon=paths.icon_16x16.bruker) 
321          self.add_uf(parent_id=id, name="bruker.read", text="&read", icon=paths.icon_16x16.open, fn=user_functions.bruker.read) 
322   
323          id = self.add_class(name="deselect", text="&deselect", icon=None) 
324          self.add_uf(parent_id=id, name="deselect.all", text="&all", icon=None, fn=user_functions.deselect.all) 
325          self.add_uf(parent_id=id, name="deselect.read", text="&read", icon=paths.icon_16x16.open, fn=user_functions.deselect.read) 
326          self.add_uf(parent_id=id, name="deselect.reverse", text="re&verse", icon=None, fn=user_functions.deselect.reverse) 
327          self.add_uf(parent_id=id, name="deselect.spin", text="&spin", icon=paths.icon_16x16.spin, fn=user_functions.deselect.spin) 
328   
329          self.add_uf(parent_id=None, name="gpl", text="&gpl", icon=paths.icon_16x16.gnu_head, fn=user_functions.gpl.run) 
330   
331          id = self.add_class(name="grace", text="gra&ce", icon=paths.icon_16x16.grace) 
332          self.add_uf(parent_id=id, name="grace.view", text="&view", icon=paths.icon_16x16.grace, fn=user_functions.grace.view) 
333          self.add_uf(parent_id=id, name="grace.write", text="&write", icon=paths.icon_16x16.save, fn=user_functions.grace.write) 
334   
335          id = self.add_class(name="molecule", text="&molecule", icon=paths.icon_16x16.molecule) 
336          self.add_uf(parent_id=id, name="molecule.copy", text="©", icon=paths.icon_16x16.copy, fn=user_functions.molecule.copy) 
337          self.add_uf(parent_id=id, name="molecule.create", text="crea&te", icon=paths.icon_16x16.add, fn=user_functions.molecule.create) 
338          self.add_uf(parent_id=id, name="molecule.delete", text="&delete", icon=paths.icon_16x16.remove, fn=user_functions.molecule.delete) 
339   
340          id = self.add_class(name="molmol", text="&molmol", icon=paths.icon_16x16.molmol) 
341          self.add_uf(parent_id=id, name="molmol.clear_history", text="clear_&history", icon=None, fn=user_functions.molmol.clear_history) 
342          self.add_uf(parent_id=id, name="molmol.command", text="&command", icon=None, fn=user_functions.molmol.command) 
343          self.add_uf(parent_id=id, name="molmol.macro_apply", text="¯o_apply", icon=paths.icon_16x16.molmol, fn=user_functions.molmol.macro_apply) 
344          self.add_uf(parent_id=id, name="molmol.macro_run", text="macro_&run", icon=paths.icon_16x16.open, fn=user_functions.molmol.macro_run) 
345          self.add_uf(parent_id=id, name="molmol.macro_write", text="macro_&write", icon=paths.icon_16x16.save, fn=user_functions.molmol.macro_write) 
346          self.add_uf(parent_id=id, name="molmol.ribbon", text="ri&bbon", icon=None, fn=user_functions.molmol.ribbon) 
347          self.add_uf(parent_id=id, name="molmol.tensor_pdb", text="&tensor_pdb", icon=None, fn=user_functions.molmol.tensor_pdb) 
348          self.add_uf(parent_id=id, name="molmol.view", text="&view", icon=None, fn=user_functions.molmol.view) 
349   
350          id = self.add_class(name="noe", text="&noe", icon=None) 
351          self.add_uf(parent_id=id, name="noe.read_restraints", text="&read_restraints", icon=paths.icon_16x16.open, fn=user_functions.noe.read_restraints) 
352          self.add_uf(parent_id=id, name="noe.spectrum_type", text="&spectrum_type", icon=None, fn=user_functions.noe.spectrum_type) 
353   
354          id = self.add_class(name="pipe", text="&pipe", icon=paths.icon_16x16.pipe) 
355          self.add_uf(parent_id=id, name="pipe.copy", text="©", icon=paths.icon_16x16.copy, fn=user_functions.pipe.copy) 
356          self.add_uf(parent_id=id, name="pipe.create", text="crea&te", icon=paths.icon_16x16.add, fn=user_functions.pipe.create) 
357          self.add_uf(parent_id=id, name="pipe.delete", text="&delete", icon=paths.icon_16x16.remove, fn=user_functions.pipe.delete) 
358          self.add_uf(parent_id=id, name="pipe.hybridise", text="&hybridise", icon=paths.icon_16x16.pipe_hybrid, fn=user_functions.pipe.hybridise) 
359          self.add_uf(parent_id=id, name="pipe.switch", text="&switch", icon=paths.icon_16x16.pipe_switch, fn=user_functions.pipe.switch) 
360   
361          id = self.add_class(name="pymol", text="&pymol", icon=paths.icon_16x16.pymol) 
362          self.add_uf(parent_id=id, name="pymol.clear_history", text="clear_&history", icon=None, fn=user_functions.pymol.clear_history) 
363          self.add_uf(parent_id=id, name="pymol.command", text="&command", icon=None, fn=user_functions.pymol.command) 
364          self.add_uf(parent_id=id, name="pymol.macro_apply", text="¯o_apply", icon=paths.icon_16x16.pymol, fn=user_functions.pymol.macro_apply) 
365          self.add_uf(parent_id=id, name="pymol.macro_run", text="¯o_&run", icon=paths.icon_16x16.open, fn=user_functions.pymol.macro_run) 
366          self.add_uf(parent_id=id, name="pymol.macro_write", text="macro_&write", icon=paths.icon_16x16.save, fn=user_functions.pymol.macro_write) 
367          self.add_uf(parent_id=id, name="pymol.ribbon", text="ri&bbon", icon=None, fn=user_functions.pymol.ribbon) 
368          self.add_uf(parent_id=id, name="pymol.tensor_pdb", text="&tensor_pdb", icon=None, fn=user_functions.pymol.tensor_pdb) 
369          self.add_uf(parent_id=id, name="pymol.view", text="&view", icon=None, fn=user_functions.pymol.view) 
370   
371          id = self.add_class(name="relax_data", text="&relax_data", icon=paths.icon_16x16.relax_data) 
372          self.add_uf(parent_id=id, name="relax_data.delete", text="&delete", icon=paths.icon_16x16.remove, fn=user_functions.relax_data.delete) 
373          self.add_uf(parent_id=id, name="relax_data.read", text="&read", icon=paths.icon_16x16.open, fn=user_functions.relax_data.read) 
374   
375          id = self.add_class(name="relax_fit", text="relax_&fit", icon=None) 
376          self.add_uf(parent_id=id, name="relax_fit.relax_time", text="&relax_time", icon=None, fn=user_functions.relax_fit.relax_time) 
377          self.add_uf(parent_id=id, name="relax_fit.select_model", text="&select_model", icon=None, fn=user_functions.relax_fit.select_model) 
378   
379          id = self.add_class(name="residue", text="resid&ue", icon=paths.icon_16x16.residue) 
380          self.add_uf(parent_id=id, name="residue.copy", text="©", icon=paths.icon_16x16.copy, fn=user_functions.residue.copy) 
381          self.add_uf(parent_id=id, name="residue.create", text="crea&te", icon=paths.icon_16x16.add, fn=user_functions.residue.create) 
382          self.add_uf(parent_id=id, name="residue.delete", text="&delete", icon=paths.icon_16x16.remove, fn=user_functions.residue.delete) 
383   
384          id = self.add_class(name="results", text="&results", icon=paths.icon_16x16.about_relax) 
385          self.add_uf(parent_id=id, name="results.display", text="&display", icon=None, fn=user_functions.results.display) 
386          self.add_uf(parent_id=id, name="results.read", text="&read", icon=paths.icon_16x16.open, fn=user_functions.results.read) 
387          self.add_uf(parent_id=id, name="results.write", text="&write", icon=paths.icon_16x16.save, fn=user_functions.results.write) 
388   
389          self.add_uf(parent_id=None, name="script", text="s&cript", icon=paths.icon_16x16.uf_script, fn=user_functions.script.run) 
390   
391          id = self.add_class(name="select", text="se&lect", icon=None) 
392          self.add_uf(parent_id=id, name="select.all", text="&all", icon=None, fn=user_functions.select.all) 
393          self.add_uf(parent_id=id, name="select.read", text="&read", icon=paths.icon_16x16.open, fn=user_functions.select.read) 
394          self.add_uf(parent_id=id, name="select.reverse", text="re&verse", icon=None, fn=user_functions.select.reverse) 
395          self.add_uf(parent_id=id, name="select.spin", text="&spin", icon=paths.icon_16x16.spin, fn=user_functions.select.spin) 
396   
397          id = self.add_class(name="sequence", text="se&quence", icon=paths.icon_16x16.sequence) 
398          self.add_uf(parent_id=id, name="sequence.copy", text="©", icon=paths.icon_16x16.copy, fn=user_functions.sequence.copy) 
399          self.add_uf(parent_id=id, name="sequence.read", text="&read", icon=paths.icon_16x16.open, fn=user_functions.sequence.read) 
400          self.add_uf(parent_id=id, name="sequence.write", text="&write", icon=paths.icon_16x16.save, fn=user_functions.sequence.write) 
401   
402          id = self.add_class(name="spectrum", text="s&pectrum", icon=None) 
403          self.add_uf(parent_id=id, name="spectrum.baseplane_rmsd", text="&baseplane_rmsd", icon=None, fn=user_functions.spectrum.baseplane_rmsd) 
404          self.add_uf(parent_id=id, name="spectrum.delete", text="&delete", icon=paths.icon_16x16.remove, fn=user_functions.spectrum.delete) 
405          self.add_uf(parent_id=id, name="spectrum.error_analysis", text="&error_analysis", icon=None, fn=user_functions.spectrum.error_analysis) 
406          self.add_uf(parent_id=id, name="spectrum.integration_points", text="&integration_points", icon=None, fn=user_functions.spectrum.integration_points) 
407          self.add_uf(parent_id=id, name="spectrum.read_intensities", text="&read_intensities", icon=paths.icon_16x16.open, fn=user_functions.spectrum.read_intensities) 
408          self.add_uf(parent_id=id, name="spectrum.replicated", text="&replicated", icon=None, fn=user_functions.spectrum.replicated) 
409   
410          id = self.add_class(name="spin", text="&spin", icon=paths.icon_16x16.spin) 
411          self.add_uf(parent_id=id, name="spin.copy", text="©", icon=paths.icon_16x16.copy, fn=user_functions.spin.copy) 
412          self.add_uf(parent_id=id, name="spin.create", text="crea&te", icon=paths.icon_16x16.add, fn=user_functions.spin.create) 
413          self.add_uf(parent_id=id, name="spin.create_pseudo", text="create_&pseudo", icon=paths.icon_16x16.add, fn=user_functions.spin.create_pseudo) 
414          self.add_uf(parent_id=id, name="spin.delete", text="&delete", icon=paths.icon_16x16.remove, fn=user_functions.spin.delete) 
415          self.add_uf(parent_id=id, name="spin.display", text="displa&y", icon=None, fn=user_functions.spin.display) 
416          self.add_uf(parent_id=id, name="spin.element", text="&element", icon=None, fn=user_functions.spin.element) 
417          self.add_uf(parent_id=id, name="spin.name", text="&name", icon=None, fn=user_functions.spin.name) 
418          self.add_uf(parent_id=id, name="spin.number", text="num&ber", icon=None, fn=user_functions.spin.number) 
419   
420          id = self.add_class(name="structure", text="s&tructure", icon=paths.icon_16x16.structure) 
421          self.add_uf(parent_id=id, name="structure.create_diff_tensor_pdb", text="&create_diff_tensor_pdb", icon=None, fn=user_functions.structure.create_diff_tensor_pdb) 
422          self.add_uf(parent_id=id, name="structure.create_vector_dist", text="&create_vector_dist", icon=None, fn=user_functions.structure.create_vector_dist) 
423          self.add_uf(parent_id=id, name="structure.delete", text="&delete", icon=paths.icon_16x16.remove, fn=user_functions.structure.delete) 
424          self.add_uf(parent_id=id, name="structure.get_pos", text="&get_pos", icon=None, fn=user_functions.structure.get_pos) 
425          self.add_uf(parent_id=id, name="structure.load_spins", text="&load_spins", icon=paths.icon_16x16.spin, fn=user_functions.structure.load_spins) 
426          self.add_uf(parent_id=id, name="structure.read_pdb", text="&read_pdb", icon=paths.icon_16x16.open, fn=user_functions.structure.read_pdb) 
427          self.add_uf(parent_id=id, name="structure.read_xyz", text="&read_xyz", icon=paths.icon_16x16.open, fn=user_functions.structure.read_xyz) 
428          self.add_uf(parent_id=id, name="structure.vectors", text="&vectors", icon=None, fn=user_functions.structure.vectors) 
429          self.add_uf(parent_id=id, name="structure.write_pdb", text="&write_pdb", icon=paths.icon_16x16.save, fn=user_functions.structure.write_pdb) 
430   
431          self.add_uf(parent_id=None, name="sys_info", text="sys_&info", icon=paths.icon_16x16.help_about, fn=user_functions.sys_info.sys_info) 
432   
433          id = self.add_class(name="value", text="&value", icon=paths.icon_16x16.value) 
434          self.add_uf(parent_id=id, name="value.set", text="&set", icon=paths.icon_16x16.add, fn=user_functions.value.set) 
 435   
436   
438          """Add the user function. 
439   
440          @keyword name:      The name of the user function, such as 'residue.delete'. 
441          @type name:         str 
442          @keyword text:      The menu text string. 
443          @type text:         str 
444          @keyword icon:      The path to the icon image file for the menu entry. 
445          @type icon:         str or None 
446          @return:            The menu ID number. 
447          @rtype:             long 
448          """ 
449   
450           
451          id = wx.NewId() 
452   
453           
454          menu_item = build_menu_item(self.menu, id=id, text=text, icon=icon) 
455   
456           
457          sub_menu = wx.Menu() 
458          menu_item.SetSubMenu(sub_menu) 
459   
460           
461          self.menu.AppendItem(menu_item) 
462   
463           
464          return id 
 465   
466   
468          """Add the user function. 
469   
470          @keyword parent_id: The unique ID number of the parent menu entry. 
471          @type parent_id:    long 
472          @keyword name:      The name of the user function, such as 'residue.delete'. 
473          @type name:         str 
474          @keyword text:      The menu text string. 
475          @type text:         str 
476          @keyword icon:      The path to the icon image file for the menu entry. 
477          @type icon:         str or None 
478          @keyword fn:        The user function to execute. 
479          @type fn:           func 
480          @return:            The menu ID number. 
481          @rtype:             long 
482          """ 
483   
484           
485          id = wx.NewId() 
486   
487           
488          self.uf_names[id] = name 
489          self.uf[id] = fn 
490   
491           
492          if parent_id != None: 
493              sub_menu = self.menu.FindItemById(parent_id).GetSubMenu() 
494              item = build_menu_item(sub_menu, id=id, text=text, icon=icon) 
495              sub_menu.AppendItem(item) 
496   
497           
498          else: 
499              item = build_menu_item(self.menu, id=id, text=text, icon=icon) 
500              self.menu.AppendItem(item) 
501   
502           
503          self.parent.Bind(wx.EVT_MENU, self.call, id=id) 
504   
505           
506          return id 
 507   
508   
510          """Execute the given user function. 
511   
512          @param event:   The wx event. 
513          @type event:    wx event 
514          """ 
515   
516           
517          id = event.GetId() 
518   
519           
520          apply(self.uf[id]) 
  521