Index: src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FittingWidget.py	(revision e90988cd3c71ed989b47df2bed55bcd11e7733ce)
+++ src/sas/qtgui/Perspectives/Fitting/FittingWidget.py	(revision 7fd20fcaad0240e364298e5839ff98bd609bacb4)
@@ -178,4 +178,5 @@
         # Batch/single fitting
         self.is_batch_fitting = False
+        self.is_chain_fitting = False
         # Current SasModel in view
         self.kernel_module = None
@@ -301,5 +302,5 @@
         self.lstParams.setStyleSheet(stylesheet)
         self.lstParams.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
-        self.lstParams.customContextMenuRequested.connect(self.showModelDescription)
+        self.lstParams.customContextMenuRequested.connect(self.showModelContextMenu)
         self.lstParams.setAttribute(QtCore.Qt.WA_MacShowFocusRect, False)
         # Poly model displayed in poly list
@@ -350,4 +351,6 @@
                 self.cbFileNames.addItem(filename)
             self.cbFileNames.setVisible(True)
+            self.chkChainFit.setEnabled(True)
+            self.chkChainFit.setVisible(True)
             # This panel is not designed to view individual fits, so disable plotting
             self.cmdPlot.setVisible(False)
@@ -389,4 +392,8 @@
         """ Enable/disable the magnetism tab """
         self.tabFitting.setTabEnabled(TAB_MAGNETISM, isChecked)
+
+    def toggleChainFit(self, isChecked):
+        """ Enable/disable chain fitting """
+        self.is_chain_fitting = isChecked
 
     def toggle2D(self, isChecked):
@@ -412,4 +419,6 @@
         self.chkMagnetism.setEnabled(False)
         self.chkMagnetism.setCheckState(False)
+        self.chkChainFit.setEnabled(False)
+        self.chkChainFit.setVisible(False)
         # Tabs
         self.tabFitting.setTabEnabled(TAB_POLY, False)
@@ -434,4 +443,5 @@
         self.chkPolydispersity.toggled.connect(self.togglePoly)
         self.chkMagnetism.toggled.connect(self.toggleMagnetism)
+        self.chkChainFit.toggled.connect(self.toggleChainFit)
         # Buttons
         self.cmdFit.clicked.connect(self.onFit)
@@ -448,7 +458,108 @@
         self.options_widget.plot_signal.connect(self.onOptionsUpdate)
 
