From e0b4a2eeab91696e54d9ff3acc319d99ab9b96f9 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 14 Dec 2018 17:20:25 +0100 Subject: [PATCH] Add GUI for executing python file --- .../python-console/modified/pyinterpreter.cc | 22 ++++++++++++++++++ .../python-console/modified/pyinterpreter.h | 1 + gui/base.qrc | 1 + gui/basewindow.cc | 18 ++++++++++++++ gui/basewindow.h | 5 ++++ gui/pyconsole.cc | 17 ++++++++++++++ gui/pyconsole.h | 1 + gui/pythontab.cc | 2 ++ gui/pythontab.h | 1 + gui/resources/py.png | Bin 0 -> 2277 bytes 10 files changed, 68 insertions(+) create mode 100644 gui/resources/py.png diff --git a/3rdparty/python-console/modified/pyinterpreter.cc b/3rdparty/python-console/modified/pyinterpreter.cc index f53207ad..89c9b88c 100644 --- a/3rdparty/python-console/modified/pyinterpreter.cc +++ b/3rdparty/python-console/modified/pyinterpreter.cc @@ -153,3 +153,25 @@ void pyinterpreter_release() { PyEval_ReleaseThread(m_threadState); } + +std::string pyinterpreter_execute_file(const char *python_file, int *errorCode) +{ + PyEval_AcquireThread(m_threadState); + *errorCode = 0; + std::string res; + FILE *fp = fopen(python_file, "r"); + if (fp == NULL) { + *errorCode = 1; + res = "Fatal error: file not found " + std::string(python_file) + "\n"; + return res; + } + + if (PyRun_SimpleFile(fp, python_file)==-1) { + *errorCode = 1; + PyErr_Print(); + } + res = redirector_take_output(m_threadState); + + PyEval_ReleaseThread(m_threadState); + return res; +} diff --git a/3rdparty/python-console/modified/pyinterpreter.h b/3rdparty/python-console/modified/pyinterpreter.h index 1a85c1fb..48512507 100644 --- a/3rdparty/python-console/modified/pyinterpreter.h +++ b/3rdparty/python-console/modified/pyinterpreter.h @@ -33,4 +33,5 @@ void pyinterpreter_initialize(); void pyinterpreter_finalize(); void pyinterpreter_aquire(); void pyinterpreter_release(); +std::string pyinterpreter_execute_file(const char *python_file, int *errorCode); #endif // PYINTERPRETER_H diff --git a/gui/base.qrc b/gui/base.qrc index 8f58f585..644b16a6 100644 --- a/gui/base.qrc +++ b/gui/base.qrc @@ -22,5 +22,6 @@ resources/route.png resources/time_add.png resources/open_json.png + resources/py.png diff --git a/gui/basewindow.cc b/gui/basewindow.cc index 49c2d8d5..346efb88 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -189,6 +189,12 @@ void BaseMainWindow::createMenusAndBars() actionRoute->setEnabled(false); connect(actionRoute, &QAction::triggered, task, &TaskManager::route); + actionExecutePy = new QAction("Execute Python", this); + actionExecutePy->setIcon(QIcon(":/icons/resources/py.png")); + actionExecutePy->setStatusTip("Execute Python script"); + actionExecutePy->setEnabled(true); + connect(actionExecutePy, &QAction::triggered, this, &BaseMainWindow::execute_python); + // Worker control toolbar actions actionPlay = new QAction("Play", this); actionPlay->setIcon(QIcon(":/icons/resources/control_play.png")); @@ -249,6 +255,8 @@ void BaseMainWindow::createMenusAndBars() menuDesign->addAction(actionAssignBudget); menuDesign->addAction(actionPlace); menuDesign->addAction(actionRoute); + menuDesign->addSeparator(); + menuDesign->addAction(actionExecutePy); // Add Help menu actions menuHelp->addAction(actionAbout); @@ -268,6 +276,7 @@ void BaseMainWindow::createMenusAndBars() mainActionBar->addAction(actionAssignBudget); mainActionBar->addAction(actionPlace); mainActionBar->addAction(actionRoute); + mainActionBar->addAction(actionExecutePy); // Add worker control toolbar QToolBar *workerControlToolBar = new QToolBar("Worker"); @@ -412,6 +421,7 @@ void BaseMainWindow::disableActions() actionAssignBudget->setEnabled(false); actionPlace->setEnabled(false); actionRoute->setEnabled(false); + actionExecutePy->setEnabled(true); actionPlay->setEnabled(false); actionPause->setEnabled(false); @@ -454,6 +464,14 @@ void BaseMainWindow::open_proj() } } +void BaseMainWindow::execute_python() +{ + QString fileName = QFileDialog::getOpenFileName(this, QString("Execute Python"), QString(), QString("*.py")); + if (!fileName.isEmpty()) { + console->execute_python(fileName.toStdString()); + } +} + void BaseMainWindow::notifyChangeContext() { Q_EMIT contextChanged(ctx.get()); } void BaseMainWindow::save_proj() { diff --git a/gui/basewindow.h b/gui/basewindow.h index eb32033a..0b2d3fbc 100644 --- a/gui/basewindow.h +++ b/gui/basewindow.h @@ -78,6 +78,8 @@ class BaseMainWindow : public QMainWindow void budget(); void place(); + void execute_python(); + void pack_finished(bool status); void budget_finish(bool status); void place_finished(bool status); @@ -122,6 +124,9 @@ class BaseMainWindow : public QMainWindow QAction *actionAssignBudget; QAction *actionPlace; QAction *actionRoute; + + QAction *actionExecutePy; + QAction *actionPlay; QAction *actionPause; QAction *actionStop; diff --git a/gui/pyconsole.cc b/gui/pyconsole.cc index 0ee393ce..d015aea2 100644 --- a/gui/pyconsole.cc +++ b/gui/pyconsole.cc @@ -76,4 +76,21 @@ void PythonConsole::moveCursorToEnd() setTextCursor(cursor); } +void PythonConsole::execute_python(std::string filename) +{ + int errorCode = 0; + std::string res; + res = pyinterpreter_execute_file(filename.c_str(), &errorCode); + if (res.size()) { + if (errorCode) { + setTextColor(ERROR_COLOR); + } else { + setTextColor(OUTPUT_COLOR); + } + append(res.c_str()); + setTextColor(NORMAL_COLOR); + moveCursorToEnd(); + } +} + NEXTPNR_NAMESPACE_END diff --git a/gui/pyconsole.h b/gui/pyconsole.h index 9dbd3b95..977242f3 100644 --- a/gui/pyconsole.h +++ b/gui/pyconsole.h @@ -43,6 +43,7 @@ class PythonConsole : public QTextEdit, public ParseListener void displayString(QString text); void moveCursorToEnd(); virtual void parseEvent(const ParseMessage &message); + void execute_python(std::string filename); protected: static const QColor NORMAL_COLOR; diff --git a/gui/pythontab.cc b/gui/pythontab.cc index 80d731e9..827f1907 100644 --- a/gui/pythontab.cc +++ b/gui/pythontab.cc @@ -114,4 +114,6 @@ void PythonTab::clearBuffer() { console->clear(); } void PythonTab::info(std::string str) { console->displayString(str.c_str()); } +void PythonTab::execute_python(std::string filename) { console->execute_python(filename); } + NEXTPNR_NAMESPACE_END diff --git a/gui/pythontab.h b/gui/pythontab.h index 134874b6..860bf1c3 100644 --- a/gui/pythontab.h +++ b/gui/pythontab.h @@ -45,6 +45,7 @@ class PythonTab : public QWidget void newContext(Context *ctx); void info(std::string str); void clearBuffer(); + void execute_python(std::string filename); private: PythonConsole *console; diff --git a/gui/resources/py.png b/gui/resources/py.png new file mode 100644 index 0000000000000000000000000000000000000000..9cc6e522f0de29cedb021cef796602a2274ad76e GIT binary patch literal 2277 zcmVU?d)MpT^~&}dysQr#V+n&eBmx#vE+Ci)@r6^lkO)K} zij+i=0(?OsQ6LEkm=FPRPC^m_*l_|e#Et-;*k*mQhu3?~?9A*OJ=0y457Q>=aM)P1 z^zTwj)$jf5|6aX%C7kthz14GBofCLXGUBGHyz)K&Y^=yfncVdC2a}!CYPHs-HI-tf z&-Zd2lq;4*Q)xHac+gGO@9<*D?FSydee7c=(0}Vg>+{1$Z?r5fZ)$B#wYRrReSHd0 zc%?kkQyHcv$I8W$c|Fz9^{d?*?tbiJBe3G;AAe;wH~!t$mU*q$ty|0Ci6Yb49ImC% zM&m{-60s+EG2X^9{dp6wllhfI@PB-C#FFo0nojCYl|MC@!AGq^6)~{Vi zZ+n8rH|;%|i$Io~otmPiNmgErDVd69}m~ zmq$0f#kPSF4v%K(Xs##e+JGhq0?J;Mh*H>=;93?`j09Cr&WgafxBt3B)Ksg=J~-N^e^n+XC%tK;uSZ92%KKDIpQHK@7zp%83b=k4#|sEkC$*cJz(g zBg$J`tQgToGn+3pKmF8Gc%Fwb2CV@R0>8@g{_|M3?n>fr1lLt$W<3I3WV)E(8*4W# zy6(W|+*ESlZP=qnq!zqVdf~Umt|A42WP_5*#YM%+s;U`Q>{F+;EjWGjj0y zOD|s0bMAS4ymNdEw8o7nJkKXz^vD*=6w5wdwTdx@APDfPRlG`-*+K;+hM4Q1EQ^vK zK^(f*T=TF{w+I5m)X=t`gFEi;uWr?O=Mw&K3W4(@pF3xU{a3DDxty77mY5CcoX6Y4 zc}AyaDU>}F22r3)O$n4i8Bi9~MQwDTv2BIHLK~r20AlUnAAw4mmZeuvDr7pgZF}Sk zW+#7>Rg~V{h7~ES?wsE`e_>A-CKgzN39O!^V)FBqJu`Pv2SV0VEG5Efw zQVs9|O;df6sdR~`n!vRXObUu=C{4l4F1q`#C0FHQU846C1*%oEbV*;gotZ7Ob^me3 zGezoLi-;}gz(*TsO2w&9#)&uGh6G<5=(+bC+8PzisJh2H=HFahOJ@ZJF}5agh+ z1Il}#@CGz|jbbrJq>f1e^DY6~nEi!(W*WcLo{YxG=4PpjM5t6eWOjhh^kX8+zAu1dl@(-2c}c@A^W)d+W64X zYv(UmiZ+_4>);0pF7%=t9ewfGC(h&d zt`NNMX}EX8T~GAi`^>Y|O}G)5ShFiH>(MA&VJ1la5FME)WM&4?fF+FJ2S& zk3sk{K1}`@R}6@OAOlhd$<>hGhSPcjF$?Rb&olnSbBq85z&n$U$N`c-<4Np2Oi!vF z3(K$RTPfBmn|A_Ctt+BB2Fv~h$%|lSBY3+=Cb5nU(+$i3X&?jS0sn)VQWdVc5oiWl zfVSO7h|gr1HJKyOdMVf`sLp_&1ziALglYiQshX9B3kcG0Q^=FvzMp7lr#ZA6pX=9t zznF)xLp2<)O8KRKv$wnZ$+nj6&pXbdFM~e~#UZGqYf~K;s#{=Ygu=kjIX<*I|KfID zFPABWw&p@U=w4vvkg&s10rJnCoN)2VQrH=@id*B=T-MS$g|a&Fb&T2cH0hC7&58Zb zl;7MrKJc4OY<}P=UJ2#ThRB5>sC?KikT3z0Km$-8A_*j|2yM4r#p2b==D=eP53R{m8uY|400000NkvXXu0mjfUyeCg literal 0 HcmV?d00001