/* | |
* nextpnr -- Next Generation Place and Route | |
* | |
* Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com> | |
* | |
* Permission to use, copy, modify, and/or distribute this software for any | |
* purpose with or without fee is hereby granted, provided that the above | |
* copyright notice and this permission notice appear in all copies. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
* | |
*/ | |
#include "pythontab.h" | |
#include <QGridLayout> | |
#include "pybindings.h" | |
#include "pyinterpreter.h" | |
NEXTPNR_NAMESPACE_BEGIN | |
const QString PythonTab::PROMPT = ">>> "; | |
const QString PythonTab::MULTILINE_PROMPT = "... "; | |
PythonTab::PythonTab(QWidget *parent) : QWidget(parent), initialized(false) | |
{ | |
QFont f("unexistent"); | |
f.setStyleHint(QFont::Monospace); | |
// Add text area for Python output and input line | |
console = new PythonConsole(); | |
console->setMinimumHeight(100); | |
console->setReadOnly(true); | |
console->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); | |
console->setFont(f); | |
console->setContextMenuPolicy(Qt::CustomContextMenu); | |
QAction *clearAction = new QAction("Clear &buffer", this); | |
clearAction->setStatusTip("Clears display buffer"); | |
connect(clearAction, &QAction::triggered, this, &PythonTab::clearBuffer); | |
contextMenu = console->createStandardContextMenu(); | |
contextMenu->addSeparator(); | |
contextMenu->addAction(clearAction); | |
connect(console, &PythonConsole::customContextMenuRequested, this, &PythonTab::showContextMenu); | |
lineEdit = new LineEditor(&parseHelper); | |
lineEdit->setMinimumHeight(30); | |
lineEdit->setMaximumHeight(30); | |
lineEdit->setFont(f); | |
lineEdit->setPlaceholderText(PythonTab::PROMPT); | |
connect(lineEdit, &LineEditor::textLineInserted, this, &PythonTab::editLineReturnPressed); | |
QGridLayout *mainLayout = new QGridLayout(); | |
mainLayout->addWidget(console, 0, 0); | |
mainLayout->addWidget(lineEdit, 1, 0); | |
setLayout(mainLayout); | |
parseHelper.subscribe(console); | |
prompt = PythonTab::PROMPT; | |
} | |
PythonTab::~PythonTab() | |
{ | |
if (initialized) { | |
pyinterpreter_finalize(); | |
deinit_python(); | |
} | |
} | |
void PythonTab::editLineReturnPressed(QString text) | |
{ | |
console->displayString(prompt + text + "\n"); | |
parseHelper.process(text.toStdString()); | |
if (parseHelper.buffered()) | |
prompt = PythonTab::MULTILINE_PROMPT; | |
else | |
prompt = PythonTab::PROMPT; | |
lineEdit->setPlaceholderText(prompt); | |
} | |
void PythonTab::newContext(Context *ctx) | |
{ | |
if (initialized) { | |
pyinterpreter_finalize(); | |
deinit_python(); | |
} | |
console->clear(); | |
pyinterpreter_preinit(); | |
init_python("nextpnr", true); | |
pyinterpreter_initialize(); | |
pyinterpreter_aquire(); | |
init_python("nextpnr", false); | |
python_export_global("ctx", ctx); | |
pyinterpreter_release(); | |
initialized = true; | |
QString version = QString("Python %1 on %2\n").arg(Py_GetVersion(), Py_GetPlatform()); | |
console->displayString(version); | |
} | |
void PythonTab::showContextMenu(const QPoint &pt) { contextMenu->exec(mapToGlobal(pt)); } | |
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 |