Index: sansview/perspectives/fitting/basepage.py
===================================================================
--- sansview/perspectives/fitting/basepage.py	(revision 01b6bd08f11fd74e3dcb6881617f495881dee060)
+++ sansview/perspectives/fitting/basepage.py	(revision 6bbeacd466719479cfdf24b6e7c1c5f52c93e03d)
@@ -21,6 +21,6 @@
 
 _BOX_WIDTH = 76
-_QMIN_DEFAULT = 0.001
-_QMAX_DEFAULT = 0.13
+_QMIN_DEFAULT = 0.0005
+_QMAX_DEFAULT = 0.5
 _NPTS_DEFAULT = 50
 #Control panel width 
@@ -33,5 +33,7 @@
     FONT_VARIANT = 1
     ON_MAC = True
-    
+
+
+
 class BasicPage(ScrolledPanel, PanelBase):
     """
@@ -39,9 +41,9 @@
     """
      ## Internal name for the AUI manager
-    window_name = "Basic Page"
+    window_name = "Fit Page"
     ## Title to appear on top of the window
-    window_caption = "Basic page "
-    
-    def __init__(self, parent, page_info, **kwargs):
+    window_caption = "Fit Page "
+    
+    def __init__(self, parent,color='blue', **kwargs):
         """
         """
@@ -51,5 +53,6 @@
         #Set window's font size 
         self.SetWindowVariant(variant=FONT_VARIANT)
-       
+      
+        self.SetBackgroundColour(color)
         ## parent of the page
         self.parent = parent
@@ -62,8 +65,9 @@
         self.data = None
         self.mask = None
+        self.id = None
         ## Q range
-        self.qmax_x = None
-        self.qmin_x = None
-        self.num_points= _NPTS_DEFAULT
+        self.qmax_x = _QMAX_DEFAULT
+        self.qmin_x = _QMIN_DEFAULT
+        self.npts_x = _NPTS_DEFAULT
         ## total number of point: float
         self.npts = None
@@ -86,6 +90,6 @@
         self.state = PageState(parent=parent)
         ## dictionary containing list of models
-        self.model_list_box = None
-        self.set_page_info(page_info=page_info)
+        self.model_list_box = {}
+       
         ## Data member to store the dispersion object created
         self._disp_obj_dict = {}
@@ -136,19 +140,5 @@
         ## Create context menu for page
         self.popUpMenu = wx.Menu()
-        #id = wx.NewId()
-        #self._undo = wx.MenuItem(self.popUpMenu,id, "Undo",
-        #"cancel the previous action")
-        #self.popUpMenu.AppendItem(self._undo)
-        #self._undo.Enable(False)
-        #wx.EVT_MENU(self, id, self.onUndo)
-        
-        #id = wx.NewId()
-        #self._redo = wx.MenuItem(self.popUpMenu,id,"Redo",
-        #" Restore the previous action")
-        #self.popUpMenu.AppendItem(self._redo)
-        #self._redo.Enable(False)
-        #wx.EVT_MENU(self, id, self.onRedo)       
-        #self.popUpMenu.AppendSeparator()
-        #if sys.platform.count("win32")>0:        
+    
         id = wx.NewId()
         self._keep = wx.MenuItem(self.popUpMenu,id,"BookMark",
@@ -174,4 +164,6 @@
         ## layout
         self.set_layout()
+        
+    
         
     def on_set_focus(self, event):
@@ -305,5 +297,4 @@
         Cancel the previous action
         """
-        #print "enable undo"
         event = PreviousStateEvent(page = self)
         wx.PostEvent(self.parent, event)
@@ -313,5 +304,4 @@
         Restore the previous action cancelled 
         """
-        #print "enable redo"
         event = NextStateEvent(page= self)
         wx.PostEvent(self.parent, event)
@@ -394,4 +384,5 @@
         self.model_list_box = dict
         self.state.model_list_box = self.model_list_box
+        self.initialize_combox()
         
     def initialize_combox(self): 
@@ -1254,7 +1245,7 @@
         Reset the plotting range to a given state
         """
-        if self.check_invalid_panel():
-            return
-        self.qmin.SetValue(str(state.qmin))
+        # if self.check_invalid_panel():
+        #    return
+        self.qmin_tctrl.SetValue(str(state.qmin))
         self.qmax.SetValue(str(state.qmax)) 
 
@@ -1281,6 +1272,5 @@
         self.state.qmin = self.qmin_x
         self.state.qmax = self.qmax_x 
-        if self.npts != None:
-            self.state.npts = self.num_points
+        self.state.npts = self.npts_x
             
     def _onparamEnter_helper(self):
@@ -1312,6 +1302,6 @@
             # If qmin and qmax have been modified, update qmin and qmax and 
             # set the is_modified flag to True
-            if self._validate_qrange(self.qmin, self.qmax):
-                tempmin = float(self.qmin.GetValue())
+            if self._validate_qrange(self.qmin_tcrl, self.qmax):
+                tempmin = float(self.qmin_tcrl.GetValue())
                 if tempmin != self.qmin_x:
                     self.qmin_x = tempmin
@@ -1367,7 +1357,7 @@
             # If qmin and qmax have been modified, update qmin and qmax and 
             # set the is_modified flag to True
-            self.fitrange = self._validate_qrange(self.qmin, self.qmax)
+            self.fitrange = self._validate_qrange(self.qmin_tcrl, self.qmax)
             if self.fitrange:
-                tempmin = float(self.qmin.GetValue())
+                tempmin = float(self.qmin_tcrl.GetValue())
                 if tempmin != self.qmin_x:
                     self.qmin_x = tempmin
@@ -1385,10 +1375,13 @@
                         flag = self.update_pinhole_smear()
                     else:
-                        self._manager.set_smearer_nodraw(smearer=temp_smearer,
+                        self._manager.set_smearer(smearer=temp_smearer,
+                                                  id=self.id,
                                                      qmin=float(self.qmin_x),
-                                                      qmax=float(self.qmax_x))
+                                                      qmax=float(self.qmax_x),
+                                                      draw=False)
                 elif not self._is_2D():
                     self._manager.set_smearer(smearer=temp_smearer,
                                               qmin=float(self.qmin_x),
+                                              id=self.id, 
                                                  qmax= float(self.qmax_x))
                     index_data = ((self.qmin_x <= self.data.x)&\
@@ -1646,6 +1639,6 @@
         to build a call to the fitting perspective manager.
         """
-        if self.check_invalid_panel():
-            return
+        #if self.check_invalid_panel():
+        #    return
         if self.model !=None:
             temp_smear=None
@@ -1653,5 +1646,4 @@
                 if not self.disable_smearer.GetValue():
                     temp_smear= self.current_smearer
-            
             self._manager.draw_model(self.model, 
                                     data=self.data,
@@ -1659,5 +1651,6 @@
                                     qmin=float(self.qmin_x), 
                                     qmax=float(self.qmax_x),
-                                    qstep= float(self.num_points),
+                                    qstep= float(self.npts_x),
+                                    id=self.id,
                                     enable2D=self.enable2D)
         
@@ -1843,7 +1836,7 @@
         Show combox box associate with type of model selected
         """
-        if self.check_invalid_panel():
-            self.shape_rbutton.SetValue(True)
-            return
+        #if self.check_invalid_panel():
+        #    self.shape_rbutton.SetValue(True)
+        #    return
 
         self._show_combox_helper()
@@ -1871,6 +1864,61 @@
                 combobox.Append(name,models)
         return 0
-
+    
     def _onQrangeEnter(self, event):
+        """
+        Check validity of value enter in the Q range field
+        
+        """
+        tcrtl = event.GetEventObject()
+        #Clear msg if previously shown.
+        msg = ""
+        wx.PostEvent(self.parent, StatusEvent(status=msg))
+        # Flag to register when a parameter has changed.
+        is_modified = False
+        if tcrtl.GetValue().lstrip().rstrip() != "":
+            try:
+                value = float(tcrtl.GetValue())
+                tcrtl.SetBackgroundColour(wx.WHITE)
+                # If qmin and qmax have been modified, update qmin and qmax
+                if self._validate_qrange(self.qmin_tcrl, self.qmax):
+                    tempmin = float(self.qmin_tcrl.GetValue())
+                    if tempmin != self.qmin_x:
+                        self.qmin_x = tempmin
+                    tempmax = float(self.qmax.GetValue())
+                    if tempmax != self.qmax_x:
+                        self.qmax_x = tempmax
+                else:
+                    tcrtl.SetBackgroundColour("pink")
+                    msg = "Model Error:wrong value entered : %s" % sys.exc_value
+                    wx.PostEvent(self.parent, StatusEvent(status=msg))
+                    return 
+            except:
+                tcrtl.SetBackgroundColour("pink")
+                msg = "Model Error:wrong value entered : %s" % sys.exc_value
+                wx.PostEvent(self.parent, StatusEvent(status=msg))
+                return 
+            #Check if # of points for theory model are valid(>0).
+            if self.npts != None:
+                if check_float(self.npts):
+                    temp_npts = float(self.npts.GetValue())
+                    if temp_npts !=  self.num_points:
+                        self.num_points = temp_npts
+                        is_modified = True
+                else:
+                    msg = "Cannot Plot :No npts in that Qrange!!!  "
+                    wx.PostEvent(self.parent, StatusEvent(status=msg))
+        else:
+           tcrtl.SetBackgroundColour("pink")
+           msg = "Model Error:wrong value entered!!!"
+           wx.PostEvent(self.parent, StatusEvent(status=msg))
+        #self._undo.Enable(True)
+        self.save_current_state()
+        event = PageInfoEvent(page=self)
+        wx.PostEvent(self.parent, event)
+        self.state_change = False
+        #Draw the model for a different range
+        self._draw_model()
+                   
+    def _theory_qrange_enter(self, event):
         """
         Check validity of value enter in the Q range field
@@ -1889,25 +1937,25 @@
 
                 # If qmin and qmax have been modified, update qmin and qmax
-                if self._validate_qrange( self.qmin, self.qmax):
-                    tempmin = float(self.qmin.GetValue())
-                    if tempmin != self.qmin_x:
-                        self.qmin_x = tempmin
-                    tempmax = float(self.qmax.GetValue())
+                if self._validate_qrange(self.theory_qmin, self.theory_qmax):
+                    tempmin = float(self.theory_qmin.GetValue())
+                    if tempmin != self.theory_qmin_x:
+                        self.theory_qmin_x = tempmin
+                    tempmax = float(self.theory_qmax.GetValue())
                     if tempmax != self.qmax_x:
-                        self.qmax_x = tempmax
+                        self.theory_qmax_x = tempmax
                 else:
                     tcrtl.SetBackgroundColour("pink")
                     msg= "Model Error:wrong value entered : %s"% sys.exc_value
-                    wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
+                    wx.PostEvent(self._manager.parent, StatusEvent(status = msg ))
                     return  
             except:
                 tcrtl.SetBackgroundColour("pink")
                 msg= "Model Error:wrong value entered : %s"% sys.exc_value
-                wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
+                wx.PostEvent(self._manager.parent, StatusEvent(status = msg ))
                 return 
             #Check if # of points for theory model are valid(>0).
-            if self.npts != None:
-                if check_float(self.npts):
-                    temp_npts = float(self.npts.GetValue())
+            if self.theory_npts != None:
+                if check_float(self.theory_npts):
+                    temp_npts = float(self.theory_npts.GetValue())
                     if temp_npts !=  self.num_points:
                         self.num_points = temp_npts
@@ -1918,5 +1966,5 @@
         else:
            tcrtl.SetBackgroundColour("pink")
-           msg= "Model Error:wrong value entered!!!"
+           msg = "Model Error:wrong value entered!!!"
            wx.PostEvent(self.parent.parent, StatusEvent(status=msg))
         #self._undo.Enable(True)
@@ -2068,5 +2116,5 @@
                             self.data.qy_data * self.data.qy_data )
         #get unmasked index
