Skip to content

Commit c2eec9b

Browse files
committed
Update Internal Command
Signed-off-by: xiaoming <2014500726@smail.xtu.edu.cn>
1 parent 4475e99 commit c2eec9b

File tree

9 files changed

+202
-20
lines changed

9 files changed

+202
-20
lines changed

src/internalcommandwindow/internalcommandprocess.cpp

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ InternalCommandProcess::~InternalCommandProcess() {
1616
wait();
1717
}
1818

19+
void InternalCommandProcess::setPyRun(PyRun *pyRun) {
20+
m_pyRun = pyRun;
21+
}
22+
1923
void InternalCommandProcess::run(void) {
2024
sendWelcome();
2125
sendPrompt();
@@ -81,9 +85,18 @@ void InternalCommandProcess::processLine(const QString &sline) {
8185
},
8286
{"?" , "show this help message" ,
8387
[&](void) {
88+
static const int maxCmdNameCount = [&]() -> int {
89+
int ret = 0;
90+
foreach(const struct Command &cmd, commands) {
91+
ret = qMax(ret, cmd.name.size());
92+
}
93+
return ret;
94+
}();
8495
sendLineString("Available commands:");
8596
foreach(const struct Command &cmd, commands) {
86-
sendLineString(" " + cmd.name + " - " + cmd.description);
97+
if(!cmd.description.isEmpty()) {
98+
sendLineString(" " + cmd.name.leftJustified(maxCmdNameCount, ' ') + " - " + cmd.description);
99+
}
87100
}
88101
}
89102
},
@@ -225,6 +238,22 @@ void InternalCommandProcess::processLine(const QString &sline) {
225238
#endif
226239
}
227240
},
241+
#ifdef ENABLE_PYTHON
242+
{"run", "run script" ,
243+
[&](void) {
244+
if(args.size() >= 1) {
245+
QFileInfo fileInfo(args.at(0));
246+
if(fileInfo.isFile()) {
247+
if(m_pyRun) {
248+
m_pyRun->runScriptFile(args.at(0));
249+
}
250+
return;
251+
}
252+
}
253+
sendLineString("Script file not found!");
254+
}
255+
},
256+
#endif
228257
};
229258
if(command.isEmpty()) {
230259
return;
@@ -237,16 +266,33 @@ void InternalCommandProcess::processLine(const QString &sline) {
237266
break;
238267
}
239268
}
269+
QString fullCommand = command;
270+
if(!args.isEmpty()) {
271+
fullCommand = command + " " + args.join(' ');
272+
}
240273
if(!matched) {
241-
sendLineString("Unknown command: " + command);
274+
if(m_pyRun) {
275+
#ifdef ENABLE_PYTHON
276+
QString result;
277+
int ret = -1;
278+
m_pyRun->runScriptStr("print("+fullCommand+")", &result, &ret);
279+
if(ret == 0) {
280+
result.replace("\n","\r\n");
281+
sendString(result);
282+
} else
283+
#endif
284+
{
285+
sendLineString("Invalid command!");
286+
}
287+
}
242288
}
243-
if((!historyCmdList.isEmpty()) && historyCmdList.last() == command) {
289+
if((!historyCmdList.isEmpty()) && historyCmdList.last() == fullCommand) {
244290
return;
245291
}
246292
if(historyCmdList.count() >= 100) {
247293
historyCmdList.removeFirst();
248294
}
249-
historyCmdList.append(command);
295+
historyCmdList.append(fullCommand);
250296
historyCmdIndex = historyCmdList.count() - 1;
251297
}
252298

src/internalcommandwindow/internalcommandprocess.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@
66
#include <QMutex>
77
#include <QWaitCondition>
88

