Index: sansview/perspectives/fitting/basepage.py
===================================================================
--- sansview/perspectives/fitting/basepage.py	(revision 2f189dc6f284c451361331ccd9f38e9b77746474)
+++ sansview/perspectives/fitting/basepage.py	(revision 7609f1a1b2847768bfea948f933437be03c37f9f)
@@ -172,5 +172,5 @@
                       if set_focus_callback is None else set_focus_callback
             self.Bind(wx.EVT_SET_FOCUS, self._on_set_focus)
-            self.Bind(wx.EVT_KILL_FOCUS, parent._onparamEnter \
+            self.Bind(wx.EVT_KILL_FOCUS, self._silent_kill_focus \
                       if kill_focus_callback is None else kill_focus_callback)                
             self.Bind(wx.EVT_TEXT_ENTER, parent._onparamEnter \
@@ -210,5 +210,12 @@
                     if start==end:
                         control.SetSelection(-1,-1)
-                 
+                        
+        def _silent_kill_focus(self,event):
+            """
+               do nothing to kill focus
+            """
+            event.Skip()
+            pass
+    
     def set_page_info(self, page_info):
         """
@@ -318,10 +325,11 @@
         self.event_owner = owner    
         self.state.event_owner = owner
-  
+        
     def get_data(self):
         """
             return the current data 
         """
-        return self.data
+        return self.data  
+    
     def set_manager(self, manager):
         """
@@ -664,5 +672,8 @@
             self.state.enable_smearer = copy.deepcopy(self.enable_smearer.GetValue())
             self.state.disable_smearer = copy.deepcopy(self.disable_smearer.GetValue())
-            
+
+        self.state.pinhole_smearer = copy.deepcopy(self.pinhole_smearer.GetValue())
+        self.state.slit_smearer = copy.deepcopy(self.slit_smearer.GetValue())  
+                  
         if hasattr(self,"disp_box"):
             self.state.disp_box = self.disp_box.GetCurrentSelection()
@@ -744,4 +755,7 @@
             self.state.enable_smearer = copy.deepcopy(self.enable_smearer.GetValue())
             self.state.disable_smearer = copy.deepcopy(self.disable_smearer.GetValue())
+            
+        self.state.pinhole_smearer = copy.deepcopy(self.pinhole_smearer.GetValue())
+        self.state.slit_smearer = copy.deepcopy(self.slit_smearer.GetValue())  
             
         if hasattr(self,"disp_box"):
@@ -897,4 +911,9 @@
             self.disable_smearer.SetValue(state.disable_smearer)
             self.onSmear(event=None)           
+        self.pinhole_smearer.SetValue(state.pinhole_smearer)
+        self.slit_smearer.SetValue(state.slit_smearer)
+        ## we have two more options for smearing
+        if self.pinhole_smearer.GetValue(): self.onPinholeSmear(event=None)
+        elif self.slit_smearer.GetValue(): self.onSlitSmear(event=None)
        
         ## reset state of checkbox,textcrtl  and dispersity parameters value
@@ -1033,5 +1052,5 @@
         """
         #flag for qmin qmax check values
-        flag =False
+        flag = True
         is_modified = False
         ##So make sure that update param values on_Fit.
@@ -1054,12 +1073,28 @@
                 if tempmax != self.qmax_x:
                     self.qmax_x = tempmax
-                flag = True
-            else:
-                flag = False
-        else:
+                if tempmax == tempmin:
+                    flag = False    
+                temp_smearer = None
+                if not self.disable_smearer.GetValue():
+                    temp_smearer= self.current_smearer
+                    if self.slit_smearer.GetValue():
+                        flag = self.update_slit_smear()
+                    elif self.pinhole_smearer.GetValue():
+                        flag = self.update_pinhole_smear()
+                    else:
+                        self.manager.set_smearer(smearer=temp_smearer, qmin= float(self.qmin_x),
+                                                 qmax= float(self.qmax_x))
+                elif self.data.__class__.__name__ !="Data2D":
+                    self.manager.set_smearer(smearer=temp_smearer, qmin= float(self.qmin_x),
+                                                 qmax= float(self.qmax_x))
+            else: flag = False
+        else: 
             flag = False
-            msg= "Cannot Fit :Must select a model!!!  "
+        
+        if not flag:
+            msg= "Cannot Fit :Must select a model or Fitting range is not valid!!!  "
             wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
-        
+            
+        self.save_current_state()
         return flag                           
                
@@ -1292,6 +1327,6 @@
             temp_smear=None
             if hasattr(self, "enable_smearer"):
-                if self.enable_smearer.GetValue():
-                    temp_smear= self.smearer
+                if not self.disable_smearer.GetValue():
+                    temp_smear= self.current_smearer
             
             self.manager.draw_model(self.model, data=self.data,
@@ -1449,8 +1484,9 @@
      
         return 0
-    
-    def _onparamEnter(self,event):
+
+    #def _onparamEnter(self,event):
         """ 
-            when enter value on panel redraw model according to changed
+        #when enter value on panel redraw model according to changed
+        """
         """
         tcrtl= event.GetEventObject()
@@ -1476,5 +1512,5 @@
             #event.Skip()
             return 
-   
+       """
     def _onQrangeEnter(self, event):
         """
@@ -1599,5 +1635,5 @@
             qmin = float(qmin_ctrl.GetValue())
             qmax = float(qmax_ctrl.GetValue())
-            if qmin < qmax:
+            if qmin <= qmax:
                 #Make sure to set both colours white.  
                 qmin_ctrl.SetBackgroundColour(wx.WHITE)
@@ -1946,12 +1982,10 @@
 
         self.qmin    = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH,20),style=wx.TE_PROCESS_ENTER,
-                                            kill_focus_callback = self._onQrangeEnter,
-                                            text_enter_callback = self._onQrangeEnter)
+                                            text_enter_callback = self._onparamEnter)
         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,