-        index_data = (float(self.qmin.GetValue()) <= radius) & \
+        index_data = (float(self.qmin_tcrl.GetValue()) <= radius) & \
                         (radius <= float(self.qmax.GetValue()))
         index_data = (index_data) & (self.data.mask) 
@@ -2075,6 +2123,6 @@
         if len(index_data[index_data]) < 10:
             # change the color pink.
-            self.qmin.SetBackgroundColour("pink")
-            self.qmin.Refresh()
+            self.qmin_tcrl.SetBackgroundColour("pink")
+            self.qmin_tcrl.Refresh()
             self.qmax.SetBackgroundColour("pink")
             self.qmax.Refresh()
@@ -2188,6 +2236,6 @@
         Redraw the model with the default dispersity (Gaussian)
         """
-        if self.check_invalid_panel():
-            return 
+        #if self.check_invalid_panel():
+        #    return 
         ## On selction if no model exists.
         if self.model ==None:
@@ -2412,79 +2460,5 @@
         event = PageInfoEvent(page = self)
         wx.PostEvent(self.parent, event)
-        
-    def _set_range_sizer(self, title, box_sizer=None, object1=None,object=None):
-        """
-        Fill the Q range sizer
-        """
-        #2D data? default
-        is_2Ddata = False
-        
-        #check if it is 2D data
-        if self.data.__class__.__name__ == 'Data2D':
-            is_2Ddata = True
-            
-        self.sizer5.Clear(True)
-        #--------------------------------------------------------------
-        if box_sizer == None:
-            box_description= wx.StaticBox(self, -1,str(title))
-            boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
-        else:
-            #for MAC
-            boxsizer1 = box_sizer
-
-        self.qmin    = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH,20),style=wx.TE_PROCESS_ENTER,
-                                            text_enter_callback = self._onQrangeEnter)
-        self.qmin.SetValue(str(self.qmin_x))
-        self.qmin.SetToolTipString("Minimun value of Q in linear scale.")
-     
-        self.qmax    = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH,20),style=wx.TE_PROCESS_ENTER,
-                                            text_enter_callback = self._onQrangeEnter)
-        self.qmax.SetValue(str(self.qmax_x))
-        self.qmax.SetToolTipString("Maximum value of Q in linear scale.")
-        
-        id = wx.NewId()
-        self.reset_qrange =wx.Button(self,id,'Reset',size=(77,20))
-      
-        self.reset_qrange.Bind(wx.EVT_BUTTON, self.on_reset_clicked,id=id)
-        self.reset_qrange.SetToolTipString("Reset Q range to the default values")
-     
-        sizer_horizontal=wx.BoxSizer(wx.HORIZONTAL)
-        sizer= wx.GridSizer(2, 4,2, 6)
-
-        self.btEditMask = wx.Button(self,wx.NewId(),'Editor', size=(88,23))
-        self.btEditMask.Bind(wx.EVT_BUTTON, self._onMask,id= self.btEditMask.GetId())
-        self.btEditMask.SetToolTipString("Edit Mask.")
-        self.EditMask_title = wx.StaticText(self, -1, ' Masking(2D)')
-
-        sizer.Add(wx.StaticText(self, -1, '    Q range'))     
-        sizer.Add(wx.StaticText(self, -1, ' Min[1/A]'))
-        sizer.Add(wx.StaticText(self, -1, ' Max[1/A]'))
-        sizer.Add(self.EditMask_title)
-        sizer.Add(self.reset_qrange)   
-        
-        sizer.Add(self.qmin)
-        sizer.Add(self.qmax)
-        sizer.Add(self.btEditMask)
-       
-        if object1!=None:
-            
-            boxsizer1.Add(object1) 
-            boxsizer1.Add((10,10))
-        boxsizer1.Add(sizer)
-        if object!=None:
-            boxsizer1.Add((10,15))
-            boxsizer1.Add(object)
-        if is_2Ddata:
-            self.btEditMask.Enable()  
-            self.EditMask_title.Enable() 
-        else:
-            self.btEditMask.Disable()  
-            self.EditMask_title.Disable()
-        ## save state
-        self.save_current_state()
-        #----------------------------------------------------------------
-        self.sizer5.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
-        self.sizer5.Layout()
-
+   
     def _lay_out(self):
         """
@@ -2511,6 +2485,6 @@
         """
         flag = True
-        if self.check_invalid_panel():
-            return
+        #if self.check_invalid_panel():
+        #    return
         ##For 3 different cases: Data2D, Data1D, and theory
         if self.data.__class__.__name__ == "Data2D":
@@ -2552,5 +2526,5 @@
         else:
             # set relative text ctrs.
-            self.qmin.SetValue(str(self.qmin_x))
+            self.qmin_tcrl.SetValue(str(self.qmin_x))
             self.qmax.SetValue(str(self.qmax_x))
             self.set_npts2fit()
@@ -2569,5 +2543,4 @@
         self._draw_model()
 
-
     def on_model_help_clicked(self,event):
         """
@@ -2575,9 +2548,5 @@
         """
         from help_panel import  HelpWindow
-        import sans.models as models 
-        
-        # Get models help model_function path
-        path = models.get_data_path(media='media')
-        model_path = os.path.join(path,"model_functions.html")
+        
         if self.model == None:
             name = 'FuncHelp'
@@ -2585,5 +2554,5 @@
             name = self.model.origin_name
 
-        frame = HelpWindow(None, -1,  pageToOpen=model_path)    
+        frame = HelpWindow(None, -1,  pageToOpen="media/model_functions.html")    
         frame.Show(True)
         if frame.rhelp.HasAnchor(name):
@@ -2592,5 +2561,4 @@
            msg= "Model does not contains an available description "
            msg +="Please try searching in the Help window"
-           wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))      
-                    
+           wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))                    
                 
Index: sansview/perspectives/fitting/fit_thread.py
===================================================================
--- sansview/perspectives/fitting/fit_thread.py	(revision 5062bbf9abf800e4b5ffab0375da1c4a03967672)
+++ sansview/perspectives/fitting/fit_thread.py	(revision 6bbeacd466719479cfdf24b6e7c1c5f52c93e03d)
@@ -10,5 +10,4 @@
                    handler,
                   pars=None,
-                 cpage=None,
                  completefn = None,
                  updatefn   = None,
@@ -23,5 +22,4 @@
         self.handler = handler
         self.fitter = fn
-        self.cpage= cpage
         self.pars = pars
         self.starttime = 0
@@ -49,6 +47,5 @@
             self.updatefn()
             self.complete(result= result,
-                          pars = self.pars,
-                          cpage= self.cpage)
+                          pars = self.pars)
            
         except KeyboardInterrupt, msg:
Index: sansview/perspectives/fitting/fitpage.py
===================================================================
--- sansview/perspectives/fitting/fitpage.py	(revision 2b0f822ebd27bfe432ad080214b60ccd213c58c8)
+++ sansview/perspectives/fitting/fitpage.py	(revision 6bbeacd466719479cfdf24b6e7c1c5f52c93e03d)
@@ -38,9 +38,9 @@
     """
     
-    def __init__(self,parent, page_info):
+    def __init__(self,parent, color='rand'):
         """ 
         Initialization of the Panel
         """
-        BasicPage.__init__(self, parent, page_info)
+        BasicPage.__init__(self, parent, color=color)
  
         ## draw sizer
@@ -51,12 +51,5 @@
         self._get_defult_custom_smear()
         self._fill_range_sizer() 
-        
-        if self.data is None:
-            self.formfactorbox.Disable()
-            self.structurebox.Disable()
-        else:
-            self.smearer = smear_selection(self.data, self.model)
-            if self.smearer ==None:
-                self.enable_smearer.Disable()
+        self._set_smear(self.data)
         ## to update the panel according to the fit engine type selected
         self.Bind(EVT_FITTER_TYPE,self._on_engine_change)
@@ -158,5 +151,7 @@
         self.Layout()
         self.Refresh()
-
+    
+  
+        
     def _fill_range_sizer(self):
         """
@@ -267,6 +262,6 @@
         self.Npts_total.SetToolTipString(" Total Npts : total number of data points")
         box_description_1= wx.StaticText(self, -1,'    Chi2/Npts')
-        box_description_2= wx.StaticText(self, -1,'  Npts')
-        box_description_3= wx.StaticText(self, -1,'  Total Npts')
+        box_description_2= wx.StaticText(self, -1,'Fitted Npts')
+        box_description_3= wx.StaticText(self, -1,'Data Npts')
         box_description_4= wx.StaticText(self, -1,' ')
         
@@ -357,8 +352,71 @@
         else: self._show_smear_sizer()
         boxsizer_range.Add(self.sizer_set_masking)
-            
-        #Set sizer for Fitting section
-        self._set_range_sizer( title=title,box_sizer=boxsizer_range, object1=sizer_chi2, object= sizer_fit)
-        
+         #2D data? default
+        is_2Ddata = False
+        
+        #check if it is 2D data
+        if self.data.__class__.__name__ == 'Data2D':
+            is_2Ddata = True
+            
+        self.sizer5.Clear(True)
+     
+        self.qmin_tcrl  = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH,20),
+                                          style=wx.TE_PROCESS_ENTER,
+                                    text_enter_callback = self._onQrangeEnter)
+        self.qmin_tcrl.SetValue(str(self.qmin_x))
+        self.qmin_tcrl.SetToolTipString("Minimun value of Q in linear scale.")
+     
+        self.qmax  = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH,20),
+                                          style=wx.TE_PROCESS_ENTER,
+                                        text_enter_callback=self._onQrangeEnter)
+        self.qmax.SetValue(str(self.qmax_x))
+        self.qmax.SetToolTipString("Maximum value of Q in linear scale.")
+        
+        self.theory_npts_tcrtl  = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH, 20), 
+                        style=wx.TE_PROCESS_ENTER, 
+                        text_enter_callback=self._onQrangeEnter)
+        self.theory_npts_tcrtl.SetValue(format_number(self.npts_x))
+        self.theory_npts_tcrtl.SetToolTipString("Number of point to plot.")
+        id = wx.NewId()
+        self.reset_qrange =wx.Button(self,id,'Reset',size=(77,20))
+      
+        self.reset_qrange.Bind(wx.EVT_BUTTON, self.on_reset_clicked,id=id)
+        self.reset_qrange.SetToolTipString("Reset Q range to the default values")
+     
+        sizer_horizontal=wx.BoxSizer(wx.HORIZONTAL)
+        sizer= wx.GridSizer(2, 5,0, 0)
+
+        self.btEditMask = wx.Button(self,wx.NewId(),'Editor', size=(88,23))
+        self.btEditMask.Bind(wx.EVT_BUTTON, self._onMask,id= self.btEditMask.GetId())
+        self.btEditMask.SetToolTipString("Edit Mask.")
+        self.EditMask_title = wx.StaticText(self, -1, ' Masking(2D)')
+
+        sizer.Add(wx.StaticText(self, -1, 'Q range'))     
+        sizer.Add(wx.StaticText(self, -1, ' Min[1/A]'))
+        sizer.Add(wx.StaticText(self, -1, ' Max[1/A]'))
+        sizer.Add(wx.StaticText(self, -1, ' Theory Npts'))
+        sizer.Add(self.EditMask_title)
+        sizer.Add(self.reset_qrange)   
+        sizer.Add(self.qmin_tcrl)
+        sizer.Add(self.qmax)
+        sizer.Add(self.theory_npts_tcrtl)
+        sizer.Add(self.btEditMask)
+        boxsizer_range.Add(sizer_chi2) 
+        boxsizer_range.Add((10,10))
+        boxsizer_range.Add(sizer)
+        
+        boxsizer_range.Add((10,15))
+        boxsizer_range.Add(sizer_fit)
+        if is_2Ddata:
+            self.btEditMask.Enable()  
+            self.EditMask_title.Enable() 
+        else:
+            self.btEditMask.Disable()  
+            self.EditMask_title.Disable()
+        ## save state
+        self.save_current_state()
+        self.sizer5.Add(boxsizer_range,0, wx.EXPAND | wx.ALL, 10)
+        self.sizer5.Layout()
+
     def _fill_datainfo_sizer(self):
         """
@@ -385,5 +443,7 @@
                 ## Maximum value of data  
                 data_max = math.sqrt(x*x + y*y)
-        
+            ## set q range to plot
+            self.qmin_x = data_min
+            self.qmax_x = data_max
         box_description= wx.StaticBox(self, -1, 'Data')
         boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
@@ -416,7 +476,5 @@
         sizer_range.Add(self.maximum_q,0, wx.LEFT, 10)
 
-        ## set q range to plot
-        self.qmin_x = data_min
-        self.qmax_x = data_max
+     
 
         boxsizer1.Add(sizer_data,0, wx.ALL, 10)
@@ -800,6 +858,6 @@
         """
         #make sure all parameter values are updated.
-        if self.check_invalid_panel():
-            return
+        #if self.check_invalid_panel():
+        #    return
         if self.model ==None:
             msg="Please select a Model first..."
@@ -828,9 +886,9 @@
         # Remove or do not allow fitting on the Q=0 point, especially 
         # when y(q=0)=None at x[0].         
-        self.qmin_x = float(self.qmin.GetValue())
+        self.qmin_x = float(self.qmin_tcrl.GetValue())
         self.qmax_x = float( self.qmax.GetValue())
-        self._manager._reset_schedule_problem( value=0)
-        self._manager.schedule_for_fit( value=1,page=self,fitproblem =None) 
-        self._manager.set_fit_range(page= self,qmin= self.qmin_x, 
+        self._manager._reset_schedule_problem(id=self.id, value=0)
+        self._manager.schedule_for_fit(id=id,value=1,page=self,fitproblem =None) 
+        self._manager.set_fit_range(id=self.id,qmin= self.qmin_x, 
                                    qmax= self.qmax_x)
         
@@ -889,13 +947,12 @@
             self._set_save_flag(True)
             # Reset smearer, model and data
-            self.set_data(self.data)
-            # update smearer sizer
-            self.onSmear(None)
+            self._set_smear(self.data)
             try:
+                # update smearer sizer
+                self.onSmear(None)
                 temp_smear = None
                 if self.enable_smearer.GetValue():
                     # Set the smearer environments
-                    temp_smear= self.smearer
-                #self.compute_chisqr(temp_smear)
+                    temp_smear = self.smearer
             except:
                 ## error occured on chisqr computation
@@ -903,22 +960,20 @@
             ## event to post model to fit to fitting plugins
             (ModelEventbox, EVT_MODEL_BOX) = wx.lib.newevent.NewEvent()
-            if self.data is not None and \
-                    self.data.__class__.__name__ !="Data2D":
-                ## set smearing value whether or not 
-                #    the data contain the smearing info
-                evt = ModelEventbox(model = self.model, 
-                                        smearer = temp_smear, 
-                                        qmin = float(self.qmin_x),
-                                     qmax = float(self.qmax_x)) 
-            else:   
-                 evt = ModelEventbox(model = self.model)
-          
-            self._manager._on_model_panel(evt = evt)
+           
+            ## set smearing value whether or not 
+            #    the data contain the smearing info
+            evt = ModelEventbox(model=self.model, 
+                                        smearer=temp_smear, 
+                                        qmin=float(self.qmin_x),
+                                        id=self.id,
+                                     qmax=float(self.qmax_x)) 
+   
+            self._manager._on_model_panel(evt=evt)
             self.state.model = self.model.clone()
             self.state.model.name = self.model.name
             if event is not None:
                 self._draw_model()
-        if event !=None:
-            #self._undo.Enable(True)
+        if event != None:
+            
             ## post state to fit panel
             event = PageInfoEvent(page = self)
@@ -965,6 +1020,8 @@
                 elif self.data.__class__.__name__ !="Data2D":
                     self._manager.set_smearer(smearer=temp_smearer, 
+                                              id=self.id,
                                              qmin= float(self.qmin_x),
-                                            qmax= float(self.qmax_x)) 
+                                            qmax= float(self.qmax_x),
+                                            draw=True) 
                 if flag:   
                     #self.compute_chisqr(smearer= temp_smearer)
@@ -992,6 +1049,6 @@
         Check validity of value enter in the parameters range field
         """
-        if self.check_invalid_panel():
-            return
+        #if self.check_invalid_panel():
+        #    return
         tcrtl= event.GetEventObject()
         #Clear msg if previously shown.
@@ -1025,6 +1082,6 @@
         Check validity of value enter in the Q range field
         """
-        if self.check_invalid_panel():
-            return
+        #if self.check_invalid_panel():
+        #    return
         tcrtl= event.GetEventObject()
         #Clear msg if previously shown.
@@ -1039,6 +1096,6 @@
 
                 # If qmin and qmax have been modified, update qmin and qmax
-                if self._validate_qrange( self.qmin, self.qmax):
-                    tempmin = float(self.qmin.GetValue())
+                if self._validate_qrange( self.qmin_tcrl, self.qmax):
+                    tempmin = float(self.qmin_tcrl.GetValue())
                     if tempmin != self.qmin_x:
                         self.qmin_x = tempmin
@@ -1077,7 +1134,9 @@
                     self.set_npts2fit() 
             else:
-                index_data = ((self.qmin_x <= self.data.x)& \
-                              (self.data.x <= self.qmax_x))
-                self.Npts_fit.SetValue(str(len(self.data.x[index_data])))
+                if self.data is not None:
+                    
+                    index_data = ((self.qmin_x <= self.data.x)& \
+                                  (self.data.x <= self.qmax_x))
+                    self.Npts_fit.SetValue(str(len(self.data.x[index_data])))
 
            
@@ -1373,8 +1432,26 @@
             self.panel.ShowMessage(msg)
         
+    def _set_smear(self, data):
+        """
+        """
+        if data is None:
+            return
+        self.smearer = smear_selection(self.data, self.model)
+        self.disable_smearer.SetValue(True)
+        if self.smearer == None:
+            self.enable_smearer.Disable()
+        else:
+            self.enable_smearer.Enable()
+            
     def set_data(self, data):
         """
         reset the current data 
         """
+        flag = False
+        if self.data is None and data is not None:
+            self.window_name = str(data.name)
+            ## Title to appear on top of the window
+            self.window_caption = str(data.name)
+            flag = True
         self.data = data
         if self.data is None:
@@ -1382,6 +1459,4 @@
             data_max = ""
             data_name = ""
-            self.formfactorbox.Disable()
-            self.structurebox.Disable()
             self._set_bookmark_flag(False)
             self._set_save_flag(False)
@@ -1389,11 +1464,5 @@
             self._set_bookmark_flag(True)
             self._set_save_flag(True)
-            self.smearer = smear_selection(self.data, self.model)
-            self.disable_smearer.SetValue(True)
-            if self.smearer == None:
-                self.enable_smearer.Disable()
-            else:
-                self.enable_smearer.Enable()
-            
+            self._set_smear(data)
             # more disables for 2D
             if self.data.__class__.__name__ =="Data2D":
@@ -1434,11 +1503,14 @@
         self.minimum_q.SetValue(str(data_min))
         self.maximum_q.SetValue(str(data_max))
-        self.qmin.SetValue(str(data_min))
+        self.qmin_tcrl.SetValue(str(data_min))
         self.qmax.SetValue(str(data_max))
-        self.qmin.SetBackgroundColour("white")
+        self.qmin_tcrl.SetBackgroundColour("white")
         self.qmax.SetBackgroundColour("white")
         self.state.data = data
         self.state.qmin = self.qmin_x
         self.state.qmax = self.qmax_x
+        #update model plot with new data information
+        if flag:
+            self._draw_model()
         
     def reset_page(self, state,first=False):
@@ -1473,4 +1545,6 @@
         
         """
+        if self.data is None:
+            return
         npts2fit = 0
         qmin,qmax = self.get_range()
@@ -1653,6 +1727,6 @@
         """
 
-        if self.check_invalid_panel():
-            return
+        #if self.check_invalid_panel():
+        #    return
         if self.model ==None:
             self.disable_smearer.SetValue(True)
@@ -1799,6 +1873,8 @@
             get_pin_max.SetBackgroundColour("white")
         ## set smearing value whether or not the data contain the smearing info
-        self._manager.set_smearer(smearer=self.current_smearer, qmin= \
-                                 float(self.qmin_x),qmax= float(self.qmax_x))
+        self._manager.set_smearer(smearer=self.current_smearer,
+                                 qmin=float(self.qmin_x),
+                                 qmax= float(self.qmax_x),
+                                 id=self.id)
         return msg
         
@@ -1830,6 +1906,6 @@
         """
  
-        if self.check_invalid_panel():
-            return
+        #if self.check_invalid_panel():
+        #    return
 
         if self.model ==None:
@@ -1969,6 +2045,8 @@
         #temp_smearer = self.current_smearer
         ## set smearing value whether or not the data contain the smearing info
-        self._manager.set_smearer(smearer=self.current_smearer, qmin= \
-                                 float(self.qmin_x), qmax= float(self.qmax_x)) 
+        self._manager.set_smearer(smearer=self.current_smearer, 
+                                 qmin=float(self.qmin_x), 
+                                 qmax= float(self.qmax_x),
+                                 id=self.id) 
         return msg
     
@@ -2001,6 +2079,7 @@
         if event != None: 
             event.Skip()    
-        if self.check_invalid_panel():
+        if self.data is None:
             return
+        
         if self.model == None:
             self.disable_smearer.SetValue(True)
@@ -2013,5 +2092,5 @@
         # Need update param values
         self._update_paramv_on_fit()
-              
+        
         temp_smearer = None
         self._get_smear_info()
@@ -2054,7 +2133,7 @@
         self.Layout()
         ## set smearing value whether or not the data contain the smearing info
-        self._manager.set_smearer(smearer=temp_smearer, qmin= float(self.qmin_x),
-                                     qmax= float(self.qmax_x)) 
-
+        self._manager.set_smearer(id=self.id, smearer=temp_smearer, qmin= float(self.qmin_x),
+                        qmax= float(self.qmax_x), draw=True) 
+        
         ##Calculate chi2
         #self.compute_chisqr(smearer= temp_smearer)
Index: sansview/perspectives/fitting/fitpanel.py
===================================================================
--- sansview/perspectives/fitting/fitpanel.py	(revision 90a7bbd9e20cfbcdbcd72d6d1e3b0391cb2fe486)
+++ sansview/perspectives/fitting/fitpanel.py	(revision 6bbeacd466719479cfdf24b6e7c1c5f52c93e03d)
@@ -3,46 +3,15 @@
 import string 
 import wx
-import wx.aui
+import wx.lib.flatnotebook as fnb
 
 from sans.guiframe.panel_base import PanelBase
 from sans.guiframe.events import PanelOnFocusEvent
+from sans.guiframe.events import StatusEvent
 import basepage
-
+import models
 _BOX_WIDTH = 80
 
 
