Index: src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FittingWidget.py	(revision 6f7f65230cc7b516a85452e22a120341bf88858e)
+++ src/sas/qtgui/Perspectives/Fitting/FittingWidget.py	(revision 86f88d1f01ba28c866b6d45139c207d986c99d1a)
@@ -15,4 +15,5 @@
 TAB_MAGNETISM = 4
 TAB_POLY = 3
+CATEGORY_DEFAULT="Choose category..."
 
 class FittingWidget(QtGui.QWidget, Ui_FittingWidgetUI):
@@ -29,18 +30,23 @@
         super(FittingWidget, self).__init__()
 
+        # Necessary globals
         self.model_is_loaded = False
         self._data = data
         self.is2D = False
-        self.modelHasShells = False
+        self.model_has_shells = False
         self.data_assigned = False
-
+        self._previous_category_index = 0
+        self._last_model_row = 0
+
+        # Main GUI setup up
         self.setupUi(self)
-
         self.setWindowTitle("Fitting")
 
-        # set the main models
+        # Set the main models
         self._model_model = QtGui.QStandardItemModel()
         self._poly_model = QtGui.QStandardItemModel()
         self._magnet_model = QtGui.QStandardItemModel()
+        # Proxy model for custom views on the main _model_model
+        self.proxyModel = QtGui.QSortFilterProxyModel()
 
         # Param model displayed in param list
@@ -48,4 +54,5 @@
         self._readCategoryInfo()
         self.model_parameters = None
+        self.lstParams.setAlternatingRowColors(True)
 
         # Poly model displayed in poly list
@@ -68,18 +75,50 @@
         # Generate the category list for display
         category_list = sorted(self.master_category_dict.keys())
-        self.cbCategory.addItem("Choose category...")
+        self.cbCategory.addItem(CATEGORY_DEFAULT)
         self.cbCategory.addItems(category_list)
         self.cbCategory.addItem("Structure Factor")
         self.cbCategory.setCurrentIndex(0)
 
-        # Connect GUI element signals
-        self.cbStructureFactor.currentIndexChanged.connect(self.selectStructureFactor)
-        self.cbCategory.currentIndexChanged.connect(self.selectCategory)
-        self.cbModel.currentIndexChanged.connect(self.selectModel)
-        self.chk2DView.toggled.connect(self.toggle2D)
-        self.chkPolydispersity.toggled.connect(self.togglePoly)
-        self.chkMagnetism.toggled.connect(self.toggleMagnetism)
-
-        # Set initial control enablement
+        # Connect signals to controls
+        self.initializeSignals()
+
+        # Initial control state
+        self.initializeControls()
+
+    @property
+    def data(self):
+        return self._data
+
+    @data.setter
+    def data(self, value):
+        """ data setter """
+        self._data = value
+        self.data_assigned = True
+        # TODO: update ranges, chi2 etc
+
+    def acceptsData(self):
+        """ Tells the caller this widget can accept new dataset """
+        return not self.data_assigned
+
+    def disableModelCombo(self):
+        self.cbModel.setEnabled(False)
+        self.label_3.setEnabled(False)
+
+    def enableModelCombo(self):
+        self.cbModel.setEnabled(True)
+        self.label_3.setEnabled(True)
+
+    def disableStructureCombo(self):
+        self.cbStructureFactor.setEnabled(False)
+        self.label_4.setEnabled(False)
+
+    def enableStructureCombo(self):
+        self.cbStructureFactor.setEnabled(True)
+        self.label_4.setEnabled(True)
+
+    def initializeControls(self):
+        """
+        Set initial control enablement
+        """
         self.cmdFit.setEnabled(False)
         self.cmdPlot.setEnabled(True)
@@ -90,8 +129,7 @@
         self.chkMagnetism.setEnabled(False)
         self.chkMagnetism.setCheckState(False)
-
+        # tabs
         self.tabFitting.setTabEnabled(TAB_POLY, False)
         self.tabFitting.setTabEnabled(TAB_MAGNETISM, False)
-
         # set initial labels
         self.lblMinRangeDef.setText("---")
@@ -99,34 +137,14 @@
         self.lblChi2Value.setText("---")
 
