From 0975e393a0f4b83da9093bd1d88645a0b4db073a Mon Sep 17 00:00:00 2001 From: Akiko Date: Sat, 12 Oct 2013 20:50:45 +0200 Subject: [PATCH] - added a general purpouse code editing widget (CodeWidget in common) - CodeWidget is now the default text editor component in the editor --- CMakeLists.txt | 1 + cmake_distclean.sh | 7 +++ common/CMakeLists.txt | 16 +++++ common/CodeWidget.cxx | 153 ++++++++++++++++++++++++++++++++++++++++++++++ common/CodeWidget.hxx | 42 +++++++++++++ editor/CMakeLists.txt | 2 +- editor/TextWindow.ui | 23 +++---- filesystem/CMakeLists.txt | 2 +- 8 files changed, 231 insertions(+), 15 deletions(-) create mode 100644 common/CMakeLists.txt create mode 100644 common/CodeWidget.cxx create mode 100644 common/CodeWidget.hxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 56e198e..eaeeeca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ set (CMAKE_CXX_FLAGS "-std=c++11 -W -Wall -Wextra -Os") set (CMAKE_C_FLAGS "-std=c++11 -W -Wall -Wextra -Os") #add_subdirectory (analyzer) +add_subdirectory (common) add_subdirectory (editor) add_subdirectory (engine) add_subdirectory (filesystem) diff --git a/cmake_distclean.sh b/cmake_distclean.sh index 94d3d59..79823eb 100755 --- a/cmake_distclean.sh +++ b/cmake_distclean.sh @@ -14,6 +14,13 @@ rm -rf analyzer/cmake_install.cmake rm -rf analyzer/*.qrc.depends rm -rf analyzer/moc_*.* +rm -rf common/CMakeCache.txt +rm -rf common/CMakeFiles/ +rm -rf common/Makefile +rm -rf common/cmake_install.cmake +rm -rf common/*.qrc.depends +rm -rf common/moc_*.* + rm -rf editor/CMakeCache.txt rm -rf editor/CMakeFiles/ rm -rf editor/Makefile diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt new file mode 100644 index 0000000..ac2464f --- /dev/null +++ b/common/CMakeLists.txt @@ -0,0 +1,16 @@ +# Qt sources +set (CO_SOURCES CodeWidget.cxx) +set (CO_HEADERS CodeWidget.hxx) +set (CO_UI_FILES ) +set (CO_RES_FILES ) +set (CO_TS_FILES ) + +# wrappers +QT5_ADD_TRANSLATION (CO_TS_SOURCES ${CO_TS_FILES}) +QT5_WRAP_CPP (CO_MOC_SOURCES ${CO_HEADERS}) +QT5_WRAP_UI (CO_UI_SOURCES ${CO_UI_FILES}) +QT5_ADD_RESOURCES (CO_RES_SOURCES ${CO_RES_FILES}) + +# libs +add_library (Common ${CO_SOURCES} ${CO_MOC_SOURCES} ${CO_UI_SOURCES} ${CO_RES_SOURCES} ${CO_TS_SOURCES}) +qt5_use_modules (Common Core Widgets) diff --git a/common/CodeWidget.cxx b/common/CodeWidget.cxx new file mode 100644 index 0000000..dd5c93a --- /dev/null +++ b/common/CodeWidget.cxx @@ -0,0 +1,153 @@ +#include +#include +#include +#include "CodeWidget.hxx" + +// --- CodeWidget: constructors and deconstructors --- + +CodeWidget::CodeWidget(QWidget *parent) +: QPlainTextEdit(parent), _area(new Area(this)) +{ + setupActions(); + updateAreaWidth(0); + highlightLine(); +} + +CodeWidget::CodeWidget(const QString& text, QWidget *parent) +: QPlainTextEdit(text, parent), _area(new Area(this)) +{ + setupActions(); + updateAreaWidth(0); + highlightLine(); +} + +CodeWidget::~CodeWidget() +{ + delete _area; +} + +// --- CodeWidget: public methods --- + +void CodeWidget::areaPaintEvent(QPaintEvent *event) +{ + QPainter painter(_area); + QTextBlock block = firstVisibleBlock(); + qint32 block_num = block.blockNumber(); + qint32 top = blockBoundingGeometry(block).translated(contentOffset()).top(); + qint32 bottom = top + blockBoundingRect(block).height(); + + painter.fillRect(event->rect(), Qt::lightGray); + + while (block.isValid() && top <= event->rect().bottom()) + { + if (block.isVisible() && bottom >= event->rect().top()) + { + QString number = QString::number(block_num + 1); + painter.setPen(Qt::black); + painter.drawText(0, top, _area->width(), fontMetrics().height(), Qt::AlignRight, number); + } + + block = block.next(); + top = bottom; + bottom = top + blockBoundingRect(block).height(); + ++block_num; + } +} + +qint32 CodeWidget::areaWidth() const +{ + qint32 digits = 1; + qint32 max = qMax(1, blockCount()); + qint32 space = 3; + + while (max >= 10) + { + max /= 10; + ++digits; + } + + space += fontMetrics().width(QLatin1Char('9')) * digits; + + return space; +} + +// --- CodeWidget: protected methods --- + +void CodeWidget::resizeEvent(QResizeEvent *event) +{ + QPlainTextEdit::resizeEvent(event); + _area->setGeometry(QRect(contentsRect().left(), contentsRect().top(), areaWidth(), contentsRect().height())); +} + +void CodeWidget::setupActions() +{ + connect(this, SIGNAL(blockCountChanged(qint32)), + this, SLOT(updateAreaWidth(qint32))); + connect(this, SIGNAL(updateRequest(QRect, qint32)), + this, SLOT(updateArea(QRect, qint32))); + connect(this, SIGNAL(cursorPositionChanged()), + this, SLOT(highlightLine())); +} + +// --- CodeWidget: protected slots --- + +void CodeWidget::updateAreaWidth(qint32 /*block_count*/) +{ + setViewportMargins(areaWidth(), 0, 0, 0); +} + +void CodeWidget::highlightLine() +{ + QList selections; + + if (!isReadOnly()) + { + QTextEdit::ExtraSelection sel; + QColor color = QColor(Qt::yellow).lighter(160); + + sel.format.setBackground(color); + sel.format.setProperty(QTextFormat::FullWidthSelection, true); + sel.cursor = textCursor(); + sel.cursor.clearSelection(); + selections.append(sel); + } + + setExtraSelections(selections); +} + +void CodeWidget::updateArea(const QRect& rect, qint32 dy) +{ + if (dy) + _area->scroll(0, dy); + else + _area->update(0, rect.y(), _area->width(), rect.height()); + + if (rect.contains(viewport()->rect())) + updateAreaWidth(0); +} + +// --- Area: constructors and deconstructors --- + +Area::Area(CodeWidget *parent) +: QWidget(parent), _parent(parent) +{ +} + +Area::~Area() +{ + _parent = 0; +} + +// --- Area: public methods --- + +QSize Area::sizeHint() const +{ + return QSize(_parent->areaWidth(), 0); +} + +// --- Area: protected methods --- + +void Area::paintEvent(QPaintEvent *event) +{ + _parent->areaPaintEvent(event); +} diff --git a/common/CodeWidget.hxx b/common/CodeWidget.hxx new file mode 100644 index 0000000..804de03 --- /dev/null +++ b/common/CodeWidget.hxx @@ -0,0 +1,42 @@ +#pragma once + +#include + +class CodeWidget : public QPlainTextEdit { + Q_OBJECT +public: + explicit CodeWidget(QWidget *parent = 0); + explicit CodeWidget(const QString& text, QWidget *parent = 0); + virtual ~CodeWidget(); + + void areaPaintEvent(QPaintEvent *event); + qint32 areaWidth() const; + +protected: + virtual void resizeEvent(QResizeEvent *event) override; + + void setupActions(); + +protected slots: + void updateAreaWidth(qint32 block_count); + void highlightLine(); + void updateArea(const QRect& rect, qint32 dy); + +private: + QWidget *_area; +}; + +class Area : public QWidget { + Q_OBJECT +public: + explicit Area(CodeWidget *parent); + virtual ~Area(); + + QSize sizeHint() const; + +protected: + virtual void paintEvent(QPaintEvent *event) override; + +private: + CodeWidget *_parent; +}; diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index e47ce78..58576f0 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -17,4 +17,4 @@ QT5_ADD_RESOURCES (ED_RES_SOURCES ${ED_RES_FILES}) add_executable (QTinNS_Editor ${ED_SOURCES} ${ED_MOC_SOURCES} ${ED_UI_SOURCES} ${ED_RES_SOURCES} ${ED_TS_SOURCES}) qt5_use_modules (QTinNS_Editor Core Widgets) -target_link_libraries (QTinNS_Editor Filesystem Engine) +target_link_libraries (QTinNS_Editor Common Engine Filesystem) diff --git a/editor/TextWindow.ui b/editor/TextWindow.ui index c04d836..ae7e560 100644 --- a/editor/TextWindow.ui +++ b/editor/TextWindow.ui @@ -35,7 +35,7 @@ 0 0 782 - 530 + 531 @@ -43,20 +43,10 @@ 0 - + Qt::ActionsContextMenu - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> - @@ -157,7 +147,7 @@ p, li { white-space: pre-wrap; } 0 0 800 - 22 + 21 @@ -230,6 +220,13 @@ p, li { white-space: pre-wrap; } + + + CodeWidget + QPlainTextEdit +
common/CodeWidget.hxx
+
+
diff --git a/filesystem/CMakeLists.txt b/filesystem/CMakeLists.txt index a6798f4..8437018 100644 --- a/filesystem/CMakeLists.txt +++ b/filesystem/CMakeLists.txt @@ -3,7 +3,7 @@ set (NCF_SOURCES FileIdentifier.cxx NCFile.cxx NCFilesystem.cx set (NCF_HEADERS FileIdentifier.hxx NCFile.hxx NCFilesystem.hxx) set (NCF_UI_FILES ) set (NCF_RES_FILES ) -set (E_TS_FILES ) +set (NCF_TS_FILES ) # wrappers QT5_ADD_TRANSLATION (NCF_TS_SOURCES ${NCF_TS_FILES}) -- 2.15.1