- added a general purpouse code editing widget (CodeWidget in common)
authorAkiko <akiko@linux-addicted.net>
Sat, 12 Oct 2013 18:50:45 +0000 (20:50 +0200)
committerAkiko <akiko@linux-addicted.net>
Sat, 12 Oct 2013 18:50:45 +0000 (20:50 +0200)
- CodeWidget is now the default text editor component in the editor

CMakeLists.txt
cmake_distclean.sh
common/CMakeLists.txt [new file with mode: 0644]
common/CodeWidget.cxx [new file with mode: 0644]
common/CodeWidget.hxx [new file with mode: 0644]
editor/CMakeLists.txt
editor/TextWindow.ui
filesystem/CMakeLists.txt

index 56e198e..eaeeeca 100644 (file)
@@ -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)
index 94d3d59..79823eb 100755 (executable)
@@ -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 (file)
index 0000000..ac2464f
--- /dev/null
@@ -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 (file)
index 0000000..dd5c93a
--- /dev/null
@@ -0,0 +1,153 @@
+#include <QPainter>
+#include <QPaintEvent>
+#include <QTextBlock>
+#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<QTextEdit::ExtraSelection> 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 (file)
index 0000000..804de03
--- /dev/null
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <QPlainTextEdit>
+
+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;
+};
index e47ce78..58576f0 100644 (file)
@@ -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)
index c04d836..ae7e560 100644 (file)
@@ -35,7 +35,7 @@
          <x>0</x>
          <y>0</y>
          <width>782</width>
-         <height>530</height>
+         <height>531</height>
         </rect>
        </property>
        <layout class="QVBoxLayout" name="verticalLayout_2">
          <number>0</number>
         </property>
         <item>
-         <widget class="QTextEdit" name="ed_text">
+         <widget class="CodeWidget" name="ed_text">
           <property name="contextMenuPolicy">
            <enum>Qt::ActionsContextMenu</enum>
           </property>
-          <property name="documentTitle">
-           <string notr="true"/>
-          </property>
-          <property name="html">
-           <string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
-&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
-p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-          </property>
          </widget>
         </item>
        </layout>
@@ -157,7 +147,7 @@ p, li { white-space: pre-wrap; }
      <x>0</x>
      <y>0</y>
      <width>800</width>
-     <height>22</height>
+     <height>21</height>
     </rect>
    </property>
    <widget class="QMenu" name="mm_text">
@@ -230,6 +220,13 @@ p, li { white-space: pre-wrap; }
    </property>
   </action>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>CodeWidget</class>
+   <extends>QPlainTextEdit</extends>
+   <header>common/CodeWidget.hxx</header>
+  </customwidget>
+ </customwidgets>
  <resources/>
  <connections/>
 </ui>
index a6798f4..8437018 100644 (file)
@@ -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})