14#include <QDialogButtonBox>
18#include <QStringListModel>
29 connect(
m_uiForm.lstCategory, SIGNAL(currentTextChanged(
const QString &)),
this,
31 connect(
m_uiForm.lstFunction, SIGNAL(currentTextChanged(
const QString &)),
this,
36 connect(
m_uiForm.btnUse, SIGNAL(clicked()),
this, SLOT(accept()));
37 connect(
m_uiForm.btnCancel, SIGNAL(clicked()),
this, SLOT(reject()));
40 m_uiForm.teUserFunction->installEventFilter(
this);
44 if (!formula.isEmpty()) {
46 QTextCursor cursor =
m_uiForm.teUserFunction->cursorForPosition(
rect.topLeft());
47 cursor.insertText(formula);
64 setFunction(
"Base",
"abs",
"abs(x)",
"Absolute value of x");
66 setFunction(
"Base",
"cos",
"cos(x)",
"Cosine of x");
67 setFunction(
"Base",
"tan",
"tan(x)",
"Tangent of x");
68 setFunction(
"Base",
"asin",
"asin(x)",
"Arc-sine of x");
69 setFunction(
"Base",
"acos",
"acos(x)",
"Arc-cosine of x");
70 setFunction(
"Base",
"atan",
"atan(x)",
"Arc-tangent of x");
71 setFunction(
"Base",
"sinh",
"sinh(x)",
"Sine hyperbolic of x");
72 setFunction(
"Base",
"cosh",
"cosh(x)",
"Cosine hyperbolic of x");
73 setFunction(
"Base",
"tanh",
"tanh(x)",
"Tangent hyperbolic of x");
74 setFunction(
"Base",
"asinh",
"asinh(x)",
"Arc-sine hyperbolic of x");
75 setFunction(
"Base",
"acosh",
"acosh(x)",
"Arc-cosine hyperbolic of x");
76 setFunction(
"Base",
"atanh",
"atanh(x)",
"Arc-tangent hyperbolic of x");
77 setFunction(
"Base",
"log2",
"log2(x)",
"Logarithm to the base 2");
78 setFunction(
"Base",
"log10",
"log10(x)",
"Logarithm to the base 10");
79 setFunction(
"Base",
"log",
"log(x)",
"Logarithm to the base 10");
80 setFunction(
"Base",
"ln",
"ln(x)",
"Logarithm to the base e = 2.71828...");
81 setFunction(
"Base",
"exp",
"exp(x)",
"e to the power of x");
82 setFunction(
"Base",
"sqrt",
"sqrt(x)",
"Sqare root of x");
83 setFunction(
"Base",
"sign",
"sign(x)",
"Sign of x");
84 setFunction(
"Base",
"rint",
"rint(x)",
"Round to nearest integer");
85 setFunction(
"Base",
"erf",
"erf(x)",
"error function of x");
86 setFunction(
"Base",
"erfc",
"erfc(x)",
"Complementary error function erfc(x) = 1 - erf(x)");
87 setFunction(
"Built-in",
"Gauss",
"h*exp(-s*(x-c)^2)");
90 "Mantid.user.functions");
91 if (funFile.exists() && funFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
92 QTextStream in(&funFile);
94 QString line = in.readLine();
95 QStringList key_value = line.split(
'=');
96 if (key_value.size() != 2)
98 m_funs.insert(key_value[0].trimmed(), key_value[1].trimmed());
111 foreach (QString cat, cats) {
m_uiForm.lstCategory->addItem(cat); }
113 auto items =
m_uiForm.lstCategory->findItems(currentCategory, Qt::MatchExactly);
114 if (!items.isEmpty()) {
115 m_uiForm.lstCategory->setCurrentItem(items[0]);
126 foreach (QString fun, funs) {
128 if (!
value.isEmpty()) {
132 if (
m_uiForm.lstFunction->count() > 0) {
134 m_uiForm.lstFunction->setCurrentRow(0);
149 QString cat =
m_uiForm.lstCategory->currentItem()->text();
154 if (!comment.isEmpty()) {
155 value +=
"\n\n" + comment;
165 QString expr =
m_uiForm.teExpression->toPlainText();
166 int iBr = expr.indexOf(
'\n');
168 expr.remove(iBr, expr.size());
177 QTextCursor cursor =
m_uiForm.teUserFunction->cursorForPosition(
rect.topLeft());
178 if (cursor.position() > 0) {
181 cursor.insertText(expr);
193 QString fun =
m_uiForm.teUserFunction->toPlainText();
201 e1.
parse(fun.toStdString());
202 e2.
parse(expr.toStdString());
212 std::vector<std::string> all(vars1.size() + vars2.size(),
"");
213 std::set_union(vars1.begin(), vars1.end(), vars2.begin(), vars2.end(), all.begin());
214 std::vector<std::string>::iterator it = std::find(all.begin(), all.end(),
"");
215 if (it != all.end()) {
216 all.erase(it, all.end());
220 std::vector<std::string> common(std::min<size_t>(vars1.size(), vars2.size()),
"");
221 std::set_intersection(vars1.begin(), vars1.end(), vars2.begin(), vars2.end(), common.begin());
222 it = std::find(common.begin(), common.end(),
"");
223 if (it != common.end()) {
224 common.erase(it, common.end());
228 if (!common.empty()) {
230 if (dlg.exec() == QDialog::Accepted) {
232 std::vector<std::string>::const_iterator v_old = common.begin();
233 std::vector<std::string>::const_iterator v_new = vars_new.begin();
234 for (; v_old != common.end(); ++v_old, ++v_new) {
236 expr = QString::fromStdString(e2.
str());
248 QString fun =
m_uiForm.teUserFunction->toPlainText();
251 e.
parse(fun.toStdString());
259 for (
auto it = vars.begin(); it != vars.end(); ++it) {
260 if (it != vars.begin()) {
263 params += QString::fromStdString(*it);
273 QMap<QString, QString>::const_iterator it =
m_funs.begin();
274 for (; it !=
m_funs.end(); ++it) {
275 QStringList cn = it.key().split(
'.');
288 QMap<QString, QString>::const_iterator it =
m_funs.begin();
289 for (; it !=
m_funs.end(); ++it) {
290 QStringList cn = it.key().split(
'.');
304 QString cur_category;
305 QListWidgetItem *currentCategoryItem =
m_uiForm.lstCategory->currentItem();
306 if (currentCategoryItem) {
307 cur_category =
m_uiForm.lstCategory->currentItem()->text();
319 if (cur_category ==
"Base" || cur_category ==
"Built-in") {
324 if (dlg->exec() == QDialog::Accepted) {
328 dlg->getFunctionName(cat, fun, comment);
330 QMessageBox::critical(
this,
"Mantid - Error",
"The function name is empty");
335 if (!items.isEmpty()) {
337 QSet<QString>::const_iterator found = functions.find(fun);
338 if (found != functions.end() &&
339 QMessageBox::question(
this,
"Mantid",
340 "A function with name " + fun +
" already exists in category " + cat +
342 "Would you like to replace it?",
343 QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
347 QString expr =
m_uiForm.teUserFunction->toPlainText();
356 "Mantid.user.functions");
357 if (funFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
358 QMap<QString, QString>::const_iterator it =
m_funs.begin();
359 for (; it !=
m_funs.end(); ++it) {
360 QTextStream out(&funFile);
361 QStringList cn = it.key().split(
'.');
362 if (cn[0] !=
"Base" && cn[0] !=
"Built-in") {
363 out << it.key() <<
"=" << it.value() <<
'\n';
373 QString cat =
m_uiForm.lstCategory->currentItem()->text();
378 QString fun =
m_uiForm.lstFunction->currentItem()->text();
379 if (QMessageBox::question(
this,
"Mantid",
"Are you sure you want to remove function " + fun +
"?",
380 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
381 QString fun_key = cat +
"." + fun;
382 QMap<QString, QString>::iterator it =
m_funs.find(fun_key);
385 it =
m_funs.find(fun_key +
".comment");
397 for (
int i = 0; i <
m_uiForm.lstCategory->count(); ++i) {
398 out <<
m_uiForm.lstCategory->item(i)->text();
404 if (ev->type() == QEvent::KeyPress) {
405 auto *keyEvent =
static_cast<QKeyEvent *
>(ev);
406 if (keyEvent->key() == Qt::Key_Return) {
412 return QObject::eventFilter(
obj, ev);
424 if (cat.isEmpty() || fun.isEmpty())
426 QMap<QString, QString>::const_iterator it =
m_funs.find(cat +
"." + fun);
440 if (cat.isEmpty() || fun.isEmpty())
442 QMap<QString, QString>::const_iterator it =
m_funs.find(cat +
"." + fun +
".comment");
458 const QString &comment) {
459 if (cat.isEmpty() || fun.isEmpty() || expr.isEmpty())
462 QString fun_key = cat +
"." + fun;
464 QString cmnt_key = fun_key +
".comment";
465 if (!comment.isEmpty()) {
466 m_funs[cmnt_key] = comment;
468 QMap<QString, QString>::iterator it =
m_funs.find(cmnt_key);
493 auto *layout =
new QVBoxLayout();
494 layout->addWidget(
new QLabel(
"Enter new or select a category"));
496 cats.removeOne(
"Base");
497 cats.removeOne(
"Built-in");
506 connect(
m_category, SIGNAL(currentIndexChanged(
const QString &)), parent, SLOT(selectCategory(
const QString &)));
507 layout->addWidget(
new QLabel(
"Enter a name for the new function"));
509 layout->addWidget(
m_name);
510 layout->addWidget(
new QLabel(
"Enter a comment"));
514 auto *buttons =
new QDialogButtonBox();
515 buttons->addButton(
"OK", QDialogButtonBox::AcceptRole);
516 buttons->addButton(
"Cancel", QDialogButtonBox::RejectRole);
517 buttons->setCenterButtons(
true);
518 connect(buttons, SIGNAL(accepted()),
this, SLOT(accept()));
519 connect(buttons, SIGNAL(rejected()),
this, SLOT(reject()));
520 layout->addWidget(buttons);
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
double obj
the value of the quadratic function
This class provides a wrapper around QDesktopServices to fix a bug in opening URLs in firefox when tc...
static bool openUrl(const QUrl &url)
Opens a url in the appropriate web browser.
This class represents an expression made up of names, binary operators and brackets.
std::unordered_set< std::string > getVariables() const
Return a list of all variable names in this expression.
void parse(const std::string &str)
Parse a string and create an expression.
void renameAll(const std::string &oldName, const std::string &newName)
Rename all variables with a given name.
std::string str() const
Returns this expression as a string.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...