From cb040f47a1d3c8dfd3e0d2b39709fde4370691a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Tue, 31 Jan 2017 19:54:18 +0000 Subject: [PATCH] added CodeEditor with line numbering from Qt sample code --- COPYING | 2 +- ChangeLog | 35 ++++++++++++++++ INSTALL | 2 +- src/editor.hxx | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ src/makefile.am | 2 +- src/testgui.hxx | 1 + src/testgui.ui | 47 +++++++++++---------- 7 files changed, 172 insertions(+), 24 deletions(-) create mode 100644 src/editor.hxx diff --git a/COPYING b/COPYING index caeca07..88798ab 120000 --- a/COPYING +++ b/COPYING @@ -1 +1 @@ -/usr/share/automake-1.14/COPYING \ No newline at end of file +/usr/share/automake-1.15/COPYING \ No newline at end of file diff --git a/ChangeLog b/ChangeLog index d82d123..a46cdf3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,38 @@ +2017-01-31 17:32 + + * [r97] src/commands.hxx, src/webrunner.cxx: + better progress indicator + +2017-01-30 15:09 + + * [r96] src/testgui.hxx, src/testgui.ui, src/webtester.cxx: + fixed window title and file modification dialog + +2017-01-27 15:57 + + * [r95] src/testgui.hxx, src/testgui.ui: + url as combobox with completion + +2017-01-24 14:17 + + * [r94] src/commands.hxx, src/testgui.hxx, src/testgui.ui: + show test result as check mark or cross + +2017-01-20 10:58 + + * [r93] doc/footer.html.in[ADD], doc/header.html.in[ADD], + doc/plantuml.jar[ADD], doc/style.css[ADD], + makefile_test.inc.am[ADD]: + packager fixed - fix + +2017-01-20 10:57 + + * [r92] ChangeLog, bootstrap.sh, build-in-docker.conf, + debian/changelog.in, doc/footer.html.in[DEL], + doc/header.html.in[DEL], doc/plantuml.jar[DEL], + doc/style.css[DEL], makefile_test.inc.am[DEL]: + packager fixed + 2017-01-20 08:30 * [r91] COPYING, INSTALL, README, configure.ac, src/commands.hxx, diff --git a/INSTALL b/INSTALL index f812f5a..ddcdb76 120000 --- a/INSTALL +++ b/INSTALL @@ -1 +1 @@ -/usr/share/automake-1.14/INSTALL \ No newline at end of file +/usr/share/automake-1.15/INSTALL \ No newline at end of file diff --git a/src/editor.hxx b/src/editor.hxx new file mode 100644 index 0000000..4baaac4 --- /dev/null +++ b/src/editor.hxx @@ -0,0 +1,107 @@ +#ifndef EDITOR_HXX +#define EDITOR_HXX +/// from qt http://doc.qt.io/qt-5/qtwidgets-widgets-codeeditor-example.html + +#include +#include +#include +#include + +class CodeEditor; + +class LineNumberArea: public QWidget { + public: + LineNumberArea(CodeEditor *editor); + QSize sizeHint() const override; + protected: + void paintEvent(QPaintEvent *event) override; + private: + CodeEditor *codeEditor; +}; + +class CodeEditor: public QPlainTextEdit { + Q_OBJECT; + public: + CodeEditor(QWidget *parent = 0): QPlainTextEdit(parent) { + lineNumberArea = new LineNumberArea(this); + connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); + connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); + connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); + updateLineNumberAreaWidth(0); + highlightCurrentLine(); + } + void lineNumberAreaPaintEvent(QPaintEvent *event) { + QPainter painter(lineNumberArea); + painter.fillRect(event->rect(), Qt::lightGray); + QTextBlock block = firstVisibleBlock(); + int blockNumber = block.blockNumber(); + int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); + int bottom = top + (int) blockBoundingRect(block).height(); + while (block.isValid() && top <= event->rect().bottom()) { + if (block.isVisible() && bottom >= event->rect().top()) { + QString number = QString::number(blockNumber + 1); + painter.setPen(Qt::black); + painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), + Qt::AlignRight, number); + } + block = block.next(); + top = bottom; + bottom = top + (int) blockBoundingRect(block).height(); + ++blockNumber; + } + } + int lineNumberAreaWidth() { + int digits(1); + int max = qMax(1, blockCount()); + while (max >= 10) { + max /= 10; + ++digits; + } + int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits; + return space; + } + protected: + void resizeEvent(QResizeEvent *e) override { + QPlainTextEdit::resizeEvent(e); + QRect cr = contentsRect(); + lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); + } + private Q_SLOTS: + void updateLineNumberAreaWidth(int newBlockCount) { + setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); + } + void highlightCurrentLine() { + QList extraSelections; + if (!isReadOnly()) { + QTextEdit::ExtraSelection selection; + QColor lineColor = QColor(Qt::yellow).lighter(160); + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = textCursor(); + selection.cursor.clearSelection(); + extraSelections.append(selection); + } + setExtraSelections(extraSelections); + } + void updateLineNumberArea(const QRect &rect, int dy) { + if (dy) + lineNumberArea->scroll(0, dy); + else + lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); + if (rect.contains(viewport()->rect())) + updateLineNumberAreaWidth(0); + } + private: + QWidget *lineNumberArea; +}; + +inline LineNumberArea::LineNumberArea(CodeEditor *editor): QWidget(editor) { + codeEditor = editor; +} +inline QSize LineNumberArea::sizeHint() const { + return QSize(codeEditor->lineNumberAreaWidth(), 0); +} +inline void LineNumberArea::paintEvent(QPaintEvent *event) { + codeEditor->lineNumberAreaPaintEvent(event); +} +#endif diff --git a/src/makefile.am b/src/makefile.am index 0c634a5..19cfa52 100644 --- a/src/makefile.am +++ b/src/makefile.am @@ -9,7 +9,7 @@ bin_PROGRAMS = webtester webrunner webtester_MOCFILES = moc_testgui.cxx moc_commands.cxx moc_webpage.cxx \ - moc_networkaccessmanager.cxx + moc_networkaccessmanager.cxx moc_editor.cxx webtester_UIFILES = ui_testgui.hxx webtester_SOURCES = version.cxx webtester.cxx exceptions.hxx version.hxx \ ${webtester_MOCFILES} ${webtester_UIFILES} diff --git a/src/testgui.hxx b/src/testgui.hxx index 4ba3501..f74c719 100644 --- a/src/testgui.hxx +++ b/src/testgui.hxx @@ -8,6 +8,7 @@ #define TESTGUI_HXX #include +#include #include #include #include diff --git a/src/testgui.ui b/src/testgui.ui index 4a7edfd..6334dbd 100644 --- a/src/testgui.ui +++ b/src/testgui.ui @@ -81,8 +81,8 @@ - - + + about:blank @@ -97,12 +97,12 @@ 0 0 888 - 20 + 26 - Views + &Views @@ -173,7 +173,7 @@ - Links + &Links 2 @@ -238,7 +238,7 @@ - Execute JavaScript on First Selected Item + Execute &JavaScript on First Selected Item 8 @@ -391,7 +391,7 @@ this.dispatchEvent(evObj); - Test Script + &Test Script 4 @@ -401,7 +401,7 @@ this.dispatchEvent(evObj); - + @@ -529,7 +529,7 @@ this.dispatchEvent(evObj); - Script Run Log + Scri&pt Run Log 8 @@ -544,7 +544,7 @@ this.dispatchEvent(evObj); - Setup Script + Set&up Script 4 @@ -603,7 +603,7 @@ this.dispatchEvent(evObj); - Script Commands + Script &Commands 4 @@ -688,7 +688,7 @@ this.dispatchEvent(evObj); - Open ... + &Open ... Ctrl+O @@ -696,7 +696,7 @@ this.dispatchEvent(evObj); - Save As ... + Save &As ... Ctrl+Shift+S @@ -704,7 +704,7 @@ this.dispatchEvent(evObj); - Quit + &Quit Ctrl+Q @@ -712,7 +712,7 @@ this.dispatchEvent(evObj); - Run + &Run Ctrl+R @@ -720,12 +720,12 @@ this.dispatchEvent(evObj); - Run Line + Run &Line - Clear + &Clear @@ -744,7 +744,7 @@ this.dispatchEvent(evObj); false - Save + &Save Ctrl+S @@ -755,7 +755,7 @@ this.dispatchEvent(evObj); false - Revert to saved + R&evert to saved Ctrl+Shift+R @@ -763,12 +763,12 @@ this.dispatchEvent(evObj); - Open Setup Script ... + O&pen Setup Script ... - Commands ... + &Commands ... @@ -778,6 +778,11 @@ this.dispatchEvent(evObj); QWidget
QtWebKitWidgets/QWebView
+ + CodeEditor + QPlainTextEdit +
editor.hxx
+
_load