Skip to content

Commit

Permalink
Update Internal Command
Browse files Browse the repository at this point in the history
Signed-off-by: xiaoming <2014500726@smail.xtu.edu.cn>
  • Loading branch information
QQxiaoming committed Jul 31, 2024
1 parent 4475e99 commit c2eec9b
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 20 deletions.
54 changes: 50 additions & 4 deletions src/internalcommandwindow/internalcommandprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ InternalCommandProcess::~InternalCommandProcess() {
wait();
}

void InternalCommandProcess::setPyRun(PyRun *pyRun) {
m_pyRun = pyRun;
}

void InternalCommandProcess::run(void) {
sendWelcome();
sendPrompt();
Expand Down Expand Up @@ -81,9 +85,18 @@ void InternalCommandProcess::processLine(const QString &sline) {
},
{"?" , "show this help message" ,
[&](void) {
static const int maxCmdNameCount = [&]() -> int {
int ret = 0;
foreach(const struct Command &cmd, commands) {
ret = qMax(ret, cmd.name.size());
}
return ret;
}();
sendLineString("Available commands:");
foreach(const struct Command &cmd, commands) {
sendLineString(" " + cmd.name + " - " + cmd.description);
if(!cmd.description.isEmpty()) {
sendLineString(" " + cmd.name.leftJustified(maxCmdNameCount, ' ') + " - " + cmd.description);
}
}
}
},
Expand Down Expand Up @@ -225,6 +238,22 @@ void InternalCommandProcess::processLine(const QString &sline) {
#endif
}
},
#ifdef ENABLE_PYTHON
{"run", "run script" ,
[&](void) {
if(args.size() >= 1) {
QFileInfo fileInfo(args.at(0));
if(fileInfo.isFile()) {
if(m_pyRun) {
m_pyRun->runScriptFile(args.at(0));
}
return;
}
}
sendLineString("Script file not found!");
}
},
#endif
};
if(command.isEmpty()) {
return;
Expand All @@ -237,16 +266,33 @@ void InternalCommandProcess::processLine(const QString &sline) {
break;
}
}
QString fullCommand = command;
if(!args.isEmpty()) {
fullCommand = command + " " + args.join(' ');
}
if(!matched) {
sendLineString("Unknown command: " + command);
if(m_pyRun) {
#ifdef ENABLE_PYTHON
QString result;
int ret = -1;
m_pyRun->runScriptStr("print("+fullCommand+")", &result, &ret);
if(ret == 0) {
result.replace("\n","\r\n");
sendString(result);
} else
#endif
{
sendLineString("Invalid command!");
}
}
}
if((!historyCmdList.isEmpty()) && historyCmdList.last() == command) {
if((!historyCmdList.isEmpty()) && historyCmdList.last() == fullCommand) {
return;
}
if(historyCmdList.count() >= 100) {
historyCmdList.removeFirst();
}
historyCmdList.append(command);
historyCmdList.append(fullCommand);
historyCmdIndex = historyCmdList.count() - 1;
}

Expand Down
11 changes: 10 additions & 1 deletion src/internalcommandwindow/internalcommandprocess.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@
#include <QMutex>
#include <QWaitCondition>

#ifdef ENABLE_PYTHON
#include "pyrun.h"
#endif