-class PageInfo(object):
-    """
-    this class contains the minimum numbers of data members
-    a fitpage or model page need to be initialized.
-    """
-    data = None
-    model =  None
-    manager = None
-    event_owner= None
-    model_list_box = None
-    name = None
-    ## Internal name for the AUI manager
-    window_name = "Page"
-    ## Title to appear on top of the window
-    window_caption = "Page"
-    #type of page can be real data , theory 1D or therory2D
-    type = "Data"
-    def __init__(self, model=None, data=None, manager=None,
-                  event_owner=None, model_list_box=None, name=None):
-        """
-        Initialize data members
-        """
-        self.data = data
-        self.model= model
-        self._manager= manager
-        self.event_owner= event_owner
-        self.model_list_box = model_list_box
-        self.name=None
-        self.window_name = "Page"
-        self.window_caption = "Page"
-        self.type = "Data"
-        
-class FitPanel(wx.aui.AuiNotebook, PanelBase):    
+class FitPanel(fnb.FlatNotebook, PanelBase):    
 
     """
@@ -59,23 +28,22 @@
     CENTER_PANE = True
     
-    def __init__(self, parent, *args, **kwargs):
-        """
-        """
-        wx.aui.AuiNotebook.__init__(self, parent, -1,
+    def __init__(self, parent, manager=None, *args, **kwargs):
+        """
+        """
+        fnb.FlatNotebook.__init__(self, parent, -1,
                     style= wx.aui.AUI_NB_WINDOWLIST_BUTTON|
                     wx.aui.AUI_NB_DEFAULT_STYLE|
                     wx.CLIP_CHILDREN)
         PanelBase.__init__(self, parent)
-    
-        self._manager = None
+        self.SetWindowStyleFlag(style=fnb.FNB_FANCY_TABS)
+        self._manager = manager
         self.parent = parent
         self.event_owner = None
-        
-        pageClosedEvent = wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE
-        self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.on_close_page)
-       
         #dictionary of miodel {model class name, model class}
-        self.model_list_box = {}
-        ## save the title of the last page tab added
+        self.menu_mng = models.ModelManager()
+        self.model_list_box = self.menu_mng.get_model_list().get_list()
+        #pageClosedEvent = fnb.EVT_FLATNOTEBOOK_PAGE_CLOSING 
+        self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CLOSING , self.on_close_page)
+         ## save the title of the last page tab added
         self.fit_page_name = {}
         ## list of existing fit page
@@ -91,16 +59,22 @@
         #add default pages
         self.add_default_pages()
-     
-        # increment number for model name
-        self.count = 0
-        #updating the panel
-        self.Update()
-        self.Center()
+    
+    def get_page_by_id(self, id):  
+        """
+        """
+        if id not in self.opened_pages:
+            msg = "Fitpanel cannot find ID: %s in self.opened_pages" % str(id)
+            raise ValueError, msg
+        else:
+            return self.opened_pages[id]
         
     def on_page_changing(self, event):
+        """
+        """
         pos = self.GetSelection()
         if pos != -1:
             selected_page = self.GetPage(pos)
             wx.PostEvent(self.parent, PanelOnFocusEvent(panel=selected_page))
+            
     def on_set_focus(self, event):
         """
@@ -136,10 +110,7 @@
         from hint_fitpage import HintFitPage
         self.hint_page = HintFitPage(self) 
-        self.AddPage(page=self.hint_page, caption="Hint")
+        self.AddPage(self.hint_page,"Hint")
         self.hint_page.set_manager(self._manager)
-        #Add the first fit page
-        self.add_empty_page()
-
-    
+  
     def close_all(self):
         """
@@ -170,8 +141,7 @@
         page_is_opened = False
         if state is not None:
-            page_info = self.get_page_info(data=state.data)
-            for name, panel in self.opened_pages.values():
+            for id, panel in self.opened_pages.values():
                 #Don't return any panel is the exact same page is created
-                if name == page_info.window_name:
+                if id == panel.id:
                     # the page is still opened
                     panel.reset_page(state=state)
@@ -182,5 +152,5 @@
                 # add data associated to the page created
                 if panel is not None:  
-                    self._manager.store_page(page=panel, data=state.data)
+                    self._manager.store_page(page=panel.id, data=state.data)
                     panel.reset_page(state=state)
                     panel.save_current_state()
@@ -241,14 +211,4 @@
                 page.set_manager(self._manager)
 
-        
-    def set_owner(self,owner):
-        """ 
-        set and owner for fitpanel
-        
-        :param owner: the class responsible of plotting
-        
-        """
-        self.event_owner = owner
-    
     def set_model_list(self, dict):
          """ 
@@ -265,5 +225,5 @@
         
         """
-        return self.GetPage(self.GetSelection() )
+        return self.GetPage(self.GetSelection())
     
     def add_sim_page(self):
@@ -274,83 +234,25 @@
         page_finder= self._manager.get_page_finder()
         self.sim_page = SimultaneousFitPage(self,page_finder=page_finder, id=-1)
-        
-        self.AddPage(self.sim_page,caption="Simultaneous Fit",select=True)
+        self.sim_page.id = wx.NewId()
+        self.AddPage(self.sim_page,"Simultaneous Fit", True)
         self.sim_page.set_manager(self._manager)
         return self.sim_page
         
-    def get_page_info(self, data=None):
-        """
-        fill information required to add a page in the fit panel
-        """
-        name = "Fit Page"
-        type = 'empty'
-        if data is not None:
-            if data.is_data:
-                name = data.name 
-                type = 'Data'
-            else:
-                if data.__class__.__name__ == "Data2D":
-                    name = 'Model 2D Fit'
-                    type = 'Theory2D'
-                else:
-                    name = 'Model 1D Fit'
-                    type = 'Theory1D'
-        page_info = PageInfo(data=data, name=name)
-        page_info.event_owner = self.event_owner 
-        page_info.manager = self._manager
-        page_info.window_name = name
-        page_info.window_caption = name
-        page_info.type = type
-        return page_info
+ 
+    def add_empty_page(self):
+        """
+        add an empty page
+        """
+        from fitpage import FitPage
+        panel = FitPage(parent=self)
+        panel.id = wx.NewId()
+        panel.populate_box(dict=self.model_list_box)
+        panel.set_manager(self._manager)
+        self.AddPage(panel, panel.window_name, select=True)
+        self.opened_pages[panel.id] = panel
+        return panel 
    
-    def add_empty_page(self):
-        """
-        add an empty page
-        """
-        page_info = self.get_page_info()
-        from fitpage import FitPage
-        panel = FitPage(parent=self, page_info=page_info)
-        panel.set_manager(self._manager)
-        self.AddPage(page=panel, caption=page_info.window_name, select=True)
-        self.opened_pages[page_info.type] = [page_info.window_name, panel]
-        return panel 
-    
-    def add_page(self, page_info):
-        """
-        add a new page
-        """
-        from fitpage import FitPage
-        panel = FitPage(parent=self, page_info=page_info)
-        panel.set_manager(self._manager)
-        self.AddPage(page=panel, caption=page_info.window_name, select=True)
-        index = self.GetPageIndex(panel)
-        self.change_page_content(data=page_info.data, index=index)
-        return panel
-    
-    def change_page_content(self, data, index):
-        """
-        replace the contains of an existing page
-        """
-        page_info = self.get_page_info(data=data)
-        self.SetPageText(index, page_info.window_name)
-        panel = self.GetPage(index)
-        panel.set_data(data)
-        if panel.model_list_box is None or len(panel.model_list_box) == 0: 
-            page_info.model_list_box = self.model_list_box.get_list()
-            panel.populate_box(dict=page_info.model_list_box)
-            panel.initialize_combox()
-        panel.set_page_info(page_info=page_info)
-        self.opened_pages[page_info.type] = [page_info.window_name, panel]
-        return panel
-    
-    def replace_page(self, index, page_info, type):
-        """
-        replace an existing page
-        """
-        self.DeletePage(index)
-        del self.opened_pages[type]
-        return self.add_page(page_info=page_info)
-        
-    def add_fit_page(self, data, reset=False):
+    
+    def set_data(self, data):
         """ 
         Add a fitting page on the notebook contained by fitpanel
@@ -363,48 +265,33 @@
         if data is None:
             return None
-        page_info = self.get_page_info(data=data)
-        type = page_info.type
-        npages = len(self.opened_pages.keys())
-        #check if only and empty page is opened
-        if len(self.opened_pages.keys()) > 0:
-            first_page_type = self.opened_pages.keys()[0]
-            if npages == 1 and first_page_type in ['empty']:
-                #replace the first empty page
-                name, panel = self.opened_pages[first_page_type]
-                index = self.GetPageIndex(panel)
-                panel = self.change_page_content(data=data, index=index)
-                del self.opened_pages[first_page_type]
-                return panel
-        if type in self.opened_pages.keys():
-            #this type of page is already created but it is a theory
-            # meaning the same page is just to fit different data
-            if not type.lower() in ['data']:
-                #delete the previous theory page and add a new one
-                name, panel = self.opened_pages[type]
-                #self._manager.reset_plot_panel(panel.get_data())
-                #delete the existing page and replace it
-                index = self.GetPageIndex(panel)
-                panel = self.replace_page(index=index, page_info=page_info, type=type)
-                return panel 
-            else:
-                for name, panel in self.opened_pages.values():
-                    #Don't return any panel is the exact same page is created
-                    if name == page_info.window_name:
-                        return None
-                    else:
-                        panel = self.add_page(page_info=page_info)
-                        return panel        
-        else:
-            #a new type of page is created
-            panel = self.add_page(page_info=page_info)
-            return panel
-        
-    def  _onGetstate(self, event):
+        for page in self.opened_pages.values():
+            #check if the selected data existing in the fitpanel
+            pos = self.GetPageIndex(page)
+            if page.get_data() is None:
+                page.set_data(data)
+                self.SetPageText(pos, str(data.name))
+                self.SetSelection(pos)
+                return page
+            elif page.get_data().id == data.id:
+                msg = "Data already existing in the fitting panel"
+                wx.PostEvent(self._manager.parent, 
+                             StatusEvent(status=msg, info='warning'))  
+                self.SetSelection(pos)
+                return page
+        
+        page = self.add_empty_page()
+        page.id = wx.NewId()
+        page.set_data(data)
+        self.SetPageText(pos, str(data.name))
+        self.opened_pages[page.id] = page
+        return page
+       
+    def _onGetstate(self, event):
         """
         copy the state of a page
         """
-        page= event.page
-        if page.window_name in self.fit_page_name:
-            self.fit_page_name[page.window_name].appendItem(page.createMemento()) 
+        page = event.page
+        if page.id in self.fit_page_name:
+           self.fit_page_name[page.id].appendItem(page.createMemento()) 
             
     def _onUndo(self, event ):
@@ -413,9 +300,9 @@
         """
         page = event.page 
-        if page.window_name in self.fit_page_name:
-            if self.fit_page_name[page.window_name].getCurrentPosition()==0:
+        if page.id in self.fit_page_name:
+            if self.fit_page_name[page.id].getCurrentPosition()==0:
                 state = None
             else:
-                state = self.fit_page_name[page.window_name].getPreviousItem()
+                state = self.fit_page_name[page.id].getPreviousItem()
                 page._redo.Enable(True)
             page.reset_page(state)
@@ -426,12 +313,12 @@
         """       
         page = event.page 
-        if page.window_name in self.fit_page_name:
-            length= len(self.fit_page_name[page.window_name])
-            if self.fit_page_name[page.window_name].getCurrentPosition()== length -1:
+        if page.id in self.fit_page_name:
+            length= len(self.fit_page_name[page.id])
+            if self.fit_page_name[page.id].getCurrentPosition()== length -1:
                 state = None
                 page._redo.Enable(False)
                 page._redo.Enable(True)
             else:
-                state = self.fit_page_name[page.window_name].getNextItem()
+                state =self.fit_page_name[page.id].getNextItem()
             page.reset_page(state)  
                  
