aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiodrag Milanovic <mmicko@gmail.com>2018-06-20 09:42:47 +0200
committerMiodrag Milanovic <mmicko@gmail.com>2018-06-20 09:43:18 +0200
commit7975afc30f737e8468b32285b82db26bf0023d32 (patch)
tree395351dc4f19329cd8ff65d1837b4ddf23284431
parent1d3450793767ced2003b6d3fb4b7ea2f49f0d1ca (diff)
downloadnextpnr-7975afc30f737e8468b32285b82db26bf0023d32.tar.gz
nextpnr-7975afc30f737e8468b32285b82db26bf0023d32.tar.bz2
nextpnr-7975afc30f737e8468b32285b82db26bf0023d32.zip
Added custom line editor with history
-rw-r--r--gui/gui.cmake2
-rw-r--r--gui/line_editor.cc67
-rw-r--r--gui/line_editor.h31
-rw-r--r--gui/pythontab.cc33
-rw-r--r--gui/pythontab.h8
5 files changed, 124 insertions, 17 deletions
diff --git a/gui/gui.cmake b/gui/gui.cmake
index 961d498a..08a2c0b4 100644
--- a/gui/gui.cmake
+++ b/gui/gui.cmake
@@ -12,6 +12,7 @@ qt5_generate_moc(gui/fpgaviewwidget.h ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_
qt5_generate_moc(gui/pythontab.h ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_pythontab.cc)
qt5_generate_moc(gui/infotab.h ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_infotab.cc)
qt5_generate_moc(gui/designwidget.h ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_designwidget.cc)
+qt5_generate_moc(gui/line_editor.h ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_line_editor.cc)
set(GENERATED_MOC_FILES
${CMAKE_CURRENT_BINARY_DIR}/generated/moc_mainwindow.cc
@@ -19,6 +20,7 @@ set(GENERATED_MOC_FILES
${CMAKE_CURRENT_BINARY_DIR}/generated/moc_pythontab.cc
${CMAKE_CURRENT_BINARY_DIR}/generated/moc_infotab.cc
${CMAKE_CURRENT_BINARY_DIR}/generated/moc_designwidget.cc
+ ${CMAKE_CURRENT_BINARY_DIR}/generated/moc_line_editor.cc
)
qt5_add_resources_custom(GUI_RESOURCE_FILES gui/nextpnr.qrc)
diff --git a/gui/line_editor.cc b/gui/line_editor.cc
new file mode 100644
index 00000000..b5ed955f
--- /dev/null
+++ b/gui/line_editor.cc
@@ -0,0 +1,67 @@
+#include "line_editor.h"
+
+#include <QKeyEvent>
+
+LineEditor::LineEditor(QWidget *parent) : QLineEdit(parent), index(0)
+{
+ setContextMenuPolicy(Qt::CustomContextMenu);
+ QAction *clearAction = new QAction("Clear &history", this);
+ clearAction->setStatusTip("Clears line edit history");
+ connect(clearAction, SIGNAL(triggered()), this, SLOT(clearHistory()));
+ contextMenu = createStandardContextMenu();
+ contextMenu->addSeparator();
+ contextMenu->addAction(clearAction);
+
+ connect(this, SIGNAL(returnPressed()), SLOT(textInserted()));
+ connect(this, SIGNAL(customContextMenuRequested(const QPoint)), this,
+ SLOT(showContextMenu(const QPoint)));
+}
+
+void LineEditor::keyPressEvent(QKeyEvent *ev)
+{
+ if (ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down) {
+ if (lines.empty())
+ return;
+
+ if (ev->key() == Qt::Key_Up)
+ index--;
+ if (ev->key() == Qt::Key_Down)
+ index++;
+
+ if (index < 0)
+ index = 0;
+ if (index >= lines.size()) {
+ index = lines.size();
+ clear();
+ return;
+ }
+ setText(lines[index]);
+ } else if (ev->key() == Qt::Key_Escape) {
+ clear();
+ return;
+ }
+ QLineEdit::keyPressEvent(ev);
+}
+
+void LineEditor::textInserted()
+{
+ if (lines.empty() || lines.back() != text())
+ lines += text();
+ if (lines.size() > 100)
+ lines.removeFirst();
+ index = lines.size();
+ clear();
+ Q_EMIT textLineInserted(lines.back());
+}
+
+void LineEditor::showContextMenu(const QPoint &pt)
+{
+ contextMenu->exec(mapToGlobal(pt));
+}
+
+void LineEditor::clearHistory()
+{
+ lines.clear();
+ index = 0;
+ clear();
+} \ No newline at end of file
diff --git a/gui/line_editor.h b/gui/line_editor.h
new file mode 100644
index 00000000..15b675f9
--- /dev/null
+++ b/gui/line_editor.h
@@ -0,0 +1,31 @@
+#ifndef LINE_EDITOR_H
+#define LINE_EDITOR_H
+
+#include <QLineEdit>
+#include <QMenu>
+
+class LineEditor : public QLineEdit
+{
+ Q_OBJECT
+
+ public:
+ explicit LineEditor(QWidget *parent = 0);
+
+ private Q_SLOTS:
+ void textInserted();
+ void showContextMenu(const QPoint &pt);
+ void clearHistory();
+
+ Q_SIGNALS:
+ void textLineInserted(QString);
+
+ protected:
+ void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE;
+
+ private:
+ int index;
+ QStringList lines;
+ QMenu *contextMenu;
+};
+
+#endif // LINE_EDITOR_H
diff --git a/gui/pythontab.cc b/gui/pythontab.cc
index 3764696e..04db056d 100644
--- a/gui/pythontab.cc
+++ b/gui/pythontab.cc
@@ -15,7 +15,7 @@ PythonTab::PythonTab(QWidget *parent) : QWidget(parent)
f.setStyleHint(QFont::Monospace);
plainTextEdit->setFont(f);
- lineEdit = new QLineEdit();
+ lineEdit = new LineEditor();
lineEdit->setMinimumHeight(30);
lineEdit->setMaximumHeight(30);
lineEdit->setFont(f);
@@ -25,8 +25,8 @@ PythonTab::PythonTab(QWidget *parent) : QWidget(parent)
mainLayout->addWidget(lineEdit, 1, 0);
setLayout(mainLayout);
- connect(lineEdit, SIGNAL(returnPressed()), this,
- SLOT(editLineReturnPressed()));
+ connect(lineEdit, SIGNAL(textLineInserted(QString)), this,
+ SLOT(editLineReturnPressed(QString)));
write = [this](std::string s) {
plainTextEdit->moveCursor(QTextCursor::End);
@@ -34,11 +34,22 @@ PythonTab::PythonTab(QWidget *parent) : QWidget(parent)
plainTextEdit->moveCursor(QTextCursor::End);
};
emb::set_stdout(write);
+
+ char buff[1024];
+ sprintf(buff, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform());
+ print(buff);
+}
+
+void PythonTab::print(std::string line)
+{
+ plainTextEdit->moveCursor(QTextCursor::End);
+ plainTextEdit->insertPlainText(line.c_str());
+ plainTextEdit->moveCursor(QTextCursor::End);
}
void handle_system_exit() { exit(-1); }
-int PythonTab::executePython(std::string command)
+int PythonTab::executePython(std::string &command)
{
PyObject *m, *d, *v;
m = PyImport_AddModule("__main__");
@@ -70,9 +81,7 @@ int PythonTab::executePython(std::string command)
PyObject *objectsRepresentation = PyObject_Str(v);
std::string errorStr =
PyUnicode_AsUTF8(objectsRepresentation) + std::string("\n");
- plainTextEdit->moveCursor(QTextCursor::End);
- plainTextEdit->insertPlainText(errorStr.c_str());
- plainTextEdit->moveCursor(QTextCursor::End);
+ print(errorStr);
Py_DECREF(objectsRepresentation);
Py_XDECREF(exception);
Py_XDECREF(v);
@@ -83,13 +92,9 @@ int PythonTab::executePython(std::string command)
return 0;
}
-void PythonTab::editLineReturnPressed()
+void PythonTab::editLineReturnPressed(QString text)
{
- std::string input = lineEdit->text().toStdString();
- plainTextEdit->moveCursor(QTextCursor::End);
- plainTextEdit->insertPlainText(std::string(">>> " + input + "\n").c_str());
- plainTextEdit->moveCursor(QTextCursor::End);
- plainTextEdit->update();
- lineEdit->clear();
+ std::string input = text.toStdString();
+ print(std::string(">>> " + input + "\n"));
int error = executePython(input);
}
diff --git a/gui/pythontab.h b/gui/pythontab.h
index 4290d277..3876b3df 100644
--- a/gui/pythontab.h
+++ b/gui/pythontab.h
@@ -4,6 +4,7 @@
#include <QLineEdit>
#include <QPlainTextEdit>
#include "emb.h"
+#include "line_editor.h"
#include "nextpnr.h"
// FIXME
@@ -17,13 +18,14 @@ class PythonTab : public QWidget
explicit PythonTab(QWidget *parent = 0);
private:
- int executePython(std::string command);
+ void print(std::string line);
+ int executePython(std::string &command);
private Q_SLOTS:
- void editLineReturnPressed();
+ void editLineReturnPressed(QString text);
private:
QPlainTextEdit *plainTextEdit;
- QLineEdit *lineEdit;
+ LineEditor *lineEdit;
emb::stdout_write_type write;
};