-    @property
-    def data(self):
-        return self._data
-
-    @data.setter
-    def data(self, value):
-        """ data setter """
-        self._data = value
-        self.data_assigned = True
-        # TODO: update ranges, chi2 etc
-
-    def acceptsData(self):
-        """ Tells the caller this widget can accept new dataset """
-        return not self.data_assigned
-
-    def disableModelCombo(self):
-        self.cbModel.setEnabled(False)
-        self.label_3.setEnabled(False)
-
-    def enableModelCombo(self):
-        self.cbModel.setEnabled(True)
-        self.label_3.setEnabled(True)
-
-    def disableStructureCombo(self):
-        self.cbStructureFactor.setEnabled(False)
-        self.label_4.setEnabled(False)
-
-    def enableStructureCombo(self):
-        self.cbStructureFactor.setEnabled(True)
-        self.label_4.setEnabled(True)
+    def initializeSignals(self):
+        """
+        Connect GUI element signals
+        """
+        self.cbStructureFactor.currentIndexChanged.connect(self.selectStructureFactor)
+        self.cbCategory.currentIndexChanged.connect(self.selectCategory)
+        self.cbModel.currentIndexChanged.connect(self.selectModel)
+        self.chk2DView.toggled.connect(self.toggle2D)
+        self.chkPolydispersity.toggled.connect(self.togglePoly)
+        self.chkMagnetism.toggled.connect(self.toggleMagnetism)
 
     def setDefaultStructureCombo(self):
@@ -145,4 +163,12 @@
         """
         category = self.cbCategory.currentText()
+        # Check if the user chose "Choose category entry"
+        if str(category) == CATEGORY_DEFAULT:
+            # if the previous category was not the default, keep it.
+            # Otherwise, just return
+            if self._previous_category_index != 0:
+                self.cbCategory.setCurrentIndex(self._previous_category_index)
+            return
+
         if category == "Structure Factor":
             self.disableModelCombo()
@@ -156,4 +182,5 @@
         self.disableStructureCombo()
 
+        self._previous_category_index = self.cbCategory.currentIndex()
         model_list = self.master_category_dict[str(category)]
         models = []
@@ -235,5 +262,51 @@
             iter_param = iter_params[0].length_control
         return (iter_param, iter_length)
-        
+
+    def addBackgroundToModel(self, model):
+        """
+        Adds background parameter with default values to the model
+        """
+        assert(isinstance(model, QtGui.QStandardItemModel))
+
+        checked_list = ['background', '0.001', '-inf', 'inf', '1/cm']
+        self.addCheckedListToModel(model, checked_list)
+
+    def addScaleToModel(self, model):
+        """
+        Adds scale parameter with default values to the model
+        """
+        assert(isinstance(model, QtGui.QStandardItemModel))
+
+        checked_list = ['scale', '1.0', '0.0', 'inf', '']
+        self.addCheckedListToModel(model, checked_list)
+
+    def addCheckedListToModel(self, model, param_list):
+        assert(isinstance(model, QtGui.QStandardItemModel))
+        item_list = [QtGui.QStandardItem(item) for item in param_list]
+        item_list[0].setCheckable(True)
+        model.appendRow(item_list)
+
+    def addHeadersToModel(self, model):
+        """
+        Adds predefined headers to the model
+        """
+        model.setHeaderData(0, QtCore.Qt.Horizontal, QtCore.QVariant("Parameter"))
+        model.setHeaderData(1, QtCore.Qt.Horizontal, QtCore.QVariant("Value"))
+        model.setHeaderData(2, QtCore.Qt.Horizontal, QtCore.QVariant("Min"))
+        model.setHeaderData(3, QtCore.Qt.Horizontal, QtCore.QVariant("Max"))
+        model.setHeaderData(4, QtCore.Qt.Horizontal, QtCore.QVariant("[Units]"))
+
+    def addPolyHeadersToModel(self, model):
+        """
+        Adds predefined headers to the model
+        """
+        model.setHeaderData(0, QtCore.Qt.Horizontal, QtCore.QVariant("Parameter"))
+        model.setHeaderData(1, QtCore.Qt.Horizontal, QtCore.QVariant("PD[ratio]"))
+        model.setHeaderData(2, QtCore.Qt.Horizontal, QtCore.QVariant("Min"))
+        model.setHeaderData(3, QtCore.Qt.Horizontal, QtCore.QVariant("Max"))
+        model.setHeaderData(4, QtCore.Qt.Horizontal, QtCore.QVariant("Npts"))
+        model.setHeaderData(5, QtCore.Qt.Horizontal, QtCore.QVariant("Nsigs"))
+        model.setHeaderData(6, QtCore.Qt.Horizontal, QtCore.QVariant("Function"))
+
     def setModelModel(self, model_name):
         """