9+
#ifdef ENABLE_PYTHON
10+
#include "pyrun.h"
11+
#endif
12+
913
class InternalCommandProcess : public QThread
1014
{
1115
Q_OBJECT
1216
public:
1317
explicit InternalCommandProcess(QObject *parent = nullptr);
1418
~InternalCommandProcess();
15-
19+
#ifdef ENABLE_PYTHON
20+
void setPyRun(PyRun *pyRun);
21+
#endif
1622
void recvData(const QByteArray &data);
1723

1824
struct Command {
@@ -43,6 +49,9 @@ class InternalCommandProcess : public QThread
4349
QMutex mutex;
4450
QWaitCondition condition;
4551
bool exit;
52+
#ifdef ENABLE_PYTHON
53+
PyRun *m_pyRun = nullptr;
54+
#endif
4655
};
4756

4857
#endif // INTERNALCOMMANDPROCESS_H

src/internalcommandwindow/internalcommandwindow.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ InternalCommandWindow::~InternalCommandWindow() {
150150
delete ui;
151151
}
152152

153+
void InternalCommandWindow::setPyRun(PyRun *pyRun) {
154+
process->setPyRun(pyRun);
155+
}
156+
153157
void InternalCommandWindow::contextMenuEvent(QContextMenuEvent *event) {
154158
QMenu *menu = new QMenu(this);
155159
QList<QAction*> ftActions = term->filterActions(event->pos());

src/internalcommandwindow/internalcommandwindow.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ class InternalCommandWindow : public QDialog
1717
public:
1818
explicit InternalCommandWindow(QWidget *parent = nullptr);
1919
~InternalCommandWindow();
20+
#ifdef ENABLE_PYTHON
21+
void setPyRun(PyRun *pyRun);
22+
#endif
2023

2124
protected:
2225
void contextMenuEvent(QContextMenuEvent *event);

src/internalcommandwindow/internalcommandwindow.ui

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,23 @@
1313
<property name="windowTitle">
1414
<string>Internal Command</string>
1515
</property>
16-
<layout class="QVBoxLayout" name="verticalLayout"/>
16+
<layout class="QVBoxLayout" name="verticalLayout">
17+
<property name="spacing">
18+
<number>0</number>
19+
</property>
20+
<property name="leftMargin">
21+
<number>1</number>
22+
</property>
23+
<property name="topMargin">
24+
<number>1</number>
25+
</property>
26+
<property name="rightMargin">
27+
<number>1</number>
28+
</property>
29+
<property name="bottomMargin">
30+
<number>1</number>
31+
</property>
32+
</layout>
1733
</widget>
1834
<resources/>
1935
<connections/>

src/mainwindow.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,7 @@ CentralWidget::CentralWidget(QString dir, StartupUIMode mode, QLocale lang, bool
914914
runAction->setEnabled(!runing);
915915
cancelAction->setEnabled(runing);
916916
});
917+
internalCommandWindow->setPyRun(pyRun);
917918
#else
918919
runAction->setEnabled(false);
919920
cancelAction->setEnabled(false);
@@ -3206,7 +3207,7 @@ void CentralWidget::menuAndToolBarConnectSignals(void) {
32063207
if(scriptPath.isEmpty()) return;
32073208
settings.setValue("Global/Options/ScriptPath",QFileInfo(scriptPath).absolutePath());
32083209
runScriptFullName = scriptPath;
3209-
pyRun->runScript(scriptPath);
3210+
pyRun->runScriptFile(scriptPath);
32103211
});
32113212
connect(cancelAction,&QAction::triggered,this,[=](){
32123213
pyRun->cancelScript();

src/scriptengine/pyrun.cpp

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -356,12 +356,40 @@ bool PyRun::isStopScript(void) {
356356
return false;
357357
}
358358

359-
void PyRun::runScript(QString scriptFile) {
359+
void PyRun::runScript(struct ScriptInfo *scriptInfo) {
360360
QMutexLocker locker(&mutex);
361-
runScriptList.enqueue(scriptFile);
361+
runScriptList.enqueue(*scriptInfo);
362362
condition.wakeOne();
363363
}
364364

365+
void PyRun::runScriptFile(const QString &scriptFile, QString *result, int *ret) {
366+
if(result != nullptr) {
367+
volatile bool finished = false;
368+
struct ScriptInfo scriptInfo = {0,scriptFile,result,ret,&finished};
369+
runScript(&scriptInfo);
370+
while(!finished) {
371+
qApp->processEvents();
372+
}
373+
} else {
374+
struct ScriptInfo scriptInfo = {0,scriptFile,nullptr,nullptr,nullptr};
375+
runScript(&scriptInfo);
376+
}
377+
}
378+
379+
void PyRun::runScriptStr(const QString &scriptStr, QString *result, int *ret) {
380+
if(result != nullptr) {
381+
volatile bool finished = false;
382+
struct ScriptInfo scriptInfo = {1,scriptStr,result,ret,&finished};
383+
runScript(&scriptInfo);
384+
while(!finished) {
385+
qApp->processEvents();
386+
}
387+
} else {
388+
struct ScriptInfo scriptInfo = {1,scriptStr,nullptr,nullptr,nullptr};
389+
runScript(&scriptInfo);
390+
}
391+
}
392+
365393
void PyRun::run() {
366394
while(m_exit == false) {
367395
mutex.lock();
@@ -372,21 +400,35 @@ void PyRun::run() {
372400
return;
373401
}
374402
}
375-
QString scriptFile = runScriptList.dequeue();
403+
//QStringList script = runScriptList.dequeue();
404+
struct ScriptInfo scriptInfo = runScriptList.dequeue();
376405
mutex.unlock();
377406
m_running = true;
378407
emit runScriptStarted();
379-
runScriptInternal(scriptFile);
408+
QString *result = scriptInfo.result;
409+
if(scriptInfo.type == 0) {
410+
if(result != nullptr)
411+
*result = runScriptFileInternal(scriptInfo.script, scriptInfo.ret);
412+
else
413+
runScriptFileInternal(scriptInfo.script,nullptr);
414+
} else if(scriptInfo.type == 1) {
415+
if(result != nullptr)
416+
*result = runScriptStrInternal(scriptInfo.script, scriptInfo.ret);
417+
else
418+
runScriptStrInternal(scriptInfo.script,nullptr);
419+
}
420+
if(scriptInfo.finished != nullptr)
421+
*scriptInfo.finished = true;
380422
m_running = false;
381423
emit runScriptFinished();
382424
}
383425
}
384426

385-
void PyRun::runScriptInternal(QString scriptFile) {
427+
QString PyRun::runScriptFileInternal(const QString &scriptFile, int *sret) {
386428
QFile file(scriptFile);
387429
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
388430
qDebug() << "Failed to open script file";
389-
return;
431+
return QString();
390432
}
391433
QTextStream in(&file);
392434
QStringList lines;
@@ -399,8 +441,58 @@ void PyRun::runScriptInternal(QString scriptFile) {
399441
QByteArray scriptBytes = script.toUtf8();
400442
const char* scriptStr = scriptBytes.constData();
401443

444+
PyObject* ioModule = PyImport_ImportModule("io");
445+
PyObject* stringIO = PyObject_CallMethod(ioModule, "StringIO", nullptr);
446+
PyObject* sysModule = PyImport_ImportModule("sys");
447+
PyObject_SetAttrString(sysModule, "stdout", stringIO);
448+
402449
int ret = PyRun_SimpleString(scriptStr);
403-
messageNotifications(tr("Script finished with return code: ") + QString::number(ret));
450+
if(sret) {
451+
*sret = ret;
452+
}
453+
454+
PyObject* output = PyObject_CallMethod(stringIO, "getvalue", nullptr);
455+
const char* outputStr = PyUnicode_AsUTF8(output);
456+
QString outputQString = QString::fromUtf8(outputStr);
457+
Py_DECREF(output);
458+
Py_DECREF(ioModule);
459+
Py_DECREF(stringIO);
460+
Py_DECREF(sysModule);
461+
462+
if(!sret) {
463+
messageNotifications(tr("Script finished with return code: ") + QString::number(ret));
464+
}
465+
466+
return outputQString;
467+
}
468+
469+
QString PyRun::runScriptStrInternal(const QString &scriptStr, int *sret) {
470+
QByteArray scriptBytes = scriptStr.toUtf8();
471+
const char* scriptString = scriptBytes.constData();
472+
473+
PyObject* ioModule = PyImport_ImportModule("io");
474+
PyObject* stringIO = PyObject_CallMethod(ioModule, "StringIO", nullptr);
475+
PyObject* sysModule = PyImport_ImportModule("sys");
476+
PyObject_SetAttrString(sysModule, "stdout", stringIO);
477+
478+
int ret = PyRun_SimpleString(scriptString);
479+
if(sret) {
480+
*sret = ret;
481+
}
482+
483+
PyObject* output = PyObject_CallMethod(stringIO, "getvalue", nullptr);
484+
const char* outputStr = PyUnicode_AsUTF8(output);
485+
QString outputQString = QString::fromUtf8(outputStr);
486+
Py_DECREF(output);
487+
Py_DECREF(ioModule);
488+
Py_DECREF(stringIO);
489+
Py_DECREF(sysModule);
490+
491+
if(!sret) {
492+
messageNotifications(tr("Script finished with return code: ") + QString::number(ret));
493+
}
494+
495+
return outputQString;
404496
}
405497

406498
QString PyRun::getActivePrinter(void) {

src/scriptengine/pyrun.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ class PyRun : public QThread
1616
~PyRun();
1717

1818
QString getPyVersion(void) { return pyVersion; }
19-
void runScript(QString scriptFile);
19+
void runScriptFile(const QString &scriptFile, QString *result = nullptr, int *ret = nullptr);
20+
void runScriptStr(const QString &scriptStr, QString *result = nullptr, int *ret = nullptr);
2021
bool isRunning(void) { return m_running; }
2122
void cancelScript(void);
2223
bool isStopScript(void);
@@ -99,14 +100,23 @@ class PyRun : public QThread
99100
void waitForStringFinished(const QString &str);
100101

101102
private:
102-
void runScriptInternal(QString scriptFile);
103+
struct ScriptInfo {
104+
int type;
105+
QString script;
106+
QString *result;
107+
int *ret;
108+
volatile bool *finished;
109+
};
110+
void runScript(struct ScriptInfo *scriptInfo);
111+
QString runScriptFileInternal(const QString &scriptFile, int *sret);
112+
QString runScriptStrInternal(const QString &scriptStr, int *sret);
103113

104114
protected:
105115
void run();
106116

107117
private:
108118
QMutex mutex;
109-
QQueue<QString> runScriptList;
119+
QQueue<struct ScriptInfo> runScriptList;
110120
QWaitCondition condition;
111121

112122
QMutex waitForStringMutex;

src/statusbarwidget/statusbarwidget.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,16 @@ class StatusBarToolButton : public QToolButton
8484

8585
QRect textRect = rect();
8686
if (!icon().isNull()) {
87-
int iconSize = 16;//style()->pixelMetric(QStyle::PM_ButtonIconSize);
8887
QSize size = this->size();
89-
int fontsize = painter.fontMetrics().horizontalAdvance(" ",1);
88+
QFontMetrics fontMetrics = painter.fontMetrics();
89+
int fontsize = fontMetrics.horizontalAdvance(" ",1);
90+
int iconSize = fontMetrics.height();
9091
if(text().isEmpty()) {
9192
int iconX = (size.width() - iconSize) / 2;
9293
int iconY = (size.height() - iconSize) / 2;
9394
painter.drawPixmap(iconX, iconY, icon().pixmap(iconSize, iconSize));
9495
} else {
95-
int iconX = (size.width() - iconSize - fontsize/2 - painter.fontMetrics().horizontalAdvance(text())) / 2;
96+
int iconX = (size.width() - iconSize - fontsize/2 - fontMetrics.horizontalAdvance(text())) / 2;
9697
int iconY = (size.height() - iconSize) / 2;
9798
painter.drawPixmap(iconX, iconY, icon().pixmap(iconSize, iconSize));
9899
textRect.setLeft(iconX + iconSize + fontsize/2);

0 commit comments

Comments
 (0)