Changeset 2d50115 in sasview for src/sas


Ignore:
Timestamp:
Apr 6, 2015 4:04:56 AM (10 years ago)
Author:
butler
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
7023fa5
Parents:
18ac46b
Message:

Fixed problem of scrolling window on easy custom model editor. Also
fixed several bugs and cleaned up pylint errors.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sas/perspectives/calculator/model_editor.py

    r18ac46b r2d50115  
    22This module provides three model editor classes: the composite model editor, 
    33the easy editor which provides a simple interface with tooltip help to enter 
    4 the parameters of the model and their default value and a panel to input a  
    5 function of y (usually the intensity).  It also provides a drop down of  
     4the parameters of the model and their default value and a panel to input a 
     5function of y (usually the intensity).  It also provides a drop down of 
    66standard available math functions.  Finally a full python editor panel for 
    77complete customizatin is provided. 
    88 
    9 ..TODO:: the writiong of the file and name checking (and maybe some other 
     9:TODO the writiong of the file and name checking (and maybe some other 
    1010funtions?) should be moved to a computational module which could be called 
    1111fropm a python script.  Basically one just needs to pass the name, 
    12 description text and function text (or in the case of the composite editor  
     12description text and function text (or in the case of the composite editor 
    1313the names of the first and second model and the operator to be used). 
    1414''' 
     
    7272    to choose two existing models (including pre-existing custom models which 
    7373    may themselves be composite models) as well as an operation on those models 
    74     (add or multiply) the resulting model will add a scale parameter for summed  
     74    (add or multiply) the resulting model will add a scale parameter for summed 
    7575    models and a background parameter for a multiplied model. 
    76      
    77     The user also gives a brief help for the model in a description box and  
     76 
     77    The user also gives a brief help for the model in a description box and 
    7878    must provide a unique name which is verified as unique before the new 
    7979    model is saved. 
    80      
     80 
    8181    This Dialog pops up for the user when they press 'Sum|Multi(p1,p2)' under 
    8282    'Edit Custom Model' under 'Fitting' menu.  This is currently called as 
    8383    a Modal Dialog. 
    84      
    85     ..TODO:: the build in compiler currently balks at when it tries to import 
    86     a model whose name contains spaces or symbols (such as + ... underscore  
     84 
     85    :TODO the build in compiler currently balks at when it tries to import 
     86    a model whose name contains spaces or symbols (such as + ... underscore 
    8787    should be fine).  Have fixed so the editor cannot save such a file name 
    8888    but if a file is dropped in the plugin directory from outside this class 
     
    121121        self.desc_sizer = None 
    122122        self.desc_tcl = None 
    123         self._selection_box= None 
     123        self._selection_box = None 
    124124        self.model1 = None 
    125125        self.model2 = None 
     
    147147 
    148148        #set up label and input box with tool tip and event handling 
    149         self.name_txt = wx.StaticText(self, -1, 'Function Name : ') 
    150         self.name_tcl = wx.TextCtrl(self, -1, value = 'MySumFunction') 
     149        name_txt = wx.StaticText(self, -1, 'Function Name : ') 
     150        self.name_tcl = wx.TextCtrl(self, -1, value='MySumFunction') 
    151151        self.name_tcl.Bind(wx.EVT_TEXT_ENTER, self.on_change_name) 
    152152        hint_name = "Unique Sum/Multiply Model Function Name." 
    153153        self.name_tcl.SetToolTipString(hint_name) 
    154154 
    155         self.name_sizer.AddMany([(self.name_txt, 0, wx.LEFT | wx.TOP, 10), 
    156                                 (self.name_tcl, -1, 
    157                                 wx.EXPAND | wx.RIGHT | wx.TOP | wx.BOTTOM, 10)]) 
     155        self.name_sizer.AddMany([(name_txt, 0, wx.LEFT | wx.TOP, 10), 
     156                                 (self.name_tcl, -1, 
     157                                  wx.EXPAND | wx.RIGHT | wx.TOP | wx.BOTTOM, 
     158                                  10)]) 
    158159 
    159160 
     
    185186        #First set up main sizer for the selection 
    186187        selection_box_title = wx.StaticBox(self, -1, 'Select', 
    187                                        size=(PNL_WIDTH - 30, 70)) 
    188         self._selection_box = wx.StaticBoxSizer(selection_box_title,  
     188                                           size=(PNL_WIDTH - 30, 70)) 
     189        self._selection_box = wx.StaticBoxSizer(selection_box_title, 
    189190                                                wx.VERTICAL) 
    190191 
     
    194195        select_help_box.Add(wx.StaticText(self, -1, model_string % (1, 1)), 
    195196                            0, 0) 
    196         select_help_box.Add((box_width - 25, 10),0,0) 
     197        select_help_box.Add((box_width - 25, 10), 0, 0) 
    197198        select_help_box.Add(wx.StaticText(self, -1, model_string % (2, 2)), 
    198199                            0, 0) 
     
    225226        selection_box_choose.Add(self.model2, 0, 0) 
    226227        # add some space between labels and selection 
    227         self._selection_box.Add((20,5), 0, 0) 
     228        self._selection_box.Add((20, 5), 0, 0) 
    228229        self._selection_box.Add(selection_box_choose, 0, 0) 
    229230 
     
    231232        """ 
    232233        Build GUI with calls to _layout_name, _layout Description 
    233         and _layout_model_selection which each build a their portion of the  
     234        and _layout_model_selection which each build a their portion of the 
    234235        GUI. 
    235236        """ 
     
    239240        # and adding to main sizer 
    240241        self._layout_name() 
    241         mainsizer.Add(self.name_sizer,0, wx.EXPAND) 
     242        mainsizer.Add(self.name_sizer, 0, wx.EXPAND) 
    242243        self._layout_description() 
    243         mainsizer.Add(self.desc_sizer,0, wx.EXPAND) 
     244        mainsizer.Add(self.desc_sizer, 0, wx.EXPAND) 
    244245 
    245246        # Add an explanation of dialog (short help) 
    246247        self.explanationctr = wx.StaticText(self, -1, self.explanation) 
    247248        self.fill_explanation_helpstring(self._operator) 
    248         mainsizer.Add(self.explanationctr,0, wx.LEFT | wx.EXPAND, 15) 
     249        mainsizer.Add(self.explanationctr, 0, wx.LEFT | wx.EXPAND, 15) 
    249250 
    250251        # Add the selection box stuff with border and labels built 
     
    264265        self.msg_sizer.Add(self._msg_box, 0, wx.LEFT, 0) 
    265266        mainsizer.Add(self.msg_sizer, 0, 
    266                  wx.LEFT | wx.RIGHT | wx.ADJUST_MINSIZE | wx.BOTTOM, 10) 
     267                      wx.LEFT | wx.RIGHT | wx.ADJUST_MINSIZE | wx.BOTTOM, 10) 
    267268 
    268269        # Finally add the buttons (apply and close) on the bottom 
    269         # TODO: need help added here 
     270        # Eventually need to add help here 
    270271        self.ok_button = wx.Button(self, wx.ID_OK, 'Apply') 
    271272        self.ok_button.Bind(wx.EVT_BUTTON, self.check_name) 
     
    274275        sizer_button.AddMany([((20, 20), 1, 0), 
    275276                              (self.ok_button, 0, 0), 
    276                               (self.close_button, 0, wx.LEFT | wx.RIGHT, 10)])         
     277                              (self.close_button, 0, wx.LEFT | wx.RIGHT, 10)]) 
    277278        mainsizer.Add(sizer_button, 0, wx.EXPAND | wx.BOTTOM | wx.TOP, 10) 
    278279 
     
    291292    def check_name(self, event=None): 
    292293        """ 
    293         Check that proposed new model name is a valid Python module name  
     294        Check that proposed new model name is a valid Python module name 
    294295        and that it does not already exist. If not show error message and 
    295296        pink background in text box else call on_apply 
    296          
    297         ..TODO:: this should be separated out from the GUI code.  For that we 
    298         need to pass it the name (or if we want to keep the default name  
     297 
     298        :TODO this should be separated out from the GUI code.  For that we 
     299        need to pass it the name (or if we want to keep the default name 
    299300        option also need to pass the self._operator attribute) We just need 
    300         the function to return an error code that the name is good or if  
    301         not why (not a valid name, name exists already).  The rest of the  
     301        the function to return an error code that the name is good or if 
     302        not why (not a valid name, name exists already).  The rest of the 
    302303        error handling should be done in this module. so on_apply would then 
    303304        start by checking the name and then either raise errors or do the 
     
    320321 
    321322        #First check if the name is a valid Python name 
    322         if re.match('^[A-Za-z0-9_]*$',title): 
     323        if re.match('^[A-Za-z0-9_]*$', title): 
    323324            self.good_name = True 
    324         else:  
     325        else: 
    325326            self.good_name = False 
    326327            msg = ("%s is not a valid Python name. Only alphanumeric \n" \ 
    327328                   "and underscore allowed" % self.name) 
    328   
     329 
    329330        #Now check if the name already exists 
    330331        if not self.overwrite_name and self.good_name: 
     
    361362        event.  Instead the apply button event goes to check_name which 
    362363        then calls this method if the name of the new file is acceptable. 
    363          
    364         ..todo:: this should be bound to the apply button.  The first line 
     364 
     365        :TODO this should be bound to the apply button.  The first line 
    365366        should call the check_name method which itself should be in another 
    366         module separated from the the GUI modules.  
     367        module separated from the the GUI modules. 
    367368        """ 
    368369        self.name_tcl.SetBackgroundColour('white') 
     
    463464        self.fill_explanation_helpstring(text) 
    464465 
    465     def fill_explanation_helpstring(self, type): 
     466    def fill_explanation_helpstring(self, operator): 
    466467        """ 
    467468        Choose the equation to use depending on whether we now have 
     
    471472        name = '' 
    472473 
    473         if type == '*': 
     474        if operator == '*': 
    474475            name = 'Multi' 
    475476            factor = 'BackGround' 
     
    481482 
    482483        self.factor = factor 
    483         self._operator = type 
     484        self._operator = operator 
    484485        self.explanation = "  Custom Model = %s %s (model1 %s model2)\n" % \ 
    485486                           (self.factor, f_oper, self._operator) 
     
    524525        try: 
    525526            out_f = open(path, 'w') 
    526         except : 
     527        except: 
    527528            raise 
    528529        lines = SUM_TEMPLATE.split('\n') 
     
    600601        kwds["style"] = wx.FULL_REPAINT_ON_RESIZE 
    601602        wx.ScrolledWindow.__init__(self, parent, *args, **kwds) 
     603        self.SetScrollbars(1,1,1,1) 
    602604        self.parent = parent 
    603605        self.base = base 
     
    813815        """ 
    814816        event.Skip() 
    815         label = self.math_combo.GetLabel() 
     817        label = self.math_combo.GetValue() 
    816818        self.function_tcl.SetFocus() 
    817819        # Put the text at the cursor position 
    818820        pos = self.function_tcl.GetCurrentPos() 
    819821        self.function_tcl.InsertText(pos, label) 
    820         # Put the cursor at appropriate postion 
     822        # Put the cursor at appropriate position 
    821823        length = len(label) 
    822         if label[-1] == ')': 
     824        print length 
     825        if label[length-1] == ')': 
    823826            length -= 1 
    824827        f_pos = pos + length 
     
    876879        """ 
    877880        Changes are saved in data object imported to edit. 
    878          
     881 
    879882        checks firs for valid name, then if it already exists then checks 
    880883        that a function was entered and finally that if entered it contains at 
    881         least a return statement.  If all passes writes file then tries to  
     884        least a return statement.  If all passes writes file then tries to 
    882885        compile.  If compile fails or import module fails or run method fails 
    883886        tries to remove any .py and pyc files that may have been created and 
    884887        sets error message. 
    885          
    886         ..todo:: this code still could do with a careful going over to clean 
     888 
     889        :todo this code still could do with a careful going over to clean 
    887890        up and simplify. the non GUI methods such as this one should be removed 
    888891        to computational code of SasView. Most of those computational methods 
     
    896899        # Sort out the errors if occur 
    897900        # First check for valid python name then if the name already exists 
    898         if not re.match('^[A-Za-z0-9_]*$',name): 
     901        if not re.match('^[A-Za-z0-9_]*$', name): 
    899902            msg = "not a valid python name. Name must include only alpha \n" 
    900903            msg += "numeric or underline characters and no spaces" 
     
    914917                        msg.replace("  ", "\n") 
    915918                        msg += "\nCompiling Failed" 
     919                        try: 
     920                            # try to remove pyc file if exists 
     921                            _delete_file(self.fname) 
     922                            _delete_file(self.fname + "c") 
     923                        except: 
     924                            pass 
    916925                else: 
    917926                    msg = "Error: The func(x) must 'return' a value at least.\n" 
     
    929938            except: 
    930939                msg = 'new model fails to import in python' 
     940                try: 
     941                    # try to remove pyc file if exists 
     942                    _delete_file(self.fname + "c") 
     943                except: 
     944                    pass 
    931945        if self.base != None and not msg: 
    932946            try: 
     
    936950                _, value, _ = sys.exc_info() 
    937951                msg += "in %s:\n%s\n" % (name, value) 
     952                try: 
     953                    # try to remove pyc file if exists 
     954                    _delete_file(self.fname + "c") 
     955                except: 
     956                    pass 
    938957        # Prepare the messagebox 
    939958        if msg: 
    940959            info = 'Error' 
    941960            color = 'red' 
    942             try: 
    943                 # try to remove pyc file if exists 
    944                 _delete_file(self.fname) 
    945                 _delete_file(self.fname + "c") 
    946             except: 
    947                 pass 
    948961        else: 
    949962            msg = "Successful! " 
     
    10991112                                 path=path, title=title) 
    11001113        self.Show(True) 
    1101         wx.EVT_CLOSE(self, self.OnClose) 
    1102  
    1103     def OnClose(self, event): 
     1114        wx.EVT_CLOSE(self, self.on_close) 
     1115 
     1116    def on_close(self, event): 
    11041117        """ 
    11051118        On close event 
     
    15141527if __name__ == "__main__": 
    15151528#    app = wx.PySimpleApp() 
    1516     app = wx.App() 
    1517     frame = TextDialog(id=1, model_list=["SphereModel", "CylinderModel"], 
     1529    main_app = wx.App() 
     1530    main_frame = TextDialog(id=1, model_list=["SphereModel", "CylinderModel"], 
    15181531                       plugin_dir='../fitting/plugin_models') 
    1519     frame.ShowModal() 
    1520     app.MainLoop() 
     1532    main_frame.ShowModal() 
     1533    main_app.MainLoop() 
    15211534 
    15221535#if __name__ == "__main__": 
Note: See TracChangeset for help on using the changeset viewer.