Index: fittingview/src/sans/perspectives/fitting/basepage.py
===================================================================
--- fittingview/src/sans/perspectives/fitting/basepage.py	(revision fa02d950e7e18accb7f8354ee8b8746662d7cb62)
+++ fittingview/src/sans/perspectives/fitting/basepage.py	(revision 6f140f2b7ee93e52dce795ce3d1b3010a48f3268)
@@ -2870,11 +2870,19 @@
             #name = self.model.__class__.__name__
         frame = HelpWindow(None, -1,  pageToOpen=model_path)    
-        frame.Show(True)
         if frame.rhelp.HasAnchor(name):
+            frame.Show(True)
             frame.rhelp.ScrollToAnchor(name)
         else:
            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 ))  
+           if self.model != None:
+               frame.Destroy() 
+               msg = 'Model description:\n'
+               msg += self.model.description + '\n'
+               info = "Info"
+               wx.MessageBox(msg, info)
+           else:
+               frame.Show(True)   
     
     def on_pd_help_clicked(self, event):
Index: fittingview/src/sans/perspectives/fitting/fitting.py
===================================================================
--- fittingview/src/sans/perspectives/fitting/fitting.py	(revision 2b878d74696eb5e752505a227d955eb0d966f358)
+++ fittingview/src/sans/perspectives/fitting/fitting.py	(revision 6f140f2b7ee93e52dce795ce3d1b3010a48f3268)
@@ -42,5 +42,6 @@
 from .pagestate import Reader
 from .fitpage import Chi2UpdateEvent
-from .fitting_widgets import TextDialog
+from sans.perspectives.calculator.model_editor import TextDialog
+from sans.perspectives.calculator.model_editor import EditorWindow
 
 MAX_NBR_DATA = 4
@@ -110,4 +111,5 @@
         self.park_id = wx.NewId()
         self.menu1 = None
+        self.new_model_frame = None
         
         self.temp_state = []
@@ -243,5 +245,5 @@
         filename = os.path.join(models.find_plugins_dir(), label)
         frame = PyConsole(parent=self.parent, manager=self, panel= self.fit_panel,
-                          title='Custom Model Editor', filename=filename)
+                          title='Advanced Custom Model Editor', filename=filename)
         self.put_icon(frame)
         frame.Show(True) 
@@ -256,5 +258,5 @@
         model_list = model_manager.get_model_name_list()
 
-        textdial = TextDialog(None, -1, 'Easy Custom Sum(p1,p2)', model_list)
+        textdial = TextDialog(None, -1, 'Modify Sum(p1, p2) Model', model_list)
         self.put_icon(textdial)
         if textdial.ShowModal() == wx.ID_OK:
@@ -277,4 +279,19 @@
                     raise
         textdial.Destroy()
+    
+    def make_new_model(self, event):
+        """
+        Make new model 
+        """
+        if self.new_model_frame != None and self.new_model_frame.IsShown():
+            self.new_model_frame.Show(False)
+        else:
+            id = event.GetId()
+            dir_path = models.find_plugins_dir()
+            title = "New Custom Model Function"
+            self.new_model_frame = EditorWindow(parent=self, base=self, 
+                                                path=dir_path, title=title)
+            self.put_icon(self.new_model_frame)
+        self.new_model_frame.Show(True)
 
     def update_custom_combo(self):