@@ -441,5 +328,5 @@
         """
         #remove hint page
-        if selected_page == self.hint_page:
+        if selected_page.id == self.hint_page.id:
             return
         ## removing sim_page
@@ -461,12 +348,9 @@
         if selected_page in page_finder:
             #Delete the name of the page into the list of open page
-            for type, list in self.opened_pages.iteritems():
+            for id, list in self.opened_pages.iteritems():
                 #Don't return any panel is the exact same page is created
-                name = str(list[0])
-                if flag and selected_page.window_name == name:
-                    if type.lower() in ['theory1d', 'theory2d']:
-                        self._manager.remove_plot(selected_page, theory=True)
-                    else:
-                        self._manager.remove_plot(selected_page, theory=False)
+                
+                if flag and selected_page.id == id:
+                    self._manager.remove_plot(id, theory=False)
                     break 
             del page_finder[selected_page]
@@ -480,8 +364,8 @@
                 
         #Delete the name of the page into the list of open page
-        for type, list in self.opened_pages.iteritems():
+        for id, list in self.opened_pages.iteritems():
             #Don't return any panel is the exact same page is created
-            name = str(list[0])
-            if selected_page.window_name == name:
+            
+            if selected_page.id == id:
                 del self.opened_pages[type]
                 break 
Index: sansview/perspectives/fitting/fitproblem.py
===================================================================
--- sansview/perspectives/fitting/fitproblem.py	(revision 5062bbf9abf800e4b5ffab0375da1c4a03967672)
+++ sansview/perspectives/fitting/fitproblem.py	(revision 6bbeacd466719479cfdf24b6e7c1c5f52c93e03d)
@@ -11,5 +11,6 @@
         """
         ## data used for fitting
-        self.fit_data=None
+        self.fit_data = None
+        self.theory_data = None
         ## the current model
         self.model = None
@@ -17,12 +18,10 @@
         ## if 1 this fit problem will be selected to fit , if 0 
         ## it will not be selected for fit
-        self.schedule=0
+        self.schedule = 0
         ##list containing parameter name and value
-        self.list_param=[]
+        self.list_param = []
         ## smear object to smear or not data1D
-        self.smearer= None
-        ## same as fit_data but with more info for plotting
-        ## axis unit info and so on see plottables definition
-        self.plotted_data=None
+        self.smearer = None
+        self.fit_tab_caption = ''
         ## fitting range
         self.qmin = None
@@ -40,4 +39,5 @@
         obj.model = model
         obj.fit_data = copy.deepcopy(self.fit_data)
+        obj.theory_data = copy.deepcopy(self.theory_data)
         obj.model = copy.deepcopy(self.model)
         obj.schedule = copy.deepcopy(self.schedule)
@@ -103,5 +103,5 @@
         return self.model_index
     
-    def add_plotted_data(self,data):
+    def set_theory_data(self, data):
         """ 
         save a copy of the data select to fit
@@ -110,15 +110,15 @@
         
         """
-        self.plotted_data = data
+        self.theory_data = data
         
 
-    def get_plotted_data(self):
+    def get_theory_data(self):
         """
         :return: list of data dList
         
         """
-        return self.plotted_data
+        return self.theory_data
 
-    def add_fit_data(self,data):
+    def set_fit_data(self,data):
         """ 
         save a copy of the data select to fit
@@ -181,3 +181,14 @@
         """
         self.list_param=[]
+        
+    def set_fit_tab_caption(self, caption):
+        """
+        """
+        self.fit_tab_caption = str(caption)
+        
+    def get_fit_tab_caption(self):
+        """
+        """
+        return self.fit_tab_caption
    
+   
Index: sansview/perspectives/fitting/fitting.py
===================================================================
--- sansview/perspectives/fitting/fitting.py	(revision 81f00d78ada09a013a9eb074a1b0579fa0fea611)
+++ sansview/perspectives/fitting/fitting.py	(revision 6bbeacd466719479cfdf24b6e7c1c5f52c93e03d)
@@ -29,10 +29,11 @@
 from sans.guiframe.dataFitting import Data2D
 from sans.guiframe.dataFitting import Data1D
-from sans.guiframe.dataFitting import Theory1D
-from sans.guiframe.events import NewPlotEvent, StatusEvent  
+from sans.guiframe.events import NewPlotEvent 
+from sans.guiframe.events import StatusEvent  
 from sans.guiframe.events import EVT_SLICER_PANEL
 from sans.guiframe.events import EVT_REMOVE_DATA
-from sans.guiframe.events import ERR_DATA
 from sans.guiframe.events import EVT_SLICER_PARS_UPDATE
+from sans.guiframe.gui_style import GUIFRAME_ID
+from sans.guiframe.plugin_base import PluginBase 
 
 
@@ -50,21 +51,8 @@
 MAX_NBR_DATA = 4
 
+
 (PageInfoEvent, EVT_PAGE_INFO)   = wx.lib.newevent.NewEvent()
 
-
-class PlotInfo:
-    """
-    store some plotting field
-    """
-    _xunit = 'A^{-1}'
-    _xaxis= "\\rm{Q}"
-    _yunit = "cm^{-1}"
-    _yaxis= "\\rm{Intensity} "
-    id = "Model"
-    group_id = "Model"
-    title= None
-    info= None
-    
-from sans.guiframe.plugin_base import PluginBase    
+   
 
 class Plugin(PluginBase):
@@ -105,7 +93,5 @@
         #keep reference of the simultaneous fit page
         self.sim_page = None
-        #dictionary containing data name and error on dy of that data 
-        self.err_dy = {}
-        self.theory_data = None  
+   
         #Create a reader for fit page's state
         self.state_reader = None 
@@ -114,4 +100,6 @@
         self.state_index = 0
         self.sfile_ext = None
+        # take care of saving  data, model and page associated with each other
+        self.page_finder = {}
         # Log startup
         logging.info("Fitting plug-in started") 
@@ -146,16 +134,14 @@
         self.menu1.AppendSeparator()
         id1 = wx.NewId()
-        simul_help = "Allow to edit fit engine with multiple model and data"
+        simul_help = "Simultaneous Fit"
         self.menu1.Append(id1, '&Simultaneous Page',simul_help)
         wx.EVT_MENU(owner, id1, self.on_add_sim_page)
-       
-        #menu for model
-        menu2 = wx.Menu()
-        self.menu_mng.populate_menu(menu2, owner)
-        id2 = wx.NewId()
-        owner.Bind(models.EVT_MODEL,self._on_model_menu)
-      
-        self.fit_panel.set_owner(owner)
-        self.fit_panel.set_model_list(self.menu_mng.get_model_list())
+        
+        id1 = wx.NewId()
+        simul_help = "Add new fit page"
+        self.menu1.Append(id1, '&Create New Page',simul_help)
+        wx.EVT_MENU(owner, id1, self.on_add_new_page)
+        
+        #self.fit_panel.set_model_list(self.menu_mng.get_model_list())
    
         #create  menubar items
@@ -181,5 +167,5 @@
         frame.Show(True)
         
-    def get_context_menu(self, graph=None):
+    def get_context_menu(self, plotpanel=None):
         """
         Get the context menu items available for P(r).them allow fitting option
@@ -194,33 +180,28 @@
                 
         """
-        self.graph = graph
+        graph = plotpanel.graph
         fit_option = "Select data for fitting"
         fit_hint =  "Dialog with fitting parameters "
-       
-        for item in graph.plottables:
-            if item.__class__.__name__ is "Data2D":
-                
-                if hasattr(item,"is_data"):
-                    if item.is_data:
-                        return [[fit_option, fit_hint, self._onSelect]]
-                    else:
-                        return [] 
-                return [[fit_option, fit_hint, self._onSelect]]
-            else:
-                if item.name == graph.selected_plottable :
-                    if item.name in ["$I_{obs}(q)$","$I_{fit}(q)$",
-                                     "$P_{fit}(r)$"]:
-                        return [] 
-                    if hasattr(item, "group_id"):
-                        # if is_data is true , this in an actual data loaded
-                        #else it is a data created from a theory model
-                        if hasattr(item,"is_data"):
-                            if item.is_data:
-                                return [[fit_option, fit_hint,
-                                          self._onSelect]]
-                            else:
-                                return [] 
-                        else:
-                           return [[fit_option, fit_hint, self._onSelect]]
+        
+        if graph.selected_plottable not in plotpanel.plots:
+            return []
+        item = plotpanel.plots[graph.selected_plottable]
+        if item.__class__.__name__ is "Data2D": 
+            if hasattr(item,"is_data"):
+                if item.is_data:
+                    return [[fit_option, fit_hint, self._onSelect]]
+                else:
+                    return [] 
+            return [[fit_option, fit_hint, self._onSelect]]
+        else:
+            
+            # if is_data is true , this in an actual data loaded
+            #else it is a data created from a theory model
+            if hasattr(item,"is_data"):
+                if item.is_data:
+                    return [[fit_option, fit_hint,
+                              self._onSelect]]
+                else:
+                    return [] 
         return []   
 
@@ -233,5 +214,6 @@
         #self.parent.Bind(EVT_FITSTATE_UPDATE, self.on_set_state_helper)
         # Creation of the fit panel
-        self.fit_panel = FitPanel(self.parent, -1)
+        self.fit_panel = FitPanel(parent=self.parent, manager=self)
+        self.on_add_new_page(event=None)
         #Set the manager for the main panel
         self.fit_panel.set_manager(self)
@@ -239,11 +221,10 @@
         self.perspective = []
         self.perspective.append(self.fit_panel.window_name)
-        # take care of saving  data, model and page associated with each other
-        self.page_finder = {}
+       
         #index number to create random model name
         self.index_model = 0
         self.index_theory= 0
         self.parent.Bind(EVT_SLICER_PANEL, self._on_slicer_event)
-        self.parent.Bind(ERR_DATA, self._on_data_error)
+       
         self.parent.Bind(EVT_REMOVE_DATA, self._closed_fitpage)
         self.parent.Bind(EVT_SLICER_PARS_UPDATE, self._onEVT_SLICER_PANEL)
@@ -333,4 +314,5 @@
                 #set state
                 data = self.parent.create_gui_data(state.data)
