From 0ac2f3e6953b64001c84584e0f0586909623f9e1 Mon Sep 17 00:00:00 2001 From: hama Date: Mon, 22 Jun 2015 00:16:49 +0200 Subject: [PATCH] reditor: improvements --- .gitignore | 11 +--- gui/ReEdit.cpp | 157 ++++++++++++++++++++++++++++++++++++++----------- gui/ReEdit.hpp | 23 ++++++-- 3 files changed, 143 insertions(+), 48 deletions(-) diff --git a/.gitignore b/.gitignore index 56703ad..a0a2e60 100644 --- a/.gitignore +++ b/.gitignore @@ -4,17 +4,8 @@ doc/ *.log *.o -build-rplstatic-Desktop-Debug/ -build-rplstatic-Desktop-Release/ -build-refind-Desktop_Qt_5_4_0_MSVC2010_OpenGL_32bit-Release/ .cproject .project *.pro.user.* - -build-unittests-Desktop5-Debug/ -cunit/build-cunit-Desktop5-Debug/ rpldoc.zip - -appl/labor/build-labor-Desktop5-Debug/ -build-cunit-Desktop_Qt_5_1_1_GCC_64bit-Debug/ -build-unittests-Desktop_Qt_5_1_1_GCC_64bit-Debug/ +build/ diff --git a/gui/ReEdit.cpp b/gui/ReEdit.cpp index 63ddd93..5a20432 100644 --- a/gui/ReEdit.cpp +++ b/gui/ReEdit.cpp @@ -100,6 +100,8 @@ ReEdit::ReEdit(QWidget* parent) : m_firstCol(0), m_cursorLine(0), m_cursorCol(-1), + m_cursorVisible(true), + m_insertMode(true), m_breakLines(false), m_widthLineNo(50), m_widthVScrollBar(0), @@ -120,7 +122,7 @@ ReEdit::ReEdit(QWidget* parent) : m_keyControlShift(), m_keyRaw(), m_keyShift(){ - setFocusPolicy(Qt::WheelFocus); + setFocusPolicy(Qt::WheelFocus); m_standardFont = new QFont("Courier"); m_standardFont->setStyleHint(QFont::TypeWriter); m_standardFont->setPixelSize(16); @@ -225,17 +227,23 @@ QBrush* ReEdit::createBrush(ReLook::BackGround background){ */ void ReEdit::paintEvent(QPaintEvent* event){ QRect rect = event->rect(); + m_widthEdit = rect.width(); int lineHeight = heightToFullHeight(m_standardMetrics->height()); - int count = rect.height() / lineHeight; - m_paragraphs.load(m_paragraphs.firstLine(), count, this); + int pageSize = rect.height() / lineHeight; + int firstLine = m_paragraphs.firstLine(); + m_paragraphs.load(firstLine, pageSize, this); QPainter painter(this); + ReLook* look = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD); + painter.setBrush(*look->m_brush); + QRect editArea(rect.left() + m_widthLineNo, rect.top(), rect.right(), + rect.bottom()); + painter.drawRect(editArea); m_paragraphs.draw(painter, rect.top(), rect.left() + m_widthLineNo); int left = rect.left() + m_widthLineNo - 3; - painter.drawLine(left, rect.top(), left, rect.bottom()); left = rect.left(); int y = 0; - int lineNo = m_paragraphs.firstLine() + 1; + int lineNo = firstLine + 1; ReLook* lookStd = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD); for (int ix = 0; ix < m_paragraphs.list().length(); ix++, lineNo++){ QString number = QString::number(lineNo) + ":"; @@ -250,7 +258,19 @@ void ReEdit::paintEvent(QPaintEvent* event){ painter.setFont(*look->m_font); painter.setPen(*look->m_pen); painter.drawText(left + m_widthLineNo - width - 5, y, number); - y += heightToFullHeight(look->m_metrics->height()); + y += lineHeight; + } + // We paint the cursor: + if (m_cursorVisible && m_cursorLine >= firstLine + && m_cursorLine < firstLine + pageSize){ + int col = m_cursorCol; + if (m_lines->lineAt(m_cursorLine).length() <= col) + col = m_lines->lineAt(m_cursorLine).length() - 1; + int x = rect.left() + m_widthLineNo + 1 + + (col + 1) * lookStd->m_metrics->width('x'); + int y = rect.top() + (m_cursorLine - firstLine) * lineHeight; + painter.setPen(*look->m_pen); + painter.drawLine(x, y, x, y + lineHeight); } } @@ -263,9 +283,54 @@ void ReEdit::mousePressEvent(QMouseEvent* event){ QPoint position = event->pos(); m_cursorLine = position.y() / heightToFullHeight(m_standardMetrics->height()) + m_paragraphs.firstLine(); + int x = position.x(); + int charWidth = m_standardMetrics->width('x'); + if (x >= m_widthLineNo && x < m_widthEdit - m_widthVScrollBar){ + if (x <= m_widthLineNo + charWidth / 2) + m_cursorCol = -1; + else + m_cursorCol = (x - m_widthLineNo) / charWidth; + } emit repaint(); } +/** + * Calculates the index of the line string from the cursor column. + * + * The index may be smaller because of expanded tabulators. + * Example: + *
"x\ty", tabulator width: 3, screen display: "x  y"
+ * columnToTextIndex(0) == 0; ('x')
+ * columnToTextIndex(1) == 1; ('\t')
+ * columnToTextIndex(2) == 1; ('\t')
+ * columnToTextIndex(3) == 2; ('y')
+ * 
+ * + * @param cursorCol the cursor position + * @return the + */ +int ReEdit::columnToTextIndex(int cursorCol){ + //@ToDo: tab handling + return cursorCol; +} +/** + * Calculates the cursor column from the line string index. + * + * The index may be larger because of expanded tabulators. + * Example: + *
"x\ty", tabulator width: 3, screen display: "x  y"
+ * textIndexToColumn(0) == 0;
+ * textIndexToColumn(1) == 1;
+ * textIndexToColumn(2) == 3;
+ * 
+ * @param index the index in the line string + * @return the column in the edit field + */ +int ReEdit::textIndexToColumn(int index){ + //@ToDo: tab handling + return index; +} + /** * Handles the key click event. * @@ -275,18 +340,40 @@ void ReEdit::keyPressEvent(QKeyEvent* event){ bool shift = event->modifiers() & Qt::ShiftModifier; bool control = event->modifiers() & Qt::ControlModifier; bool alt = event->modifiers() & Qt::MetaModifier; - if (!event->text().isEmpty()){ - m_lines->insertText(m_cursorLine, m_cursorCol + 1, event->text()); + int key = event->key(); + QString keyText = event->text(); + if (!keyText.isEmpty() && !shift && !control && !alt){ + switch (key) { + case Qt::Key_Enter: + case Qt::Key_Return: + m_lines->insertText(m_cursorLine, columnToTextIndex(m_cursorCol + 1), + "\n"); + m_cursorCol = -1; + m_cursorLine++; + break; + case Qt::Key_Backspace: + m_lines->remove(m_cursorLine, columnToTextIndex(m_cursorCol + 1), 1); + if (m_cursorCol-- < -1) + m_cursorCol = -1; + break; + case Qt::Key_Delete: + m_lines->remove(m_cursorLine, columnToTextIndex(m_cursorCol + 1), 1); + break; + default: + m_lines->insertText(m_cursorLine, columnToTextIndex(m_cursorCol + 1), + keyText); + m_cursorCol++; + break; + } }else{ QMap * map; - int key = event->key(); if (!shift && !alt && !control) map = &m_keyRaw; else if (shift && !alt && !control) map = &m_keyShift; else if (alt && !shift && !control) map = &m_keyAlt; - else if (control && ! alt && ! shift) + else if (control && !alt && !shift) map = &m_keyControl; else if (alt && control && !shift) map = &m_keyAltControl; @@ -317,14 +404,13 @@ int ReEdit::cursorLine() const{ * @param cursorLine -1 or number of the new cursor line */ void ReEdit::ensureCursorVisible(int cursorLine){ - if (cursorLine >= 0) - m_cursorLine = cursorLine; - int firstLine = m_paragraphs.firstLine(); - int pageSize = m_paragraphs.list().length(); - if (m_cursorLine < firstLine - || m_cursorLine >= firstLine + pageSize){ - reposition(m_cursorLine); - } + if (cursorLine >= 0) + m_cursorLine = cursorLine; + int firstLine = m_paragraphs.firstLine(); + int pageSize = m_paragraphs.list().length(); + if (m_cursorLine < firstLine || m_cursorLine >= firstLine + pageSize){ + reposition(m_cursorLine); + } } /** @@ -333,7 +419,7 @@ void ReEdit::ensureCursorVisible(int cursorLine){ * @param action action to do */ void ReEdit::editorAction(ReEdit::EditorAction action){ - int pageSize = m_paragraphs.list().length() - 1; + int pageSize = m_paragraphs.list().length() - 1; switch (action) { case EA_UNDEF: break; @@ -343,7 +429,8 @@ void ReEdit::editorAction(ReEdit::EditorAction action){ ensureCursorVisible(); break; case EA_CHAR_RIGHT: - m_cursorCol++; + if (++m_cursorCol >= m_lines->lineAt(m_cursorLine).length()) + m_cursorCol = m_lines->lineAt(m_cursorLine).length() - 1; ensureCursorVisible(); break; case EA_LINE_UP: @@ -353,7 +440,7 @@ void ReEdit::editorAction(ReEdit::EditorAction action){ break; case EA_LINE_DOWN: if (++m_cursorLine >= m_lines->lineCount()) - m_cursorLine = m_lines->lineCount() - 1; + m_cursorLine = m_lines->lineCount() - 1; ensureCursorVisible(); break; case EA_BEGIN_OF_LINE: @@ -361,7 +448,8 @@ void ReEdit::editorAction(ReEdit::EditorAction action){ ensureCursorVisible(); break; case EA_END_OF_LINE: - m_cursorCol = 99; + m_cursorCol = m_lines->lineAt(m_cursorLine).length() - 1; + ; ensureCursorVisible(); break; case EA_BEGIN_OF_FILE: @@ -371,13 +459,13 @@ void ReEdit::editorAction(ReEdit::EditorAction action){ ensureCursorVisible(m_lines->lineCount() - 1); break; case EA_PAGE_UP: - // Do not change cursor line! - reposition(m_paragraphs.firstLine() - pageSize); - break; + // Do not change cursor line! + reposition(m_paragraphs.firstLine() - pageSize); + break; case EA_PAGE_DOWN: - // Do not change cursor line! - reposition(m_paragraphs.firstLine() + pageSize); - break; + // Do not change cursor line! + reposition(m_paragraphs.firstLine() + pageSize); + break; case EA_DEL_CHAR: break; case EA_BACKSPACE: @@ -400,12 +488,13 @@ void ReEdit::editorAction(ReEdit::EditorAction action){ * @param firstLine number of the line which should be visible */ void ReEdit::reposition(int firstLine){ - int pageSize = m_paragraphs.list().length(); - if (firstLine <= 0) - firstLine = 0; - else if (firstLine >= m_lines->lineCount() - pageSize) - firstLine = m_lines->lineCount() - pageSize + 1; - m_paragraphs.load(firstLine, pageSize, this); + int pageSize = m_paragraphs.list().length(); + if (firstLine <= 0) + firstLine = 0; + else if (firstLine >= m_lines->lineCount() - pageSize) + firstLine = m_lines->lineCount() - pageSize + 1; + // We do not load because each redraw loads it: + m_paragraphs.setFirstLine(firstLine); } /** diff --git a/gui/ReEdit.hpp b/gui/ReEdit.hpp index ab71c94..930b188 100644 --- a/gui/ReEdit.hpp +++ b/gui/ReEdit.hpp @@ -193,6 +193,13 @@ public: int firstLine() const{ return m_firstLine; } + /** Sets the number of the first line. + * @param firstLine the number of the first line + */ + void setFirstLine(int firstLine){ + m_firstLine = firstLine; + } + /** Returns the paragraph list. * @return the paragraph list */ @@ -254,13 +261,15 @@ public: } protected: - QBrush*createBrush(ReLook::BackGround background); + int columnToTextIndex(int cursorCol); + QBrush* createBrush(ReLook::BackGround background); void ensureCursorVisible(int cursorLine = -1); void reposition(int firstLine); + int textIndexToColumn(int index); protected slots: - void paintEvent(QPaintEvent *); - void mousePressEvent(QMouseEvent* event); - void keyPressEvent(QKeyEvent* event); + void paintEvent(QPaintEvent *); + void mousePressEvent(QMouseEvent* event); + void keyPressEvent(QKeyEvent* event); protected: /// the lines to display ReParagraphs m_paragraphs; @@ -272,6 +281,12 @@ protected: int m_cursorLine; /// the column number of the cursor. -1: before the first column int m_cursorCol; + /// true: the text cursor is visible (blinking) + bool m_cursorVisible; + // number of pixels of the width of the edit field + int m_widthEdit; + /// true: keys will be inserted at the cursor position + bool m_insertMode; /// true: a file line will be displayed in multiple lines (if long enough) bool m_breakLines; /// number of pixels for the line number -- 2.39.5