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 // Might not be the most efficient way to do it. m_functionManager might be
971 // searched instead,
972 // but it is not being kept up-to-date at the moment (is not cleared).
973 for (const auto &property : m_properties.keys()) {
974 if (isFunction(property) && getIndex(property) == index) {
975 return property;
976 }
977 }
978
979 // No function with such index
980 return nullptr;
981}
982
989void FunctionTreeView::addTieProperty(QtProperty *prop, std::string const &tie, bool globalTie) {
990 if (!prop) {
991 throw std::runtime_error("FunctionTreeView: null property pointer");
992 }
993
994 if (!isParameter(prop))
995 return;
996
997 QtProperty *funProp = getFunctionProperty().prop;
998
999 // Create and add a QtProperty for the tie.
1000 m_tieManager->blockSignals(true);
1001 QtProperty *tieProp = m_tieManager->addProperty("Tie");
1002 m_tieManager->setValue(tieProp, QString::fromStdString(globalTie ? tie : getFullTie(tie)));
1003 addProperty(prop, tieProp);
1004 m_tieManager->blockSignals(false);
1005
1006 const auto parName = getParameterName(prop);
1007 // Store tie information for easier access
1008 ATie atie;
1009 atie.paramProp = prop;
1010 atie.paramName = parName;
1011 atie.tieProp = tieProp;
1012 m_ties.insert(funProp, atie);
1013}
1014
1021std::string FunctionTreeView::getFullTie(std::string const &tie) const {
1022 if (!isNumber(tie) && !containsOneOf(tie, "="))
1023 return m_multiDomainFunctionPrefix + tie;
1024 return tie;
1025}
1026
1036std::string FunctionTreeView::getFullParameterName(const std::string &parameter, int compositeIndex) const {
1037 auto fullParameterName = m_multiDomainFunctionPrefix;
1038 if (compositeIndex != -1)
1039 fullParameterName += "f" + std::to_string(compositeIndex) + ".";
1040 fullParameterName += parameter;
1041 return fullParameterName;
1042}
1043
1048bool FunctionTreeView::hasTie(QtProperty *prop) const {
1049 if (!prop)
1050 return false;
1051 const auto children = prop->subProperties();
1052 return std::any_of(children.cbegin(), children.cend(),
1053 [](const auto child) { return child->propertyName() == "Tie"; });
1054}
1055
1060bool FunctionTreeView::isTie(QtProperty *prop) const {
1061 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_tieManager) == prop->propertyManager();
1062}
1063
1068QString FunctionTreeView::getTie(QtProperty *prop) const {
1069 if (!prop)
1070 return "";
1071 if (prop->propertyName() == "Tie") {
1072 return m_tieManager->value(prop);
1073 }
1074 const auto children = prop->subProperties();
1075 const auto it =
1076 std::find_if(children.cbegin(), children.cend(), [](const auto child) { return child->propertyName() == "Tie"; });
1077 if (it != children.cend()) {
1078 return m_tieManager->value(*it);
1079 }
1080 return "";
1081}
1082
1089 std::string const &constraint) {
1090 if (!isParameter(prop))
1092 auto const parts = splitConstraintString(constraint);
1093 if (parts.first.empty())
1095 auto lowerBound = parts.second.first;
1096 auto upperBound = parts.second.second;
1097
1098 // add properties
1100 AConstraint ac;
1101 ac.paramProp = prop;
1102 ac.lower = ac.upper = nullptr;
1103
1104 if (!lowerBound.empty()) {
1105 auto apLower = addProperty(prop, m_constraintManager->addProperty("LowerBound"));
1106 plist << apLower;
1107 ac.lower = apLower.prop;
1108 m_constraintManager->setValue(ac.lower, QString::fromStdString(lowerBound).toDouble());
1109 }
1110
1111 if (!upperBound.empty()) {
1112 auto apUpper = addProperty(prop, m_constraintManager->addProperty("UpperBound"));
1113 plist << apUpper;
1114 ac.upper = apUpper.prop;
1115 m_constraintManager->setValue(ac.upper, QString::fromStdString(upperBound).toDouble());
1116 }
1117
1118 if (ac.lower || ac.upper) {
1119 m_constraints.insert(m_properties[prop].parent, ac);
1120 }
1121 return plist;
1122}
1123
1128bool FunctionTreeView::isConstraint(QtProperty *prop) const {
1129 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_constraintManager) == prop->propertyManager();
1130}
1131
1136bool FunctionTreeView::hasConstraint(QtProperty *prop) const { return hasLowerBound(prop) || hasUpperBound(prop); }
1137
1142bool FunctionTreeView::hasLowerBound(QtProperty *prop) const {
1143 if (!isParameter(prop))
1144 return false;
1145 const auto props = prop->subProperties();
1146 return std::any_of(props.cbegin(), props.cend(), [&](const auto &p) {
1147 return dynamic_cast<QtAbstractPropertyManager *>(m_constraintManager) == p->propertyManager() &&
1148 p->propertyName() == "LowerBound";
1149 });
1150}
1151
1156bool FunctionTreeView::hasUpperBound(QtProperty *prop) const {
1157 if (!isParameter(prop))
1158 return false;
1159 const auto props = prop->subProperties();
1160 return std::any_of(props.cbegin(), props.cend(), [&](const auto &p) {
1161 return dynamic_cast<QtAbstractPropertyManager *>(m_constraintManager) == p->propertyManager() &&
1162 p->propertyName() == "UpperBound";
1163 });
1164}
1165
1167std::string FunctionTreeView::getConstraint(std::string const &parameterName, const double &lowerBound,
1168 const double &upperBound) const {
1169
1170 std::string constraint;
1171 if (lowerBound != Mantid::EMPTY_DBL())
1172 constraint += QString::number(lowerBound).toStdString() + "<";
1173
1174 constraint += parameterName;
1175 if (upperBound != Mantid::EMPTY_DBL())
1176 constraint += "<" + QString::number(upperBound).toStdString();
1177
1178 return constraint;
1179}
1180
1184void FunctionTreeView::popupMenu(const QPoint &) {
1185 auto item = m_browser->currentItem();
1186 if (!item) {
1187 QMenu context(this);
1188 context.addAction(m_actionAddFunction);
1189 if (!QApplication::clipboard()->text().isEmpty()) {
1190 context.addAction(m_actionFromClipboard);
1191 }
1192 if (!m_browser->properties().isEmpty()) {
1193 context.addAction(m_actionToClipboard);
1194 }
1195 context.exec(QCursor::pos());
1196 return;
1197 }
1198 QtProperty *prop = item->property();
1199 if (isFunction(prop)) { // functions
1200 QMenu context(this);
1202 Mantid::API::FunctionFactory::Instance().createFunction(prop->propertyName().toStdString());
1203 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
1204 if (cf || m_properties[prop].parent == nullptr) {
1205 context.addAction(m_actionAddFunction);
1206 }
1207 context.addAction(m_actionRemoveFunction);
1208 if (!QApplication::clipboard()->text().isEmpty()) {
1209 context.addAction(m_actionFromClipboard);
1210 }
1211 if (!m_browser->properties().isEmpty()) {
1212 context.addAction(m_actionToClipboard);
1213 }
1214 context.addAction(m_actionFunctionHelp);
1215 context.exec(QCursor::pos());
1216 } else if (isParameter(prop)) { // parameters
1217 QMenu context(this);
1218 if (hasTie(prop)) {
1219 context.addAction(m_actionRemoveTie);
1220 } else {
1221 context.addAction(m_actionFixParameter);
1222 context.addAction(m_actionAddTie);
1223 }
1224 bool hasLower = hasLowerBound(prop);
1225 bool hasUpper = hasUpperBound(prop);
1226 if (!hasLower && !hasUpper) {
1227 QMenu *constraintMenu = new QMenu("Constraints", this);
1228 constraintMenu->addAction(m_actionConstraints10);
1229 constraintMenu->addAction(m_actionConstraints50);
1230 constraintMenu->addAction(m_actionConstraints);
1231 context.addMenu(constraintMenu);
1232 } else {
1233 context.addAction(m_actionRemoveConstraints);
1234 }
1235 context.exec(QCursor::pos());
1236 } else if (isConstraint(prop)) { // constraints
1237 QMenu context(this);
1238 context.addAction(m_actionRemoveConstraint);
1239 context.exec(QCursor::pos());
1240 }
1241}
1242
1247
1248 auto item = m_browser->currentItem();
1249 QtProperty *prop = nullptr;
1250 if (item) {
1251 prop = item->property();
1252 if (!isFunction(prop))
1253 return;
1254 }
1255
1256 // check if the browser is empty
1257 if (!prop) {
1258 auto top = m_browser->properties();
1259 if (!top.isEmpty()) {
1260 prop = top[0];
1261 if (!isFunction(prop))
1262 return;
1263 }
1264 }
1265
1266 // Start the dialog
1269 connect(m_selectFunctionDialog, SIGNAL(finished(int)), this, SLOT(addFunctionEnd(int)));
1270 }
1273 m_selectFunctionDialog->open();
1274}
1275
1277 if (result != QDialog::Accepted) {
1278 return;
1279 }
1280
1281 QString newFunction = m_selectFunctionDialog->getFunction();
1282 if (newFunction.isEmpty())
1283 return;
1284
1285 // create new function
1286 auto f = Mantid::API::FunctionFactory::Instance().createFunction(newFunction.toStdString());
1287
1288 // get previous global parameters
1289 auto globalParameters = getGlobalParameters();
1290
1291 auto prop = m_selectedFunctionProperty;
1292 if (prop) { // there are other functions defined
1294 Mantid::API::FunctionFactory::Instance().createFunction(prop->propertyName().toStdString());
1295 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
1296 if (cf) {
1297 auto const isAdded = addFunction(prop, f);
1298 if (!isAdded)
1299 return;
1300 } else {
1301 cf.reset(new Mantid::API::CompositeFunction);
1302 auto f0 = getFunction(prop);
1303 if (f0) {
1304 // Modify the previous globals so they have a function prefix
1305 std::transform(globalParameters.begin(), globalParameters.end(), globalParameters.begin(),
1306 m_multiDomainFunctionPrefix.empty() ? addPrefix : insertPrefix);
1307 cf->addFunction(f0);
1308 }
1309 cf->addFunction(f);
1310 setFunction(cf);
1311 }
1312 } else { // the browser is empty - add first function
1313 auto const isAdded = addFunction(nullptr, f);
1314 if (!isAdded)
1315 return;
1316 }
1317 emit functionAdded(f->asString());
1318 setGlobalParameters(globalParameters);
1319 emit globalsChanged(globalParameters);
1320}
1321
1328 std::string attName = prop->propertyName().toStdString();
1329 SetAttributeFromProperty setter(this, prop);
1331 attr.apply(setter);
1332 try {
1333 fun.setAttribute(attName, attr);
1334 } catch (std::exception &expt) {
1335 QMessageBox::critical(this, "Mantid - Error",
1336 "Cannot set attribute " + QString::fromStdString(attName) + " of function " +
1337 prop->propertyName() + ":\n\n" + QString::fromStdString(expt.what()));
1338 }
1339}
1340
1346Mantid::API::IFunction_sptr FunctionTreeView::getFunction(QtProperty *prop, bool attributesOnly) {
1347 if (prop == nullptr) { // get overall function
1348 auto props = m_browser->properties();
1349 if (props.isEmpty())
1351 prop = props[0];
1352 }
1353 if (!isFunction(prop))
1355
1356 // construct the function
1357 auto fun = Mantid::API::FunctionFactory::Instance().createFunction(prop->propertyName().toStdString());
1358 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
1359 if (cf) {
1360 auto children = prop->subProperties();
1361 foreach (QtProperty *child, children) {
1362 if (isFunction(child)) {
1363 auto f = getFunction(child);
1364 // if f is null ignore that function
1365 if (f) {
1366 cf->addFunction(f);
1367 }
1368 } else if (isAttribute(child)) {
1369 setAttributeToFunction(*fun, child);
1370 }
1371 }
1372 } else {
1373 // loop over the children properties and set parameters and attributes
1374 auto children = prop->subProperties();
1375 foreach (QtProperty *child, children) {
1376 if (isAttribute(child)) {
1377 setAttributeToFunction(*fun, child);
1378 } else if (!attributesOnly && isParameter(child)) {
1379 fun->setParameter(child->propertyName().toStdString(), getParameter(child));
1380 }
1381 }
1382 }
1383
1384 // if this flag is set the function requires attributes only
1385 // attempts to set other properties may result in exceptions
1386 if (attributesOnly)
1387 return fun;
1388
1389 // add ties
1390 {
1391 auto from = m_ties.lowerBound(prop);
1392 auto to = m_ties.upperBound(prop);
1393 // ties can become invalid after some editing
1394 QList<QtProperty *> failedTies;
1395 for (auto it = from; it != to; ++it) {
1396 auto const tie = (it->paramName + "=" + m_tieManager->value(it.value().tieProp).toStdString());
1397 try {
1398 fun->addTies(tie);
1399 } catch (...) {
1400 failedTies << it.value().tieProp;
1401 g_log.warning() << "Invalid tie has been removed: " << tie << std::endl;
1402 }
1403 }
1404 // remove failed ties from the browser
1405 foreach (QtProperty *p, failedTies) {
1406 removeProperty(p);
1407 }
1408 }
1409
1410 // add constraints
1411 {
1412 auto from = m_constraints.lowerBound(prop);
1413 auto to = m_constraints.upperBound(prop);
1414 for (auto it = from; it != to; ++it) {
1415 try {
1416 const auto &localParam = it.value();
1417 const auto lower = m_constraintManager->value(localParam.lower);
1418 const auto upper = m_constraintManager->value(localParam.upper);
1419 const auto constraint = getConstraint(localParam.paramProp->propertyName().toStdString(), lower, upper);
1420 fun->addConstraints(constraint);
1421 } catch (...) {
1422 }
1423 }
1424 }
1425
1426 return fun;
1427}
1428
1434void FunctionTreeView::setParameter(std::string const &parameterName, double value) {
1435 auto prop = getParameterProperty(parameterName);
1437 m_parameterManager->setValue(prop, value);
1438}
1439
1445void FunctionTreeView::setParameterError(std::string const &parameterName, double error) {
1446 std::string index, name;
1447 std::tie(index, name) = splitParameterName(parameterName);
1448 if (auto const *prop = getFunctionProperty(index)) {
1449 auto children = prop->subProperties();
1450 const auto it = std::find_if(children.cbegin(), children.cend(), [&](auto &child) {
1451 return isParameter(child) && child->propertyName().toStdString() == name;
1452 });
1453 if (it != children.cend()) {
1454 m_parameterManager->setError(*it, error);
1455 }
1456 }
1457}
1463void FunctionTreeView::setDoubleAttribute(std::string const &attrName, double value) {
1464 auto prop = getAttributeProperty(attrName);
1466 m_attributeDoubleManager->setValue(prop, value);
1467}
1473void FunctionTreeView::setIntAttribute(std::string const &attrName, int value) {
1474 auto prop = getAttributeProperty(attrName);
1476 m_attributeIntManager->setValue(prop, value);
1477}
1483void FunctionTreeView::setStringAttribute(std::string const &attrName, std::string &valueAsStdStr) {
1484 QString value = QString::fromStdString(valueAsStdStr);
1485 auto prop = getAttributeProperty(attrName);
1487 // attName is the un-prefixed attribute name
1488 auto attName = prop->propertyName();
1489 if (attName == "FileName") {
1490 m_filenameManager->setValue(prop, value);
1491 } else if (attName == "Formula") {
1492 m_formulaManager->setValue(prop, value);
1493 } else if (attName == "Workspace") {
1494 m_workspaceManager->setValue(prop, value);
1495 } else {
1496 m_attributeStringManager->setValue(prop, value);
1497 }
1498}
1504void FunctionTreeView::setBooleanAttribute(std::string const &attrName, bool value) {
1505 auto prop = getAttributeProperty(attrName);
1507 m_attributeBoolManager->setValue(prop, value);
1508}
1518void FunctionTreeView::setVectorAttribute(std::string const &attrName, std::vector<double> &value) {
1519 UNUSED_ARG(attrName);
1521}
1526double FunctionTreeView::getParameter(std::string const &parameterName) const {
1527 auto const *prop = getParameterProperty(parameterName);
1528 return m_parameterManager->value(prop);
1529}
1534IFunction::Attribute FunctionTreeView::getAttribute(std::string const &attrName) const {
1535 auto prop = getAttributeProperty(attrName);
1536 if (isDoubleAttribute(prop)) {
1538 } else if (isIntAttribute(prop)) {
1539 return IFunction::Attribute(m_attributeIntManager->value(prop));
1540 } else if (isStringAttribute(prop)) {
1541 return IFunction::Attribute(m_attributeStringManager->value(prop).toStdString());
1542 } else if (isBoolAttribute(prop)) {
1543 return IFunction::Attribute(m_attributeBoolManager->value(prop));
1544 } else if (isVectorAttribute(prop)) {
1546 } else {
1547 throw std::runtime_error("Unknown function attribute " + attrName);
1548 }
1549}
1551QtProperty *FunctionTreeView::getParameterProperty(std::string const &parameterName) const {
1552 std::string index, name;
1553 std::tie(index, name) = splitParameterName(parameterName);
1554 if (auto const *prop = getFunctionProperty(index)) {
1555 const auto children = prop->subProperties();
1556 const auto it = std::find_if(children.cbegin(), children.cend(), [&](const auto &child) {
1557 return isParameter(child) && child->propertyName().toStdString() == name;
1558 });
1559 if (it != children.cend()) {
1560 return *it;
1561 }
1562 }
1563 std::string message = "Unknown function parameter " + parameterName +
1564 "\n\n This may happen if there is a CompositeFunction "
1565 "containing only one function.";
1566 throw std::runtime_error(message);
1567}
1569QtProperty *FunctionTreeView::getAttributeProperty(std::string const &attributeName) const {
1570 std::string index, name;
1571 const QtProperty *prop;
1572 std::tie(index, name) = splitParameterName(attributeName);
1573 if (!variableIsPrefixed(attributeName)) {
1574 // If variable is unprefixed then we are on the top level composite
1575 // function so grab first property from the tree
1576 prop = m_browser->properties()[0];
1577 } else {
1578 prop = getFunctionProperty(index);
1579 }
1580 const auto children = prop->subProperties();
1581 const auto it = std::find_if(children.cbegin(), children.cend(), [&](const auto &child) {
1582 return isAttribute(child) && child->propertyName().toStdString() == name;
1583 });
1584 if (it != children.cend()) {
1585 return *it;
1586 }
1587 std::string message = "Unknown function attribute " + attributeName;
1588 throw std::runtime_error(message);
1589}
1590
1593QtProperty *FunctionTreeView::getParentParameterProperty(QtProperty *prop) const {
1594 const auto itProp =
1595 std::find_if(m_ties.cbegin(), m_ties.cend(), [&prop](const auto &tie) { return tie.tieProp == prop; });
1596 if (itProp != m_ties.cend())
1597 return (*itProp).paramProp;
1598
1599 const auto itConstr = std::find_if(m_constraints.cbegin(), m_constraints.cend(), [&prop](const auto &constraint) {
1600 return (constraint.lower == prop || constraint.upper == prop);
1601 });
1602 if (itConstr != m_constraints.cend())
1603 return (*itConstr).paramProp;
1604 throw std::logic_error("QtProperty " + prop->propertyName().toStdString() +
1605 " is not a child of a property for any function parameter.");
1606}
1607
1612 auto item = m_browser->currentItem();
1613 if (!item)
1614 return;
1615 QtProperty *prop = item->property();
1616 if (!isFunction(prop))
1617 return;
1618 auto const functionString = getFunction(prop)->asString();
1619 auto const functionIndex = getIndex(prop);
1620 removeProperty(prop);
1622
1623 // After removing a function we could end up with
1624 // a CompositeFunction with only one function
1625 // In this case, the function should be kept but
1626 // the composite function should be removed
1627 auto props = m_browser->properties();
1628 auto globalParameters = getGlobalParameters();
1629 if (!props.isEmpty()) {
1630 // The function browser is not empty
1631
1632 // Check if the current function in the browser is a
1633 // composite function
1634 auto topProp = props[0];
1635 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(getFunction(topProp));
1636 if (cf) {
1637 // If it is a composite function
1638 // check that there are more than one function
1639 // which means more than two subproperties
1640
1641 if (cf->nFunctions() == 1 && cf->name() == "CompositeFunction") {
1642 // If only one function remains, remove the composite function:
1643 // Temporary copy the remaining function
1644 auto func = getFunction(props[0]->subProperties()[1]);
1645 std::transform(globalParameters.begin(), globalParameters.end(), globalParameters.begin(),
1646 m_multiDomainFunctionPrefix.empty() ? removePrefix : removeEmbeddedPrefix);
1647 // Remove the composite function
1648 m_browser->removeProperty(topProp);
1649 // Add the temporary stored function
1650 setFunction(func);
1651 }
1652 }
1653 }
1654 emit functionRemovedString(functionString);
1655 emit functionRemoved(functionIndex);
1656 setGlobalParameters(globalParameters);
1657 emit globalsChanged(globalParameters);
1658}
1659
1664 auto item = m_browser->currentItem();
1665 if (!item)
1666 return;
1667 QtProperty *prop = item->property();
1668 if (!isParameter(prop))
1669 return;
1670 auto tie = QString::number(getParameter(prop)).toStdString();
1671 addTieProperty(prop, tie);
1672 emit parameterTieChanged(getParameterName(prop), tie);
1673}
1674
1676QtProperty *FunctionTreeView::getTieProperty(QtProperty *prop) const {
1677 const auto children = prop->subProperties();
1678 const auto it = std::find_if(children.cbegin(), children.cend(),
1679 [](const auto &child) { return child->propertyName() == "Tie"; });
1680 if (it != children.cend()) {
1681 return *it;
1682 }
1683 return nullptr;
1684}
1685
1690 auto item = m_browser->currentItem();
1691 if (!item)
1692 return;
1693 QtProperty *prop = item->property();
1694 if (!isParameter(prop))
1695 return;
1696 auto tieProp = getTieProperty(prop);
1697 if (tieProp) {
1698 removeProperty(tieProp);
1699 }
1700 emit parameterTieChanged(getParameterName(prop), "");
1701}
1702
1707 auto item = m_browser->currentItem();
1708 if (!item)
1709 return;
1710 QtProperty *prop = item->property();
1711 if (!isParameter(prop))
1712 return;
1713
1714 bool ok;
1715 auto tie = QInputDialog::getText(this, "Add a tie", "Tie:", QLineEdit::Normal, "", &ok).toStdString();
1716 if (ok && !tie.empty()) {
1717 try {
1718 addTieProperty(prop, tie);
1719 emit parameterTieChanged(getParameterName(prop), tie);
1721 QMessageBox::critical(this, "Mantid - Error", "Syntax errors found in tie: " + QString::fromStdString(tie));
1722 } catch (std::exception &e) {
1723 QMessageBox::critical(this, "Mantid - Error", QString::fromLatin1("Errors found in tie: ") + e.what());
1724 }
1725 }
1726}
1727
1732 auto funStr = QApplication::clipboard()->text().toStdString();
1733 if (funStr.empty())
1734 return;
1735 try {
1736 auto fun = Mantid::API::FunctionFactory::Instance().createInitialized(funStr);
1737 if (!fun)
1738 return;
1739 this->setFunction(fun);
1740 emit functionReplaced(funStr);
1741 } catch (...) {
1742 // text in the clipboard isn't a function definition
1743 QMessageBox::warning(this, "Mantid - Warning",
1744 "Text in the clipboard isn't a function definition"
1745 " or contains errors.");
1746 }
1747}
1748
1753
1758 auto item = m_browser->currentItem();
1759 if (!item)
1760 return;
1761 QtProperty *prop = item->property();
1762 if (!isParameter(prop))
1763 return;
1764 std::string functionIndex, name;
1765 std::tie(functionIndex, name) = splitParameterName(getParameterName(prop));
1766 auto const value = QString::number(getParameter(prop)).toStdString();
1767 auto const constraint = value + "<" + name + "<" + value;
1768 addConstraintProperties(prop, constraint);
1769 emit parameterConstraintAdded(functionIndex, constraint);
1770}
1771
1776 auto item = m_browser->currentItem();
1777 if (!item)
1778 return;
1779 QtProperty *prop = item->property();
1780 if (!isParameter(prop))
1781 return;
1782 double val = getParameter(prop);
1783 std::string functionIndex, name;
1784 std::tie(functionIndex, name) = splitParameterName(getParameterName(prop));
1785 auto const constraint =
1786 QString::number(val * 0.9).toStdString() + "<" + name + "<" + QString::number(val * 1.1).toStdString();
1787 addConstraintProperties(prop, constraint);
1788 emit parameterConstraintAdded(functionIndex, constraint);
1789}
1790
1795 auto item = m_browser->currentItem();
1796 if (!item)
1797 return;
1798 QtProperty *prop = item->property();
1799 if (!isParameter(prop))
1800 return;
1801 double val = getParameter(prop);
1802 std::string functionIndex, name;
1803 std::tie(functionIndex, name) = splitParameterName(getParameterName(prop));
1804 auto const constraint =
1805 QString::number(val * 0.5).toStdString() + "<" + name + "<" + QString::number(val * 1.5).toStdString();
1806 addConstraintProperties(prop, constraint);
1807 emit parameterConstraintAdded(functionIndex, constraint);
1808}
1809
1811 auto props = prop->subProperties();
1812 foreach (QtProperty *p, props) {
1813 if (isConstraint(p)) {
1814 removeProperty(p);
1815 }
1816 }
1817}
1818
1823 auto item = m_browser->currentItem();
1824 if (!item)
1825 return;
1826 QtProperty *prop = item->property();
1827 if (!isParameter(prop))
1828 return;
1831}
1832
1837 auto item = m_browser->currentItem();
1838 if (!item)
1839 return;
1840 QtProperty *prop = item->property();
1841 if (!isConstraint(prop))
1842 return;
1843 auto paramProp = getParentParameterProperty(prop);
1844 removeProperty(prop);
1845 auto const parName = getParameterName(paramProp);
1846 emit parameterConstraintRemoved(parName);
1847 std::string functionIndex, constraint;
1848 std::tie(functionIndex, constraint) = getFunctionAndConstraint(paramProp);
1849 if (!constraint.empty()) {
1850 emit parameterConstraintAdded(functionIndex, constraint);
1851 }
1852}
1857 auto item = m_browser->currentItem();
1858 if (!item)
1859 return IFunction_sptr();
1860 QtProperty *prop = item->property();
1861 if (!isFunction(prop))
1862 return IFunction_sptr();
1863 return getFunction(prop);
1864}
1868void FunctionTreeView::showFunctionHelp(std::string const &functionName) const {
1869 API::InterfaceManager().showFitFunctionHelp(QString::fromStdString(functionName));
1870}
1871
1872std::pair<std::string, std::string> FunctionTreeView::getFunctionAndConstraint(QtProperty *prop) const {
1873 auto const parName = getParameterName(prop);
1874 double lower = Mantid::EMPTY_DBL();
1875 double upper = Mantid::EMPTY_DBL();
1876 for (auto const *p : prop->subProperties()) {
1877 if (p->propertyName() == "LowerBound")
1878 lower = m_constraintManager->value(p);
1879 if (p->propertyName() == "UpperBound")
1880 upper = m_constraintManager->value(p);
1881 }
1883 std::string functionIndex, name;
1884 std::tie(functionIndex, name) = splitParameterName(parName);
1885 return std::make_pair(functionIndex, getConstraint(name, lower, upper));
1886 }
1887 return std::make_pair("", "");
1888}
1889
1896 auto attributeName = getAttributeName(prop);
1897 // Some attributes require the function to be fully reconstructed, in this
1898 // case we'd need to emit a function replaced signal. If its not one of these
1899 // attributes emit an attributeValueChanged signal.
1900 try {
1901 if (std::find(REQUIRESRECONSTRUCTIONATTRIBUTES.begin(), REQUIRESRECONSTRUCTIONATTRIBUTES.end(),
1902 removePrefix(attributeName)) != REQUIRESRECONSTRUCTIONATTRIBUTES.end()) {
1903 auto funProp = m_properties[prop].parent;
1904 if (!funProp)
1905 return;
1906 auto fun = getFunction(funProp, true);
1907
1908 // delete and recreate all function's properties (attributes, parameters,
1909 // etc)
1910 setFunction(funProp, fun);
1913 emit functionReplaced(getFunction()->asString());
1914 }
1915 } else {
1917 emit attributePropertyChanged(attributeName);
1918 }
1919 }
1920 } catch (std::exception &expt) {
1921 QMessageBox::critical(this, "Mantid - Error", QString::fromStdString(expt.what()));
1922 }
1923}
1924
1929 QtProperty *vectorProp = m_properties[prop].parent;
1930 if (!vectorProp)
1931 throw std::logic_error("FunctionTreeView: inconsistency in vector "
1932 "properties.\nAttribute property not found.");
1933 auto funProp = m_properties[vectorProp].parent;
1934 if (!funProp)
1935 throw std::logic_error("FunctionTreeView: inconsistency in vector "
1936 "properties.\nFunction property not found.");
1937 auto fun = getFunction(funProp, true);
1938 if (!fun)
1939 throw std::logic_error("FunctionTreeView: inconsistency in vector "
1940 "properties.\nFunction undefined.");
1941 auto attName = vectorProp->propertyName().toStdString();
1942 auto attribute = fun->getAttribute(attName).asVector();
1943 auto newSize = m_attributeSizeManager->value(prop);
1944 if (newSize < 0)
1945 newSize = 0;
1946 if (attribute.size() != static_cast<size_t>(newSize)) {
1947 if (newSize == 0) {
1948 attribute.clear();
1949 } else {
1950 attribute.resize(newSize);
1951 }
1952 fun->setAttributeValue(attName, attribute);
1953 setFunction(funProp, fun);
1955 }
1956}
1957
1964 QtProperty *vectorProp = m_properties[prop].parent;
1965 if (!vectorProp)
1966 throw std::runtime_error("FunctionTreeView: inconsistency in vector properties.");
1967 attributeChanged(vectorProp);
1968}
1969
1971 auto tieProp = getTieProperty(prop);
1972 if (tieProp && !tieProp->isEnabled()) {
1973 // it is a fixed tie
1974 QString newTie = QString("%1=%2").arg(prop->propertyName()).arg(m_parameterManager->value(prop));
1975 if (!newTie.isEmpty()) {
1976 m_tieManager->setValue(tieProp, newTie);
1977 }
1978 }
1980 setErrorsEnabled(false);
1982 }
1983}
1984
1986void FunctionTreeView::tieChanged(QtProperty *prop) {
1987 for (const auto &atie : m_ties) {
1988 if (atie.tieProp == prop) {
1989 emit parameterTieChanged(getParameterName(prop), getTie(prop).toStdString());
1990 }
1991 }
1992}
1993
1996 for (const auto &constr : m_constraints) {
1997 const bool isLower = constr.lower == prop;
1998 const bool isUpper = constr.upper == prop;
1999 if (isLower || isUpper) {
2000 auto paramProp = getParentParameterProperty(prop);
2001 std::string functionIndex, constraint;
2002 std::tie(functionIndex, constraint) = getFunctionAndConstraint(paramProp);
2003 if (!constraint.empty()) {
2004 emit parameterConstraintAdded(functionIndex, constraint);
2005 return; // No need to keep looping as found constraint changed
2006 }
2007 }
2008 }
2009}
2010
2012 emit localParameterButtonClicked(getIndex(prop) + prop->propertyName().toStdString());
2013}
2014
2015bool FunctionTreeView::hasFunction() const { return !m_functionManager->properties().isEmpty(); }
2016
2021void FunctionTreeView::setColumnSizes(int s0, int s1, int s2) { m_browser->setColumnSizes(s0, s1, s2); }
2022
2023void FunctionTreeView::setStretchLastColumn(bool stretch) { m_browser->setStretchLastColumn(stretch); }
2024
2027// Hide global column
2029
2038void FunctionTreeView::setMultiDomainFunctionPrefix(std::string const &functionPrefix) {
2039 m_multiDomainFunctionPrefix = functionPrefix;
2040}
2041
2049void FunctionTreeView::setGlobalTies(std::vector<GlobalTie> const &globalTies) { m_globalTies = globalTies; }
2050
2054void FunctionTreeView::globalChanged(QtProperty *, const QString &, bool) {
2056}
2057
2062void FunctionTreeView::setErrorsEnabled(bool enabled) { m_parameterManager->setErrorsEnabled(enabled); }
2063
2068
2069std::optional<std::string> FunctionTreeView::currentFunctionIndex() const { return m_currentFunctionIndex; }
2070
2072 std::optional<std::string> newIndex;
2073
2074 if (auto item = m_browser->currentItem()) {
2075 auto prop = item->property();
2076 newIndex = getIndex(prop);
2077 }
2078
2079 if (m_currentFunctionIndex != newIndex) {
2080 m_currentFunctionIndex = newIndex;
2082 }
2083}
2084
2085void FunctionTreeView::setParameterTie(std::string const &parameterName, std::string const &tie) {
2086 auto paramProp = getParameterProperty(parameterName);
2087 auto tieProp = getTieProperty(paramProp);
2088 if (!tie.empty()) {
2089 if (tieProp) {
2090 m_tieManager->setValue(tieProp, QString::fromStdString(tie));
2091 } else {
2092 addTieProperty(paramProp, tie);
2093 }
2094 } else if (tieProp) {
2095 removeProperty(tieProp);
2096 }
2097}
2098
2099void FunctionTreeView::setParameterConstraint(std::string const &parameterName, std::string const &constraint) {
2100 auto paramProp = getParameterProperty(parameterName);
2101 if (hasConstraint(paramProp)) {
2102 removeConstraintsQuiet(paramProp);
2103 }
2104 addConstraintProperties(paramProp, constraint);
2105}
2106
2107std::vector<std::string> FunctionTreeView::getGlobalParameters() const {
2108 std::vector<std::string> globals;
2109 for (const auto &prop : m_properties) {
2110 if (prop.prop->checkOption(globalOptionName)) {
2111 auto const name = getParameterName(prop.prop);
2112 globals.emplace_back(name);
2113 }
2114 }
2115 return globals;
2116}
2117
2118void FunctionTreeView::setGlobalParameters(const std::vector<std::string> &globals) {
2119 for (const auto &ap : m_properties) {
2120 auto prop = ap.prop;
2121 if (!prop->hasOption(globalOptionName))
2122 continue;
2123
2124 auto const parameterName = getParameterName(prop);
2125 auto const isGlobal = std::any_of(globals.cbegin(), globals.cend(), [&](std::string const &global) {
2126 return m_multiDomainFunctionPrefix + global == parameterName;
2127 });
2128 prop->setOption(globalOptionName, isGlobal);
2129 }
2130}
2131
2132QTreeWidgetItem *FunctionTreeView::getPropertyWidgetItem(QtProperty *prop) const {
2133 return m_browser->getItemWidget(m_properties.find(prop)->item);
2134}
2135
2136QRect FunctionTreeView::visualItemRect(QtProperty *prop) const {
2137 if (!prop)
2138 return QRect();
2139 auto item = getPropertyWidgetItem(prop);
2140 return item->treeWidget()->visualItemRect(item);
2141}
2142
2144 QRect rect;
2145 try {
2147 } catch (std::exception &) {
2148 }
2149 return rect;
2150}
2151
2153 QRect rect;
2154 try {
2156 } catch (std::exception &) {
2157 }
2158 return rect;
2159}
2160
2161QWidget *FunctionTreeView::getParamWidget(std::string const &parameterName) const {
2162 try {
2163 auto item = getPropertyWidgetItem(getParameterProperty(parameterName));
2164 return item->treeWidget()->itemWidget(item, 1);
2165 } catch (std::exception &) {
2166 }
2167 return nullptr;
2168}
2169
2170QTreeWidget *FunctionTreeView::treeWidget() const { return m_browser->treeWidget(); }
2171
2172QtTreePropertyBrowser *FunctionTreeView::treeBrowser() { return m_browser; }
2173
2174DoubleDialogEditorFactory *FunctionTreeView::doubleEditorFactory() { return m_doubleEditorFactory; }
2175
2176} // 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:48
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.