+                
                 data.group_id = state.data.group_id
                 wx.PostEvent(self.parent, NewPlotEvent(plot=data,
@@ -343,10 +325,9 @@
                 data = self.parent.create_gui_data(state.data)
                 data.group_id = state.data.group_id
-                page_info = self.fit_panel.get_page_info(data=data)
-                panel = self.fit_panel.add_page(page_info)
-                self.store_page(page=panel, data=data)
+                self.add_fit_page(data)
+                caption = panel.window_name
+                self.store_data(page=panel.id, data=data, caption=caption)
                 self.mypanels.append(panel) 
                 
-               
             # get ready for the next set_state
             self.state_index += 1
@@ -371,35 +352,11 @@
         self.state_reader.write(filename=filepath, fitstate=fitstate)
         
-    def copy_data(self, item, dy=None):
-        """
-        receive a data 1D and the list of errors on dy
-        and create a new data1D data
-    
-        """
-        id = None
-        if hasattr(item,"id"):
-            id = item.id
-
-        data= Data1D(x=item.x, y=item.y,dx=None, dy=None)
-        data.copy_from_datainfo(item)
-        item.clone_without_data(clone=data)    
-        data.dy = deepcopy(dy)
-        data.name = item.name
-        ## allow to highlight data when plotted
-        data.interactive = deepcopy(item.interactive)
-        ## when 2 data have the same id override the 1 st plotted
-        data.id = id
-        data.group_id = item.group_id
-        return data
-    
-    def set_fit_range(self, page, qmin, qmax):
+    def set_fit_range(self, id, qmin, qmax):
         """
         Set the fitting range of a given page
         """
-        if page in self.page_finder.iterkeys():
-            fitproblem= self.page_finder[page]
-            fitproblem.set_range(qmin= qmin, qmax= qmax)
+        self.page_finder[id].set_range(qmin=qmin, qmax=qmax)
                     
-    def schedule_for_fit(self,value=0,page=None,fitproblem =None):  
+    def schedule_for_fit(self,value=0, id=None,fitproblem =None):  
         """
         Set the fit problem field to 0 or 1 to schedule that problem to fit.
@@ -414,7 +371,5 @@
             fitproblem.schedule_tofit(value)
         else:
-            if page in self.page_finder.iterkeys():
-                fitproblem= self.page_finder[page]
-                fitproblem.schedule_tofit(value)
+            self.page_finder[id].schedule_tofit(value)
           
     def get_page_finder(self):
@@ -435,11 +390,11 @@
          
         """  
-        sim_page= self.sim_page
-        for page, value in self.page_finder.iteritems():
-            if page != sim_page:
-                list=value.get_model()
+        sim_page_id = self.sim_page.id
+        for id, value in self.page_finder.iteritems():
+            if id != sim_page_id:
+                list = value.get_model()
                 model = list[0]
-                if model.name== modelname:
-                    value.set_model_param(names,values)
+                if model.name == modelname:
+                    value.set_model_param(names, values)
                     break
          
@@ -471,6 +426,6 @@
             wx.PostEvent(self.parent, StatusEvent(status="Fitting  \
                 is cancelled" , type="stop"))
-           
-    def set_smearer_nodraw(self,smearer, qmin=None, qmax=None):
+  
+    def set_smearer(self, id, smearer, qmin=None, qmax=None, draw=True):
         """
         Get a smear object and store it to a fit problem
@@ -478,35 +433,22 @@
         :param smearer: smear object to allow smearing data
         
-        """  
-        self.current_pg=self.fit_panel.get_current_page()
-        self.page_finder[self.current_pg].set_smearer(smearer)
-        ## draw model 1D with smeared data
-        data =  self.page_finder[self.current_pg].get_fit_data()
-        model = self.page_finder[self.current_pg].get_model()
-        ## if user has already selected a model to plot
-        ## redraw the model with data smeared
-        smear =self.page_finder[self.current_pg].get_smearer()   
-            
-    def set_smearer(self,smearer, qmin=None, qmax=None):
-        """
-        Get a smear object and store it to a fit problem
-        
-        :param smearer: smear object to allow smearing data
-        
         """   
-        self.current_pg=self.fit_panel.get_current_page()
-        self.page_finder[self.current_pg].set_smearer(smearer)
-        ## draw model 1D with smeared data
-        data =  self.page_finder[self.current_pg].get_fit_data()
-        model = self.page_finder[self.current_pg].get_model()
-        ## if user has already selected a model to plot
-        ## redraw the model with data smeared
-
-        smear = self.page_finder[self.current_pg].get_smearer()
-        if model != None:
-            self.draw_model(model=model, data=data, smearer=smear,
+        if id not in self.page_finder.keys():
+            msg = "Cannot find ID: %s in page_finder" % str(id)
+            raise ValueError, msg
+        self.page_finder[id].set_smearer(smearer)
+        if draw:
+            ## draw model 1D with smeared data
+            data =  self.page_finder[id].get_fit_data()
+            model = self.page_finder[id].get_model()
+            if model is None:
+                return
+            ## if user has already selected a model to plot
+            ## redraw the model with data smeared
+            smear = self.page_finder[id].get_smearer()
+            self.draw_model(model=model, data=data, id=id, smearer=smear,
                 qmin=qmin, qmax=qmax)
 
-    def draw_model(self, model, data=None, smearer=None,
+    def draw_model(self, model, id, data=None, smearer=None,
                    enable1D=True, enable2D=False,
                    qmin=DEFAULT_QMIN, qmax=DEFAULT_QMAX, qstep=DEFAULT_NPTS):
@@ -527,6 +469,8 @@
         if data.__class__.__name__ != "Data2D":    
             ## draw model 1D with no loaded data
+            
             self._draw_model1D(model=model, 
                                data=data,
+                               id=id,
                                enable1D=enable1D, 
                                smearer=smearer,
@@ -537,4 +481,5 @@
             ## draw model 2D with no initial data
              self._draw_model2D(model=model,
+                                id=id,
                                 data=data,
                                 enable2D=enable2D,
@@ -570,5 +515,5 @@
         fproblemId = 0
         self.current_pg = None
-        for page, value in self.page_finder.iteritems():
+        for id, value in self.page_finder.iteritems():
             try:
                 if value.get_scheduled() == 1:
@@ -576,4 +521,5 @@
                     pars = []
                     templist = []
+                    page = self.fit_panel.get_page_by_id(id)
                     templist = page.get_param_list()
                     for element in templist:
@@ -584,10 +530,11 @@
                                       id=fproblemId, title=engineType) 
                     fproblemId += 1 
-                    self.current_pg = page
+                    self.current_page_id = page
             except:
-                msg= "%s error: %s" % (engineType, sys.exc_value)
-                wx.PostEvent(self.parent, StatusEvent(status=msg, info="error",
-                                                      type="stop"))
-                return 
+                raise
+                #msg= "%s error: %s" % (engineType, sys.exc_value)
+                #wx.PostEvent(self.parent, StatusEvent(status=msg, info="error",
+                #                                      type="stop"))
+                #return 
         ## If a thread is already started, stop it
         #if self.calc_fit!= None and self.calc_fit.isrunning():
@@ -600,5 +547,4 @@
                                     handler = handler,
                                     fn=self.fitter,
-                                   cpage=self.current_pg,
                                    pars=pars,
                                    updatefn=handler.update_fit,
@@ -625,86 +571,22 @@
             time.sleep(0.4)
             
-    def remove_plot(self, page, theory=False):
+    def remove_plot(self, id, theory=False):
         """
         remove model plot when a fit page is closed
         """
-        fitproblem = self.page_finder[page]
+        fitproblem = self.page_finder[id]
         data = fitproblem.get_fit_data()
         model = fitproblem.get_model()
+        id = None
         if model is not None:
-            name = model.name
-            new_plot = Theory1D(x=[], y=[], dy=None)
-            new_plot.name = name
-            new_plot.xaxis(data._xaxis, data._xunit)
-            new_plot.yaxis(data._yaxis, data._yunit)
-            new_plot.group_id = data.group_id
-            new_plot.id = data.id + name
-            wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot,
-                                                   title=data.name))
+            id = data.id + name
         if theory:
-            new_plot_data = Data1D(x=[], y=[], dx=None, dy=None)
-            new_plot_data.name = data.name
-            new_plot_data.xaxis(data._xaxis, data._xunit)
-            new_plot_data.yaxis(data._yaxis, data._yunit)
-            new_plot_data.group_id = data.group_id
-            new_plot_data.id = data.id 
-            wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot_data,
-                                                    title=data.name))
-    def create_fittable_data2D(self, data):
-        """
-        check if the current data is a data 2d and add dy to that data
-        
-        :return: Data2D
-        
-        """
-        if data.__class__.__name__ != "Data2D":
-            raise ValueError, " create_fittable_data2D expects a Data2D"
-        ## Data2D case
-        new_data = deepcopy(data)
-        if not hasattr(data, "is_data"):
-            new_data.group_id += "data2D"
-            new_data.id +="data2D"
-            new_data.is_data = False
-            title = new_data.name
-            title += " Fit"
-            wx.PostEvent(self.parent, NewPlotEvent(plot=new_data,
-                                                    title=str(title)))
-        else:
-            new_data.is_data = True
-        return new_data
-        
-    def create_fittable_data1D(self, data):
-        """
-        check if the current data is a theory 1d and add dy to that data
-        
-        :return: Data1D
-        
-        """
-        class_name = data.__class__.__name__
-        if not class_name in ["Data1D", "Theory1D"]:
-            raise ValueError, "create_fittable_data1D expects Data1D"
-      
-        #get the appropriate dy 
-        dy = deepcopy(data.dy)
-        if len(self.err_dy) > 0:
-            if data.name in  self.err_dy.iterkeys():
-                dy = self.err_dy[data.name]   
-        if data.__class__.__name__ == "Theory1D":
-            new_data = self.copy_data(data, dy)
-            new_data.group_id = str(new_data.group_id)+"data1D"
-            new_data.id = str(new_data.id)+"data1D"
-            new_data.is_data = False
-            title = new_data.name
-            title = 'Data created from Theory'
-            wx.PostEvent(self.parent, NewPlotEvent(plot=new_data,
-                                                    title=str(title),
-                                                   reset=True))
-        else:
-            new_data = self.copy_data(data, dy) 
-            new_data.id = data.id 
-            new_data.is_data = True
-        return new_data
+            id = data.id 
+        group_id = data.group_id[len(data.group_id)-1]
+        wx.PostEvent(self.parent, NewPlotEvent(id=id,
+                                                   group_id=group_id,
+                                                   remove=True))
            
-    def store_page(self, page, data):
+    def store_data(self, id, data=None, caption=None):
         """
         Helper to save page reference into the plug-in
@@ -713,21 +595,21 @@
         
         """
-        page.set_data(data) 
         #create a fitproblem storing all link to data,model,page creation
-        if not page in self.page_finder.keys():
-            self.page_finder[page] = FitProblem()
-        self.page_finder[page].add_fit_data(data)
-        
-    def add_fit_page(self, data):
-        """
-        given a data, ask to the fitting panel to create a new fitting page,
-        get this page and store it into the page_finder of this plug-in
+        if not id in self.page_finder.keys():
+            self.page_finder[id] = FitProblem()
+        self.page_finder[id].set_fit_data(data)
+        self.page_finder[id].set_fit_tab_caption(caption)
+        
+    def on_add_new_page(self, event=None):
+        """
+        ask fit panel to create a new empty page
         """
         try:
-            page = self.fit_panel.add_fit_page(data)
-            
+            page = self.fit_panel.add_empty_page()
+            page_caption = page.window_name
             # add data associated to the page created
             if page != None:  
-                self.store_page(page=page, data=data)
+                self.store_data(id=page.id, caption=page_caption,
+                                data=page.get_data())
                 wx.PostEvent(self.parent, StatusEvent(status="Page Created",
                                                info="info"))
@@ -737,7 +619,31 @@
                                                        info="warning"))
         except:
-            msg = "Creating Fit page: %s"%sys.exc_value
-            wx.PostEvent(self.parent, StatusEvent(status=msg, info="error"))
-       
+            raise
+            #msg = "Creating Fit page: %s"%sys.exc_value
+            #wx.PostEvent(self.parent, StatusEvent(status=msg, info="error"))
+        
+        
+    def add_fit_page(self, data):
+        """
+        given a data, ask to the fitting panel to create a new fitting page,
+        get this page and store it into the page_finder of this plug-in
+        """
+        page = self.fit_panel.set_data(data)
+        page_caption = page.window_name
+        #append Data1D to the panel containing its theory
+        #if theory already plotted
+        if page.id in self.page_finder:
+            theory_data = self.page_finder[page.id].get_theory_data()
+            if issubclass(data.__class__, Data2D):
+                data.group_id.append(wx.NewId())
+            else:
+                if theory_data is not None:
+                    group_id = theory_data.group_id[len(theory_data.group_id)-1]
+                    if group_id not in data.group_id:
+                        data.group_id.append(group_id)
+        self.store_data(id=page.id, data=data, caption=page.window_name)
+        if self.sim_page is not None:
+            self.sim_page.draw_page()
+            
     def _onEVT_SLICER_PANEL(self, event):
         """
@@ -794,5 +700,5 @@
                     page = self.fit_panel.add_fit_page(data= data,reset=True)
                     if fitproblem != None:
-                        self.page_finder[page]=fitproblem
+                        self.page_finder[id] = fitproblem
                         if self.sim_page != None:
                             self.sim_page.draw_page()
@@ -808,5 +714,5 @@
         unschedule or schedule all fitproblem to be fit
         """
-        for page, fitproblem in self.page_finder.iteritems():
+        for fitproblem in self.page_finder.values():
             fitproblem.schedule_tofit(value)
             
@@ -845,6 +751,7 @@
             value.clear_model_param()
         except:
-            msg = title + " error: %s" % sys.exc_value
-            wx.PostEvent(self.parent, StatusEvent(status=msg, type="stop"))
+            raise
+            #msg = title + " error: %s" % sys.exc_value
+            #wx.PostEvent(self.parent, StatusEvent(status=msg, type="stop"))
           
     def _onSelect(self,event):
@@ -858,12 +765,12 @@
             if plottable.__class__.__name__ in ["Data1D", "Theory1D"]:
                 if plottable.name == self.panel.graph.selected_plottable:
-                    data = self.create_fittable_data1D(data=plottable)
+                    data = plottable
                     self.add_fit_page(data=data)
                     return
             else:
-                data = self.create_fittable_data2D(data=plottable)
+                data = plottable
                 self.add_fit_page(data=data)
             
-    def _single_fit_completed(self,result,pars,cpage, elapsed=None):
+    def _single_fit_completed(self,result, pars, elapsed=None):
         """
         Display fit result on one page of the notebook.
@@ -889,7 +796,9 @@
                              StatusEvent(status=msg, type="stop"))
                 return
