From 1a896d01d068fcec167c8511fc70f16f06377640 Mon Sep 17 00:00:00 2001
From: Michael Whitty <michael.whitty@stfc.ac.uk>
Date: Mon, 28 Feb 2011 10:28:56 +0000
Subject: [PATCH] refs #2552 - mantidplot ida interface, allow users to fix
 fitting parameters on "furyfit" tab. partially complete.

---
 .../IndirectDataAnalysis.h                    |  13 +-
 .../src/IndirectDataAnalysis.cpp              | 122 +++++++++++++++---
 2 files changed, 115 insertions(+), 20 deletions(-)

diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDataAnalysis.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDataAnalysis.h
index 4e157a2adee..b6ae0634c24 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDataAnalysis.h
+++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDataAnalysis.h
@@ -39,6 +39,7 @@ class QtProperty;
 class QtBoolPropertyManager;
 class QtDoublePropertyManager;
 class QtGroupPropertyManager;
+class QtStringPropertyManager;
 class QtTreePropertyBrowser;
 //----------------------
 //       End Of
@@ -92,7 +93,7 @@ namespace MantidQt
       void absorptionRun();
 
       Mantid::API::CompositeFunctionMW* furyfitCreateFunction(bool tie=false);
-      Mantid::API::IFitFunction* furyfitCreateUserFunction(const QString & name);
+      Mantid::API::IFitFunction* furyfitCreateUserFunction(const QString & name, bool tie=false);
       Mantid::API::CompositeFunctionMW* confitCreateFunction(bool tie=false);
       QtProperty* createLorentzian(const QString &);
       QtProperty* createExponential(const QString &);
@@ -137,6 +138,10 @@ namespace MantidQt
       void furyfitRangePropChanged(QtProperty*, double);
       void furyfitSequential();
       void furyfitPlotGuess(QtProperty*);
+      // context menu on fitting property browser
+      void furyfitContextMenu(const QPoint &);
+      void ffFixItem();
+      void ffUnFixItem();
 
       // Convolution Fit
       void confitTypeSelection(int index);
@@ -152,6 +157,8 @@ namespace MantidQt
       void confitHwhmChanged(double);
       void confitHwhmUpdateRS(double);
 
+      void confitContextMenu(const QPoint &);
+
       // Absorption (Basic)
       // (nothing for this)
 
@@ -211,6 +218,7 @@ namespace MantidQt
       QtTreePropertyBrowser* m_ffTree; ///< FuryFit Property Browser
       QtGroupPropertyManager* m_groupManager;
       QtDoublePropertyManager* m_ffDblMng;
+      QtBoolPropertyManager* m_ffBlnMng;
       QtDoublePropertyManager* m_ffRangeManager; ///< StartX and EndX for FuryFit
       QMap<QString, QtProperty*> m_ffProp;
       QwtPlot* m_ffPlot;
@@ -223,6 +231,9 @@ namespace MantidQt
       std::string m_ffInputWSName;
       QString m_furyfitTies;
 
+      QtStringPropertyManager* m_stringManager;
+
+
       // Confit (prefix: 'm_cf')
       QtTreePropertyBrowser* m_cfTree;
       QwtPlot* m_cfPlot;
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataAnalysis.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataAnalysis.cpp
index 6c780028e3e..caf16924deb 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataAnalysis.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataAnalysis.cpp
@@ -21,6 +21,7 @@
 
 #include <QLineEdit>
 #include <QFileInfo>
+#include <QMenu>
 
 #include <QDesktopServices>
 #include <QUrl>
@@ -309,9 +310,12 @@ void IndirectDataAnalysis::setupFuryFit()
   m_groupManager = new QtGroupPropertyManager();
   m_ffDblMng = new QtDoublePropertyManager();
   m_ffRangeManager = new QtDoublePropertyManager();
+  m_ffBlnMng = new QtBoolPropertyManager();
+  m_stringManager = new QtStringPropertyManager();
 
   m_ffTree->setFactoryForManager(m_ffDblMng, m_dblEdFac);
   m_ffTree->setFactoryForManager(m_ffRangeManager, m_dblEdFac);
+  m_ffTree->setFactoryForManager(m_ffBlnMng, m_blnEdFac);
 
   m_ffProp["StartX"] = m_ffRangeManager->addProperty("StartX");
   m_ffRangeManager->setDecimals(m_ffProp["StartX"], m_nDec);
@@ -344,6 +348,10 @@ void IndirectDataAnalysis::setupFuryFit()
   connect(m_uiForm.furyfit_pbSeqFit, SIGNAL(clicked()), this, SLOT(furyfitSequential()));
   // apply validators - furyfit
   m_uiForm.furyfit_leSpecNo->setValidator(m_valInt);
+
+  // Set a custom handler for the QTreePropertyBrowser's ContextMenu event
+  m_ffTree->setContextMenuPolicy(Qt::CustomContextMenu);
+  connect(m_ffTree, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(furyfitContextMenu(const QPoint &)));
 }
 
 void IndirectDataAnalysis::setupConFit()
