Mantid
Loading...
Searching...
No Matches
FunctionTreeView.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
9
16
17#include "MantidKernel/Logger.h"
18
21#include "MantidQtWidgets/Common/QtPropertyBrowser/DoubleDialogEditor.h"
22#include "MantidQtWidgets/Common/QtPropertyBrowser/FilenameDialogEditor.h"
23#include "MantidQtWidgets/Common/QtPropertyBrowser/FormulaDialogEditor.h"
24#include "MantidQtWidgets/Common/QtPropertyBrowser/WorkspaceEditorFactory.h"
27
28#include "MantidQtWidgets/Common/QtPropertyBrowser/CompositeEditorFactory.h"
29#include "MantidQtWidgets/Common/QtPropertyBrowser/DoubleEditorFactory.h"
30#include "MantidQtWidgets/Common/QtPropertyBrowser/qteditorfactory.h"
31#include "MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h"
32#include "MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h"
33
34#include <QApplication>
35#include <QClipboard>
36#include <QFileInfo>
37#include <QGridLayout>
38#include <QHBoxLayout>
39#include <QInputDialog>
40#include <QMenu>
41#include <QMessageBox>
42#include <QMetaMethod>
43#include <QPushButton>
44#include <QSettings>
45#include <QSignalMapper>
46#include <QTreeWidget>
47#include <QVBoxLayout>
48
49#include <algorithm>
50#include <boost/lexical_cast.hpp>
51#include <regex>
52#include <utility>
53
54using namespace Mantid::API;
55
56namespace {
57const char *globalOptionName = "Global";
58Mantid::Kernel::Logger g_log("Function Browser");
59const std::regex PREFIX_REGEX("(^[f][0-9](.*))");
60inline bool variableIsPrefixed(std::string const &name) { return std::regex_match(name, PREFIX_REGEX); }
61
62std::string insertPrefix(std::string const &param) {
63 auto const parameterName = QString::fromStdString(param);
64 return parameterName.left(parameterName.indexOf(".") + 1).toStdString() + "f0." +
65 parameterName.right(parameterName.size() - parameterName.indexOf(".") - 1).toStdString();
66}
67
68std::string addPrefix(std::string const &param) { return "f0." + param; }
69
70std::string removeEmbeddedPrefix(std::string const &param) {
71 if (variableIsPrefixed(param)) {
72 const auto paramSplit = QString::fromStdString(param).split(".");
73 return paramSplit[0].toStdString() + "." + paramSplit[paramSplit.size() - 1].toStdString();
74 } else {
75 return param;
76 }
77}
78
79std::string removePrefix(std::string const &param) {
80 if (variableIsPrefixed(param)) {
81 const auto paramSplit = QString::fromStdString(param).split(".");
82 return paramSplit[paramSplit.size() - 1].toStdString();
83 } else {
84 return param;
85 }
86}
87
88bool containsOneOf(std::string const &str, std::string const &delimiters) {
89 return !str.empty() && str.find_first_of(delimiters) != std::string::npos;
90}
91
92// These attributes require the function to be fully reconstructed, as a
93// different number of properties will be required
94const std::vector<std::string> REQUIRESRECONSTRUCTIONATTRIBUTES = {"n", "Formula", "Workspace"};
95} // namespace
96
98
106FunctionTreeView::FunctionTreeView(QWidget *parent, bool multi, std::vector<std::string> categories)
107 : IFunctionView(parent), m_multiDataset(multi), m_multiDomainFunctionPrefix(),
108 m_allowedCategories(std::move(categories)), m_selectFunctionDialog(nullptr)
109
110{
111 // create m_browser
114
115 QVBoxLayout *layout = new QVBoxLayout(this);
116 layout->setContentsMargins(0, 0, 0, 0);
117 layout->addWidget(m_browser);
118}
119
124 m_browser->unsetFactoryForManager(m_parameterManager);
125 m_browser->unsetFactoryForManager(m_attributeStringManager);
126 m_browser->unsetFactoryForManager(m_attributeDoubleManager);
127 m_browser->unsetFactoryForManager(m_attributeIntManager);
128 m_browser->unsetFactoryForManager(m_attributeBoolManager);
129 m_browser->unsetFactoryForManager(m_indexManager);
130 m_browser->unsetFactoryForManager(m_tieManager);
131 m_browser->unsetFactoryForManager(m_constraintManager);
132 m_browser->unsetFactoryForManager(m_filenameManager);
133 m_browser->unsetFactoryForManager(m_formulaManager);
134 m_browser->unsetFactoryForManager(m_workspaceManager);
135 m_browser->unsetFactoryForManager(m_attributeSizeManager);
136 m_browser->unsetFactoryForManager(m_attributeVectorDoubleManager);
137}
138
143 QStringList options;
144 if (m_multiDataset) {
145 options << globalOptionName;
146 }
147 m_browser = new QtTreePropertyBrowser(this, options);
148
149 /* Create property managers: they create, own properties, get and set values
150 */
151 m_functionManager = new QtGroupPropertyManager(this);
152 m_parameterManager = new ParameterPropertyManager(this);
153 m_attributeStringManager = new QtStringPropertyManager(this);
154 m_attributeDoubleManager = new QtDoublePropertyManager(this);
155 m_attributeIntManager = new QtIntPropertyManager(this);
156 m_attributeBoolManager = new QtBoolPropertyManager(this);
157 m_indexManager = new QtStringPropertyManager(this);
158 m_tieManager = new QtStringPropertyManager(this);
159 m_constraintManager = new QtDoublePropertyManager(this);
160 m_filenameManager = new QtStringPropertyManager(this);
161 m_formulaManager = new QtStringPropertyManager(this);
162 m_workspaceManager = new QtStringPropertyManager(this);
163 m_attributeVectorManager = new QtGroupPropertyManager(this);
164 m_attributeSizeManager = new QtIntPropertyManager(this);
165 m_attributeVectorDoubleManager = new QtDoublePropertyManager(this);
166
167 // create editor factories
168 QtSpinBoxFactory *spinBoxFactory = new QtSpinBoxFactory(this);
169 DoubleEditorFactory *dblEditorFactory = new DoubleEditorFactory(this);
170 ParameterEditorFactory *paramEditorFactory = new ParameterEditorFactory(this);
171
172 QtAbstractEditorFactory<ParameterPropertyManager> *parameterEditorFactory(nullptr);
173 if (m_multiDataset) {
174 m_doubleEditorFactory = new DoubleDialogEditorFactory(this);
175 auto compositeFactory = new CompositeEditorFactory<ParameterPropertyManager>(this, m_doubleEditorFactory);
176 compositeFactory->setSecondaryFactory(globalOptionName, paramEditorFactory);
177 parameterEditorFactory = compositeFactory;
178 connect(m_doubleEditorFactory, SIGNAL(buttonClicked(QtProperty *)), this,
179 SLOT(parameterButtonClicked(QtProperty *)));
180 connect(m_doubleEditorFactory, SIGNAL(closeEditor()), m_browser, SLOT(closeEditor()));
181 } else {
182 parameterEditorFactory = paramEditorFactory;
183 }
184
185 QtLineEditFactory *lineEditFactory = new QtLineEditFactory(this);
186 QtCheckBoxFactory *checkBoxFactory = new QtCheckBoxFactory(this);
187 FilenameDialogEditorFactory *filenameDialogEditorFactory = new FilenameDialogEditorFactory(this);
188 FormulaDialogEditorFactory *formulaDialogEditFactory = new FormulaDialogEditorFactory(this);
189 WorkspaceEditorFactory *workspaceEditorFactory = new WorkspaceEditorFactory(this);
190
191 // assign factories to property managers
192 m_browser->setFactoryForManager(m_parameterManager, parameterEditorFactory);
193 m_browser->setFactoryForManager(m_attributeStringManager, lineEditFactory);
194 m_browser->setFactoryForManager(m_attributeDoubleManager, dblEditorFactory);
195 m_browser->setFactoryForManager(m_attributeIntManager, spinBoxFactory);
196 m_browser->setFactoryForManager(m_attributeBoolManager, checkBoxFactory);
197 m_browser->setFactoryForManager(m_indexManager, lineEditFactory);
198 m_browser->setFactoryForManager(m_tieManager, lineEditFactory);
199 m_browser->setFactoryForManager(m_constraintManager, dblEditorFactory);
200 m_browser->setFactoryForManager(m_filenameManager, filenameDialogEditorFactory);
201 m_browser->setFactoryForManager(m_formulaManager, formulaDialogEditFactory);
202 m_browser->setFactoryForManager(m_workspaceManager, workspaceEditorFactory);
203 m_browser->setFactoryForManager(m_attributeSizeManager, spinBoxFactory);
204 m_browser->setFactoryForManager(m_attributeVectorDoubleManager, dblEditorFactory);
205
206 m_browser->setContextMenuPolicy(Qt::CustomContextMenu);
207 connect(m_browser, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(popupMenu(const QPoint &)));
208 connect(m_browser, SIGNAL(optionChanged(QtProperty *, const QString &, bool)), this,
209 SLOT(globalChanged(QtProperty *, const QString &, bool)));
210
211 connect(m_attributeStringManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
212 connect(m_attributeDoubleManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
213 connect(m_attributeIntManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
214 connect(m_attributeBoolManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
215 connect(m_formulaManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
216 connect(m_filenameManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
217 connect(m_workspaceManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
218 connect(m_attributeVectorDoubleManager, SIGNAL(propertyChanged(QtProperty *)), this,
219 SLOT(attributeVectorDoubleChanged(QtProperty *)));
220 connect(m_attributeSizeManager, SIGNAL(propertyChanged(QtProperty *)), this,
221 SLOT(attributeVectorSizeChanged(QtProperty *)));
222 connect(m_tieManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(tieChanged(QtProperty *)));
223 connect(m_constraintManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(constraintChanged(QtProperty *)));
224 connect(m_parameterManager, SIGNAL(valueChanged(QtProperty *, double)), SLOT(parameterPropertyChanged(QtProperty *)));
225
226 connect(m_browser, SIGNAL(currentItemChanged(QtBrowserItem *)), SLOT(updateCurrentFunctionIndex()));
227
228 m_browser->setFocusPolicy(Qt::StrongFocus);
229}
230
235 m_actionAddFunction = new QAction("Add function", this);
236 m_actionAddFunction->setObjectName("add_function");
237 connect(m_actionAddFunction, SIGNAL(triggered()), this, SLOT(addFunctionBegin()));
238
239 m_actionRemoveFunction = new QAction("Remove function", this);
240 m_actionRemoveFunction->setObjectName("remove_function");
241 connect(m_actionRemoveFunction, SIGNAL(triggered()), this, SLOT(removeFunction()));
242
243 m_actionFixParameter = new QAction("Fix", this);
244 connect(m_actionFixParameter, SIGNAL(triggered()), this, SLOT(fixParameter()));
245
246 m_actionRemoveTie = new QAction("Remove tie", this);
247 connect(m_actionRemoveTie, SIGNAL(triggered()), this, SLOT(removeTie()));
248
249 m_actionAddTie = new QAction("Add tie", this);
250 connect(m_actionAddTie, SIGNAL(triggered()), this, SLOT(addTie()));
251
252 m_actionFromClipboard = new QAction("Paste from clipboard", this);
253 m_actionFromClipboard->setObjectName("paste_from_clipboard");
254 connect(m_actionFromClipboard, SIGNAL(triggered()), this, SLOT(pasteFromClipboard()));
255
256 m_actionToClipboard = new QAction("Copy to clipboard", this);
257 m_actionToClipboard->setObjectName("copy_to_clipboard");
258 connect(m_actionToClipboard, SIGNAL(triggered()), this, SLOT(copyToClipboard()));
259
260 m_actionConstraints = new QAction("Custom", this);
261 connect(m_actionConstraints, SIGNAL(triggered()), this, SLOT(addConstraints()));
262
263 m_actionConstraints10 = new QAction("10%", this);
264 connect(m_actionConstraints10, SIGNAL(triggered()), this, SLOT(addConstraints10()));
265
266 m_actionConstraints50 = new QAction("50%", this);
267 connect(m_actionConstraints50, SIGNAL(triggered()), this, SLOT(addConstraints50()));
268
269 m_actionRemoveConstraints = new QAction("Remove constraints", this);
270 connect(m_actionRemoveConstraints, SIGNAL(triggered()), this, SLOT(removeConstraints()));
271
272 m_actionRemoveConstraint = new QAction("Remove", this);
273 connect(m_actionRemoveConstraint, SIGNAL(triggered()), this, SLOT(removeConstraint()));
274
275 m_actionFunctionHelp = new QAction("Help", this);
276 connect(m_actionFunctionHelp, SIGNAL(triggered()), this, SIGNAL(functionHelpRequest()));
277
278 setErrorsEnabled(false);
279}
280
285 m_browser->clear();
286 m_properties.clear();
287}
288
294 clear();
295 if (fun) {
296 addFunction(nullptr, fun);
297 }
298}
299
305FunctionTreeView::AProperty FunctionTreeView::addProperty(QtProperty *parent, QtProperty *subproperty) {
306 AProperty ap;
307 ap.prop = subproperty;
308 if (parent == nullptr) {
309 ap.item = m_browser->addProperty(subproperty);
310 } else {
311 parent->addSubProperty(subproperty);
312 auto items = m_browser->items(subproperty);
313 if (items.isEmpty()) {
314 throw std::runtime_error("Unexpected error in FunctionTreeView [1]");
315 }
316 ap.item = items[0];
317 }
318 ap.parent = parent;
319 m_properties[subproperty] = ap;
320 return ap;
321}
322
327void FunctionTreeView::removeProperty(QtProperty *prop) {
328 auto p = m_properties.find(prop);
329 if (p == m_properties.end())
330 return;
331 AProperty ap = *p;
332
333 // remove references to the children
334 auto children = prop->subProperties();
335 foreach (QtProperty *child, children) {
336 removeProperty(child);
337 }
338 m_properties.erase(p);
339
340 if (isFunction(prop)) {
341 m_ties.remove(prop);
342 }
343
344 if (isTie(prop)) { //
345 for (auto it = m_ties.begin(); it != m_ties.end(); ++it) {
346 if (it.value().tieProp == prop) {
347 m_ties.erase(it);
348 break;
349 }
350 }
351 }
352
353 if (isConstraint(prop)) {
354 for (auto it = m_constraints.begin(); it != m_constraints.end(); ++it) {
355 auto &cp = it.value();
356 if (cp.lower == prop) {
357 if (!cp.upper) {
358 m_constraints.erase(it);
359 } else {
360 cp.lower = nullptr;
361 }
362 break;
363 } else if (cp.upper == prop) {
364 if (!cp.lower) {
365 m_constraints.erase(it);
366 } else {
367 cp.upper = nullptr;
368 }
369 break;
370 }
371 }
372 }
373
374 // remove property from Qt browser
375 if (ap.parent) {
376 ap.parent->removeSubProperty(prop);
377 } else {
378 m_browser->removeProperty(prop);
379 }
380 delete prop;
381}
382
389FunctionTreeView::AProperty FunctionTreeView::addFunctionProperty(QtProperty *parent, std::string const &funName) {
390 // check that parent is a function property
391 if (parent && dynamic_cast<QtAbstractPropertyManager *>(m_functionManager) != parent->propertyManager()) {
392 throw std::runtime_error("Unexpected error in FunctionTreeView [2]");
393 }
394 QtProperty *prop = m_functionManager->addProperty(QString::fromStdString(funName));
395 return addProperty(parent, prop);
396}
397
405FunctionTreeView::AProperty FunctionTreeView::addParameterProperty(QtProperty *parent, std::string const &parameterName,
406 std::string const &paramDesc, double paramValue) {
407 // check that parent is a function property
408 if (!parent || dynamic_cast<QtAbstractPropertyManager *>(m_functionManager) != parent->propertyManager()) {
409 throw std::runtime_error("Unexpected error in FunctionTreeView [3]");
410 }
411 QtProperty *prop = m_parameterManager->addProperty(QString::fromStdString(parameterName));
412 m_parameterManager->blockSignals(true);
413 m_parameterManager->setDecimals(prop, 6);
414 m_parameterManager->setValue(prop, paramValue);
415 m_parameterManager->setDescription(prop, paramDesc);
416 m_parameterManager->blockSignals(false);
417
418 if (m_multiDataset) {
419 prop->setOption(globalOptionName, false);
420 }
421 return addProperty(parent, prop);
422}
423
430 auto children = prop->subProperties();
431 foreach (QtProperty *child, children) {
432 removeProperty(child);
433 }
434 // m_localParameterValues.clear();
435 if (!m_multiDomainFunctionPrefix.empty())
438}
439
446 if (!fun)
447 return false;
448 if (!prop) {
449 AProperty ap = addFunctionProperty(nullptr, fun->name());
450 setFunction(ap.prop, fun);
451 } else {
453 if (!parentFun)
454 return false;
455 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(parentFun);
456 if (!cf) {
457 throw std::logic_error("FunctionTreeView: CompositeFunction is expected for addFunction");
458 }
459 try {
460 cf->addFunction(fun);
461 } catch (const std::exception &e) {
462 QMessageBox::warning(this, "Mantid - Warning", QString("Cannot Add function:\n\n%1").arg(e.what()));
463 return false;
464 }
465 setFunction(prop, cf);
466 }
468 return true;
469}
470
476 : public Mantid::API::IFunction::ConstAttributeVisitor<FunctionTreeView::AProperty> {
477public:
478 CreateAttributePropertyForFunctionTreeView(FunctionTreeView *browser, QtProperty *parent, std::string const &attName)
479 : m_browser(browser), m_parent(parent), m_attName(QString::fromStdString(attName)) {
480 // check that parent is a function property
481 if (!m_parent ||
482 dynamic_cast<QtAbstractPropertyManager *>(m_browser->m_functionManager) != m_parent->propertyManager()) {
483 throw std::runtime_error("Unexpected error in FunctionTreeView [4]");
484 }
485 }
486
487protected:
489 FunctionTreeView::AProperty apply(const std::string &str) const override {
490 QtProperty *prop = nullptr;
491 if (m_attName.indexOf("FileName") != -1) {
492 m_browser->m_filenameManager->blockSignals(true);
493 prop = m_browser->m_filenameManager->addProperty(m_attName);
494 m_browser->m_filenameManager->setValue(prop, QString::fromStdString(str));
495 m_browser->m_filenameManager->blockSignals(false);
496 } else if (m_attName.indexOf("Formula") != -1) {
497 m_browser->m_formulaManager->blockSignals(true);
498 prop = m_browser->m_formulaManager->addProperty(m_attName);
499 m_browser->m_formulaManager->setValue(prop, QString::fromStdString(str));
500 m_browser->m_formulaManager->blockSignals(false);
501 } else if (m_attName.indexOf("Workspace") != -1) {
502 m_browser->m_workspaceManager->blockSignals(true);
503 prop = m_browser->m_workspaceManager->addProperty(m_attName);
504 m_browser->m_workspaceManager->setValue(prop, QString::fromStdString(str));
505 m_browser->m_workspaceManager->blockSignals(false);
506 } else {
507 m_browser->m_attributeStringManager->blockSignals(true);
508 prop = m_browser->m_attributeStringManager->addProperty(m_attName);
509 m_browser->m_attributeStringManager->setValue(prop, QString::fromStdString(str));
510 m_browser->m_attributeStringManager->blockSignals(false);
511 }
512 return m_browser->addProperty(m_parent, prop);
513 }
515 FunctionTreeView::AProperty apply(const double &d) const override {
516 m_browser->m_attributeDoubleManager->blockSignals(true);
517 QtProperty *prop = m_browser->m_attributeDoubleManager->addProperty(m_attName);
518 m_browser->m_attributeDoubleManager->setValue(prop, d);
519 m_browser->m_attributeDoubleManager->blockSignals(false);
520 return m_browser->addProperty(m_parent, prop);
521 }
523 FunctionTreeView::AProperty apply(const int &i) const override {
524 m_browser->m_attributeIntManager->blockSignals(true);
525 QtProperty *prop = m_browser->m_attributeIntManager->addProperty(m_attName);
526 prop->setEnabled(i < std::numeric_limits<int>::max());
527 m_browser->m_attributeIntManager->setValue(prop, i);
528 m_browser->m_attributeIntManager->blockSignals(false);
529 return m_browser->addProperty(m_parent, prop);
530 }
532 FunctionTreeView::AProperty apply(const bool &b) const override {
533 m_browser->m_attributeBoolManager->blockSignals(true);
534 QtProperty *prop = m_browser->m_attributeBoolManager->addProperty(m_attName);
535 m_browser->m_attributeBoolManager->setValue(prop, b);
536 m_browser->m_attributeBoolManager->blockSignals(false);
537 return m_browser->addProperty(m_parent, prop);
538 }
540 FunctionTreeView::AProperty apply(const std::vector<double> &v) const override {
541 QtProperty *prop = m_browser->m_attributeVectorManager->addProperty(m_attName);
543
544 m_browser->m_attributeSizeManager->blockSignals(true);
545 QtProperty *sizeProp = m_browser->m_attributeSizeManager->addProperty("Size");
546 m_browser->m_attributeSizeManager->setValue(sizeProp, static_cast<int>(v.size()));
547 m_browser->addProperty(prop, sizeProp);
548 m_browser->m_attributeSizeManager->blockSignals(false);
549
550 m_browser->m_attributeVectorDoubleManager->blockSignals(true);
551 QString parName = "value[%1]";
552 for (size_t i = 0; i < v.size(); ++i) {
553 QtProperty *dprop = m_browser->m_attributeVectorDoubleManager->addProperty(parName.arg(i));
554 m_browser->m_attributeVectorDoubleManager->setValue(dprop, v[i]);
555 m_browser->addProperty(prop, dprop);
556 }
557 m_browser->m_attributeVectorDoubleManager->blockSignals(false);
558
559 sizeProp->setEnabled(false);
560 m_browser->m_browser->setExpanded(aprop.item, false);
561 return aprop;
562 }
563
564private:
566 QtProperty *m_parent;
567 QString m_attName;
568};
569
576public:
577 SetAttributeFromProperty(FunctionTreeView *browser, QtProperty *prop) : m_browser(browser), m_prop(prop) {}
578
579protected:
581 void apply(std::string &str) const override {
582 QString attName = m_prop->propertyName();
583 if (attName == "FileName") {
584 str = m_browser->m_filenameManager->value(m_prop).toStdString();
585 } else if (attName == "Formula") {
586 str = m_browser->m_formulaManager->value(m_prop).toStdString();
587 } else if (attName == "Workspace") {
588 str = m_browser->m_workspaceManager->value(m_prop).toStdString();
589 } else {
590 str = m_browser->m_attributeStringManager->value(m_prop).toStdString();
591 }
592 }
594 void apply(double &d) const override { d = m_browser->m_attributeDoubleManager->value(m_prop); }
596 void apply(int &i) const override { i = m_browser->m_attributeIntManager->value(m_prop); }
598 void apply(bool &b) const override { b = m_browser->m_attributeBoolManager->value(m_prop); }
600 void apply(std::vector<double> &v) const override {
601 QList<QtProperty *> members = m_prop->subProperties();
602 if (members.empty())
603 throw std::runtime_error("FunctionTreeView: empty vector attribute group.");
604 int n = members.size() - 1;
605 if (n == 0) {
606 v.clear();
607 return;
608 }
609 v.resize(n);
610 for (int i = 0; i < n; ++i) {
611 v[i] = m_browser->m_attributeVectorDoubleManager->value(members[i + 1]);
612 }
613 }
614
615private:
617 QtProperty *m_prop;
618};
619
626FunctionTreeView::AProperty FunctionTreeView::addAttributeProperty(QtProperty *parent, std::string const &attName,
628 CreateAttributePropertyForFunctionTreeView cap(this, parent, attName);
629 return att.apply(cap);
630}
631
643 const CompositeFunction_sptr &parentComposite,
644 const std::size_t &parentIndex) {
645 // add the function index property
646 addIndexProperty(prop);
647
648 // add attribute properties
649 auto attributeNames = fun->getAttributeNames();
650 for (const auto &att : attributeNames) {
651 if (!variableIsPrefixed(att)) {
652 addAttributeProperty(prop, att, fun->getAttribute(att));
653 }
654 }
655
656 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
657 if (cf) {
658 // if composite add members
659 for (size_t i = 0; i < cf->nFunctions(); ++i) {
660 AProperty ap = addFunctionProperty(prop, cf->getFunction(i)->name());
661 addAttributeAndParameterProperties(ap.prop, cf->getFunction(i), cf, i);
662 }
663 } else { // if simple add parameters
664 for (size_t i = 0; i < fun->nParams(); ++i) {
665 auto name = fun->parameterName(i);
666 auto desc = fun->parameterDescription(i);
667 double value = fun->getParameter(i);
668 AProperty ap = addParameterProperty(prop, name, desc, value);
669 // if parameter has a tie
670 if (!fun->isActive(i))
671 addParameterTie(ap.prop, fun, name, i, parentComposite, parentIndex);
672 else
673 addGlobalParameterTie(ap.prop, name, parentComposite, parentIndex);
674
675 if (const auto constraint = fun->getConstraint(i)) {
676 addConstraintProperties(ap.prop, constraint->asString());
677 }
678 }
679 }
680}
681
693void FunctionTreeView::addParameterTie(QtProperty *property, const IFunction_sptr &function,
694 const std::string &parameterName, const std::size_t &parameterIndex,
695 const CompositeFunction_sptr &parentComposite, const std::size_t &parentIndex) {
696 if (const auto tie = function->getTie(parameterIndex)) {
697 addTieProperty(property, tie->asString());
698 } else {
699 auto tieAdded = false;
700 if (parentComposite)
701 tieAdded = addParameterTieInComposite(property, parameterName, parentComposite, parentIndex);
702
703 if (!tieAdded)
704 addTieProperty(property, QString::number(function->getParameter(parameterIndex)).toStdString());
705 }
706}
707
717bool FunctionTreeView::addParameterTieInComposite(QtProperty *property, const std::string &parameterName,
718 const CompositeFunction_sptr &composite, const std::size_t &index) {
719 for (auto i = 0u; i < composite->nParams(); ++i) {
720 const auto fullName = "f" + std::to_string(index) + "." + parameterName;
721 if (fullName == composite->parameterName(i)) {
722 if (const auto tie = composite->getTie(i)) {
723 const auto tieStr = QString::fromStdString(tie->asString());
724 addTieProperty(property, tieStr.mid(tieStr.indexOf('=') + 1).toStdString());
725 return true;
726 }
727 return false;
728 }
729 }
730 return false;
731}
732
742void FunctionTreeView::addGlobalParameterTie(QtProperty *property, const std::string &parameterName,
743 const CompositeFunction_sptr &parentComposite,
744 const std::size_t &parentIndex) {
745 if (m_multiDomainFunctionPrefix.empty() || m_globalTies.empty())
746 return;
747
748 auto const fullName = getFullParameterName(parameterName, parentComposite ? static_cast<int>(parentIndex) : -1);
749
750 const auto it = std::find_if(m_globalTies.cbegin(), m_globalTies.cend(),
751 [&fullName](const auto &globalTie) { return fullName == globalTie.m_parameter; });
752 if (it != m_globalTies.cend())
753 addTieProperty(property, (*it).m_tie, true);
754}
755
763 QtProperty *indexProperty = m_indexManager->addProperty("Index");
764 indexProperty->setEnabled(false);
765 m_indexManager->setValue(indexProperty, QString::fromStdString(m_multiDomainFunctionPrefix));
766 (void)addProperty(prop, indexProperty);
767}
768
777 AProperty ap;
778 ap.item = nullptr;
779 ap.parent = nullptr;
780 ap.prop = nullptr;
781 if (!prop)
782 return ap;
783 if (!isFunction(prop))
784 return ap;
785 if (!m_properties[prop].parent)
786 return ap;
787
788 QString index = "fff";
789 QtProperty *ip = m_indexManager->addProperty("Index");
790 ip->setEnabled(false);
791 m_indexManager->setValue(ip, index);
792 auto retval = addProperty(prop, ip);
794 return retval;
795}
796
802void FunctionTreeView::updateFunctionIndices(QtProperty *prop, std::string const &index) {
803 if (prop == nullptr) {
804 auto top = m_browser->properties();
805 if (top.isEmpty())
806 return;
807 prop = top[0];
808 }
809 auto children = prop->subProperties();
810 size_t i = 0;
811 foreach (QtProperty *child, children) {
812 if (isFunction(child)) {
813 updateFunctionIndices(child, index + "f" + std::to_string(i) + ".");
814 ++i;
815 } else if (isIndex(child)) {
816 m_indexManager->setValue(child, QString::fromStdString(m_multiDomainFunctionPrefix + index));
817 }
818 }
819}
820
825 auto props = m_browser->properties();
826 if (props.isEmpty()) {
827 AProperty ap;
828 ap.item = nullptr;
829 ap.parent = nullptr;
830 ap.prop = nullptr;
831 return ap;
832 }
833 QtProperty *prop = props[0];
834 return m_properties[prop];
835}
836
841bool FunctionTreeView::isFunction(QtProperty *prop) const {
842 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_functionManager) == prop->propertyManager();
843}
844
849bool FunctionTreeView::isStringAttribute(QtProperty *prop) const {
850 return prop && (dynamic_cast<QtAbstractPropertyManager *>(m_attributeStringManager) == prop->propertyManager() ||
851 dynamic_cast<QtAbstractPropertyManager *>(m_formulaManager) == prop->propertyManager() ||
852 dynamic_cast<QtAbstractPropertyManager *>(m_filenameManager) == prop->propertyManager() ||
853 dynamic_cast<QtAbstractPropertyManager *>(m_workspaceManager) == prop->propertyManager());
854}
855
860bool FunctionTreeView::isDoubleAttribute(QtProperty *prop) const {
861 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_attributeDoubleManager) == prop->propertyManager();
862}
863
868bool FunctionTreeView::isIntAttribute(QtProperty *prop) const {
869 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_attributeIntManager) == prop->propertyManager();
870}
871
876bool FunctionTreeView::isBoolAttribute(QtProperty *prop) const {
877 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_attributeBoolManager) == prop->propertyManager();
878}
879
884bool FunctionTreeView::isVectorAttribute(QtProperty *prop) const {
885 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_attributeVectorManager) == prop->propertyManager();
886}
887
892bool FunctionTreeView::isAttribute(QtProperty *prop) const {
893 return isStringAttribute(prop) || isDoubleAttribute(prop) || isIntAttribute(prop) || isBoolAttribute(prop) ||
894 isVectorAttribute(prop);
895}
896
901bool FunctionTreeView::isParameter(QtProperty *prop) const {
902 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_parameterManager) == prop->propertyManager();
903}
904
909double FunctionTreeView::getParameter(QtProperty *prop) const { return m_parameterManager->value(prop); }
914bool FunctionTreeView::isIndex(QtProperty *prop) const {
915 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_indexManager) == prop->propertyManager();
916}
917
922std::string FunctionTreeView::getIndex(QtProperty *prop) const {
923 if (!prop)
924 return "";
925 if (isFunction(prop)) {
926 auto props = prop->subProperties();
927 if (props.isEmpty())
928 return "";
929 const auto it = std::find_if(props.cbegin(), props.cend(), [&](const auto &prop) { return isIndex(prop); });
930 if (it != props.cend()) {
931 return m_indexManager->value(*it).toStdString();
932 }
933 return "";
934 }
935
936 auto ap = m_properties[prop];
937 return getIndex(ap.parent);
938}
939
944std::string FunctionTreeView::getParameterName(QtProperty *prop) const {
945 if (isParameter(prop)) {
946 return getIndex(prop) + prop->propertyName().toStdString();
947 } else {
948 auto const *parent = getParentParameterProperty(prop);
949 return getIndex(prop) + parent->propertyName().toStdString();
950 }
951}
956std::string FunctionTreeView::getAttributeName(QtProperty *prop) const {
957 if (isAttribute(prop)) {
958 return getIndex(prop) + prop->propertyName().toStdString();
959 }
960 throw std::logic_error("QtProperty " + prop->propertyName().toStdString() + " is not an attribute property.");
961}
962
969QtProperty *FunctionTreeView::getFunctionProperty(std::string const &index) const {
970 const auto &keys = m_properties.keys();
971 const auto it = std::find_if(keys.cbegin(), keys.cend(), [&](const auto &property) {
972 return isFunction(property) && getIndex(property) == index;
973 });
974 if (it != keys.cend())
975 return *it;
976 // No function with such index
977 return nullptr;
978}
979
986void FunctionTreeView::addTieProperty(QtProperty *prop, std::string const &tie, bool globalTie) {
987 if (!prop) {
988 throw std::runtime_error("FunctionTreeView: null property pointer");
989 }
990
991 if (!isParameter(prop))
992 return;
993
994 QtProperty *funProp = getFunctionProperty().prop;
995
996 // Create and add a QtProperty for the tie.
997 m_tieManager->blockSignals(true);
998 QtProperty *tieProp = m_tieManager->addProperty("Tie");
999 m_tieManager->setValue(tieProp, QString::fromStdString(globalTie ? tie : getFullTie(tie)));
1000 addProperty(prop, tieProp);
1001 m_tieManager->blockSignals(false);
1002
1003 const auto parName = getParameterName(prop);
1004 // Store tie information for easier access
1005 ATie atie;
1006 atie.paramProp = prop;
1007 atie.paramName = parName;
1008 atie.tieProp = tieProp;
1009 m_ties.insert(funProp, atie);
1010}
1011
1018std::string FunctionTreeView::getFullTie(std::string const &tie) const {
1019 if (!isNumber(tie) && !containsOneOf(tie, "="))
1020 return m_multiDomainFunctionPrefix + tie;
1021 return tie;
1022}
1023
1033std::string FunctionTreeView::getFullParameterName(const std::string &parameter, int compositeIndex) const {
1034 auto fullParameterName = m_multiDomainFunctionPrefix;
1035 if (compositeIndex != -1)
1036 fullParameterName += "f" + std::to_string(compositeIndex) + ".";
1037 fullParameterName += parameter;
1038 return fullParameterName;
1039}
1040
1045bool FunctionTreeView::hasTie(QtProperty *prop) const {
1046 if (!prop)
1047 return false;
1048 const auto children = prop->subProperties();
1049 return std::any_of(children.cbegin(), children.cend(),
1050 [](const auto child) { return child->propertyName() == "Tie"; });
1051}
1052
1057bool FunctionTreeView::isTie(QtProperty *prop) const {
1058 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_tieManager) == prop->propertyManager();
1059}
1060
1065QString FunctionTreeView::getTie(QtProperty *prop) const {
1066 if (!prop)
1067 return "";
1068 if (prop->propertyName() == "Tie") {
1069 return m_tieManager->value(prop);
1070 }
1071 const auto children = prop->subProperties();
1072 const auto it =
1073 std::find_if(children.cbegin(), children.cend(), [](const auto child) { return child->propertyName() == "Tie"; });
1074 if (it != children.cend()) {
1075 return m_tieManager->value(*it);
1076 }
1077 return "";
1078}
1079
1086 std::string const &constraint) {
1087 if (!isParameter(prop))
1089 auto const parts = splitConstraintString(constraint);
1090 if (parts.first.empty())
1092 auto lowerBound = parts.second.first;
1093 auto upperBound = parts.second.second;
1094
1095 // add properties
1097 AConstraint ac;
1098 ac.paramProp = prop;
1099 ac.lower = ac.upper = nullptr;
1100
1101 if (!lowerBound.empty()) {
1102 auto apLower = addProperty(prop, m_constraintManager->addProperty("LowerBound"));
1103 plist << apLower;
1104 ac.lower = apLower.prop;
1105 m_constraintManager->setValue(ac.lower, QString::fromStdString(lowerBound).toDouble());
1106 }
1107
1108 if (!upperBound.empty()) {
1109 auto apUpper = addProperty(prop, m_constraintManager->addProperty("UpperBound"));
1110 plist << apUpper;
1111 ac.upper = apUpper.prop;
1112 m_constraintManager->setValue(ac.upper, QString::fromStdString(upperBound).toDouble());
1113 }
1114
1115 if (ac.lower || ac.upper) {
1116 m_constraints.insert(m_properties[prop].parent, ac);
1117 }
1118 return plist;
1119}
1120
1125bool FunctionTreeView::isConstraint(QtProperty *prop) const {
1126 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_constraintManager) == prop->propertyManager();
1127}
1128
1133bool FunctionTreeView::hasConstraint(QtProperty *prop) const { return hasLowerBound(prop) || hasUpperBound(prop); }
1134
1139bool FunctionTreeView::hasLowerBound(QtProperty *prop) const {
1140 if (!isParameter(prop))
1141 return false;
1142 const auto props = prop->subProperties();
1143 return std::any_of(props.cbegin(), props.cend(), [&](const auto &p) {
1144 return dynamic_cast<QtAbstractPropertyManager *>(m_constraintManager) == p->propertyManager() &&
1145 p->propertyName() == "LowerBound";
1146 });
1147}
1148
1153bool FunctionTreeView::hasUpperBound(QtProperty *prop) const {
1154 if (!isParameter(prop))
1155 return false;
1156 const auto props = prop->subProperties();
1157 return std::any_of(props.cbegin(), props.cend(), [&](const auto &p) {
1158 return dynamic_cast<QtAbstractPropertyManager *>(m_constraintManager) == p->propertyManager() &&
1159 p->propertyName() == "UpperBound";
1160 });
1161}
1162
1164std::string FunctionTreeView::getConstraint(std::string const &parameterName, const double &lowerBound,
1165 const double &upperBound) const {
1166
1167 std::string constraint;
1168 if (lowerBound != Mantid::EMPTY_DBL())
1169 constraint += QString::number(lowerBound).toStdString() + "<";
1170
1171 constraint += parameterName;
1172 if (upperBound != Mantid::EMPTY_DBL())
1173 constraint += "<" + QString::number(upperBound).toStdString();
1174
1175 return constraint;
1176}
1177
1181void FunctionTreeView::popupMenu(const QPoint &) {
1182 auto item = m_browser->currentItem();
1183 if (!item) {
1184 QMenu context(this);
1185 context.addAction(m_actionAddFunction);
1186 if (!QApplication::clipboard()->text().isEmpty()) {
1187 context.addAction(m_actionFromClipboard);
1188 }
1189 if (!m_browser->properties().isEmpty()) {
1190 context.addAction(m_actionToClipboard);
1191 }
1192 context.exec(QCursor::pos());
1193 return;
1194 }
1195 QtProperty *prop = item->property();
1196 if (isFunction(prop)) { // functions
1197 QMenu context(this);
1199 Mantid::API::FunctionFactory::Instance().createFunction(prop->propertyName().toStdString());
1200 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
1201 if (cf || m_properties[prop].parent == nullptr) {
1202 context.addAction(m_actionAddFunction);
1203 }
1204 context.addAction(m_actionRemoveFunction);
1205 if (!QApplication::clipboard()->text().isEmpty()) {
1206 context.addAction(m_actionFromClipboard);
1207 }
1208 if (!m_browser->properties().isEmpty()) {
1209 context.addAction(m_actionToClipboard);
1210 }
1211 context.addAction(m_actionFunctionHelp);
1212 context.exec(QCursor::pos());
1213 } else if (isParameter(prop)) { // parameters
1214 QMenu context(this);
1215 if (hasTie(prop)) {
1216 context.addAction(m_actionRemoveTie);
1217 } else {
1218 context.addAction(m_actionFixParameter);
1219 context.addAction(m_actionAddTie);
1220 }
1221 bool hasLower = hasLowerBound(prop);
1222 bool hasUpper = hasUpperBound(prop);
1223 if (!hasLower && !hasUpper) {
1224 QMenu *constraintMenu = new QMenu("Constraints", this);
1225 constraintMenu->addAction(m_actionConstraints10);
1226 constraintMenu->addAction(m_actionConstraints50);
1227 constraintMenu->addAction(m_actionConstraints);
1228 context.addMenu(constraintMenu);
1229 } else {
1230 context.addAction(m_actionRemoveConstraints);
1231 }
1232 context.exec(QCursor::pos());
1233 } else if (isConstraint(prop)) { // constraints
1234 QMenu context(this);
1235 context.addAction(m_actionRemoveConstraint);
1236 context.exec(QCursor::pos());
1237 }
1238}
1239
1244
1245 auto item = m_browser->currentItem();
1246 QtProperty *prop = nullptr;
1247 if (item) {
1248 prop = item->property();
1249 if (!isFunction(prop))
1250 return;
1251 }
1252
1253 // check if the browser is empty
1254 if (!prop) {
1255 auto top = m_browser->properties();
1256 if (!top.isEmpty()) {
1257 prop = top[0];
1258 if (!isFunction(prop))
1259 return;
1260 }
1261 }
1262
1263 // Start the dialog
1266 connect(m_selectFunctionDialog, SIGNAL(finished(int)), this, SLOT(addFunctionEnd(int)));
1267 }
1270 m_selectFunctionDialog->open();
1271}
1272
1274 if (result != QDialog::Accepted) {
1275 return;
1276 }
1277
1278 QString newFunction = m_selectFunctionDialog->getFunction();
1279 if (newFunction.isEmpty())
1280 return;
1281
1282 // create new function
1283 auto f = Mantid::API::FunctionFactory::Instance().createFunction(newFunction.toStdString());
1284
1285 // get previous global parameters
1286 auto globalParameters = getGlobalParameters();
1287
1288 auto prop = m_selectedFunctionProperty;
1289 if (prop) { // there are other functions defined
1291 Mantid::API::FunctionFactory::Instance().createFunction(prop->propertyName().toStdString());
1292 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
1293 if (cf) {
1294 auto const isAdded = addFunction(prop, f);
1295 if (!isAdded)
1296 return;
1297 } else {
1298 cf.reset(new Mantid::API::CompositeFunction);
1299 auto f0 = getFunction(prop);
1300 if (f0) {
1301 // Modify the previous globals so they have a function prefix
1302 std::transform(globalParameters.begin(), globalParameters.end(), globalParameters.begin(),
1303 m_multiDomainFunctionPrefix.empty() ? addPrefix : insertPrefix);
1304 cf->addFunction(f0);
1305 }
1306 cf->addFunction(f);
1307 setFunction(cf);
1308 }
1309 } else { // the browser is empty - add first function
1310 auto const isAdded = addFunction(nullptr, f);
1311 if (!isAdded)
1312 return;
1313 }
1314 emit functionAdded(f->asString());
1315 setGlobalParameters(globalParameters);
1316 emit globalsChanged(globalParameters);
1317}
1318
1325 std::string attName = prop->propertyName().toStdString();
1326 SetAttributeFromProperty setter(this, prop);
1328 attr.apply(setter);
1329 try {
1330 fun.setAttribute(attName, attr);
1331 } catch (std::exception &expt) {
1332 QMessageBox::critical(this, "Mantid - Error",
1333 "Cannot set attribute " + QString::fromStdString(attName) + " of function " +
1334 prop->propertyName() + ":\n\n" + QString::fromStdString(expt.what()));
1335 }
1336}
1337
1343Mantid::API::IFunction_sptr FunctionTreeView::getFunction(QtProperty *prop, bool attributesOnly) {
1344 if (prop == nullptr) { // get overall function
1345 auto props = m_browser->properties();
1346 if (props.isEmpty())
1348 prop = props[0];
1349 }
1350 if (!isFunction(prop))
1352
1353 // construct the function
1354 auto fun = Mantid::API::FunctionFactory::Instance().createFunction(prop->propertyName().toStdString());
1355 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
1356 if (cf) {
1357 auto children = prop->subProperties();
1358 foreach (QtProperty *child, children) {
1359 if (isFunction(child)) {
1360 auto f = getFunction(child);
1361 // if f is null ignore that function
1362 if (f) {
1363 cf->addFunction(f);
1364 }
1365 } else if (isAttribute(child)) {
1366 setAttributeToFunction(*fun, child);
1367 }
1368 }
1369 } else {
1370 // loop over the children properties and set parameters and attributes
1371 auto children = prop->subProperties();
1372 foreach (QtProperty *child, children) {
1373 if (isAttribute(child)) {
1374 setAttributeToFunction(*fun, child);
1375 } else if (!attributesOnly && isParameter(child)) {
1376 fun->setParameter(child->propertyName().toStdString(), getParameter(child));
1377 }
1378 }
1379 }
1380
1381 // if this flag is set the function requires attributes only
1382 // attempts to set other properties may result in exceptions
1383 if (attributesOnly)
1384 return fun;
1385
1386 // add ties
1387 {
1388 auto from = m_ties.lowerBound(prop);
1389 auto to = m_ties.upperBound(prop);
1390 // ties can become invalid after some editing
1391 QList<QtProperty *> failedTies;
1392 for (auto it = from; it != to; ++it) {
1393 auto const tie = (it->paramName + "=" + m_tieManager->value(it.value().tieProp).toStdString());
1394 try {
1395 fun->addTies(tie);
1396 } catch (...) {
1397 failedTies << it.value().tieProp;
1398 g_log.warning() << "Invalid tie has been removed: " << tie << std::endl;
1399 }
1400 }
1401 // remove failed ties from the browser
1402 foreach (QtProperty *p, failedTies) {
1403 removeProperty(p);
1404 }
1405 }
1406
1407 // add constraints
1408 {
1409 auto from = m_constraints.lowerBound(prop);
1410 auto to = m_constraints.upperBound(prop);
1411 for (auto it = from; it != to; ++it) {
1412 try {
1413 const auto &localParam = it.value();
1414 const auto lower = m_constraintManager->value(localParam.lower);
1415 const auto upper = m_constraintManager->value(localParam.upper);
1416 const auto constraint = getConstraint(localParam.paramProp->propertyName().toStdString(), lower, upper);
1417 fun->addConstraints(constraint);
1418 } catch (...) {
1419 }
1420 }
1421 }
1422
1423 return fun;
1424}
1425
1431void FunctionTreeView::setParameter(std::string const &parameterName, double value) {
1432 auto prop = getParameterProperty(parameterName);
1434 m_parameterManager->setValue(prop, value);
1435}
1436
1442void FunctionTreeView::setParameterError(std::string const &parameterName, double error) {
1443 std::string index, name;
1444 std::tie(index, name) = splitParameterName(parameterName);
1445 if (auto const *prop = getFunctionProperty(index)) {
1446 auto children = prop->subProperties();
1447 const auto it = std::find_if(children.cbegin(), children.cend(), [&](auto &child) {
1448 return isParameter(child) && child->propertyName().toStdString() == name;
1449 });
1450 if (it != children.cend()) {
1451 m_parameterManager->setError(*it, error);
1452 }
1453 }
1454}
1460void FunctionTreeView::setDoubleAttribute(std::string const &attrName, double value) {
1461 auto prop = getAttributeProperty(attrName);
1463 m_attributeDoubleManager->setValue(prop, value);
1464}
1470void FunctionTreeView::setIntAttribute(std::string const &attrName, int value) {
1471 auto prop = getAttributeProperty(attrName);
1473 m_attributeIntManager->setValue(prop, value);
1474}
1480void FunctionTreeView::setStringAttribute(std::string const &attrName, std::string &valueAsStdStr) {
1481 QString value = QString::fromStdString(valueAsStdStr);
1482 auto prop = getAttributeProperty(attrName);
1484 // attName is the un-prefixed attribute name
1485 auto attName = prop->propertyName();
1486 if (attName == "FileName") {
1487 m_filenameManager->setValue(prop, value);
1488 } else if (attName == "Formula") {
1489 m_formulaManager->setValue(prop, value);
1490 } else if (attName == "Workspace") {
1491 m_workspaceManager->setValue(prop, value);
1492 } else {
1493 m_attributeStringManager->setValue(prop, value);
1494 }
1495}
1501void FunctionTreeView::setBooleanAttribute(std::string const &attrName, bool value) {
1502 auto prop = getAttributeProperty(attrName);
1504 m_attributeBoolManager->setValue(prop, value);
1505}
1515void FunctionTreeView::setVectorAttribute(std::string const &attrName, std::vector<double> &value) {
1516 UNUSED_ARG(attrName);
1518}
1523double FunctionTreeView::getParameter(std::string const &parameterName) const {
1524 auto const *prop = getParameterProperty(parameterName);
1525 return m_parameterManager->value(prop);
1526}
1531IFunction::Attribute FunctionTreeView::getAttribute(std::string const &attrName) const {
1532 auto prop = getAttributeProperty(attrName);
1533 if (isDoubleAttribute(prop)) {
1535 } else if (isIntAttribute(prop)) {
1536 return IFunction::Attribute(m_attributeIntManager->value(prop));
1537 } else if (isStringAttribute(prop)) {
1538 return IFunction::Attribute(m_attributeStringManager->value(prop).toStdString());
1539 } else if (isBoolAttribute(prop)) {
1540 return IFunction::Attribute(m_attributeBoolManager->value(prop));
1541 } else if (isVectorAttribute(prop)) {
1543 } else {
1544 throw std::runtime_error("Unknown function attribute " + attrName);
1545 }
1546}
1548QtProperty *FunctionTreeView::getParameterProperty(std::string const &parameterName) const {
1549 std::string index, name;
1550 std::tie(index, name) = splitParameterName(parameterName);
1551 if (auto const *prop = getFunctionProperty(index)) {
1552 const auto children = prop->subProperties();
1553 const auto it = std::find_if(children.cbegin(), children.cend(), [&](const auto &child) {
1554 return isParameter(child) && child->propertyName().toStdString() == name;
1555 });
1556 if (it != children.cend()) {
1557 return *it;
1558 }
1559 }
1560 std::string message = "Unknown function parameter " + parameterName +
1561 "\n\n This may happen if there is a CompositeFunction "
1562 "containing only one function.";
1563 throw std::runtime_error(message);
1564}
1566QtProperty *FunctionTreeView::getAttributeProperty(std::string const &attributeName) const {
1567 std::string index, name;
1568 const QtProperty *prop;
1569 std::tie(index, name) = splitParameterName(attributeName);
1570 if (!variableIsPrefixed(attributeName)) {
1571 // If variable is unprefixed then we are on the top level composite
1572 // function so grab first property from the tree
1573 prop = m_browser->properties()[0];
1574 } else {
1575 prop = getFunctionProperty(index);
1576 }
1577 const auto children = prop->subProperties();
1578 const auto it = std::find_if(children.cbegin(), children.cend(), [&](const auto &child) {
1579 return isAttribute(child) && child->propertyName().toStdString() == name;
1580 });
1581 if (it != children.cend()) {
1582 return *it;
1583 }
1584 std::string message = "Unknown function attribute " + attributeName;
1585 throw std::runtime_error(message);
1586}
1587
1590QtProperty *FunctionTreeView::getParentParameterProperty(QtProperty *prop) const {
1591 const auto itProp =
1592 std::find_if(m_ties.cbegin(), m_ties.cend(), [&prop](const auto &tie) { return tie.tieProp == prop; });
1593 if (itProp != m_ties.cend())
1594 return (*itProp).paramProp;
1595
1596 const auto itConstr = std::find_if(m_constraints.cbegin(), m_constraints.cend(), [&prop](const auto &constraint) {
1597 return (constraint.lower == prop || constraint.upper == prop);
1598 });
1599 if (itConstr != m_constraints.cend())
1600 return (*itConstr).paramProp;
1601 throw std::logic_error("QtProperty " + prop->propertyName().toStdString() +
1602 " is not a child of a property for any function parameter.");
1603}
1604
1609 auto item = m_browser->currentItem();
1610 if (!item)
1611 return;
1612 QtProperty *prop = item->property();
1613 if (!isFunction(prop))
1614 return;
1615 auto const functionString = getFunction(prop)->asString();
1616 auto const functionIndex = getIndex(prop);
1617 removeProperty(prop);
1619
1620 // After removing a function we could end up with
1621 // a CompositeFunction with only one function
1622 // In this case, the function should be kept but
1623 // the composite function should be removed
1624 auto props = m_browser->properties();
1625 auto globalParameters = getGlobalParameters();
1626 if (!props.isEmpty()) {
1627 // The function browser is not empty
1628
1629 // Check if the current function in the browser is a
1630 // composite function
1631 auto topProp = props[0];
1632 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(getFunction(topProp));
1633 if (cf) {
1634 // If it is a composite function
1635 // check that there are more than one function
1636 // which means more than two subproperties
1637
1638 if (cf->nFunctions() == 1 && cf->name() == "CompositeFunction") {
1639 // If only one function remains, remove the composite function:
1640 // Temporary copy the remaining function
1641 auto func = getFunction(props[0]->subProperties()[1]);
1642 std::transform(globalParameters.begin(), globalParameters.end(), globalParameters.begin(),
1643 m_multiDomainFunctionPrefix.empty() ? removePrefix : removeEmbeddedPrefix);
1644 // Remove the composite function
1645 m_browser->removeProperty(topProp);
1646 // Add the temporary stored function
1647 setFunction(func);
1648 }
1649 }
1650 }
1651 emit functionRemovedString(functionString);
1652 emit functionRemoved(functionIndex);
1653 setGlobalParameters(globalParameters);
1654 emit globalsChanged(globalParameters);
1655}
1656
1661 auto item = m_browser->currentItem();
1662 if (!item)
1663 return;
1664 QtProperty *prop = item->property();
1665 if (!isParameter(prop))
1666 return;
1667 auto tie = QString::number(getParameter(prop)).toStdString();
1668 addTieProperty(prop, tie);
1669 emit parameterTieChanged(getParameterName(prop), tie);
1670}
1671
1673QtProperty *FunctionTreeView::getTieProperty(QtProperty *prop) const {
1674 const auto children = prop->subProperties();
1675 const auto it = std::find_if(children.cbegin(), children.cend(),
1676 [](const auto &child) { return child->propertyName() == "Tie"; });
1677 if (it != children.cend()) {
1678 return *it;
1679 }
1680 return nullptr;
1681}
1682
1687 auto item = m_browser->currentItem();
1688 if (!item)
1689 return;
1690 QtProperty *prop = item->property();
1691 if (!isParameter(prop))
1692 return;
1693 auto tieProp = getTieProperty(prop);
1694 if (tieProp) {
1695 removeProperty(tieProp);
1696 }
1697 emit parameterTieChanged(getParameterName(prop), "");
1698}
1699
1704 auto item = m_browser->currentItem();
1705 if (!item)
1706 return;
1707 QtProperty *prop = item->property();
1708 if (!isParameter(prop))
1709 return;
1710
1711 bool ok;
1712 auto tie = QInputDialog::getText(this, "Add a tie", "Tie:", QLineEdit::Normal, "", &ok).toStdString();
1713 if (ok && !tie.empty()) {
1714 try {
1715 addTieProperty(prop, tie);
1716 emit parameterTieChanged(getParameterName(prop), tie);
1718 QMessageBox::critical(this, "Mantid - Error", "Syntax errors found in tie: " + QString::fromStdString(tie));
1719 } catch (std::exception &e) {
1720 QMessageBox::critical(this, "Mantid - Error", QString::fromLatin1("Errors found in tie: ") + e.what());
1721 }
1722 }
1723}
1724
1729 auto funStr = QApplication::clipboard()->text().toStdString();
1730 if (funStr.empty())
1731 return;
1732 try {
1733 auto fun = Mantid::API::FunctionFactory::Instance().createInitialized(funStr);
1734 if (!fun)
1735 return;
1736 this->setFunction(fun);
1737 emit functionReplaced(funStr);
1738 } catch (...) {
1739 // text in the clipboard isn't a function definition
1740 QMessageBox::warning(this, "Mantid - Warning",
1741 "Text in the clipboard isn't a function definition"
1742 " or contains errors.");
1743 }
1744}
1745
1750
1755 auto item = m_browser->currentItem();
1756 if (!item)
1757 return;
1758 QtProperty *prop = item->property();
1759 if (!isParameter(prop))
1760 return;
1761 std::string functionIndex, name;
1762 std::tie(functionIndex, name) = splitParameterName(getParameterName(prop));
1763 auto const value = QString::number(getParameter(prop)).toStdString();
1764 auto const constraint = value + "<" + name + "<" + value;
1765 addConstraintProperties(prop, constraint);
1766 emit parameterConstraintAdded(functionIndex, constraint);
1767}
1768
1773 auto item = m_browser->currentItem();
1774 if (!item)
1775 return;
1776 QtProperty *prop = item->property();
1777 if (!isParameter(prop))
1778 return;
1779 double val = getParameter(prop);
1780 std::string functionIndex, name;
1781 std::tie(functionIndex, name) = splitParameterName(getParameterName(prop));
1782 auto const constraint =
1783 QString::number(val * 0.9).toStdString() + "<" + name + "<" + QString::number(val * 1.1).toStdString();
1784 addConstraintProperties(prop, constraint);
1785 emit parameterConstraintAdded(functionIndex, constraint);
1786}
1787
1792 auto item = m_browser->currentItem();
1793 if (!item)
1794 return;
1795 QtProperty *prop = item->property();
1796 if (!isParameter(prop))
1797 return;
1798 double val = getParameter(prop);
1799 std::string functionIndex, name;
1800 std::tie(functionIndex, name) = splitParameterName(getParameterName(prop));
1801 auto const constraint =
1802 QString::number(val * 0.5).toStdString() + "<" + name + "<" + QString::number(val * 1.5).toStdString();
1803 addConstraintProperties(prop, constraint);
1804 emit parameterConstraintAdded(functionIndex, constraint);
1805}
1806
1808 auto props = prop->subProperties();
1809 foreach (QtProperty *p, props) {
1810 if (isConstraint(p)) {
1811 removeProperty(p);
1812 }
1813 }
1814}
1815
1820 auto item = m_browser->currentItem();
1821 if (!item)
1822 return;
1823 QtProperty *prop = item->property();
1824 if (!isParameter(prop))
1825 return;
1828}
1829
1834 auto item = m_browser->currentItem();
1835 if (!item)
1836 return;
1837 QtProperty *prop = item->property();
1838 if (!isConstraint(prop))
1839 return;
1840 auto paramProp = getParentParameterProperty(prop);
1841 removeProperty(prop);
1842 auto const parName = getParameterName(paramProp);
1843 emit parameterConstraintRemoved(parName);
1844 std::string functionIndex, constraint;
1845 std::tie(functionIndex, constraint) = getFunctionAndConstraint(paramProp);
1846 if (!constraint.empty()) {
1847 emit parameterConstraintAdded(functionIndex, constraint);
1848 }
1849}
1854 auto item = m_browser->currentItem();
1855 if (!item)
1856 return IFunction_sptr();
1857 QtProperty *prop = item->property();
1858 if (!isFunction(prop))
1859 return IFunction_sptr();
1860 return getFunction(prop);
1861}
1865void FunctionTreeView::showFunctionHelp(std::string const &functionName) const {
1866 API::InterfaceManager().showFitFunctionHelp(QString::fromStdString(functionName));
1867}
1868
1869std::pair<std::string, std::string> FunctionTreeView::getFunctionAndConstraint(QtProperty *prop) const {
1870 auto const parName = getParameterName(prop);
1871 double lower = Mantid::EMPTY_DBL();
1872 double upper = Mantid::EMPTY_DBL();
1873 for (auto const *p : prop->subProperties()) {
1874 if (p->propertyName() == "LowerBound")
1875 lower = m_constraintManager->value(p);
1876 if (p->propertyName() == "UpperBound")
1877 upper = m_constraintManager->value(p);
1878 }
1880 std::string functionIndex, name;
1881 std::tie(functionIndex, name) = splitParameterName(parName);
1882 return std::make_pair(functionIndex, getConstraint(name, lower, upper));
1883 }
1884 return std::make_pair("", "");
1885}
1886
1893 auto attributeName = getAttributeName(prop);
1894 // Some attributes require the function to be fully reconstructed, in this
1895 // case we'd need to emit a function replaced signal. If its not one of these
1896 // attributes emit an attributeValueChanged signal.
1897 try {
1898 if (std::find(REQUIRESRECONSTRUCTIONATTRIBUTES.begin(), REQUIRESRECONSTRUCTIONATTRIBUTES.end(),
1899 removePrefix(attributeName)) != REQUIRESRECONSTRUCTIONATTRIBUTES.end()) {
1900 auto funProp = m_properties[prop].parent;
1901 if (!funProp)
1902 return;
1903 auto fun = getFunction(funProp, true);
1904
1905 // delete and recreate all function's properties (attributes, parameters,
1906 // etc)
1907 setFunction(funProp, fun);
1910 emit functionReplaced(getFunction()->asString());
1911 }
1912 } else {
1914 emit attributePropertyChanged(attributeName);
1915 }
1916 }
1917 } catch (std::exception &expt) {
1918 QMessageBox::critical(this, "Mantid - Error", QString::fromStdString(expt.what()));
1919 }
1920}
1921
1926 QtProperty *vectorProp = m_properties[prop].parent;
1927 if (!vectorProp)
1928 throw std::logic_error("FunctionTreeView: inconsistency in vector "
1929 "properties.\nAttribute property not found.");
1930 auto funProp = m_properties[vectorProp].parent;
1931 if (!funProp)
1932 throw std::logic_error("FunctionTreeView: inconsistency in vector "
1933 "properties.\nFunction property not found.");
1934 auto fun = getFunction(funProp, true);
1935 if (!fun)
1936 throw std::logic_error("FunctionTreeView: inconsistency in vector "
1937 "properties.\nFunction undefined.");
1938 auto attName = vectorProp->propertyName().toStdString();
1939 auto attribute = fun->getAttribute(attName).asVector();
1940 auto newSize = m_attributeSizeManager->value(prop);
1941 if (newSize < 0)
1942 newSize = 0;
1943 if (attribute.size() != static_cast<size_t>(newSize)) {
1944 if (newSize == 0) {
1945 attribute.clear();
1946 } else {
1947 attribute.resize(newSize);
1948 }
1949 fun->setAttributeValue(attName, attribute);
1950 setFunction(funProp, fun);
1952 }
1953}
1954
1961 QtProperty *vectorProp = m_properties[prop].parent;
1962 if (!vectorProp)
1963 throw std::runtime_error("FunctionTreeView: inconsistency in vector properties.");
1964 attributeChanged(vectorProp);
1965}
1966
1968 auto tieProp = getTieProperty(prop);
1969 if (tieProp && !tieProp->isEnabled()) {
1970 // it is a fixed tie
1971 QString newTie = QString("%1=%2").arg(prop->propertyName()).arg(m_parameterManager->value(prop));
1972 if (!newTie.isEmpty()) {
1973 m_tieManager->setValue(tieProp, newTie);
1974 }
1975 }
1977 setErrorsEnabled(false);
1979 }
1980}
1981
1983void FunctionTreeView::tieChanged(QtProperty *prop) {
1984 for (const auto &atie : m_ties) {
1985 if (atie.tieProp == prop) {
1986 emit parameterTieChanged(getParameterName(prop), getTie(prop).toStdString());
1987 }
1988 }
1989}
1990
1993 for (const auto &constr : m_constraints) {
1994 const bool isLower = constr.lower == prop;
1995 const bool isUpper = constr.upper == prop;
1996 if (isLower || isUpper) {
1997 auto paramProp = getParentParameterProperty(prop);
1998 std::string functionIndex, constraint;
1999 std::tie(functionIndex, constraint) = getFunctionAndConstraint(paramProp);
2000 if (!constraint.empty()) {
2001 emit parameterConstraintAdded(functionIndex, constraint);
2002 return; // No need to keep looping as found constraint changed
2003 }
2004 }
2005 }
2006}
2007
2009 emit localParameterButtonClicked(getIndex(prop) + prop->propertyName().toStdString());
2010}
2011
2012bool FunctionTreeView::hasFunction() const { return !m_functionManager->properties().isEmpty(); }
2013
2018void FunctionTreeView::setColumnSizes(int s0, int s1, int s2) { m_browser->setColumnSizes(s0, s1, s2); }
2019
2020void FunctionTreeView::setStretchLastColumn(bool stretch) { m_browser->setStretchLastColumn(stretch); }
2021
2024// Hide global column
2026
2035void FunctionTreeView::setMultiDomainFunctionPrefix(std::string const &functionPrefix) {
2036 m_multiDomainFunctionPrefix = functionPrefix;
2037}
2038
2046void FunctionTreeView::setGlobalTies(std::vector<GlobalTie> const &globalTies) { m_globalTies = globalTies; }
2047
2051void FunctionTreeView::globalChanged(QtProperty *, const QString &, bool) {
2053}
2054
2059void FunctionTreeView::setErrorsEnabled(bool enabled) { m_parameterManager->setErrorsEnabled(enabled); }
2060
2065
2066std::optional<std::string> FunctionTreeView::currentFunctionIndex() const { return m_currentFunctionIndex; }
2067
2069 std::optional<std::string> newIndex;
2070
2071 if (auto item = m_browser->currentItem()) {
2072 auto prop = item->property();
2073 newIndex = getIndex(prop);
2074 }
2075
2076 if (m_currentFunctionIndex != newIndex) {
2077 m_currentFunctionIndex = newIndex;
2079 }
2080}
2081
2082void FunctionTreeView::setParameterTie(std::string const &parameterName, std::string const &tie) {
2083 auto paramProp = getParameterProperty(parameterName);
2084 auto tieProp = getTieProperty(paramProp);
2085 if (!tie.empty()) {
2086 if (tieProp) {
2087 m_tieManager->setValue(tieProp, QString::fromStdString(tie));
2088 } else {
2089 addTieProperty(paramProp, tie);
2090 }
2091 } else if (tieProp) {
2092 removeProperty(tieProp);
2093 }
2094}
2095
2096void FunctionTreeView::setParameterConstraint(std::string const &parameterName, std::string const &constraint) {
2097 auto paramProp = getParameterProperty(parameterName);
2098 if (hasConstraint(paramProp)) {
2099 removeConstraintsQuiet(paramProp);
2100 }
2101 addConstraintProperties(paramProp, constraint);
2102}
2103
2104std::vector<std::string> FunctionTreeView::getGlobalParameters() const {
2105 std::vector<std::string> globals;
2106 for (const auto &prop : m_properties) {
2107 if (prop.prop->checkOption(globalOptionName)) {
2108 auto const name = getParameterName(prop.prop);
2109 globals.emplace_back(name);
2110 }
2111 }
2112 return globals;
2113}
2114
2115void FunctionTreeView::setGlobalParameters(const std::vector<std::string> &globals) {
2116 for (const auto &ap : m_properties) {
2117 auto prop = ap.prop;
2118 if (!prop->hasOption(globalOptionName))
2119 continue;
2120
2121 auto const parameterName = getParameterName(prop);
2122 auto const isGlobal = std::any_of(globals.cbegin(), globals.cend(), [&](std::string const &global) {
2123 return m_multiDomainFunctionPrefix + global == parameterName;
2124 });
2125 prop->setOption(globalOptionName, isGlobal);
2126 }
2127}
2128
2129QTreeWidgetItem *FunctionTreeView::getPropertyWidgetItem(QtProperty *prop) const {
2130 return m_browser->getItemWidget(m_properties.find(prop)->item);
2131}
2132
2133QRect FunctionTreeView::visualItemRect(QtProperty *prop) const {
2134 if (!prop)
2135 return QRect();
2136 auto item = getPropertyWidgetItem(prop);
2137 return item->treeWidget()->visualItemRect(item);
2138}
2139
2141 QRect rect;
2142 try {
2144 } catch (std::exception &) {
2145 }
2146 return rect;
2147}
2148
2150 QRect rect;
2151 try {
2153 } catch (std::exception &) {
2154 }
2155 return rect;
2156}
2157
2158QWidget *FunctionTreeView::getParamWidget(std::string const &parameterName) const {
2159 try {
2160 auto item = getPropertyWidgetItem(getParameterProperty(parameterName));
2161 return item->treeWidget()->itemWidget(item, 1);
2162 } catch (std::exception &) {
2163 }
2164 return nullptr;
2165}
2166
2167QTreeWidget *FunctionTreeView::treeWidget() const { return m_browser->treeWidget(); }
2168
2169QtTreePropertyBrowser *FunctionTreeView::treeBrowser() { return m_browser; }
2170
2171DoubleDialogEditorFactory *FunctionTreeView::doubleEditorFactory() { return m_doubleEditorFactory; }
2172
2173} // namespace MantidQt::MantidWidgets
std::string name
Definition Run.cpp:60
double value
The value of the point.
Definition FitMW.cpp:51
double error
std::map< DeltaEMode::Type, std::string > index
double top
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition System.h:44
double lower
lower and upper bounds on the multiplier, if known
double upper
This class is responsible for creating the correct dialog for an algorithm.
void showFitFunctionHelp(const QString &name=QString())
FunctionTreeView::AProperty apply(const std::vector< double > &v) const override
Create vector property.
FunctionTreeView::AProperty apply(const bool &b) const override
Create bool property.
CreateAttributePropertyForFunctionTreeView(FunctionTreeView *browser, QtProperty *parent, std::string const &attName)
FunctionTreeView::AProperty apply(const int &i) const override
Create int property.
FunctionTreeView::AProperty apply(const double &d) const override
Create double property.
FunctionTreeView::AProperty apply(const std::string &str) const override
Create string property.
The factory for the FilenameDialogEditor.
Class FitPropertyBrowser implements QtPropertyBrowser to display and control fitting function paramet...
void removeConstraint()
Remove one of the constraints.
bool isConstraint(QtProperty *prop) const
Check if a property is a constraint.
void setStringAttribute(std::string const &attrName, std::string &value) override
Updates the value of a string attribute.
std::optional< std::string > m_currentFunctionIndex
Index of currently selected function.
QAction * m_actionRemoveConstraint
Remove one constraints from current parameter.
QtStringPropertyManager * m_attributeStringManager
Manager for function string attribute properties.
void setParameterTie(std::string const &parameterName, std::string const &tie) override
Set a tie.
void clearErrors() override
Clear all errors.
bool hasTie(QtProperty *prop) const
Check if a parameter property has a tie.
bool hasFunction() const override
Check if a function is set.
QAction * m_actionRemoveTie
Unfix a parameter.
QtProperty * getTieProperty(QtProperty *prop) const
Get a tie property attached to a parameter property.
QAction * m_actionFixParameter
Fix a parameter.
void addTieProperty(QtProperty *prop, std::string const &tie, bool globalTie=false)
Add a tie property.
bool isBoolAttribute(QtProperty *prop) const
Check if property is a bool attribute.
QtProperty * getAttributeProperty(std::string const &parameterName) const
Get a property for a parameter.
void popupMenu(const QPoint &)
Show the context menu.
QtIntPropertyManager * m_attributeSizeManager
Manager for vector attribute size properties.
void setDoubleAttribute(std::string const &attrName, double value) override
Update a double attribute.
bool isTie(QtProperty *prop) const
Check if a property is a tie.
QtGroupPropertyManager * m_functionManager
Manager for function group properties.
bool m_multiDataset
Set true if the constructed function is intended to be used in a multi-dataset fit.
void setIntAttribute(std::string const &attrName, int value) override
Updates the value of a integer attribute.
std::string getAttributeName(QtProperty *prop) const
Get name of the attribute for a property.
QtGroupPropertyManager * m_attributeVectorManager
Manager for vector attribute properties.
QRect visualItemRect(QtProperty *prop) const
QAction * m_actionFromClipboard
Copy a function from the clipboard.
void removeProperty(QtProperty *prop)
Remove and delete property.
QAction * m_actionFunctionHelp
Show function help menu.
void copyToClipboard()
Copy the function to the clipboard.
QtStringPropertyManager * m_workspaceManager
Manager for Workspace attributes.
QtTreePropertyBrowser * m_browser
Qt property browser which displays properties.
QtProperty * getParameterProperty(std::string const &parameterName) const
Get a property for a parameter Get a property for a parameter.
bool addFunction(QtProperty *prop, const Mantid::API::IFunction_sptr &fun)
Add a function.
void attributeVectorSizeChanged(QtProperty *)
Called when the size of a vector attribute is changed.
QTreeWidgetItem * getPropertyWidgetItem(QtProperty *prop) const
void createBrowser()
Create the Qt property browser.
QRect getVisualRectFunctionProperty(std::string const &index) const
bool hasUpperBound(QtProperty *prop) const
Check if a parameter property has a upper bound.
void addConstraints50()
Add both constraints to current parameter.
QString getTie(QtProperty *prop) const
Get a tie for a paramater.
void setAttributeToFunction(Mantid::API::IFunction &fun, QtProperty *prop)
Set value of an attribute (as a property) to a function.
QAction * m_actionConstraints50
Add both constraints to current parameter with 50% spread.
QtDoublePropertyManager * m_attributeVectorDoubleManager
Manager for vector attribute member properties.
QAction * m_actionConstraints
Add both constraints to current parameter.
AProperty addAttributeProperty(QtProperty *parent, std::string const &attName, const Mantid::API::IFunction::Attribute &att)
Add a attribute property.
void setParameter(std::string const &parameterName, double value) override
Update the function parameter value.
QAction * m_actionConstraints10
Add both constraints to current parameter with 10% spread.
QtStringPropertyManager * m_filenameManager
Manager for file name attributes.
FunctionTreeView(QWidget *parent, bool multi, std::vector< std::string > categories=std::vector< std::string >())
Constructor.
void addGlobalParameterTie(QtProperty *property, const std::string &parameterName, const CompositeFunction_sptr &parentComposite=nullptr, const std::size_t &parentIndex=0)
Adds a global tie for a parameter if one exists.
void clear() override
Clear the contents.
void setParameterError(std::string const &parameterName, double error) override
Update the function parameter error.
AProperty addProperty(QtProperty *parent, QtProperty *subproperty)
Add a sub-property.
void addConstraints10()
Add both constraints to current parameter.
void attributeVectorDoubleChanged(QtProperty *)
Called when a member of a vector attribute is changed.
void parameterButtonClicked(QtProperty *)
Called when button in local parameter editor was clicked.
QAction * m_actionToClipboard
Copy a function to the clipboard.
QtDoublePropertyManager * m_attributeDoubleManager
Manager for function double attribute properties.
QRect getVisualRectParameterProperty(std::string const &index) const
double getParameter(std::string const &parameterName) const override
Get a value of a parameter.
bool isFunction(QtProperty *prop) const
Check if property is a function group.
void setFunction(Mantid::API::IFunction_sptr fun) override
Set the function in the browser.
void addConstraints()
Add both constraints to current parameter.
IFunction::Attribute getAttribute(std::string const &attrName) const override
Get a value of a attribute.
bool isStringAttribute(QtProperty *prop) const
Check if property is a string attribute.
bool addParameterTieInComposite(QtProperty *property, const std::string &parameterName, const Mantid::API::CompositeFunction_sptr &composite, const std::size_t &index)
Add tie to a parameter property stored within a composite function.
AProperty addParameterProperty(QtProperty *parent, std::string const &parameterName, std::string const &paramDesc, double paramValue)
Add a parameter property.
QAction * m_actionRemoveConstraints
Remove both constraints from current parameter.
void addMultiDomainIndexProperty(QtProperty *prop)
Adds an index property representing the function index of a specific domain within a MultiDomainFunct...
QtDoublePropertyManager * m_constraintManager
Manager for parameter constraint properties.
std::string getFullParameterName(const std::string &parameter, int compositeIndex=-1) const
Gets the full parameter name when using the m_multiDomainFunctionPrefix.
AProperty getFunctionProperty() const
Get property of the overall function.
void tieChanged(QtProperty *)
Called when a tie property changes.
void setStretchLastColumn(bool stretch)
Set the last column to stretch.
std::vector< std::string > m_allowedCategories
bool hasConstraint(QtProperty *prop) const
Check if a parameter property has a constraint.
void removeConstraints()
Remove both constraints from current parameter.
QtProperty * getParentParameterProperty(QtProperty *prop) const
Get a property for a parameter which is a parent of a given property (tie or constraint).
QMultiMap< QtProperty *, ATie > m_ties
Store parameter ties. Keys are function properties.
bool isParameter(QtProperty *prop) const
Check if property is a function paramater.
QMap< QtProperty *, AProperty > m_properties
Store all properties in a map for easy access.
QAction * m_actionAddTie
Add a custom tie to a parameter.
void pasteFromClipboard()
Copy function from the clipboard.
QtIntPropertyManager * m_attributeIntManager
Manager for function int attribute properties.
void setParameterConstraint(std::string const &parameterName, std::string const &constraint) override
Set a constraint.
AProperty addFunctionProperty(QtProperty *parent, std::string const &funName)
Add a function property.
void setMultiDomainFunctionPrefix(std::string const &functionPrefix)
The function index displayed as a multi-domain function index at the top of the FunctionTreeView.
AProperty addIndexProperty(QtProperty *prop)
Add property showing function's index in the composite function.
QtBoolPropertyManager * m_attributeBoolManager
Manager for function bool attribute properties.
bool isIndex(QtProperty *prop) const
Check if a property is an index.
DoubleDialogEditorFactory * doubleEditorFactory()
IFunction_sptr getSelectedFunction() override
Get user selected function.
void updateFunctionIndices(QtProperty *prop=nullptr, std::string const &index="")
Update function index properties.
std::string getIndex(QtProperty *prop) const
Get the function index for a property.
void setBooleanAttribute(std::string const &attrName, bool value) override
Updates the value of a boolean attribute.
std::string getConstraint(std::string const &parameterName, const double &lowerBound=Mantid::EMPTY_DBL(), const double &upperBound=Mantid::EMPTY_DBL()) const
Get a constraint string.
std::string m_multiDomainFunctionPrefix
The function prefix of the domain with a MultiDomainFunction currently being displayed.
bool isIntAttribute(QtProperty *prop) const
Check if property is a int attribute.
void setErrorsEnabled(bool enabled) override
Set error display on/off.
std::string getFullTie(std::string const &tie) const
Gets the full tie when using the m_multiDomainFunctionPrefix.
QtStringPropertyManager * m_tieManager
Manager for function tie properties.
std::vector< std::string > getGlobalParameters() const
Get a list of global parameters.
void updateCurrentFunctionIndex()
Update index of currently selected function.
ParameterPropertyManager * m_parameterManager
Manager for function parameter properties.
void createActions()
Create and connect actions.
bool isAttribute(QtProperty *prop) const
Check if property is a function attribute.
void showFunctionHelp(std::string const &functionName) const override
Show function help page for input functionName.
void parameterPropertyChanged(QtProperty *)
Called when a function parameter property is changed.
bool hasLowerBound(QtProperty *prop) const
Check if a parameter property has a lower bound.
void setColumnSizes(int s0, int s1, int s2=-1)
Resize the browser's columns.
QtStringPropertyManager * m_formulaManager
Manager for Formula attributes.
void globalChanged(QtProperty *, const QString &, bool)
Called when "Global" check-box was clicked.
void addParameterTie(QtProperty *property, const Mantid::API::IFunction_sptr &function, const std::string &parameterName, const std::size_t &parameterIndex, const Mantid::API::CompositeFunction_sptr &parentComposite=nullptr, const std::size_t &parentIndex=0)
Add tie to a parameter property.
void setGlobalParameters(const std::vector< std::string > &) override
Set new global parameters.
QMultiMap< QtProperty *, AConstraint > m_constraints
Store parameter constraints. Keys are function properties.
DoubleDialogEditorFactory * m_doubleEditorFactory
Editor used for editing doubles.
void constraintChanged(QtProperty *)
Called when a constraint property changes.
std::optional< std::string > currentFunctionIndex() const override
Index of currently selected function.
void attributeChanged(QtProperty *)
Called when a function attribute property is changed.
void removeConstraintsQuiet(QtProperty *paramProp)
std::pair< std::string, std::string > getFunctionAndConstraint(QtProperty *prop) const
Get a pair of function index (eg f0.f2.) and constraint expression given a parameter property.
bool isDoubleAttribute(QtProperty *prop) const
Check if property is a double attribute.
void addAttributeAndParameterProperties(QtProperty *prop, const Mantid::API::IFunction_sptr &fun, const Mantid::API::CompositeFunction_sptr &parentComposite=nullptr, const std::size_t &parentIndex=0)
Add attribute and parameter properties to a function property.
void setVectorAttribute(std::string const &attrName, std::vector< double > &val) override
Updates the value of a vector attribute NOTE: This is currently not implemented as there is no need f...
QWidget * getParamWidget(std::string const &parameterName) const
QList< AProperty > addConstraintProperties(QtProperty *prop, std::string const &constraint)
Add a constraint property.
bool isVectorAttribute(QtProperty *prop) const
Check if property is a vector attribute.
QAction * m_actionRemoveFunction
Remove a function.
Mantid::API::IFunction_sptr getFunction(QtProperty *prop=nullptr, bool attributesOnly=false)
Return the function.
void setGlobalTies(std::vector< GlobalTie > const &globalTies)
The global ties within a multi-domain function.
std::string getParameterName(QtProperty *prop) const
Get name of the parameter for a property.
QtStringPropertyManager * m_indexManager
Manager for function index properties.
The interface to a function view.
void localParameterButtonClicked(std::string const &parameterName)
In multi-dataset context a button value editor was clicked.
void parameterTieChanged(std::string const &parameterName, std::string const &tie)
User sets a tie.
void copyToClipboardRequest()
User requested copy function to clipboard.
void globalsChanged(const std::vector< std::string > &)
User changed the list of global parameters.
void parameterChanged(std::string const &parameterName)
Function parameter gets changed.
void functionAdded(std::string const &funStr)
User adds a function.
void parameterConstraintRemoved(std::string const &parameterName)
User removes a constraint.
void attributePropertyChanged(std::string const &attrName)
Function attribute gets changed.
void functionHelpRequest()
User requested function help.
void functionReplaced(std::string const &funStr)
User replaces the whole function (eg, by pasting it from clipboard)
void parameterConstraintAdded(std::string const &functionIndex, std::string const &constraint)
User sets a constraint.
void functionRemovedString(std::string const &funStr)
User removes a function.
void functionRemoved(std::string const &functionIndex)
User removes a function.
void currentFunctionChanged()
User selects a different (sub)function (or one of it's sub-properties)
Select a function type out of a list of available ones.
void clearSearchBoxText() const
Clear the text in the search box.
QString getFunction() const
Return selected function.
Attribute visitor to set an attribute from a QtProperty.
void apply(bool &b) const override
Set bool attribute.
SetAttributeFromProperty(FunctionTreeView *browser, QtProperty *prop)
void apply(std::string &str) const override
Set string attribute.
void apply(int &i) const override
Set int attribute.
void apply(double &d) const override
Set double attribute.
void apply(std::vector< double > &v) const override
Set vector attribute.
A composite function is a function containing other functions.
Specialised exception for parsing errors.
Definition Expression.h:39
Attribute is a non-fitting parameter.
Definition IFunction.h:285
T apply(AttributeVisitor< T > &v)
Apply an attribute visitor.
Definition IFunction.h:303
Const version of AttributeVisitor.
Definition IFunction.h:244
This is an interface to a fitting function - a semi-abstarct class.
Definition IFunction.h:166
virtual Attribute getAttribute(const std::string &name) const
Return a value of attribute attName.
virtual void setAttribute(const std::string &name, const Attribute &)
Set a value to attribute attName.
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition Logger.h:51
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
EXPORT_OPT_MANTIDQT_COMMON std::pair< std::string, std::pair< std::string, std::string > > splitConstraintString(const std::string &constraint)
Split a constraint definition into a parameter name and a pair of bounds, for example -1 < f0....
EXPORT_OPT_MANTIDQT_COMMON bool isNumber(std::string const &str)
Checks if a string contains a number, or whether it contains characters.
EXPORT_OPT_MANTIDQT_COMMON std::pair< std::string, std::string > splitParameterName(std::string const &parameterName)
Split a qualified parameter name into function index and local parameter name.
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
Definition IFunction.h:743
std::shared_ptr< CompositeFunction > CompositeFunction_sptr
shared pointer to the composite function base class
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition EmptyValues.h:42
STL namespace.
std::string to_string(const wide_integer< Bits, Signed > &n)
To keep QtProperty and its QtBrowserItem in one place.