-            for page, value in self.page_finder.iteritems():
-                if page == cpage :
+            page_id = None
+            for id, value in self.page_finder.iteritems():   
+                if value.get_scheduled()==1:
                     model = value.get_model()
+                    page_id = id
                     break
             param_name = []
@@ -897,5 +806,6 @@
             for name in pars:
                 param_name.append(name)
-
+                
+            cpage = self.fit_panel.get_page_by_id(page_id)
             cpage.onsetValues(result.fitness, 
                               param_name, result.pvec,result.stderr)
@@ -908,5 +818,5 @@
             return
        
-    def _simul_fit_completed(self, result, pars=None, cpage=None, elapsed=None):
+    def _simul_fit_completed(self, result, pars=None, elapsed=None):
         """
         Parameter estimation completed, 
@@ -925,10 +835,10 @@
                 return
             if not numpy.isfinite(result.fitness) or numpy.any(result.pvec ==None )or not numpy.all(numpy.isfinite(result.pvec) ):
-                msg= "Single Fitting did not converge!!!"
+                msg= "Simultaneous Fitting did not converge!!!"
                 wx.PostEvent(self.parent, StatusEvent(status=msg,type="stop"))
                 return
               
-            for page, value in self.page_finder.iteritems():   
-                if value.get_scheduled()==1:
+            for id, value in self.page_finder.iteritems():   
+                if value.get_scheduled() == 1:
                     model = value.get_model()
                     data =  value.get_fit_data()
@@ -949,17 +859,18 @@
 
                     # Display result on each page 
-                    page.onsetValues(result.fitness,
+                    cpage = self.fit_panel.get_page_by_id(id)
+                    cpage.onsetValues(result.fitness,
                                       small_param_name,
                                       small_out,small_cov)
         except:
-             msg= "Simultaneous Fit completed"
-             msg +=" but Following error occurred:%s"%sys.exc_value
-             wx.PostEvent(self.parent, StatusEvent(status=msg,type="stop"))
-             return 
+            raise
+            #msg= "Simultaneous Fit completed"
+            #msg +=" but Following error occurred:%s"%sys.exc_value
+            #wx.PostEvent(self.parent, StatusEvent(status=msg,type="stop"))
+            #return 
              
     def _on_show_panel(self, event):
         """
         """
-        #print "_on_show_panel: fitting"
         pass
         
@@ -1044,6 +955,5 @@
         event = fitpage.FitterTypeEvent()
         event.type = self._fit_engine
-        for key in self.page_finder.keys():
-            wx.PostEvent(key, event)
+        wx.PostEvent(self.fit_panel, event)
        
     def _on_model_panel(self, evt):
@@ -1055,48 +965,22 @@
         """
         model = evt.model
+        id = evt.id 
+        qmin = evt.qmin
+        qmax = evt.qmax
+        smearer = evt.smearer
         if model == None:
             return
-        smearer = None
-        qmin = None
-        qmax = None
-        if hasattr(evt, "qmin"):
-            qmin = evt.qmin
-        if hasattr(evt, "qmax"):
-            qmax = evt.qmax
-        if hasattr(evt, "smearer"):
-            smearer = evt.smearer
-        model.origin_name = model.name
-        self.current_pg = self.fit_panel.get_current_page() 
-        ## make sure nothing is done on self.sim_page
-        ## example trying to call set_panel on self.sim_page
-        if self.current_pg != self.sim_page :
-            if self.page_finder[self.current_pg].get_model() is None:
-                model.name = "M" + str(self.index_model)
-                self.index_model += 1  
-            else:
-                model.name= self.page_finder[self.current_pg].get_model().name
-            data = self.page_finder[self.current_pg].get_fit_data()
-            # save the name containing the data name with the appropriate model
-            self.page_finder[self.current_pg].set_model(model)
-            qmin, qmax= self.current_pg.get_range()
-            self.page_finder[self.current_pg].set_range(qmin=qmin, qmax=qmax)
-           
-            if self.sim_page != None:
-                self.sim_page.draw_page()
-        
-    def _on_model_menu(self, evt):
-        """
-        Plot a theory from a model selected from the menu
-        
-        :param evt: wx.menu event
-        
-        """
-        model = evt.model
-        Plugin.on_perspective(self,event=evt)
-        # Create a model page. If a new page is created, the model
-        # will be plotted automatically. If a page already exists,
-        # the content will be updated and the plot refreshed
-        self.fit_panel.add_model_page(model, topmenu=True)
-
+       
+        if self.page_finder[id].get_model() is None:
+            model.name = "M" + str(self.index_model)
+            self.index_model += 1  
+        else:
+            model.name = self.page_finder[id].get_model().name
+        # save the name containing the data name with the appropriate model
+        self.page_finder[id].set_model(model)
+        self.page_finder[id].set_range(qmin=qmin, qmax=qmax)
+        if self.sim_page is not None:
+            self.sim_page.draw_page()
+        
     def _update1D(self,x, output):
         """
@@ -1108,5 +992,5 @@
         #self.calc_thread.ready(0.01)
     
-    def _fill_default_model2D(self, theory, qmax,qstep, qmin=None):
+    def _fill_default_model2D(self, theory,id, qmax,qstep, qmin=None):
         """
         fill Data2D with default value 
@@ -1191,72 +1075,74 @@
         theory.ymin = ymin 
         theory.ymax = ymax 
-        theory.group_id = "Model"
-        theory.id = "Model"
-        
-    def _get_plotting_info(self, data=None):
-        """
-        get plotting info from data if data !=None else use some default
-        """
-        my_info = PlotInfo()
-        if data !=None:
-            if hasattr(data,"info"):
-                x_name, x_units = data.get_xaxis() 
-                y_name, y_units = data.get_yaxis() 
+        theory.group_id = str(id) + "Model2D"
+        theory.id = str(id) + "Mode2D"
+  
                 
-                my_info._xunit = x_units
-                my_info._xaxis = x_name
-                my_info._yunit = y_units
-                my_info._yaxis = y_name
-                
-            my_info.title= data.name
-            if hasattr(data, "info"):
-                my_info.info= data.info
-            if hasattr(data, "group_id"):
-                my_info.group_id= data.group_id
-        return my_info
-                
-    def _complete1D(self, x,y, elapsed,index,model,data=None):
+    def _complete1D(self, x,y, id, elapsed,index,model,data=None):
         """
         Complete plotting 1D data
         """ 
         try:
-            new_plot = Theory1D(x=x, y=y)
-            my_info = self._get_plotting_info( data)
-            new_plot.name = model.name
-            new_plot.id = my_info.id
-            new_plot.group_id = my_info.group_id
-            
-            new_plot.xaxis(my_info._xaxis,  my_info._xunit)
-            new_plot.yaxis(my_info._yaxis, my_info._yunit)
+            new_plot = Data1D(x=x, y=y)
+            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
             if data != None:
-                if new_plot.id == data.id:
-                    new_plot.id += "Model"
-                new_plot.is_data =False 
+                _xaxis, _xunit = data.get_xaxis() 
+                _yaxis, _yunit = data.get_yaxis() 
+                new_plot.title = data.name
+                #if the theory is already plotted use the same group id 
+                #to replot
+                if id in self.page_finder:
+                    theory_data = self.page_finder[id].get_theory_data()
+                    if theory_data is not None:
+                        print "theory_data", theory_data.group_id
+                        group_id = theory_data.group_id[len(theory_data.group_id)-1]
+                        if group_id not in data.group_id:
+                            data.group_id.append(group_id)
+                        print "data", data.group_id
+                #data is plotted before the theory, then take its group_id
+                #assign to the new theory
+                group_id = data.group_id[len(data.group_id)-1]
+                if group_id not in new_plot.group_id:
+                    new_plot.group_id.append(group_id)
+            else:
+                _xaxis, _xunit = "\\rm{Q}", 'A^{-1}'
+                _yaxis, _yunit = "\\rm{Intensity} ", "cm^{-1}"
+                new_plot.title = "Analytical model 1D "
+                #find a group id to plot theory without data
+                group_id =  str(id) + " Model1D"  
+                if group_id not in new_plot.group_id:
+                    new_plot.group_id.append(group_id)
+                new_plot.is_data = False 
+            new_plot.id =  str(id) + " Model1D"  
+            #find if this theory was already plotted and replace that plot given
+            #the same id
+            if id in self.page_finder:
+                theory_data = self.page_finder[id].get_theory_data()
+                if theory_data is not None:
+                    temp_id = theory_data.id
+                    new_plot.id = temp_id
+            new_plot.name = model.name + " ["+ str(model.__class__.__name__)+ "]"
+            new_plot.xaxis(_xaxis, _xunit)
+            new_plot.yaxis(_yaxis, _yunit)
+            self.page_finder[id].set_theory_data(new_plot)
            
-            title = new_plot.name
-            # x, y are only in range of index 
-            self.theory_data = new_plot
-            #new_plot.perspective = self.get_perspective()
-            # Pass the reset flag to let the plotting event handler
-            # know that we are replacing the whole plot
-            if title is None:
-                title = "Analytical model 1D "
             if data is None:
                 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot,
-                             title=str(title), reset=True))
+                             title=str(new_plot.title)))
             else:
                 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot,
-                                                       title= str(title)))
-            # Chisqr in fitpage
-            current_pg = self.fit_panel.get_current_page()
+                                            title= str(new_plot.title)))
+            current_pg = self.fit_panel.get_page_by_id(id)
             wx.PostEvent(current_pg,
-                         Chi2UpdateEvent(output=self._cal_chisqr(data=data,
-                                                                 index=index)))
+                Chi2UpdateEvent(output=self._cal_chisqr(data=data,
+                                                        id=id,
+                                                        index=index)))
             msg = "Plot 1D  complete !"
             wx.PostEvent( self.parent, StatusEvent(status=msg, type="stop" ))
         except:
-            msg = " Error occurred when drawing %s Model 1D: " % new_plot.name
-            msg += " %s"  % sys.exc_value
-            wx.PostEvent(self.parent, StatusEvent(status=msg, type="stop"))
+            raise
+            #msg = " Error occurred when drawing %s Model 1D: " % new_plot.name
+            #msg += " %s"  % sys.exc_value
+            #wx.PostEvent(self.parent, StatusEvent(status=msg, type="stop"))
    
     def _update2D(self, output,time=None):
@@ -1269,5 +1155,5 @@
         #self.calc_thread.ready(0.01)
     
