35#include <QListWidgetItem>
38#include <QRegularExpression>
56 if (collNameStr.contains(
"/")) {
57 QStringList tok = collNameStr.split(
'/', Qt::SkipEmptyParts);
58 collNameStr = tok[tok.count()-1];
60 QLabel *collName =
new QLabel(collNameStr);
61 QLabel *numVars =
new QLabel(QString(
"#variables: %1").arg(info.
fVarName.count()));
62 QListWidget *list =
new QListWidget();
63 for (
int i=0; i<info.
fVarName.count(); i++) {
64 QListWidgetItem *newItem =
new QListWidgetItem;
65 newItem->setText(QString(
"%1 : %2").arg(i, 2).arg(info.
fVarName[i]));
66 list->addItem(newItem);
68 QPushButton *done =
new QPushButton(
"Done",
this);
70 QVBoxLayout *vLayout =
new QVBoxLayout;
71 vLayout->addWidget(collName);
72 vLayout->addWidget(numVars);
73 vLayout->addWidget(list);
74 vLayout->addWidget(done);
76 connect(done, SIGNAL( clicked() ),
this, SLOT( accept() ));
81 setWindowTitle(
"Variable Names");
85 iconName = QString(
":/icons/varEdit-dark.svg");
87 iconName = QString(
":/icons/varEdit-plain.svg");
88 setWindowIcon( QIcon( QPixmap(iconName) ) );
114 QWidget *parent, Qt::WindowFlags f) :
115 QDialog(parent, f),
fCollList(collection_list)
117 fVarEdit = std::make_unique<QPlainTextEdit>();
119 fCancel = std::make_unique<QPushButton>(
"&Cancel",
this);
120 fCheck = std::make_unique<QPushButton>(
"Chec&k",
this);
121 fAdd = std::make_unique<QPushButton>(
"&Add",
this);
122 fHelp = std::make_unique<QPushButton>(
"&Help",
this);
123 fShowVarName = std::make_unique<QPushButton>(
"Show&VarName",
this);
126 for (
int i=0; i<
fCollList.count(); i++) {
127 QListWidgetItem *newItem =
new QListWidgetItem;
128 newItem->setText(
fCollList[i].fCollName);
132 fCollectionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
134 QHBoxLayout *hLayout0 =
new QHBoxLayout;
136 hLayout0->addWidget(
fHelp.get());
138 QHBoxLayout *hLayout1 =
new QHBoxLayout;
139 hLayout1->addWidget(
fCancel.get());
140 hLayout1->addWidget(
fCheck.get());
141 hLayout1->addWidget(
fAdd.get());
143 QLabel *varLabel =
new QLabel(
"Edit Variables:");
144 QVBoxLayout *varVLayout =
new QVBoxLayout;
145 varVLayout->addWidget(varLabel);
146 varVLayout->addWidget(
fVarEdit.get());
148 QLabel *collLabel =
new QLabel(
"Collections:");
149 QVBoxLayout *collVLayout =
new QVBoxLayout;
150 collVLayout->addWidget(collLabel);
153 QWidget *varWidget =
new QWidget(
this);
154 varWidget->setLayout(varVLayout);
155 QWidget *collWidget =
new QWidget(
this);
156 collWidget->setLayout(collVLayout);
158 QSplitter *splitter =
new QSplitter(Qt::Vertical,
this);
159 splitter->addWidget(varWidget);
160 splitter->addWidget(collWidget);
162 QVBoxLayout *vLayout =
new QVBoxLayout;
163 vLayout->addWidget(splitter);
164 vLayout->addLayout(hLayout0);
165 vLayout->addLayout(hLayout1);
171 connect(
fCancel.get(), SIGNAL( clicked() ),
this, SLOT( reject() ));
172 connect(
fCheck.get(), SIGNAL( clicked() ),
this, SLOT(
check() ));
173 connect(
fAdd.get(), SIGNAL( clicked() ),
this, SLOT(
add() ));
174 connect(
fHelp.get(), SIGNAL( clicked() ),
this, SLOT(
help() ));
177 QString iconName(
"");
179 iconName = QString(
":/icons/varEdit-dark.svg");
181 iconName = QString(
":/icons/varEdit-plain.svg");
182 setWindowIcon( QIcon( QPixmap(iconName) ) );
205 for (
int i=0; i<selected.count(); i++) {
222 if (
fVarEdit->toPlainText().isEmpty()) {
223 QMessageBox::critical(
this,
"**ERROR**",
"No input available.");
227 QMessageBox::critical(
this,
"**ERROR**",
"One or more collection(s) need to linked to the variable(s).");
240 for (
int i=0; i<selected.count(); i++) {
259 QMessageBox::information(
this,
"Var Help",
260 "Syntax: var <var_name> = <expr>.\n"\
261 "<expr> can contain identifiers defined in the collections.\n"\
262 "An identifier is an addressed variable which is defined\n"\
263 "by a preceeding '$' before the variable name.\n"\
264 "Example: variable sigma -> identifier $sigma.\n"\
265 "Example:\nvar sigSC = pow(abs(pow($sigma,2.0)-pow(0.11,2.0)),0.5)\n"\
267 "Python mode (optional):\n"\
268 "Declare the variables with '= python', then provide the\n"\
269 "calculation inside a <python> ... </python> block.\n"\
270 "Collection parameters are available as bare-name lists (one\n"\
271 "value per run); the error of a parameter 'p' is 'pErr'. Names\n"\
272 "that clash with Python (e.g. 'lambda') are reachable via\n"\
273 "par['lambda'] / parErr['lambda']. The script must assign the\n"\
274 "variable and its error (<var_name>Err). Example:\n"\
275 "var sigSC = python\n"\
276 "var sigSCErr = python\n"\
278 "import numpy as np\n"\
279 "T = np.array(sigma)\n"\
280 "sigSC = np.sqrt(np.abs(T**2 - 0.11**2))\n"\
281 "sigSCErr = T/np.where(sigSC==0,1,sigSC) * np.array(sigmaErr)\n"\
298 QMessageBox::critical(
this,
"**ERROR**",
"At least one collection needs to be selected.");
302 QMessageBox::critical(
this,
"**ERROR**",
"Currently only the vars of a single collection can be shown.");
308 QMessageBox::critical(
this,
"**ERROR**", QString(
"Collection idx=%1 > #Collections=%2. This never should have happened.").arg(idx).arg(
fCollList.count()));
333 QString varStr =
fVarEdit->toPlainText();
336 if (varStr.isEmpty()) {
337 QMessageBox::critical(
this,
"**ERROR**",
"No input available.");
341 QMessageBox::critical(
this,
"**ERROR**",
"One or more collection(s) need to linked to the variable(s).");
347 QString declStr = varStr;
348 int pyIdx = varStr.indexOf(
"<python>");
350 declStr = varStr.left(pyIdx);
353 QStringList strList = declStr.split(QRegularExpression(
"\\s+"), Qt::SkipEmptyParts);
357 for (
int i=0; i<strList.count(); i++) {
358 if (strList[i] ==
"var") {
364 QMessageBox::critical(
this,
"**ERROR**",
"<b>NO</b> 'var' definition found.");
371 QMessageBox::critical(
this,
"**ERROR**",
"found 'var' without <var_name>.");
376 QMessageBox::critical(
this,
"**ERROR**", QString(
"found <var_name>=%1 without corresponding %1Err.<br>Both, a variable <b>and</b> its corresponding error variable needs to be defined.").arg(name));
399 QString varStr =
fVarEdit->toPlainText();
403 if (varStr.contains(
"<python>"))
407 int idx = 0, idxEnd = 0;
408 QStringList varNames;
409 QVector<int> isIdendifier;
413 idx = varStr.indexOf(
"$", idx);
418 ch = varStr[idxEnd].toLatin1();
419 if (isalnum(ch) || (ch ==
'_'))
423 }
while (!done && (idxEnd <= varStr.length()));
424 varNames << varStr.mid(idx+1, idxEnd-idx-1);
425 isIdendifier.push_back(1);
433 idx = varStr.indexOf(
"var ", idx);
435 idxEnd = varStr.indexOf(
"=", idx);
439 varNames << varStr.mid(idx+4, idxEnd-idx-5);
440 isIdendifier.push_back(0);
450 for (
int i=0; i<varNames.count(); i++) {
451 if (isIdendifier[i] == 0)
454 if (str.endsWith(
"Err")) {
455 str = str.left(str.indexOf(
"Err"));
458 for (
int j=i+1; j<varNames.count(); j++) {
459 if ((varNames[j] == str) && isIdendifier[j] == 0) {
467 for (
int j=0; j<selColl.count(); j++) {
470 for (
int k=0; k<
fCollList[idx].fVarName.count(); k++) {
477 QMessageBox::critical(
this,
"**ERROR**", QString(
"Identifier '%1' not present in selected collection '%2'").arg(str).arg(
fCollList[idx].fCollName));
503 for (
int i=0; i<list.count(); i++) {
504 if (list[i] ==
"var") {
505 if (i+1 >= list.count()) {
533 for (
int i=0; i<varNames.count(); i++) {
534 if (!varNames[i].contains(
"Err", Qt::CaseSensitive)) {
535 errStr = varNames[i] +
"Err";
537 for (
int j=0; j<varNames.count(); j++) {
538 if (varNames[j] == errStr) {
void check()
Slot to validate variable definitions and emit check_request signal.
bool basic_check()
Performs basic validation checks on variable definitions.
void add()
Slot to validate and add variable definitions, emitting add_request signal.
QVector< PCollInfo > fCollList
vector holding all collection information
QStringList collectVarNames(QStringList &list, bool &ok)
Collects all variable names from a tokenized string list.
void showVarNames()
Slot to show a dialog displaying variable names from the selected collection.
void help()
Slot to display help information about variable syntax.
std::unique_ptr< QPushButton > fCheck
check button to validate variable definitions
std::unique_ptr< QPushButton > fAdd
add button to add variables to mupp GUI
std::unique_ptr< QPushButton > fShowVarName
button to show variable names from selected collection
std::unique_ptr< QListWidget > fCollectionView
list widget displaying available collections
bool hasErrorDef(QStringList &varNames, QString &name)
Checks that each variable has a corresponding error definition.
void add_request(QString varStr, QVector< int > idx)
Signal emitted when user requests to add variable definitions.
std::unique_ptr< QPushButton > fCancel
cancel button to reject the dialog
std::unique_ptr< QPushButton > fHelp
help button to display syntax information
void check_request(QString varStr, QVector< int > idx)
Signal emitted when user requests to check variable definitions.
std::unique_ptr< QPlainTextEdit > fVarEdit
text editor for variable definitions
bool var_consistency_check()
Validates that all identifiers exist in selected collections.
PVarDialog(QVector< PCollInfo > collection_list, bool darkTheme, QWidget *parent=nullptr, Qt::WindowFlags f=Qt::WindowFlags())
Constructor for PVarDialog.
The PCollInfo struct holds collection information.
QStringList fVarName
variable names of the given collection
QString fCollName
collection name (may include path)