@@ -248,28 +321,28 @@
         self.model_parameters = modelinfo.make_parameter_table(getattr(kernel_module, 'parameters', []))
 
-        #TODO: scaale and background are implicit in sasmodels and needs to be added
-        item1 = QtGui.QStandardItem('scale')
-        item1.setCheckable(True)
-        item2 = QtGui.QStandardItem('1.0')
-        item3 = QtGui.QStandardItem('0.0')
-        item4 = QtGui.QStandardItem('inf')
-        item5 = QtGui.QStandardItem('')
-        self._model_model.appendRow([item1, item2, item3, item4, item5])
-
-        item1 = QtGui.QStandardItem('background')
-        item1.setCheckable(True)
-        item2 = QtGui.QStandardItem('0.001')
-        item3 = QtGui.QStandardItem('-inf')
-        item4 = QtGui.QStandardItem('inf')
-        item5 = QtGui.QStandardItem('1/cm')
-        self._model_model.appendRow([item1, item2, item3, item4, item5])
-
-        multishell_parameters = self.getIterParams(self.model_parameters)
-        multishell_param_name, _ = self.getMultiplicity(self.model_parameters)
+        #TODO: scale and background are implicit in sasmodels and needs to be added
+        self.addScaleToModel(self._model_model)
+        self.addBackgroundToModel(self._model_model)
+
+        self.addParametersToModel(self.model_parameters, self._model_model)
+
+        self.addHeadersToModel(self._model_model)
+
+        self.addExtraShells()
+
+        self.setPolyModel()
+        self.setMagneticModel()
+        self.model_is_loaded = True
+
+    def addParametersToModel(self, parameters, model):
+        """
+        Update local ModelModel with sasmodel parameters
+        """
+        multishell_parameters = self.getIterParams(parameters)
+        multishell_param_name, _ = self.getMultiplicity(parameters)
 
         #TODO: iq_parameters are used here. If orientation paramateres or magnetic are needed
         # kernel_paramters should be used instead
-        #For orientation and magentic parameters param.type needs to be checked
-        for param in self.model_parameters.iq_parameters:
+        for param in parameters.iq_parameters:
             # don't include shell parameters
             if param.name == multishell_param_name:
@@ -279,23 +352,36 @@
             if param in multishell_parameters:
                 item_name = self.replaceShellName(param.name, 1)
+
             item1 = QtGui.QStandardItem(item_name)
             item1.setCheckable(True)
+            # check for polydisp params
+            if param.polydisperse:
+                poly_item = QtGui.QStandardItem("Polydispersity")
+                item1_1 = QtGui.QStandardItem("Distribution")
+                # Find param in volume_params
+                for p in parameters.form_volume_parameters:
+                    if p.name == param.name:
+                        item1_2 = QtGui.QStandardItem(str(p.default))
+                        item1_3 = QtGui.QStandardItem(str(p.limits[0]))
+                        item1_4 = QtGui.QStandardItem(str(p.limits[1]))
+                        item1_5 = QtGui.QStandardItem(p.units)
+                        poly_item.appendRow([item1_1, item1_2, item1_3, item1_4, item1_5])
+                        break
+
+                item1.appendRow([poly_item])
+
             item2 = QtGui.QStandardItem(str(param.default))
             item3 = QtGui.QStandardItem(str(param.limits[0]))
             item4 = QtGui.QStandardItem(str(param.limits[1]))
             item5 = QtGui.QStandardItem(param.units)
-            self._model_model.appendRow([item1, item2, item3, item4, item5])
-
-        self._model_model.setHeaderData(0, QtCore.Qt.Horizontal, QtCore.QVariant("Parameter"))
-        self._model_model.setHeaderData(1, QtCore.Qt.Horizontal, QtCore.QVariant("Value"))
-        self._model_model.setHeaderData(2, QtCore.Qt.Horizontal, QtCore.QVariant("Min"))
-        self._model_model.setHeaderData(3, QtCore.Qt.Horizontal, QtCore.QVariant("Max"))
-        self._model_model.setHeaderData(4, QtCore.Qt.Horizontal, QtCore.QVariant("[Units]"))
-
-        self.addExtraShells()
-
-        self.setPolyModel()
-        self.setMagneticModel()
-        self.model_is_loaded = True
+            model.appendRow([item1, item2, item3, item4, item5])
+
+        self._last_model_row = self._model_model.rowCount()
+
+    def modelToFittingParameters(self):
+        """
+        Prepare the fitting data object, based on current ModelModel
+        """
+        pass
 
     def replaceShellName(self, param_name, value):
