Index: sansview/perspectives/fitting/basepage.py
===================================================================
--- sansview/perspectives/fitting/basepage.py	(revision 87a43fedbdc7b6600d724354da7ae1f6a5d7dd52)
+++ sansview/perspectives/fitting/basepage.py	(revision cfc091378ea439152bd4e2d41ece44c4e94ebece)
@@ -6,5 +6,7 @@
 from sans.guiframe.utils import format_number
 from sans.guicomm.events import StatusEvent   
-
+import pagestate
+from pagestate import PageState
+(PageInfoEvent, EVT_PAGE_INFO)   = wx.lib.newevent.NewEvent()
 _BOX_WIDTH = 80
 
@@ -13,30 +15,28 @@
         This class provide general structure of  fitpanel page
     """
-    ## Internal name for the AUI manager
-    window_name = "Fit page"
-    ## Title to appear on top of the window
-    window_caption = "Fit Page"
-    
-    name=""
-    
-    def __init__(self,parent, pageinfo, name):
+    
+    def __init__(self,parent, page_info):
         wx.ScrolledWindow.__init__(self, parent)
         ## store name
-        self.name = name
-        ## store info of panel
-        self.page_info= pageinfo
-        self.page_info.page_name = name
+        self.name = page_info.name
+        ##window_name
+        self.window_name = page_info.window_name
+        ##window_caption
+        self.window_caption = page_info.window_caption
         ## parent of the page
         self.parent = parent
         ## manager is the fitting plugin
-        self.manager=None
+        self.manager= page_info.manager
         ## owner of the page (fitting plugin)
-        self.event_owner= None
-        ## create the basic structure of the panel with empty sizer
-        self.define_page_structure()
+        self.event_owner= page_info.event_owner
+         ## current model
+        self.model = page_info.model
+        ## data
+        self.data = page_info.data
         ## dictionary containing list of models
-        self.model_list_box={}
+        self.model_list_box = page_info.model_list_box
         ## Data member to store the dispersion object created
         self._disp_obj_dict = {}
+        ## selected parameters to apply dispersion
         self.disp_cb_dict ={}
         ##list of model parameters. each item must have same length
@@ -52,31 +52,23 @@
         ##list of dispersion parameters
         self.disp_list=[]
-        
+        if self.model !=None:
+            self.disp_list= self.model.getDispParamList()
         ##enable model 2D draw
         self.enable2D= False
         ## check that the fit range is correct to plot the model again
         self.fitrange= True
-        ## current model
-        self.model= None
-        ## data
-        self.data=None
         ## Q range
         self.qmin_x= 0.001
         self.qmax_x= 0.1
         self.num_points= 100
-        ## changing initial values given page_info value
-        if self.page_info !=None and len(self.page_info.model_list_box) >0:
-            self.model_list_box = self.page_info.model_list_box
-            ## current model
-            self.model=self.page_info.model
-            self.data = self.page_info.data
-            self.event_owner = self.page_info.event_owner
-            self.manager=self.page_info.manager
-            
-            if self.model !=None:
-                self.disp_list= self.model.getDispParamList()
+        ## Create memento to save the current state
+        
+        self.state= PageState(parent= self.parent,model=self.model, data=self.data)
+        ## create the basic structure of the panel with empty sizer
+        self.define_page_structure()
         ## drawing Initial dispersion parameters sizer 
         self.set_dispers_sizer()
         self._fill_save_sizer()
+        
         ## layout
         self.set_layout()
@@ -134,5 +126,5 @@
         """
         self.event_owner = owner    
-        self.page_info.event_owner = owner
+        self.state.event_owner = owner
   
     def set_manager(self, manager):
@@ -142,5 +134,5 @@
         """
         self.manager = manager  
-        self.page_info.manager = manager
+        self.state.manager = manager
         
     def populate_box(self, dict):
@@ -150,6 +142,5 @@
         """
         self.model_list_box = dict
-        if self.page_info!=None:
-            self.page_info.model_list_box = self.model_list_box
+        self.state.model_list_box = self.model_list_box
             
     
@@ -165,4 +156,7 @@
         self.disable_disp = wx.RadioButton(self, -1, 'No', (10, 10), style=wx.RB_GROUP)
         self.enable_disp = wx.RadioButton(self, -1, 'Yes', (10, 30))
+        ## saving the state of enable dispersity button
+        self.state.enable_disp= self.enable_disp.GetValue()
+        
         self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param, id=self.disable_disp.GetId())
         self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param, id=self.enable_disp.GetId())
@@ -278,6 +272,6 @@
             save history of the data and model
         """
-        self.page_info.model= self.model
-        self.page_info.data = self.data
+        self.state.model= self.model
+        self.state.data = self.data
         import os
                  
@@ -363,4 +357,5 @@
             after fitting
         """
+        
         if hasattr(self,"text2_3"):
             self.text2_3.Hide()
@@ -420,6 +415,65 @@
         except:
             raise 
