diff --git a/src/musredit_qt5/mupp/CMakeLists.txt b/src/musredit_qt5/mupp/CMakeLists.txt index ba38114f..34868248 100644 --- a/src/musredit_qt5/mupp/CMakeLists.txt +++ b/src/musredit_qt5/mupp/CMakeLists.txt @@ -48,7 +48,8 @@ set(MUPP_SOURCE_FILES Pmupp.cpp PmuppScript.cpp PmuppGui.cpp - PGetNormValDialog.cpp + PVarDialog.cpp +#as35 PGetNormValDialog.cpp ) if (APPLE) diff --git a/src/musredit_qt5/mupp/PGetNormValDialog.h b/src/musredit_qt5/mupp/PGetNormValDialog.h deleted file mode 100644 index 0f8e99c1..00000000 --- a/src/musredit_qt5/mupp/PGetNormValDialog.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - - PGetNormValDialog.h - - Author: Andreas Suter - e-mail: andreas.suter@psi.ch - -***************************************************************************/ - -/*************************************************************************** - * Copyright (C) 2007-2020 by Andreas Suter * - * andreas.suter@psi.ch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#ifndef _PGETNORMVALDIALOG_H_ -#define _PGETNORMVALDIALOG_H_ - -#include -#include - -class PGetNormValDialog : public QDialog -{ - Q_OBJECT - - public: - PGetNormValDialog(double dval, QWidget *parent = 0, Qt::WindowFlags f = 0); - virtual ~PGetNormValDialog() {} - - virtual double getValue() { return fValue; } - - private: - double fValue; - QLineEdit *fEdit; - - private slots: - virtual void gotValue(const QString& str); -}; - -#endif // _PGETNORMVALDIALOG_H_ diff --git a/src/musredit_qt5/mupp/PVarDialog.cpp b/src/musredit_qt5/mupp/PVarDialog.cpp new file mode 100644 index 00000000..f390a4dc --- /dev/null +++ b/src/musredit_qt5/mupp/PVarDialog.cpp @@ -0,0 +1,404 @@ +/*************************************************************************** + + PVarDialog.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007-2020 by Andreas Suter * + * andreas.suter@psi.ch * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "PVarDialog.h" + +//-------------------------------------------------------------------------- +PShowVarNameDialog::PShowVarNameDialog(PCollInfo &info) +{ + // if fCollName is a path name, extract the fln + QString collNameStr(info.fCollName); + if (collNameStr.contains("/")) { + QStringList tok = collNameStr.split('/', QString::SkipEmptyParts); + collNameStr = tok[tok.count()-1]; + } + QLabel *collName = new QLabel(collNameStr); + QLabel *numVars = new QLabel(QString("#variables: %1").arg(info.fVarName.count())); + QListWidget *list = new QListWidget(); + for (int i=0; isetText(QString("%1 : %2").arg(i, 2).arg(info.fVarName[i])); + list->addItem(newItem); + } + QPushButton *done = new QPushButton("Done", this); + + QVBoxLayout *vLayout = new QVBoxLayout; + vLayout->addWidget(collName); + vLayout->addWidget(numVars); + vLayout->addWidget(list); + vLayout->addWidget(done); + + connect(done, SIGNAL( clicked() ), this, SLOT( accept() )); + + resize(300, 450); + setLayout(vLayout); + setModal(false); + setWindowTitle("Variable Names"); + + QString iconName(""); + if (true) // <-- NEEDS TO BE PROPERLY IMPLEMENTED + iconName = QString(":/icons/varEdit-dark.svg"); + else + iconName = QString(":/icons/varEdit-plain.svg"); + setWindowIcon( QIcon( QPixmap(iconName) ) ); +} + +//-------------------------------------------------------------------------- +PVarDialog::PVarDialog(QVector collection_list, bool darkTheme, + QWidget *parent, Qt::WindowFlags f) : + QDialog(parent, f), fCollList(collection_list) +{ + fVarEdit = new QPlainTextEdit(); + fCollectionView = new QListWidget(); + fCancel = new QPushButton("&Cancel", this); + fCheck = new QPushButton("Chec&k", this); + fAdd = new QPushButton("&Add", this); + fHelp = new QPushButton("&Help", this); + fShowVarName = new QPushButton("Show&VarName", this); + + // fill collection view + for (int i=0; isetText(fCollList[i].fCollName); + fCollectionView->addItem(newItem); + } + fCollectionView->setSelectionMode(QAbstractItemView::ExtendedSelection); + + QHBoxLayout *hLayout0 = new QHBoxLayout; + hLayout0->addWidget(fShowVarName); + hLayout0->addWidget(fHelp); + + QHBoxLayout *hLayout1 = new QHBoxLayout; + hLayout1->addWidget(fCancel); + hLayout1->addWidget(fCheck); + hLayout1->addWidget(fAdd); + + QLabel *varLabel = new QLabel("Edit Variables:"); + QVBoxLayout *varVLayout = new QVBoxLayout; + varVLayout->addWidget(varLabel); + varVLayout->addWidget(fVarEdit); + + QLabel *collLabel = new QLabel("Collections:"); + QVBoxLayout *collVLayout = new QVBoxLayout; + collVLayout->addWidget(collLabel); + collVLayout->addWidget(fCollectionView); + + QWidget *varWidget = new QWidget(this); // only needed since splitter needs a QWidget + varWidget->setLayout(varVLayout); + QWidget *collWidget = new QWidget(this); // only needed since splitter needs a QWidget + collWidget->setLayout(collVLayout); + + QSplitter *splitter = new QSplitter(Qt::Vertical, this); + splitter->addWidget(varWidget); + splitter->addWidget(collWidget); + + QVBoxLayout *vLayout = new QVBoxLayout; + vLayout->addWidget(splitter); + vLayout->addLayout(hLayout0); + vLayout->addLayout(hLayout1); + + fVarEdit->resize(600, 300); + setLayout(vLayout); + resize(600, 450); + + connect(fCancel, SIGNAL( clicked() ), this, SLOT( reject() )); + connect(fCheck, SIGNAL( clicked() ), this, SLOT( check() )); + connect(fAdd, SIGNAL( clicked() ), this, SLOT( add() )); + connect(fHelp, SIGNAL( clicked() ), this, SLOT( help() )); + connect(fShowVarName, SIGNAL( clicked() ), this, SLOT( showVarNames() )); + + QString iconName(""); + if (darkTheme) + iconName = QString(":/icons/varEdit-dark.svg"); + else + iconName = QString(":/icons/varEdit-plain.svg"); + setWindowIcon( QIcon( QPixmap(iconName) ) ); +} + +//-------------------------------------------------------------------------- +void PVarDialog::check() +{ + if (!basic_check()) + return; + + if (!var_consistency_check()) + return; + + // create the collection index vector + QVector idx; + QList selected = fCollectionView->selectedItems(); + for (int i=0; irow(selected[i])); + } + emit check_request(fVarEdit->toPlainText(), idx); +} + +//-------------------------------------------------------------------------- +void PVarDialog::add() +{ + if (fVarEdit->toPlainText().isEmpty()) { + QMessageBox::critical(this, "**ERROR**", "No input available."); + return; + } + if (fCollectionView->selectedItems().count() == 0) { + QMessageBox::critical(this, "**ERROR**", "One or more collection(s) need to linked to the variable(s)."); + return; + } + + if (!basic_check()) + return; + + if (!var_consistency_check()) + return; + + // create the collection index vector + QVector idx; + QList selected = fCollectionView->selectedItems(); + for (int i=0; irow(selected[i])); + } + + emit check_request(fVarEdit->toPlainText(), idx); +} + +//-------------------------------------------------------------------------- +void PVarDialog::help() +{ + QMessageBox::information(this, "Var Help", "Syntax: var = .\n can contain identifiers defined in the collections.\nExample:\nvar sigSC = pow(abs(pow($sigma,2.0)-pow(0.11,2.0)),0.5)"); +} + +//-------------------------------------------------------------------------- +void PVarDialog::showVarNames() +{ + // get the selected collection + if (fCollectionView->selectedItems().count() == 0) { + QMessageBox::critical(this, "**ERROR**", "At least one collection needs to be selected."); + return; + } + if (fCollectionView->selectedItems().count() > 1) { + QMessageBox::critical(this, "**ERROR**", "Currently only the vars of a single collection can be shown."); + return; + } + int idx = fCollectionView->currentRow(); + + if (idx >= fCollList.count()) { + QMessageBox::critical(this, "**ERROR**", QString("Collection idx=%1 > #Collections=%2. This never should have happened.").arg(idx).arg(fCollList.count())); + return; + } + + PCollInfo info = fCollList[idx]; + + PShowVarNameDialog *dialog = new PShowVarNameDialog(info); + dialog->show(); +} + +//-------------------------------------------------------------------------- +bool PVarDialog::basic_check() +{ + QString varStr = fVarEdit->toPlainText(); + bool ok; + + if (varStr.isEmpty()) { + QMessageBox::critical(this, "**ERROR**", "No input available."); + return false; + } + if (fCollectionView->selectedItems().count() == 0) { + QMessageBox::critical(this, "**ERROR**", "One or more collection(s) need to linked to the variable(s)."); + return false; + } + + // tokenize variable input + QStringList strList = varStr.split(QRegularExpression("\\s+"), QString::SkipEmptyParts); + + // check if there are ANY var definitions + ok = false; + for (int i=0; iNO 'var' definition found."); + return false; + } + + // check that for each variable, there is also an Err variable present + QStringList varNames = collectVarNames(strList, ok); + if (!ok) { + QMessageBox::critical(this, "**ERROR**", "found 'var' without ."); + return false; + } + QString name(""); + if (!hasErrorDef(varNames, name)) { + QMessageBox::critical(this, "**ERROR**", QString("found <var_name>=%1 without corresponding %1Err.
Both, a variable and its corresponding error variable needs to be defined.").arg(name)); + return false; + } + + return true; +} + +//-------------------------------------------------------------------------- +bool PVarDialog::var_consistency_check() +{ + QString varStr = fVarEdit->toPlainText(); + + // collect all identifiers + int idx = 0, idxEnd = 0; + QStringList varNames; + QVector isIdendifier; + char ch; + bool done; + do { + idx = varStr.indexOf("$", idx); + if (idx > -1) { // found identifier + idxEnd = idx+1; + done = false; + do { + ch = varStr[idxEnd].toLatin1(); + if (isalnum(ch) || (ch == '_')) + idxEnd++; + else + done = true; + } while (!done && (idxEnd <= varStr.length())); + varNames << varStr.mid(idx+1, idxEnd-idx-1); + isIdendifier.push_back(1); + idx++; + } + } while (idx != -1); + + // collect all the variable names + idx = 0; + do { + idx = varStr.indexOf("var ", idx); + if (idx > -1) { // found variable + idxEnd = varStr.indexOf("=", idx); + if (idxEnd == -1) { + return false; + } + varNames << varStr.mid(idx+4, idxEnd-idx-5); + isIdendifier.push_back(0); + idx++; + } + } while (idx != -1); + + // make sure that identifier is found in collection if it is not a variable + bool isVar = false; + bool found = false; + QString str; + QList selColl = fCollectionView->selectedItems(); + for (int i=0; irow(selColl[j]); + found = false; + for (int k=0; k= list.count()) { + ok = false; + } else { + name << list[i+1]; + i++; + } + } + } + + return name; +} + +//-------------------------------------------------------------------------- +bool PVarDialog::hasErrorDef(QStringList &varNames, QString &name) +{ + QString errStr; + for (int i=0; i -#include -#include -#include -#include +#ifndef _PVARDIALOG_H_ +#define _PVARDIALOG_H_ + +#include #include +#include +#include +#include -#include "PGetNormValDialog.h" - -//------------------------------------------------------------------------------ -PGetNormValDialog::PGetNormValDialog(double dval, QWidget *parent, Qt::WindowFlags f) : - QDialog(parent, f), fValue(dval) +//----------------------------------------------------------------------------- +struct PCollInfo { - QVBoxLayout *vbox = new QVBoxLayout; - QHBoxLayout *hbox1 = new QHBoxLayout; - QHBoxLayout *hbox2 = new QHBoxLayout; + QString fCollName; + QStringList fVarName; +}; - vbox->addLayout(hbox1); - vbox->addLayout(hbox2); - - QLabel *lab = new QLabel("Norm Value: "); - QLineEdit *fEdit = new QLineEdit(); - fEdit->setValidator(new QDoubleValidator()); - fEdit->setText(QString("%1").arg(fValue)); - hbox1->addWidget(lab); - hbox1->addWidget(fEdit); - - QPushButton *ok = new QPushButton("OK"); - QPushButton *cancel = new QPushButton("Cancel"); - hbox2->addWidget(ok); - hbox2->addWidget(cancel); - - setModal(true); - - setLayout(vbox); - - connect( fEdit, SIGNAL(textChanged(const QString&)), this, SLOT(gotValue(const QString&))); - connect( ok, SIGNAL(clicked()), this, SLOT(accept())); - connect( cancel, SIGNAL(clicked()), this, SLOT(reject())); -} - -//------------------------------------------------------------------------------ -void PGetNormValDialog::gotValue(const QString& str) +//----------------------------------------------------------------------------- +class PShowVarNameDialog : public QDialog { - fValue = str.toDouble(); -} + Q_OBJECT + + public: + PShowVarNameDialog(PCollInfo &info); +}; + +//----------------------------------------------------------------------------- +class PVarDialog : public QDialog +{ + Q_OBJECT + + public: + PVarDialog(QVector collection_list, bool darkTheme, + QWidget *parent = nullptr, + Qt::WindowFlags f = Qt::WindowFlags()); + + private: + QPlainTextEdit *fVarEdit; + QListWidget *fCollectionView; + QPushButton *fCancel; + QPushButton *fAdd; + QPushButton *fCheck; + QPushButton *fHelp; + QPushButton *fShowVarName; + + QVector fCollList; + + bool basic_check(); + bool var_consistency_check(); + QStringList collectVarNames(QStringList &list, bool& ok); + bool hasErrorDef(QStringList &varNames, QString& name); + + private slots: + void check(); + void add(); + void help(); + void showVarNames(); + + signals: + void check_request(QString varStr, QVector idx); + void add_request(QString varStr, QVector idx); +}; + +#endif // _PVARDIALOG_H_ diff --git a/src/musredit_qt5/mupp/PmuppGui.cpp b/src/musredit_qt5/mupp/PmuppGui.cpp index cd32b288..c8186777 100644 --- a/src/musredit_qt5/mupp/PmuppGui.cpp +++ b/src/musredit_qt5/mupp/PmuppGui.cpp @@ -59,7 +59,6 @@ #include "mupp_version.h" #include "PmuppGui.h" -#include "PGetNormValDialog.h" //---------------------------------------------------------------------------------------------------- /** @@ -211,7 +210,8 @@ PmuppGui::PmuppGui( QStringList fln, QWidget *parent, Qt::WindowFlags f ) fNormalizeAction = nullptr; fNormalize = false; - fNormVal = 0.0; + + fVarDlg = nullptr; fMacroPath = QString("./"); fMacroName = QString(""); @@ -549,16 +549,25 @@ void PmuppGui::setupToolActions() menu->addSeparator(); + a = new QAction(tr( "Add Variable" ), this ); + a->setStatusTip( tr("Calls a dialog which allows to add variables which are expressions of db/dat vars.") ); + connect( a, SIGNAL( triggered() ), this, SLOT( addVar() )); + menu->addAction(a); + + menu->addSeparator(); + fNormalizeAction = new QAction(tr( "Normalize" ), this); fNormalizeAction->setStatusTip( tr("Plot Data Normalized (y-axis)") ); fNormalizeAction->setCheckable(true); connect( fNormalizeAction, SIGNAL( changed() ), this, SLOT( normalize() ) ); menu->addAction(fNormalizeAction); +/* //as35 - eventually also remove PGetNormValDialog.* from the source a = new QAction(tr( "Normalize by Value" ), this); a->setStatusTip( tr("Normalize by Value") ); connect( a, SIGNAL( triggered() ), this, SLOT( normVal() ) ); menu->addAction(a); +*/ } //---------------------------------------------------------------------------------------------------- @@ -705,27 +714,6 @@ void PmuppGui::normalize() fNormalize = fNormalizeAction->isChecked(); } -//---------------------------------------------------------------------------------------------------- -void PmuppGui::normVal() -{ - PGetNormValDialog *dlg = new PGetNormValDialog(fNormVal); - if (dlg == nullptr) { - QMessageBox::critical(this, "**ERROR**", "Couldn't invoke dialog, sorry :-(", QMessageBox::Ok, QMessageBox::NoButton); - return; - } - - dlg->exec(); - - if (dlg->result() != QDialog::Accepted) { - delete dlg; - return; - } - - fNormVal = dlg->getValue(); - - delete dlg; -} - //---------------------------------------------------------------------------------------------------- /** * @brief PmuppGui::helpCmds @@ -733,6 +721,7 @@ void PmuppGui::normVal() void PmuppGui::helpCmds() { QMessageBox::information(this, "cmd help", "help: this help.
"\ + "add var: allows to add a variable which is formula of collection vars.
"\ "ditto: addX/Y for the new selection as for the previous ones.
"\ "dump collections: dumps all currently loaded collections.
"\ "dump XY: dumps X/Y tree.
"\ @@ -1244,6 +1233,76 @@ void PmuppGui::addDitto() fColList->clearSelection(); } +//---------------------------------------------------------------------------------------------------- +void PmuppGui::addVar() +{ + // create collection list + QVector collection_list; + + // go through all available collections and obtain the needed information + PCollInfo collInfo; + for (int i=0; iGetNoOfCollections(); i++) { + // get collection name + collInfo.fCollName = fParamDataHandler->GetCollectionName(i); + // get variable names + for (int j=0; jGetCollection(i)->GetRun(0).GetNoOfParam(); j++) { + collInfo.fVarName << fParamDataHandler->GetCollection(i)->GetRun(0).GetParam(j).GetName(); + } + collection_list.push_back(collInfo); + } + + // call variable dialog + if (fVarDlg == nullptr) { + fVarDlg = new PVarDialog(collection_list, fDarkTheme); + connect(fVarDlg, SIGNAL(check_request(QString,QVector)), this, SLOT(check(QString,QVector))); + connect(fVarDlg, SIGNAL(add_request(QString,QVector)), this, SLOT(add(QString,QVector))); + } + fVarDlg->show(); + +} + +//---------------------------------------------------------------------------------------------------- +void PmuppGui::check(QString varStr, QVector idx) +{ + int count = 0; + for (int i=0; iGetCollection(i), varStr.toLatin1().data()); + if (var_check.isValid()) { + count++; + } else { + // get error messages + QString mupp_err = QString("%1/.musrfit/mupp/mupp_err.log").arg(QString(qgetenv("HOME"))); + QFile fin(mupp_err); + QString errStr(""); + if (fin.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&fin); + while (!in.atEnd()) { + errStr += in.readLine(); + errStr += "\n"; + } + } + fin.close(); + QFile::remove(mupp_err); + + if (errStr.isEmpty()) + errStr = "unknown error - should never happen."; + QString msg = QString("Parse error(s):\n"); + msg += errStr; + QMessageBox::critical(this, "**ERROR**", msg); + return; + } + } + if (count == idx.size()) { + QMessageBox::information(this, "**INFO**", "Parsing successful."); + } +} + +//---------------------------------------------------------------------------------------------------- +void PmuppGui::add(QString varStr, QVector idx) +{ + +} + //---------------------------------------------------------------------------------------------------- /** * @brief PmuppGui::findValue @@ -1765,13 +1824,9 @@ void PmuppGui::plot() double max=0.0; for (int k=0; k max) - max = yyy[k][j]; - } - } else { - max = fNormVal; + for (int j=0; j max) + max = yyy[k][j]; } for (int j=0; jsetText("$ "); @@ -2190,48 +2247,32 @@ QString PmuppGui::substituteDefaultLabels(QString label) result =QString("E (keV)"); } else if (!label.compare("sigma", Qt::CaseInsensitive)) { if (fNormalize) { - if (fNormVal == 0.0) - result = QString("#sigma/max(#sigma)"); - else - result = QString("#sigma/%1 (1/#mus)").arg(fNormVal); + result = QString("#sigma/max(#sigma)"); } else { result = QString("#sigma (1/#mus)"); } } else if (!label.compare("lambda", Qt::CaseInsensitive)) { if (fNormalize) { - if (fNormVal == 0.0) - result = QString("#lambda/max(#lambda)"); - else - result = QString("#lambda/%1 (1/#mus)").arg(fNormVal); + result = QString("#lambda/max(#lambda)"); } else { result = QString("#lambda (1/#mus)"); } } else if (!label.compare("alpha_LR", Qt::CaseInsensitive)) { if (fNormalize) { - if (fNormVal == 0.0) - result = QString("#alpha_{LR}/max(#alpha_{LR})"); - else - result = QString("#alpha_{LR}/%1").arg(fNormVal); + result = QString("#alpha_{LR}/max(#alpha_{LR})"); } else { result = QString("#alpha_{LR}"); } } else if (!label.compare("alpha_TB", Qt::CaseInsensitive)) { if (fNormalize) { - if (fNormVal == 0.0) - result = QString("#alpha_{TB}/max(#alpha_{TB})"); - else - result = QString("#alpha_{TB}/%1").arg(fNormVal); + result = QString("#alpha_{TB}/max(#alpha_{TB})"); } else { result = QString("#alpha_{TB}"); } } else { if (fNormalize) { - if (fNormVal == 0.0) { - result = QString("Normalized "); - result += label; - } else { - result = QString("%1/%2").arg(label).arg(fNormVal); - } + result = QString("Normalized "); + result += label; } } diff --git a/src/musredit_qt5/mupp/PmuppGui.h b/src/musredit_qt5/mupp/PmuppGui.h index fa3f8ea2..d714f442 100644 --- a/src/musredit_qt5/mupp/PmuppGui.h +++ b/src/musredit_qt5/mupp/PmuppGui.h @@ -45,11 +45,13 @@ #include #include +#include "PVarHandler.h" +#include "PVarDialog.h" #include "PmuppAdmin.h" #include "Pmupp.h" #include "mupp.h" -//---------------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------- class PmuppXY { public: @@ -78,7 +80,7 @@ private: void init(); }; -//---------------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------- // Layout Scheme of PmuppGui: // |--------------------------------------------------------------------| // | Main | @@ -96,9 +98,11 @@ private: // | |----------------------------------------------------------------| | // ---------------------------------------------------------------------- // -// Grid Left contains: fColLabel, fColParamSplitter, fRemoveCollection, fRefreshCollection -// Grid Right contains: f(X,Y)axisLabel, fView(X,Y), fAdd(X,Y), fRemove(X,Y), fAddDitto, fPlot -//---------------------------------------------------------------------------------------------- +// Grid Left contains: fColLabel, fColParamSplitter, +// fRemoveCollection, fRefreshCollection +// Grid Right contains: f(X,Y)axisLabel, fView(X,Y), fAdd(X,Y), fRemove(X,Y), +// fAddDitto, fPlot +//----------------------------------------------------------------------------- class PmuppGui : public QMainWindow { Q_OBJECT @@ -115,8 +119,8 @@ public slots: void toolDumpCollections(); void toolDumpXY(); + void addVar(); void normalize(); - void normVal(); void helpCmds(); void helpAbout(); @@ -132,13 +136,13 @@ private: bool fDarkTheme; bool fDarkToolBarIcon; bool fNormalize; - double fNormVal; uint fDatime; uint fMuppInstance; PParamDataHandler *fParamDataHandler; QVector fXY; + QVector fVarHandler; QString fMacroPath; QString fMacroName; @@ -178,6 +182,8 @@ private: QVector fCmdHistory; + PVarDialog *fVarDlg; + QProcess *fMuppPlot; void setupFileActions(); @@ -198,34 +204,37 @@ private: void selectCollection(QString cmd); uint getFirstAvailableMuppInstance(); -private slots: - void refresh(); - void remove(); - void addX(QString param=""); - void addY(QString param=""); - void removeX(QString param=""); - void removeY(QString param=""); - void addDitto(); - void createMacro(); - void plot(); - void handleCmds(); - - void handleNewData(); void updateCollectionList(); - void updateParamList(int currentRow); void updateXYList(int idx); void updateXYListGui(); - void editCollName(QListWidgetItem *item); - void dropOnViewX(QListWidgetItem *item); - void dropOnViewY(QListWidgetItem *item); - void refreshY(); - bool findValue(PmuppRun &run, EAxis tag); bool allXYEqual(); bool indexAlreadyPresent(int idx); void replaceIndex(PmuppXY &data, const int idx); void startMuppPlot(); + +private slots: + void addDitto(); + void addX(QString param=""); + void addY(QString param=""); + void createMacro(); + void handleCmds(); + void plot(); + void refresh(); + void remove(); + void removeX(QString param=""); + void removeY(QString param=""); + + void handleNewData(); + void updateParamList(int currentRow); + void editCollName(QListWidgetItem *item); + void dropOnViewX(QListWidgetItem *item); + void dropOnViewY(QListWidgetItem *item); + void refreshY(); + + void check(QString varStr, QVector idx); + void add(QString varStr, QVector idx); }; #endif // _PMUPPGUI_H_ diff --git a/src/musredit_qt5/mupp/PmuppScript.cpp b/src/musredit_qt5/mupp/PmuppScript.cpp index 9305b9a6..2e12e6cc 100644 --- a/src/musredit_qt5/mupp/PmuppScript.cpp +++ b/src/musredit_qt5/mupp/PmuppScript.cpp @@ -807,8 +807,23 @@ int PmuppScript::var_cmd(const QString str) } PVarHandler varHandler(fParamDataHandler->GetCollection(idx), parse_str, tok[1].toLatin1().data()); - if (!varHandler.isValid()) + if (!varHandler.isValid()) { + // deal with errors + QString mupp_err = QString("%1/.musrfit/mupp/mupp_err.log").arg(QString(qgetenv("HOME"))); + + // dump error messages if present + QFile fout(mupp_err); + if (fout.open(QIODevice::ReadOnly | QIODevice::Text)) { + QString msg; + while (!fout.atEnd()) { + msg = fout.readLine(); + std::cerr << msg.toLatin1().data(); + } + // delete potentially present mupp_err.log file + QFile::remove(mupp_err); + } return 1; + } fVarHandler.push_back(varHandler); return 0; diff --git a/src/musredit_qt5/mupp/mupp.qrc b/src/musredit_qt5/mupp/mupp.qrc index dd5966e4..8390e2e1 100644 --- a/src/musredit_qt5/mupp/mupp.qrc +++ b/src/musredit_qt5/mupp/mupp.qrc @@ -4,6 +4,8 @@ icons/mupp-dark.svg icons/document-open-plain.svg icons/document-open-dark.svg + icons/varEdit-plain.svg + icons/varEdit-dark.svg icons/mupp.icns mupp_startup.xml.in diff --git a/src/musredit_qt5/mupp/var/include/PErrorHandler.hpp b/src/musredit_qt5/mupp/var/include/PErrorHandler.hpp index 214a386d..7c127ed2 100644 --- a/src/musredit_qt5/mupp/var/include/PErrorHandler.hpp +++ b/src/musredit_qt5/mupp/var/include/PErrorHandler.hpp @@ -34,6 +34,7 @@ #define _PERROR_HANDLER_HPP_ #include +#include #include #include @@ -59,15 +60,19 @@ namespace mupp { int line; Iterator line_start = get_pos(err_pos, line); + const char *homeStr = getenv("HOME"); + char fln[1024]; + sprintf(fln, "%s/.musrfit/mupp/mupp_err.log", homeStr); + std::ofstream fout(fln, std::ofstream::app); if (err_pos != last) { - std::cout << message << what << ':' << std::endl; - std::cout << get_line(line_start) << std::endl; + fout << message << what << ':' << std::endl; + fout << get_line(line_start) << std::endl; for (; line_start != err_pos; ++line_start) - std::cout << ' '; - std::cout << "^~~" << std::endl; + fout << ' '; + fout << "^~~" << std::endl; } else { - std::cout << "**ERROR** Unexpected end of file. "; - std::cout << message << what << " line " << line << std::endl; + fout << "**ERROR** Unexpected end of file. "; + fout << message << what << " line " << line << std::endl; } } diff --git a/src/musredit_qt5/mupp/var/include/PVarHandler.h b/src/musredit_qt5/mupp/var/include/PVarHandler.h index 2e71288f..2ba4f1c9 100644 --- a/src/musredit_qt5/mupp/var/include/PVarHandler.h +++ b/src/musredit_qt5/mupp/var/include/PVarHandler.h @@ -42,15 +42,16 @@ class PVarHandler { public: PVarHandler(); - PVarHandler(PmuppCollection *coll, std::string parse_str, std::string var_name); + PVarHandler(PmuppCollection *coll, std::string parse_str, std::string var_name=""); bool isValid() { return fIsValid; } + QString getCollName() { return fColl->GetName(); } QString getVarName() { return QString(fVarName.c_str()); } std::vector getValues(); std::vector getErrors(); private: - PmuppCollection *fColl; ///< collection need for parsing and evaluation + PmuppCollection *fColl; ///< collection needed for parsing and evaluation std::string fParseStr; ///< the variable input to be parsed std::string fVarName; ///< variable name mupp::prog::PVarHandler fVar; ///< values of the evaluation diff --git a/src/musredit_qt5/mupp/var/src/PVarHandler.cpp b/src/musredit_qt5/mupp/var/src/PVarHandler.cpp index 9ac9c78a..af0c0710 100644 --- a/src/musredit_qt5/mupp/var/src/PVarHandler.cpp +++ b/src/musredit_qt5/mupp/var/src/PVarHandler.cpp @@ -74,15 +74,17 @@ PVarHandler::PVarHandler(PmuppCollection *coll, std::string parse_str, std::stri dataErr = getDataErr(i); prog.add_predef_var_values(getVarName(i), data, dataErr); } - mupp::prog::PProgEval eval(prog.getVars()); // setup evaluation stage - eval(fAst); // evaluate stuff + if (!fVarName.empty()) { + mupp::prog::PProgEval eval(prog.getVars()); // setup evaluation stage + eval(fAst); // evaluate stuff - // keep data - bool ok; - fVar = eval.getVar(fVarName, ok); - if (!ok) { - std::cerr << "**ERROR** evalution failed..." << std::endl; - fIsValid = false; + // keep data + bool ok; + fVar = eval.getVar(fVarName, ok); + if (!ok) { + std::cerr << "**ERROR** evalution failed..." << std::endl; + fIsValid = false; + } } } fIsValid = true;