-    def _complete2D(self, image, data, model, elapsed, index, qmin,
+    def _complete2D(self, image, data, model, id,  elapsed, index, qmin,
                      qmax, qstep=DEFAULT_NPTS):
         """
@@ -1283,10 +1169,12 @@
             self._fill_default_model2D(theory=theory, 
                                        qmax=qmax, 
+                                       id=id,
                                        qstep=qstep,
                                         qmin= qmin)
-        
+           
         else:
-            theory.id = data.id + "Model"
-            theory.group_id = data.name + "Model"
+            theory.id = str(id) + "Model2D"
+            theory.group_id = str(id) + "Model2D"
+         
             theory.x_bins = data.x_bins
             theory.y_bins = data.y_bins
@@ -1305,23 +1193,18 @@
             theory.xmin = data.xmin
             theory.xmax = data.xmax
-        self.theory_data = theory
+        theory.title = "Analytical model 2D "
+        self.page_finder[id].set_theory_data(theory)
+        
         ## plot
         wx.PostEvent(self.parent, NewPlotEvent(plot=theory,
-                         title="Analytical model 2D ", reset=True))
+                         title=theory.title))
         # Chisqr in fitpage
-        current_pg = self.fit_panel.get_current_page()
+        current_pg = self.fit_panel.get_page_by_id(id)
         wx.PostEvent(current_pg,
-            Chi2UpdateEvent(output=self._cal_chisqr(data=data, index=index)))
+            Chi2UpdateEvent(output=self._cal_chisqr(data=data, id=id, index=index)))
         msg = "Plot 2D complete !"
         wx.PostEvent(self.parent, StatusEvent(status=msg, type="stop"))
-     
-    def _on_data_error(self, event):
-        """
-        receives and event from plotting plu-gins to store the data name and 
-        their errors of y coordinates for 1Data hide and show error
-        """
-        self.err_dy = event.err_dy
-         
-    def _draw_model2D(self, model, data=None, smearer=None,
+    
+    def _draw_model2D(self, model, id, data=None, smearer=None,
                       description=None, enable2D=False,
                       qmin=DEFAULT_QMIN, qmax=DEFAULT_QMAX,
@@ -1346,4 +1229,7 @@
                                num=qstep,
                                endpoint=True)
+        if model is None:
+            msg = "Panel with ID: %s does not contained model" % str(id)
+            raise ValueError, msg
         ## use data info instead
         if data is not None:
@@ -1366,4 +1252,5 @@
                                     model=model, 
                                     data=data,
+                                    id=id,
                                     smearer=smearer,
                                     qmin=qmin,
@@ -1375,9 +1262,10 @@
 
         except:
-            msg = " Error occurred when drawing %s Model 2D: " % model.name
-            msg += " %s" % sys.exc_value
-            wx.PostEvent(self.parent, StatusEvent(status=msg))
-
-    def _draw_model1D(self, model, data=None, smearer=None,
+            raise
+            #msg = " Error occurred when drawing %s Model 2D: " % model.name
+            #msg += " %s" % sys.exc_value
+            #wx.PostEvent(self.parent, StatusEvent(status=msg))
+
+    def _draw_model1D(self, model, id, data=None, smearer=None,
                 qmin=DEFAULT_QMIN, qmax=DEFAULT_QMAX, 
                 qstep=DEFAULT_NPTS, enable1D=True):
@@ -1412,5 +1300,6 @@
             self.calc_1D = Calc1D(x=x,
                                   data=data,
-                                  model=model, 
+                                  model=model,
+                                  id=id, 
                                   qmin=qmin,
                                   qmax=qmax,
@@ -1425,5 +1314,5 @@
             wx.PostEvent(self.parent, StatusEvent(status=msg))
 
-    def _cal_chisqr(self, data=None, index=None): 
+    def _cal_chisqr(self, id, data=None, index=None): 
         """
         Get handy Chisqr using the output from draw1D and 2D, 
@@ -1443,5 +1332,6 @@
             index = index & (data.err_data != 0)  
             fn = data.data[index] 
-            gn = self.theory_data.data[index]
+            theory_data = self.page_finder[id].get_theory_data()
+            gn = theory_data.data[index]
             en = data.err_data[index]
         else:
@@ -1457,5 +1347,6 @@
                 dy[dy==0] = 1  
             fn = data.y[index] 
-            gn = self.theory_data.y
+            theory_data = self.page_finder[id].get_theory_data()
+            gn = theory_data.y
             en = dy[index]
         # residual
Index: sansview/perspectives/fitting/model_thread.py
===================================================================
--- sansview/perspectives/fitting/model_thread.py	(revision 5062bbf9abf800e4b5ffab0375da1c4a03967672)
+++ sansview/perspectives/fitting/model_thread.py	(revision 6bbeacd466719479cfdf24b6e7c1c5f52c93e03d)
@@ -15,4 +15,5 @@
     """
     def __init__(self, x, y, data,model,smearer,qmin, qmax,qstep,
+                 id ,
                  completefn = None,
                  updatefn   = None,
@@ -31,4 +32,5 @@
         self.y = y
         self.data= data
+        self.page_id = id
         # the model on to calculate
         self.model = model
@@ -115,12 +117,13 @@
 
         elapsed = time.time()-self.starttime
-        self.complete( image = output,
-                       data = self.data , 
-                       model = self.model,
-                       elapsed = elapsed,
-                       index = index_model,
-                       qmin = self.qmin,
-                       qmax = self.qmax,
-                       qstep = self.qstep )
+        self.complete(image=output,
+                       data=self.data, 
+                       id=self.page_id,
+                       model=self.model,
+                       elapsed=elapsed,
+                       index=index_model,
+                       qmin=self.qmin,
+                       qmax=self.qmax,
+                       qstep=self.qstep)
         
 
@@ -130,4 +133,5 @@
     """
     def __init__(self, x, model,
+                 id,
                  data=None,
                  qmin=None,
@@ -150,4 +154,5 @@
         self.qmax= qmax
         self.model = model
+        self.page_id = id
         self.smearer= smearer
         self.starttime = 0
@@ -172,4 +177,5 @@
        
         self.complete(x=self.x[index], y=output[index], 
+                      id=self.page_id,
                       elapsed=elapsed,index=index, model=self.model,
                                         data=self.data)
Index: sansview/perspectives/fitting/models.py
===================================================================
--- sansview/perspectives/fitting/models.py	(revision 6886000a4cc45f87810bae7cd4667d8de793ed71)
+++ sansview/perspectives/fitting/models.py	(revision 6bbeacd466719479cfdf24b6e7c1c5f52c93e03d)
@@ -163,5 +163,9 @@
     ## Event owner (guiframe)
     event_owner = None
-    
+    def __init__(self):
+        """
+        """
+        self._getModelList()
+        
     def _getModelList(self):
         """
@@ -552,4 +556,9 @@
         
         """
+        self.model_combobox.set_list("Shapes", self.shape_list)
+        self.model_combobox.set_list("Shape-Independent", self.shape_indep_list)
+        self.model_combobox.set_list("Structure Factors", self.struct_list)
+        self.model_combobox.set_list("Customized Models", self.plugins)
+        self.model_combobox.set_list("P(Q)*S(Q)", self.multiplication_factor)
         self.model_combobox.set_list("multiplication", self.multiplication_factor)
         self.model_combobox.set_list("Multi-Functions", self.multi_func_list)
Index: sansview/perspectives/fitting/simfitpage.py
===================================================================
--- sansview/perspectives/fitting/simfitpage.py	(revision 4ce74917db4f7013acfaaff394cf25d8213f8eee)
+++ sansview/perspectives/fitting/simfitpage.py	(revision 6bbeacd466719479cfdf24b6e7c1c5f52c93e03d)
@@ -50,10 +50,10 @@
         ##Font size
         self.SetWindowVariant(variant = FONT_VARIANT)
-        
+        self.id = None
         self.parent = parent
         ## store page_finder
         self.page_finder = page_finder
         ## list contaning info to set constraint 
-        ## look like self.constraint_dict[page]= page 
+        ## look like self.constraint_dict[page_id]= page 
         self.constraint_dict={}
         ## item list  self.constraints_list=[combobox1, combobox2,=,textcrtl, button ]
@@ -135,6 +135,6 @@
             self._set_constraint()
         ## get the fit range of very fit problem        
-        for page, value in self.page_finder.iteritems():
-            qmin, qmax= page.get_range()
+        for id, value in self.page_finder.iteritems():
+            qmin, qmax= self.page_finder[id].get_range()
             value.set_range(qmin, qmax)
         ## model was actually selected from this page to be fit
@@ -162,6 +162,6 @@
         check all models names
         """
-        self.model_toFit=[] 
-        if self.cb1.GetValue()==True:
+        self.model_toFit = [] 
+        if self.cb1.GetValue()== True:
             for item in self.model_list:
                 item[0].SetValue(True)
@@ -270,6 +270,6 @@
         for item in self.model_toFit:
             model = item[3]
-            page= item[2]
-            self.constraint_dict[page] = model
+            page_id= item[2]
+            self.constraint_dict[page_id] = model
                    
     def _display_constraint(self, event):
@@ -333,5 +333,5 @@
         btRemove.SetToolTipString("Remove constraint.")
        
-        for page,model in self.constraint_dict.iteritems():
+        for id,model in self.constraint_dict.iteritems():
             ## check if all parameters have been selected for constraint
             ## then do not allow add constraint on parameters
@@ -364,6 +364,6 @@
         hide buttons related constraint 
         """  
-        for page in  self.page_finder.iterkeys():
-            self.page_finder[page].clear_model_param()
+        for id in  self.page_finder.iterkeys():
+            self.page_finder[id].clear_model_param()
                
         self.nb_constraint =0     
@@ -539,5 +539,5 @@
                 msg+= " to set constraint! "
                 wx.PostEvent(self.parent.Parent, StatusEvent(status= msg ))
-            for page , value in self.constraint_dict.iteritems():
+            for id, value in self.constraint_dict.iteritems():
                 if model == value:
                     if constraint == "":
@@ -546,5 +546,5 @@
                         wx.PostEvent(self.parent.Parent, StatusEvent(status= msg ))
                         constraint = None
-                    self.page_finder[page].set_model_param(param,constraint)
+                    self.page_finder[id].set_model_param(param,constraint)
                     break
     
@@ -575,29 +575,44 @@
         sizer.Add(data_used,(iy, ix),(1,1),
                             wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
-        
-        for page, value in self.page_finder.iteritems():
+        ix += 1 
+        tab_used = wx.StaticText(self, -1, '  Fit Tab')
+        tab_used.SetBackgroundColour('grey')
+        sizer.Add(tab_used,(iy, ix),(1,1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        for id, value in self.page_finder.iteritems():
             try:
                 ix = 0
                 iy += 1 
                 model = value.get_model()
-                cb = wx.CheckBox(self, -1, str(model.name))
+                name = '_'
+                if model is not None:
+                    name = str(model.name)
+                cb = wx.CheckBox(self, -1, name)
                 cb.SetValue(False)
+                cb.Enable(model is not None)
                 sizer.Add( cb,( iy,ix),(1,1),  wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
                 wx.EVT_CHECKBOX(self, cb.GetId(), self.check_model_name)
-                
                 ix += 2 
                 type = model.__class__.__name__
                 model_type = wx.StaticText(self, -1, str(type))
                 sizer.Add(model_type,( iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+                data = value.get_fit_data()
+                name = '-'
+                if data is not None:
+                    name = str(data.name)
+                data_used = wx.StaticText(self, -1, name)
+                ix += 1 
+                sizer.Add(data_used,( iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+                    
+                ix += 1 
+                caption = value.get_fit_tab_caption()
+                tab_caption_used= wx.StaticText(self, -1, str(caption))
+                sizer.Add(tab_caption_used,( iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
                 
-                ix += 1 
-                data = value.get_fit_data()
-                data_used= wx.StaticText(self, -1, str(data.name))
-                sizer.Add(data_used,( iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
-                
-                self.model_list.append([cb,value,page,model])
+                self.model_list.append([cb,value,id,model])
                 
             except:
-                pass
+                raise
+                #pass
         iy += 1
         sizer.Add((20,20),( iy,ix),(1,1),  wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
