1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22   
 23  """Module containing a set of special GUI elements to be used in the relax wizards.""" 
 24   
 25   
 26  import wx 
 27  import wx.lib.mixins.listctrl 
 28   
 29   
 30  from gui.input_elements.sequence import Sequence, Sequence_list_ctrl, Sequence_window 
 31  from gui.string_conv import int_to_gui 
 32  from lib.check_types import is_list_of_lists 
 33  from status import Status; status = Status() 
 34   
 35   
 37      """Wizard GUI element for the input of all types of 2D Python sequence objects. 
 38   
 39      The supported Python types include: 
 40          - list of floats 
 41          - list of integers 
 42          - list of strings 
 43          - tuple of floats 
 44          - tuple of integers 
 45          - tuple of strings 
 46      """ 
 47   
 48 -    def __init__(self, name=None, default=None, parent=None, sizer=None, element_type='default', seq_type=None, value_type=None, dim=None, min=0, max=1000, titles=None, desc=None, combo_choices=None, combo_data=None, combo_list_min=None, tooltip=None, divider=None, padding=0, spacer=None, height_element=27, read_only=False, can_be_none=False): 
  49          """Set up the element. 
 50   
 51          @keyword name:              The name of the element to use in titles, etc. 
 52          @type name:                 str 
 53          @keyword default:           The default value of the element. 
 54          @type default:              2D sequence object 
 55          @keyword parent:            The wizard GUI element. 
 56          @type parent:               wx.Panel instance 
 57          @keyword sizer:             The sizer to put the input field widget into. 
 58          @type sizer:                wx.Sizer instance 
 59          @keyword element_type:      The type of GUI element to create.  If set to 'default', the wx.TextCtrl element with a button to bring up a dialog with ListCtrl will be used.  If set to 'combo_list', the special gui.components.combo_list.Combo_list element will be used. 
 60          @type element_type:         str 
 61          @keyword seq_type:          The type of Python sequence.  This should be one of 'list' or 'tuple'. 
 62          @type seq_type:             str 
 63          @keyword value_type:        The type of Python object that the value should be.  This can be one of 'float', 'int', or 'str'. 
 64          @type value_type:           str 
 65          @keyword dim:               The dimensions that a list or tuple must conform to.  For a 1D sequence, this can be a single value or a tuple of possible sizes.  For a 2D sequence (a numpy matrix or list of lists), this must be a tuple of the fixed dimension sizes, e.g. a 3x5 matrix should be specified as (3, 5). 
 66          @type dim:                  int, tuple of int or None 
 67          @keyword min:               For a SpinCtrl, the minimum value allowed. 
 68          @type min:                  int 
 69          @keyword max:               For a SpinCtrl, the maximum value allowed. 
 70          @type max:                  int 
 71          @keyword titles:            The titles of each of the elements of the fixed width second dimension. 
 72          @type titles:               list of str 
 73          @keyword desc:              The text description. 
 74          @type desc:                 str 
 75          @keyword combo_choices:     The list of choices to present to the user.  This is only used if the element_type is set to 'combo'. 
 76          @type combo_choices:        list of str 
 77          @keyword combo_data:        The data returned by a call to GetValue().  This is only used if the element_type is set to 'combo'.  If supplied, it should be the same length at the combo_choices list.  If not supplied, the combo_choices list will be used for the returned data. 
 78          @type combo_data:           list 
 79          @keyword combo_list_min:    The minimum length for the Combo_list object. 
 80          @type combo_list_min:       int or None 
 81          @keyword tooltip:           The tooltip which appears on hovering over the text or input field. 
 82          @type tooltip:              str 
 83          @keyword divider:           The optional position of the divider.  If None, the class variable _div_left will be used. 
 84          @type divider:              None or int 
 85          @keyword padding:           Spacing to the left and right of the widgets. 
 86          @type padding:              int 
 87          @keyword spacer:            The amount of spacing to add below the field in pixels.  If None, a stretchable spacer will be used. 
 88          @type spacer:               None or int 
 89          @keyword height_element:    The height in pixels of the GUI element. 
 90          @type height_element:       int 
 91          @keyword read_only:         A flag which if True means that the text of the element cannot be edited. 
 92          @type read_only:            bool 
 93          @keyword can_be_none:       A flag which specifies if the element is allowed to have the None value. 
 94          @type can_be_none:          bool 
 95          """ 
 96   
 97           
 98          self.titles = titles 
 99   
100           
101          Sequence.__init__(self, name=name, default=default, parent=parent, sizer=sizer, element_type=element_type, seq_type=seq_type, value_type=value_type, dim=dim, min=min, max=max, titles=titles, desc=desc, combo_choices=combo_choices, combo_data=combo_data, combo_list_min=combo_list_min, tooltip=tooltip, divider=divider, padding=padding, spacer=spacer, height_element=height_element, read_only=read_only, can_be_none=can_be_none) 
 102   
