Mantid
Loading...
Searching...
No Matches
SelectFunctionDialog.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 +
7//-------------------------------------------
8// Includes
9//-------------------------------------------
11#include "ui_SelectFunctionDialog.h"
12
14#include "MantidAPI/IFunction.h"
16
17#include <boost/lexical_cast.hpp>
18
19#include <QButtonGroup>
20#include <QCheckBox>
21#include <QComboBox>
22#include <QCompleter>
23#include <QGridLayout>
24#include <QGroupBox>
25#include <QIcon>
26#include <QLabel>
27#include <QPushButton>
28#include <QTreeWidget>
29#include <QVBoxLayout>
30
32
38 : SelectFunctionDialog(parent, std::vector<std::string>()) {}
39
45SelectFunctionDialog::SelectFunctionDialog(QWidget *parent, const std::vector<std::string> &restrictions)
46 : MantidDialog(parent), m_form(new Ui::SelectFunctionDialog) {
47 setWindowModality(Qt::WindowModal);
48 setWindowIcon(QIcon(":/images/MantidIcon.ico"));
49 m_form->setupUi(this);
50 m_form->errorMessage->hide();
51
52 auto &factory = Mantid::API::FunctionFactory::Instance();
53 auto registeredFunctions = factory.getFunctionNamesGUI();
54 // Add functions to each of the categories. If it appears in more than one
55 // category then add to both
56 // Store in a map. Key = category. Value = vector of fit functions belonging
57 // to that category.
58 std::map<std::string, std::vector<std::string>> categories;
59 for (const auto &registeredFunction : registeredFunctions) {
60 auto f = factory.createFunction(registeredFunction);
61 std::vector<std::string> tempCategories = f->categories();
62 for (size_t j = 0; j < tempCategories.size(); ++j) {
63 categories[tempCategories[boost::lexical_cast<int>(j)]].emplace_back(registeredFunction);
64 }
65 }
66
67 // Set up the search box
68 m_form->searchBox->completer()->setCompletionMode(QCompleter::PopupCompletion);
69 m_form->searchBox->completer()->setFilterMode(Qt::MatchContains);
70
71 // Complete suggestions in search box,
72 // number of suggestions same as number of registeredFunctions
73 addSearchBoxFunctionNames(registeredFunctions);
74
75 connect(m_form->searchBox, SIGNAL(editTextChanged(const QString &)), this, SLOT(searchBoxChanged(const QString &)));
76
77 // Construct the QTreeWidget based on the map information of categories and
78 // their respective fit functions.
79 constructFunctionTree(categories, restrictions);
81
82 connect(m_form->fitTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this,
83 SLOT(functionDoubleClicked(QTreeWidgetItem *)));
84 m_form->fitTree->setToolTip("Select a function type and press OK.");
85
86 connect(m_form->buttonBox, SIGNAL(accepted()), this, SLOT(acceptFunction()));
87 connect(m_form->buttonBox, SIGNAL(rejected()), this, SLOT(rejectFunction()));
88
89 m_form->searchBox->setCurrentIndex(-1);
90
91 connect(m_form->helpButton, SIGNAL(clicked()), this, SLOT(helpClicked()));
92}
93
98void SelectFunctionDialog::addSearchBoxFunctionNames(const std::vector<std::string> &registeredFunctions) {
99 for (const auto &function : registeredFunctions) {
100 m_form->searchBox->addItem(QString::fromStdString(function));
101 }
102}
103
112 const std::map<std::string, std::vector<std::string>> &categoryFunctionsMap,
113 const std::vector<std::string> &restrictions) {
114 // Don't show category if it's not in the list (unless list is empty)
115 auto showCategory = [&restrictions](const std::string &name) {
116 if (restrictions.empty()) {
117 return true;
118 } else {
119 return (std::find(restrictions.begin(), restrictions.end(), name) != restrictions.end());
120 }
121 };
122
123 // keeps track of categories added to the tree
124 QMap<QString, QTreeWidgetItem *> categories;
125
126 for (const auto &entry : categoryFunctionsMap) {
127
128 QString categoryName = QString::fromStdString(entry.first);
129 QStringList subCategories = categoryName.split('\\');
130 if (!categories.contains(categoryName)) {
131 if (subCategories.size() == 1) {
132 if (showCategory(entry.first)) {
133 QTreeWidgetItem *catItem = new QTreeWidgetItem(QStringList(categoryName));
134 categories.insert(categoryName, catItem);
135 m_form->fitTree->addTopLevelItem(catItem);
136 for (const auto &function : entry.second) {
137 QTreeWidgetItem *fit = new QTreeWidgetItem(catItem);
138 fit->setText(0, QString::fromStdString(function));
139 }
140 }
141 } else {
142 // go through the path and add the folders if they don't already exist
143 QString currentPath = subCategories[0];
144 QTreeWidgetItem *catItem = nullptr;
145 int subCategoryNo = subCategories.size();
146 bool show = false;
147 for (int j = 0; j < subCategoryNo; ++j) {
148 if (showCategory(subCategories[j].toStdString())) {
149 show = true;
150 }
151 }
152 if (show) {
153 for (int j = 0; j < subCategoryNo; ++j) {
154 if (categories.contains(currentPath)) {
155 catItem = categories[currentPath];
156 } else {
157 QTreeWidgetItem *newCatItem = new QTreeWidgetItem(QStringList(subCategories[j]));
158 categories.insert(currentPath, newCatItem);
159 if (!catItem) {
160 m_form->fitTree->addTopLevelItem(newCatItem);
161 } else {
162 catItem->addChild(newCatItem);
163 }
164 catItem = newCatItem;
165 }
166 if (j != subCategoryNo - 1)
167 currentPath += "\\" + subCategories[j + 1];
168 else {
169 // This is the end of the path so add the functions
170 for (const auto &function : entry.second) {
171 QTreeWidgetItem *fit = new QTreeWidgetItem(catItem);
172 fit->setText(0, QString::fromStdString(function));
173 }
174 }
175 }
176 }
177 }
178 }
179 }
180}
181
183
189 auto const numberOfTopLevelItems = m_form->fitTree->topLevelItemCount();
190 if (numberOfTopLevelItems > 0) {
191 auto const firstItem = m_form->fitTree->topLevelItem(0);
192 auto const itemHeight = m_form->fitTree->visualItemRect(firstItem).height();
193 m_form->fitTree->setMinimumHeight(itemHeight * numberOfTopLevelItems);
194 }
195}
196
201 const auto searchText = m_form->searchBox->currentText();
202 QList<QTreeWidgetItem *> items(m_form->fitTree->selectedItems());
203 if (items.size() == 1 && items[0]->childCount() == 0) {
204 return items[0]->text(0);
205 } else if (m_form->searchBox->findText(searchText) >= 0) {
206 return searchText;
207 }
208 return "";
209}
210
211void SelectFunctionDialog::clearSearchBoxText() const { m_form->searchBox->clearEditText(); }
212
216void SelectFunctionDialog::searchBoxChanged(const QString &text) {
217 if (text.isEmpty()) {
218 return;
219 }
220 m_form->fitTree->setCurrentIndex(QModelIndex());
221
222 const auto index = m_form->searchBox->findText(text);
223 if (index >= 0)
224 m_form->searchBox->setCurrentIndex(index);
225}
226
228 if (item->childCount() == 0)
230}
231
233 const auto func = getFunction();
234 if (func.isEmpty()) {
235 m_form->errorMessage->setText(QString("<span style='color:red'> Function not found</span> "));
236 m_form->errorMessage->show();
237 } else {
238 m_form->errorMessage->hide();
239 accept();
240 }
241}
242
244 m_form->errorMessage->hide();
245 reject();
246}
247
249 auto function = getFunction();
250 if (!function.isEmpty()) {
251 MantidQt::API::HelpWindow::showFitFunction(function.toStdString());
252 } else { // No function selected open fit function index
254 }
255}
256
257} // namespace MantidQt::MantidWidgets
std::string name
Definition Run.cpp:60
std::map< DeltaEMode::Type, std::string > index
static void showFitFunction(const std::string &name=std::string())
Select a function type out of a list of available ones.
void clearSearchBoxText() const
Clear the text in the search box.
void searchBoxChanged(const QString &text)
Called when the text in the search box changes.
QString getFunction() const
Return selected function.
void constructFunctionTree(const std::map< std::string, std::vector< std::string > > &categoryFunctionsMap, const std::vector< std::string > &restrictions)
Construct QTreeWidget with categories and functions.
Ui::SelectFunctionDialog * m_form
Ui elements form.
SelectFunctionDialog(QWidget *parent=nullptr)
Default constructor.
void addSearchBoxFunctionNames(const std::vector< std::string > &registeredFunctions)
Complete QComboBox for searching functions with available functions.
void setMinimumHeightOfFunctionTree()
Sets the minimum height of the function tree so that all catagories are visible.
STL namespace.