-     
-    
+    
+    
+    def createMemento(self):
+        """
+            return the current state of the page
+        """
+        return self.state.clone()
+    
+    
+    def save_current_state(self):
+        """
+            Store current state
+        """
+        self.state.model = self.model.clone()
+        self.state.save_data(self.data)
+    
+        if hasattr(self,"cb1"):
+            self.state.cb1= self.cb1.GetValue()
+            
+        if hasattr(self,"enable_disp"):
+            self.state.enable_disp= self.enable_disp.GetValue()
+            
+        if hasattr(self,"enable_smearer"):
+            self.state.enable_smearer = self.enable_smearer.GetValue()   
+      
+        ## save checkbutton state and txtcrtl values
+        self.state.parameters=[]
+        self.state.fittable_param=[]
+        self.state.fixed_param=[]
+        self._copy_parameters_state(self.parameters, self.state.parameters)
+        self._copy_parameters_state(self.fittable_param, self.state.fittable_param)
+        self._copy_parameters_state(self.fixed_param, self.state.fixed_param)
+        
+        ## post state to fit panel
+        event = PageInfoEvent(page = self)
+        wx.PostEvent(self.parent, event)
+    
+    def reset_page(self, state):
+        """
+            Use page_info and change the state of existing button
+        """
+        self.state = state.clone()
+        self.model= self.state.model
+        self.data = self.state.data
+        self._set_model_sizer_selection( self.model )
+        self.set_model_param_sizer(self.model)
+        self._reset_plotting_range()
+        
+        self.enable_disp.SetValue(self.state.enable_disp)
+        self._set_dipers_Param(event=None)
+        
+        if hasattr(self,"enable_smearer"):
+            self.enable_smearer= self.state.enable_smearer
+        if hasattr(self, "cb1"):    
+            self.cb1.SetValue(self.state.cb1)
+        self._reset_parameters_state(self.parameters,state.parameters)
+        self._reset_parameters_state(self.fittable_param,state.fittable_param)
+        self._reset_parameters_state(self.fixed_param,state.fixed_param)
+        self._draw_model()
+        
+        
     def _selectDlg(self):
         """
@@ -433,6 +487,30 @@
         dlg.Destroy()
         return path
-          
-    
+    
+    
+    def _reset_plotting_range(self):
+        """
+            Reset the plotting range to a given state
+        """
+        
+        self.qmin.SetValue(format_number(self.state.qmin))
+        self.qmax.SetValue(format_number(self.state.qmax)) 
+        if self.state.npts!=None:
+            self.npts= self.state.npts
+            
+        self.qmin_x = float(self.qmin.GetValue())
+        self.qmax_x = float(self.qmax.GetValue())
+        
+        
+    def _save_plotting_range(self ):
+        """
+            save the state of plotting range 
+        """
+        self.state.qmin = self.qmin.GetValue()   
+        self.state.qmax = self.qmax.GetValue()   
+        if self.npts!=None:
+            self.state.npts= self.npts.GetValue()
+            
+            
     def _onparamEnter_helper(self):
         """
@@ -442,5 +520,5 @@
         """
         if self.model !=None:
-            
+            self.save_current_state()
             # Flag to register when a parameter has changed.
             is_modified = False
@@ -449,4 +527,5 @@
             is_modified =self._check_value_enter( self.parameters ,is_modified)        
            
+            
             self.Layout()
             # Here we should check whether the boundaries have been modified.
@@ -473,4 +552,93 @@
                 
                 
+    def _reset_parameters_state(self, listtorestore,statelist):
+        """
+            Reset the parameters at the given state
+        """
+        if len(self.state.parameters)!=  len(listtorestore) :
+            return
+        for j in range(len(listtorestore)):
+            item_page = listtorestore[j]
+            item_page_info = statelist[j]
+            ##change the state of the check box for simple parameters
+            if item_page[0]!=None:
+                item_page[0].SetValue(item_page_info[0])
+    
+            if item_page[2]!=None:
+                item_page[2].SetValue(item_page_info[2])
+                
+            if item_page[3]!=None:
+                ## show or hide text +/-
+                if item_page_info[2]:
+                    item_page[3].Show(True)
+                else:
+                    item_page[3].Hide()
+            if item_page[4]!=None:
+                ## show of hide the text crtl for fitting error
+                if item_page_info[4][0]:
+                    item_page[4].Show(True)
+                    item_page[4].SetValue(item_page_info[4][1])
+                else:
+                    item_page[3].Hide()
+            if item_page[5]!=None:
+                ## show of hide the text crtl for fitting error
+                if item_page_info[5][0]:
+                    item_page[5].Show(True)
+                    item_page[5].SetValue(item_page_info[4][1])
+                else:
+                    item_page[5].Hide()
+                    
+            if item_page[6]!=None:
+                ## show of hide the text crtl for fitting error
+                if item_page_info[6][0]:
+                    item_page[6].Show(True)
+                    item_page[6].SetValue(item_page_info[6][1])
+                else:
+                    item_page[6].Hide()
+                            
+    def _copy_parameters_state(self, listtocopy, statelist):
+        """
+            copy the state of button 
+            @param listtocopy: the list of check button to copy
+            @param statelist: list of state object to store the current state
+        """
+        if len(listtocopy)==0:
+            return
+        
+        for item in listtocopy:
+            checkbox_state = None
+            if item[0]!= None:
+                checkbox_state= item[0].GetValue()
+            parameter_name = item[1]
+            parameter_value = None
+            if item[2]!=None:
+                parameter_value = item[2].GetValue()
+            static_text = None
+            if item[3]!=None:
+                static_text = item[3].IsShown()
+            error_value = None
+            error_state = None
+            if item[4]!= None:
+                error_value = item[4].GetValue()
+                error_state = item[4].IsShown()
+                
+            min_value = None
+            min_state = None
+            if item[5]!= None:
+                min_value = item[5].GetValue()
+                min_state = item[5].IsShown()
+                
+            max_value = None
+            max_state = None
+            if item[6]!= None:
+                max_value = item[6].GetValue()
+                max_state = item[6].IsShown()
+               
+            statelist.append([checkbox_state, parameter_name, parameter_value,
+                              static_text ,[error_state,error_value],
+                                [min_state,min_value],[max_state , max_value],None])
+           
+        
+   
     def _set_model_sizer_selection(self, model):
         """