@@ -331,30 +417,30 @@
         Set polydispersity values
         """
-        if self.model_parameters:
-            for row, param in enumerate(self.model_parameters.form_volume_parameters):
-                item1 = QtGui.QStandardItem("Distribution of "+param.name)
-                item1.setCheckable(True)
-                item2 = QtGui.QStandardItem("0")
-                item3 = QtGui.QStandardItem("")
-                item4 = QtGui.QStandardItem("")
-                item5 = QtGui.QStandardItem("35")
-                item6 = QtGui.QStandardItem("3")
-                item7 = QtGui.QStandardItem("")
-
-                self._poly_model.appendRow([item1, item2, item3, item4, item5, item6, item7])
-
-                #TODO: Need to find cleaner way to input functions
-                func = QtGui.QComboBox()
-                func.addItems(['rectangle','array','lognormal','gaussian','schulz',])
-                func_index = self.lstPoly.model().index(row,6)
-                self.lstPoly.setIndexWidget(func_index,func)
-
-        self._poly_model.setHeaderData(0, QtCore.Qt.Horizontal, QtCore.QVariant("Parameter"))
-        self._poly_model.setHeaderData(1, QtCore.Qt.Horizontal, QtCore.QVariant("PD[ratio]"))
-        self._poly_model.setHeaderData(2, QtCore.Qt.Horizontal, QtCore.QVariant("Min"))
-        self._poly_model.setHeaderData(3, QtCore.Qt.Horizontal, QtCore.QVariant("Max"))
-        self._poly_model.setHeaderData(4, QtCore.Qt.Horizontal, QtCore.QVariant("Npts"))
-        self._poly_model.setHeaderData(5, QtCore.Qt.Horizontal, QtCore.QVariant("Nsigs"))
-        self._poly_model.setHeaderData(6, QtCore.Qt.Horizontal, QtCore.QVariant("Function"))
+        ### TODO: apply proper proxy model filtering from the main _model_model
+
+        if not self.model_parameters:
+            return
+        self._poly_model.clear()
+        for row, param in enumerate(self.model_parameters.form_volume_parameters):
+            # Counters should not be included
+            if not param.polydisperse:
+                continue
+
+            # Potential multishell params
+            #length_control = param.length_control
+            #if length_control in param.name:
+
+            checked_list = ["Distribution of "+param.name, str(param.default),
+                            str(param.limits[0]),str(param.limits[1]),
+                            "35", "3", ""]
+            self.addCheckedListToModel(self._poly_model, checked_list)
+
+            #TODO: Need to find cleaner way to input functions
+            func = QtGui.QComboBox()
+            func.addItems(['rectangle','array','lognormal','gaussian','schulz',])
+            func_index = self.lstPoly.model().index(row,6)
+            self.lstPoly.setIndexWidget(func_index,func)
+
+        self.addPolyHeadersToModel(self._poly_model)
 
     def setMagneticModel(self):
@@ -362,30 +448,18 @@
         Set magnetism values on model
         """