@@ -303,11 +320,17 @@
         """
         id = wx.NewId()
-        self.edit_model_menu.Append(id, 'Easy Custom Sum(p1, p2)', 
-                                    'Sum two models') 
+        #new_model_menu = wx.Menu()
+        self.edit_model_menu.Append(id, 'New Model Function', 
+                                   'Add a new model function')#, 
+                                   #new_model_menu) 
+        wx.EVT_MENU(owner, id,  self.make_new_model)
+        id = wx.NewId()
+        self.edit_model_menu.Append(id, 'Modify Sum(p1, p2)', 
+                                    'Sum of two model functions') 
         wx.EVT_MENU(owner, id,  self.make_sum_model)
         e_id = wx.NewId()
         self.edit_menu =wx.Menu()
         self.edit_model_menu.AppendMenu(e_id, 
-                                    'Edit Sample File', self.edit_menu) 
+                                    'Advanced Edit', self.edit_menu) 
         self.set_edit_menu_helper(owner)
     
Index: fittingview/src/sans/perspectives/fitting/fitting_widgets.py
===================================================================
--- fittingview/src/sans/perspectives/fitting/fitting_widgets.py	(revision 6e01f064cb85dcaa34cf72be2fe3011e642137ac)
+++ fittingview/src/sans/perspectives/fitting/fitting_widgets.py	(revision 6f140f2b7ee93e52dce795ce3d1b3010a48f3268)
@@ -15,14 +15,4 @@
 import os
 from wx.lib.scrolledpanel import ScrolledPanel
-
-#TextDialog size
-if sys.platform.count("win32") > 0:
-    FONT_VARIANT = 0
-    PNL_WIDTH = 460
-    PNL_HITE = 210
-else:
-    FONT_VARIANT = 1
-    PNL_WIDTH = 500
-    PNL_HITE = 250
 
 MAX_NBR_DATA = 4
@@ -200,455 +190,2 @@
         else:
             self._data_text_ctrl.SetForegroundColour('red')
-        
- 
-class TextDialog(wx.Dialog):
-    """
-    Dialog for easy custom sum models  
-    """
-    def __init__(self, parent=None, id=None, title='', model_list=[]):
-        """
-        Dialog window popup when selecting 'Easy Custom Sum' on the menu
-        """
-        wx.Dialog.__init__(self, parent=parent, id=id, 
-                           title=title, size=(PNL_WIDTH, PNL_HITE))
-        self.parent = parent
-        #Font
-        self.SetWindowVariant(variant=FONT_VARIANT)
-        # default
-        self.model_list = model_list
-        self.model1_string = "SphereModel"
-        self.model2_string = "CylinderModel"
-        self._build_sizer()
-        self.model1_name = str(self.model1.GetValue())
-        self.model2_name = str(self.model2.GetValue())
-        
-    def _build_sizer(self):
-        """
-        Build gui
-        """
-        _BOX_WIDTH = 195 # combobox width
-        vbox  = wx.BoxSizer(wx.VERTICAL)
-        sizer = wx.GridBagSizer(1, 3)
-        sum_description= wx.StaticBox(self, -1, 'Select', 
-                                       size=(PNL_WIDTH-30, 70))
-        sum_box = wx.StaticBoxSizer(sum_description, wx.VERTICAL)
-        model1_box = wx.BoxSizer(wx.HORIZONTAL)
-        model2_box = wx.BoxSizer(wx.HORIZONTAL)
-        model_vbox = wx.BoxSizer(wx.VERTICAL)
-        self.model1 =  wx.ComboBox(self, -1, style=wx.CB_READONLY)
-        wx.EVT_COMBOBOX(self.model1, -1, self.on_model1)
-        self.model1.SetMinSize((_BOX_WIDTH, -1))
-        self.model1.SetToolTipString("model1")
-        self.model2 =  wx.ComboBox(self, -1, style=wx.CB_READONLY)
-        wx.EVT_COMBOBOX(self.model2, -1, self.on_model2)
-        self.model2.SetMinSize((_BOX_WIDTH, -1))
-        self.model2.SetToolTipString("model2")
-        self._set_model_list()
-        
-         # Buttons on the bottom
-        self.static_line_1 = wx.StaticLine(self, -1)
-        self.okButton = wx.Button(self,wx.ID_OK, 'OK', size=(_BOX_WIDTH/2, 25))
-        self.closeButton = wx.Button(self,wx.ID_CANCEL, 'Cancel', 
-                                     size=(_BOX_WIDTH/2, 25))
-        # Intro
-        explanation  = "  custom model = scale_factor * (model1 + model2)\n"
-        model_string = " Model%s (p%s):"
-        vbox.Add(sizer)
-        ix = 0
-        iy = 1
-        sizer.Add(wx.StaticText(self, -1, explanation), (iy, ix),
-                 (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        model1_box.Add(wx.StaticText(self,-1, model_string% (1, 1)), -1, 0)
-        model1_box.Add((_BOX_WIDTH-35,10))
-        model1_box.Add(wx.StaticText(self, -1, model_string% (2, 2)), -1, 0)
-        model2_box.Add(self.model1, -1, 0)
-        model2_box.Add((20,10))
-        model2_box.Add(self.model2, -1, 0)
-        model_vbox.Add(model1_box, -1, 0)
-        model_vbox.Add(model2_box, -1, 0)
-        sum_box.Add(model_vbox, -1, 10)
-        iy += 1
-        ix = 0
-        sizer.Add(sum_box, (iy, ix),
-                  (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
-        vbox.Add((10,10))
-        vbox.Add(self.static_line_1, 0, wx.EXPAND, 10)
-        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
-        sizer_button.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
-        sizer_button.Add(self.okButton, 0, 
-                         wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 0)
-        sizer_button.Add(self.closeButton, 0,
-                          wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 15)        
-        vbox.Add(sizer_button, 0, wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
-        self.SetSizer(vbox)
-        self.Centre()
-                 
-    def _set_model_list(self):
-        """
-        Set the list of models
-        """
-        # list of model names
-        list = self.model_list
-        if len(list) > 1:
-            list.sort()
-        for idx in range(len(list)):
-            self.model1.Append(list[idx],idx) 
-            self.model2.Append(list[idx],idx)
-        self.model1.SetStringSelection(self.model1_string)
-        self.model2.SetStringSelection(self.model2_string)
-           
-    def on_model1(self, event):
-        """
-        Set model1
-        """
-        event.Skip()
-        self.model1_name = str(self.model1.GetValue())
-        self.model1_string = self.model1_name
-            
-    def on_model2(self, event):
-        """
-        Set model2
-        """
-        event.Skip()
-        self.model2_name = str(self.model2.GetValue())
-        self.model2_string = self.model2_name
- 
-    def getText(self):
-        """
-        Returns model name string as list
-        """
-        return [self.model1_name, self.model2_name]
-    
-    def write_string(self, fname, name1, name2):
-        """
-        Write and Save file
-        """
-        try:
-            out_f =  open(fname,'w')
-        except :
-            raise
-        lines = SUM_TEMPLATE.split('\n')
-        for line in lines:
-            if line.count("import %s as P1"):
-                out_f.write(line % (name1, name1) + "\n")
-            elif line.count("import %s as P2"):
-                out_f.write(line % (name2, name2) + "\n")
-            else:
-                out_f.write(line + "\n")
-        out_f.close() 
-        
-    def compile_file(self, path):
-        """
-        Compile the file in the path
-        """
-        try:
-            import py_compile
-            py_compile.compile(file=path, doraise=True)
-        except:
-            type, value, traceback = sys.exc_info()
-            return value
-        
-    def delete_file(self, path):
-        """
-        Delete file in the path
-        """
-        try:
-            os.remove(path)
-        except:
-            raise
-        
-        
-SUM_TEMPLATE = """
-# A sample of an experimental model function for Sum(Pmodel1,Pmodel2)
-import copy
-from sans.models.pluginmodel import Model1DPlugin
-# User can change the name of the model (only with single functional model)
-#P1_model: 
-from sans.models.%s import %s as P1
-
-#P2_model: 
-from sans.models.%s import %s as P2
-
-class Model(Model1DPlugin):
-    name = ""
-    def __init__(self):
-        Model1DPlugin.__init__(self, name='')
-        p_model1 = P1()
-        p_model2 = P2()
-        ## Setting  model name model description
-        self.description=""
-        self.name = self._get_name(p_model1.name, p_model2.name)
-        self.description = p_model1.name
-        self.description += p_model2.name
-        self.fill_description(p_model1, p_model2)
-
-        ## Define parameters
-        self.params = {}
-
-        ## Parameter details [units, min, max]
-        self.details = {}
-        
-        # non-fittable parameters
-        self.non_fittable = p_model1.non_fittable  
-        self.non_fittable += p_model2.non_fittable  
-            
-        ##models 
-        self.p_model1= p_model1
-        self.p_model2= p_model2
-        
-       
-        ## dispersion
-        self._set_dispersion()
-        ## Define parameters
-        self._set_params()
-        ## New parameter:Scaling factor
-        self.params['scale_factor'] = 1
-        
-        ## Parameter details [units, min, max]
-        self._set_details()
-        self.details['scale_factor'] = ['', None, None]
-
-        
-        #list of parameter that can be fitted
-        self._set_fixed_params()  
-        ## parameters with orientation
-        for item in self.p_model1.orientation_params:
-            new_item = "p1_" + item
-            if not new_item in self.orientation_params:
-                self.orientation_params.append(new_item)
-            
-        for item in self.p_model2.orientation_params:
-            new_item = "p2_" + item
-            if not new_item in self.orientation_params:
-                self.orientation_params.append(new_item)
-        # get multiplicity if model provide it, else 1.
-        try:
-            multiplicity1 = p_model1.multiplicity
-            try:
-                multiplicity2 = p_model2.multiplicity
-            except:
-                multiplicity2 = 1
-        except:
-            multiplicity1 = 1
-            multiplicity2 = 1
-        ## functional multiplicity of the model
-        self.multiplicity1 = multiplicity1  
-        self.multiplicity2 = multiplicity2    
-        self.multiplicity_info = []   
-        
-    def _clone(self, obj):
-        obj.params     = copy.deepcopy(self.params)
-        obj.description     = copy.deepcopy(self.description)
-        obj.details    = copy.deepcopy(self.details)
-        obj.dispersion = copy.deepcopy(self.dispersion)
-        obj.p_model1  = self.p_model1.clone()
-        obj.p_model2  = self.p_model2.clone()
-        #obj = copy.deepcopy(self)
-        return obj
-    
-    def _get_name(self, name1, name2):
-        name = self._get_upper_name(name1)
-        name += "+"
-        name += self._get_upper_name(name2)
-        return name
-    
-    def _get_upper_name(self, name=None):
-        if name == None:
-            return ""
-        upper_name = ""
-        str_name = str(name)
-        for index in range(len(str_name)):
-            if str_name[index].isupper():
-                upper_name += str_name[index]
-        return upper_name
-        
-    def _set_dispersion(self):
-        ##set dispersion only from p_model 
-        for name , value in self.p_model1.dispersion.iteritems():
-            #if name.lower() not in self.p_model1.orientation_params:
-            new_name = "p1_" + name
-            self.dispersion[new_name]= value 
-        for name , value in self.p_model2.dispersion.iteritems():
-            #if name.lower() not in self.p_model2.orientation_params:
-            new_name = "p2_" + name
-            self.dispersion[new_name]= value 
-            
-    def function(self, x=0.0): 
-        return 0
-                               
-    def getProfile(self):
-        try:
-            x,y = self.p_model1.getProfile()
-        except:
-            x = None
-            y = None
-            
-        return x, y
-    
-    def _set_params(self):
-        for name , value in self.p_model1.params.iteritems():
-            # No 2D-supported
-            #if name not in self.p_model1.orientation_params:
-            new_name = "p1_" + name
-            self.params[new_name]= value
-            
-        for name , value in self.p_model2.params.iteritems():
-            # No 2D-supported
-            #if name not in self.p_model2.orientation_params:
-            new_name = "p2_" + name
-            self.params[new_name]= value
-                
-        # Set "scale" as initializing
-        self._set_scale_factor()
-      
-            
-    def _set_details(self):
-        for name ,detail in self.p_model1.details.iteritems():
-            new_name = "p1_" + name
-            #if new_name not in self.orientation_params:
-            self.details[new_name]= detail
-            
-        for name ,detail in self.p_model2.details.iteritems():
-            new_name = "p2_" + name
-            #if new_name not in self.orientation_params:
-            self.details[new_name]= detail
-    
-    def _set_scale_factor(self):
-        pass
-        
-                
-    def setParam(self, name, value):
-        # set param to p1+p2 model
-        self._setParamHelper(name, value)
-        
-        ## setParam to p model 
-        model_pre = name.split('_', 1)[0]
-        new_name = name.split('_', 1)[1]
-        if model_pre == "p1":
-            if new_name in self.p_model1.getParamList():
-                self.p_model1.setParam(new_name, value)
-        elif model_pre == "p2":
-             if new_name in self.p_model2.getParamList():
-                self.p_model2.setParam(new_name, value)
-        elif name.lower() == 'scale_factor':
-            self.params['scale_factor'] = value
-        else:
-            raise ValueError, "Model does not contain parameter %s" % name
-            
-    def getParam(self, name):
-        # Look for dispersion parameters
-        toks = name.split('.')
-        if len(toks)==2:
-            for item in self.dispersion.keys():
-                # 2D not supported
-                if item.lower()==toks[0].lower():
-                    for par in self.dispersion[item]:
-                        if par.lower() == toks[1].lower():
-                            return self.dispersion[item][par]
-        else:
-            # Look for standard parameter
-            for item in self.params.keys():
-                if item.lower()==name.lower():
-                    return self.params[item]
-        return  
-        #raise ValueError, "Model does not contain parameter %s" % name
-       
-    def _setParamHelper(self, name, value):
-        # Look for dispersion parameters
-        toks = name.split('.')
-        if len(toks)== 2:
-            for item in self.dispersion.keys():
-                if item.lower()== toks[0].lower():
-                    for par in self.dispersion[item]:
-                        if par.lower() == toks[1].lower():
-                            self.dispersion[item][par] = value
-                            return
-        else:
-            # Look for standard parameter
-            for item in self.params.keys():
-                if item.lower()== name.lower():
-                    self.params[item] = value
-                    return
-            
-        raise ValueError, "Model does not contain parameter %s" % name
-             
-   
-    def _set_fixed_params(self):
-        for item in self.p_model1.fixed:
-            new_item = "p1" + item
-            self.fixed.append(new_item)
-        for item in self.p_model2.fixed:
-            new_item = "p2" + item
-            self.fixed.append(new_item)
-
-        self.fixed.sort()
-                
-                    
-    def run(self, x = 0.0):
-        self._set_scale_factor()
-        return self.params['scale_factor'] * \
-(self.p_model1.run(x) + self.p_model2.run(x))
-    
-    def runXY(self, x = 0.0):
-        self._set_scale_factor()
-        return self.params['scale_factor'] * \
-(self.p_model1.runXY(x) + self.p_model2.runXY(x))
-    
-    ## Now (May27,10) directly uses the model eval function 
-    ## instead of the for-loop in Base Component.
-    def evalDistribution(self, x = []):
-        self._set_scale_factor()
-        return self.params['scale_factor'] * \
-(self.p_model1.evalDistribution(x) + \
-self.p_model2.evalDistribution(x))
-
-    def set_dispersion(self, parameter, dispersion):
-        value= None
-        new_pre = parameter.split("_", 1)[0]
-        new_parameter = parameter.split("_", 1)[1]
-        try:
-            if new_pre == 'p1' and \
-new_parameter in self.p_model1.dispersion.keys():
-                value= self.p_model1.set_dispersion(new_parameter, dispersion)
-            if new_pre == 'p2' and \
-new_parameter in self.p_model2.dispersion.keys():
-                value= self.p_model2.set_dispersion(new_parameter, dispersion)
-            self._set_dispersion()
-            return value
-        except:
-            raise 
-
-    def fill_description(self, p_model1, p_model2):
-        description = ""
-        description +="This model gives the summation of  %s and %s. "% \
-( p_model1.name, p_model2.name )
-        self.description += description
-        
-if __name__ == "__main__": 
-    m1= Model() 
-    #m1.setParam("p1_scale", 25)  
-    #m1.setParam("p1_length", 1000)
-    #m1.setParam("p2_scale", 100) 
-    #m1.setParam("p2_rg", 100) 
-    out1 = m1.runXY(0.01)
-
-    m2= Model()
-    #m2.p_model1.setParam("scale", 25) 
-    #m2.p_model1.setParam("length", 1000) 
-    #m2.p_model2.setParam("scale", 100)
-    #m2.p_model2.setParam("rg", 100)
-    out2 = m2.p_model1.runXY(0.01) + m2.p_model2.runXY(0.01)
-    print out1, " = ", out2
-    if out1 == out2:
-        print "===> Simple Test: Passed!"
-    else:
-        print "===> Simple Test: Failed!"
-"""
-        
-if __name__ == "__main__": 
-    app = wx.PySimpleApp()
-    frame = TextDialog(id=1, model_list=["SphereModel", "CylinderModel"])   
-    frame.Show(True)
-    app.MainLoop()             
-
-          
Index: fittingview/src/sans/perspectives/fitting/help_panel.py
===================================================================
--- fittingview/src/sans/perspectives/fitting/help_panel.py	(revision fdc3cb09d14421671fe0022bc886da554c65ebb0)
+++ fittingview/src/sans/perspectives/fitting/help_panel.py	(revision 6f140f2b7ee93e52dce795ce3d1b3010a48f3268)
@@ -21,4 +21,5 @@
         contains help info
         """
