1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22   
 23   
 24  """Module containing the base GUI element for listing things.""" 
 25   
 26   
 27  import wx 
 28  import wx.lib.buttons 
 29   
 30   
 31  from gui.components.menu import build_menu_item 
 32  from gui.fonts import font 
 33  from gui.misc import add_border 
 34  from gui.string_conv import str_to_gui 
 35  from gui.uf_objects import Uf_storage; uf_store = Uf_storage() 
 36  from status import Status; status = Status() 
 37  from user_functions.data import Uf_info; uf_info = Uf_info() 
 38   
 39   
 41      """The GUI element for listing the software used in the analysis.""" 
 42   
 43 -    def __init__(self, gui=None, parent=None, box=None, id=None, proportion=0, button_placement='default'): 
  44          """Build the base list GUI element. 
 45   
 46          @keyword gui:               The main GUI object. 
 47          @type gui:                  wx.Frame instance 
 48          @keyword parent:            The parent GUI element that this is to be attached to. 
 49          @type parent:               wx object 
 50          @keyword box:               The box sizer to pack this GUI component into. 
 51          @type box:                  wx.BoxSizer instance 
 52          @keyword id:                A unique identification string.  This is used to register the update method with the GUI user function observer object. 
 53          @type id:                   str 
 54          @keyword proportion:        The window proportion parameter. 
 55          @type proportion:           bool 
 56          @keyword button_placement:  Override the button visibility and placement.  The value of 'default' will leave the buttons at the default setting.  The value of 'top' will place the buttons at the top, 'bottom' will place them at the bottom, and None will turn off the buttons. 
 57          @type button_placement:     str or None 
 58          """ 
 59   
 60           
 61          self.gui = gui 
 62          self.parent = parent 
 63          self.proportion = proportion 
 64   
 65           
 66          self.title = "" 
 67          self.spacing = 5 
 68          self.border = 5 
 69          self.observer_base_name = None 
 70          self.columns = [] 
 71          self.button_placement = None 
 72          self.button_size = (120, 40) 
 73          self.button_spacing = 5 
 74          self.button_info = [] 
 75          self.popup_menus = [] 
 76   
 77           
 78          self.setup() 
 79   
 80           
 81          if button_placement != 'default': 
 82              self.button_placement = button_placement 
 83   
 84           
 85          self.panel = wx.Panel(self.parent) 
 86          box.Add(self.panel, self.proportion, wx.ALL|wx.EXPAND, 0) 
 87   
 88           
 89          panel_sizer = wx.BoxSizer(wx.VERTICAL) 
 90          self.panel.SetSizer(panel_sizer) 
 91   
 92           
 93          self.data_box = wx.StaticBox(self.panel, -1) 
 94          self.set_box_label() 
 95          self.data_box.SetFont(font.subtitle) 
 96          sub_sizer = wx.StaticBoxSizer(self.data_box, wx.VERTICAL) 
 97   
 98           
 99          panel_sizer.Add(sub_sizer, self.proportion, wx.ALL|wx.EXPAND, 0) 
100   
101           
102          box_centre = add_border(sub_sizer, border=self.border) 
103   
104           
105          if self.button_placement == 'top': 
106              self.add_buttons(box_centre) 
107              box_centre.AddSpacer(self.spacing) 
108   
109           
110          self.init_element(box_centre) 
111   
112           
113          self.build_element() 
114   
115           
116          if self.button_placement == 'bottom': 
117              box_centre.AddSpacer(self.spacing) 
118              self.add_buttons(box_centre) 
119   
120           
121          if self.observer_base_name: 
122              self.name = '%s: %s' % (self.observer_base_name, id) 
123          else: 
124              self.name = id 
125   
126           
127          self.observer_register() 
 128   
129   
130 -    def Enable(self, enable=True): 
 131          """Enable or disable the element. 
132   
133          @keyword enable:    The flag specifying if the element should be enabled or disabled. 
134          @type enable:       bool 
135          """ 
136   
137           
138          for i in range(len(self.button_info)): 
139               
140              button = getattr(self, self.button_info[i]['object']) 
141   
142               
143              button.Enable(enable) 
 144   
