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

Source Code for Module gui.input_elements.sequence

  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 graphics import fetch_icon 
 32  from gui.input_elements.combo_list import Combo_list 
 33  from gui.fonts import font 
 34  from gui.misc import add_border 
 35  from gui.string_conv import float_to_gui, gui_to_float, gui_to_int, gui_to_list, gui_to_py, gui_to_str, gui_to_tuple, int_to_gui, list_to_gui, py_to_gui, str_to_gui, tuple_to_gui 
 36  from lib.check_types import is_list 
 37  from lib.errors import RelaxError 
 38  from status import Status; status = Status() 
 39   
 40   
41 -class Sequence:
42 """Wizard GUI element for the input of all types of Python sequence objects. 43 44 The supported Python types include: 45 - list of floats 46 - list of integers 47 - list of strings 48 - tuple of floats 49 - tuple of integers 50 - tuple of strings 51 """ 52
53 - def __init__(self, name=None, default=None, parent=None, element_type='default', seq_type=None, value_type=None, dim=None, min=0, max=1000, sizer=None, 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, single_value=False, read_only=False, can_be_none=False):
54 """Set up the element. 55 56 @keyword name: The name of the element to use in titles, etc. 57 @type name: str 58 @keyword default: The default value of the element. 59 @type default: sequence object 60 @keyword parent: The wizard GUI element. 61 @type parent: wx.Panel instance 62 @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. 63 @type element_type: str 64 @keyword seq_type: The type of Python sequence. This should be one of 'list' or 'tuple'. 65 @type seq_type: str 66 @keyword value_type: The type of Python object that the value should be. This can be one of 'float', 'int', or 'str'. 67 @type value_type: str 68 @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). 69 @type dim: int, tuple of int or None 70 @keyword min: For a SpinCtrl, the minimum value allowed. 71 @type min: int 72 @keyword max: For a SpinCtrl, the maximum value allowed. 73 @type max: int 74 @keyword sizer: The sizer to put the input field widget into. 75 @type sizer: wx.Sizer instance 76 @keyword titles: The titles of each of the elements of the fixed dimension elements. 77 @type titles: list of str 78 @keyword desc: The text description. 79 @type desc: str 80 @keyword combo_choices: The list of choices to present to the user. This is only used if the element_type is set to 'combo'. 81 @type combo_choices: list of str 82 @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. 83 @type combo_data: list 84 @keyword combo_list_min: The minimum length for the Combo_list object. 85 @type combo_list_min: int or None 86 @keyword tooltip: The tooltip which appears on hovering over the text or input field. 87 @type tooltip: str 88 @keyword divider: The position of the divider. 89 @type divider: int 90 @keyword padding: Spacing to the left and right of the widgets. 91 @type padding: int 92 @keyword spacer: The amount of spacing to add below the field in pixels. If None, a stretchable spacer will be used. 93 @type spacer: None or int 94 @keyword height_element: The height in pixels of the GUI element. 95 @type height_element: int 96 @keyword single_value: A flag which if True will cause single input values to be treated as single values rather than a list or tuple. 97 @type single_value: bool 98 @keyword read_only: A flag which if True means that the text of the element cannot be edited. 99 @type read_only: bool 100 @keyword can_be_none: A flag which specifies if the element is allowed to have the None value. 101 @type can_be_none: bool 102 """ 103 104 # Store the args. 105 self.parent = parent 106 self.name = name 107 self.default = default 108 self.element_type = element_type 109 self.seq_type = seq_type 110 self.value_type = value_type 111 self.dim = dim 112 self.min = min 113 self.max = max 114 self.titles = titles 115 self.single_value = single_value 116 self.can_be_none = can_be_none 117 118 # The base types. 119 if value_type in ['float', 'num']: 120 self.convert_from_gui = gui_to_float 121 self.convert_to_gui = float_to_gui 122 elif value_type == 'int': 123 self.convert_from_gui = gui_to_int 124 self.convert_to_gui = int_to_gui 125 elif value_type == 'str': 126 self.convert_from_gui = gui_to_str 127 self.convert_to_gui = str_to_gui 128 else: 129 self.convert_from_gui = gui_to_py 130 self.convert_to_gui = py_to_gui 131 132 # The sequence types. 133 if seq_type == 'list': 134 self.convert_from_gui_seq = gui_to_list 135 self.convert_to_gui_seq = list_to_gui 136 elif seq_type == 'tuple': 137 self.convert_from_gui_seq = gui_to_tuple 138 self.convert_to_gui_seq = tuple_to_gui 139 else: 140 raise RelaxError("Unknown sequence type '%s'." % seq_type) 141 142 # Initialise the default element. 143 if self.element_type == 'default': 144 # Translate the read_only flag if None. 145 if read_only == None: 146 read_only = False 147 148 # Init. 149 sub_sizer = wx.BoxSizer(wx.HORIZONTAL) 150 151 # Left padding. 152 sub_sizer.AddSpacer(padding) 153 154 # The description. 155 text = wx.StaticText(parent, -1, desc, style=wx.ALIGN_LEFT) 156 text.SetFont(font.normal) 157 sub_sizer.Add(text, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 0) 158 159 # The divider. 160 if not divider: 161 raise RelaxError("The divider position has not been supplied.") 162 163 # Spacing. 164 dc = wx.ScreenDC() 165 dc.SetFont(font.normal) 166 x, y = dc.GetTextExtent(desc) 167 if dep_check.wx_classic: 168 sub_sizer.AddSpacer((divider - x, 0)) 169 else: 170 sub_sizer.AddSpacer(int(divider - x)) 171 172 # The input field. 173 self._field = wx.TextCtrl(parent, -1, '') 174 self._field.SetMinSize((50, height_element)) 175 self._field.SetFont(font.normal) 176 sub_sizer.Add(self._field, 1, wx.ADJUST_MINSIZE|wx.ALIGN_CENTER_VERTICAL, 0) 177 178 # Read-only. 179 if read_only: 180 self._field.SetEditable(False) 181 colour = parent.GetBackgroundColour() 182 self._field.SetOwnBackgroundColour(colour) 183 184 # A little spacing. 185 sub_sizer.AddSpacer(5) 186 187 # The edit button. 188 button = wx.BitmapButton(parent, -1, wx.Bitmap(fetch_icon('oxygen.actions.edit-rename', "16x16"), wx.BITMAP_TYPE_ANY)) 189 button.SetMinSize((-1, height_element)) 190 button.SetToolTip(wx.ToolTip("Edit the values.")) 191 sub_sizer.Add(button, 0, wx.ADJUST_MINSIZE|wx.ALIGN_CENTER_VERTICAL, 0) 192 parent.Bind(wx.EVT_BUTTON, self.open_dialog, button) 193 194 # Right padding. 195 sub_sizer.AddSpacer(padding) 196 197 # Add to the main sizer. 198 sizer.Add(sub_sizer, 1, wx.EXPAND|wx.ALL, 0) 199 200 # Spacing below the widget. 201 if spacer == None: 202 sizer.AddStretchSpacer() 203 else: 204 sizer.AddSpacer(spacer) 205 206 # Tooltip. 207 if tooltip: 208 text.SetToolTip(wx.ToolTip(tooltip)) 209 self._field.SetToolTip(wx.ToolTip(tooltip)) 210 211 # Set the default value. 212 if self.default is not None: 213 self._field.SetValue(self.convert_to_gui_seq(self.default)) 214 215 # Initialise the combo list input field. 216 elif self.element_type == 'combo_list': 217 # Translate the read_only flag if None. 218 if read_only == None: 219 read_only = False 220 221 # Correct the min_length argument. 222 if combo_list_min == None: 223 combo_list_min = 1 224 225 # Set up the Combo_list object. 226 self._field = Combo_list(parent, sizer, desc, value_type=value_type, min_length=combo_list_min, choices=combo_choices, data=combo_data, default=default, tooltip=tooltip, read_only=read_only, can_be_none=can_be_none) 227 228 # Unknown field. 229 else: 230 raise RelaxError("Unknown element type '%s'." % self.element_type)
231 232
233 - def Clear(self):
234 """Special method for clearing or resetting the GUI element.""" 235 236 # Clear the value from a TextCtrl or ComboBox. 237 if self.element_type in ['default', 'combo_list']: 238 self._field.Clear()
239 240
241 - def GetValue(self):
242 """Special method for returning the sequence values of the GUI element. 243 244 @return: The sequence of values. 245 @rtype: sequence type 246 """ 247 248 # The value. 249 value = self._field.GetValue() 250 251 # Handle Combo_list elements. 252 if self.element_type == 'combo_list': 253 # Empty lists. 254 if value == [] or value == None: 255 return None 256 257 # Non Combo_list elements. 258 else: 259 # Handle single values. 260 value_set = False 261 if self.single_value: 262 try: 263 # Convert. 264 value = self.convert_from_gui(value) 265 266 # Check that the conversion was successful. 267 if value == None and self.can_be_none: 268 value_set = True 269 elif self.value_type == None: 270 value_set = True 271 elif self.value_type in ['float', 'num']: 272 if isinstance(value, int) or isinstance(value, float): 273 value_set = True 274 elif self.value_type == 'int': 275 if isinstance(value, int): 276 value_set = True 277 elif self.value_type == 'str': 278 if self.seq_type == 'list' and value[0] != '[': 279 value_set = True 280 elif self.seq_type == 'tuple' and value[0] != '(': 281 value_set = True 282 except: 283 pass 284 285 # Convert to a sequence, handling bad user behaviour. 286 if not value_set: 287 try: 288 value = self.convert_from_gui_seq(value) 289 290 # Set the value to None or an empty sequence. 291 except RelaxError: 292 if self.can_be_none: 293 value = None 294 elif self.seq_type == 'list': 295 value = [] 296 else: 297 value = () 298 299 # Handle all other errors. 300 except: 301 value = None 302 303 # Nothing to do. 304 if value == None: 305 return None 306 307 # Convert sequences to single values as needed. 308 if self.single_value: 309 if (isinstance(value, list) or isinstance(value, tuple)) and len(value) == 1: 310 value = value[0] 311 312 # Convert single values to sequences as needed. 313 elif value != None: 314 if self.seq_type == 'list' and not isinstance(value, list): 315 value = [value] 316 elif self.seq_type == 'tuple' and not isinstance(value, tuple): 317 value = (value,) 318 319 # Handle empty list and tuple values. 320 if not self.single_value and len(value) == 0: 321 return None 322 323 # Return the value. 324 return value
325 326
327 - def SetValue(self, value=None, index=None):
328 """Special method for setting the value of the GUI element. 329 330 @keyword value: The value to set. 331 @type value: value or list of values 332 @keyword index: The index of the value to set, if the full list is not given. 333 @type index: int or None 334 """ 335 336 # The ComboBox list. 337 if self.element_type == 'combo_list': 338 self._field.SetValue(value=value, index=index) 339 340 # The other elements. 341 else: 342 # Handle single values. 343 if self.single_value and isinstance(value, list) and len(value) == 1: 344 value = value[0] 345 346 # Convert and set the value. 347 self._field.SetValue(self.convert_to_gui_seq(value))
348 349
350 - def UpdateChoices(self, combo_choices=None, combo_data=None, combo_default=None):
351 """Special wizard method for updating the list of choices in a ComboBox type element. 352 353 @keyword combo_choices: The list of choices to present to the user. This is only used if the element_type is set to 'combo_list'. 354 @type combo_choices: list of str 355 @keyword combo_data: The data returned by a call to GetValue(). This is only used if the element_type is set to 'combo_list'. 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. 356 @type combo_data: list 357 @keyword combo_default: The default value of the ComboBox. This is only used if the element_type is set to 'combo_list'. 358 @type combo_default: str or None 359 """ 360 361 # The ComboBox list. 362 if self.element_type == 'combo_list': 363 self._field.UpdateChoices(combo_choices=combo_choices, combo_data=combo_data, combo_default=combo_default)
364 365
366 - def open_dialog(self, event):
367 """Open a special dialog for inputting a list of text values. 368 369 @param event: The wx event. 370 @type event: wx event 371 """ 372 373 # Show the window. 374 self.selection_win_show() 375 376 # Extract the data from the selection window once closed. 377 self.selection_win_data() 378 379 # Destroy the window. 380 self.sel_win.Destroy() 381 del self.sel_win
382 383
384 - def selection_win_data(self):
385 """Extract the data from the selection window.""" 386 387 # Get the value. 388 value = self.sel_win.GetValue() 389 390 # No sequence data. 391 if value == None or not len(value): 392 self.Clear() 393 394 # Set the values. 395 else: 396 self.SetValue(value)
397 398
399 - def selection_win_show(self):
400 """Show the selection window.""" 401 402 # Destroy any pre-existing sequence window. 403 if hasattr(self, 'sel_win'): 404 self.sel_win.Destroy() 405 del self.sel_win 406 407 # Initialise the model selection window. 408 self.sel_win = Sequence_window(parent=self.parent, name=self.name, seq_type=self.seq_type, value_type=self.value_type, titles=self.titles, dim=self.dim) 409 410 # Set the model selector window selections. 411 self.sel_win.SetValue(self.GetValue()) 412 413 # Show the model selector window. 414 if status.show_gui: 415 self.sel_win.ShowModal() 416 self.sel_win.Close()
417 418 419
420 -class Sequence_list_ctrl(wx.ListCtrl, wx.lib.mixins.listctrl.TextEditMixin, wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin):
421 """The string list ListCtrl object.""" 422
423 - def __init__(self, parent):
424 """Initialise the control. 425 426 @param parent: The parent window. 427 @type parent: wx.Frame instance 428 """ 429 430 # Execute the parent __init__() methods. 431 wx.ListCtrl.__init__(self, parent, -1, style=wx.BORDER_SUNKEN|wx.LC_REPORT|wx.LC_HRULES|wx.LC_VRULES) 432 wx.lib.mixins.listctrl.TextEditMixin.__init__(self) 433 wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin.__init__(self) 434 435 # Catch edits. 436 self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.begin_label_edit)
437 438
439 - def begin_label_edit(self, event):
440 """Catch edits to make the first column read only. 441 442 @param event: The wx event. 443 @type event: wx event 444 """ 445 446 # Prevent edits in the first column. 447 if event.m_col == 0: 448 event.Veto() 449 450 # Otherwise the user is free to edit. 451 else: 452 event.Skip()
453 454 455
456 -class Sequence_window(wx.Dialog):
457 """The Python sequence object editor window.""" 458 459 # The window size. 460 SIZE = (800, 600) 461 462 # A border. 463 BORDER = 10 464 465 # Sizes. 466 SIZE_BUTTON = (150, 33) 467
468 - def __init__(self, parent=None, name='', seq_type='list', value_type='str', dim=None, titles=None):
469 """Set up the string list editor window. 470 471 @keyword parent: The parent GUI element. 472 @type parent: wx.Window instance or None 473 @keyword name: The name of the window. 474 @type name: str 475 @keyword seq_type: The type of Python sequence. This should be one of 'list' or 'tuple'. 476 @type seq_type: str 477 @keyword value_type: The type of Python data expected in the sequence. This should be one of 'float', 'int', or 'str'. 478 @type value_type: str 479 @keyword dim: The fixed dimension that the sequence must conform to. 480 @type dim: int or None 481 @keyword titles: The titles of each of the elements of the fixed dimension elements. 482 @type titles: list of str 483 """ 484 485 # Store the args. 486 self.name = name 487 self.seq_type = seq_type 488 self.value_type = value_type 489 self.dim = dim 490 self.titles = titles 491 492 # The base types. 493 if value_type in ['float', 'num']: 494 self.convert_from_gui = gui_to_float 495 self.convert_to_gui = float_to_gui 496 elif value_type == 'int': 497 self.convert_from_gui = gui_to_int 498 self.convert_to_gui = int_to_gui 499 elif value_type == 'str': 500 self.convert_from_gui = gui_to_str 501 self.convert_to_gui = str_to_gui 502 else: 503 raise RelaxError("Unknown base data type '%s'." % value_type) 504 505 # Variable length. 506 if not hasattr(self, 'variable_length'): 507 self.variable_length = False 508 self.offset = 0 509 if dim == None: 510 self.variable_length = True 511 self.offset = 1 512 513 # The title of the dialog. 514 title = "Edit the %s values." % name 515 516 # Set up the dialog. 517 wx.Dialog.__init__(self, parent, id=-1, title=title) 518 519 # Initialise some values 520 self.width = self.SIZE[0] - 2*self.BORDER 521 522 # Set the frame properties. 523 self.SetSize(self.SIZE) 524 if not dep_check.wx_classic and status.show_gui: 525 self.Centre() 526 self.SetFont(font.normal) 527 528 # The main box sizer. 529 main_sizer = wx.BoxSizer(wx.VERTICAL) 530 531 # Pack the sizer into the frame. 532 self.SetSizer(main_sizer) 533 534 # Build the central sizer, with borders. 535 sizer = add_border(main_sizer, border=self.BORDER, packing=wx.VERTICAL) 536 537 # Add the list control. 538 self.add_list(sizer) 539 540 # Some spacing. 541 sizer.AddSpacer(self.BORDER) 542 543 # Add the bottom buttons. 544 self.add_buttons(sizer) 545 546 # Initialise the list of elements to a single element. 547 if not self.sequence.GetItemCount(): 548 self.add_element()
549 550
551 - def GetValue(self):
552 """Return the values as a sequence of values. 553 554 @return: The sequence of values. 555 @rtype: sequence type 556 """ 557 558 # Init. 559 values = [] 560 561 # Loop over the entries. 562 for i in range(self.sequence.GetItemCount()): 563 # Get the text. 564 item = self.sequence.GetItem(i, col=1) 565 text = item.GetText() 566 567 # Store the text. 568 try: 569 value = self.convert_from_gui(text) 570 except: 571 value = None 572 values.append(value) 573 574 # Sequence conversion. 575 if self.seq_type == 'tuple': 576 values = tuple(values) 577 578 # Check that something is set. 579 empty = True 580 for i in range(len(values)): 581 if values[i] != None: 582 empty = False 583 break 584 585 # Return nothing. 586 if empty: 587 return None 588 589 # Return the sequence. 590 return values
591 592
593 - def SetValue(self, values):
594 """Set up the list values. 595 596 @param values: The list of values to add to the list. 597 @type values: list of str or None 598 """ 599 600 # No value. 601 if values == None: 602 return 603 604 # Invalid list, so do nothing. 605 if not self.variable_length and is_list(values) and len(values) != self.dim: 606 return 607 608 # Single values. 609 try: 610 len(values) 611 except TypeError: 612 if self.seq_type == 'list': 613 values = [values] 614 elif self.seq_type == 'tuple': 615 values = (values,) 616 617 # Loop over the entries. 618 for i in range(len(values)): 619 # Fixed dimension sequences - set the values of the pre-created list. 620 if not self.variable_length: 621 if dep_check.wx_classic: 622 self.sequence.SetStringItem(i, 1, self.convert_to_gui(values[i])) 623 else: 624 self.sequence.SetItem(i, 1, self.convert_to_gui(values[i])) 625 626 # Variable dimension sequences - append the item to the end of the blank list. 627 else: 628 # The first element already exists. 629 if i != 0: 630 # First add the index+1. 631 if dep_check.wx_classic: 632 self.sequence.InsertStringItem(i, int_to_gui(i+1)) 633 else: 634 self.sequence.InsertItem(i, int_to_gui(i+1)) 635 636 # Then set the value. 637 if dep_check.wx_classic: 638 self.sequence.SetStringItem(i, 1, self.convert_to_gui(values[i])) 639 else: 640 self.sequence.SetItem(i, 1, self.convert_to_gui(values[i]))
641 642
643 - def add_buttons(self, sizer):
644 """Add the buttons to the sizer. 645 646 @param sizer: A sizer object. 647 @type sizer: wx.Sizer instance 648 """ 649 650 # Create a horizontal layout for the buttons. 651 button_sizer = wx.BoxSizer(wx.HORIZONTAL) 652 sizer.Add(button_sizer, 0, wx.ALIGN_CENTER|wx.ALL, 0) 653 654 # The non-fixed sequence buttons. 655 if self.variable_length: 656 # The add button. 657 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, " Add") 658 button.SetBitmapLabel(wx.Bitmap(fetch_icon('oxygen.actions.list-add-relax-blue', "22x22"), wx.BITMAP_TYPE_ANY)) 659 button.SetFont(font.normal) 660 button.SetToolTip(wx.ToolTip("Add an item to the list.")) 661 button.SetMinSize(self.SIZE_BUTTON) 662 button_sizer.Add(button, 0, wx.ADJUST_MINSIZE, 0) 663 self.Bind(wx.EVT_BUTTON, self.add_element, button) 664 665 # Spacer. 666 button_sizer.AddSpacer(20) 667 668 # The delete button. 669 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, " Delete") 670 button.SetBitmapLabel(wx.Bitmap(fetch_icon('oxygen.actions.list-remove', "22x22"), wx.BITMAP_TYPE_ANY)) 671 button.SetFont(font.normal) 672 button.SetToolTip(wx.ToolTip("Delete the last item.")) 673 button.SetMinSize(self.SIZE_BUTTON) 674 button_sizer.Add(button, 0, wx.ADJUST_MINSIZE, 0) 675 self.Bind(wx.EVT_BUTTON, self.delete, button) 676 677 # Spacer. 678 button_sizer.AddSpacer(20) 679 680 # The delete all button. 681 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, " Delete all") 682 button.SetBitmapLabel(wx.Bitmap(fetch_icon('oxygen.actions.edit-delete', "22x22"), wx.BITMAP_TYPE_ANY)) 683 button.SetFont(font.normal) 684 button.SetToolTip(wx.ToolTip("Delete all items.")) 685 button.SetMinSize(self.SIZE_BUTTON) 686 button_sizer.Add(button, 0, wx.ADJUST_MINSIZE, 0) 687 self.Bind(wx.EVT_BUTTON, self.delete_all, button) 688 689 # Spacer. 690 button_sizer.AddSpacer(20) 691 692 # The Ok button. 693 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, " Ok") 694 button.SetBitmapLabel(wx.Bitmap(fetch_icon('oxygen.actions.dialog-ok', "22x22"), wx.BITMAP_TYPE_ANY)) 695 button.SetFont(font.normal) 696 button.SetMinSize(self.SIZE_BUTTON) 697 button_sizer.Add(button, 0, wx.ADJUST_MINSIZE, 0) 698 self.Bind(wx.EVT_BUTTON, self.close, button)
699 700
701 - def add_element(self, event=None):
702 """Append a new row to the list. 703 704 @keyword event: The wx event. 705 @type event: wx event 706 """ 707 708 # The next index. 709 next = self.sequence.GetItemCount() 710 711 # Add a new row with the index at the start. 712 if self.variable_length: 713 if dep_check.wx_classic: 714 self.sequence.InsertStringItem(next, int_to_gui(next+1)) 715 else: 716 self.sequence.InsertItem(next, int_to_gui(next+1)) 717 718 # Add a new empty row. 719 else: 720 if dep_check.wx_classic: 721 self.sequence.InsertStringItem(next, str_to_gui('')) 722 else: 723 self.sequence.InsertItem(next, str_to_gui(''))
724 725
726 - def add_list(self, sizer):
727 """Set up the list control. 728 729 @param sizer: A sizer object. 730 @type sizer: wx.Sizer instance 731 """ 732 733 # The control. 734 self.sequence = Sequence_list_ctrl(self) 735 736 # Set the column title. 737 title = "%s%s" % (self.name[0].upper(), self.name[1:]) 738 739 # Add the index column. 740 if self.titles: 741 self.sequence.InsertColumn(0, "Title") 742 self.sequence.SetColumnWidth(0, 200) 743 else: 744 self.sequence.InsertColumn(0, "Number") 745 self.sequence.SetColumnWidth(0, 70) 746 747 # Add a single column, full width. 748 self.sequence.InsertColumn(1, title) 749 self.sequence.SetColumnWidth(1, wx.LIST_AUTOSIZE) 750 751 # Add the table to the sizer. 752 sizer.Add(self.sequence, 1, wx.ALL|wx.EXPAND, 0) 753 754 # The fixed dimension sequence - add all the rows needed. 755 if not self.variable_length: 756 for i in range(self.dim): 757 # Add a new row. 758 self.add_element() 759 760 # Add a title to the first column. 761 if self.titles: 762 if dep_check.wx_classic: 763 self.sequence.SetStringItem(i, 0, str_to_gui(self.titles[i])) 764 else: 765 self.sequence.SetItem(i, 0, str_to_gui(self.titles[i])) 766 767 # Otherwise add numbers starting from 1. 768 else: 769 if dep_check.wx_classic: 770 self.sequence.SetStringItem(i, 0, int_to_gui(i+1)) 771 else: 772 self.sequence.SetItem(i, 0, int_to_gui(i+1))
773 774
775 - def close(self, event):
776 """Close the window. 777 778 @param event: The wx event. 779 @type event: wx event 780 """ 781 782 # Close the window. 783 self.Close()
784 785
786 - def delete(self, event):
787 """Remove the last item from the list. 788 789 @param event: The wx event. 790 @type event: wx event 791 """ 792 793 # Delete the last item. 794 item = self.sequence.GetItemCount() 795 self.sequence.DeleteItem(item-1) 796 797 # If the list is empty, start again with a single blank element. 798 if not self.sequence.GetItemCount(): 799 self.add_element()
800 801
802 - def delete_all(self, event):
803 """Remove all items from the list. 804 805 @param event: The wx event. 806 @type event: wx event 807 """ 808 809 # Delete. 810 self.sequence.DeleteAllItems() 811 812 # Start again with a single blank element. 813 self.add_element()
814