-    def showModelDescription(self, position):
-        """
-        Shows a window with model description, when right clicked in the treeview
+    def showModelContextMenu(self, position):
+
+        rows = len([s.row() for s in self.lstParams.selectionModel().selectedRows()])
+        menu = self.showModelDescription() if not rows else self.modelContextMenu(rows)
+        try:
+            menu.exec_(self.lstParams.viewport().mapToGlobal(position))
+        except AttributeError as ex:
+            logging.error("Error generating context menu: %s" % ex)
+        return
+
+    def modelContextMenu(self, rows):
+        menu = QtWidgets.QMenu()
+
+        # Select for fitting
+        self.actionSelect = QtWidgets.QAction(self)
+        self.actionSelect.setObjectName("actionSelect")
+        self.actionSelect.setText(QtCore.QCoreApplication.translate("self", "Select parameter for fitting"))
+        # Unselect from fitting
+        self.actionDeselect = QtWidgets.QAction(self)
+        self.actionDeselect.setObjectName("actionDeselect")
+        self.actionDeselect.setText(QtCore.QCoreApplication.translate("self", "De-select parameter from fitting"))
+
+        self.actionConstrain = QtWidgets.QAction(self)
+        self.actionConstrain.setObjectName("actionConstrain")
+        self.actionConstrain.setText(QtCore.QCoreApplication.translate("self", "Constrain parameter to current value"))
+
+        self.actionMultiConstrain = QtWidgets.QAction(self)
+        self.actionMultiConstrain.setObjectName("actionMultiConstrain")
+        self.actionMultiConstrain.setText(QtCore.QCoreApplication.translate("self", "Constrain selected parameters to their current values"))
+
+        self.actionMutualMultiConstrain = QtWidgets.QAction(self)
+        self.actionMutualMultiConstrain.setObjectName("actionMutualMultiConstrain")
+        self.actionMutualMultiConstrain.setText(QtCore.QCoreApplication.translate("self", "Mutual constrain of selected parameters..."))
+
+        #action.setDefaultWidget(label)
+        menu.addAction(self.actionSelect)
+        menu.addAction(self.actionDeselect)
+        menu.addSeparator()
+
+        if rows == 1:
+            menu.addAction(self.actionConstrain)
+        elif rows == 2:
+            menu.addAction(self.actionMultiConstrain)
+            menu.addAction(self.actionMutualMultiConstrain)
+        elif rows > 2:
+            menu.addAction(self.actionMultiConstrain)
+
+        # Define the callbacks
+        self.actionConstrain.triggered.connect(self.addConstraint)
+        self.actionMutualMultiConstrain.triggered.connect(self.showMultiConstrain)
+        self.actionSelect.triggered.connect(self.selectParameters)
+        self.actionDeselect.triggered.connect(self.deselectParameters)
+        return menu
+
+    def showMultiConstrain(self):
+        """
+        Show the constraint widget and receive the expression
+        """
+        from sas.qtgui.Perspectives.Fitting.MultiConstraint import MultiConstraint
+        params_list = [s.data() for s in self.lstParams.selectionModel().selectedRows()]
+        mc_widget = MultiConstraint(self, params=params_list)
+        mc_widget.exec_()
+        constraint = mc_widget.txtConstraint.text()
+        # Pass the constraint to the parser
+        self.communicate.statusBarUpdateSignal.emit('Constraints added')
+        pass
+
+    def addConstraint(self):
+        """
+        Adds a constraint on a single parameter.
+        """
+        self.communicate.statusBarUpdateSignal.emit('Constraint added')
+        pass
+
+    def selectParameters(self):
+        """
+        Selected parameters are chosen for fitting
+        """
+        status = QtCore.Qt.Checked
+        self.setParameterSelection(status)
+
+    def deselectParameters(self):
+        """
+        Selected parameters are removed for fitting
+        """
+        status = QtCore.Qt.Unchecked
+        self.setParameterSelection(status)
+
+    def selectedParameters(self):
+        """ Returns list of selected (highlighted) parameters """
+        return [s.row() for s in self.lstParams.selectionModel().selectedRows() if self.isCheckable(s.row())]
+
+    def setParameterSelection(self, status=QtCore.Qt.Unchecked):
+        """
+        Selected parameters are chosen for fitting
+        """
+        # Convert to proper indices and set requested enablement
+        for row in self.selectedParameters():
+            self._model_model.item(row, 0).setCheckState(status)
+        pass
+
+    def showModelDescription(self):
+        """
+        Creates a window with model description, when right clicked in the treeview
         """
         msg = 'Model description:\n'
@@ -466,5 +577,5 @@
         action.setDefaultWidget(label)
         menu.addAction(action)
-        menu.exec_(self.lstParams.viewport().mapToGlobal(position))
+        return menu
 
     def onSelectModel(self):
@@ -1344,4 +1455,7 @@
         self.updateUndo()
 
+    def isCheckable(self, row):
+        return self._model_model.item(row, 0).isCheckable()
+
     def checkboxSelected(self, item):
         # Assure we're dealing with checkboxes
@@ -1350,14 +1464,10 @@
         status = item.checkState()
 
-        def isCheckable(row):
-            return self._model_model.item(row, 0).isCheckable()
-
         # If multiple rows selected - toggle all of them, filtering uncheckable
-        rows = [s.row() for s in self.lstParams.selectionModel().selectedRows() if isCheckable(s.row())]
-
         # Switch off signaling from the model to avoid recursion
         self._model_model.blockSignals(True)
         # Convert to proper indices and set requested enablement
-        [self._model_model.item(row, 0).setCheckState(status) for row in rows]
+        self.setParameterSelection(status)
+        #[self._model_model.item(row, 0).setCheckState(status) for row in self.selectedParameters()]
         self._model_model.blockSignals(False)
 
Index: src/sas/qtgui/Perspectives/Fitting/MultiConstraint.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/MultiConstraint.py	(revision 7fd20fcaad0240e364298e5839ff98bd609bacb4)
+++ src/sas/qtgui/Perspectives/Fitting/MultiConstraint.py	(revision 7fd20fcaad0240e364298e5839ff98bd609bacb4)
@@ -0,0 +1,55 @@
+"""
+Widget for parameter constraints.
+"""
+from PyQt5 import QtCore
+from PyQt5 import QtGui
+from PyQt5 import QtWidgets
+
+import sas.qtgui.Utilities.GuiUtils as GuiUtils
+
+# Local UI
+from sas.qtgui.Perspectives.Fitting.UI.MultiConstraintUI import Ui_MultiConstraintUI
+
+class MultiConstraint(QtWidgets.QDialog, Ui_MultiConstraintUI):
+    def __init__(self, parent=None, params=None):
+        super(MultiConstraint, self).__init__()
+
+        self.setupUi(self)
+        self.setFixedSize(self.minimumSizeHint())
+        self.setModal(True)
+        self.params = params
+
+        self.setupLabels()
+        self.setupTooltip()
+
+        self.cmdOK.clicked.connect(self.accept)
+        self.cmdRevert.clicked.connect(self.revert)
+
+    def revert(self):
+        """
+        switch M1 <-> M2
+        """
+        self.params[1], self.params[0] = self.params[0], self.params[1]
+        self.setupLabels()
+        self.setupTooltip()
+
+    def setupLabels(self):
+        """
+        Setup labels based on current parameters
+        """
+        l1 = self.params[0]
+        l2 = self.params[1]
+        self.txtParam1.setText(l1)
+        self.txtParam1_2.setText(l1)
+        self.txtParam2.setText(l2)
+
+    def setupTooltip(self):
+        """
+        Tooltip for txtConstraint
+        """
+        tooltip = "E.g.\n%s = 2.0 * (%s)\n" %(self.params[0], self.params[1])
+        tooltip += "%s = sqrt(%s) + 5"%(self.params[0], self.params[1])
+        self.txtConstraint.setToolTip(tooltip)
+
+        pass
+
Index: src/sas/qtgui/Perspectives/Fitting/UI/FittingWidgetUI.ui
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/UI/FittingWidgetUI.ui	(revision d1955d675110f45de94a27bcfb2944496bed625c)
+++ src/sas/qtgui/Perspectives/Fitting/UI/FittingWidgetUI.ui	(revision 7fd20fcaad0240e364298e5839ff98bd609bacb4)
@@ -7,6 +7,6 @@
     <x>0</x>
     <y>0</y>
-    <width>434</width>
-    <height>466</height>
+    <width>448</width>
+    <height>526</height>
    </rect>
   </property>
@@ -26,6 +26,6 @@
    <string>FittingWidget</string>
   </property>
-  <layout class="QGridLayout" name="gridLayout_4">
-   <item row="0" column="0" colspan="4">
+  <layout class="QGridLayout" name="gridLayout_5">
+   <item row="0" column="0">
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
@@ -72,5 +72,5 @@
     </layout>
    </item>
-   <item row="1" column="0" colspan="4">
+   <item row="1" column="0">
     <widget class="QTabWidget" name="tabFitting">
      <property name="currentIndex">
@@ -81,5 +81,5 @@
        <string>Model</string>
       </attribute>
-      <layout class="QGridLayout" name="gridLayout_19">
+      <layout class="QGridLayout" name="gridLayout_4">
        <item row="0" column="0" colspan="4">
         <widget class="QGroupBox" name="groupBox_6">
@@ -161,6 +161,6 @@
           <string>Options </string>
          </property>
-         <layout class="QGridLayout" name="gridLayout_16">
-          <item row="0" column="0">
+         <layout class="QVBoxLayout" name="verticalLayout">
+          <item>
            <widget class="QCheckBox" name="chkPolydispersity">
             <property name="enabled">
@@ -178,5 +178,5 @@
            </widget>
           </item>
-          <item row="1" column="0">
+          <item>
            <widget class="QCheckBox" name="chk2DView">
             <property name="enabled">
@@ -194,5 +194,5 @@
            </widget>
           </item>
-          <item row="2" column="0">
+          <item>
            <widget class="QCheckBox" name="chkMagnetism">
             <property name="enabled">
@@ -204,4 +204,20 @@
             <property name="text">
              <string>Magnetism</string>
+            </property>
+            <property name="checkable">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QCheckBox" name="chkChainFit">
+            <property name="enabled">
+             <bool>true</bool>
+            </property>
+            <property name="toolTip">
+             <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Switch on magnetic scattering parameters.&lt;/p&gt;&lt;p&gt;This option is available only for 2D models.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+            </property>
+            <property name="text">
+             <string>Chain fit</string>
             </property>
             <property name="checkable">
@@ -412,72 +428,76 @@
    </item>
    <item row="2" column="0">
-    <spacer name="horizontalSpacer">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>273</width>
-       <height>20</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item row="2" column="1">
-    <widget class="QPushButton" name="cmdPlot">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="minimumSize">
-      <size>
-       <width>75</width>
-       <height>23</height>
-      </size>
-     </property>
-     <property name="text">
-      <string>Show Plot</string>
-     </property>
-    </widget>
-   </item>
-   <item row="2" column="2">
-    <widget class="QPushButton" name="cmdFit">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="minimumSize">
-      <size>
-       <width>75</width>
-       <height>23</height>
-      </size>
-     </property>
-     <property name="text">
-      <string>Fit</string>
-     </property>
-    </widget>
-   </item>
-   <item row="2" column="3">
-    <widget class="QPushButton" name="cmdHelp">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="minimumSize">
-      <size>
-       <width>75</width>
-       <height>23</height>
-      </size>
-     </property>
-     <property name="text">
-      <string>Help</string>
-     </property>
-    </widget>
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>273</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="cmdPlot">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>75</width>
+         <height>23</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Show Plot</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="cmdFit">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>75</width>
+         <height>23</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Fit</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="cmdHelp">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>75</width>
+         <height>23</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Help</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
    </item>
   </layout>
Index: src/sas/qtgui/Perspectives/Fitting/UI/MultiConstraintUI.ui
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/UI/MultiConstraintUI.ui	(revision 7fd20fcaad0240e364298e5839ff98bd609bacb4)
+++ src/sas/qtgui/Perspectives/Fitting/UI/MultiConstraintUI.ui	(revision 7fd20fcaad0240e364298e5839ff98bd609bacb4)
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MultiConstraintUI</class>
+ <widget class="QDialog" name="MultiConstraintUI">
+  <property name="windowModality">
+   <enum>Qt::WindowModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>335</width>
+    <height>143</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle">
+   <string>2 parameter constraint</string>
+  </property>
+  <property name="modal">
+   <bool>true</bool>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="txtParam1">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;parameter1&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;= function(&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="txtParam2">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;parameter2&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="label_3">
+       <property name="text">
+        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="cmdRevert">
+       <property name="text">
+        <string>Revert</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <item>
+      <widget class="QLabel" name="txtParam1_2">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>parameter1</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>=</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="txtConstraint"/>
+     </item>
+    </layout>
+   </item>
+   <item row="2" column="0">
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>35</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="3" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="cmdOK">
+       <property name="text">
+        <string>OK</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