145   
182   
183   
193   
194   
196          """Build the spectra listing GUI element in a thread safe wx.CallAfter call.""" 
197   
198           
199          self.element.Freeze() 
200   
201           
202          self.set_box_label() 
203   
204           
205          self.element.DeleteAllItems() 
206   
207           
208          self.update_data() 
209   
210           
211          self.size_cols() 
212   
213           
214          event = wx.PyCommandEvent(wx.EVT_SIZE.typeId, self.parent.GetId()) 
215          wx.PostEvent(self.parent.GetEventHandler(), event) 
216   
217           
218          if not self.proportion: 
219               
220              n = self.element.GetItemCount() 
221   
222               
223              head = self.height_char + 10 
224   
225               
226              centre = (self.height_char + 6) * n  
227   
228               
229              foot = wx.SystemSettings_GetMetric(wx.SYS_HSCROLL_Y) 
230   
231               
232              height = head + centre + foot 
233   
234               
235              self.element.SetMinSize((-1, height)) 
236              self.element.Layout() 
237   
238           
239          self.element.Thaw() 
 240   
241   
252   
253   
255          """Create and return the popup menu. 
256   
257          @keyword id:    The ID string for the row that was clicked on. 
258          @type id:       str 
259          @return:        The popup menu. 
260          @rtype:         list of dict of wxID, str, str, method 
261          """ 
262   
263           
264          return self.popup_menus 
 265   
266   
268          """Initialise the GUI element. 
269   
270          @param sizer:   The sizer element to pack the element into. 
271          @type sizer:    wx.BoxSizer instance 
272          """ 
273   
274           
275          self.element = wx.ListCtrl(self.panel, -1, style=wx.BORDER_SUNKEN|wx.LC_REPORT) 
276   
277           
278          for i in range(len(self.columns)): 
279              self.element.InsertColumn(i, str_to_gui(self.columns[i])) 
280   
281           
282          self.element.SetFont(font.normal) 
283   
284           
285          self.height_char = self.element.GetCharHeight() 
286   
287           
288          self.element.Bind(wx.EVT_SIZE, self.resize) 
289          self.element.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.on_right_click)   
290          self.element.Bind(wx.EVT_RIGHT_UP, self.on_right_click)    
291   
292           
293          sizer.Add(self.element, self.proportion, wx.ALL|wx.EXPAND, 0) 
 294   
295   
297          """Base method which always returns True. 
298   
299          @return:    The answer to the question. 
300          @rtype:     bool 
301          """ 
302   
303           
304          return True 
 305   
306   
308          """Register and unregister methods with the observer objects. 
309   
310          @keyword remove:    If set to True, then the methods will be unregistered. 
311          @type remove:       False 
312          """ 
313   
314           
315          if not remove: 
316              status.observers.gui_uf.register(self.name, self.build_element, method_name='build_element') 
317              status.observers.pipe_alteration.register(self.name, self.build_element, method_name='build_element') 
318   
319           
320          else: 
321              status.observers.gui_uf.unregister(self.name) 
322              status.observers.pipe_alteration.unregister(self.name) 
 323   
324   
326          """Pop up menu for the right click. 
327   
328          @param event:   The wx event. 
329          @type event:    wx event 
330          """ 
331   
332           
333          pos = event.GetPosition() 
334   
335           
336          wx.Yield() 
337   
338           
339          item, flags = self.element.HitTest(pos) 
340   
341           
342          id = None 
343          if item != -1: 
344              id = self.element.GetItemText(item) 
345   
346           
347          popup_menus = self.generate_popup_menu(id=id) 
348   
349           
350          if popup_menus == []: 
351              return 
352   
353           
354          if status.exec_lock.locked(): 
355              return 
356   
357           
358          menu = wx.Menu() 
359   
360           
361          for i in range(len(popup_menus)): 
362               
363              info = popup_menus[i] 
364   
365               
366              menu.AppendItem(build_menu_item(menu, id=info['id'], text=info['text'], icon=info['icon'])) 
367   
368               
369              self.element.Bind(wx.EVT_MENU, info['method'], id=info['id']) 
370   
371           
372          if status.show_gui: 
373              self.element.PopupMenu(menu) 
374   
375           
376          menu.Destroy() 
 377   
378   
380          """Catch the resize to allow the element to be resized. 
381   
382          @param event:   The wx event. 
383          @type event:    wx event 
384          """ 
385   
386           
387          self.size_cols() 
388   
389           
390          event.Skip() 
 391   
392   
394          """Set the label of the StaticBox.""" 
395   
396           
397          self.data_box.SetLabel(self.title) 
 398   
399   
401          """Set the column sizes.""" 
402   
403           
404          x, y = self.element.GetSize() 
405   
406           
407          n = self.element.GetColumnCount() 
408   
409           
410          if n == 0: 
411              width = x 
412          else: 
413              width = int(x / n) 
414   
415           
416          for i in range(n): 
417              self.element.SetColumnWidth(i, width) 
  418