"Fossies" - the Fresh Open Source Software Archive

Member "relax-5.0.0/gui/input_elements/sequence_2D.py" (2 Dec 2019, 13810 Bytes) of package /linux/privat/relax-5.0.0.src.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "sequence_2D.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.1.3_vs_5.0.0.

    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, (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)