-                                            kill_focus_callback = self._onQrangeEnter,
-                                            text_enter_callback = self._onQrangeEnter)
+                                            text_enter_callback = self._onparamEnter)
         self.qmax.SetValue(str(self.qmax_x))
         self.qmax.SetToolTipString("Maximum value of Q in linear scale.")
@@ -2037,4 +2071,5 @@
         #On 'Reset' button  for Q range clicked
         """
+        flag = True
         if self.check_invalid_panel():
             return
@@ -2049,4 +2084,14 @@
             self.qmin_x = min(self.data.x)
             self.qmax_x = max(self.data.x)
+            # check smearing
+            if not self.disable_smearer.GetValue():
+                temp_smearer= self.current_smearer
+                ## set smearing value whether or not the data contain the smearing info
+                if self.slit_smearer.GetValue():
+                    flag = self.update_slit_smear()
+                elif self.pinhole_smearer.GetValue():
+                    flag = self.update_pinhole_smear()
+                else:
+                    flag = True
         else:
             self.qmin_x = _QMIN_DEFAULT
@@ -2055,5 +2100,9 @@
             self.state.npts = self.num_points
             
-
+        if flag == False:
+            msg= "Cannot Plot :Must enter a number!!!  "
+            wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
+            
+        self.save_current_state()
         self.state.qmin = self.qmin_x
         self.state.qmax = self.qmax_x
Index: sansview/perspectives/fitting/fitpage.py
===================================================================
--- sansview/perspectives/fitting/fitpage.py	(revision 00e8df8739d8d64a8f692658916c7d62c69ca448)
+++ sansview/perspectives/fitting/fitpage.py	(revision 7609f1a1b2847768bfea948f933437be03c37f9f)
@@ -9,8 +9,8 @@
 import time
 from sans.models.dispersion_models import ArrayDispersion, GaussianDispersion
-
+from DataLoader.data_info import Data1D
 from sans.guicomm.events import StatusEvent   
 from sans.guiframe.utils import format_number,check_float
- 
+
 ## event to post model to fit to fitting plugins
 (ModelEventbox, EVT_MODEL_BOX) = wx.lib.newevent.NewEvent()
@@ -21,4 +21,7 @@
 _BOX_WIDTH = 76
 _DATA_BOX_WIDTH = 300
+SMEAR_SIZE_L = 0.005
+SMEAR_SIZE_H = 0.01
+
 import basepage
 from basepage import BasicPage
@@ -47,21 +50,33 @@
         ## default fitengine type
         self.engine_type = None
+        ## smear default
+        self.smearer = None
+        self.current_smearer = None
+        self.dxl = None
+        self.dxw = None
+        self.dx_min = None
+        self.dx_max = None
         
         ## draw sizer
         self._fill_datainfo_sizer()
-       
+        
+        # get smear info from data
+        self._get_smear_info()
+        
         self._fill_model_sizer( self.sizer1)
- 
+        
+        self._get_defult_custom_smear()
+        
         self._fill_range_sizer() 
-        self.enable_smearer.Disable()
-        self.disable_smearer.Disable()
+        
         if self.data is None:
             self.formfactorbox.Disable()
             self.structurebox.Disable()
         else:
-            self.smearer = smear_selection(self.data)
+            self.smearer = smear_selection( self.data )
             if self.smearer ==None:
                 self.enable_smearer.Disable()
-                self.disable_smearer.Disable()
+                #self.disable_smearer.Disable()
+
         self.disp_cb_dict = {}
         ## to update the panel according to the fit engine type selected
@@ -155,4 +170,17 @@
         """
         title = "Fitting"
+        #smear messages & titles
+        smear_message_none  =  "No smearing is selected..."
+        smear_message_dqdata  =  "The dQ data is being used for smearing..."
+        smear_message_2d  =  "No smearing is supported for 2D model fitting..."
+        smear_message_new_ssmear  =  "Please enter only the value of interest to customize smearing..."
+        smear_message_new_psmear  =  "Please enter both; the dQ will be generated by interpolation..."
+        smear_message_pinhole_min_title = "dQ_min[1/A]:"
+        smear_message_pinhole_max_title = "dQ_max[1/A]:"
+        smear_message_slit_height_title = "Slit height[1/A]:"
+        smear_message_slit_width_title = "Slit width[1/A]:"
+        
+        self._get_smear_info()
+
         box_description_range = wx.StaticBox(self, -1,str(title))
         boxsizer_range = wx.StaticBoxSizer(box_description_range, wx.VERTICAL)
@@ -166,36 +194,143 @@
         
         sizer_fit.Add((5,5),1, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)        
-        sizer_fit.Add(self.btFit,0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 35) 
+        sizer_fit.Add(self.btFit,0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 63) 
         sizer_fit.Layout()
+        self.sizer_set_smearer = wx.BoxSizer(wx.VERTICAL)
         sizer_smearer = wx.BoxSizer(wx.HORIZONTAL)