103   
105          """Open a special dialog for inputting a list of text values. 
106   
107          @param event:   The wx event. 
108          @type event:    wx event 
109          """ 
110   
111           
112          self.selection_win_show() 
113   
114           
115          self.selection_win_data() 
116   
117           
118          self.sel_win.Destroy() 
119          del self.sel_win 
 120   
121   
123          """Show the selection window.""" 
124   
125           
126          if hasattr(self, 'sel_win'): 
127              self.sel_win.Destroy() 
128              del self.sel_win 
129   
130           
131          self.sel_win = Sequence_window_2D(name=self.name, seq_type=self.seq_type, value_type=self.value_type, titles=self.titles, dim=self.dim) 
132   
133           
134          self.sel_win.SetValue(self.GetValue()) 
135   
136           
137          if status.show_gui: 
138              self.sel_win.ShowModal() 
139              self.sel_win.Close() 
  140   
141   
142   
144      """The Python 2D sequence object editor window.""" 
145   
146 -    def __init__(self, name='', seq_type='list', value_type='str', dim=None, titles=None): 
 147          """Set up the string list editor window. 
148   
149          @keyword name:          The name of the window. 
150          @type name:             str 
151          @keyword seq_type:      The type of Python sequence.  This should be one of 'list' or 'tuple'. 
152          @type seq_type:         str 
153          @keyword value_type:    The type of Python data expected in the sequence.  This should be one of 'float', 'int', or 'str'. 
154          @type value_type:       str 
155          @keyword dim:           The fixed dimensions that the sequence must conform to. 
156          @type dim:              tuple of int or None 
157          @keyword titles:        The titles of each of the elements of the fixed width second dimension.  If the dim argument is given, the length of this list must match the second number. 
158          @type titles:           list of str 
159          """ 
160   
161           
162          self.titles = titles 
163          if titles == None: 
164              if dim == None: 
165                  self.titles = [wx.EmptyString] 
166              else: 
167                  self.titles = [wx.EmptyString] * dim[1] 
168   
169           
170          if dim == None: 
171              dim = (None, len(self.titles)) 
172   
173           
174          self.variable_length = False 
175          self.offset = 0 
176          if dim[0] == None: 
177              self.variable_length = True 
178              self.offset = 1 
179   
180           
181          Sequence_window.__init__(self, name=name, seq_type=seq_type, value_type=value_type, dim=dim, titles=self.titles) 
 182   
183   
185          """Return the values as a 2D sequence of values. 
186   
187          @return:    The list of lists of values. 
188          @rtype:     list of lists of str or None 
189          """ 
190   
191           
192          values = [] 
193   
194           
195          for i in range(self.sequence.GetItemCount()): 
196               
197              values.append([]) 
198   
199               
200              for j in range(self.dim[1]): 
201                   
202                  item = self.sequence.GetItem(i, j+self.offset) 
203   
204                   
205                  try: 
206                      value = self.convert_from_gui(item.GetText()) 
207                  except: 
208                      value = None 
209                  values[-1].append(value) 
210   
211               
212              if self.seq_type == 'tuple': 
213                  values[-1] = tuple(values[-1]) 
214   
215           
216          if self.seq_type == 'tuple': 
217              values = tuple(values) 
218   
219           
220          empty = True 
221          for i in range(len(values)): 
222              for j in range(len(values[i])): 
223                  if values[i][j] != None: 
224                      empty = False 
225                      break 
226   
227           
228          if empty: 
229              return None 
230   
231           
232          return values 
 233   
234   
236          """Set up the list of lists values. 
237   
238          @param values:  The list of lists of values to add to the list. 
239          @type values:   list of lists of str or None 
240          """ 
241   
242           
243          if values == None: 
244              return 
245   
246           
247          if not is_list_of_lists(values): 
248              return 
249   
250           
251          for i in range(len(values)): 
252               
253              if self.variable_length and i != 0: 
254                  self.sequence.InsertStringItem(i, int_to_gui(i+1)) 
255   
256               
257              for j in range(self.dim[1]): 
258                   
259                  self.sequence.SetStringItem(i, j+self.offset, self.convert_to_gui(values[i][j])) 
260   
261           
262          self.Refresh() 
 263   
264   
266          """Set up the list control. 
267   
268          @param sizer:   A sizer object. 
269          @type sizer:    wx.Sizer instance 
270          """ 
271   
272           
273          self.sequence = Sequence_list_ctrl(self) 
274   
275           
276          title = "%s%s" % (self.name[0].upper(), self.name[1:]) 
277   
278           
279          index_width = 0 
280          if self.variable_length: 
281              index_width = 70 
282              self.sequence.InsertColumn(0, "Number") 
283              self.sequence.SetColumnWidth(0, index_width) 
284   
285           
286          for i in range(self.dim[1]): 
287              self.sequence.InsertColumn(i+self.offset, self.titles[i]) 
288              self.sequence.SetColumnWidth(i+self.offset, (self.width - index_width)/self.dim[1]) 
289   
290           
291          sizer.Add(self.sequence, 1, wx.ALL|wx.EXPAND, 0) 
292   
293           
294          if not self.variable_length: 
295              for i in range(self.dim[0]): 
296                  self.add_element(None) 
  297