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(const std::string &name) { return std::regex_match(name, PREFIX_REGEX); }
61
62QString insertPrefix(const QString &param) {
63 return param.left(param.indexOf(".") + 1) + "f0." + param.right(param.size() - param.indexOf(".") - 1);
64}
65
66QString addPrefix(const QString &param) { return "f0." + param; }
67
68QString removeEmbeddedPrefix(const QString &param) {
69 if (variableIsPrefixed(param.toStdString())) {
70 const auto paramSplit = param.split(".");
71 return paramSplit[0] + "." + paramSplit[paramSplit.size() - 1];
72 } else {
73 return param;
74 }
75}
76
77QString removePrefix(const QString &param) {
78 if (variableIsPrefixed(param.toStdString())) {
79 const auto paramSplit = param.split(".");
80 return paramSplit[paramSplit.size() - 1];
81 } else {
82 return param;
83 }
84}
85
86bool containsOneOf(std::string const &str, std::string const &delimiters) {
87 return !str.empty() && str.find_first_of(delimiters) != std::string::npos;
88}
89
90// These attributes require the function to be fully reconstructed, as a
91// different number of properties will be required
92const std::vector<QString> REQUIRESRECONSTRUCTIONATTRIBUTES = {QString("n"), QString("Formula")};
93} // namespace
94
96
104FunctionTreeView::FunctionTreeView(QWidget *parent, bool multi, std::vector<std::string> categories)
105 : IFunctionView(parent), m_multiDataset(multi), m_multiDomainFunctionPrefix(),
106 m_allowedCategories(std::move(categories)), m_selectFunctionDialog(nullptr)
107
108{
109 // create m_browser
112
113 QVBoxLayout *layout = new QVBoxLayout(this);
114 layout->setContentsMargins(0, 0, 0, 0);
115 layout->addWidget(m_browser);
116}
117
122 m_browser->unsetFactoryForManager(m_parameterManager);
123 m_browser->unsetFactoryForManager(m_attributeStringManager);
124 m_browser->unsetFactoryForManager(m_attributeDoubleManager);
125 m_browser->unsetFactoryForManager(m_attributeIntManager);
126 m_browser->unsetFactoryForManager(m_attributeBoolManager);
127 m_browser->unsetFactoryForManager(m_indexManager);
128 m_browser->unsetFactoryForManager(m_tieManager);
129 m_browser->unsetFactoryForManager(m_constraintManager);
130 m_browser->unsetFactoryForManager(m_filenameManager);
131 m_browser->unsetFactoryForManager(m_formulaManager);
132 m_browser->unsetFactoryForManager(m_workspaceManager);
133 m_browser->unsetFactoryForManager(m_attributeSizeManager);
134 m_browser->unsetFactoryForManager(m_attributeVectorDoubleManager);
135}
136
141 QStringList options;
142 if (m_multiDataset) {
143 options << globalOptionName;
144 }
145 m_browser = new QtTreePropertyBrowser(this, options);
146
147 /* Create property managers: they create, own properties, get and set values
148 */
149 m_functionManager = new QtGroupPropertyManager(this);
150 m_parameterManager = new ParameterPropertyManager(this);
151 m_attributeStringManager = new QtStringPropertyManager(this);
152 m_attributeDoubleManager = new QtDoublePropertyManager(this);
153 m_attributeIntManager = new QtIntPropertyManager(this);
154 m_attributeBoolManager = new QtBoolPropertyManager(this);
155 m_indexManager = new QtStringPropertyManager(this);
156 m_tieManager = new QtStringPropertyManager(this);
157 m_constraintManager = new QtDoublePropertyManager(this);
158 m_filenameManager = new QtStringPropertyManager(this);
159 m_formulaManager = new QtStringPropertyManager(this);
160 m_workspaceManager = new QtStringPropertyManager(this);
161 m_attributeVectorManager = new QtGroupPropertyManager(this);
162 m_attributeSizeManager = new QtIntPropertyManager(this);
163 m_attributeVectorDoubleManager = new QtDoublePropertyManager(this);
164
165 // create editor factories
166 QtSpinBoxFactory *spinBoxFactory = new QtSpinBoxFactory(this);
167 DoubleEditorFactory *doubleEditorFactory = new DoubleEditorFactory(this);
168 ParameterEditorFactory *paramEditorFactory = new ParameterEditorFactory(this);
169
170 QtAbstractEditorFactory<ParameterPropertyManager> *parameterEditorFactory(nullptr);
171 if (m_multiDataset) {
172 m_doubleEditorFactory = new DoubleDialogEditorFactory(this);
173 auto compositeFactory = new CompositeEditorFactory<ParameterPropertyManager>(this, m_doubleEditorFactory);
174 compositeFactory->setSecondaryFactory(globalOptionName, paramEditorFactory);
175 parameterEditorFactory = compositeFactory;
176 connect(m_doubleEditorFactory, SIGNAL(buttonClicked(QtProperty *)), this,
177 SLOT(parameterButtonClicked(QtProperty *)));
178 connect(m_doubleEditorFactory, SIGNAL(closeEditor()), m_browser, SLOT(closeEditor()));
179 } else {
180 parameterEditorFactory = paramEditorFactory;
181 }
182
183 QtLineEditFactory *lineEditFactory = new QtLineEditFactory(this);
184 QtCheckBoxFactory *checkBoxFactory = new QtCheckBoxFactory(this);
185 FilenameDialogEditorFactory *filenameDialogEditorFactory = new FilenameDialogEditorFactory(this);
186 FormulaDialogEditorFactory *formulaDialogEditFactory = new FormulaDialogEditorFactory(this);
187 WorkspaceEditorFactory *workspaceEditorFactory = new WorkspaceEditorFactory(this);
188
189 // assign factories to property managers
190 m_browser->setFactoryForManager(m_parameterManager, parameterEditorFactory);
191 m_browser->setFactoryForManager(m_attributeStringManager, lineEditFactory);
193 m_browser->setFactoryForManager(m_attributeIntManager, spinBoxFactory);
194 m_browser->setFactoryForManager(m_attributeBoolManager, checkBoxFactory);
195 m_browser->setFactoryForManager(m_indexManager, lineEditFactory);
196 m_browser->setFactoryForManager(m_tieManager, lineEditFactory);
197 m_browser->setFactoryForManager(m_constraintManager, doubleEditorFactory);
198 m_browser->setFactoryForManager(m_filenameManager, filenameDialogEditorFactory);
199 m_browser->setFactoryForManager(m_formulaManager, formulaDialogEditFactory);
200 m_browser->setFactoryForManager(m_workspaceManager, workspaceEditorFactory);
201 m_browser->setFactoryForManager(m_attributeSizeManager, spinBoxFactory);
203
204 m_browser->setContextMenuPolicy(Qt::CustomContextMenu);
205 connect(m_browser, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(popupMenu(const QPoint &)));
206 connect(m_browser, SIGNAL(optionChanged(QtProperty *, const QString &, bool)), this,
207 SLOT(globalChanged(QtProperty *, const QString &, bool)));
208
209 connect(m_attributeStringManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
210 connect(m_attributeDoubleManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
211 connect(m_attributeIntManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
212 connect(m_attributeBoolManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
213 connect(m_formulaManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
214 connect(m_filenameManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
215 connect(m_workspaceManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(attributeChanged(QtProperty *)));
216 connect(m_attributeVectorDoubleManager, SIGNAL(propertyChanged(QtProperty *)), this,
217 SLOT(attributeVectorDoubleChanged(QtProperty *)));
218 connect(m_attributeSizeManager, SIGNAL(propertyChanged(QtProperty *)), this,
219 SLOT(attributeVectorSizeChanged(QtProperty *)));
220 connect(m_tieManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(tieChanged(QtProperty *)));
221 connect(m_constraintManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(constraintChanged(QtProperty *)));
222 connect(m_parameterManager, SIGNAL(valueChanged(QtProperty *, double)), SLOT(parameterPropertyChanged(QtProperty *)));
223
224 connect(m_browser, SIGNAL(currentItemChanged(QtBrowserItem *)), SLOT(updateCurrentFunctionIndex()));
225
226 m_browser->setFocusPolicy(Qt::StrongFocus);
227}
228
233 m_actionAddFunction = new QAction("Add function", this);
234 m_actionAddFunction->setObjectName("add_function");
235 connect(m_actionAddFunction, SIGNAL(triggered()), this, SLOT(addFunctionBegin()));
236
237 m_actionRemoveFunction = new QAction("Remove function", this);
238 m_actionRemoveFunction->setObjectName("remove_function");
239 connect(m_actionRemoveFunction, SIGNAL(triggered()), this, SLOT(removeFunction()));
240
241 m_actionFixParameter = new QAction("Fix", this);
242 connect(m_actionFixParameter, SIGNAL(triggered()), this, SLOT(fixParameter()));
243
244 m_actionRemoveTie = new QAction("Remove tie", this);
245 connect(m_actionRemoveTie, SIGNAL(triggered()), this, SLOT(removeTie()));
246
247 m_actionAddTie = new QAction("Add tie", this);
248 connect(m_actionAddTie, SIGNAL(triggered()), this, SLOT(addTie()));
249
250 m_actionFromClipboard = new QAction("Paste from clipboard", this);
251 m_actionFromClipboard->setObjectName("paste_from_clipboard");
252 connect(m_actionFromClipboard, SIGNAL(triggered()), this, SLOT(pasteFromClipboard()));
253
254 m_actionToClipboard = new QAction("Copy to clipboard", this);
255 m_actionToClipboard->setObjectName("copy_to_clipboard");
256 connect(m_actionToClipboard, SIGNAL(triggered()), this, SLOT(copyToClipboard()));
257
258 m_actionConstraints = new QAction("Custom", this);
259 connect(m_actionConstraints, SIGNAL(triggered()), this, SLOT(addConstraints()));
260
261 m_actionConstraints10 = new QAction("10%", this);
262 connect(m_actionConstraints10, SIGNAL(triggered()), this, SLOT(addConstraints10()));
263
264 m_actionConstraints50 = new QAction("50%", this);
265 connect(m_actionConstraints50, SIGNAL(triggered()), this, SLOT(addConstraints50()));
266
267 m_actionRemoveConstraints = new QAction("Remove constraints", this);
268 connect(m_actionRemoveConstraints, SIGNAL(triggered()), this, SLOT(removeConstraints()));
269
270 m_actionRemoveConstraint = new QAction("Remove", this);
271 connect(m_actionRemoveConstraint, SIGNAL(triggered()), this, SLOT(removeConstraint()));
272
273 m_actionFunctionHelp = new QAction("Help", this);
274 connect(m_actionFunctionHelp, SIGNAL(triggered()), this, SIGNAL(functionHelpRequest()));
275
276 setErrorsEnabled(false);
277}
278
283 m_browser->clear();
284 m_properties.clear();
285}
286
292 clear();
293 if (fun) {
294 addFunction(nullptr, fun);
295 }
296}
297
303FunctionTreeView::AProperty FunctionTreeView::addProperty(QtProperty *parent, QtProperty *subproperty) {
304 AProperty ap;
305 ap.prop = subproperty;
306 if (parent == nullptr) {
307 ap.item = m_browser->addProperty(subproperty);
308 } else {
309 parent->addSubProperty(subproperty);
310 auto items = m_browser->items(subproperty);
311 if (items.isEmpty()) {
312 throw std::runtime_error("Unexpected error in FunctionTreeView [1]");
313 }
314 ap.item = items[0];
315 }
316 ap.parent = parent;
317 m_properties[subproperty] = ap;
318 return ap;
319}
320
325void FunctionTreeView::removeProperty(QtProperty *prop) {
326 auto p = m_properties.find(prop);
327 if (p == m_properties.end())
328 return;
329 AProperty ap = *p;
330
331 // remove references to the children
332 auto children = prop->subProperties();
333 foreach (QtProperty *child, children) { removeProperty(child); }
334 m_properties.erase(p);
335
336 if (isFunction(prop)) {
337 m_ties.remove(prop);
338 }
339
340 if (isTie(prop)) { //
341 for (auto it = m_ties.begin(); it != m_ties.end(); ++it) {
342 if (it.value().tieProp == prop) {
343 m_ties.erase(it);
344 break;
345 }
346 }
347 }
348
349 if (isConstraint(prop)) {
350 for (auto it = m_constraints.begin(); it != m_constraints.end(); ++it) {
351 auto &cp = it.value();
352 if (cp.lower == prop) {
353 if (!cp.upper) {
354 m_constraints.erase(it);
355 } else {
356 cp.lower = nullptr;
357 }
358 break;
359 } else if (cp.upper == prop) {
360 if (!cp.lower) {
361 m_constraints.erase(it);
362 } else {
363 cp.upper = nullptr;
364 }
365 break;
366 }
367 }
368 }
369
370 // remove property from Qt browser
371 if (ap.parent) {
372 ap.parent->removeSubProperty(prop);
373 } else {
374 m_browser->removeProperty(prop);
375 }
376 delete prop;
377}
378
385FunctionTreeView::AProperty FunctionTreeView::addFunctionProperty(QtProperty *parent, const QString &funName) {
386 // check that parent is a function property
387 if (parent && dynamic_cast<QtAbstractPropertyManager *>(m_functionManager) != parent->propertyManager()) {
388 throw std::runtime_error("Unexpected error in FunctionTreeView [2]");
389 }
390 QtProperty *prop = m_functionManager->addProperty(funName);
391 return addProperty(parent, prop);
392}
393
401FunctionTreeView::AProperty FunctionTreeView::addParameterProperty(QtProperty *parent, const QString &paramName,
402 const QString &paramDesc, double paramValue) {
403 // check that parent is a function property
404 if (!parent || dynamic_cast<QtAbstractPropertyManager *>(m_functionManager) != parent->propertyManager()) {
405 throw std::runtime_error("Unexpected error in FunctionTreeView [3]");
406 }
407 QtProperty *prop = m_parameterManager->addProperty(paramName);
408 m_parameterManager->blockSignals(true);
409 m_parameterManager->setDecimals(prop, 6);
410 m_parameterManager->setValue(prop, paramValue);
411 m_parameterManager->setDescription(prop, paramDesc.toStdString());
412 m_parameterManager->blockSignals(false);
413
414 if (m_multiDataset) {
415 prop->setOption(globalOptionName, false);
416 }
417 return addProperty(parent, prop);
418}
419
426 auto children = prop->subProperties();
427 foreach (QtProperty *child, children) { removeProperty(child); }
428 // m_localParameterValues.clear();
429 if (!m_multiDomainFunctionPrefix.isEmpty())
432}
433
440 if (!fun)
441 return false;
442 if (!prop) {
443 AProperty ap = addFunctionProperty(nullptr, QString::fromStdString(fun->name()));
444 setFunction(ap.prop, fun);
445 } else {
447 if (!parentFun)
448 return false;
449 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(parentFun);
450 if (!cf) {
451 throw std::logic_error("FunctionTreeView: CompositeFunction is expected for addFunction");
452 }
453 try {
454 cf->addFunction(fun);
455 } catch (const std::exception &e) {
456 QMessageBox::warning(this, "Mantid - Warning", QString("Cannot Add function:\n\n%1").arg(e.what()));
457 return false;
458 }
459 setFunction(prop, cf);
460 }
462 return true;
463}
464
470 : public Mantid::API::IFunction::ConstAttributeVisitor<FunctionTreeView::AProperty> {
471public:
472 CreateAttributePropertyForFunctionTreeView(FunctionTreeView *browser, QtProperty *parent, const QString &attName)
473 : m_browser(browser), m_parent(parent), m_attName(attName) {
474 // check that parent is a function property
475 if (!m_parent ||
476 dynamic_cast<QtAbstractPropertyManager *>(m_browser->m_functionManager) != m_parent->propertyManager()) {
477 throw std::runtime_error("Unexpected error in FunctionTreeView [4]");
478 }
479 }
480
481protected:
483 FunctionTreeView::AProperty apply(const std::string &str) const override {
484 QtProperty *prop = nullptr;
485 if (m_attName.indexOf("FileName") != -1) {
486 m_browser->m_filenameManager->blockSignals(true);
487 prop = m_browser->m_filenameManager->addProperty(m_attName);
488 m_browser->m_filenameManager->setValue(prop, QString::fromStdString(str));
489 m_browser->m_filenameManager->blockSignals(false);
490 } else if (m_attName.indexOf("Formula") != -1) {
491 m_browser->m_formulaManager->blockSignals(true);
492 prop = m_browser->m_formulaManager->addProperty(m_attName);
493 m_browser->m_formulaManager->setValue(prop, QString::fromStdString(str));
494 m_browser->m_formulaManager->blockSignals(false);
495 } else if (m_attName.indexOf("Workspace") != -1) {
496 m_browser->m_workspaceManager->blockSignals(true);
497 prop = m_browser->m_workspaceManager->addProperty(m_attName);
498 m_browser->m_workspaceManager->setValue(prop, QString::fromStdString(str));
499 m_browser->m_workspaceManager->blockSignals(false);
500 } else {
501 m_browser->m_attributeStringManager->blockSignals(true);
502 prop = m_browser->m_attributeStringManager->addProperty(m_attName);
503 m_browser->m_attributeStringManager->setValue(prop, QString::fromStdString(str));
504 m_browser->m_attributeStringManager->blockSignals(false);
505 }
506 return m_browser->addProperty(m_parent, prop);
507 }
509 FunctionTreeView::AProperty apply(const double &d) const override {
510 m_browser->m_attributeDoubleManager->blockSignals(true);
511 QtProperty *prop = m_browser->m_attributeDoubleManager->addProperty(m_attName);
512 m_browser->m_attributeDoubleManager->setValue(prop, d);
513 m_browser->m_attributeDoubleManager->blockSignals(false);
514 return m_browser->addProperty(m_parent, prop);
515 }
517 FunctionTreeView::AProperty apply(const int &i) const override {
518 m_browser->m_attributeIntManager->blockSignals(true);
519 QtProperty *prop = m_browser->m_attributeIntManager->addProperty(m_attName);
520 m_browser->m_attributeIntManager->setValue(prop, i);
521 m_browser->m_attributeIntManager->blockSignals(false);
522 return m_browser->addProperty(m_parent, prop);
523 }
525 FunctionTreeView::AProperty apply(const bool &b) const override {
526 m_browser->m_attributeBoolManager->blockSignals(true);
527 QtProperty *prop = m_browser->m_attributeBoolManager->addProperty(m_attName);
528 m_browser->m_attributeBoolManager->setValue(prop, b);
529 m_browser->m_attributeBoolManager->blockSignals(false);
530 return m_browser->addProperty(m_parent, prop);
531 }
533 FunctionTreeView::AProperty apply(const std::vector<double> &v) const override {
534 QtProperty *prop = m_browser->m_attributeVectorManager->addProperty(m_attName);
536
537 m_browser->m_attributeSizeManager->blockSignals(true);
538 QtProperty *sizeProp = m_browser->m_attributeSizeManager->addProperty("Size");
539 m_browser->m_attributeSizeManager->setValue(sizeProp, static_cast<int>(v.size()));
540 m_browser->addProperty(prop, sizeProp);
541 m_browser->m_attributeSizeManager->blockSignals(false);
542
543 m_browser->m_attributeVectorDoubleManager->blockSignals(true);
544 QString parName = "value[%1]";
545 for (size_t i = 0; i < v.size(); ++i) {
546 QtProperty *dprop = m_browser->m_attributeVectorDoubleManager->addProperty(parName.arg(i));
547 m_browser->m_attributeVectorDoubleManager->setValue(dprop, v[i]);
548 m_browser->addProperty(prop, dprop);
549 }
550 m_browser->m_attributeVectorDoubleManager->blockSignals(false);
551
552 sizeProp->setEnabled(false);
553 m_browser->m_browser->setExpanded(aprop.item, false);
554 return aprop;
555 }
556
557private:
559 QtProperty *m_parent;
560 QString m_attName;
561};
562
569public:
570 SetAttributeFromProperty(FunctionTreeView *browser, QtProperty *prop) : m_browser(browser), m_prop(prop) {}
571
572protected:
574 void apply(std::string &str) const override {
575 QString attName = m_prop->propertyName();
576 if (attName == "FileName") {
577 str = m_browser->m_filenameManager->value(m_prop).toStdString();
578 } else if (attName == "Formula") {
579 str = m_browser->m_formulaManager->value(m_prop).toStdString();
580 } else if (attName == "Workspace") {
581 str = m_browser->m_workspaceManager->value(m_prop).toStdString();
582 } else {
583 str = m_browser->m_attributeStringManager->value(m_prop).toStdString();
584 }
585 }
587 void apply(double &d) const override { d = m_browser->m_attributeDoubleManager->value(m_prop); }
589 void apply(int &i) const override { i = m_browser->m_attributeIntManager->value(m_prop); }
591 void apply(bool &b) const override { b = m_browser->m_attributeBoolManager->value(m_prop); }
593 void apply(std::vector<double> &v) const override {
594 QList<QtProperty *> members = m_prop->subProperties();
595 if (members.empty())
596 throw std::runtime_error("FunctionTreeView: empty vector attribute group.");
597 int n = members.size() - 1;
598 if (n == 0) {
599 v.clear();
600 return;
601 }
602 v.resize(n);
603 for (int i = 0; i < n; ++i) {
604 v[i] = m_browser->m_attributeVectorDoubleManager->value(members[i + 1]);
605 }
606 }
607
608private:
610 QtProperty *m_prop;
611};
612
621 CreateAttributePropertyForFunctionTreeView cap(this, parent, attName);
622 return att.apply(cap);
623}
624
636 const CompositeFunction_sptr &parentComposite,
637 const std::size_t &parentIndex) {
638 // add the function index property
639 addIndexProperty(prop);
640
641 // add attribute properties
642 auto attributeNames = fun->getAttributeNames();
643 for (const auto &att : attributeNames) {
644 if (!variableIsPrefixed(att)) {
645 QString attName = QString::fromStdString(att);
646 addAttributeProperty(prop, attName, fun->getAttribute(att));
647 }
648 }
649
650 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
651 if (cf) {
652 // if composite add members
653 for (size_t i = 0; i < cf->nFunctions(); ++i) {
654 AProperty ap = addFunctionProperty(prop, QString::fromStdString(cf->getFunction(i)->name()));
655 addAttributeAndParameterProperties(ap.prop, cf->getFunction(i), cf, i);
656 }
657 } else { // if simple add parameters
658 for (size_t i = 0; i < fun->nParams(); ++i) {
659 QString name = QString::fromStdString(fun->parameterName(i));
660 QString desc = QString::fromStdString(fun->parameterDescription(i));
661 double value = fun->getParameter(i);
662 AProperty ap = addParameterProperty(prop, name, desc, value);
663 // if parameter has a tie
664 if (!fun->isActive(i))
665 addParameterTie(ap.prop, fun, name.toStdString(), i, parentComposite, parentIndex);
666 else
667 addGlobalParameterTie(ap.prop, name.toStdString(), parentComposite, parentIndex);
668
669 if (const auto constraint = fun->getConstraint(i)) {
670 addConstraintProperties(ap.prop, QString::fromStdString(constraint->asString()));
671 }
672 }
673 }
674}
675
687void FunctionTreeView::addParameterTie(QtProperty *property, const IFunction_sptr &function,
688 const std::string &parameterName, const std::size_t &parameterIndex,
689 const CompositeFunction_sptr &parentComposite, const std::size_t &parentIndex) {
690 if (const auto tie = function->getTie(parameterIndex)) {
691 addTieProperty(property, QString::fromStdString(tie->asString()));
692 } else {
693 auto tieAdded = false;
694 if (parentComposite)
695 tieAdded = addParameterTieInComposite(property, parameterName, parentComposite, parentIndex);
696
697 if (!tieAdded)
698 addTieProperty(property, QString::number(function->getParameter(parameterIndex)));
699 }
700}
701
711bool FunctionTreeView::addParameterTieInComposite(QtProperty *property, const std::string &parameterName,
712 const CompositeFunction_sptr &composite, const std::size_t &index) {
713 for (auto i = 0u; i < composite->nParams(); ++i) {
714 const auto fullName = "f" + std::to_string(index) + "." + parameterName;
715 if (fullName == composite->parameterName(i)) {
716 if (const auto tie = composite->getTie(i)) {
717 const auto tieStr = QString::fromStdString(tie->asString());
718 addTieProperty(property, tieStr.mid(tieStr.indexOf('=') + 1));
719 return true;
720 }
721 return false;
722 }
723 }
724 return false;
725}
726
736void FunctionTreeView::addGlobalParameterTie(QtProperty *property, const std::string &parameterName,
737 const CompositeFunction_sptr &parentComposite,
738 const std::size_t &parentIndex) {
739 if (m_multiDomainFunctionPrefix.isEmpty() || m_globalTies.empty())
740 return;
741
742 auto const fullName = getFullParameterName(parameterName, parentComposite ? static_cast<int>(parentIndex) : -1);
743
744 const auto it = std::find_if(m_globalTies.cbegin(), m_globalTies.cend(),
745 [&fullName](const auto &globalTie) { return fullName == globalTie.m_parameter; });
746 if (it != m_globalTies.cend())
747 addTieProperty(property, QString::fromStdString((*it).m_tie), true);
748}
749
757 QtProperty *indexProperty = m_indexManager->addProperty("Index");
758 indexProperty->setEnabled(false);
759 m_indexManager->setValue(indexProperty, m_multiDomainFunctionPrefix);
760 (void)addProperty(prop, indexProperty);
761}
762
771 AProperty ap;
772 ap.item = nullptr;
773 ap.parent = nullptr;
774 ap.prop = nullptr;
775 if (!prop)
776 return ap;
777 if (!isFunction(prop))
778 return ap;
779 if (!m_properties[prop].parent)
780 return ap;
781
782 QString index = "fff";
783 QtProperty *ip = m_indexManager->addProperty("Index");
784 ip->setEnabled(false);
785 m_indexManager->setValue(ip, index);
786 auto retval = addProperty(prop, ip);
788 return retval;
789}
790
796void FunctionTreeView::updateFunctionIndices(QtProperty *prop, const QString &index) {
797 if (prop == nullptr) {
798 auto top = m_browser->properties();
799 if (top.isEmpty())
800 return;
801 prop = top[0];
802 }
803 auto children = prop->subProperties();
804 size_t i = 0;
805 foreach (QtProperty *child, children) {
806 if (isFunction(child)) {
807 updateFunctionIndices(child, index + "f" + QString::number(i) + ".");
808 ++i;
809 } else if (isIndex(child)) {
811 }
812 }
813}
814
819 auto props = m_browser->properties();
820 if (props.isEmpty()) {
821 AProperty ap;
822 ap.item = nullptr;
823 ap.parent = nullptr;
824 ap.prop = nullptr;
825 return ap;
826 }
827 QtProperty *prop = props[0];
828 return m_properties[prop];
829}
830
835bool FunctionTreeView::isFunction(QtProperty *prop) const {
836 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_functionManager) == prop->propertyManager();
837}
838
843bool FunctionTreeView::isStringAttribute(QtProperty *prop) const {
844 return prop && (dynamic_cast<QtAbstractPropertyManager *>(m_attributeStringManager) == prop->propertyManager() ||
845 dynamic_cast<QtAbstractPropertyManager *>(m_formulaManager) == prop->propertyManager() ||
846 dynamic_cast<QtAbstractPropertyManager *>(m_filenameManager) == prop->propertyManager() ||
847 dynamic_cast<QtAbstractPropertyManager *>(m_workspaceManager) == prop->propertyManager());
848}
849
854bool FunctionTreeView::isDoubleAttribute(QtProperty *prop) const {
855 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_attributeDoubleManager) == prop->propertyManager();
856}
857
862bool FunctionTreeView::isIntAttribute(QtProperty *prop) const {
863 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_attributeIntManager) == prop->propertyManager();
864}
865
870bool FunctionTreeView::isBoolAttribute(QtProperty *prop) const {
871 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_attributeBoolManager) == prop->propertyManager();
872}
873
878bool FunctionTreeView::isVectorAttribute(QtProperty *prop) const {
879 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_attributeVectorManager) == prop->propertyManager();
880}
881
886bool FunctionTreeView::isAttribute(QtProperty *prop) const {
887 return isStringAttribute(prop) || isDoubleAttribute(prop) || isIntAttribute(prop) || isBoolAttribute(prop) ||
888 isVectorAttribute(prop);
889}
890
895bool FunctionTreeView::isParameter(QtProperty *prop) const {
896 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_parameterManager) == prop->propertyManager();
897}
898
903double FunctionTreeView::getParameter(QtProperty *prop) const { return m_parameterManager->value(prop); }
908bool FunctionTreeView::isIndex(QtProperty *prop) const {
909 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_indexManager) == prop->propertyManager();
910}
911
916QString FunctionTreeView::getIndex(QtProperty *prop) const {
917 if (!prop)
918 return "";
919 if (isFunction(prop)) {
920 auto props = prop->subProperties();
921 if (props.isEmpty())
922 return "";
923 for (auto it = props.begin(); it != props.end(); ++it) {
924 if (isIndex(*it)) {
925 return m_indexManager->value(*it);
926 }
927 }
928 return "";
929 }
930
931 auto ap = m_properties[prop];
932 return getIndex(ap.parent);
933}
934
939QString FunctionTreeView::getParameterName(QtProperty *prop) const {
940 if (isParameter(prop)) {
941 return getIndex(prop) + prop->propertyName();
942 } else {
943 auto parent = getParentParameterProperty(prop);
944 return getIndex(prop) + parent->propertyName();
945 }
946}
951QString FunctionTreeView::getAttributeName(QtProperty *prop) const {
952 if (isAttribute(prop)) {
953 return getIndex(prop) + prop->propertyName();
954 }
955 throw std::logic_error("QtProperty " + prop->propertyName().toStdString() + " is not an attribute property.");
956}
957
964QtProperty *FunctionTreeView::getFunctionProperty(const QString &index) const {
965 // Might not be the most efficient way to do it. m_functionManager might be
966 // searched instead,
967 // but it is not being kept up-to-date at the moment (is not cleared).
968 foreach (auto property, m_properties.keys()) {
969 if (isFunction(property) && getIndex(property) == index) {
970 return property;
971 }
972 }
973
974 // No function with such index
975 return nullptr;
976}
977
984void FunctionTreeView::addTieProperty(QtProperty *prop, const QString &tie, bool globalTie) {
985 if (!prop) {
986 throw std::runtime_error("FunctionTreeView: null property pointer");
987 }
988
989 if (!isParameter(prop))
990 return;
991
992 QtProperty *funProp = getFunctionProperty().prop;
993
994 // Create and add a QtProperty for the tie.
995 m_tieManager->blockSignals(true);
996 QtProperty *tieProp = m_tieManager->addProperty("Tie");
997 m_tieManager->setValue(tieProp, globalTie ? tie : getFullTie(tie));
998 addProperty(prop, tieProp);
999 m_tieManager->blockSignals(false);
1000
1001 const auto parName = getParameterName(prop);
1002 // Store tie information for easier access
1003 ATie atie;
1004 atie.paramProp = prop;
1005 atie.paramName = parName;
1006 atie.tieProp = tieProp;
1007 m_ties.insert(funProp, atie);
1008}
1009
1016QString FunctionTreeView::getFullTie(const QString &tie) const {
1017 if (!isNumber(tie.toStdString()) && !containsOneOf(tie.toStdString(), "="))
1018 return m_multiDomainFunctionPrefix + tie;
1019 return tie;
1020}
1021
1031std::string FunctionTreeView::getFullParameterName(const std::string &parameter, int compositeIndex) const {
1032 auto fullParameterName = m_multiDomainFunctionPrefix.toStdString();
1033 if (compositeIndex != -1)
1034 fullParameterName += "f" + std::to_string(compositeIndex) + ".";
1035 fullParameterName += parameter;
1036 return fullParameterName;
1037}
1038
1043bool FunctionTreeView::hasTie(QtProperty *prop) const {
1044 if (!prop)
1045 return false;
1046 auto children = prop->subProperties();
1047 foreach (QtProperty *child, children) {
1048 if (child->propertyName() == "Tie") {
1049 return true;
1050 }
1051 }
1052 return false;
1053}
1054
1059bool FunctionTreeView::isTie(QtProperty *prop) const {
1060 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_tieManager) == prop->propertyManager();
1061}
1062
1067QString FunctionTreeView::getTie(QtProperty *prop) const {
1068 if (!prop)
1069 return "";
1070 if (prop->propertyName() == "Tie") {
1071 return m_tieManager->value(prop);
1072 }
1073 auto children = prop->subProperties();
1074 foreach (QtProperty *child, children) {
1075 if (child->propertyName() == "Tie") {
1076 return m_tieManager->value(child);
1077 }
1078 }
1079 return "";
1080}
1081
1088 const QString &constraint) {
1089 if (!isParameter(prop))
1091 auto const parts = splitConstraintString(constraint);
1092 if (parts.first.isEmpty())
1094 auto lowerBound = parts.second.first;
1095 auto upperBound = parts.second.second;
1096
1097 // add properties
1099 AConstraint ac;
1100 ac.paramProp = prop;
1101 ac.lower = ac.upper = nullptr;
1102
1103 if (!lowerBound.isEmpty()) {
1104 auto apLower = addProperty(prop, m_constraintManager->addProperty("LowerBound"));
1105 plist << apLower;
1106 ac.lower = apLower.prop;
1107 m_constraintManager->setValue(ac.lower, lowerBound.toDouble());
1108 }
1109
1110 if (!upperBound.isEmpty()) {
1111 auto apUpper = addProperty(prop, m_constraintManager->addProperty("UpperBound"));
1112 plist << apUpper;
1113 ac.upper = apUpper.prop;
1114 m_constraintManager->setValue(ac.upper, upperBound.toDouble());
1115 }
1116
1117 if (ac.lower || ac.upper) {
1118 m_constraints.insert(m_properties[prop].parent, ac);
1119 }
1120 return plist;
1121}
1122
1127bool FunctionTreeView::isConstraint(QtProperty *prop) const {
1128 return prop && dynamic_cast<QtAbstractPropertyManager *>(m_constraintManager) == prop->propertyManager();
1129}
1130
1135bool FunctionTreeView::hasConstraint(QtProperty *prop) const { return hasLowerBound(prop) || hasUpperBound(prop); }
1136
1141bool FunctionTreeView::hasLowerBound(QtProperty *prop) const {
1142 if (!isParameter(prop))
1143 return false;
1144 auto props = prop->subProperties();
1145 if (props.isEmpty())
1146 return false;
1147 foreach (QtProperty *p, props) {
1148 if (dynamic_cast<QtAbstractPropertyManager *>(m_constraintManager) == p->propertyManager() &&
1149 p->propertyName() == "LowerBound")
1150 return true;
1151 }
1152 return false;
1153}
1154
1159bool FunctionTreeView::hasUpperBound(QtProperty *prop) const {
1160 if (!isParameter(prop))
1161 return false;
1162 auto props = prop->subProperties();
1163 if (props.isEmpty())
1164 return false;
1165 foreach (QtProperty *p, props) {
1166 if (dynamic_cast<QtAbstractPropertyManager *>(m_constraintManager) == p->propertyManager() &&
1167 p->propertyName() == "UpperBound")
1168 return true;
1169 }
1170 return false;
1171}
1172
1174QString FunctionTreeView::getConstraint(const QString &paramName, const double &lowerBound,
1175 const double &upperBound) const {
1176
1177 QString constraint;
1178 if (lowerBound != Mantid::EMPTY_DBL())
1179 constraint += QString::number(lowerBound) + "<";
1180
1181 constraint += paramName;
1182 if (upperBound != Mantid::EMPTY_DBL())
1183 constraint += "<" + QString::number(upperBound);
1184
1185 return constraint;
1186}
1187
1191void FunctionTreeView::popupMenu(const QPoint &) {
1192 auto item = m_browser->currentItem();
1193 if (!item) {
1194 QMenu context(this);
1195 context.addAction(m_actionAddFunction);
1196 if (!QApplication::clipboard()->text().isEmpty()) {
1197 context.addAction(m_actionFromClipboard);
1198 }
1199 if (!m_browser->properties().isEmpty()) {
1200 context.addAction(m_actionToClipboard);
1201 }
1202 context.exec(QCursor::pos());
1203 return;
1204 }
1205 QtProperty *prop = item->property();
1206 if (isFunction(prop)) { // functions
1207 QMenu context(this);
1209 Mantid::API::FunctionFactory::Instance().createFunction(prop->propertyName().toStdString());
1210 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
1211 if (cf || m_properties[prop].parent == nullptr) {
1212 context.addAction(m_actionAddFunction);
1213 }
1214 context.addAction(m_actionRemoveFunction);
1215 if (!QApplication::clipboard()->text().isEmpty()) {
1216 context.addAction(m_actionFromClipboard);
1217 }
1218 if (!m_browser->properties().isEmpty()) {
1219 context.addAction(m_actionToClipboard);
1220 }
1221 context.addAction(m_actionFunctionHelp);
1222 context.exec(QCursor::pos());
1223 } else if (isParameter(prop)) { // parameters
1224 QMenu context(this);
1225 if (hasTie(prop)) {
1226 context.addAction(m_actionRemoveTie);
1227 } else {
1228 context.addAction(m_actionFixParameter);
1229 context.addAction(m_actionAddTie);
1230 }
1231 bool hasLower = hasLowerBound(prop);
1232 bool hasUpper = hasUpperBound(prop);
1233 if (!hasLower && !hasUpper) {
1234 QMenu *constraintMenu = new QMenu("Constraints", this);
1235 constraintMenu->addAction(m_actionConstraints10);
1236 constraintMenu->addAction(m_actionConstraints50);
1237 constraintMenu->addAction(m_actionConstraints);
1238 context.addMenu(constraintMenu);
1239 } else {
1240 context.addAction(m_actionRemoveConstraints);
1241 }
1242 context.exec(QCursor::pos());
1243 } else if (isConstraint(prop)) { // constraints
1244 QMenu context(this);
1245 context.addAction(m_actionRemoveConstraint);
1246 context.exec(QCursor::pos());
1247 }
1248}
1249
1254
1255 auto item = m_browser->currentItem();
1256 QtProperty *prop = nullptr;
1257 if (item) {
1258 prop = item->property();
1259 if (!isFunction(prop))
1260 return;
1261 }
1262
1263 // check if the browser is empty
1264 if (!prop) {
1265 auto top = m_browser->properties();
1266 if (!top.isEmpty()) {
1267 prop = top[0];
1268 if (!isFunction(prop))
1269 return;
1270 }
1271 }
1272
1273 // Start the dialog
1276 connect(m_selectFunctionDialog, SIGNAL(finished(int)), this, SLOT(addFunctionEnd(int)));
1277 }
1280 m_selectFunctionDialog->open();
1281}
1282
1284 if (result != QDialog::Accepted) {
1285 return;
1286 }
1287
1288 QString newFunction = m_selectFunctionDialog->getFunction();
1289 if (newFunction.isEmpty())
1290 return;
1291
1292 // create new function
1293 auto f = Mantid::API::FunctionFactory::Instance().createFunction(newFunction.toStdString());
1294
1295 // get previous global parameters
1296 auto globalParameters = getGlobalParameters();
1297
1298 auto prop = m_selectedFunctionProperty;
1299 if (prop) { // there are other functions defined
1301 Mantid::API::FunctionFactory::Instance().createFunction(prop->propertyName().toStdString());
1302 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
1303 if (cf) {
1304 auto const isAdded = addFunction(prop, f);
1305 if (!isAdded)
1306 return;
1307 } else {
1308 cf.reset(new Mantid::API::CompositeFunction);
1309 auto f0 = getFunction(prop);
1310 if (f0) {
1311 // Modify the previous globals so they have a function prefix
1312 std::transform(globalParameters.begin(), globalParameters.end(), globalParameters.begin(),
1313 m_multiDomainFunctionPrefix.isEmpty() ? addPrefix : insertPrefix);
1314 cf->addFunction(f0);
1315 }
1316 cf->addFunction(f);
1317 setFunction(cf);
1318 }
1319 } else { // the browser is empty - add first function
1320 auto const isAdded = addFunction(nullptr, f);
1321 if (!isAdded)
1322 return;
1323 }
1324 emit functionAdded(QString::fromStdString(f->asString()));
1325 setGlobalParameters(globalParameters);
1326 emit globalsChanged(globalParameters);
1327}
1328
1335 std::string attName = prop->propertyName().toStdString();
1336 SetAttributeFromProperty setter(this, prop);
1338 attr.apply(setter);
1339 try {
1340 fun.setAttribute(attName, attr);
1341 } catch (std::exception &expt) {
1342 QMessageBox::critical(this, "Mantid - Error",
1343 "Cannot set attribute " + QString::fromStdString(attName) + " of function " +
1344 prop->propertyName() + ":\n\n" + QString::fromStdString(expt.what()));
1345 }
1346}
1347
1353Mantid::API::IFunction_sptr FunctionTreeView::getFunction(QtProperty *prop, bool attributesOnly) {
1354 if (prop == nullptr) { // get overall function
1355 auto props = m_browser->properties();
1356 if (props.isEmpty())
1358 prop = props[0];
1359 }
1360 if (!isFunction(prop))
1362
1363 // construct the function
1364 auto fun = Mantid::API::FunctionFactory::Instance().createFunction(prop->propertyName().toStdString());
1365 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
1366 if (cf) {
1367 auto children = prop->subProperties();
1368 foreach (QtProperty *child, children) {
1369 if (isFunction(child)) {
1370 auto f = getFunction(child);
1371 // if f is null ignore that function
1372 if (f) {
1373 cf->addFunction(f);
1374 }
1375 } else if (isAttribute(child)) {
1376 setAttributeToFunction(*fun, child);
1377 }
1378 }
1379 } else {
1380 // loop over the children properties and set parameters and attributes
1381 auto children = prop->subProperties();
1382 foreach (QtProperty *child, children) {
1383 if (isAttribute(child)) {
1384 setAttributeToFunction(*fun, child);
1385 } else if (!attributesOnly && isParameter(child)) {
1386 fun->setParameter(child->propertyName().toStdString(), getParameter(child));
1387 }
1388 }
1389 }
1390
1391 // if this flag is set the function requires attributes only
1392 // attempts to set other properties may result in exceptions
1393 if (attributesOnly)
1394 return fun;
1395
1396 // add ties
1397 {
1398 auto from = m_ties.lowerBound(prop);
1399 auto to = m_ties.upperBound(prop);
1400 // ties can become invalid after some editing
1401 QList<QtProperty *> failedTies;
1402 for (auto it = from; it != to; ++it) {
1403 auto const tie = (it->paramName + "=" + m_tieManager->value(it.value().tieProp)).toStdString();
1404 try {
1405 fun->addTies(tie);
1406 } catch (...) {
1407 failedTies << it.value().tieProp;
1408 g_log.warning() << "Invalid tie has been removed: " << tie << std::endl;
1409 }
1410 }
1411 // remove failed ties from the browser
1412 foreach (QtProperty *p, failedTies) { removeProperty(p); }
1413 }
1414
1415 // add constraints
1416 {
1417 auto from = m_constraints.lowerBound(prop);
1418 auto to = m_constraints.upperBound(prop);
1419 for (auto it = from; it != to; ++it) {
1420 try {
1421 const auto &localParam = it.value();
1422 const auto lower = m_constraintManager->value(localParam.lower);
1423 const auto upper = m_constraintManager->value(localParam.upper);
1424 const auto constraint = getConstraint(localParam.paramProp->propertyName(), lower, upper);
1425 fun->addConstraints(constraint.toStdString());
1426 } catch (...) {
1427 }
1428 }
1429 }
1430
1431 return fun;
1432}
1433
1439void FunctionTreeView::setParameter(const QString &paramName, double value) {
1440 auto prop = getParameterProperty(paramName);
1442 m_parameterManager->setValue(prop, value);
1443}
1444
1450void FunctionTreeView::setParameterError(const QString &paramName, double error) {
1451 QString index, name;
1452 std::tie(index, name) = splitParameterName(paramName);
1453 if (auto prop = getFunctionProperty(index)) {
1454 auto children = prop->subProperties();
1455 foreach (QtProperty *child, children) {
1456 if (isParameter(child) && child->propertyName() == name) {
1457 m_parameterManager->setError(child, error);
1458 break;
1459 }
1460 }
1461 }
1462}
1468void FunctionTreeView::setDoubleAttribute(const QString &attrName, double value) {
1469 auto prop = getAttributeProperty(attrName);
1471 m_attributeDoubleManager->setValue(prop, value);
1472}
1478void FunctionTreeView::setIntAttribute(const QString &attrName, int value) {
1479 auto prop = getAttributeProperty(attrName);
1481 m_attributeIntManager->setValue(prop, value);
1482}
1488void FunctionTreeView::setStringAttribute(const QString &attrName, std::string &valueAsStdStr) {
1489 QString value = QString::fromStdString(valueAsStdStr);
1490 auto prop = getAttributeProperty(attrName);
1492 // attName is the un-prefixed attribute name
1493 auto attName = prop->propertyName();
1494 if (attName == "FileName") {
1495 m_filenameManager->setValue(prop, value);
1496 } else if (attName == "Formula") {
1497 m_formulaManager->setValue(prop, value);
1498 } else if (attName == "Workspace") {
1499 m_workspaceManager->setValue(prop, value);
1500 } else {
1501 m_attributeStringManager->setValue(prop, value);
1502 }
1503}
1509void FunctionTreeView::setBooleanAttribute(const QString &attrName, bool value) {
1510 auto prop = getAttributeProperty(attrName);
1512 m_attributeBoolManager->setValue(prop, value);
1513}
1523void FunctionTreeView::setVectorAttribute(const QString &attrName, std::vector<double> &value) {
1524 UNUSED_ARG(attrName);
1526}
1531double FunctionTreeView::getParameter(const QString &paramName) const {
1532 auto prop = getParameterProperty(paramName);
1533 return m_parameterManager->value(prop);
1534}
1540 auto prop = getAttributeProperty(attrName);
1541 if (isDoubleAttribute(prop)) {
1543 } else if (isIntAttribute(prop)) {
1544 return IFunction::Attribute(m_attributeIntManager->value(prop));
1545 } else if (isStringAttribute(prop)) {
1546 return IFunction::Attribute(m_attributeStringManager->value(prop).toStdString());
1547 } else if (isBoolAttribute(prop)) {
1548 return IFunction::Attribute(m_attributeBoolManager->value(prop));
1549 } else if (isVectorAttribute(prop)) {
1551 } else {
1552 throw std::runtime_error("Unknown function attribute " + attrName.toStdString());
1553 }
1554}
1556QtProperty *FunctionTreeView::getParameterProperty(const QString &paramName) const {
1557 QString index, name;
1558 std::tie(index, name) = splitParameterName(paramName);
1559 if (auto prop = getFunctionProperty(index)) {
1560 auto children = prop->subProperties();
1561 foreach (QtProperty *child, children) {
1562 if (isParameter(child) && child->propertyName() == name) {
1563 return child;
1564 }
1565 }
1566 }
1567 std::string message = "Unknown function parameter " + paramName.toStdString() +
1568 "\n\n This may happen if there is a CompositeFunction "
1569 "containing only one function.";
1570 throw std::runtime_error(message);
1571}
1573QtProperty *FunctionTreeView::getAttributeProperty(const QString &attributeName) const {
1574 QString index, name;
1575 QtProperty *prop;
1576 std::tie(index, name) = splitParameterName(attributeName);
1577 if (!variableIsPrefixed(attributeName.toStdString())) {
1578 // If variable is unprefixed then we are on the top level composite
1579 // function so grab first property from the tree
1580 prop = m_browser->properties()[0];
1581 } else {
1582 prop = getFunctionProperty(index);
1583 }
1584 auto children = prop->subProperties();
1585 foreach (QtProperty *child, children) {
1586 if (isAttribute(child) && child->propertyName() == name) {
1587 return child;
1588 }
1589 }
1590 std::string message = "Unknown function attribute " + attributeName.toStdString();
1591 throw std::runtime_error(message);
1592}
1593
1596QtProperty *FunctionTreeView::getParentParameterProperty(QtProperty *prop) const {
1597 const auto itProp =
1598 std::find_if(m_ties.cbegin(), m_ties.cend(), [&prop](const auto &tie) { return tie.tieProp == prop; });
1599 if (itProp != m_ties.cend())
1600 return (*itProp).paramProp;
1601
1602 const auto itConstr = std::find_if(m_constraints.cbegin(), m_constraints.cend(), [&prop](const auto &constraint) {
1603 return (constraint.lower == prop || constraint.upper == prop);
1604 });
1605 if (itConstr != m_constraints.cend())
1606 return (*itConstr).paramProp;
1607 throw std::logic_error("QtProperty " + prop->propertyName().toStdString() +
1608 " is not a child of a property for any function parameter.");
1609}
1610
1615 auto item = m_browser->currentItem();
1616 if (!item)
1617 return;
1618 QtProperty *prop = item->property();
1619 if (!isFunction(prop))
1620 return;
1621 auto const functionString = QString::fromStdString(getFunction(prop)->asString());
1622 auto const functionIndex = getIndex(prop);
1623 removeProperty(prop);
1625
1626 // After removing a function we could end up with
1627 // a CompositeFunction with only one function
1628 // In this case, the function should be kept but
1629 // the composite function should be removed
1630 auto props = m_browser->properties();
1631 auto globalParameters = getGlobalParameters();
1632 if (!props.isEmpty()) {
1633 // The function browser is not empty
1634
1635 // Check if the current function in the browser is a
1636 // composite function
1637 auto topProp = props[0];
1638 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(getFunction(topProp));
1639 if (cf) {
1640 // If it is a composite function
1641 // check that there are more than one function
1642 // which means more than two subproperties
1643
1644 if (cf->nFunctions() == 1 && cf->name() == "CompositeFunction") {
1645 // If only one function remains, remove the composite function:
1646 // Temporary copy the remaining function
1647 auto func = getFunction(props[0]->subProperties()[1]);
1648 std::transform(globalParameters.begin(), globalParameters.end(), globalParameters.begin(),
1649 m_multiDomainFunctionPrefix.isEmpty() ? removePrefix : removeEmbeddedPrefix);
1650 // Remove the composite function
1651 m_browser->removeProperty(topProp);
1652 // Add the temporary stored function
1653 setFunction(func);
1654 }
1655 }
1656 }
1657 emit functionRemovedString(functionString);
1658 emit functionRemoved(functionIndex);
1659 setGlobalParameters(globalParameters);
1660 emit globalsChanged(globalParameters);
1661}
1662
1667 auto item = m_browser->currentItem();
1668 if (!item)
1669 return;
1670 QtProperty *prop = item->property();
1671 if (!isParameter(prop))
1672 return;
1673 QString tie = QString::number(getParameter(prop));
1674 addTieProperty(prop, tie);
1675 emit parameterTieChanged(getParameterName(prop), tie);
1676}
1677
1679QtProperty *FunctionTreeView::getTieProperty(QtProperty *prop) const {
1680 auto children = prop->subProperties();
1681 foreach (QtProperty *child, children) {
1682 if (child->propertyName() == "Tie") {
1683 return child;
1684 }
1685 }
1686 return nullptr;
1687}
1688
1693 auto item = m_browser->currentItem();
1694 if (!item)
1695 return;
1696 QtProperty *prop = item->property();
1697 if (!isParameter(prop))
1698 return;
1699 auto tieProp = getTieProperty(prop);
1700 if (tieProp) {
1701 removeProperty(tieProp);
1702 }
1703 emit parameterTieChanged(getParameterName(prop), "");
1704}
1705
1710 auto item = m_browser->currentItem();
1711 if (!item)
1712 return;
1713 QtProperty *prop = item->property();
1714 if (!isParameter(prop))
1715 return;
1716
1717 bool ok;
1718 QString tie = QInputDialog::getText(this, "Add a tie", "Tie:", QLineEdit::Normal, "", &ok);
1719 if (ok && !tie.isEmpty()) {
1720 try {
1721 addTieProperty(prop, tie);
1722 emit parameterTieChanged(getParameterName(prop), tie);
1724 QMessageBox::critical(this, "Mantid - Error", "Syntax errors found in tie: " + tie);
1725 } catch (std::exception &e) {
1726 QMessageBox::critical(this, "Mantid - Error", QString::fromLatin1("Errors found in tie: ") + e.what());
1727 }
1728 }
1729}
1730
1735 QString funStr = QApplication::clipboard()->text();
1736 if (funStr.isEmpty())
1737 return;
1738 try {
1739 auto fun = Mantid::API::FunctionFactory::Instance().createInitialized(funStr.toStdString());
1740 if (!fun)
1741 return;
1742 this->setFunction(fun);
1743 emit functionReplaced(funStr);
1744 } catch (...) {
1745 // text in the clipboard isn't a function definition
1746 QMessageBox::warning(this, "Mantid - Warning",
1747 "Text in the clipboard isn't a function definition"
1748 " or contains errors.");
1749 }
1750}
1751
1756
1761 auto item = m_browser->currentItem();
1762 if (!item)
1763 return;
1764 QtProperty *prop = item->property();
1765 if (!isParameter(prop))
1766 return;
1767 QString functionIndex, name;
1768 std::tie(functionIndex, name) = splitParameterName(getParameterName(prop));
1769 auto const value = QString::number(getParameter(prop));
1770 auto const constraint = value + "<" + name + "<" + value;
1771 addConstraintProperties(prop, constraint);
1772 emit parameterConstraintAdded(functionIndex, constraint);
1773}
1774
1779 auto item = m_browser->currentItem();
1780 if (!item)
1781 return;
1782 QtProperty *prop = item->property();
1783 if (!isParameter(prop))
1784 return;
1785 double val = getParameter(prop);
1786 QString functionIndex, name;
1787 std::tie(functionIndex, name) = splitParameterName(getParameterName(prop));
1788 auto const constraint = QString::number(val * 0.9) + "<" + name + "<" + QString::number(val * 1.1);
1789 addConstraintProperties(prop, constraint);
1790 emit parameterConstraintAdded(functionIndex, constraint);
1791}
1792
1797 auto item = m_browser->currentItem();
1798 if (!item)
1799 return;
1800 QtProperty *prop = item->property();
1801 if (!isParameter(prop))
1802 return;
1803 double val = getParameter(prop);
1804 QString functionIndex, name;
1805 std::tie(functionIndex, name) = splitParameterName(getParameterName(prop));
1806 auto const constraint = QString::number(val * 0.5) + "<" + name + "<" + QString::number(val * 1.5);
1807 addConstraintProperties(prop, constraint);
1808 emit parameterConstraintAdded(functionIndex, constraint);
1809}
1810
1812 auto props = prop->subProperties();
1813 foreach (QtProperty *p, props) {
1814 if (isConstraint(p)) {
1815 removeProperty(p);
1816 }
1817 }
1818}
1819
1824 auto item = m_browser->currentItem();
1825 if (!item)
1826 return;
1827 QtProperty *prop = item->property();
1828 if (!isParameter(prop))
1829 return;
1832}
1833
1838 auto item = m_browser->currentItem();
1839 if (!item)
1840 return;
1841 QtProperty *prop = item->property();
1842 if (!isConstraint(prop))
1843 return;
1844 auto paramProp = getParentParameterProperty(prop);
1845 removeProperty(prop);
1846 auto const parName = getParameterName(paramProp);
1847 emit parameterConstraintRemoved(parName);
1848 QString functionIndex, constraint;
1849 std::tie(functionIndex, constraint) = getFunctionAndConstraint(paramProp);
1850 if (!constraint.isEmpty()) {
1851 emit parameterConstraintAdded(functionIndex, constraint);
1852 }
1853}
1858 auto item = m_browser->currentItem();
1859 if (!item)
1860 return IFunction_sptr();
1861 QtProperty *prop = item->property();
1862 if (!isFunction(prop))
1863 return IFunction_sptr();
1864 return getFunction(prop);
1865}
1869void FunctionTreeView::showFunctionHelp(const QString &functionName) const {
1871}
1872
1873std::pair<QString, QString> FunctionTreeView::getFunctionAndConstraint(QtProperty *prop) const {
1874 auto const parName = getParameterName(prop);
1875 double lower = Mantid::EMPTY_DBL();
1876 double upper = Mantid::EMPTY_DBL();
1877 for (auto p : prop->subProperties()) {
1878 if (p->propertyName() == "LowerBound")
1879 lower = m_constraintManager->value(p);
1880 if (p->propertyName() == "UpperBound")
1881 upper = m_constraintManager->value(p);
1882 }
1884 QString functionIndex, name;
1885 std::tie(functionIndex, name) = splitParameterName(parName);
1886 return std::make_pair(functionIndex, getConstraint(name, lower, upper));
1887 }
1888 return std::make_pair("", "");
1889}
1890
1897 auto attributeName = getAttributeName(prop);
1898 // Some attributes require the function to be fully reconstructed, in this
1899 // case we'd need to emit a function replaced signal. If its not one of these
1900 // attributes emit an attributeValueChanged signal.
1901 try {
1902 if (std::find(REQUIRESRECONSTRUCTIONATTRIBUTES.begin(), REQUIRESRECONSTRUCTIONATTRIBUTES.end(),
1903 removePrefix(attributeName)) != REQUIRESRECONSTRUCTIONATTRIBUTES.end()) {
1904 auto funProp = m_properties[prop].parent;
1905 if (!funProp)
1906 return;
1907 auto fun = getFunction(funProp, true);
1908
1909 // delete and recreate all function's properties (attributes, parameters,
1910 // etc)
1911 setFunction(funProp, fun);
1914 emit functionReplaced(QString::fromStdString(getFunction()->asString()));
1915 }
1916 } else {
1918 emit attributePropertyChanged(attributeName);
1919 }
1920 }
1921 } catch (std::exception &expt) {
1922 QMessageBox::critical(this, "Mantid - Error", QString::fromStdString(expt.what()));
1923 }
1924}
1925
1930 QtProperty *vectorProp = m_properties[prop].parent;
1931 if (!vectorProp)
1932 throw std::logic_error("FunctionTreeView: inconsistency in vector "
1933 "properties.\nAttribute property not found.");
1934 auto funProp = m_properties[vectorProp].parent;
1935 if (!funProp)
1936 throw std::logic_error("FunctionTreeView: inconsistency in vector "
1937 "properties.\nFunction property not found.");
1938 auto fun = getFunction(funProp, true);
1939 if (!fun)
1940 throw std::logic_error("FunctionTreeView: inconsistency in vector "
1941 "properties.\nFunction undefined.");
1942 auto attName = vectorProp->propertyName().toStdString();
1943 auto attribute = fun->getAttribute(attName).asVector();
1944 auto newSize = m_attributeSizeManager->value(prop);
1945 if (newSize < 0)
1946 newSize = 0;
1947 if (attribute.size() != static_cast<size_t>(newSize)) {
1948 if (newSize == 0) {
1949 attribute.clear();
1950 } else {
1951 attribute.resize(newSize);
1952 }
1953 fun->setAttributeValue(attName, attribute);
1954 setFunction(funProp, fun);
1956 }
1957}
1958
1965 QtProperty *vectorProp = m_properties[prop].parent;
1966 if (!vectorProp)
1967 throw std::runtime_error("FunctionTreeView: inconsistency in vector properties.");
1968 attributeChanged(vectorProp);
1969}
1970
1972 auto tieProp = getTieProperty(prop);
1973 if (tieProp && !tieProp->isEnabled()) {
1974 // it is a fixed tie
1975 QString newTie = QString("%1=%2").arg(prop->propertyName()).arg(m_parameterManager->value(prop));
1976 if (!newTie.isEmpty()) {
1977 m_tieManager->setValue(tieProp, newTie);
1978 }
1979 }
1981 setErrorsEnabled(false);
1983 }
1984}
1985
1987void FunctionTreeView::tieChanged(QtProperty *prop) {
1988 for (const auto &atie : m_ties) {
1989 if (atie.tieProp == prop) {
1990 emit parameterTieChanged(getParameterName(prop), getTie(prop));
1991 }
1992 }
1993}
1994
1997 for (const auto &constr : m_constraints) {
1998 const bool isLower = constr.lower == prop;
1999 const bool isUpper = constr.upper == prop;
2000 if (isLower || isUpper) {
2001 auto paramProp = getParentParameterProperty(prop);
2002 QString functionIndex, constraint;
2003 std::tie(functionIndex, constraint) = getFunctionAndConstraint(paramProp);
2004 if (!constraint.isEmpty()) {
2005 emit parameterConstraintAdded(functionIndex, constraint);
2006 return; // No need to keep looping as found constraint changed
2007 }
2008 }
2009 }
2010}
2011
2013 emit localParameterButtonClicked(getIndex(prop) + prop->propertyName());
2014}
2015
2016bool FunctionTreeView::hasFunction() const { return !m_functionManager->properties().isEmpty(); }
2017
2022void FunctionTreeView::setColumnSizes(int s0, int s1, int s2) { m_browser->setColumnSizes(s0, s1, s2); }
2023
2024void FunctionTreeView::setStretchLastColumn(bool stretch) { m_browser->setStretchLastColumn(stretch); }
2025
2028// Hide global column
2030
2039void FunctionTreeView::setMultiDomainFunctionPrefix(const QString &functionPrefix) {
2040 m_multiDomainFunctionPrefix = functionPrefix;
2041}
2042
2050void FunctionTreeView::setGlobalTies(std::vector<GlobalTie> const &globalTies) { m_globalTies = globalTies; }
2051
2055void FunctionTreeView::globalChanged(QtProperty *, const QString &, bool) {
2057}
2058
2063void FunctionTreeView::setErrorsEnabled(bool enabled) { m_parameterManager->setErrorsEnabled(enabled); }
2064
2069
2070boost::optional<QString> FunctionTreeView::currentFunctionIndex() const { return m_currentFunctionIndex; }
2071
2073 boost::optional<QString> newIndex;
2074
2075 if (auto item = m_browser->currentItem()) {
2076 auto prop = item->property();
2077 newIndex = getIndex(prop);
2078 }
2079
2080 if (m_currentFunctionIndex != newIndex) {
2081 m_currentFunctionIndex = newIndex;
2083 }
2084}
2085
2086void FunctionTreeView::setParameterTie(const QString &paramName, const QString &tie) {
2087 auto paramProp = getParameterProperty(paramName);
2088 auto tieProp = getTieProperty(paramProp);
2089 if (!tie.isEmpty()) {
2090 if (tieProp) {
2091 m_tieManager->setValue(tieProp, tie);
2092 } else {
2093 addTieProperty(paramProp, tie);
2094 }
2095 } else if (tieProp) {
2096 removeProperty(tieProp);
2097 }
2098}
2099
2100void FunctionTreeView::setParameterConstraint(const QString &paramName, const QString &constraint) {
2101 auto paramProp = getParameterProperty(paramName);
2102 if (hasConstraint(paramProp)) {
2103 removeConstraintsQuiet(paramProp);
2104 }
2105 addConstraintProperties(paramProp, constraint);
2106}
2107
2109 QStringList globals;
2110 for (auto prop : m_properties) {
2111 if (prop.prop->checkOption(globalOptionName)) {
2112 auto const name = getParameterName(prop.prop);
2113 globals << name;
2114 }
2115 }
2116 return globals;
2117}
2118
2119void FunctionTreeView::setGlobalParameters(const QStringList &globals) {
2120 for (auto ap : m_properties) {
2121 auto prop = ap.prop;
2122 if (!prop->hasOption(globalOptionName))
2123 continue;
2124
2125 auto const parameterName = getParameterName(prop);
2126 auto const isGlobal = std::any_of(globals.cbegin(), globals.cend(), [&](QString const &global) {
2127 return m_multiDomainFunctionPrefix + global == parameterName;
2128 });
2129 prop->setOption(globalOptionName, isGlobal);
2130 }
2131}
2132
2133QTreeWidgetItem *FunctionTreeView::getPropertyWidgetItem(QtProperty *prop) const {
2134 return m_browser->getItemWidget(m_properties.find(prop)->item);
2135}
2136
2137QRect FunctionTreeView::visualItemRect(QtProperty *prop) const {
2138 if (!prop)
2139 return QRect();
2140 auto item = getPropertyWidgetItem(prop);
2141 return item->treeWidget()->visualItemRect(item);
2142}
2143
2145 QRect rect;
2146 try {
2148 } catch (std::exception &) {
2149 }
2150 return rect;
2151}
2152
2153QRect FunctionTreeView::getVisualRectParameterProperty(const QString &paramName) const {
2154 QRect rect;
2155 try {
2157 } catch (std::exception &) {
2158 }
2159 return rect;
2160}
2161
2162QWidget *FunctionTreeView::getParamWidget(const QString &paramName) const {
2163 try {
2164 auto item = getPropertyWidgetItem(getParameterProperty(paramName));
2165 return item->treeWidget()->itemWidget(item, 1);
2166 } catch (std::exception &) {
2167 }
2168 return nullptr;
2169}
2170
2171QTreeWidget *FunctionTreeView::treeWidget() const { return m_browser->treeWidget(); }
2172
2173QtTreePropertyBrowser *FunctionTreeView::treeBrowser() { return m_browser; }
2174
2175DoubleDialogEditorFactory *FunctionTreeView::doubleEditorFactory() { return m_doubleEditorFactory; }
2176
2177} // namespace MantidQt::MantidWidgets
double value
The value of the point.
Definition: FitMW.cpp:51
double error
Definition: IndexPeaks.cpp:133
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
double top
Definition: LineProfile.cpp:78
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition: System.h:64
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, const QString &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.
QString getParameterName(QtProperty *prop) const
Get name of the parameter for a property.
QRect getVisualRectFunctionProperty(const QString &index) const
QAction * m_actionRemoveConstraint
Remove one constraints from current parameter.
void setParameter(const QString &paramName, double value) override
Update the function parameter value.
QtStringPropertyManager * m_attributeStringManager
Manager for function string attribute properties.
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.
void addTie()
Add a tie to a parameter.
QtProperty * getTieProperty(QtProperty *prop) const
Get a tie property attached to a parameter property.
QAction * m_actionFixParameter
Fix a parameter.
bool isBoolAttribute(QtProperty *prop) const
Check if property is a bool attribute.
void popupMenu(const QPoint &)
Show the context menu.
QtIntPropertyManager * m_attributeSizeManager
Manager for vector attribute size properties.
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.
QtProperty * getAttributeProperty(const QString &paramName) const
Get a property for a parameter.
void showFunctionHelp(const QString &functionName) const override
Show function help page for input functionName.
QtGroupPropertyManager * m_attributeVectorManager
Manager for vector attribute properties.
QRect visualItemRect(QtProperty *prop) const
boost::optional< QString > currentFunctionIndex() const override
Index of currently selected function.
QAction * m_actionFromClipboard
Copy a function from the clipboard.
void removeProperty(QtProperty *prop)
Remove and delete property.
QAction * m_actionFunctionHelp
Show function help menu.
IFunction::Attribute getAttribute(const QString &attrName) const override
Get a value of a attribute.
void setVectorAttribute(const QString &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...
QRect getVisualRectParameterProperty(const QString &paramName) const
void copyToClipboard()
Copy the function to the clipboard.
QtStringPropertyManager * m_workspaceManager
Manager for Workspace attributes.
QtTreePropertyBrowser * m_browser
Qt property browser which displays properties.
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.
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.
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.
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.
QString getAttributeName(QtProperty *prop) const
Get name of the attribute for a property.
void setMultiDomainFunctionPrefix(const QString &functionPrefix)
The function index displayed as a multi-domain function index at the top of the FunctionTreeView.
QtProperty * getParameterProperty(const QString &paramName) const
Get a property for a parameter Get a property for a parameter.
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.
void setBooleanAttribute(const QString &attrName, bool value) override
Updates the value of a boolean attribute.
void setParameterTie(const QString &paramName, const QString &tie) override
Set a tie.
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.
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.
QAction * m_actionRemoveConstraints
Remove both constraints from current parameter.
QString m_multiDomainFunctionPrefix
The function prefix of the domain with a MultiDomainFunction currently being displayed.
QString getFullTie(const QString &tie) const
Gets the full tie when using the m_multiDomainFunctionPrefix.
boost::optional< QString > m_currentFunctionIndex
Index of currently selected function.
AProperty addAttributeProperty(QtProperty *parent, const QString &attName, const Mantid::API::IFunction::Attribute &att)
Add a attribute property.
void addMultiDomainIndexProperty(QtProperty *prop)
Adds an index property representing the function index of a specific domain within a MultiDomainFunct...
QWidget * getParamWidget(const QString &paramName) const
QtDoublePropertyManager * m_constraintManager
Manager for parameter constraint properties.
void updateFunctionIndices(QtProperty *prop=nullptr, const QString &index="")
Update function index 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.
QStringList getGlobalParameters() const
Get a list of global parameters.
void tieChanged(QtProperty *)
Called when a tie property changes.
void setStretchLastColumn(bool stretch)
Set the last column to stretch.
void setDoubleAttribute(const QString &attrName, double value) override
Update a double attribute.
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.
AProperty addFunctionProperty(QtProperty *parent, const QString &funName)
Add a function property.
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.
QString getConstraint(const QString &paramName, const double &lowerBound=Mantid::EMPTY_DBL(), const double &upperBound=Mantid::EMPTY_DBL()) const
Get a constraint string.
QtIntPropertyManager * m_attributeIntManager
Manager for function int attribute properties.
void setParameterError(const QString &paramName, double error) override
Update the function parameter error.
void setStringAttribute(const QString &attrName, std::string &value) override
Updates the value of a string attribute.
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.
AProperty addParameterProperty(QtProperty *parent, const QString &paramName, const QString &paramDesc, double paramValue)
Add a parameter property.
void addTieProperty(QtProperty *prop, const QString &tie, bool globalTie=false)
Add a tie property.
QList< AProperty > addConstraintProperties(QtProperty *prop, const QString &constraint)
Add a constraint property.
bool isIntAttribute(QtProperty *prop) const
Check if property is a int attribute.
double getParameter(const QString &paramName) const override
Get a value of a parameter.
void setErrorsEnabled(bool enabled) override
Set error display on/off.
QtStringPropertyManager * m_tieManager
Manager for function tie properties.
void updateCurrentFunctionIndex()
Update index of currently selected function.
std::pair< QString, QString > getFunctionAndConstraint(QtProperty *prop) const
Get a pair of function index (eg f0.f2.) and constraint expression given a parameter property.
ParameterPropertyManager * m_parameterManager
Manager for function parameter properties.
void setGlobalParameters(const QStringList &) override
Set new global parameters.
void createActions()
Create and connect actions.
bool isAttribute(QtProperty *prop) const
Check if property is a function attribute.
QString getIndex(QtProperty *prop) const
Get the function index for a property.
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.
QAction * m_actionAddFunction
Add a function.
void globalChanged(QtProperty *, const QString &, bool)
Called when "Global" check-box was clicked.
void setIntAttribute(const QString &attrName, int value) override
Updates the value of a integer attribute.
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.
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.
void attributeChanged(QtProperty *)
Called when a function attribute property is changed.
void removeConstraintsQuiet(QtProperty *paramProp)
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.
bool isVectorAttribute(QtProperty *prop) const
Check if property is a vector attribute.
void setParameterConstraint(const QString &paramName, const QString &constraint) override
Set a constraint.
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.
QtStringPropertyManager * m_indexManager
Manager for function index properties.
The interface to a function view.
Definition: IFunctionView.h:26
void globalsChanged(const QStringList &)
User changed the list of global parameters.
void attributePropertyChanged(const QString &attrName)
Function attribute gets changed.
void parameterConstraintAdded(const QString &functionIndex, const QString &constraint)
User sets a constraint.
void localParameterButtonClicked(const QString &parName)
In multi-dataset context a button value editor was clicked.
void parameterTieChanged(const QString &parName, const QString &tie)
User sets a tie.
void copyToClipboardRequest()
User requested copy function to clipboard.
void functionRemoved(const QString &functionIndex)
User removes a function.
void functionHelpRequest()
User requested function help.
void parameterConstraintRemoved(const QString &paramName)
User removes a constraint.
void functionAdded(const QString &funStr)
User adds a function.
void functionReplaced(const QString &funStr)
User replaces the whole function (eg, by pasting it from clipboard)
void functionRemovedString(const QString &funStr)
User removes a function.
void currentFunctionChanged()
User selects a different (sub)function (or one of it's sub-properties)
void parameterChanged(const QString &paramName)
Function parameter gets changed.
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:282
T apply(AttributeVisitor< T > &v)
Apply an attribute visitor.
Definition: IFunction.h:300
Const version of AttributeVisitor.
Definition: IFunction.h:241
This is an interface to a fitting function - a semi-abstarct class.
Definition: IFunction.h:163
virtual Attribute getAttribute(const std::string &name) const
Return a value of attribute attName.
Definition: IFunction.cpp:1394
virtual void setAttribute(const std::string &name, const Attribute &)
Set a value to attribute attName.
Definition: IFunction.cpp:1409
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition: Logger.h:52
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
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< QString, std::pair< QString, QString > > 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 std::pair< QString, QString > splitParameterName(const QString &paramName)
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:732
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:43
STL namespace.
std::string to_string(const wide_integer< Bits, Signed > &n)
To keep QtProperty and its QtBrowserItem in one place.
QtProperty * paramProp
Parameter property.