+        self.sizer_new_smear= wx.BoxSizer(wx.HORIZONTAL)
+        self.sizer_set_masking = wx.BoxSizer(wx.HORIZONTAL)
+        sizer_chi2 = wx.BoxSizer(wx.VERTICAL)
+        smear_set_box= wx.StaticBox(self, -1,'Set Instrumental Smearing')
+        sizer_smearer_box = wx.StaticBoxSizer(smear_set_box, wx.HORIZONTAL)
+        sizer_smearer_box.SetMinSize((_DATA_BOX_WIDTH,85))
+        
+        #textcntrl for new resolution
+        self.smear_pinhole_max = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-20,20),style=wx.TE_PROCESS_ENTER,
+                                            text_enter_callback = self.onPinholeSmear)
+        self.smear_pinhole_min = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-20,20),style=wx.TE_PROCESS_ENTER,
+                                            text_enter_callback = self.onPinholeSmear)
+        self.smear_slit_height= self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-20,20),style=wx.TE_PROCESS_ENTER,
+                                            text_enter_callback = self.onSlitSmear)
+        self.smear_slit_width = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-20,20),style=wx.TE_PROCESS_ENTER,
+                                            text_enter_callback = self.onSlitSmear)
+        self.smear_data_left= BGTextCtrl(self, -1, size=(_BOX_WIDTH-20,20), style=0)
+        self.smear_data_left.SetValue(str(self.dq_l))
+        self.smear_data_right = BGTextCtrl(self, -1, size=(_BOX_WIDTH-20,20), style=0)
+        self.smear_data_right.SetValue(str(self.dq_r))
+
+        #set default values
+        self.smear_pinhole_max.SetValue(str(self.dx_max))
+        self.smear_pinhole_min.SetValue(str(self.dx_min))
+        self.smear_slit_height.SetValue(str(self.dxl))
+        self.smear_slit_width.SetValue(str(self.dxw))
+
         #Filling the sizer containing instruments smearing info.
-        self.disable_smearer = wx.RadioButton(self, -1, 'No', style=wx.RB_GROUP)
-        self.enable_smearer = wx.RadioButton(self, -1, 'Yes')
+        self.disable_smearer = wx.RadioButton(self, -1, 'None', style=wx.RB_GROUP)
+        self.enable_smearer = wx.RadioButton(self, -1, 'Use dQ Data')
+        #self.enable_smearer.SetToolTipString("Click to use the loaded dQ data for smearing.")
+        self.pinhole_smearer = wx.RadioButton(self, -1, 'Custom Pinhole Smear')
+        #self.pinhole_smearer.SetToolTipString("Click to input custom resolution for pinhole smearing.")
+        self.slit_smearer = wx.RadioButton(self, -1, 'Custom Slit Smear')
+        #self.slit_smearer.SetToolTipString("Click to input custom resolution for slit smearing.")
         self.Bind(wx.EVT_RADIOBUTTON, self.onSmear, id=self.disable_smearer.GetId())
         self.Bind(wx.EVT_RADIOBUTTON, self.onSmear, id=self.enable_smearer.GetId())
+        self.Bind(wx.EVT_RADIOBUTTON, self.onPinholeSmear, id=self.pinhole_smearer.GetId())
+        self.Bind(wx.EVT_RADIOBUTTON, self.onSlitSmear, id=self.slit_smearer.GetId())
         self.disable_smearer.SetValue(True)
         
-        sizer_smearer.Add(wx.StaticText(self,-1,'Instrument Smearing? '))
-        sizer_smearer.Add((10, 10))
-        sizer_smearer.Add( self.enable_smearer )
+        # add 4 types of smearing to the sizer
+        sizer_smearer.Add( self.disable_smearer,0, wx.LEFT, 10)
         sizer_smearer.Add((10,10))
-        sizer_smearer.Add( self.disable_smearer )
-        #Display Chi^2/dof
-        sizer_smearer.Add((78,10))
+        sizer_smearer.Add( self.enable_smearer)
+        sizer_smearer.Add((10,10))
+        sizer_smearer.Add( self.pinhole_smearer ) 
+        sizer_smearer.Add((10,10))
+        sizer_smearer.Add( self.slit_smearer ) 
+        sizer_smearer.Add((10,10))       
+        
+        # static box for chi2
         box_description= wx.StaticBox(self, -1,'Chi2/dof')
         boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
-        boxsizer1.SetMinSize((80,-1))
-        temp_smearer = None
-        if self.enable_smearer.GetValue():
-            temp_smearer= self.smearer
-        
+        boxsizer1.SetMinSize((70,40))
+        
+        
+        
+        # StaticText for chi2 and smear
         self.tcChi    =  wx.StaticText(self, -1, "-", style=wx.ALIGN_LEFT)
