diff options
| -rw-r--r-- | gui/gui.cmake | 2 | ||||
| -rw-r--r-- | gui/line_editor.cc | 67 | ||||
| -rw-r--r-- | gui/line_editor.h | 31 | ||||
| -rw-r--r-- | gui/pythontab.cc | 33 | ||||
| -rw-r--r-- | gui/pythontab.h | 8 | 
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;
  };
  | 