@@ -853,29 +861,13 @@ Mantid::API::CompositeFunctionMW* IndirectDataAnalysis::furyfitCreateFunction(bo
   if ( fitType == 2 ) { fname = "Stretched Exponential"; }
   else { fname = "Exponential 1"; }
 
-  result->addFunction(furyfitCreateUserFunction(fname));
-
-  if ( tie )
-  {
-    result->tie("f1.Intensity", m_ffProp[fname+".Intensity"]->valueText().toStdString());
-    result->tie("f1.Tau", m_ffProp[fname+".Tau"]->valueText().toStdString());
-    if ( fitType == 2 )
-      result->tie("f1.Beta", m_ffProp[fname+".Beta"]->valueText().toStdString());
-  }
+  result->addFunction(furyfitCreateUserFunction(fname, tie));
 
   if ( fitType == 1 || fitType == 3 )
   {
     if ( fitType == 1 ) { fname = "Exponential 2"; }
     else { fname = "Stretched Exponential"; }
-    result->addFunction(furyfitCreateUserFunction(fname));
-
-    if ( tie )
-    {
-      result->tie("f2.Intensity", m_ffProp[fname+".Intensity"]->valueText().toStdString());
-      result->tie("f2.Tau", m_ffProp[fname+".Tau"]->valueText().toStdString());
-      if ( fitType == 3 )
-        result->tie("f2.Beta", m_ffProp[fname+".Beta"]->valueText().toStdString());
-    }
+    result->addFunction(furyfitCreateUserFunction(fname, tie));
   }
 
   // Return CompositeFunction object to caller.
@@ -883,7 +875,7 @@ Mantid::API::CompositeFunctionMW* IndirectDataAnalysis::furyfitCreateFunction(bo
   return result;
 }
 
-Mantid::API::IFitFunction* IndirectDataAnalysis::furyfitCreateUserFunction(const QString & name)
+Mantid::API::IFitFunction* IndirectDataAnalysis::furyfitCreateUserFunction(const QString & name, bool tie)
 {
   Mantid::API::IFitFunction* result = Mantid::API::FunctionFactory::Instance().createFunction("UserFunction");  
   std::string formula;
@@ -895,10 +887,23 @@ Mantid::API::IFitFunction* IndirectDataAnalysis::furyfitCreateUserFunction(const
   result->setAttribute("Formula", att);
 
   result->setParameter("Intensity", m_ffDblMng->value(m_ffProp[name+".Intensity"]));
+
+  if ( tie || ! m_ffProp[name+".Intensity"]->subProperties().isEmpty() )
+  {
+    result->tie("Intensity", m_ffProp[name+".Intensity"]->valueText().toStdString());
+  }
   result->setParameter("Tau", m_ffDblMng->value(m_ffProp[name+".Tau"]));
+  if ( tie || ! m_ffProp[name+".Tau"]->subProperties().isEmpty() )
+  {
+    result->tie("Tau", m_ffProp[name+".Tau"]->valueText().toStdString());
+  }
   if ( name.startsWith("Str") )
   {
     result->setParameter("Beta", m_ffDblMng->value(m_ffProp[name+".Beta"]));
+    if ( tie || ! m_ffProp[name+".Beta"]->subProperties().isEmpty() )
+    {
+      result->tie("Beta", m_ffProp[name+".Beta"]->valueText().toStdString());
+    }
   }
 
   return result;
@@ -1767,6 +1772,80 @@ void IndirectDataAnalysis::furyfitPlotGuess(QtProperty*)
   m_ffPlot->replot();
 }
 
+void IndirectDataAnalysis::furyfitContextMenu(const QPoint &)
+{
+  QtBrowserItem* curItem = m_ffTree->currentItem();
+  if ( ! curItem )
+  {
+    return;
+  }
+
+  // is it a fit property ?  
+  QtProperty* prop = curItem->property();
+  bool isProperty = ( prop->propertyManager() == m_ffDblMng );
+
+  if ( ! isProperty )
+  {
+    return;
+  }
+
+  // is it already fixed?
+  QList<QtProperty*> subProps = prop->subProperties();
+  bool fixed = ! subProps.isEmpty();
+
+  // Create the menu
+  QMenu* menu = new QMenu("FuryFit", m_ffTree);
+  QAction* action;
+
+  if ( ! fixed )
+  {
+    action = new QAction("Fix", this);
+    connect(action, SIGNAL(triggered()), this, SLOT(ffFixItem()));
+  }
+  else
+  {
+    action = new QAction("Remove Fix", this);
+    connect(action, SIGNAL(triggered()), this, SLOT(ffUnFixItem()));
+  }
+
+  menu->addAction(action);
+
+  // Show the menu
+  menu->popup(QCursor::pos());
+}
+
+void IndirectDataAnalysis::ffFixItem()
+{
+  m_uiForm.tabWidget->currentPageIndex();
+
+  // Determine what the property is.
+  QtBrowserItem* item = m_ffTree->currentItem();
+  QtProperty* prop = item->property();
+
+  QtProperty* fixedProp = m_stringManager->addProperty("Fixed:");
+  m_stringManager->setValue(fixedProp, prop->valueText());
+  prop->addSubProperty(fixedProp);
+
+  fixedProp->setEnabled(false);
+  prop->setEnabled(false);
+  
+}
+
+void IndirectDataAnalysis::ffUnFixItem()
+{
+  QtBrowserItem* item = m_ffTree->currentItem();
+  QtProperty* prop = item->property();
+  prop->subProperties().isEmpty();
+  QList<QtProperty*> subProps = prop->subProperties();
+
+  for ( QList<QtProperty*>::iterator it = subProps.begin(); it != subProps.end(); ++it )
+  {
+    if ( (*it)->propertyManager() != m_ffDblMng ) { delete (*it); }
+  }
+
+  prop->setEnabled(true);
+}
+
 void IndirectDataAnalysis::confitRun()
 {
   confitPlotInput();
@@ -2134,6 +2213,11 @@ void IndirectDataAnalysis::confitCheckBoxUpdate(QtProperty* prop, bool checked)
   }
 }
 
+void IndirectDataAnalysis::confitContextMenu(const QPoint &)
+{
+  return;
+}
+
 void IndirectDataAnalysis::absorptionRun()
 {
   if ( ! validateAbsorption() )
-- 
GitLab