-        if self.model_parameters:
-            for row, param in enumerate(self.model_parameters.form_volume_parameters):
-                item1 = QtGui.QStandardItem("Distribution of "+param.name)
-                item1.setCheckable(True)
-                item2 = QtGui.QStandardItem("0")
-                item3 = QtGui.QStandardItem("")
-                item4 = QtGui.QStandardItem("")
-                item5 = QtGui.QStandardItem("35")
-                item6 = QtGui.QStandardItem("3")
-                item7 = QtGui.QStandardItem("")
-
-                self._magnet_model.appendRow([item1, item2, item3, item4, item5, item6, item7])
-
-                #TODO: Need to find cleaner way to input functions
-                func = QtGui.QComboBox()
-                func.addItems(['rectangle','array','lognormal','gaussian','schulz',])
-                func_index = self.lstMagnetic.model().index(row,6)
-                self.lstMagnetic.setIndexWidget(func_index,func)
-
-        self._magnet_model.setHeaderData(0, QtCore.Qt.Horizontal, QtCore.QVariant("Parameter"))
-        self._magnet_model.setHeaderData(1, QtCore.Qt.Horizontal, QtCore.QVariant("PD[ratio]"))
-        self._magnet_model.setHeaderData(2, QtCore.Qt.Horizontal, QtCore.QVariant("Min"))
-        self._magnet_model.setHeaderData(3, QtCore.Qt.Horizontal, QtCore.QVariant("Max"))
-        self._magnet_model.setHeaderData(4, QtCore.Qt.Horizontal, QtCore.QVariant("Npts"))
-        self._magnet_model.setHeaderData(5, QtCore.Qt.Horizontal, QtCore.QVariant("Nsigs"))
-        self._magnet_model.setHeaderData(6, QtCore.Qt.Horizontal, QtCore.QVariant("Function"))
+        if not self.model_parameters:
+            return
+        self._magnet_model.clear()
+        for param in self.model_parameters.call_parameters:
+            if param.type != "magnetic":
+                continue
+            checked_list = [param.name,
+                            str(param.default),
+                            str(param.limits[0]),
+                            str(param.limits[1]),
+                            param.units]
+            self.addCheckedListToModel(self._magnet_model, checked_list)
+
+        self.addHeadersToModel(self._magnet_model)
 
     def addExtraShells(self):
@@ -403,4 +477,5 @@
         func = QtGui.QComboBox()
         func.addItems([str(i+1) for i in xrange(param_length)])
+        func.currentIndexChanged.connect(self.modifyShellsInList)
 
         # cell 2: combobox
@@ -412,5 +487,47 @@
         shell_index = self._model_model.index(shell_row-1, 1)
         self.lstParams.setIndexWidget(shell_index, func)
-        self.lstParams.setSpan(shell_row-1,2,2,4)
+
+        self._last_model_row = self._model_model.rowCount()
+
+
+    def modifyShellsInList(self, index):
+        """
+        Add/remove additional multishell parameters
+        """
+        # Find row location of the combobox
+        last_row = self._last_model_row
+        remove_rows = self._model_model.rowCount() - last_row
+
+        if remove_rows > 1:
+            self._model_model.removeRows(last_row, remove_rows)
+
+        multishell_parameters = self.getIterParams(self.model_parameters)
+
+        for i in xrange(index):
+            for par in multishell_parameters:
+                param_name = self.replaceShellName(par.name, i+2)
+                #param_name = str(p.name) + str(i+2)
+                item1 = QtGui.QStandardItem(param_name)
+                item1.setCheckable(True)
+                # check for polydisp params
+                if par.polydisperse:
+                    poly_item = QtGui.QStandardItem("Polydispersity")
+                    item1_1 = QtGui.QStandardItem("Distribution")
+                    # Find param in volume_params
+                    for p in self.model_parameters.form_volume_parameters:
+                        if p.name == par.name:
+                            item1_2 = QtGui.QStandardItem(str(p.default))
+                            item1_3 = QtGui.QStandardItem(str(p.limits[0]))
+                            item1_4 = QtGui.QStandardItem(str(p.limits[1]))
+                            item1_5 = QtGui.QStandardItem(p.units)
+                            poly_item.appendRow([item1_1, item1_2, item1_3, item1_4, item1_5])
+                            break
+                    item1.appendRow([poly_item])
+
+                item2 = QtGui.QStandardItem(str(par.default))
+                item3 = QtGui.QStandardItem(str(par.limits[0]))
+                item4 = QtGui.QStandardItem(str(par.limits[1]))
+                item5 = QtGui.QStandardItem(par.units)
+                self._model_model.appendRow([item1, item2, item3, item4, item5])
 
     def togglePoly(self, isChecked):
Index: src/sas/qtgui/Perspectives/Fitting/UI/FittingWidgetUI.ui
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/UI/FittingWidgetUI.ui	(revision 6f7f65230cc7b516a85452e22a120341bf88858e)
+++ src/sas/qtgui/Perspectives/Fitting/UI/FittingWidgetUI.ui	(revision 86f88d1f01ba28c866b6d45139c207d986c99d1a)
@@ -99,5 +99,5 @@
           </item>
           <item row="1" column="0">
-           <widget class="QTableView" name="lstParams">
+           <widget class="QTreeView" name="lstParams">
             <property name="styleSheet">
              <string notr="true"/>