class InternalCommandProcess : public QThread
{
Q_OBJECT
public:
explicit InternalCommandProcess(QObject *parent = nullptr);
~InternalCommandProcess();

#ifdef ENABLE_PYTHON
void setPyRun(PyRun *pyRun);
#endif
void recvData(const QByteArray &data);

struct Command {
Expand Down Expand Up @@ -43,6 +49,9 @@ class InternalCommandProcess : public QThread
QMutex mutex;
QWaitCondition condition;
bool exit;
#ifdef ENABLE_PYTHON
PyRun *m_pyRun = nullptr;
#endif
};

#endif // INTERNALCOMMANDPROCESS_H
4 changes: 4 additions & 0 deletions src/internalcommandwindow/internalcommandwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ InternalCommandWindow::~InternalCommandWindow() {
delete ui;
}

void InternalCommandWindow::setPyRun(PyRun *pyRun) {
process->setPyRun(pyRun);
}

void InternalCommandWindow::contextMenuEvent(QContextMenuEvent *event) {
QMenu *menu = new QMenu(this);
QList<QAction*> ftActions = term->filterActions(event->pos());
Expand Down
3 changes: 3 additions & 0 deletions src/internalcommandwindow/internalcommandwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class InternalCommandWindow : public QDialog
public:
explicit InternalCommandWindow(QWidget *parent = nullptr);
~InternalCommandWindow();
#ifdef ENABLE_PYTHON
void setPyRun(PyRun *pyRun);
#endif

protected:
void contextMenuEvent(QContextMenuEvent *event);
Expand Down
18 changes: 17 additions & 1 deletion src/internalcommandwindow/internalcommandwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,23 @@
<property name="windowTitle">
<string>Internal Command</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout"/>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
</layout>
</widget>
<resources/>
<connections/>
Expand Down
3 changes: 2 additions & 1 deletion src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,7 @@ CentralWidget::CentralWidget(QString dir, StartupUIMode mode, QLocale lang, bool
runAction->setEnabled(!runing);
cancelAction->setEnabled(runing);
});
internalCommandWindow->setPyRun(pyRun);
#else
runAction->setEnabled(false);
cancelAction->setEnabled(false);
Expand Down Expand Up @@ -3206,7 +3207,7 @@ void CentralWidget::menuAndToolBarConnectSignals(void) {
if(scriptPath.isEmpty()) return;
settings.setValue("Global/Options/ScriptPath",QFileInfo(scriptPath).absolutePath());
runScriptFullName = scriptPath;
pyRun->runScript(scriptPath);
pyRun->runScriptFile(scriptPath);
});
connect(cancelAction,&QAction::triggered,this,[=](){
pyRun->cancelScript();
Expand Down
106 changes: 99 additions & 7 deletions src/scriptengine/pyrun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,12 +356,40 @@ bool PyRun::isStopScript(void) {
return false;
}

void PyRun::runScript(QString scriptFile) {
void PyRun::runScript(struct ScriptInfo *scriptInfo) {
QMutexLocker locker(&mutex);
runScriptList.enqueue(scriptFile);
runScriptList.enqueue(*scriptInfo);
condition.wakeOne();
}

void PyRun::runScriptFile(const QString &scriptFile, QString *result, int *ret) {
if(result != nullptr) {
volatile bool finished = false;
struct ScriptInfo scriptInfo = {0,scriptFile,result,ret,&finished};
runScript(&scriptInfo);
while(!finished) {
qApp->processEvents();
}
} else {
struct ScriptInfo scriptInfo = {0,scriptFile,nullptr,nullptr,nullptr};
runScript(&scriptInfo);
}
}

void PyRun::runScriptStr(const QString &scriptStr, QString *result, int *ret) {
if(result != nullptr) {
volatile bool finished = false;
struct ScriptInfo scriptInfo = {1,scriptStr,result,ret,&finished};
runScript(&scriptInfo);
while(!finished) {
qApp->processEvents();
}
} else {
struct ScriptInfo scriptInfo = {1,scriptStr,nullptr,nullptr,nullptr};
runScript(&scriptInfo);
}
}

void PyRun::run() {
while(m_exit == false) {
mutex.lock();
Expand All @@ -372,21 +400,35 @@ void PyRun::run() {
return;
}
}
QString scriptFile = runScriptList.dequeue();
//QStringList script = runScriptList.dequeue();
struct ScriptInfo scriptInfo = runScriptList.dequeue();
mutex.unlock();
m_running = true;
emit runScriptStarted();
runScriptInternal(scriptFile);
QString *result = scriptInfo.result;
if(scriptInfo.type == 0) {
if(result != nullptr)
*result = runScriptFileInternal(scriptInfo.script, scriptInfo.ret);
else
runScriptFileInternal(scriptInfo.script,nullptr);
} else if(scriptInfo.type == 1) {
if(result != nullptr)
*result = runScriptStrInternal(scriptInfo.script, scriptInfo.ret);
else
runScriptStrInternal(scriptInfo.script,nullptr);
}
if(scriptInfo.finished != nullptr)
*scriptInfo.finished = true;
m_running = false;
emit runScriptFinished();
}
}

void PyRun::runScriptInternal(QString scriptFile) {
QString PyRun::runScriptFileInternal(const QString &scriptFile, int *sret) {
QFile file(scriptFile);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Failed to open script file";
return;
return QString();
}
QTextStream in(&file);
QStringList lines;
Expand All @@ -399,8 +441,58 @@ void PyRun::runScriptInternal(QString scriptFile) {
QByteArray scriptBytes = script.toUtf8();
const char* scriptStr = scriptBytes.constData();

PyObject* ioModule = PyImport_ImportModule("io");
PyObject* stringIO = PyObject_CallMethod(ioModule, "StringIO", nullptr);
PyObject* sysModule = PyImport_ImportModule("sys");
PyObject_SetAttrString(sysModule, "stdout", stringIO);

int ret = PyRun_SimpleString(scriptStr);
messageNotifications(tr("Script finished with return code: ") + QString::number(ret));
if(sret) {
*sret = ret;
}

PyObject* output = PyObject_CallMethod(stringIO, "getvalue", nullptr);
const char* outputStr = PyUnicode_AsUTF8(output);
QString outputQString = QString::fromUtf8(outputStr);
Py_DECREF(output);
Py_DECREF(ioModule);
Py_DECREF(stringIO);
Py_DECREF(sysModule);

if(!sret) {
messageNotifications(tr("Script finished with return code: ") + QString::number(ret));
}

return outputQString;
}

QString PyRun::runScriptStrInternal(const QString &scriptStr, int *sret) {
QByteArray scriptBytes = scriptStr.toUtf8();
const char* scriptString = scriptBytes.constData();

PyObject* ioModule = PyImport_ImportModule("io");
PyObject* stringIO = PyObject_CallMethod(ioModule, "StringIO", nullptr);
PyObject* sysModule = PyImport_ImportModule("sys");
PyObject_SetAttrString(sysModule, "stdout", stringIO);

int ret = PyRun_SimpleString(scriptString);
if(sret) {
*sret = ret;
}

PyObject* output = PyObject_CallMethod(stringIO, "getvalue", nullptr);
const char* outputStr = PyUnicode_AsUTF8(output);
QString outputQString = QString::fromUtf8(outputStr);
Py_DECREF(output);
Py_DECREF(ioModule);
Py_DECREF(stringIO);
Py_DECREF(sysModule);

if(!sret) {
messageNotifications(tr("Script finished with return code: ") + QString::number(ret));
}

return outputQString;
}

QString PyRun::getActivePrinter(void) {
Expand Down
16 changes: 13 additions & 3 deletions src/scriptengine/pyrun.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ class PyRun : public QThread
~PyRun();

QString getPyVersion(void) { return pyVersion; }
void runScript(QString scriptFile);
void runScriptFile(const QString &scriptFile, QString *result = nullptr, int *ret = nullptr);
void runScriptStr(const QString &scriptStr, QString *result = nullptr, int *ret = nullptr);
bool isRunning(void) { return m_running; }
void cancelScript(void);
bool isStopScript(void);
Expand Down Expand Up @@ -99,14 +100,23 @@ class PyRun : public QThread
void waitForStringFinished(const QString &str);

private:
void runScriptInternal(QString scriptFile);
struct ScriptInfo {
int type;
QString script;
QString *result;
int *ret;
volatile bool *finished;
};
void runScript(struct ScriptInfo *scriptInfo);
QString runScriptFileInternal(const QString &scriptFile, int *sret);
QString runScriptStrInternal(const QString &scriptStr, int *sret);

protected:
void run();

private:
QMutex mutex;
QQueue<QString> runScriptList;
QQueue<struct ScriptInfo> runScriptList;
QWaitCondition condition;

QMutex waitForStringMutex;
Expand Down
7 changes: 4 additions & 3 deletions src/statusbarwidget/statusbarwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,16 @@ class StatusBarToolButton : public QToolButton

QRect textRect = rect();
if (!icon().isNull()) {
int iconSize = 16;//style()->pixelMetric(QStyle::PM_ButtonIconSize);
QSize size = this->size();
int fontsize = painter.fontMetrics().horizontalAdvance(" ",1);
QFontMetrics fontMetrics = painter.fontMetrics();
int fontsize = fontMetrics.horizontalAdvance(" ",1);
int iconSize = fontMetrics.height();
if(text().isEmpty()) {
int iconX = (size.width() - iconSize) / 2;
int iconY = (size.height() - iconSize) / 2;
painter.drawPixmap(iconX, iconY, icon().pixmap(iconSize, iconSize));
} else {
int iconX = (size.width() - iconSize - fontsize/2 - painter.fontMetrics().horizontalAdvance(text())) / 2;
int iconX = (size.width() - iconSize - fontsize/2 - fontMetrics.horizontalAdvance(text())) / 2;
int iconY = (size.height() - iconSize) / 2;
painter.drawPixmap(iconX, iconY, icon().pixmap(iconSize, iconSize));
textRect.setLeft(iconX + iconSize + fontsize/2);
Expand Down

0 comments on commit c2eec9b

Please sign in to comment.