+        self.Show(False)
         self.SetTitle('Fitting Help') 
         from sans.perspectives.fitting import get_data_path as fit_path
@@ -132,5 +133,4 @@
         self.splitter = splitter
         self.Centre()
-        self.Show(True)
         self.Bind(wx.EVT_SIZE, self.on_Size)
         
Index: fittingview/src/sans/perspectives/fitting/plugin_models/testmodel_2.py
===================================================================
--- fittingview/src/sans/perspectives/fitting/plugin_models/testmodel_2.py	(revision e9bd127913a8ceb9ec7480a739688e320a4a8239)
+++ fittingview/src/sans/perspectives/fitting/plugin_models/testmodel_2.py	(revision 6f140f2b7ee93e52dce795ce3d1b3010a48f3268)
@@ -16,6 +16,6 @@
 
 from sans.models.pluginmodel import Model1DPlugin  ##DO NOT CHANGE THIS LINE!!!
-from math import *                    ##DO NOT CHANGE THIS LINE!!!
-from numpy import *                ##DO NOT CHANGE THIS LINE!!!
+import math                     ##DO NOT CHANGE THIS LINE!!!
+import numpy                    ##DO NOT CHANGE THIS LINE!!!
 
 ##PLEASE READ COMMENTS CAREFULLY !!! COMMENT ARE IN CAPITAL LETTERS AND AFTER ##
