diff --git a/src/batchprocessing.cpp b/src/batchprocessing.cpp index 124fceb..474503c 100644 --- a/src/batchprocessing.cpp +++ b/src/batchprocessing.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include "scriptengine.h" #include "chartgraph.h" @@ -110,6 +111,35 @@ BatchProcessing::BatchProcessing(Database *database, QWidget *parent) : QDialog( _textColor = _ui->log->palette().text().color(); + _engine = new Script::ScriptEngine(_database, this); + connect(_engine, &Script::ScriptEngine::newMessage, this, &BatchProcessing::newMessage); + QStringList apiList; + apiList << "core.log" << "core.mark" << "core.unmark" << "core.isMarked" << "core.getObjects" << "core.setMaxthread"; + apiList << "core.sync" << "core.getString" << "core.getInt" << "core.getFloat" << "core.question" << "core.plot"; + apiList << "fileName" << "absoluteFileName"; + _completerModel = new QStringListModel(this); + _completerModel->setStringList(apiList); + _completer = new QCompleter(_completerModel, this); + _ui->consoleLineEdit->setCompleter(_completer); + connect(_ui->executeButton, &QPushButton::clicked, _ui->consoleLineEdit, &QLineEdit::returnPressed); + connect(_ui->consoleLineEdit, &QLineEdit::returnPressed, [this](){ + if(!_completer->popup()->isVisible()) + { + QString program = _ui->consoleLineEdit->text(); + QJSValue val = _engine->eval(program); + _ui->consoleLineEdit->addLine(); + qDebug() << val.toString(); + } + }); + + connect(_ui->consoleLineEdit, &QLineEdit::textEdited, [this](const QString &text){ + QStringList comp = _engine->complete(text); + qDebug() << comp; + _completerModel->setStringList(comp); + }); + + _ui->addFilesButton->setAutoDefault(false); + QSettings settings; _ui->outputPath->setText(settings.value("batchprocessing/outputpath", QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).first()).toString()); } @@ -143,6 +173,15 @@ void BatchProcessing::closeEvent(QCloseEvent *event) } } +void BatchProcessing::refreshPaths() +{ + QStringList paths; + for(int i=0; i<_ui->pathsList->count(); i++) + paths.append(_ui->pathsList->item(i)->text()); + _paths = scanDirectories(paths); + _engine->setParams("", _paths, _ui->outputPath->text()); +} + void BatchProcessing::addFiles() { QSettings settings; @@ -152,6 +191,7 @@ void BatchProcessing::addFiles() _ui->pathsList->addItems(files); settings.setValue("batchprocessing/inputpath", QFileInfo(files.first()).absolutePath()); } + refreshPaths(); } void BatchProcessing::addDir() @@ -163,6 +203,7 @@ void BatchProcessing::addDir() _ui->pathsList->addItem(dir); settings.setValue("batchprocessing/inputpath", dir); } + refreshPaths(); } void BatchProcessing::addMarked() @@ -174,17 +215,20 @@ void BatchProcessing::addMarked() if(info.exists() && info.isReadable()) _ui->pathsList->addItem(file); }; + refreshPaths(); } void BatchProcessing::removePath() { for(auto &item : _ui->pathsList->selectedItems()) delete item; + refreshPaths(); } void BatchProcessing::removeAllPaths() { _ui->pathsList->clear(); + refreshPaths(); } void BatchProcessing::browse() @@ -208,9 +252,6 @@ void BatchProcessing::runScript() _engineThread = new Script::ScriptEngineThread(_database, this); connect(_engineThread, &Script::ScriptEngineThread::newMessage, this, &BatchProcessing::newMessage); connect(_engineThread, &Script::ScriptEngineThread::finished, this, &BatchProcessing::scriptFinished); - QStringList paths; - for(int i=0; i<_ui->pathsList->count(); i++) - paths.append(_ui->pathsList->item(i)->text()); QFileInfo outDir(_ui->outputPath->text()); if(outDir.exists() && outDir.isWritable()) @@ -221,7 +262,7 @@ void BatchProcessing::runScript() else script = ":/scripts/" + script; - _engineThread->setParams(script, scanDirectories(paths), _ui->outputPath->text()); + _engineThread->setParams(script, _paths, _ui->outputPath->text()); _engineThread->start(); _ui->startButton->setEnabled(false); _ui->stopButton->setEnabled(true); @@ -329,6 +370,48 @@ void BatchProcessing::plot(const QVariant &graph) chart->plot(graph); } +ConsoleLine::ConsoleLine(QWidget *parent) : QLineEdit(parent) +{ +} + +void ConsoleLine::addLine() +{ + QString line = text(); + clear(); + if(_history.size() && _history.last() == line)return; + + _history.append(line); + if(_history.size() > 100)_history.removeFirst(); + _currentLine = _history.size(); +} + +void ConsoleLine::keyReleaseEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Up) + { + _currentLine--; + if(_currentLine < 0) + { + _currentLine = -1; + clear(); + return; + } + setText(_history.at(_currentLine)); + } + else if(event->key() == Qt::Key_Down) + { + _currentLine++; + if(_currentLine >= _history.size()) + { + _currentLine = _history.size(); + clear(); + return; + } + setText(_history.at(_currentLine)); + } + else QLineEdit::keyReleaseEvent(event); +} + void openDir(const QString &path) { #ifdef Q_OS_LINUX diff --git a/src/batchprocessing.h b/src/batchprocessing.h index e8b6fc4..0896505 100644 --- a/src/batchprocessing.h +++ b/src/batchprocessing.h @@ -3,6 +3,9 @@ #include #include +#include +#include +#include #include "scriptengine.h" namespace Ui { class BatchProcessing; } @@ -16,8 +19,12 @@ class BatchProcessing : public QDialog QString _scriptBasePath; QFileSystemWatcher _fileWatcher; Script::ScriptEngineThread *_engineThread = nullptr; + Script::ScriptEngine *_engine = nullptr; QColor _textColor; Database *_database; + QStringListModel *_completerModel = nullptr; + QCompleter *_completer = nullptr; + QList> _paths; private slots: void scanScriptDir(); public: @@ -25,6 +32,7 @@ public: ~BatchProcessing(); protected: void closeEvent(QCloseEvent *event); + void refreshPaths(); public slots: void addFiles(); void addDir(); @@ -47,6 +55,18 @@ public slots: void plot(const QVariant &graph); }; +class ConsoleLine : public QLineEdit +{ + Q_OBJECT +public: + explicit ConsoleLine(QWidget *parent = nullptr); + void addLine(); + void keyReleaseEvent(QKeyEvent *event) override; +private: + int _currentLine = 0; + QStringList _history; +}; + void openDir(const QString &path); #endif // BATCHPROCESSING_H diff --git a/src/batchprocessing.ui b/src/batchprocessing.ui index 6070fa1..9c10245 100644 --- a/src/batchprocessing.ui +++ b/src/batchprocessing.ui @@ -43,6 +43,9 @@ Add files + + false + @@ -50,6 +53,9 @@ Add directories + + false + @@ -57,6 +63,9 @@ Add marked + + false + @@ -64,6 +73,9 @@ Remove + + false + @@ -71,6 +83,9 @@ Remove all + + false + @@ -98,6 +113,9 @@ Browse + + false + @@ -129,6 +147,9 @@ Open scripts + + false + @@ -171,23 +192,30 @@ - - - Qt::Horizontal + + + Console - - - 40 - 20 - + + + + + + Execute - + + false + + Start script + + false + @@ -198,12 +226,8 @@ Stop script - - - - - - Close + + false @@ -211,23 +235,29 @@ + + + ConsoleLine + QLineEdit +
batchprocessing.h
+
+
+ + pathsList + addFilesButton + addDirButton + addMarkedButton + removeButton + removeAllButton + browseButton + openScriptsButton + scriptsList + consoleLineEdit + startButton + stopButton + outputPath + log + - - - closeButton - released() - BatchProcessing - close() - - - 973 - 745 - - - 511 - 383 - - - - + diff --git a/src/scriptengine.cpp b/src/scriptengine.cpp index 8a2d88e..7be8ffd 100644 --- a/src/scriptengine.cpp +++ b/src/scriptengine.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "loadrunable.h" #include "rawimage.h" #include "loadimage.h" @@ -40,7 +41,7 @@ ScriptEngine::ScriptEngine(Database *database, BatchProcessing *parent) void ScriptEngine::setParams(const QString &scriptPath, const QList> &paths, const QString &outputDir) { _scriptPath = scriptPath; - _paths = paths; + setPaths(paths); _outputDir = outputDir + "/"; } @@ -417,14 +418,73 @@ QJSValue ScriptEngine::newArray(uint size) return _jsEngine->newArray(size); } -void ScriptEngine::run() +QJSValue ScriptEngine::eval(const QString &program) { - QJSValue jsPaths = _jsEngine->newArray(_paths.size()); - for(qsizetype i=0; i<_paths.size(); i++) - jsPaths.setProperty(i, _jsEngine->newQObject(new File(_paths[i].first, _paths[i].second, this))); + QStringList stackTrace; + QJSValue result = _jsEngine->evaluate(program, QString(), 1, &stackTrace); + + if(result.isError()) + { + QString error = result.property("name").toString() + " on line " + result.property("lineNumber").toString() + " : " + result.toString(); + error += "\n" + result.property("stack").toString(); + emit newMessage(error, true); + } + else if(!result.isUndefined()) + { + emit newMessage(result.toString(), false); + } + + return result; +} + +QStringList ScriptEngine::complete(const QString &line) +{ + QStringList complete; + + QJSValue globObj = _jsEngine->globalObject(); + + QRegularExpression reg("[a-zA-Z_][a-zA-Z0-9_]*"); + auto match = reg.match(line); + if(match.hasMatch()) + { + QString var = match.captured(); + if(globObj.hasProperty(var)) + { + complete.clear(); + QJSValueIterator it(globObj.property(var)); + while(it.hasNext()) + { + it.next(); + if((it.value().isCallable() || it.value().isObject()) && it.name() != "contructor" && it.name() != "objectNameChanged") + complete.append(var + "." + it.name()); + } + } + } + else + { + QJSValueIterator it(globObj); + while(it.hasNext()) + { + it.next(); + complete.append(it.name()); + } + } + + return complete; +} + +void ScriptEngine::setPaths(const QList > &paths) +{ + _paths = paths; + QJSValue jsPaths = _jsEngine->newArray(paths.size()); + for(qsizetype i=0; inewQObject(new File(paths[i].first, paths[i].second, this))); _jsEngine->globalObject().setProperty("files", jsPaths); +} +void ScriptEngine::run() +{ QFile scriptFile(_scriptPath); if(!scriptFile.open(QIODevice::ReadOnly)) { diff --git a/src/scriptengine.h b/src/scriptengine.h index f4667d9..7eb03dd 100644 --- a/src/scriptengine.h +++ b/src/scriptengine.h @@ -64,6 +64,9 @@ public: #endif // PLATESOLVER QJSValue newObject(); QJSValue newArray(uint size); + QJSValue eval(const QString &program); + QStringList complete(const QString &line); + void setPaths(const QList> &paths); public slots: void run(); signals: