Package gui :: Package input_elements :: Module sequence_2D
[hide private]
[frames] | no frames]

Source Code for Module gui.input_elements.sequence_2D

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2012,2014,2019 Edward d'Auvergne                              # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """Module containing a set of special GUI elements to be used in the relax wizards.""" 
 24   
 25  # Python module imports. 
 26  import wx 
 27  import wx.lib.mixins.listctrl 
 28   
 29  # relax module imports. 
 30  import dep_check 
 31  from gui.input_elements.sequence import Sequence, Sequence_list_ctrl, Sequence_window 
 32  from gui.string_conv import int_to_gui 
 33  from lib.check_types import is_list, is_list_of_lists 
 34  from status import Status; status = Status() 
 35   
 36   
37 -class Sequence_2D(Sequence):
38 """Wizard GUI element for the input of all types of 2D Python sequence objects. 39 40 The supported Python types include: 41 - list of floats 42 - list of integers 43 - list of strings 44 - tuple of floats 45 - tuple of integers 46 - tuple of strings 47 """ 48
49 - 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):
50 """Set up the element. 51 52 @keyword name: The name of the element to use in titles, etc. 53 @type name: str 54 @keyword default: The default value of the element. 55 @type default: 2D sequence object 56 @keyword parent: The wizard GUI element. 57 @type parent: wx.Panel instance 58 @keyword sizer: The sizer to put the input field widget into. 59 @type sizer: wx.Sizer instance 60 @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. 61 @type element_type: str 62 @keyword seq_type: The type of Python sequence. This should be one of 'list' or 'tuple'. 63 @type seq_type: str 64 @keyword value_type: The type of Python object that the value should be. This can be one of 'float', 'int', or 'str'. 65 @type value_type: str 66 @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). 67 @type dim: int, tuple of int or None 68 @keyword min: For a SpinCtrl, the minimum value allowed. 69 @type min: int 70 @keyword max: For a SpinCtrl, the maximum value allowed. 71 @type max: int 72 @keyword titles: The titles of each of the elements of the fixed width second dimension. 73 @type titles: list of str 74 @keyword desc: The text description. 75 @type desc: str 76 @keyword combo_choices: The list of choices to present to the user. This is only used if the element_type is set to 'combo'. 77 @type combo_choices: list of str 78 @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. 79 @type combo_data: list 80 @keyword combo_list_min: The minimum length for the Combo_list object. 81 @type combo_list_min: int or None 82 @keyword tooltip: The tooltip which appears on hovering over the text or input field. 83 @type tooltip: str 84 @keyword divider: The optional position of the divider. If None, the class variable _div_left will be used. 85 @type divider: None or int 86 @keyword padding: Spacing to the left and right of the widgets. 87 @type padding: int 88 @keyword spacer: The amount of spacing to add below the field in pixels. If None, a stretchable spacer will be used. 89 @type spacer: None or int 90 @keyword height_element: The height in pixels of the GUI element. 91 @type height_element: int 92 @keyword read_only: A flag which if True means that the text of the element cannot be edited. 93 @type read_only: bool 94 @keyword can_be_none: A flag which specifies if the element is allowed to have the None value. 95 @type can_be_none: bool 96 """ 97 98 # Store some of the args. 99 self.titles = titles 100 101 # Initialise the base class. 102 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)
103 104
105 - def open_dialog(self, event):
106 """Open a special dialog for inputting a list of text values. 107 108 @param event: The wx event. 109 @type event: wx event 110 """ 111 112 # Show the window. 113 self.selection_win_show() 114 115 # Extract the data from the selection window once closed. 116 self.selection_win_data() 117 118 # Destroy the window. 119 self.sel_win.Destroy() 120 del self.sel_win
121 122
123 - def selection_win_show(self):
124 """Show the selection window.""" 125 126 # Destroy any pre-existing sequence window. 127 if hasattr(self, 'sel_win'): 128 self.sel_win.Destroy() 129 del self.sel_win 130 131 # Initialise the window. 132 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) 133 134 # Set the values. 135 self.sel_win.SetValue(self.GetValue()) 136 137 # Show the window. 138 if status.show_gui: 139 self.sel_win.ShowModal() 140 self.sel_win.Close()
141 142 143
144 -class Sequence_window_2D(Sequence_window):
145 """The Python 2D sequence object editor window.""" 146
147 - def __init__(self, name='', seq_type='list', value_type='str', dim=None, titles=None):
148 """Set up the string list editor window. 149 150 @keyword name: The name of the window. 151 @type name: str 152 @keyword seq_type: The type of Python sequence. This should be one of 'list' or 'tuple'. 153 @type seq_type: str 154 @keyword value_type: The type of Python data expected in the sequence. This should be one of 'float', 'int', or 'str'. 155 @type value_type: str 156 @keyword dim: The fixed dimensions that the sequence must conform to. 157 @type dim: tuple of int or None 158 @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. 159 @type titles: list of str 160 """ 161 162 # Store the titles. 163 self.titles = titles 164 if titles == None: 165 if dim == None: 166 self.titles = [wx.EmptyString] 167 else: 168 self.titles = [wx.EmptyString] * dim[1] 169 170 # Determine the dimensions if not given. 171 if dim == None: 172 dim = (None, len(self.titles)) 173 174 # Variable length. 175 self.variable_length = False 176 self.offset = 0 177 if dim[0] == None: 178 self.variable_length = True 179 self.offset = 1 180 181 # Initialise the base class. 182 Sequence_window.__init__(self, name=name, seq_type=seq_type, value_type=value_type, dim=dim, titles=self.titles)
183 184
185 - def GetValue(self):
186 """Return the values as a 2D sequence of values. 187 188 @return: The list of lists of values. 189 @rtype: list of lists of str or None 190 """ 191 192 # Init. 193 values = [] 194 195 # Loop over the entries. 196 for i in range(self.sequence.GetItemCount()): 197 # Append a new list. 198 values.append([]) 199 200 # Loop over the items. 201 for j in range(self.dim[1]): 202 # The item. 203 item = self.sequence.GetItem(i, j+self.offset) 204 205 # Append the value. 206 try: 207 value = self.convert_from_gui(item.GetText()) 208 except: 209 value = None 210 values[-1].append(value) 211 212 # Sequence conversion. 213 if self.seq_type == 'tuple': 214 values[-1] = tuple(values[-1]) 215 216 # Sequence conversion. 217 if self.seq_type == 'tuple': 218 values = tuple(values) 219 220 # Check that something is set. 221 empty = True 222 for i in range(len(values)): 223 for j in range(len(values[i])): 224 if values[i][j] != None: 225 empty = False 226 break 227 228 # Return nothing. 229 if empty: 230 return None 231 232 # Return the list. 233 return values
234 235
236 - def SetValue(self, values):
237 """Set up the list of lists values. 238 239 @param values: The list of lists of values to add to the list. 240 @type values: list of lists of str or None 241 """ 242 243 # No value. 244 if values == None: 245 return 246 247 # Convert to a list of lists if needed. 248 if is_list_of_lists(values): 249 pass 250 elif is_list(values): 251 values = [values] 252 253 # Not a list of lists. 254 if not is_list_of_lists(values): 255 return 256 257 # Incorrect dimensions. 258 if self.dim[0] != None and len(values) != self.dim[0]: 259 return 260 261 # Loop over the entries. 262 for i in range(len(values)): 263 # Incorrect dimensions. 264 if self.dim[1] != None and len(values[i]) != self.dim[1]: 265 continue 266 267 # Append a row for variable dimension sequences (the first element already exists). 268 if self.variable_length and i != 0: 269 if dep_check.wx_classic: 270 self.sequence.InsertStringItem(i, int_to_gui(i+1)) 271 else: 272 self.sequence.InsertItem(i, int_to_gui(i+1)) 273 274 # Loop over the values. 275 for j in range(self.dim[1]): 276 # Set the value. 277 if dep_check.wx_classic: 278 self.sequence.SetStringItem(i, j+self.offset, self.convert_to_gui(values[i][j])) 279 else: 280 self.sequence.SetItem(i, j+self.offset, self.convert_to_gui(values[i][j])) 281 282 # Refresh. 283 self.Refresh()
284 285
286 - def add_list(self, sizer):
287 """Set up the list control. 288 289 @param sizer: A sizer object. 290 @type sizer: wx.Sizer instance 291 """ 292 293 # The control. 294 self.sequence = Sequence_list_ctrl(self) 295 296 # Set the column title. 297 title = "%s%s" % (self.name[0].upper(), self.name[1:]) 298 299 # Add a column for the indices. 300 index_width = 0 301 if self.variable_length: 302 index_width = 70 303 self.sequence.InsertColumn(0, "Number") 304 self.sequence.SetColumnWidth(0, index_width) 305 306 # Add the columns. 307 for i in range(self.dim[1]): 308 self.sequence.InsertColumn(i+self.offset, self.titles[i]) 309 self.sequence.SetColumnWidth(i+self.offset, int((self.width - index_width)/self.dim[1])) 310 311 # Add the table to the sizer. 312 sizer.Add(self.sequence, 1, wx.ALL|wx.EXPAND, 0) 313 314 # The fixed dimension sequence - add all the rows needed. 315 if not self.variable_length: 316 for i in range(self.dim[0]): 317 self.add_element(None)
318