Added custom line editor with history

This commit is contained in:
Miodrag Milanovic 2018-06-20 09:42:47 +02:00
parent 1d34507937
commit 7975afc30f
5 changed files with 124 additions and 17 deletions

View File

@ -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)

67
gui/line_editor.cc Normal file
View File

@ -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();
}

31
gui/line_editor.h Normal file
View File

@ -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

View File

@ -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);
}

View File

@ -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;
};