Mantid
Loading...
Searching...
No Matches
EditLocalParameterDialog.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 +
8
12
13#include <QClipboard>
14#include <QMenu>
15#include <QMessageBox>
16#include <limits>
17#include <utility>
18
19namespace {
20QString makeNumber(double d) { return QString::number(d, 'g', 16); }
21const int valueColumn = 0;
22const int roleColumn = 1;
23} // namespace
24
26
38EditLocalParameterDialog::EditLocalParameterDialog(QWidget *parent, const std::string &parName,
39 const std::vector<std::string> &datasetNames,
40 const std::vector<std::string> &datasetDomainNames,
41 const QList<double> &values, const QList<bool> &fixes,
42 const QStringList &ties, const QStringList &constraints)
43 : MantidDialog(parent), m_parName(parName), m_values(values), m_fixes(fixes), m_ties(std::move(ties)),
44 m_constraints(std::move(constraints)) {
45 assert(static_cast<std::size_t>(values.size()) == datasetDomainNames.size());
46 assert(static_cast<std::size_t>(fixes.size()) == datasetDomainNames.size());
47 assert(static_cast<std::size_t>(ties.size()) == datasetDomainNames.size());
48 assert(static_cast<std::size_t>(constraints.size()) == datasetDomainNames.size());
49 m_uiForm.setupUi(this);
50 setAttribute(Qt::WA_DeleteOnClose);
51 doSetup(parName, datasetNames, datasetDomainNames);
52}
53
62void EditLocalParameterDialog::doSetup(const std::string &parName, const std::vector<std::string> &datasetNames,
63 const std::vector<std::string> &datasetDomainNames) {
64 m_logFinder = std::make_unique<LogValueFinder>(stdVectorToQStringList(datasetNames));
65 // Populate list of logs
66 auto *logCombo = m_uiForm.logValueSelector->getLogComboBox();
67 for (const auto &logName : m_logFinder->getLogNames()) {
68 logCombo->addItem(QString::fromStdString(logName));
69 }
70
71 m_uiForm.logValueSelector->setCheckboxShown(true);
72 connect(m_uiForm.logValueSelector, SIGNAL(logOptionsEnabled(bool)), this, SIGNAL(logOptionsChecked(bool)));
73 QHeaderView *header = m_uiForm.tableWidget->horizontalHeader();
74 header->setSectionResizeMode(QHeaderView::Stretch);
75 connect(m_uiForm.tableWidget, SIGNAL(cellChanged(int, int)), this, SLOT(valueChanged(int, int)));
76 m_uiForm.lblParameterName->setText("Parameter: " + QString::fromStdString(parName));
77
78 for (int i = 0; i < static_cast<int>(datasetDomainNames.size()); i++) {
79 m_uiForm.tableWidget->insertRow(i);
80 auto cell = new QTableWidgetItem(makeNumber(m_values[i]));
81 m_uiForm.tableWidget->setItem(i, valueColumn, cell);
82 auto headerItem = new QTableWidgetItem(QString::fromStdString(datasetDomainNames[i]));
83 m_uiForm.tableWidget->setVerticalHeaderItem(i, headerItem);
84 cell = new QTableWidgetItem("");
85 auto flags = cell->flags();
86 flags ^= Qt::ItemIsEditable;
87 flags ^= Qt::ItemIsSelectable;
88 flags ^= Qt::ItemIsEnabled;
89 cell->setFlags(flags);
90 m_uiForm.tableWidget->setItem(i, roleColumn, cell);
92 }
93 auto deleg = new LocalParameterItemDelegate(this);
94 m_uiForm.tableWidget->setItemDelegateForColumn(valueColumn, deleg);
95 connect(deleg, SIGNAL(setAllValues(double)), this, SLOT(setAllValues(double)));
96 connect(deleg, SIGNAL(fixParameter(int, bool)), this, SLOT(fixParameter(int, bool)));
97 connect(deleg, SIGNAL(setAllFixed(bool)), this, SLOT(setAllFixed(bool)));
98 connect(deleg, SIGNAL(setTie(int, QString)), this, SLOT(setTie(int, QString)));
99 connect(deleg, SIGNAL(setTieAll(QString)), this, SLOT(setTieAll(QString)));
100 connect(deleg, SIGNAL(setConstraint(int, QString)), this, SLOT(setConstraint(int, QString)));
101 connect(deleg, SIGNAL(setConstraintAll(QString)), this, SLOT(setConstraintAll(QString)));
102 connect(deleg, SIGNAL(setValueToLog(int)), this, SLOT(setValueToLog(int)));
103 connect(deleg, SIGNAL(setAllValuesToLog()), this, SLOT(setAllValuesToLog()));
104
105 m_uiForm.tableWidget->installEventFilter(this);
106
107 connect(this, SIGNAL(finished(int)), this, SLOT(emitDialogFinished(int)));
108}
109
110void EditLocalParameterDialog::emitDialogFinished(int result) { emit dialogFinished(result, this); }
111
116 if (col == valueColumn) {
117 QString text = m_uiForm.tableWidget->item(row, col)->text();
118 try {
119 bool ok = false;
120 double value = text.toDouble(&ok);
121 if (ok) {
122 m_values[row] = value;
123 } else {
124 m_ties[row] = text;
125 }
126 } catch (std::exception &) {
127 // restore old value
128 m_uiForm.tableWidget->item(row, col)->setText(makeNumber(m_values[row]));
129 }
130 }
131}
132
136 int n = m_values.size();
137 for (int i = 0; i < n; ++i) {
138 m_values[i] = value;
139 m_uiForm.tableWidget->item(i, valueColumn)->setText(makeNumber(value));
141 }
142}
143
146
149
151const QStringList &EditLocalParameterDialog::getTies() const { return m_ties; }
152
154const QStringList &EditLocalParameterDialog::getConstraints() const { return m_constraints; }
155
160 m_fixes[index] = fix;
161 m_ties[index] = "";
163}
164
169 m_ties[index] = std::move(tie);
170 m_fixes[index] = false;
172}
173
176void EditLocalParameterDialog::setTieAll(const QString &tie) {
177 for (int i = 0; i < m_ties.size(); ++i) {
178 m_ties[i] = tie;
179 m_fixes[i] = false;
181 }
182 redrawCells();
183}
184
185void EditLocalParameterDialog::setConstraint(int index, QString constraint) {
186 m_constraints[index] = std::move(constraint);
188}
189
190void EditLocalParameterDialog::setConstraintAll(const QString &constraint) {
191 for (int i = 0; i < m_constraints.size(); ++i) {
192 m_constraints[i] = constraint;
194 }
195 redrawCells();
196}
197
201 if (m_fixes.empty())
202 return;
203 for (int i = 0; i < m_fixes.size(); ++i) {
204 m_fixes[i] = fix;
205 m_ties[i] = "";
207 }
208 redrawCells();
209}
210
212bool EditLocalParameterDialog::eventFilter(QObject *obj, QEvent *ev) {
213 if (obj == m_uiForm.tableWidget && ev->type() == QEvent::ContextMenu) {
215 }
216 return QDialog::eventFilter(obj, ev);
217}
218
221 auto selection = m_uiForm.tableWidget->selectionModel()->selectedColumns();
222
223 bool hasSelection = false;
224
225 for (auto &index : selection) {
226 if (index.column() == valueColumn)
227 hasSelection = true;
228 }
229
230 if (!hasSelection)
231 return;
232
233 QMenu *menu = new QMenu(this);
234 {
235 QAction *action = new QAction("Copy", this);
236 action->setToolTip("Copy data to clipboard.");
237 connect(action, SIGNAL(triggered()), this, SLOT(copy()));
238 menu->addAction(action);
239 }
240 {
241 QAction *action = new QAction("Paste", this);
242 action->setToolTip("Paste data from clipboard.");
243 connect(action, SIGNAL(triggered()), this, SLOT(paste()));
244 auto text = QApplication::clipboard()->text();
245 action->setEnabled(!text.isEmpty());
246 menu->addAction(action);
247 }
248
249 menu->exec(QCursor::pos());
250}
251
255 QStringList text;
256 auto n = m_values.size();
257 for (int i = 0; i < n; ++i) {
258 text << makeNumber(m_values[i]);
259 }
260 QApplication::clipboard()->setText(text.join("\n"));
261}
262
265 auto text = QApplication::clipboard()->text();
266 auto vec = text.split(QRegExp("\\s|,"), Qt::SkipEmptyParts);
267 auto n = qMin(vec.size(), m_uiForm.tableWidget->rowCount());
268 // prepare for pasting data
269 auto deleg = static_cast<LocalParameterItemDelegate *>(m_uiForm.tableWidget->itemDelegateForColumn(valueColumn));
270 deleg->prepareForPastedData();
271 // insert data into table
272 for (int i = 0; i < n; ++i) {
273 auto str = vec[i];
274 bool ok;
275 m_values[i] = str.toDouble(&ok);
276 if (!ok)
277 str = "0";
278 m_uiForm.tableWidget->item(i, valueColumn)->setText(str);
279 }
280}
281
284 for (int i = 0; i < m_values.size(); ++i) {
285 // it's the only way I am able to make the table to repaint itself
286 auto text = makeNumber(m_values[i]);
287 m_uiForm.tableWidget->item(i, valueColumn)->setText(text + " ");
288 m_uiForm.tableWidget->item(i, valueColumn)->setText(text);
289 }
290}
291
294 auto cell = m_uiForm.tableWidget->item(index, roleColumn);
295 QString text;
296 if (m_fixes[index]) {
297 text = "fixed";
298 cell->setForeground(QBrush(Qt::red));
299 } else if (!m_ties[index].isEmpty()) {
300 text = "tied";
301 cell->setForeground(QBrush(Qt::blue));
302 } else {
303 text = "fitted";
304 cell->setForeground(QBrush(Qt::darkGreen));
305 }
306 if (!m_constraints[index].isEmpty()) {
307 text += ", " + m_constraints[index];
308 }
309 cell->setText(text);
310}
311
314 for (int j = 0; j < m_fixes.size(); ++j) {
315 if (j != i && m_fixes[j])
316 return true;
317 }
318 return false;
319}
320
323 for (int j = 0; j < m_fixes.size(); ++j) {
324 if (j != i && !m_fixes[j])
325 return false;
326 }
327 return true;
328}
329
332 for (int j = 0; j < m_fixes.size(); ++j) {
333 if (j != i && !m_ties[j].isEmpty())
334 return true;
335 }
336 return false;
337}
338
342 assert(i < m_values.size());
343
344 const auto &logName = m_uiForm.logValueSelector->getLog();
345 const auto &function = m_uiForm.logValueSelector->getFunction();
346
347 double value = std::numeric_limits<double>::quiet_NaN();
348 try {
349 value = m_logFinder->getLogValue(logName, function, i);
350 } catch (const std::invalid_argument &err) {
351 const auto &message = QString("Failed to get log value:\n\n %1").arg(err.what());
352 QMessageBox::critical(this, "Mantid - Error", message);
353 }
354 m_values[i] = value;
355 m_uiForm.tableWidget->item(i, valueColumn)->setText(makeNumber(value));
357}
358
361 const int nValues = m_values.size();
362 for (int i = 0; i < nValues; ++i) {
363 setValueToLog(i);
364 }
365}
366
369bool EditLocalParameterDialog::isLogCheckboxTicked() const { return m_uiForm.logValueSelector->isCheckboxTicked(); }
370
371} // namespace MantidQt::MantidWidgets
double value
The value of the point.
Definition FitMW.cpp:51
std::map< DeltaEMode::Type, std::string > index
std::vector< T > const * vec
double obj
the value of the quadratic function
EditLocalParameterDialog(QWidget *parent, const std::string &parName, const std::vector< std::string > &datasetNames, const std::vector< std::string > &datasetDomainNames, const QList< double > &values, const QList< bool > &fixes, const QStringList &ties, const QStringList &constraints)
Constructor for EditLocalParameterDialog used in FunctionBrowser.
const QList< double > & getValues() const
Get the list of new parameter values.
std::unique_ptr< LogValueFinder > m_logFinder
Log value finder.
void setTieAll(const QString &)
Set the same tie to all parameters.
QList< bool > m_fixes
Cache for the "fixed" attribute.
void copy()
Copy all parameter values to the clipboard.
bool areAllOthersFixed(int i) const
Check if all other parameters are fixed.
void updateRoleColumn(int index)
Update the text in the role column.
void fixParameter(int, bool)
Fix/unfix a single parameter.
QStringList m_constraints
Cache for the constraints.
QList< double > m_values
Cache for new values. size() == number of spectra.
const QStringList & getConstraints() const
Get a list of the constraints.
bool areOthersTied(int i) const
Check if there are any other tied parameters.
bool eventFilter(QObject *obj, QEvent *ev) override
Event filter for managing the context menu.
void paste()
Paste a list of values from the clipboard.
bool isLogCheckboxTicked() const
Returns whether log checkbox is ticked or not.
void redrawCells()
Force the table to redraw its cells.
void dialogFinished(int, EditLocalParameterDialog *)
const QStringList & getTies() const
Get a list of the ties.
const QList< bool > & getFixes() const
Get a list with the "fixed" attribute.
void setTie(int, QString)
Set a new tie for a parameter.
void doSetup(const std::string &parName, const std::vector< std::string > &datasetDomains, const std::vector< std::string > &datasetDomainNames)
Common setup method used by both constructors Prerequisite: one of the constructors must have filled ...
bool areOthersFixed(int i) const
Check if there are any other fixed parameters.
void setAllValues(double)
Set all parameters to the same value.
void setAllValuesToLog()
Set value of each parameter to log value from respective workspace.
A custom item delegate - an object controlling display and editing of a cell in a table widget.
void prepareForPastedData()
Data is about to be pasted into the table.
QStringList EXPORT_OPT_MANTIDQT_COMMON stdVectorToQStringList(std::vector< std::string > const &vec)
STL namespace.