-         
-        boxsizer1.Add( self.tcChi )   
-        sizer_smearer.Add( boxsizer1 )
-               
+        self.smear_description_none    =  wx.StaticText(self, -1, smear_message_none , style=wx.ALIGN_LEFT)
+        self.smear_description_dqdata    =  wx.StaticText(self, -1, smear_message_dqdata , style=wx.ALIGN_LEFT)
+        self.smear_description_type    =  wx.StaticText(self, -1, "Type:" , style=wx.ALIGN_LEFT)
+        self.smear_description_smear_type    =  BGTextCtrl(self, -1, size=(45,20), style=0)
+        self.smear_description_smear_type.SetValue(str(self.dq_l))
+        self.SetBackgroundColour(self.GetParent().GetBackgroundColour())
+        self.smear_description_2d     =  wx.StaticText(self, -1, smear_message_2d  , style=wx.ALIGN_LEFT)
+        self.smear_message_new_s = wx.StaticText(self, -1, smear_message_new_ssmear  , style=wx.ALIGN_LEFT)
+        self.smear_message_new_p = wx.StaticText(self, -1, smear_message_new_psmear  , style=wx.ALIGN_LEFT)
+        self.smear_description_pin_min     =  wx.StaticText(self, -1, smear_message_pinhole_min_title  , style=wx.ALIGN_LEFT)
+        self.smear_description_pin_max     =  wx.StaticText(self, -1, smear_message_pinhole_max_title  , style=wx.ALIGN_LEFT)
+        self.smear_description_slit_height    =  wx.StaticText(self, -1, smear_message_slit_height_title   , style=wx.ALIGN_LEFT)
+        self.smear_description_slit_width    =  wx.StaticText(self, -1, smear_message_slit_width_title   , style=wx.ALIGN_LEFT)
+        
+        #arrange sizers 
+        boxsizer1.Add( self.tcChi )  
+        self.sizer_set_smearer.Add(sizer_smearer )
+        self.sizer_set_smearer.Add((10,10))
+        self.sizer_set_smearer.Add( self.smear_description_none,0, wx.CENTER, 10 ) 
+        self.sizer_set_smearer.Add( self.smear_description_dqdata,0, wx.CENTER, 10 )
+        self.sizer_set_smearer.Add( self.smear_description_2d,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add( self.smear_description_type,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add( self.smear_description_smear_type,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add((15,-1))
+        self.sizer_new_smear.Add( self.smear_description_pin_min,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add( self.smear_description_slit_height,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add( self.smear_pinhole_min,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add( self.smear_slit_height,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add( self.smear_data_left,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add((20,-1))
+        self.sizer_new_smear.Add( self.smear_description_pin_max,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add( self.smear_description_slit_width,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add( self.smear_pinhole_max,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add( self.smear_slit_width,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add( self.smear_data_right,0, wx.CENTER, 10 )
+           
+        self.sizer_set_smearer.Add( self.smear_message_new_s,0, wx.CENTER, 10)
+        self.sizer_set_smearer.Add( self.smear_message_new_p,0, wx.CENTER, 10)
+        self.sizer_set_smearer.Add((5,2))
+        self.sizer_set_smearer.Add( self.sizer_new_smear,0, wx.CENTER, 10 )
+        
+        # add all to chi2 sizer
+        
+        sizer_smearer_box.Add(self.sizer_set_smearer) 
+        
+        sizer_chi2.Add(sizer_smearer_box)
+        sizer_chi2.Add((-1,5))
+        self.sizer_set_masking.Add((305,-1))
+        self.sizer_set_masking.Add(boxsizer1,0, wx.RIGHT, 10)
+        sizer_chi2.Add(self.sizer_set_masking )
+
+        #sizer_smearer_box.Add(sizer_chi2)
+        # hide all smear messages and textctrl
+        self._hide_all_smear_info()
+        
+        # get smear_selection
+        self.current_smearer= smear_selection( self.data )
+        print "self.current_smearer",self.current_smearer,self.data.__class__.__name__
+        # Show only the relevant smear messages, etc
+        if self.current_smearer == None:
+            if self.data.__class__.__name__ != 'Data2D':
+                self.smear_description_none.Show(True)
+                self.enable_smearer.Disable()  
+            else:
+                print "2dl"
+                self.smear_description_2d.Show(True) 
+                self.pinhole_smearer.Disable() 
+                self.slit_smearer.Disable()   
+                self.enable_smearer.Disable() 
+        else: self._show_smear_sizer()
+  
+            
         #Set sizer for Fitting section
-        self._set_range_sizer( title=title,box_sizer=boxsizer_range, object1=sizer_smearer, object= sizer_fit)
-
+        self._set_range_sizer( title=title,box_sizer=boxsizer_range, object1=sizer_chi2, object= sizer_fit)
+        
     def _fill_datainfo_sizer(self):
         """
@@ -229,7 +364,7 @@
         #Filling the sizer containing data related fields
         #self.dataSource = wx.StaticText(self, -1,str(self.data.name))
-        self.dataSource = wx.TextCtrl(self, -1)
+        self.dataSource = BGTextCtrl(self, -1)
         self.dataSource.SetValue(str(data_name))
-        self.dataSource.SetEditable(False)
+        #self.dataSource.SetEditable(False)
         self.dataSource.SetMinSize((_DATA_BOX_WIDTH, -1))
         sizer_data.Add(wx.StaticText(self, -1, 'Source Name : '))
@@ -242,10 +377,10 @@
         sizer_range = wx.BoxSizer(wx.HORIZONTAL)
         sizer_range.Add( text4_3 ,0, wx.RIGHT, 10)
-        self.minimum_q = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20))
+        self.minimum_q = BGTextCtrl(self, -1, size=(_BOX_WIDTH,20))
         self.minimum_q.SetValue(str(data_min))
-        self.minimum_q.SetEditable(False)
-        self.maximum_q = wx.TextCtrl(self, -1,size=(_BOX_WIDTH,20))
+        #self.minimum_q.SetEditable(False)
+        self.maximum_q = BGTextCtrl(self, -1,size=(_BOX_WIDTH,20))
         self.maximum_q.SetValue(str(data_max))
-        self.maximum_q.SetEditable(False)
+        #self.maximum_q.SetEditable(False)
         sizer_range.Add(wx.StaticText(self, -1, "Min: "),0, wx.LEFT, 10)
         sizer_range.Add(self.minimum_q,0, wx.LEFT, 10)
@@ -388,5 +523,4 @@
                         ix = 4
                         ctl3 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
-                                                       kill_focus_callback = self._onparamRangeEnter,
                                                        text_enter_callback = self._onparamRangeEnter)
 
@@ -396,5 +530,4 @@
                         ix = 5
                         ctl4 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
-                                                       kill_focus_callback = self._onparamRangeEnter,
                                                        text_enter_callback = self._onparamRangeEnter)
                         self.sizer4_4.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
@@ -487,5 +620,4 @@
                         ix = 4
                         ctl3 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
-                                                       kill_focus_callback = self._onparamRangeEnter,
                                                        text_enter_callback = self._onparamRangeEnter)
 
@@ -496,5 +628,4 @@
                         ix = 5
                         ctl4 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
-                                                       kill_focus_callback = self._onparamRangeEnter,
                                                        text_enter_callback = self._onparamRangeEnter)
                         self.sizer4_4.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
@@ -584,5 +715,5 @@
                 
         if not flag:
-            msg= "Fitting range invalid"
+            msg= "Fitting range or parameters are invalid"
             wx.PostEvent(self.parent.parent, StatusEvent(status= msg ))
             return 
@@ -663,4 +794,6 @@
         self.state.enable_disp = self.enable_disp.GetValue()
         self.state.disable_disp = self.disable_disp.GetValue()
+        self.state.pinhole_smearer = self.pinhole_smearer.GetValue()
+        self.state.slit_smearer = self.slit_smearer.GetValue()
     
         self.state.structurecombobox = self.structurebox.GetCurrentSelection()
@@ -687,9 +820,19 @@
 
         if check_float(tcrtl):
-            flag = self._onparamEnter_helper()
-            if flag:
-                temp_smearer = None
-                if self.enable_smearer.GetValue():
-                    temp_smearer= self.smearer
+            flag = self._onparamEnter_helper()                
+            temp_smearer = None
+            if not self.disable_smearer.GetValue():
+                temp_smearer= self.current_smearer
+                ## set smearing value whether or not the data contain the smearing info
+                if self.slit_smearer.GetValue():
+                    flag1 = self.update_slit_smear()
+                    flag = flag or flag1
+                elif self.pinhole_smearer.GetValue():
+                    flag1 = self.update_pinhole_smear()
+                    flag = flag or flag1
+            else:
+                self.manager.set_smearer(smearer=temp_smearer, qmin= float(self.qmin_x),
+                                                         qmax= float(self.qmax_x)) 
+            if flag:   
                 self.compute_chisqr(smearer= temp_smearer)
     
@@ -699,13 +842,13 @@
                     event = PageInfoEvent(page = self)
                     wx.PostEvent(self.parent, event)
-                self.state_change= False
-            self.save_current_state()
+                self.state_change= False           
         else:
             self.save_current_state()
             msg= "Cannot Plot :Must enter a number!!!  "
             wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
-            return 
-        
-
+             
+        self.save_current_state() 
+        return 
+   
     def _onparamRangeEnter(self, event):
         """
@@ -841,4 +984,104 @@
         return        
                 
+    def _get_defult_custom_smear(self):
+        """
+           Get the defult values for custum smearing.
+        """
+
+        # get the default values
+        if self.dxl == None: self.dxl = 0.0
+        if self.dxw == None: self.dxw = ""
+        if self.dx_min == None: self.dx_min = SMEAR_SIZE_L
+        if self.dx_max == None: self.dx_max = SMEAR_SIZE_H
+        
+    def _get_smear_info(self):
+        """
+           Get the smear info from data.
+           @return: self.smear_type, self.dq_l and self.dq_r, 
+            respectively the type of the smear, dq_min and dq_max for pinhole smear data 
+            while dxl and dxw for slit smear
+        """
+
+        # default
+        self.smear_type = None
+        self.dq_l = None
+        self.dq_r = None
+        
+        if self.data is None or\
+                self.data.__class__.__name__ == 'Data2D':           
+            return
+
+        data = self.data
+
+        # check if it is pinhole smear and get min max if it is.
+        if data.dx != None and all(data.dx !=0): 
+            self.smear_type = "Pinhole" 
+            self.dq_l = numpy.min(data.dx)
+            self.dq_r = numpy.max(data.dx)
+            
+        # check if it is slit smear and get min max if it is.
+        elif data.dxl != None or data.dxw != None: 
+            self.smear_type = "Slit" 
+            if data.dxl != None and all(data.dxl !=0):
+                self.dq_l = data.dxl[0]
+            if data.dxw != None and all(data.dxw !=0): 
+                self.dq_r = data.dxw[0]
+                
+        #return self.smear_type,self.dq_l,self.dq_r       
+    
+    def _show_smear_sizer(self):    
+        """
+            Show only the sizers depending on smear selection
+        """
+        if self.disable_smearer.GetValue():
+            self.smear_description_none.Show(True)
+        elif self.enable_smearer.GetValue():
+            self.smear_description_dqdata.Show(True)
+            if self.smear_type != None:
+                self.smear_description_type.Show(True)
+                self.smear_description_smear_type.Show(True)
+                if self.smear_type == 'Slit':
+                    self.smear_description_slit_height.Show(True)
+                    self.smear_description_slit_width.Show(True)
+                elif self.smear_type == 'Pinhole':
+                    self.smear_description_pin_min.Show(True)
+                    self.smear_description_pin_max.Show(True)
+                self.smear_data_left.Show(True)
+                self.smear_data_right.Show(True)
+        elif self.pinhole_smearer.GetValue():
+            self.smear_message_new_p.Show(True)
+            self.smear_description_pin_min.Show(True)
+            self.smear_pinhole_min.Show(True)
+            self.smear_description_pin_max.Show(True)
+            self.smear_pinhole_max.Show(True)
+        elif self.slit_smearer.GetValue():
+            self.smear_message_new_s.Show(True)
+            self.smear_description_slit_height.Show(True)
+            self.smear_slit_height.Show(True)
+            self.smear_description_slit_width.Show(True)
+            self.smear_slit_width.Show(True)
+
+    def _hide_all_smear_info(self):
+        """
+           Hide all smearing messages in the set_smearer sizer
+        """
+        self.smear_description_none.Hide()
+        self.smear_description_dqdata.Hide()
+        self.smear_description_type.Hide()
+        self.smear_description_smear_type.Hide()
+        self.smear_description_2d.Hide()
+        self.smear_data_left.Hide()
+        self.smear_data_right.Hide()
+        self.smear_description_pin_min.Hide()
+        self.smear_pinhole_min.Hide()
+        self.smear_description_pin_max.Hide()
+        self.smear_pinhole_max.Hide()
+        self.smear_description_slit_height.Hide()
+        self.smear_slit_height.Hide()
+        self.smear_description_slit_width.Hide()
+        self.smear_slit_width.Hide()
+        self.smear_message_new_p.Hide()
+        self.smear_message_new_s.Hide()
+    
         
     def set_data(self, data):
@@ -857,8 +1100,13 @@
             if self.smearer == None:
                 self.enable_smearer.Disable()
-                self.disable_smearer.Disable()
             else:
                 self.enable_smearer.Enable()
-                self.disable_smearer.Enable()
+
+            # more disables for 2D
+            if self.data.__class__.__name__ =="Data2D":
+                self.smear_description_none.Hide()
+                self.smear_description_2d.Show(True)
+                self.pinhole_smearer.Disable()
+                self.slit_smearer.Disable()
                 
             self.formfactorbox.Enable()
@@ -892,5 +1140,5 @@
         self.state.qmax = self.qmax_x
         
-        
+
     def reset_page(self, state,first=False):
         """
@@ -972,7 +1220,8 @@
         if chisqr != None or numpy.isfinite(chisqr):
         #format chi2  
-            if self.engine_type == "park" and npt_fit > 0:  
+            if self.engine_type == "park":  
                 npt_fit = float(self.get_npts2fit()) 
-                chisqr =chisqr/npt_fit    
+                if npt_fit > 0:
+                    chisqr =chisqr/npt_fit    
             chi2 = format_number(chisqr)    
             self.tcChi.SetLabel(chi2)    
@@ -1076,6 +1325,294 @@
         msg = "Fit completed! "
         wx.PostEvent(self.manager.parent, StatusEvent(status=msg))
-      
-
+
+    def onPinholeSmear(self, event):
+        """
+            Create a custom pinhole smear object that will change the way residuals
+            are compute when fitting
+        """
+
+        if self.check_invalid_panel():
+            return
+        if self.model ==None:
+            msg="Need model and data to smear plot"
+            wx.PostEvent(self.manager.parent, StatusEvent(status=\
+                            "Smear: %s"%msg))
+            return
+        
+        # msg default
+        msg = None
+        if event != None:
+            tcrtl= event.GetEventObject()
+            # event case of radio button
+            if tcrtl.GetValue()== True:
+                self.dx_min = 0.0
+                self.dx_max = 0.0
+                is_new_pinhole = True
+            else:
+                is_new_pinhole = self._is_changed_pinhole()
+        # if any value is changed
+        if is_new_pinhole:
+            msg = self._set_pinhole_smear()
+        # hide all silt sizer    
+        self._hide_all_smear_info()
+           
+        ##Calculate chi2
+        self.compute_chisqr(smearer= self.current_smearer) 
+        # show relevant slit sizers 
+        self._show_smear_sizer()
+        self.sizer_set_smearer.Layout()
+        self.Layout()   
+        
+        if event != None: 
+            event.Skip()                  
+        #self._undo.Enable(True)
+        self.save_current_state()
+        event = PageInfoEvent(page = self)
+        wx.PostEvent(self.parent, event)
+        
+    def _is_changed_pinhole(self):  
+        """
+            check if any of pinhole smear is changed
+            return: True or False
+        """
+        # get the values
+        pin_min = self.smear_pinhole_min.GetValue()
+        pin_max = self.smear_pinhole_max.GetValue()
+                    
+        # Check changes in slit width    
+        try:
+            dx_min = float(pin_min)
+        except:
+            return True
+        if self.dx_min != dx_min:
+            return True
+        
+        # Check changes in slit heigth
+        try:
+            dx_max = float(pin_max)
+        except:
+            return True
+        if self.dx_max != dx_max:
+            return True
+        return False
+    
+    def _set_pinhole_smear(self):
+        """
+            Set custom pinhole smear
+            return: msg
+        """
+        # copy data
+        data = copy.deepcopy(self.data)
+        data_len = len(data.x)
+        data.dx = None
+        data.dxl = None
+        data.dxw = None
+        msg = None
+   
+        # make sure once more if it is smearer
+        data = copy.deepcopy(self.data)
+        len_data = len(data.x)
+        data.dx = numpy.zeros(len_data)
+        get_pin_min = self.smear_pinhole_min
+        get_pin_max = self.smear_pinhole_max        
+
+        if self._validate_qrange(get_pin_min, get_pin_max ):
+            if len_data < 2: len_data = 2     
+            self.dx_min = float(get_pin_min.GetValue())
+            self.dx_max = float(get_pin_max.GetValue())
+            if self.dx_min != None and self.dx_max != None:             
+                if self.dx_min == self.dx_max:
+                    data.dx[data.dx==0] = self.dx_min
+                else:
+                    step = math.fabs(self.dx_max - self.dx_min)/(len_data-1)    
+                    data.dx = numpy.arange(self.dx_min,self.dx_max+step/1.1,step)            
+            elif self.dx_min != None: 
+                data.dx[data.dx==0] = self.dx_min 
+            elif self.dx_max != None:
+                data.dx[data.dx==0] = self.dx_max          
+            self.current_smearer = smear_selection(data)
+
+        else:
+            get_pin_min.SetBackgroundColour("pink")
+            get_pin_max.SetBackgroundColour("pink")
+            msg= "Model Error:wrong value entered!!!"
+            wx.PostEvent(self.manager.parent, StatusEvent(status = msg ))
+        ## 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))
+ 
+        return msg
+        
+    def update_pinhole_smear(self):
+        """
+            called by kill_focus on pinhole TextCntrl
+            to update the changes 
+            return: msg: False when wrong value was entered
+        """
+        # msg default
+        msg = None
+        # check if any value is changed
+        if self._is_changed_pinhole():
+            msg = self._set_pinhole_smear()           
+        #self._undo.Enable(True)
+        self.save_current_state()
+
+        if msg != None:
+            return False   
+        else:
+            return True
+                     
+    def onSlitSmear(self, event):
+        """
+            Create a custom slit smear object that will change the way residuals
+            are compute when fitting
+        """
+
+               
+        if self.check_invalid_panel():
+            return
+        if self.model ==None:
+            msg="Need model and data to smear plot"
+            wx.PostEvent(self.manager.parent, StatusEvent(status=\
+                            "Smear: %s"%msg))
+            return
+        # msg default
+        msg = None
+        # for event given
+        if event != None:
+            tcrtl= event.GetEventObject()
+            # event case of radio button
+            if tcrtl.GetValue():
+                self.dxl = 0.0
+                self.dxw = 0.0
+                is_new_slit = True
+            else:
+                is_new_slit = self._is_changed_slit()
+                
+        # if any value is changed
+        if is_new_slit:
+            msg = self._set_slit_smear()
+        # hide all silt sizer
+        self._hide_all_smear_info()        
+        ##Calculate chi2
+        self.compute_chisqr(smearer= self.current_smearer)  
+        # show relevant slit sizers       
+        self._show_smear_sizer()
+        self.sizer_set_smearer.Layout()
+        self.Layout()
+        
+        if event != None:
+            event.Skip()     
+        #self._undo.Enable(True)
+        self.save_current_state()
+        event = PageInfoEvent(page = self)
+        wx.PostEvent(self.parent, event)
+        if msg != None:
+            wx.PostEvent(self.manager.parent, StatusEvent(status = msg))
+
+            
+    def _is_changed_slit(self):  
+        """
+            check if any of slit lengths is changed
+            return: True or False
+        """
+        # get the values
+        width = self.smear_slit_width.GetValue()
+        height = self.smear_slit_height.GetValue()
+        
+        # check and change the box bg color if it was pink but it should be white now
+        # because this is the case that _set_slit_smear() will not handle
+        if height.lstrip().rstrip()=="":
+            self.smear_slit_height.SetBackgroundColour(wx.WHITE)
+        if width.lstrip().rstrip()=="":
+            self.smear_slit_width.SetBackgroundColour(wx.WHITE)
+            
+        # Check changes in slit width    
+        if width == "": 
+            dxw = 0.0
+        else:
+            try:
+                dxw = float(width)
+            except:
+                return True
+        if self.dxw != dxw:
+            return True
+        
+        # Check changes in slit heigth
+        if height == "": 
+            dxl = 0.0
+        else:
+            try:
+                dxl = float(height)
+            except:
+                return True
+        if self.dxl != dxl:
+            return True
+        return False
+    
+    def _set_slit_smear(self):
+        """
+            Set custom slit smear
+            return: msg
+        """
+        temp_smearer = None
+        # make sure once more if it is smearer
+        data = copy.deepcopy(self.data)
+        data_len = len(data.x)
+        data.dx = None
+        data.dxl = None
+        data.dxw = None
+        msg = None
+   
+        try:
+            self.dxl = float(self.smear_slit_height.GetValue())
+            data.dxl = self.dxl* numpy.ones(data_len)
+            self.smear_slit_height.SetBackgroundColour(wx.WHITE)
+        except: 
+            data.dxl = numpy.zeros(data_len)
+            if self.smear_slit_height.GetValue().lstrip().rstrip()!="":
+                self.smear_slit_height.SetBackgroundColour("pink")
+                msg = "Wrong value entered... "  
+            else:
+                self.smear_slit_height.SetBackgroundColour(wx.WHITE)
+        try:
+            self.dxw = float(self.smear_slit_width.GetValue())
+            self.smear_slit_width.SetBackgroundColour(wx.WHITE)
+            data.dxw = self.dxw* numpy.ones(data_len)
+        except: 
+            data.dxw = numpy.zeros(data_len)
+            if self.smear_slit_width.GetValue().lstrip().rstrip()!="":
+                self.smear_slit_width.SetBackgroundColour("pink")
+                msg = "Wrong Fit value entered... "
+            else:
+                self.smear_slit_width.SetBackgroundColour(wx.WHITE)
+                
+        self.current_smearer = smear_selection(data)
+        #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)) 
+
+        return msg
+    
+    
+    def update_slit_smear(self):
+        """
+            called by kill_focus on pinhole TextCntrl
+            to update the changes 
+            return: msg: False when wrong value was entered
+        """             
+        # msg default
+        msg = None
+        # check if any value is changed
+        if self._is_changed_slit():
+            msg = self._set_slit_smear()           
+        #self._undo.Enable(True)
+        self.save_current_state()
+
+        if msg != None:
+            return False   
+        else:
+            return True
+                            
+    
     def onSmear(self, event):
         """
@@ -1091,8 +1628,22 @@
             return
         temp_smearer = None
-      
+        self._get_smear_info()
+        
+        #renew smear sizer
+        if self.smear_type != None:
+            self.smear_description_smear_type.SetValue(str(self.smear_type))
+            self.smear_data_left.SetValue(str(self.dq_l))   
+            self.smear_data_right.SetValue(str(self.dq_r))       
+        
+        self._hide_all_smear_info()
+        
+        data = copy.deepcopy(self.data)
+        # make sure once more if it is smearer
+        self.current_smearer = smear_selection(data)
+
         if self.enable_smearer.GetValue():
-            temp_smearer= self.smearer
+            temp_smearer= self.current_smearer
             if hasattr(self.data,"dxl"):
+                
                 msg= ": Resolution smearing parameters"
             if hasattr(self.data,"dxw"):
@@ -1104,5 +1655,13 @@
                 wx.PostEvent(self.manager.parent, StatusEvent(status=\
                             "Data contains smearing information %s"%msg))
-       
+            self.smear_description_dqdata.Show(True)
+            self.smear_data_left.Show(True)
+            self.smear_data_right.Show(True)
+        elif self.disable_smearer.GetValue():
+            self.smear_description_none.Show(True)
+            
+        self._show_smear_sizer()
+        self.sizer_set_smearer.Layout()
+        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),
@@ -1113,5 +1672,7 @@
         self.state.enable_smearer=  self.enable_smearer.GetValue()
         self.state.disable_smearer=self.disable_smearer.GetValue()
-   
+        self.state.pinhole_smearer = self.pinhole_smearer.GetValue()
+        self.state.slit_smearer = self.slit_smearer.GetValue()
+        
     def complete_chisqr(self, output, elapsed=None):  
         """
@@ -1417,5 +1978,4 @@
                 ix += 1
                 ctl3 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
-                                               kill_focus_callback = self._onparamRangeEnter,
                                                text_enter_callback = self._onparamRangeEnter)
      
@@ -1425,5 +1985,4 @@
                 ix += 1
                 ctl4 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
-                                               kill_focus_callback = self._onparamRangeEnter,
                                                text_enter_callback = self._onparamRangeEnter)
                 sizer.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
@@ -1516,5 +2075,4 @@
                     ix += 1
                     ctl3 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
-                                                   kill_focus_callback = self._onparamRangeEnter,
                                                    text_enter_callback = self._onparamRangeEnter)
                
@@ -1524,5 +2082,4 @@
                     ix += 1
                     ctl4 = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
-                                                   kill_focus_callback = self._onparamRangeEnter,
                                                    text_enter_callback = self._onparamRangeEnter)
                     sizer.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
@@ -1571,5 +2128,26 @@
         self.SetScrollbars(20,20,25,65)
 
-
+class BGTextCtrl(wx.TextCtrl):
+    """
+        Text control used to display outputs.
+        No editing allowed. The background is 
+        grayed out. User can't select text.
+    """
+    def __init__(self, *args, **kwds):
+        wx.TextCtrl.__init__(self, *args, **kwds)
+        self.SetEditable(False)
+        self.SetBackgroundColour(self.GetParent().GetBackgroundColour())
+        
+        # Bind to mouse event to avoid text highlighting
+        # The event will be skipped once the call-back
+        # is called.
+        self.Bind(wx.EVT_MOUSE_EVENTS, self._click)
+        
+    def _click(self, event):
+        """
+            Prevent further handling of the mouse event
+            by not calling Skip().
+        """ 
+        pass
         
 class HelpWindow(wx.Frame):
Index: sansview/perspectives/fitting/pagestate.py
===================================================================
--- sansview/perspectives/fitting/pagestate.py	(revision b421b1a08ae7adfc77e2f7190153fd10bd1931b9)
+++ sansview/perspectives/fitting/pagestate.py	(revision 7609f1a1b2847768bfea948f933437be03c37f9f)
@@ -51,4 +51,8 @@
         ## smearer info
         self.smearer=None
+        self.smear_type = None
+        self.dq_l = None
+        self.dq_r = None
+
         #list of dispersion paramaters
         self.disp_list =[]
@@ -85,4 +89,6 @@
         self.enable_smearer = False
         self.disable_smearer = True
+        self.pinhole_smearer = False
+        self.slit_smearer   = False
         ## disperity selection
         self.enable_disp= False
@@ -138,4 +144,10 @@
         obj.enable_smearer = copy.deepcopy(self.enable_smearer)
         obj.disable_smearer = copy.deepcopy(self.disable_smearer)
+        obj.pinhole_smearer = copy.deepcopy(self.pinhole_smearer)
+        obj.slit_smearer = copy.deepcopy(self.slit_smearer)
+        obj.smear_type = copy.deepcopy(self.smear_type)
+        obj.dq_l = copy.deepcopy(self.dq_l)
+        obj.dq_r = copy.deepcopy(self.dq_r)
+
        
         obj.disp_box = copy.deepcopy(self.disp_box)
