source: sasview/sansview/perspectives/fitting/basepage.py @ 13a63ab

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 13a63ab was 23cdeab, checked in by Jae Cho <jhjcho@…>, 14 years ago

fixed a MAC problem, not saving a status file unless the file extension is typed in

  • Property mode set to 100644
File size: 108.8 KB
Line 
1
2import sys
3import os
4import wx
5import numpy
6import time
7import copy 
8import math
9import string
10from sans.guiframe.panel_base import PanelBase
11from wx.lib.scrolledpanel import ScrolledPanel
12from sans.guiframe.utils import format_number,check_float
13from sans.guiframe.events import PanelOnFocusEvent
14from sans.guiframe.events import StatusEvent
15from sans.guiframe.events import AppendBookmarkEvent
16import pagestate
17from pagestate import PageState
18(PageInfoEvent, EVT_PAGE_INFO)   = wx.lib.newevent.NewEvent()
19(PreviousStateEvent, EVT_PREVIOUS_STATE)   = wx.lib.newevent.NewEvent()
20(NextStateEvent, EVT_NEXT_STATE)   = wx.lib.newevent.NewEvent()
21
22_BOX_WIDTH = 76
23_QMIN_DEFAULT = 0.0005
24_QMAX_DEFAULT = 0.5
25_NPTS_DEFAULT = 50
26#Control panel width
27if sys.platform.count("darwin")==0:
28    PANEL_WIDTH = 450
29    FONT_VARIANT = 0
30    ON_MAC = False
31else:
32    PANEL_WIDTH = 500
33    FONT_VARIANT = 1
34    ON_MAC = True
35
36
37
38class BasicPage(ScrolledPanel, PanelBase):
39    """
40    This class provide general structure of  fitpanel page
41    """
42     ## Internal name for the AUI manager
43    window_name = "Fit Page"
44    ## Title to appear on top of the window
45    window_caption = "Fit Page "
46   
47    def __init__(self, parent,color='blue', **kwargs):
48        """
49        """
50        ScrolledPanel.__init__(self, parent, **kwargs)
51        PanelBase.__init__(self, parent)
52        self.SetupScrolling()
53        #Set window's font size
54        self.SetWindowVariant(variant=FONT_VARIANT)
55     
56        self.SetBackgroundColour(color)
57        ## parent of the page
58        self.parent = parent
59        ## manager is the fitting plugin
60        ## owner of the page (fitting plugin)
61        self.event_owner = None
62         ## current model
63        self.model = None
64        ## data
65        self.data = None
66        self.mask = None
67        self.uid = None
68        ## Q range
69        self.qmin = None
70        self.qmax = None
71        self.qmax_x = _QMAX_DEFAULT
72        self.qmin_x = _QMIN_DEFAULT
73        self.npts_x = _NPTS_DEFAULT
74        ## total number of point: float
75        self.npts = None
76        ## default fitengine type
77        self.engine_type = 'scipy'
78        ## smear default
79        self.smearer = None
80        self.current_smearer = None
81        ## 2D smear accuracy default
82        self.smear2d_accuracy = 'Low'
83        ## slit smear:
84        self.dxl = None
85        self.dxw = None
86        ## pinhole smear
87        self.dx_min = None
88        self.dx_max = None
89       
90        self.disp_cb_dict = {}
91   
92        self.state = PageState(parent=parent)
93        ## dictionary containing list of models
94        self.model_list_box = {}
95       
96        ## Data member to store the dispersion object created
97        self._disp_obj_dict = {}
98        ## selected parameters to apply dispersion
99        self.disp_cb_dict ={}
100
101        ## smearer object
102        self.smearer = None
103        self.enable2D = False
104       
105        ##list of model parameters. each item must have same length
106        ## each item related to a given parameters
107        ##[cb state, name, value, "+/-", error of fit, min, max , units]
108        self.parameters = []
109        # non-fittable parameter whose value is astring
110        self.str_parameters = []
111        ## list of parameters to fit , must be like self.parameters
112        self.param_toFit = []
113        ## list of looking like parameters but with non fittable parameters info
114        self.fixed_param = []
115        ## list of looking like parameters but with  fittable parameters info
116        self.fittable_param = []
117        ##list of dispersion parameters
118        self.disp_list = []
119        self.disp_name = ""
120       
121        ## list of orientation parameters
122        self.orientation_params = []
123        self.orientation_params_disp = []
124        if self.model != None:
125            self.disp_list = self.model.getDispParamList()
126       
127        ##enable model 2D draw
128        self.enable2D = False
129        ## check that the fit range is correct to plot the model again
130        self.fitrange = True
131        ## Create memento to save the current state
132        self.state = PageState(parent=self.parent,
133                               model=self.model, data=self.data)
134        ## flag to determine if state has change
135        self.state_change = False
136        ## save customized array
137        self.values = []
138        self.weights = []
139        ## retrieve saved state
140        self.number_saved_state = 0
141        ## dictionary of saved state
142        self.saved_states = {} 
143        ## Create context menu for page
144        self.popUpMenu = wx.Menu()
145   
146        id = wx.NewId()
147        self._keep = wx.MenuItem(self.popUpMenu,id,"Add bookmark",
148                                 " Keep the panel status to recall it later")
149        self.popUpMenu.AppendItem(self._keep)
150        self._keep.Enable(False)
151        self._set_bookmark_flag(False)
152        self._set_save_flag(False)
153        wx.EVT_MENU(self, id, self.on_bookmark)
154        self.popUpMenu.AppendSeparator()
155   
156        ## Default locations
157        self._default_save_location = os.getcwd()     
158        ## save initial state on context menu
159        #self.onSave(event=None)
160        self.Bind(wx.EVT_CONTEXT_MENU, self.onContextMenu)
161       
162        # bind key event
163        self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
164
165        ## create the basic structure of the panel with empty sizer
166        self.define_page_structure()
167        ## drawing Initial dispersion parameters sizer
168        self.set_dispers_sizer()
169       
170        ## layout
171        self.set_layout()
172       
173   
174       
175    def on_set_focus(self, event):
176        """
177        """
178        if self._manager is not None:
179            wx.PostEvent(self._manager.parent, PanelOnFocusEvent(panel=self))
180       
181    class ModelTextCtrl(wx.TextCtrl):
182        """
183        Text control for model and fit parameters.
184        Binds the appropriate events for user interactions.
185        Default callback methods can be overwritten on initialization
186       
187        :param kill_focus_callback: callback method for EVT_KILL_FOCUS event
188        :param set_focus_callback:  callback method for EVT_SET_FOCUS event
189        :param mouse_up_callback:   callback method for EVT_LEFT_UP event
190        :param text_enter_callback: callback method for EVT_TEXT_ENTER event
191       
192        """
193        ## Set to True when the mouse is clicked while the whole string is selected
194        full_selection = False
195        ## Call back for EVT_SET_FOCUS events
196        _on_set_focus_callback = None
197       
198        def __init__(self, parent, id=-1, 
199                     value=wx.EmptyString, 
200                     pos=wx.DefaultPosition, 
201                     size=wx.DefaultSize,
202                     style=0, 
203                     validator=wx.DefaultValidator,
204                     name=wx.TextCtrlNameStr,
205                     kill_focus_callback=None,
206                     set_focus_callback=None,
207                     mouse_up_callback=None,
208                     text_enter_callback = None):
209             
210            wx.TextCtrl.__init__(self, parent, id, value, pos,
211                                  size, style, validator, name)
212           
213            # Bind appropriate events
214            self._on_set_focus_callback = parent.onSetFocus \
215                      if set_focus_callback is None else set_focus_callback
216            self.Bind(wx.EVT_SET_FOCUS, self._on_set_focus)
217            self.Bind(wx.EVT_KILL_FOCUS, self._silent_kill_focus \
218                      if kill_focus_callback is None else kill_focus_callback)               
219            self.Bind(wx.EVT_TEXT_ENTER, parent._onparamEnter \
220                      if text_enter_callback is None else text_enter_callback)
221            if not ON_MAC :
222                self.Bind(wx.EVT_LEFT_UP,    self._highlight_text \
223                          if mouse_up_callback is None else mouse_up_callback)
224           
225        def _on_set_focus(self, event):
226            """
227            Catch when the text control is set in focus to highlight the whole
228            text if necessary
229           
230            :param event: mouse event
231           
232            """
233            event.Skip()
234            self.full_selection = True
235            return self._on_set_focus_callback(event)
236       
237 
238           
239        def _highlight_text(self, event):
240            """
241            Highlight text of a TextCtrl only of no text has be selected
242           
243            :param event: mouse event
244           
245            """
246            # Make sure the mouse event is available to other listeners
247            event.Skip()
248            control  = event.GetEventObject()
249            if self.full_selection:
250                self.full_selection = False
251                # Check that we have a TextCtrl
252                if issubclass(control.__class__, wx.TextCtrl):
253                    # Check whether text has been selected,
254                    # if not, select the whole string
255                    (start, end) = control.GetSelection()
256                    if start==end:
257                        control.SetSelection(-1,-1)
258                       
259        def _silent_kill_focus(self,event):
260            """
261            Save the state of the page
262            """
263           
264            event.Skip()
265            pass
266   
267    def set_page_info(self, page_info):
268        """
269        set some page important information at once
270        """
271       ##window_name
272        self.window_name = page_info.window_name
273        ##window_caption
274        self.window_caption = page_info.window_caption
275        ## manager is the fitting plugin
276        self._manager= page_info.manager
277        ## owner of the page (fitting plugin)
278        self.event_owner= page_info.event_owner
279         ## current model
280        self.model = page_info.model
281        ## data
282        self.data = page_info.data
283        ## dictionary containing list of models
284        self.model_list_box = page_info.model_list_box
285        ## Data member to store the dispersion object created
286        self.populate_box(dict=self.model_list_box)
287       
288    def onContextMenu(self, event): 
289        """
290        Retrieve the state selected state
291        """
292        # Skipping the save state functionality for release 0.9.0
293        #return
294   
295        pos = event.GetPosition()
296        pos = self.ScreenToClient(pos)
297       
298        self.PopupMenu(self.popUpMenu, pos) 
299     
300       
301    def onUndo(self, event):
302        """
303        Cancel the previous action
304        """
305        event = PreviousStateEvent(page = self)
306        wx.PostEvent(self.parent, event)
307       
308    def onRedo(self, event):
309        """
310        Restore the previous action cancelled
311        """
312        event = NextStateEvent(page= self)
313        wx.PostEvent(self.parent, event)
314   
315    def define_page_structure(self):
316        """
317        Create empty sizer for a panel
318        """
319        self.vbox  = wx.BoxSizer(wx.VERTICAL)
320        self.sizer0 = wx.BoxSizer(wx.VERTICAL)
321        self.sizer1 = wx.BoxSizer(wx.VERTICAL)
322        self.sizer2 = wx.BoxSizer(wx.VERTICAL)
323        self.sizer3 = wx.BoxSizer(wx.VERTICAL)
324        self.sizer4 = wx.BoxSizer(wx.VERTICAL)
325        self.sizer5 = wx.BoxSizer(wx.VERTICAL)
326        self.sizer6 = wx.BoxSizer(wx.VERTICAL)
327       
328        self.sizer0.SetMinSize((PANEL_WIDTH,-1))
329        self.sizer1.SetMinSize((PANEL_WIDTH,-1))
330        self.sizer2.SetMinSize((PANEL_WIDTH,-1))
331        self.sizer3.SetMinSize((PANEL_WIDTH,-1))
332        self.sizer4.SetMinSize((PANEL_WIDTH,-1))
333        self.sizer5.SetMinSize((PANEL_WIDTH,-1))
334        self.sizer6.SetMinSize((PANEL_WIDTH,-1))
335       
336        self.vbox.Add(self.sizer0)
337        self.vbox.Add(self.sizer1)
338        self.vbox.Add(self.sizer2)
339        self.vbox.Add(self.sizer3)
340        self.vbox.Add(self.sizer4)
341        self.vbox.Add(self.sizer5)
342        self.vbox.Add(self.sizer6)
343       
344    def set_layout(self):
345        """
346        layout
347        """
348        self.vbox.Layout()
349        self.vbox.Fit(self) 
350        self.SetSizer(self.vbox)
351        self.Centre()
352 
353    def set_owner(self,owner):
354        """
355        set owner of fitpage
356       
357        :param owner: the class responsible of plotting
358       
359        """
360        self.event_owner = owner   
361        self.state.event_owner = owner
362       
363    def get_state(self):
364        """
365        """
366        return self.state
367    def get_data(self):
368        """
369        return the current data
370        """
371        return self.data 
372   
373    def set_manager(self, manager):
374        """
375        set panel manager
376       
377        :param manager: instance of plugin fitting
378       
379        """
380        self._manager = manager 
381        self.state.manager = manager
382       
383    def populate_box(self, dict):
384        """
385        Store list of model
386       
387        :param dict: dictionary containing list of models
388       
389        """
390        self.model_list_box = dict
391        self.state.model_list_box = self.model_list_box
392        self.initialize_combox()
393       
394    def initialize_combox(self): 
395        """
396        put default value in the combobox
397        """ 
398        ## fill combox box
399        if self.model_list_box is None:
400            return
401        if len(self.model_list_box) > 0:
402            self._populate_box(self.formfactorbox,
403                               self.model_list_box["Shapes"])
404       
405        if len(self.model_list_box) > 0:
406            self._populate_box(self.structurebox,
407                                self.model_list_box["Structure Factors"])
408            self.structurebox.Insert("None", 0, None)
409            self.structurebox.SetSelection(0)
410            self.structurebox.Hide()
411            self.text2.Hide()
412            self.structurebox.Disable()
413            self.text2.Disable()
414             
415            if self.model.__class__ in self.model_list_box["P(Q)*S(Q)"]:
416                self.structurebox.Show()
417                self.text2.Show()
418                self.structurebox.Enable()
419                self.text2.Enable()           
420               
421    def set_dispers_sizer(self):
422        """
423        fill sizer containing dispersity info
424        """
425        self.sizer4.Clear(True)
426        name="Polydispersity and Orientational Distribution"
427        box_description= wx.StaticBox(self, -1,name)
428        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
429        #----------------------------------------------------
430        self.disable_disp = wx.RadioButton(self, -1, 'Off', (10, 10),
431                                            style=wx.RB_GROUP)
432        self.enable_disp = wx.RadioButton(self, -1, 'On', (10, 30))
433        # best size for MAC and PC
434        if ON_MAC:
435            size_q = (-1, -1)     
436        else:
437            size_q =  (20,15)   
438        self.disp_help_bt = wx.Button(self,wx.NewId(),'?', 
439                                      style = wx.BU_EXACTFIT,
440                                      size=size_q)
441        self.disp_help_bt.Bind(wx.EVT_BUTTON, 
442                        self.on_pd_help_clicked,id= self.disp_help_bt.GetId())
443        self.disp_help_bt.SetToolTipString("Helps for Polydispersion.")       
444       
445        self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param,
446                     id=self.disable_disp.GetId())
447        self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param,
448                   id=self.enable_disp.GetId())
449        #MAC needs SetValue
450        self.disable_disp.SetValue(True)
451        sizer_dispersion = wx.BoxSizer(wx.HORIZONTAL)
452        sizer_dispersion.Add((20,20))
453        name=""#Polydispersity and \nOrientational Distribution "
454        sizer_dispersion.Add(wx.StaticText(self,-1,name))
455        sizer_dispersion.Add(self.enable_disp )
456        sizer_dispersion.Add((20,20))
457        sizer_dispersion.Add(self.disable_disp )
458        sizer_dispersion.Add((25,20))
459        sizer_dispersion.Add(self.disp_help_bt)
460       
461        ## fill a sizer for dispersion         
462        boxsizer1.Add( sizer_dispersion,0,
463                wx.TOP|wx.BOTTOM|wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE,border=5)
464        #boxsizer1.Add( (10,10) )
465        #boxsizer1.Add( sizer_select_dispers )
466        self.sizer4_4 = wx.GridBagSizer(6,5)
467
468        boxsizer1.Add( self.sizer4_4  )
469        #-----------------------------------------------------
470        self.sizer4.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
471        self.sizer4_4.Layout()
472        self.sizer4.Layout()
473        self.Layout()
474     
475        self.Refresh()
476        ## saving the state of enable dispersity button
477        self.state.enable_disp= self.enable_disp.GetValue()
478        self.state.disable_disp= self.disable_disp.GetValue()
479        self.SetupScrolling()
480
481   
482    def onResetModel(self, event):
483        """
484        Reset model state
485        """
486        menu = event.GetEventObject()
487        ## post help message for the selected model
488        msg = menu.GetHelpString(event.GetId())
489        msg +=" reloaded"
490        wx.PostEvent(self.parent.parent, StatusEvent(status=msg))
491       
492        name = menu.GetLabel(event.GetId())
493        self._on_select_model_helper()
494       
495        if name in self.saved_states.keys():
496            previous_state = self.saved_states[name]
497            ## reset state of checkbox,textcrtl  and  regular parameters value
498            self.reset_page(previous_state)   
499       
500               
501    def on_preview(self, event):
502        """
503        Report the current fit results
504        """   
505        # Get plot image from plotpanel
506        images, canvases = self.get_images()
507        # get the report dialog
508        self.state.report(images, canvases)
509       
510         
511    def on_save(self, event):   
512        """
513        Save the current state into file
514        """ 
515        self.save_current_state()
516        new_state = self.state.clone()
517        # Ask the user the location of the file to write to.
518        path = None
519        dlg = wx.FileDialog(self, "Choose a file", self._default_save_location,
520                                                 "", "*.fitv", wx.SAVE)
521        if dlg.ShowModal() == wx.ID_OK:
522            path = dlg.GetPath()
523            self._default_save_location = os.path.dirname(path)
524        else:
525            return None
526        # MAC always needs the extension for saving
527        extens = ".fitv"
528        # Make sure the ext included in the file name
529        fName = os.path.splitext(path)[0] + extens
530        #the manager write the state into file
531        self._manager.save_fit_state(filepath=fName, fitstate=new_state)
532        return new_state 
533   
534    def _get_time_stamp(self):
535        """
536        return time and date stings
537        """
538        # date and time
539        year, month, day,hour,minute,second,tda,ty,tm_isdst= time.localtime()
540        current_time= str(hour)+":"+str(minute)+":"+str(second)
541        current_date= str( month)+"/"+str(day)+"/"+str(year)
542        return current_time, current_date
543     
544    def on_bookmark(self, event):
545        """
546        save history of the data and model
547        """
548        if self.model==None:
549            msg="Can not bookmark; Please select Data and Model first..."
550            wx.MessageBox(msg, 'Info')
551            return 
552        self.save_current_state()
553        new_state = self.state.clone()
554        ##Add model state on context menu
555        self.number_saved_state += 1
556        current_time, current_date = self._get_time_stamp()
557        #name= self.model.name+"[%g]"%self.number_saved_state
558        name = "Fitting: %g]" % self.number_saved_state
559        name += self.model.__class__.__name__
560        name += "bookmarked at %s on %s" % (current_time, current_date)
561        self.saved_states[name]= new_state
562       
563        ## Add item in the context menu
564        msg =  "Model saved at %s on %s"%(current_time, current_date)
565         ## post help message for the selected model
566        msg +=" Saved! right click on this page to retrieve this model"
567        wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
568       
569        id = wx.NewId()
570        self.popUpMenu.Append(id,name,str(msg))
571        wx.EVT_MENU(self, id, self.onResetModel)
572        wx.PostEvent(self.parent.parent, 
573                     AppendBookmarkEvent(title=name, 
574                                         hint=str(msg), handler=self._back_to_bookmark))
575    def _back_to_bookmark(self, event): 
576        """
577        Back to bookmark
578        """
579        self._manager.on_perspective(event)
580        self.onResetModel(event)
581    def old_on_bookmark(self, event):
582        """
583        save history of the data and model
584        """
585        if self.model==None:
586            msg="Can not bookmark; Please select Data and Model first..."
587            wx.MessageBox(msg, 'Info')
588            return 
589        if hasattr(self,"enable_disp"):
590            self.state.enable_disp = copy.deepcopy(self.enable_disp.GetValue())
591        if hasattr(self, "disp_box"):
592            self.state.disp_box = copy.deepcopy(self.disp_box.GetSelection())
593
594        self.state.model.name= self.model.name
595       
596        #Remember fit engine_type for fit panel
597        if self.engine_type == None: 
598            self.engine_type = "scipy"
599        if self._manager !=None:
600            self._manager._on_change_engine(engine=self.engine_type)
601       
602            self.state.engine_type = self.engine_type
603
604        new_state = self.state.clone()
605        new_state.model.name = self.state.model.name
606       
607        new_state.enable2D = copy.deepcopy(self.enable2D)
608        ##Add model state on context menu
609        self.number_saved_state += 1
610        #name= self.model.name+"[%g]"%self.number_saved_state
611        name= self.model.__class__.__name__+"[%g]"%self.number_saved_state
612        self.saved_states[name]= new_state
613       
614        ## Add item in the context menu
615       
616        year, month, day,hour,minute,second,tda,ty,tm_isdst= time.localtime()
617        my_time= str(hour)+" : "+str(minute)+" : "+str(second)+" "
618        date= str( month)+"|"+str(day)+"|"+str(year)
619        msg=  "Model saved at %s on %s"%(my_time, date)
620         ## post help message for the selected model
621        msg +=" Saved! right click on this page to retrieve this model"
622        wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
623       
624        id = wx.NewId()
625        self.popUpMenu.Append(id,name,str(msg))
626        wx.EVT_MENU(self, id, self.onResetModel)
627       
628    def onSetFocus(self, evt):
629        """
630        highlight the current textcrtl and hide the error text control shown
631        after fitting
632        """
633        return
634   
635    def read_file(self, path):
636        """
637        Read two columns file
638       
639        :param path: the path to the file to read
640       
641        """
642        try:
643            if path==None:
644                wx.PostEvent(self.parent.parent, StatusEvent(status=\
645                            " Selected Distribution was not loaded: %s"%path))
646                return None, None
647            input_f = open(path, 'r')
648            buff = input_f.read()
649            lines = buff.split('\n')
650           
651            angles = []
652            weights=[]
653            for line in lines:
654                toks = line.split()
655                try:
656                    angle = float(toks[0])
657                    weight = float(toks[1])
658                except:
659                    # Skip non-data lines
660                    pass
661                angles.append(angle)
662                weights.append(weight)
663            return numpy.array(angles), numpy.array(weights)
664        except:
665            raise 
666
667    def createMemento(self):
668        """
669        return the current state of the page
670        """
671        return self.state.clone()
672   
673   
674    def save_current_state(self):
675        """
676        Store current state
677        """
678        self.state.engine_type = copy.deepcopy(self.engine_type)
679        ## save model option
680        if self.model!= None:
681            self.disp_list= self.model.getDispParamList()
682            self.state.disp_list= copy.deepcopy(self.disp_list)
683            self.state.model = self.model.clone()
684        #save radiobutton state for model selection
685        self.state.shape_rbutton = self.shape_rbutton.GetValue()
686        self.state.shape_indep_rbutton = self.shape_indep_rbutton.GetValue()
687        self.state.struct_rbutton = self.struct_rbutton.GetValue()
688        self.state.plugin_rbutton = self.plugin_rbutton.GetValue()
689        #model combobox
690        self.state.structurebox = self.structurebox.GetSelection()
691        self.state.formfactorbox = self.formfactorbox.GetSelection()
692       
693        self.state.enable2D = copy.deepcopy(self.enable2D)
694        self.state.values= copy.deepcopy(self.values)
695        self.state.weights = copy.deepcopy( self.weights)
696        ## save data   
697        self.state.data= copy.deepcopy(self.data)
698        self.state.qmax_x = self.qmax_x
699        self.state.qmin_x = self.qmin_x
700     
701        if hasattr(self,"enable_disp"):
702            self.state.enable_disp= self.enable_disp.GetValue()
703            self.state.disable_disp = self.disable_disp.GetValue()
704           
705        self.state.smearer = copy.deepcopy(self.smearer)
706        if hasattr(self,"enable_smearer"):
707            self.state.enable_smearer = \
708                                copy.deepcopy(self.enable_smearer.GetValue())
709            self.state.disable_smearer = \
710                                copy.deepcopy(self.disable_smearer.GetValue())
711
712        self.state.pinhole_smearer = \
713                                copy.deepcopy(self.pinhole_smearer.GetValue())
714        self.state.slit_smearer = copy.deepcopy(self.slit_smearer.GetValue()) 
715                 
716        if len(self._disp_obj_dict)>0:
717            for k , v in self._disp_obj_dict.iteritems():
718                self.state._disp_obj_dict[k]= v
719                       
720           
721            self.state.values = copy.deepcopy(self.values)
722            self.state.weights = copy.deepcopy(self.weights)
723        ## save plotting range
724        self._save_plotting_range()
725       
726        self.state.orientation_params = []
727        self.state.orientation_params_disp = []
728        self.state.parameters = []
729        self.state.fittable_param = []
730        self.state.fixed_param = []
731        self.state.str_parameters = []
732
733       
734        ## save checkbutton state and txtcrtl values
735        self._copy_parameters_state(self.str_parameters, 
736                                    self.state.str_parameters)
737        self._copy_parameters_state(self.orientation_params,
738                                     self.state.orientation_params)
739        self._copy_parameters_state(self.orientation_params_disp,
740                                     self.state.orientation_params_disp)
741       
742        self._copy_parameters_state(self.parameters, self.state.parameters)
743        self._copy_parameters_state(self.fittable_param,
744                                     self.state.fittable_param)
745        self._copy_parameters_state(self.fixed_param, self.state.fixed_param)
746        #save chisqr
747        self.state.tcChi = self.tcChi.GetValue()
748       
749    def save_current_state_fit(self):
750        """
751        Store current state for fit_page
752        """
753        ## save model option
754        if self.model!= None:
755            self.disp_list= self.model.getDispParamList()
756            self.state.disp_list= copy.deepcopy(self.disp_list)
757            self.state.model = self.model.clone()
758        if hasattr(self, "engine_type"):
759            self.state.engine_type = copy.deepcopy(self.engine_type)
760           
761        self.state.enable2D = copy.deepcopy(self.enable2D)
762        self.state.values= copy.deepcopy(self.values)
763        self.state.weights = copy.deepcopy( self.weights)
764        ## save data   
765        self.state.data= copy.deepcopy(self.data)
766       
767        if hasattr(self,"enable_disp"):
768            self.state.enable_disp= self.enable_disp.GetValue()
769            self.state.disable_disp = self.disable_disp.GetValue()
770           
771        self.state.smearer = copy.deepcopy(self.smearer)
772        if hasattr(self,"enable_smearer"):
773            self.state.enable_smearer = \
774                                copy.deepcopy(self.enable_smearer.GetValue())
775            self.state.disable_smearer = \
776                                copy.deepcopy(self.disable_smearer.GetValue())
777           
778        self.state.pinhole_smearer = \
779                                copy.deepcopy(self.pinhole_smearer.GetValue())
780        self.state.slit_smearer = copy.deepcopy(self.slit_smearer.GetValue()) 
781           
782        if hasattr(self,"disp_box"):
783            self.state.disp_box = self.disp_box.GetCurrentSelection()
784
785            if len(self.disp_cb_dict) > 0:
786                for k, v in self.disp_cb_dict.iteritems():
787         
788                    if v == None :
789                        self.state.disp_cb_dict[k] = v
790                    else:
791                        try:
792                            self.state.disp_cb_dict[k] = v.GetValue()
793                        except:
794                            self.state.disp_cb_dict[k] = None
795           
796            if len(self._disp_obj_dict) > 0:
797                for k , v in self._disp_obj_dict.iteritems():
798     
799                    self.state._disp_obj_dict[k] = v
800                       
801           
802            self.state.values = copy.deepcopy(self.values)
803            self.state.weights = copy.deepcopy(self.weights)
804           
805        ## save plotting range
806        self._save_plotting_range()
807       
808        ## save checkbutton state and txtcrtl values
809        self._copy_parameters_state(self.orientation_params,
810                                     self.state.orientation_params)
811        self._copy_parameters_state(self.orientation_params_disp,
812                                     self.state.orientation_params_disp)
813        self._copy_parameters_state(self.parameters, self.state.parameters)
814        self._copy_parameters_state(self.fittable_param,
815                                             self.state.fittable_param)
816        self._copy_parameters_state(self.fixed_param, self.state.fixed_param)
817   
818         
819    def check_invalid_panel(self): 
820        """
821        check if the user can already perform some action with this panel
822        """ 
823        flag = False
824        if self.data is None:
825            self.disable_smearer.SetValue(True)
826            self.disable_disp.SetValue(True)
827            msg = "Please load Data and select Model to start..."
828            wx.MessageBox(msg, 'Info')
829            return  True
830       
831    def set_model_state(self, state):
832        """
833        reset page given a model state
834        """
835        self.disp_cb_dict = state.disp_cb_dict
836        self.disp_list = state.disp_list
837     
838        ## set the state of the radio box
839        self.shape_rbutton.SetValue(state.shape_rbutton )
840        self.shape_indep_rbutton.SetValue(state.shape_indep_rbutton)
841        self.struct_rbutton.SetValue(state.struct_rbutton)
842        self.plugin_rbutton.SetValue(state.plugin_rbutton)
843       
844        ## fill model combobox
845        self._show_combox_helper()
846        #select the current model
847        self.formfactorbox.Select(int(state.formfactorcombobox))
848        self.structurebox.SetSelection(state.structurecombobox )
849        if state.multi_factor != None:
850            self.multifactorbox.SetSelection(state.multi_factor)
851           
852         ## reset state of checkbox,textcrtl  and  regular parameters value
853        self._reset_parameters_state(self.orientation_params_disp,
854                                     state.orientation_params_disp)
855        self._reset_parameters_state(self.orientation_params,
856                                     state.orientation_params)
857        self._reset_parameters_state(self.str_parameters,
858                                     state.str_parameters)
859        self._reset_parameters_state(self.parameters,state.parameters)
860         ## display dispersion info layer       
861        self.enable_disp.SetValue(state.enable_disp)
862        self.disable_disp.SetValue(state.disable_disp)
863       
864        if hasattr(self, "disp_box"):
865           
866            self.disp_box.SetSelection(state.disp_box) 
867            n= self.disp_box.GetCurrentSelection()
868            dispersity= self.disp_box.GetClientData(n)
869            name = dispersity.__name__     
870
871            self._set_dipers_Param(event=None)
872       
873            if name == "ArrayDispersion":
874               
875                for item in self.disp_cb_dict.keys():
876                   
877                    if hasattr(self.disp_cb_dict[item], "SetValue") :
878                        self.disp_cb_dict[item].SetValue(\
879                                                    state.disp_cb_dict[item])
880                        # Create the dispersion objects
881                        from sans.models.dispersion_models import ArrayDispersion
882                        disp_model = ArrayDispersion()
883                        if hasattr(state,"values")and\
884                                 self.disp_cb_dict[item].GetValue() == True:
885                            if len(state.values)>0:
886                                self.values=state.values
887                                self.weights=state.weights
888                                disp_model.set_weights(self.values,
889                                                        state.weights)
890                            else:
891                                self._reset_dispersity()
892                       
893                        self._disp_obj_dict[item] = disp_model
894                        # Set the new model as the dispersion object
895                        #for the selected parameter
896                        self.model.set_dispersion(item, disp_model)
897                   
898                        self.model._persistency_dict[item] = \
899                                                [state.values, state.weights]
900                   
901            else:
902                keys = self.model.getParamList()
903                for item in keys:
904                    if item in self.disp_list and \
905                        not self.model.details.has_key(item):
906                        self.model.details[item] = ["", None, None]
907                for k,v in self.state.disp_cb_dict.iteritems():
908                    self.disp_cb_dict = copy.deepcopy(state.disp_cb_dict) 
909                    self.state.disp_cb_dict = copy.deepcopy(state.disp_cb_dict)
910         ## smearing info  restore
911        if hasattr(self, "enable_smearer"):
912            ## set smearing value whether or not the data
913            #contain the smearing info
914            self.enable_smearer.SetValue(state.enable_smearer)
915            self.disable_smearer.SetValue(state.disable_smearer)
916            self.onSmear(event=None)           
917        self.pinhole_smearer.SetValue(state.pinhole_smearer)
918        self.slit_smearer.SetValue(state.slit_smearer)
919        ## we have two more options for smearing
920        if self.pinhole_smearer.GetValue(): self.onPinholeSmear(event=None)
921        elif self.slit_smearer.GetValue(): self.onSlitSmear(event=None)
922       
923        ## reset state of checkbox,textcrtl  and dispersity parameters value
924        self._reset_parameters_state(self.fittable_param,state.fittable_param)
925        self._reset_parameters_state(self.fixed_param,state.fixed_param)
926       
927        ## draw the model with previous parameters value
928        self._onparamEnter_helper()
929        self.select_param(event=None) 
930        #Save state_fit
931        self.save_current_state_fit()
932        self._lay_out()
933        self.Refresh()
934       
935    def reset_page_helper(self, state):
936        """
937        Use page_state and change the state of existing page
938       
939        :precondition: the page is already drawn or created
940       
941        :postcondition: the state of the underlying data change as well as the
942            state of the graphic interface
943        """
944        if state == None:
945            #self._undo.Enable(False)
946            return 
947        # set data, etc. from the state
948        # reset page between theory and fitting from bookmarking
949        #if state.data == None:
950        #    data = None
951        #else:
952        data = state.data
953
954        #if data != None:
955       
956        if data == None:
957            data_min = state.qmin
958            data_max = state.qmax
959            self.qmin_x = data_min
960            self.qmax_x = data_max
961            self.minimum_q.SetValue(str(data_min))
962            self.maximum_q.SetValue(str(data_max))
963            self.qmin.SetValue(str(data_min))
964            self.qmax.SetValue(str(data_max))
965
966            self.state.data = data
967            self.state.qmin = self.qmin_x
968            self.state.qmax = self.qmax_x
969        else:
970            self.set_data(data)
971           
972        self.enable2D= state.enable2D
973        self.engine_type = state.engine_type
974
975        self.disp_cb_dict = state.disp_cb_dict
976        self.disp_list = state.disp_list
977     
978        ## set the state of the radio box
979        self.shape_rbutton.SetValue(state.shape_rbutton )
980        self.shape_indep_rbutton.SetValue(state.shape_indep_rbutton)
981        self.struct_rbutton.SetValue(state.struct_rbutton)
982        self.plugin_rbutton.SetValue(state.plugin_rbutton)
983       
984        ## fill model combobox
985        self._show_combox_helper()
986        #select the current model
987        self.formfactorbox.Select(int(state.formfactorcombobox))
988        self.structurebox.SetSelection(state.structurecombobox )
989        if state.multi_factor != None:
990            self.multifactorbox.SetSelection(state.multi_factor)
991
992        #reset the fitting engine type
993        self.engine_type = state.engine_type
994        #draw the pnael according to the new model parameter
995        self._on_select_model(event=None)
996        # take care of 2D button
997        if data == None and self.model_view.IsEnabled():
998            if self.enable2D:
999                self.model_view.SetLabel("Switch to 1D")
1000            else:
1001                self.model_view.SetLabel("Switch to 2D")
1002        # else:
1003               
1004        if self._manager !=None:
1005            self._manager._on_change_engine(engine=self.engine_type)
1006        ## set the select all check box to the a given state
1007        self.cb1.SetValue(state.cb1)
1008     
1009        ## reset state of checkbox,textcrtl  and  regular parameters value
1010        self._reset_parameters_state(self.orientation_params_disp,
1011                                     state.orientation_params_disp)
1012        self._reset_parameters_state(self.orientation_params,
1013                                     state.orientation_params)
1014        self._reset_parameters_state(self.str_parameters,
1015                                     state.str_parameters)
1016        self._reset_parameters_state(self.parameters,state.parameters)   
1017         ## display dispersion info layer       
1018        self.enable_disp.SetValue(state.enable_disp)
1019        self.disable_disp.SetValue(state.disable_disp)
1020        # If the polydispersion is ON
1021        if state.enable_disp:
1022            # reset dispersion according the state
1023            self._set_dipers_Param(event=None)
1024            self._reset_page_disp_helper(state)
1025        ##plotting range restore   
1026        self._reset_plotting_range(state)
1027        ## smearing info  restore
1028        if hasattr(self, "enable_smearer"):
1029            ## set smearing value whether or not the data
1030            #contain the smearing info
1031            self.enable_smearer.SetValue(state.enable_smearer)
1032            self.disable_smearer.SetValue(state.disable_smearer)
1033            self.onSmear(event=None)           
1034        self.pinhole_smearer.SetValue(state.pinhole_smearer)
1035        self.slit_smearer.SetValue(state.slit_smearer)
1036        ## we have two more options for smearing
1037        if self.pinhole_smearer.GetValue(): self.onPinholeSmear(event=None)
1038        elif self.slit_smearer.GetValue(): self.onSlitSmear(event=None)
1039       
1040        ## reset state of checkbox,textcrtl  and dispersity parameters value
1041        self._reset_parameters_state(self.fittable_param,state.fittable_param)
1042        self._reset_parameters_state(self.fixed_param,state.fixed_param)
1043       
1044        ## draw the model with previous parameters value
1045        self._onparamEnter_helper()
1046        #reset the value of chisqr when not consistent with the value computed
1047        self.tcChi.SetValue(str(self.state.tcChi))
1048        ## reset context menu items
1049        self._reset_context_menu()
1050       
1051        ## set the value of the current state to the state given as parameter
1052        self.state = state.clone() 
1053   
1054    def _reset_page_disp_helper(self, state):
1055        """
1056        Help to rest page for dispersions
1057        """
1058        keys = self.model.getParamList()
1059        for item in keys:
1060            if item in self.disp_list and \
1061                not self.model.details.has_key(item):
1062                self.model.details[item] = ["", None, None]
1063        #for k,v in self.state.disp_cb_dict.iteritems():
1064        self.disp_cb_dict = copy.deepcopy(state.disp_cb_dict) 
1065        self.state.disp_cb_dict = copy.deepcopy(state.disp_cb_dict)
1066        self.values = copy.deepcopy(state.values)
1067        self.weights = copy.deepcopy(state.weights)
1068       
1069        for key, disp in state._disp_obj_dict.iteritems():
1070            # From saved file, disp_model can not be sent in model obj.
1071            # it will be sent as a string here, then converted to model object.
1072            if disp.__class__.__name__ == 'str':
1073                com_str  = "from sans.models.dispersion_models "
1074                com_str += "import %s as disp_func"
1075                exec com_str % disp
1076                disp_model = disp_func()
1077            else:
1078                disp_model = disp
1079
1080            self._disp_obj_dict[key] = disp_model
1081            param_name = key.split('.')[0]
1082            # Try to set dispersion only when available
1083            # for eg., pass the orient. angles for 1D Cal
1084            try:
1085                self.model.set_dispersion(param_name, disp_model)
1086                self.model._persistency_dict[key] = \
1087                                 [state.values, state.weights]
1088            except:
1089                pass
1090            selection = self._find_polyfunc_selection(disp_model)
1091            for list in self.fittable_param:
1092                if list[1] == key and list[7] != None:
1093                    list[7].SetSelection(selection)
1094                    # For the array disp_model, set the values and weights
1095                    if selection == 1:
1096                        disp_model.set_weights(self.values[key], 
1097                                              self.weights[key])
1098                        try:
1099                            # Diables all fittable params for array
1100                            list[0].SetValue(False)
1101                            list[0].Disable()
1102                            list[2].Disable()
1103                            list[5].Disable()
1104                            list[6].Disable()
1105                        except:
1106                            pass
1107            # For array, disable all fixed params
1108            if selection == 1:
1109                for item in self.fixed_param:
1110                    if item[1].split(".")[0] == key.split(".")[0]:
1111                        # try it and pass it for the orientation for 1D
1112                        try:
1113                            item[2].Disable()
1114                        except:
1115                            pass
1116   
1117        # Make sure the check box updated when all checked
1118        if self.cb1.GetValue():
1119            self.select_all_param(None)       
1120     
1121    def _selectDlg(self):
1122        """
1123        open a dialog file to selected the customized dispersity
1124        """
1125        import os
1126        dlg = wx.FileDialog(self, "Choose a weight file",
1127                                self._default_save_location , "", 
1128                                "*.*", wx.OPEN)
1129        path = None
1130        if dlg.ShowModal() == wx.ID_OK:
1131            path = dlg.GetPath()
1132        dlg.Destroy()
1133        return path
1134
1135    def _reset_context_menu(self):
1136        """
1137        reset the context menu
1138        """
1139        for name, state in self.state.saved_states.iteritems():
1140            self.number_saved_state += 1
1141            ## Add item in the context menu
1142            id = wx.NewId()
1143            msg = 'Save model and state %g' % self.number_saved_state
1144            self.popUpMenu.Append(id, name, msg)
1145            wx.EVT_MENU(self, id, self.onResetModel)
1146   
1147    def _reset_plotting_range(self, state):
1148        """
1149        Reset the plotting range to a given state
1150        """
1151        # if self.check_invalid_panel():
1152        #    return
1153        self.qmin.SetValue(str(state.qmin))
1154        self.qmax.SetValue(str(state.qmax)) 
1155
1156    def _save_typeOfmodel(self):
1157        """
1158        save radiobutton containing the type model that can be selected
1159        """
1160        self.state.shape_rbutton = self.shape_rbutton.GetValue()
1161        self.state.shape_indep_rbutton = self.shape_indep_rbutton.GetValue()
1162        self.state.struct_rbutton = self.struct_rbutton.GetValue()
1163        self.state.plugin_rbutton = self.plugin_rbutton.GetValue()
1164        self.state.structurebox= self.structurebox.GetCurrentSelection()
1165        self.state.formfactorbox = self.formfactorbox.GetCurrentSelection()
1166       
1167        #self._undo.Enable(True)
1168        ## post state to fit panel
1169        event = PageInfoEvent(page = self)
1170        wx.PostEvent(self.parent, event)
1171       
1172    def _save_plotting_range(self ):
1173        """
1174        save the state of plotting range
1175        """
1176        self.state.qmin = self.qmin_x
1177        self.state.qmax = self.qmax_x
1178        self.state.npts = self.npts_x
1179           
1180    def _onparamEnter_helper(self):
1181        """
1182        check if values entered by the user are changed and valid to replot
1183        model
1184        """
1185        # Flag to register when a parameter has changed.   
1186        is_modified = False
1187        self.fitrange = True
1188        is_2Ddata = False
1189        #self._undo.Enable(True)
1190        # check if 2d data
1191        if self.data.__class__.__name__ == "Data2D":
1192            is_2Ddata = True
1193        if self.model !=None:
1194            try:
1195                is_modified = self._check_value_enter(self.fittable_param,
1196                                                     is_modified)
1197                is_modified = self._check_value_enter(self.fixed_param,
1198                                                      is_modified)
1199                is_modified = self._check_value_enter(self.parameters,
1200                                                      is_modified) 
1201            except:
1202                pass
1203            #if is_modified:
1204
1205            # Here we should check whether the boundaries have been modified.
1206            # If qmin and qmax have been modified, update qmin and qmax and
1207            # set the is_modified flag to True
1208            if self._validate_qrange(self.qmin, self.qmax):
1209                tempmin = float(self.qmin.GetValue())
1210                if tempmin != self.qmin_x:
1211                    self.qmin_x = tempmin
1212                    is_modified = True
1213                tempmax = float(self.qmax.GetValue())
1214                if tempmax != self.qmax_x:
1215                    self.qmax_x = tempmax
1216                    is_modified = True
1217           
1218                if is_2Ddata:
1219                    # set mask   
1220                    is_modified = self._validate_Npts()
1221                   
1222            else:
1223                self.fitrange = False   
1224           
1225            ## if any value is modify draw model with new value
1226            if not self.fitrange:
1227                #self.btFit.Disable()
1228                if is_2Ddata: self.btEditMask.Disable()
1229            else:
1230                #self.btFit.Enable(True)
1231                if is_2Ddata: self.btEditMask.Enable(True)
1232            if is_modified and self.fitrange:
1233                if self.data == None:
1234                    # Theory case: need to get npts value to draw
1235                    self.npts_x = float(self.Npts_total.GetValue())
1236                self.state_change= True
1237                self._draw_model() 
1238                self.Refresh()
1239        return is_modified
1240   
1241    def _update_paramv_on_fit(self):
1242        """
1243        make sure that update param values just before the fitting
1244        """
1245        #flag for qmin qmax check values
1246        flag = True
1247        self.fitrange = True
1248        is_modified = False
1249
1250        #wx.PostEvent(self._manager.parent, StatusEvent(status=" \
1251        #updating ... ",type="update"))
1252
1253        ##So make sure that update param values on_Fit.
1254        #self._undo.Enable(True)
1255        if self.model !=None:           
1256            ##Check the values
1257            self._check_value_enter( self.fittable_param ,is_modified)
1258            self._check_value_enter( self.fixed_param ,is_modified)
1259            self._check_value_enter( self.parameters ,is_modified)
1260
1261            # If qmin and qmax have been modified, update qmin and qmax and
1262             # Here we should check whether the boundaries have been modified.
1263            # If qmin and qmax have been modified, update qmin and qmax and
1264            # set the is_modified flag to True
1265            self.fitrange = self._validate_qrange(self.qmin, self.qmax)
1266            if self.fitrange:
1267                tempmin = float(self.qmin.GetValue())
1268                if tempmin != self.qmin_x:
1269                    self.qmin_x = tempmin
1270                tempmax = float(self.qmax.GetValue())
1271                if tempmax != self.qmax_x:
1272                    self.qmax_x = tempmax
1273                if tempmax == tempmin:
1274                    flag = False   
1275                temp_smearer = None
1276                if not self.disable_smearer.GetValue():
1277                    temp_smearer= self.current_smearer
1278                    if self.slit_smearer.GetValue():
1279                        flag = self.update_slit_smear()
1280                    elif self.pinhole_smearer.GetValue():
1281                        flag = self.update_pinhole_smear()
1282                    else:
1283                        self._manager.set_smearer(smearer=temp_smearer,
1284                                                  uid=self.uid,
1285                                                     qmin=float(self.qmin_x),
1286                                                      qmax=float(self.qmax_x),
1287                                                      draw=False)
1288                elif not self._is_2D():
1289                    self._manager.set_smearer(smearer=temp_smearer,
1290                                              qmin=float(self.qmin_x),
1291                                              uid=self.uid, 
1292                                                 qmax= float(self.qmax_x))
1293                    if self.data != None:
1294                        index_data = ((self.qmin_x <= self.data.x)&\
1295                                      (self.data.x <= self.qmax_x))
1296                        val = str(len(self.data.x[index_data==True]))
1297                        self.Npts_fit.SetValue(val)
1298                    else:
1299                        # No data in the panel
1300                        try:
1301                            self.npts_x = float(self.Npts_total.GetValue())
1302                        except:
1303                            flag = False
1304                            return flag
1305                    flag = True
1306                if self._is_2D():
1307                    # only 2D case set mask 
1308                    flag = self._validate_Npts()
1309                    if not flag:
1310                        return flag
1311            else: flag = False
1312        else: 
1313            flag = False
1314
1315        #For invalid q range, disable the mask editor and fit button, vs.   
1316        if not self.fitrange:
1317            #self.btFit.Disable()
1318            if self._is_2D():self.btEditMask.Disable()
1319        else:
1320            #self.btFit.Enable(True)
1321            if self._is_2D():self.btEditMask.Enable(True)
1322
1323        if not flag:
1324            msg = "Cannot Plot or Fit :Must select a "
1325            msg += " model or Fitting range is not valid!!!  "
1326            wx.PostEvent(self.parent.parent, StatusEvent(status=msg))
1327       
1328        self.save_current_state()
1329   
1330        return flag                           
1331               
1332    def _is_modified(self, is_modified):
1333        """
1334        return to self._is_modified
1335        """
1336        return is_modified
1337                       
1338    def _reset_parameters_state(self, listtorestore, statelist):
1339        """
1340        Reset the parameters at the given state
1341        """
1342        if len(statelist) == 0 or len(listtorestore) == 0:
1343            return
1344        if len(statelist) !=  len(listtorestore):
1345            return
1346
1347        for j in range(len(listtorestore)):
1348            item_page = listtorestore[j]
1349            item_page_info = statelist[j]
1350            ##change the state of the check box for simple parameters
1351            if item_page[0]!=None:   
1352                item_page[0].SetValue(item_page_info[0])
1353            if item_page[2]!=None:
1354                item_page[2].SetValue(item_page_info[2])
1355                if item_page[2].__class__.__name__ == "ComboBox":
1356                   if self.model.fun_list.has_key(item_page_info[2]):
1357                       fun_val = self.model.fun_list[item_page_info[2]]
1358                       self.model.setParam(item_page_info[1],fun_val)
1359            if item_page[3]!=None:
1360                ## show or hide text +/-
1361                if item_page_info[2]:
1362                    item_page[3].Show(True)
1363                else:
1364                    item_page[3].Hide()
1365            if item_page[4]!=None:
1366                ## show of hide the text crtl for fitting error
1367                if item_page_info[4][0]:
1368                    item_page[4].Show(True)
1369                    item_page[4].SetValue(item_page_info[4][1])
1370                else:
1371                    item_page[3].Hide()
1372            if item_page[5]!=None:
1373                ## show of hide the text crtl for fitting error
1374                item_page[5].Show(item_page_info[5][0])
1375                item_page[5].SetValue(item_page_info[5][1])
1376               
1377            if item_page[6]!=None:
1378                ## show of hide the text crtl for fitting error
1379                item_page[6].Show(item_page_info[6][0])
1380                item_page[6].SetValue(item_page_info[6][1])
1381
1382                   
1383    def _reset_strparam_state(self, listtorestore, statelist):
1384        """
1385        Reset the string parameters at the given state
1386        """
1387        if len(statelist) == 0:
1388            return
1389
1390        listtorestore = copy.deepcopy(statelist)
1391       
1392        for j in range(len(listtorestore)):
1393            item_page = listtorestore[j]
1394            item_page_info = statelist[j]
1395            ##change the state of the check box for simple parameters
1396           
1397            if item_page[0] != None:   
1398                item_page[0].SetValue(format_number(item_page_info[0], True))
1399
1400            if item_page[2] != None:
1401                param_name = item_page_info[1]
1402                value = item_page_info[2]
1403                selection = value
1404                if self.model.fun_list.has_key(value):
1405                    selection = self.model.fun_list[value]
1406                item_page[2].SetValue(selection)
1407                self.model.setParam(param_name, selection)
1408                                     
1409    def _copy_parameters_state(self, listtocopy, statelist):
1410        """
1411        copy the state of button
1412       
1413        :param listtocopy: the list of check button to copy
1414        :param statelist: list of state object to store the current state
1415       
1416        """
1417        if len(listtocopy)==0:
1418            return
1419       
1420        for item in listtocopy:
1421 
1422            checkbox_state = None
1423            if item[0]!= None:
1424                checkbox_state= item[0].GetValue()
1425            parameter_name = item[1]
1426            parameter_value = None
1427            if item[2]!=None:
1428                parameter_value = item[2].GetValue()
1429            static_text = None
1430            if item[3]!=None:
1431                static_text = item[3].IsShown()
1432            error_value = None
1433            error_state = None
1434            if item[4]!= None:
1435                error_value = item[4].GetValue()
1436                error_state = item[4].IsShown()
1437               
1438            min_value = None
1439            min_state = None
1440            if item[5]!= None:
1441                min_value = item[5].GetValue()
1442                min_state = item[5].IsShown()
1443               
1444            max_value = None
1445            max_state = None
1446            if item[6]!= None:
1447                max_value = item[6].GetValue()
1448                max_state = item[6].IsShown()
1449            unit=None
1450            if item[7]!=None:
1451                unit = item[7].GetLabel()
1452               
1453            statelist.append([checkbox_state, parameter_name, parameter_value,
1454                              static_text ,[error_state, error_value],
1455                                [min_state, min_value],
1456                                [max_state, max_value], unit])
1457           
1458    def _set_model_sizer_selection(self, model):
1459        """
1460        Display the sizer according to the type of the current model
1461        """
1462        if model == None:
1463            return
1464        if hasattr(model ,"s_model"):
1465           
1466            class_name = model.s_model.__class__
1467            name = model.s_model.name
1468            flag = (name != "NoStructure")
1469            if flag and \
1470                (class_name in self.model_list_box["Structure Factors"]):
1471                self.structurebox.Show()
1472                self.text2.Show()               
1473                self.structurebox.Enable()
1474                self.text2.Enable()
1475                items = self.structurebox.GetItems()
1476                self.sizer1.Layout()
1477               
1478                for i in range(len(items)):
1479                    if items[i]== str(name):
1480                        self.structurebox.SetSelection(i)
1481                        break
1482                   
1483        if hasattr(model ,"p_model"):
1484            class_name = model.p_model.__class__
1485            name = model.p_model.name
1486            self.formfactorbox.Clear()
1487           
1488            for k, list in self.model_list_box.iteritems():
1489                if k in["P(Q)*S(Q)","Shapes" ] and class_name in self.model_list_box["Shapes"]:
1490                    self.shape_rbutton.SetValue(True)
1491                    ## fill the form factor list with new model
1492                    self._populate_box(self.formfactorbox,self.model_list_box["Shapes"])
1493                    items = self.formfactorbox.GetItems()
1494                    ## set comboxbox to the selected item
1495                    for i in range(len(items)):
1496                        if items[i]== str(name):
1497                            self.formfactorbox.SetSelection(i)
1498                            break
1499                    return
1500                elif k == "Shape-Independent":
1501                    self.shape_indep_rbutton.SetValue(True)
1502                elif k == "Structure Factors":
1503                     self.struct_rbutton.SetValue(True)
1504                elif  k == "Multi-Functions":
1505                    continue
1506                else:
1507                    self.plugin_rbutton.SetValue(True)
1508               
1509                if class_name in list:
1510                    ## fill the form factor list with new model
1511                    self._populate_box(self.formfactorbox, list)
1512                    items = self.formfactorbox.GetItems()
1513                    ## set comboxbox to the selected item
1514                    for i in range(len(items)):
1515                        if items[i]== str(name):
1516                            self.formfactorbox.SetSelection(i)
1517                            break
1518                    break
1519        else:
1520
1521            ## Select the model from the menu
1522            class_name = model.__class__
1523            name = model.name
1524            self.formfactorbox.Clear()
1525            items = self.formfactorbox.GetItems()
1526   
1527            for k, list in self.model_list_box.iteritems():         
1528                if k in["P(Q)*S(Q)","Shapes" ] and class_name in self.model_list_box["Shapes"]:
1529                    if class_name in self.model_list_box["P(Q)*S(Q)"]:
1530                        self.structurebox.Show()
1531                        self.text2.Show()
1532                        self.structurebox.Enable()
1533                        self.structurebox.SetSelection(0)
1534                        self.text2.Enable()
1535                    else:
1536                        self.structurebox.Hide()
1537                        self.text2.Hide()
1538                        self.structurebox.Disable()
1539                        self.structurebox.SetSelection(0)
1540                        self.text2.Disable()
1541                       
1542                    self.shape_rbutton.SetValue(True)
1543                    ## fill the form factor list with new model
1544                    self._populate_box(self.formfactorbox,self.model_list_box["Shapes"])
1545                    items = self.formfactorbox.GetItems()
1546                    ## set comboxbox to the selected item
1547                    for i in range(len(items)):
1548                        if items[i]== str(name):
1549                            self.formfactorbox.SetSelection(i)
1550                            break
1551                    return
1552                elif k == "Shape-Independent":
1553                    self.shape_indep_rbutton.SetValue(True)
1554                elif k == "Structure Factors":
1555                    self.struct_rbutton.SetValue(True)
1556                elif  k == "Multi-Functions":
1557                    continue
1558                else:
1559                    self.plugin_rbutton.SetValue(True)
1560                if class_name in list:
1561                    self.structurebox.SetSelection(0)
1562                    self.structurebox.Disable()
1563                    self.text2.Disable()                   
1564                    ## fill the form factor list with new model
1565                    self._populate_box(self.formfactorbox, list)
1566                    items = self.formfactorbox.GetItems()
1567                    ## set comboxbox to the selected item
1568                    for i in range(len(items)):
1569                        if items[i]== str(name):
1570                            self.formfactorbox.SetSelection(i)
1571                            break
1572                    break
1573   
1574    def _draw_model(self, update_chisqr=True):
1575        """
1576        Method to draw or refresh a plotted model.
1577        The method will use the data member from the model page
1578        to build a call to the fitting perspective manager.
1579       
1580        :param chisqr: update chisqr value [bool]
1581        """
1582        #if self.check_invalid_panel():
1583        #    return
1584        if self.model !=None:
1585            temp_smear=None
1586            if hasattr(self, "enable_smearer"):
1587                if not self.disable_smearer.GetValue():
1588                    temp_smear= self.current_smearer
1589            toggle_mode_on = self.model_view.IsEnabled()
1590            self._manager.draw_model(self.model, 
1591                                    data=self.data,
1592                                    smearer= temp_smear,
1593                                    qmin=float(self.qmin_x), 
1594                                    qmax=float(self.qmax_x),
1595                                    qstep= float(self.npts_x),
1596                                    page_id=self.uid,
1597                                    toggle_mode_on=toggle_mode_on, 
1598                                    state = self.state,
1599                                    enable2D=self.enable2D,
1600                                    update_chisqr=update_chisqr)
1601       
1602       
1603    def _on_show_sld(self, event=None):
1604        """
1605        Plot SLD profile
1606        """
1607        # get profile data
1608        x,y=self.model.getProfile()
1609
1610        from danse.common.plottools import Data1D
1611        #from sans.perspectives.theory.profile_dialog import SLDPanel
1612        from sans.guiframe.local_perspectives.plotting.profile_dialog \
1613        import SLDPanel
1614        sld_data = Data1D(x,y)
1615        sld_data.name = 'SLD'
1616        sld_data.axes = self.sld_axes
1617        self.panel = SLDPanel(self, data=sld_data,axes =self.sld_axes,id =-1 )
1618        self.panel.ShowModal()   
1619       
1620    def _set_multfactor_combobox(self, multiplicity=10):   
1621        """
1622        Set comboBox for muitfactor of CoreMultiShellModel
1623        :param multiplicit: no. of multi-functionality
1624        """
1625        # build content of the combobox
1626        for idx in range(0,multiplicity):
1627            self.multifactorbox.Append(str(idx),int(idx))
1628            #self.multifactorbox.SetSelection(1)
1629        self._hide_multfactor_combobox()
1630       
1631    def _show_multfactor_combobox(self):   
1632        """
1633        Show the comboBox of muitfactor of CoreMultiShellModel
1634        """ 
1635        if not self.mutifactor_text.IsShown():
1636            self.mutifactor_text.Show(True)
1637            self.mutifactor_text1.Show(True)
1638        if not self.multifactorbox.IsShown():
1639            self.multifactorbox.Show(True) 
1640             
1641    def _hide_multfactor_combobox(self):   
1642        """
1643        Hide the comboBox of muitfactor of CoreMultiShellModel
1644        """ 
1645        if self.mutifactor_text.IsShown():
1646            self.mutifactor_text.Hide()
1647            self.mutifactor_text1.Hide()
1648        if self.multifactorbox.IsShown():
1649            self.multifactorbox.Hide()   
1650
1651       
1652    def _show_combox_helper(self):
1653        """
1654        Fill panel's combo box according to the type of model selected
1655        """
1656        if self.shape_rbutton.GetValue():
1657            ##fill the combobox with form factor list
1658            self.structurebox.SetSelection(0)
1659            self.structurebox.Disable()
1660            self.formfactorbox.Clear()
1661            self._populate_box( self.formfactorbox,self.model_list_box["Shapes"])
1662        if self.shape_indep_rbutton.GetValue():
1663            ##fill the combobox with shape independent  factor list
1664            self.structurebox.SetSelection(0)
1665            self.structurebox.Disable()
1666            self.formfactorbox.Clear()
1667            self._populate_box( self.formfactorbox,
1668                                self.model_list_box["Shape-Independent"])
1669        if self.struct_rbutton.GetValue():
1670            ##fill the combobox with structure factor list
1671            self.structurebox.SetSelection(0)
1672            self.structurebox.Disable()
1673            self.formfactorbox.Clear()
1674            self._populate_box( self.formfactorbox,
1675                                self.model_list_box["Structure Factors"])
1676        if self.plugin_rbutton.GetValue():
1677            ##fill the combobox with form factor list
1678            self.structurebox.Disable()
1679            self.formfactorbox.Clear()
1680            self._populate_box( self.formfactorbox,
1681                                self.model_list_box["Customized Models"])
1682       
1683    def _show_combox(self, event=None):
1684        """
1685        Show combox box associate with type of model selected
1686        """
1687        #if self.check_invalid_panel():
1688        #    self.shape_rbutton.SetValue(True)
1689        #    return
1690
1691        self._show_combox_helper()
1692        self._on_select_model(event=None)
1693        self._save_typeOfmodel()
1694        self.sizer4_4.Layout()
1695        self.sizer4.Layout()
1696        self.Layout()
1697        self.Refresh()
1698 
1699    def _populate_box(self, combobox, list):
1700        """
1701        fill combox box with dict item
1702       
1703        :param list: contains item to fill the combox
1704            item must model class
1705        """
1706        for models in list:
1707            model= models()
1708            name = model.__class__.__name__
1709            if models.__name__!="NoStructure":
1710                if hasattr(model, "name"):
1711                    name = model.name
1712                combobox.Append(name,models)
1713        return 0
1714   
1715    def _onQrangeEnter(self, event):
1716        """
1717        Check validity of value enter in the Q range field
1718       
1719        """
1720        tcrtl = event.GetEventObject()
1721        #Clear msg if previously shown.
1722        msg = ""
1723        wx.PostEvent(self.parent, StatusEvent(status=msg))
1724        # Flag to register when a parameter has changed.
1725        is_modified = False
1726        if tcrtl.GetValue().lstrip().rstrip() != "":
1727            try:
1728                value = float(tcrtl.GetValue())
1729                tcrtl.SetBackgroundColour(wx.WHITE)
1730                # If qmin and qmax have been modified, update qmin and qmax
1731                if self._validate_qrange(self.qmin, self.qmax):
1732                    tempmin = float(self.qmin.GetValue())
1733                    if tempmin != self.qmin_x:
1734                        self.qmin_x = tempmin
1735                    tempmax = float(self.qmax.GetValue())
1736                    if tempmax != self.qmax_x:
1737                        self.qmax_x = tempmax
1738                else:
1739                    tcrtl.SetBackgroundColour("pink")
1740                    msg = "Model Error:wrong value entered : %s" % sys.exc_value
1741                    wx.PostEvent(self.parent, StatusEvent(status=msg))
1742                    return 
1743            except:
1744                tcrtl.SetBackgroundColour("pink")
1745                msg = "Model Error:wrong value entered : %s" % sys.exc_value
1746                wx.PostEvent(self.parent, StatusEvent(status=msg))
1747                return 
1748            #Check if # of points for theory model are valid(>0).
1749            if self.npts != None:
1750                if check_float(self.npts):
1751                    temp_npts = float(self.npts.GetValue())
1752                    if temp_npts !=  self.num_points:
1753                        self.num_points = temp_npts
1754                        is_modified = True
1755                else:
1756                    msg = "Cannot Plot :No npts in that Qrange!!!  "
1757                    wx.PostEvent(self.parent, StatusEvent(status=msg))
1758        else:
1759           tcrtl.SetBackgroundColour("pink")
1760           msg = "Model Error:wrong value entered!!!"
1761           wx.PostEvent(self.parent, StatusEvent(status=msg))
1762        #self._undo.Enable(True)
1763        self.save_current_state()
1764        event = PageInfoEvent(page=self)
1765        wx.PostEvent(self.parent, event)
1766        self.state_change = False
1767        #Draw the model for a different range
1768        self._draw_model()
1769                   
1770    def _theory_qrange_enter(self, event):
1771        """
1772        Check validity of value enter in the Q range field
1773        """
1774       
1775        tcrtl= event.GetEventObject()
1776        #Clear msg if previously shown.
1777        msg= ""
1778        wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
1779        # Flag to register when a parameter has changed.
1780        is_modified = False
1781        if tcrtl.GetValue().lstrip().rstrip()!="":
1782            try:
1783                value = float(tcrtl.GetValue())
1784                tcrtl.SetBackgroundColour(wx.WHITE)
1785
1786                # If qmin and qmax have been modified, update qmin and qmax
1787                if self._validate_qrange(self.theory_qmin, self.theory_qmax):
1788                    tempmin = float(self.theory_qmin.GetValue())
1789                    if tempmin != self.theory_qmin_x:
1790                        self.theory_qmin_x = tempmin
1791                    tempmax = float(self.theory_qmax.GetValue())
1792                    if tempmax != self.qmax_x:
1793                        self.theory_qmax_x = tempmax
1794                else:
1795                    tcrtl.SetBackgroundColour("pink")
1796                    msg= "Model Error:wrong value entered : %s"% sys.exc_value
1797                    wx.PostEvent(self._manager.parent, StatusEvent(status = msg ))
1798                    return 
1799            except:
1800                tcrtl.SetBackgroundColour("pink")
1801                msg= "Model Error:wrong value entered : %s"% sys.exc_value
1802                wx.PostEvent(self._manager.parent, StatusEvent(status = msg ))
1803                return 
1804            #Check if # of points for theory model are valid(>0).
1805            if self.Npts_total.IsEditable() :
1806                if check_float(self.Npts_total):
1807                    temp_npts = float(self.Npts_total.GetValue())
1808                    if temp_npts !=  self.num_points:
1809                        self.num_points = temp_npts
1810                        is_modified = True
1811                else:
1812                    msg= "Cannot Plot :No npts in that Qrange!!!  "
1813                    wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
1814        else:
1815           tcrtl.SetBackgroundColour("pink")
1816           msg = "Model Error:wrong value entered!!!"
1817           wx.PostEvent(self.parent.parent, StatusEvent(status=msg))
1818        #self._undo.Enable(True)
1819        self.save_current_state()
1820        event = PageInfoEvent(page = self)
1821        wx.PostEvent(self.parent, event)
1822        self.state_change= False
1823        #Draw the model for a different range
1824        self._draw_model()
1825                   
1826    def _on_select_model_helper(self): 
1827        """
1828        call back for model selection
1829        """
1830        ## reset dictionary containing reference to dispersion
1831        self._disp_obj_dict = {}
1832        self.disp_cb_dict ={}
1833       
1834        f_id = self.formfactorbox.GetCurrentSelection()
1835        #For MAC
1836        form_factor = None
1837        if f_id >= 0:
1838            form_factor = self.formfactorbox.GetClientData(f_id)
1839
1840        if not form_factor in  self.model_list_box["multiplication"]:
1841            self.structurebox.Hide()
1842            self.text2.Hide()           
1843            self.structurebox.Disable()
1844            self.structurebox.SetSelection(0)
1845            self.text2.Disable()
1846        else:
1847            self.structurebox.Show()
1848            self.text2.Show()
1849            self.structurebox.Enable()
1850            self.text2.Enable()
1851           
1852        if form_factor != None:   
1853            # set multifactor for Mutifunctional models   
1854            if form_factor().__class__ in self.model_list_box["Multi-Functions"]:
1855                m_id = self.multifactorbox.GetCurrentSelection()
1856                multiplicity = form_factor().multiplicity_info[0]
1857                self.multifactorbox.Clear()
1858                #self.mutifactor_text.SetLabel(form_factor().details[])
1859                self._set_multfactor_combobox(multiplicity)
1860                self._show_multfactor_combobox()
1861                #ToDo:  this info should be called directly from the model
1862                text = form_factor().multiplicity_info[1]#'No. of Shells: '
1863
1864                #self.mutifactor_text.Clear()
1865                self.mutifactor_text.SetLabel(text)
1866                if m_id > multiplicity -1:
1867                    # default value
1868                    m_id = 1
1869                   
1870                self.multi_factor = self.multifactorbox.GetClientData(m_id)
1871                if self.multi_factor == None: self.multi_factor =0
1872                form_factor = form_factor(int(self.multi_factor))
1873                self.multifactorbox.SetSelection(m_id)
1874                # Check len of the text1 and max_multiplicity
1875                text = ''
1876                if form_factor.multiplicity_info[0] == len(form_factor.multiplicity_info[2]):
1877                    text = form_factor.multiplicity_info[2][self.multi_factor]
1878                self.mutifactor_text1.SetLabel(text)
1879                # Check if model has  get sld profile.
1880                if len(form_factor.multiplicity_info[3]) > 0:
1881                    self.sld_axes = form_factor.multiplicity_info[3]
1882                    self.show_sld_button.Show(True)
1883                else:
1884                    self.sld_axes = ""
1885
1886            else:
1887                self._hide_multfactor_combobox()
1888                self.show_sld_button.Hide()
1889                form_factor = form_factor()
1890                self.multi_factor = None
1891        else:
1892            self._hide_multfactor_combobox()
1893            self.show_sld_button.Hide()
1894            self.multi_factor = None 
1895             
1896        s_id = self.structurebox.GetCurrentSelection()
1897        struct_factor = self.structurebox.GetClientData( s_id )
1898       
1899        if  struct_factor !=None:
1900            from sans.models.MultiplicationModel import MultiplicationModel
1901            self.model= MultiplicationModel(form_factor,struct_factor())
1902           
1903        else:
1904            if form_factor != None:
1905                self.model= form_factor
1906            else:
1907                self.model = None
1908                return self.model
1909           
1910
1911        ## post state to fit panel
1912        self.state.parameters =[]
1913        self.state.model =self.model
1914        self.state.qmin = self.qmin_x
1915        self.state.multi_factor = self.multi_factor
1916        self.disp_list =self.model.getDispParamList()
1917        self.state.disp_list = self.disp_list
1918        self.on_set_focus(None)
1919        self.Layout()     
1920       
1921    def _validate_qrange(self, qmin_ctrl, qmax_ctrl):
1922        """
1923        Verify that the Q range controls have valid values
1924        and that Qmin < Qmax.
1925       
1926        :param qmin_ctrl: text control for Qmin
1927        :param qmax_ctrl: text control for Qmax
1928       
1929        :return: True is the Q range is value, False otherwise
1930       
1931        """
1932        qmin_validity = check_float(qmin_ctrl)
1933        qmax_validity = check_float(qmax_ctrl)
1934        if not (qmin_validity and qmax_validity):
1935            return False
1936        else:
1937            qmin = float(qmin_ctrl.GetValue())
1938            qmax = float(qmax_ctrl.GetValue())
1939            if qmin <= qmax:
1940                #Make sure to set both colours white. 
1941                qmin_ctrl.SetBackgroundColour(wx.WHITE)
1942                qmin_ctrl.Refresh()
1943                qmax_ctrl.SetBackgroundColour(wx.WHITE)
1944                qmax_ctrl.Refresh()
1945            else:
1946                qmin_ctrl.SetBackgroundColour("pink")
1947                qmin_ctrl.Refresh()
1948                qmax_ctrl.SetBackgroundColour("pink")
1949                qmax_ctrl.Refresh()
1950                msg= "Invalid Q range: Q min must be smaller than Q max"
1951                wx.PostEvent(self.parent.parent, StatusEvent(status = msg))
1952                return False
1953        return True
1954   
1955    def _validate_Npts(self): 
1956        """
1957        Validate the number of points for fitting is more than 10 points.
1958        If valid, setvalues Npts_fit otherwise post msg.
1959        """
1960        #default flag
1961        flag = True
1962        # Theory
1963        if self.data == None and self.enable2D:
1964            return flag
1965
1966        # q value from qx and qy
1967        radius= numpy.sqrt( self.data.qx_data * self.data.qx_data + 
1968                            self.data.qy_data * self.data.qy_data )
1969        #get unmasked index
1970        index_data = (float(self.qmin.GetValue()) <= radius) & \
1971                        (radius <= float(self.qmax.GetValue()))
1972        index_data = (index_data) & (self.data.mask) 
1973        index_data = (index_data) & (numpy.isfinite(self.data.data))
1974
1975        if len(index_data[index_data]) < 10:
1976            # change the color pink.
1977            self.qmin.SetBackgroundColour("pink")
1978            self.qmin.Refresh()
1979            self.qmax.SetBackgroundColour("pink")
1980            self.qmax.Refresh()
1981            msg= "Cannot Plot :No or too little npts in that data range!!!  "
1982            wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
1983            self.fitrange = False
1984            flag = False
1985        else:
1986            self.Npts_fit.SetValue(str(len(self.data.mask[index_data==True])))
1987            self.fitrange = True
1988           
1989        return flag
1990   
1991    def _check_value_enter(self, list, modified):
1992        """
1993        :param list: model parameter and panel info
1994        :Note: each item of the list should be as follow:
1995            item=[check button state, parameter's name,
1996                paramater's value, string="+/-",
1997                parameter's error of fit,
1998                parameter's minimum value,
1999                parrameter's maximum value ,
2000                parameter's units]
2001        """ 
2002        is_modified =  modified
2003        if len(list)==0:
2004            return is_modified
2005        for item in list:
2006            #skip angle parameters for 1D
2007            if not self.enable2D:#self.data.__class__.__name__ !="Data2D":
2008                if item in self.orientation_params:
2009                    continue
2010            #try:
2011            name = str(item[1])
2012           
2013            if string.find(name,".npts") ==-1 and \
2014                                        string.find(name,".nsigmas")==-1:     
2015                ## check model parameters range             
2016                param_min= None
2017                param_max= None
2018               
2019                ## check minimun value
2020                if item[5]!= None and item[5]!= "":
2021                    if item[5].GetValue().lstrip().rstrip()!="":
2022                        try:
2023                           
2024                            param_min = float(item[5].GetValue())
2025                            if not self._validate_qrange(item[5],item[2]):
2026                                if numpy.isfinite(param_min):
2027                                    item[2].SetValue(format_number(param_min))
2028                           
2029                            item[5].SetBackgroundColour(wx.WHITE)
2030                            item[2].SetBackgroundColour(wx.WHITE)
2031                                           
2032                        except:
2033                            msg = "Wrong Fit parameter range entered "
2034                            wx.PostEvent(self.parent.parent, 
2035                                         StatusEvent(status = msg))
2036                            raise ValueError, msg
2037                        is_modified = True
2038                ## check maximum value
2039                if item[6]!= None and item[6]!= "":
2040                    if item[6].GetValue().lstrip().rstrip()!="":
2041                        try:                         
2042                            param_max = float(item[6].GetValue())
2043                            if not self._validate_qrange(item[2],item[6]):
2044                                if numpy.isfinite(param_max):
2045                                    item[2].SetValue(format_number(param_max)) 
2046                           
2047                            item[6].SetBackgroundColour(wx.WHITE)
2048                            item[2].SetBackgroundColour(wx.WHITE)
2049                        except:
2050                            msg = "Wrong Fit parameter range entered "
2051                            wx.PostEvent(self.parent.parent, 
2052                                         StatusEvent(status = msg))
2053                            raise ValueError, msg
2054                        is_modified = True
2055               
2056
2057                if param_min != None and param_max !=None:
2058                    if not self._validate_qrange(item[5], item[6]):
2059                        msg= "Wrong Fit range entered for parameter "
2060                        msg+= "name %s of model %s "%(name, self.model.name)
2061                        wx.PostEvent(self.parent.parent, 
2062                                     StatusEvent(status = msg))
2063               
2064                if name in self.model.details.keys():   
2065                        self.model.details[name][1:3] = param_min, param_max
2066                        is_modified = True
2067             
2068                else:
2069                        self.model.details [name] = ["", param_min, param_max] 
2070                        is_modified = True
2071            try:   
2072                # Check if the textctr is enabled
2073                if item[2].IsEnabled():
2074                    value= float(item[2].GetValue())
2075                    item[2].SetBackgroundColour("white")
2076                    # If the value of the parameter has changed,
2077                    # +update the model and set the is_modified flag
2078                    if value != self.model.getParam(name) and \
2079                                                numpy.isfinite(value):
2080                        self.model.setParam(name, value)
2081                       
2082            except:
2083                item[2].SetBackgroundColour("pink")
2084                msg = "Wrong Fit parameter value entered "
2085                wx.PostEvent(self.parent.parent, StatusEvent(status = msg))
2086               
2087        return is_modified
2088       
2089 
2090    def _set_dipers_Param(self, event):
2091        """
2092        respond to self.enable_disp and self.disable_disp radio box.
2093        The dispersity object is reset inside the model into Gaussian.
2094        When the user select yes , this method display a combo box for more selection
2095        when the user selects No,the combo box disappears.
2096        Redraw the model with the default dispersity (Gaussian)
2097        """
2098        #if self.check_invalid_panel():
2099        #    return
2100        ## On selction if no model exists.
2101        if self.model ==None:
2102            self.disable_disp.SetValue(True)
2103            msg="Please select a Model first..."
2104            wx.MessageBox(msg, 'Info')
2105            wx.PostEvent(self._manager.parent, StatusEvent(status=\
2106                            "Polydispersion: %s"%msg))
2107            return
2108
2109        self._reset_dispersity()
2110   
2111        if self.model ==None:
2112            self.model_disp.Hide()
2113            self.sizer4_4.Clear(True)
2114            return
2115
2116        if self.enable_disp.GetValue():
2117            ## layout for model containing no dispersity parameters
2118           
2119            self.disp_list= self.model.getDispParamList()
2120             
2121            if len(self.disp_list)==0 and len(self.disp_cb_dict)==0:
2122                self._layout_sizer_noDipers() 
2123            else:
2124                ## set gaussian sizer
2125                self._on_select_Disp(event=None)
2126        else:
2127            self.sizer4_4.Clear(True)
2128           
2129        ## post state to fit panel
2130        self.save_current_state()
2131        if event !=None:
2132            #self._undo.Enable(True)
2133            event = PageInfoEvent(page = self)
2134            wx.PostEvent(self.parent, event)
2135        #draw the model with the current dispersity
2136        self._draw_model()
2137        self.sizer4_4.Layout()
2138        self.sizer5.Layout()
2139        self.Layout()
2140        self.Refresh()     
2141         
2142       
2143    def _layout_sizer_noDipers(self):
2144        """
2145        Draw a sizer with no dispersity info
2146        """
2147        ix=0
2148        iy=1
2149        self.fittable_param=[]
2150        self.fixed_param=[]
2151        self.orientation_params_disp=[]
2152       
2153        self.sizer4_4.Clear(True)
2154        text = "No polydispersity available for this model"
2155        text = "No polydispersity available for this model"
2156        model_disp = wx.StaticText(self, -1, text)
2157        self.sizer4_4.Add(model_disp,( iy, ix),(1,1), 
2158                            wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 10)
2159        self.sizer4_4.Layout()
2160        self.sizer4.Layout()
2161   
2162    def _reset_dispersity(self):
2163        """
2164        put gaussian dispersity into current model
2165        """
2166        if len(self.param_toFit)>0:
2167            for item in self.fittable_param:
2168                if item in self.param_toFit:
2169                    self.param_toFit.remove(item)
2170
2171            for item in self.orientation_params_disp:
2172                if item in self.param_toFit:
2173                    self.param_toFit.remove(item)
2174         
2175        self.fittable_param=[]
2176        self.fixed_param=[]
2177        self.orientation_params_disp=[]
2178        self.values={}
2179        self.weights={}
2180     
2181        from sans.models.dispersion_models import GaussianDispersion, ArrayDispersion
2182        if len(self.disp_cb_dict)==0:
2183            self.save_current_state()
2184            self.sizer4_4.Clear(True)
2185            self.Layout()
2186 
2187            return 
2188        if (len(self.disp_cb_dict)>0) :
2189            for p in self.disp_cb_dict:
2190                # The parameter was un-selected. Go back to Gaussian model (with 0 pts)                   
2191                disp_model = GaussianDispersion()
2192               
2193                self._disp_obj_dict[p] = disp_model
2194                # Set the new model as the dispersion object for the selected parameter
2195                try:
2196                   self.model.set_dispersion(p, disp_model)
2197                except:
2198
2199                    pass
2200
2201        ## save state into
2202        self.save_current_state()
2203        self.Layout() 
2204        self.Refresh()
2205                 
2206    def _on_select_Disp(self,event):
2207        """
2208        allow selecting different dispersion
2209        self.disp_list should change type later .now only gaussian
2210        """
2211        self._set_sizer_dispersion()
2212
2213        ## Redraw the model
2214        self._draw_model() 
2215        #self._undo.Enable(True)
2216        event = PageInfoEvent(page = self)
2217        wx.PostEvent(self.parent, event)
2218       
2219        self.sizer4_4.Layout()
2220        self.sizer4.Layout()
2221        self.SetupScrolling()
2222   
2223    def _on_disp_func(self, event=None): 
2224        """
2225        Select a distribution function for the polydispersion
2226       
2227        :Param event: ComboBox event
2228        """
2229        # get ready for new event
2230        if event != None:
2231            event.Skip()
2232        # Get event object
2233        disp_box =  event.GetEventObject() 
2234
2235        # Try to select a Distr. function
2236        try:   
2237            disp_box.SetBackgroundColour("white")
2238            selection = disp_box.GetCurrentSelection()
2239            param_name = disp_box.Name.split('.')[0]
2240            disp_name = disp_box.GetValue()
2241            dispersity= disp_box.GetClientData(selection)
2242   
2243            #disp_model =  GaussianDispersion()
2244            disp_model = dispersity()
2245            # Get param names to reset the values of the param
2246            name1 = param_name + ".width"
2247            name2 = param_name + ".npts"
2248            name3 = param_name + ".nsigmas"
2249            # Check Disp. function whether or not it is 'array'
2250            if disp_name.lower() == "array":
2251                value2= ""
2252                value3= ""
2253                value1 = self._set_array_disp(name=name1, disp=disp_model)
2254            else:
2255                self._del_array_values(name1)
2256                #self._reset_array_disp(param_name)
2257                self._disp_obj_dict[name1] = disp_model
2258                self.model.set_dispersion(param_name, disp_model)
2259                self.state._disp_obj_dict[name1]= disp_model
2260 
2261                value1= str(format_number(self.model.getParam(name1), True))
2262                value2= str(format_number(self.model.getParam(name2)))
2263                value3= str(format_number(self.model.getParam(name3)))
2264            # Reset fittable polydispersin parameter value
2265            for item in self.fittable_param:
2266                 if item[1] == name1:
2267                    item[2].SetValue(value1) 
2268                    item[5].SetValue("")
2269                    item[6].SetValue("")
2270                    # Disable for array
2271                    if disp_name.lower() == "array":
2272                        item[0].SetValue(False)
2273                        item[0].Disable()
2274                        item[2].Disable()
2275                        item[5].Disable()
2276                        item[6].Disable()
2277                    else:
2278                        item[0].Enable()
2279                        item[2].Enable()
2280                        item[5].Enable()
2281                        item[6].Enable()                       
2282                    break
2283            # Reset fixed polydispersion params
2284            for item in self.fixed_param:
2285                if item[1] == name2:
2286                    item[2].SetValue(value2) 
2287                    # Disable Npts for array
2288                    if disp_name.lower() == "array":
2289                        item[2].Disable()
2290                    else:
2291                        item[2].Enable()
2292                if item[1] == name3:
2293                    item[2].SetValue(value3) 
2294                    # Disable Nsigs for array
2295                    if disp_name.lower() == "array":
2296                        item[2].Disable()
2297                    else:
2298                        item[2].Enable()
2299               
2300            # Make sure the check box updated when all checked
2301            if self.cb1.GetValue():
2302                self.select_all_param(None)
2303
2304            # update params
2305            self._update_paramv_on_fit() 
2306            # draw
2307            self._draw_model()
2308            self.Refresh()
2309        except:
2310            # Error msg
2311            msg = "Error occurred:"
2312            msg += " Could not select the distribution function..."
2313            msg += " Please select another distribution function."
2314            disp_box.SetBackgroundColour("pink")
2315            # Focus on Fit button so that users can see the pinky box
2316            self.btFit.SetFocus()
2317            wx.PostEvent(self.parent.parent, 
2318                         StatusEvent(status=msg, info="error"))
2319       
2320       
2321    def _set_array_disp(self, name=None, disp=None):
2322        """
2323        Set array dispersion
2324       
2325        :param name: name of the parameter for the dispersion to be set
2326        :param disp: the polydisperion object
2327        """
2328        # The user wants this parameter to be averaged.
2329        # Pop up the file selection dialog.
2330        path = self._selectDlg()
2331        # Array data
2332        values = []
2333        weights = []
2334        # If nothing was selected, just return
2335        if path is None:
2336            self.disp_cb_dict[name].SetValue(False)
2337            #self.noDisper_rbox.SetValue(True)
2338            return
2339        self._default_save_location = os.path.dirname(path)
2340
2341        basename  = os.path.basename(path)
2342        values,weights = self.read_file(path)
2343       
2344        # If any of the two arrays is empty, notify the user that we won't
2345        # proceed
2346        if len(self.param_toFit)>0:
2347            if name in self.param_toFit:
2348                self.param_toFit.remove(name)
2349
2350        # Tell the user that we are about to apply the distribution
2351        msg = "Applying loaded %s distribution: %s" % (name, path)
2352        wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 
2353
2354        disp.set_weights(values, weights)
2355        self._disp_obj_dict[name] = disp
2356        self.model.set_dispersion(name.split('.')[0], disp)
2357        self.state._disp_obj_dict[name]= disp
2358        self.values[name] = values
2359        self.weights[name] = weights
2360        # Store the object to make it persist outside the
2361        # scope of this method
2362        #TODO: refactor model to clean this up?
2363        self.state.values = {}
2364        self.state.weights = {}
2365        self.state.values = copy.deepcopy(self.values)
2366        self.state.weights = copy.deepcopy(self.weights)
2367
2368        # Set the new model as the dispersion object for the
2369        #selected parameter
2370        #self.model.set_dispersion(p, disp_model)
2371        # Store a reference to the weights in the model object
2372        #so that
2373        # it's not lost when we use the model within another thread.
2374        #TODO: total hack - fix this
2375        self.state.model= self.model.clone()
2376        self.model._persistency_dict[name.split('.')[0]] = \
2377                                        [values, weights]
2378        self.state.model._persistency_dict[name.split('.')[0]] = \
2379                                        [values,weights]
2380        return basename
2381   
2382    def _del_array_values(self, name=None): 
2383        """
2384        Reset array dispersion
2385       
2386        :param name: name of the parameter for the dispersion to be set
2387        """
2388        # Try to delete values and weight of the names array dic if exists
2389        try:
2390            del self.values[name]
2391            del self.weights[name]
2392            # delete all other dic
2393            del self.state.values[name]
2394            del self.state.weights[name]
2395            del self.model._persistency_dict[name.split('.')[0]] 
2396            del self.state.model._persistency_dict[name.split('.')[0]]
2397        except:
2398            pass
2399                                           
2400    def _lay_out(self):
2401        """
2402        returns self.Layout
2403       
2404        :Note: Mac seems to like this better when self.
2405            Layout is called after fitting.
2406        """
2407        self._sleep4sec()
2408        self.Layout()
2409        return 
2410   
2411    def _sleep4sec(self):
2412        """
2413            sleep for 1 sec only applied on Mac
2414            Note: This 1sec helps for Mac not to crash on self.:ayout after self._draw_model
2415        """
2416        if ON_MAC == True:
2417            time.sleep(1)
2418           
2419    def _find_polyfunc_selection(self, disp_func = None):
2420        """
2421        FInd Comboox selection from disp_func
2422       
2423        :param disp_function: dispersion distr. function
2424        """
2425        # List of the poly_model name in the combobox
2426        list = ["RectangleDispersion", "ArrayDispersion", 
2427                    "LogNormalDispersion", "GaussianDispersion", 
2428                    "SchulzDispersion"]
2429
2430        # Find the selection
2431        try:
2432            selection = list.index(disp_func.__class__.__name__)
2433            return selection
2434        except:
2435             return 3
2436                           
2437    def on_reset_clicked(self,event):
2438        """
2439        On 'Reset' button  for Q range clicked
2440        """
2441        flag = True
2442        #if self.check_invalid_panel():
2443        #    return
2444        ##For 3 different cases: Data2D, Data1D, and theory
2445        if self.model == None:
2446            msg="Please select a model first..."
2447            wx.MessageBox(msg, 'Info')
2448            flag = False
2449            return
2450           
2451        elif self.data.__class__.__name__ == "Data2D":
2452            data_min= 0
2453            x= max(math.fabs(self.data.xmin), math.fabs(self.data.xmax)) 
2454            y= max(math.fabs(self.data.ymin), math.fabs(self.data.ymax))
2455            self.qmin_x = data_min
2456            self.qmax_x = math.sqrt(x*x + y*y)
2457            # check smearing
2458            if not self.disable_smearer.GetValue():
2459                temp_smearer= self.current_smearer
2460                ## set smearing value whether or not the data contain the smearing info
2461                if self.pinhole_smearer.GetValue():
2462                    flag = self.update_pinhole_smear()
2463                else:
2464                    flag = True
2465                   
2466        elif self.data == None:
2467            self.qmin_x = _QMIN_DEFAULT
2468            self.qmax_x = _QMAX_DEFAULT
2469            self.num_points = _NPTS_DEFAULT           
2470            self.state.npts = self.num_points
2471           
2472        elif self.data.__class__.__name__ != "Data2D":
2473            self.qmin_x = min(self.data.x)
2474            self.qmax_x = max(self.data.x)
2475            # check smearing
2476            if not self.disable_smearer.GetValue():
2477                temp_smearer= self.current_smearer
2478                ## set smearing value whether or not the data contain the smearing info
2479                if self.slit_smearer.GetValue():
2480                    flag = self.update_slit_smear()
2481                elif self.pinhole_smearer.GetValue():
2482                    flag = self.update_pinhole_smear()
2483                else:
2484                    flag = True
2485        else:
2486            flag = False
2487           
2488        if flag == False:
2489            msg= "Cannot Plot :Must enter a number!!!  "
2490            wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
2491        else:
2492            # set relative text ctrs.
2493            self.qmin.SetValue(str(self.qmin_x))
2494            self.qmax.SetValue(str(self.qmax_x))
2495            self.set_npts2fit()
2496            # At this point, some button and variables satatus (disabled?) should be checked
2497            # such as color that should be reset to white in case that it was pink.
2498            self._onparamEnter_helper()
2499
2500        self.save_current_state()
2501        self.state.qmin = self.qmin_x
2502        self.state.qmax = self.qmax_x
2503       
2504        #reset the q range values
2505        self._reset_plotting_range(self.state)
2506        #self.compute_chisqr(smearer=self.current_smearer)
2507        #Re draw plot
2508        self._draw_model()
2509       
2510    def get_images(self):
2511        """
2512        Get the images of the plots corresponding this panel for report
2513       
2514        : return graphs: list of figures
2515        : TODO: Move to guiframe
2516        """
2517        # set list of graphs
2518        graphs = []
2519        canvases = []
2520        # call gui_manager
2521        gui_manager = self.parent.parent
2522        # loops through the panels [dic]
2523        for item1, item2 in gui_manager.panels.iteritems():
2524             data_title = self.data.group_id
2525             data_name = str(self.data.name).split(" [")[0]
2526            # try to get all plots belonging to this control panel
2527             try:
2528                 title = ''
2529                 # check titles (main plot)
2530                 if hasattr(item2,"data2D"):
2531                     title = item2.data2D.title
2532                 # and data_names (model plot[2D], and residuals)
2533                 if item2.group_id == data_title or \
2534                                title.count(data_name) or \
2535                                item2.window_name.count(data_name) or \
2536                                item2.window_caption.count(data_name):
2537                     #panel = gui_manager._mgr.GetPane(item2.window_name)
2538                     # append to the list
2539                     graphs.append(item2.figure) 
2540                     canvases.append(item2.canvas)     
2541             except:
2542                 # Not for control panels
2543                 pass
2544        # return the list of graphs
2545        return graphs, canvases
2546
2547    def on_model_help_clicked(self,event):
2548        """
2549        on 'More details' button
2550        """
2551        from help_panel import  HelpWindow
2552        import sans.models as models 
2553       
2554        # Get models help model_function path
2555        path = models.get_data_path(media='media')
2556        model_path = os.path.join(path,"model_functions.html")
2557        if self.model == None:
2558            name = 'FuncHelp'
2559        else:
2560            name = self.formfactorbox.GetValue()
2561            #name = self.model.__class__.__name__
2562        frame = HelpWindow(None, -1,  pageToOpen=model_path)   
2563        frame.Show(True)
2564        if frame.rhelp.HasAnchor(name):
2565            frame.rhelp.ScrollToAnchor(name)
2566        else:
2567           msg= "Model does not contains an available description "
2568           msg +="Please try searching in the Help window"
2569           wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))     
2570   
2571    def on_pd_help_clicked(self, event):
2572        """
2573        Button event for PD help
2574        """
2575        from help_panel import  HelpWindow
2576        import sans.models as models 
2577       
2578        # Get models help model_function path
2579        path = models.get_data_path(media='media')
2580        pd_path = os.path.join(path,"pd_help.html")
2581
2582        frame = HelpWindow(None, -1,  pageToOpen=pd_path)   
2583        frame.Show(True)
2584       
2585    def on_left_down(self, event):
2586        """
2587        Get key stroke event
2588        """
2589        # Figuring out key combo: Cmd for copy, Alt for paste
2590        if event.CmdDown() and event.ShiftDown():
2591            flag = self.get_paste()
2592        elif event.CmdDown():
2593            flag = self.get_copy()
2594        else:
2595            event.Skip()
2596            return
2597        # make event free
2598        event.Skip()
2599        # messages depending on the flag
2600        if flag == None:
2601            msg = " Parameter values are copied to the clipboard..."
2602            infor = 'warning'
2603        elif flag:
2604            msg = " Parameter values are pasted from the clipboad..."
2605            infor = "warning"
2606        else:
2607            msg = "Error was occured during pasting the parameter values "
2608            msg += "from the clipboard..."
2609            infor = "error"
2610        # inform msg to wx
2611        wx.PostEvent( self.parent.parent, 
2612                      StatusEvent(status= msg, info=infor))
2613       
2614           
2615    def get_copy(self): 
2616        """
2617        Get the string copies of the param names and values in the tap
2618        """ 
2619        content = 'sansview_parameter_values:'
2620        # Do it if params exist       
2621        if  self.parameters !=[]:
2622           
2623            # go through the parameters
2624            string = self._get_copy_helper(self.parameters, 
2625                                           self.orientation_params)
2626            content += string
2627           
2628            # go through the fittables
2629            string = self._get_copy_helper(self.fittable_param, 
2630                                           self.orientation_params_disp)
2631            content += string
2632
2633            # go through the fixed params
2634            string = self._get_copy_helper(self.fixed_param, 
2635                                           self.orientation_params_disp)
2636            content += string
2637               
2638            # go through the str params
2639            string = self._get_copy_helper(self.str_parameters, 
2640                                           self.orientation_params)
2641            content += string
2642
2643        if wx.TheClipboard.Open():
2644            wx.TheClipboard.SetData(wx.TextDataObject(str(content)))
2645            data = wx.TextDataObject()
2646            success = wx.TheClipboard.GetData(data)
2647            text = data.GetText()
2648            wx.TheClipboard.Close()
2649           
2650        return None
2651   
2652    def _get_copy_helper(self, param, orient_param):
2653        """
2654        Helping get value and name of the params
2655       
2656        : param param:  parameters
2657        : param orient_param = oritational params
2658        : return content: strings [list] [name,value:....]
2659        """
2660        content = ''
2661        # go through the str params
2662        for item in param: 
2663            # 2D
2664            if self.data.__class__.__name__== "Data2D":
2665                name = item[1]
2666                value = item[2].GetValue()
2667            # 1D
2668            else:
2669                ## for 1D all parameters except orientation
2670                if not item[1] in orient_param:
2671                    name = item[1]
2672                    value = item[2].GetValue()
2673            # add to the content
2674            content += name + ',' + value + ':'
2675           
2676        return content
2677   
2678    def get_paste(self): 
2679        """
2680        Get the string copies of the param names and values in the tap
2681        """ 
2682        context = {}
2683        text = ""
2684       
2685        # Get text from the clip board       
2686        if wx.TheClipboard.Open():
2687            if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)):
2688                data = wx.TextDataObject()
2689                # get wx dataobject
2690                success = wx.TheClipboard.GetData(data)
2691                # get text
2692                text = data.GetText()
2693            # close clipboard
2694            wx.TheClipboard.Close()
2695           
2696        # put the text into dictionary   
2697        lines = text.split(':')
2698        if lines[0] != 'sansview_parameter_values':
2699            return False
2700        for line in lines[1:-1]:
2701            if len(line) != 0:
2702                item =line.split(',')
2703                name = item[0]
2704                value = item[1]
2705                # Transfer the text to content[dictionary]
2706                context[name] = value
2707       
2708        # Do it if params exist       
2709        if  self.parameters != []:
2710            # go through the parameters 
2711            self._get_paste_helper(self.parameters, 
2712                                   self.orientation_params, context)
2713
2714            # go through the fittables
2715            self._get_paste_helper(self.fittable_param, 
2716                                   self.orientation_params_disp, context)
2717
2718            # go through the fixed params
2719            self._get_paste_helper(self.fixed_param, 
2720                                   self.orientation_params_disp, context)
2721           
2722            # go through the str params
2723            self._get_paste_helper(self.str_parameters, 
2724                                   self.orientation_params, context)
2725           
2726        return True
2727   
2728    def _get_paste_helper(self, param, orient_param, content):
2729        """
2730        Helping set values of the params
2731       
2732        : param param:  parameters
2733        : param orient_param: oritational params
2734        : param content: dictionary [ name, value: name1.value1,...]
2735        """
2736        # go through the str params
2737        for item in param: 
2738            # 2D
2739            if self.data.__class__.__name__== "Data2D":
2740                name = item[1]
2741                if name in content.keys():
2742                    item[2].SetValue(content[name])
2743            # 1D
2744            else:
2745                ## for 1D all parameters except orientation
2746                if not item[1] in orient_param:
2747                    name = item[1]
2748                    if name in content.keys():
2749                        # Avoid changing combox content which needs special care
2750                        if item[2].__class__.__name__ != "ComboBox":
2751                            item[2].SetValue(content[name])
2752                           
2753               
Note: See TracBrowser for help on using the repository browser.