@@ -565,5 +733,4 @@
                     
         
-        
     def _draw_model(self):
         """
@@ -606,11 +773,5 @@
                             id= self.plugin_rbutton.GetId() )  
         wx.EVT_CHECKBOX(self, self.multip_cb.GetId() , self._show_combox )              
-        ## store state
-        self.page_info.save_radiobox_state( self.shape_rbutton )
-        self.page_info.save_radiobox_state( self.shape_indep_rbutton )
-        self.page_info.save_radiobox_state( self.struct_rbutton )
-        self.page_info.save_radiobox_state( self.plugin_rbutton )
-       
-        
+      
         sizer_radiobutton = wx.GridSizer(3, 3,5, 5)
         sizer_radiobutton.Add(self.shape_rbutton)
@@ -674,9 +835,4 @@
             Show combox box associate with type of model selected
         """
-        self.page_info.save_radiobox_state( self.shape_rbutton )
-        self.page_info.save_radiobox_state( self.shape_indep_rbutton )
-        self.page_info.save_radiobox_state( self.struct_rbutton )
-        self.page_info.save_radiobox_state( self.plugin_rbutton )
-        
         ## Don't want to populate combo box again if the event comes from check box
         if self.shape_rbutton.GetValue()and\
@@ -758,6 +914,4 @@
         
         self.set_scroll()
-        
-        
    
             
@@ -781,5 +935,5 @@
         except:
             pass
-        #wx.EVT_COMBOBOX(combobox,-1, self._on_select_model) 
+    
         return 0
    
@@ -811,5 +965,7 @@
         else:
             self.model= form_factor()
-        self.page_info.model= self.model
+       
+        ## post state to fit panel
+        self.save_current_state()
        
         
@@ -842,5 +998,5 @@
                     if format_number(item[5].GetValue())!="NaN":
                         param_min = float(item[5].GetValue())
-                    self.model.details[name][1]=param_min
+                    
                 ## check maximum value
                 if item[6]!= None:
@@ -854,6 +1010,6 @@
                         msg+= "name %s of model %s "%(name, self.model.name)
                         wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
-                    
-                self.model.details[name][1:]= param_min,param_max
+                if name in self.model.details.keys():   
+                    self.model.details[name][1:]= param_min,param_max
                 
                 ## hide statictext +/-    
@@ -878,5 +1034,4 @@
         return is_modified 
         
-        
  
     def _set_dipers_Param(self, event):
@@ -889,4 +1044,5 @@
             return 
         else:
+           
             if self.enable_disp.GetValue():
                 self.model_disp.Show(True)
@@ -903,4 +1059,8 @@
                 self.sizer4_4.Clear(True)
                 self._reset_dispersity()
+                
+          
+            ## post state to fit panel
+            self.save_current_state()
             
             self.sizer4.Layout()
@@ -908,5 +1068,4 @@
             self.SetScrollbars(20,20,200,100)
             
-   
         
     def _layout_sizer_noDipers(self):
@@ -929,5 +1088,4 @@
         return 
     
- 
             
     def _reset_dispersity(self):
@@ -966,6 +1124,5 @@
         if  name=="ArrayDispersion":
             self._set_sizer_arraydispersion()
-            
-            
+        
             
     
@@ -1038,5 +1195,6 @@
            boxsizer1.Add((10,10))
         boxsizer1.Add(sizer_horizontal)
-       
+        ## save state
+        self.save_current_state()
         #----------------------------------------------------------------
         self.sizer5.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
@@ -1044,4 +1202,5 @@
         self.Layout()
         self.SetScrollbars(20,20,200,100)
+    
     
     def _fill_save_sizer(self):
