From: hama Date: Wed, 29 Jul 2015 08:55:32 +0000 (+0200) Subject: EA_DEL_LINE implemented and tested X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=50822cc1f3677fc6fcfa4d6b755d98ff1ac67577;p=reqt EA_DEL_LINE implemented and tested --- diff --git a/base/ReFile.cpp b/base/ReFile.cpp index 821dc32..57efc9a 100644 --- a/base/ReFile.cpp +++ b/base/ReFile.cpp @@ -210,7 +210,7 @@ bool ReLines::joinLines(int first) { * * @param lineNo the line number (0..N-1) of the first position to delete * @param col -1: join the current line with the previous line. - * : join the current line with the following + * >= line_length: join the current line with the following * the column number (0..M-1) of the first position to delete * @param count the number of character to delete * @param withUndo true: prepares undo operation
@@ -219,33 +219,30 @@ bool ReLines::joinLines(int first) { */ bool ReLines::removePart(int lineNo, int col, int count, bool withUndo) { bool rc = false; - if (lineNo >= 0 && lineNo < lineCount()) { + if (lineNo >= 0 && lineNo < lineCount() && count > 0) { const QString& current = at(lineNo); - if (col == -1) { + int length = current.length(); + if (col <= -1) { if (lineNo > 0) { if (withUndo) storeJoin(lineNo - 1, at(lineNo - 1).length()); rc = joinLines(lineNo - 1); } - } else if (col == current.length()) { + } else if (col >= length) { if (withUndo) - storeJoin(lineNo, current.length()); + storeJoin(lineNo, length); rc = joinLines(lineNo); - } else if (col >= 0) { - int length = current.length(); - if (col < length - 1) { - if (col + count > length) - count = length - col; - if (withUndo) - storeRemovePart(lineNo, col, current.mid(col, count)); - if (col == 0) - replace(lineNo, current.mid(count)); - else if (col + count >= length) - replace(lineNo, current.mid(0, col)); - else - replace(lineNo, - current.mid(0, col) + current.mid(col + count)); - } + } else { + if (col + count > length) + count = length - col; + if (withUndo) + storeRemovePart(lineNo, col, current.mid(col, count)); + if (col == 0) + replace(lineNo, current.mid(count)); + else if (col + count >= length) + replace(lineNo, current.mid(0, col)); + else + replace(lineNo, current.mid(0, col) + current.mid(col + count)); } } return rc; @@ -254,6 +251,8 @@ bool ReLines::removePart(int lineNo, int col, int count, bool withUndo) { /** * Removes a given number of lines. * + * If all lines are removed a single empty line will remain. + * * @param start the line number (0..N-1) of the first line to remove * @param count the number of lines to delete * @param withUndo true: prepares undo operation
@@ -265,8 +264,10 @@ void ReLines::removeLines(int start, int count, bool withUndo) { count = length() - start; if (withUndo) storeRemoveLines(start, count, *this); - for (int ix = start + count - 1; ix >= 0; ix--) + for (int ix = start + count - 1; ix >= start; ix--) removeAt(ix); + if (length() == 0) + append(m_empty); } } diff --git a/cunit/cuReEdit.cpp b/cunit/cuReEdit.cpp index a82b8c3..6ab65ef 100644 --- a/cunit/cuReEdit.cpp +++ b/cunit/cuReEdit.cpp @@ -181,10 +181,139 @@ public: pushKey(Qt::Key_Return, "\n"); checkEqu("xy", m_lines.lineAt(2)); checkEqu("z", m_lines.lineAt(3)); - log("ok"); } + void testDeleteText() { + init("abcd\n1234\nxy"); + m_screenWidth = 5; + m_firstLine = 0; + m_firstCol = 0; + + // first line: + m_cursorLineNo = 0; + // in the middle of the line: + m_cursorCol = 1; + editorAction(EA_DEL_BEGIN_OF_LINE); + checkEqu("cd", m_lines.lineAt(0)); + checkEqu("1234", m_lines.lineAt(1)); + checkEqu(-1, m_cursorCol); + checkEqu(0, m_cursorLineNo); + // at the begin of the line: + init("abcd\n1234\nxy"); + m_cursorCol = -1; + editorAction(EA_DEL_BEGIN_OF_LINE); + checkEqu("abcd", m_lines.lineAt(0)); + checkEqu("1234", m_lines.lineAt(1)); + + // in the middle of the line: + init("abcd\n1234\nxy"); + m_cursorCol = 1; + editorAction(EA_DEL_END_OF_LINE); + checkEqu("ab", m_lines.lineAt(0)); + checkEqu("1234", m_lines.lineAt(1)); + checkEqu(1, m_cursorCol); + checkEqu(0, m_cursorLineNo); + // at the end of the line: + init("abcd\n1234\nxy"); + m_cursorCol = 3; + editorAction(EA_DEL_END_OF_LINE); + checkEqu("abcd", m_lines.lineAt(0)); + checkEqu("1234", m_lines.lineAt(1)); + + // last line: + init("abcd\n1234\nxy"); + m_cursorLineNo = 2; + // in the middle of the line: + m_cursorCol = 0; + editorAction(EA_DEL_BEGIN_OF_LINE); + checkEqu("abcd", m_lines.lineAt(0)); + checkEqu("1234", m_lines.lineAt(1)); + checkEqu("y", m_lines.lineAt(2)); + checkEqu(-1, m_cursorCol); + checkEqu(2, m_cursorLineNo); + // at the begin of the line: + init("abcd\n1234\nxy"); + m_cursorCol = -1; + editorAction(EA_DEL_BEGIN_OF_LINE); + checkEqu("abcd", m_lines.lineAt(0)); + checkEqu("1234", m_lines.lineAt(1)); + + // in the middle of the line: + init("abcd\n1234\nxy"); + m_cursorCol = 0; + editorAction(EA_DEL_END_OF_LINE); + checkEqu("abcd", m_lines.lineAt(0)); + checkEqu("1234", m_lines.lineAt(1)); + checkEqu("x", m_lines.lineAt(2)); + checkEqu(0, m_cursorCol); + checkEqu(2, m_cursorLineNo); + // at the end of the line: + init("abcd\n1234\nxy"); + m_cursorCol = 1; + editorAction(EA_DEL_END_OF_LINE); + checkEqu("abcd", m_lines.lineAt(0)); + checkEqu("1234", m_lines.lineAt(1)); + checkEqu("xy", m_lines.lineAt(2)); + } + void testDeleteLine() { + init("abcd\n1234\nxy"); + m_screenWidth = 5; + m_firstLine = 0; + m_firstCol = 0; + + // first line: + m_cursorLineNo = 0; + m_cursorCol = 1; + editorAction(EA_DEL_LINE); + checkEqu(2, m_lines.lineCount()); + checkEqu("1234", m_lines.lineAt(0)); + checkEqu("xy", m_lines.lineAt(1)); + checkEqu(-1, m_cursorCol); + checkEqu(0, m_cursorLineNo); + + // middle line: + init("abcd\n1234\nxy"); + m_cursorLineNo = 1; + m_cursorCol = 1; + editorAction(EA_DEL_LINE); + checkEqu(2, m_lines.lineCount()); + checkEqu("abcd", m_lines.lineAt(0)); + checkEqu("xy", m_lines.lineAt(1)); + checkEqu(-1, m_cursorCol); + checkEqu(1, m_cursorLineNo); + + // last line: + init("abcd\n1234\nxy"); + m_cursorLineNo = 2; + m_cursorCol = 1; + editorAction(EA_DEL_LINE); + checkEqu(2, m_lines.lineCount()); + checkEqu("abcd", m_lines.lineAt(0)); + checkEqu("1234", m_lines.lineAt(1)); + checkEqu(-1, m_cursorCol); + checkEqu(2, m_cursorLineNo); + + // wrong line numbers: + init("abcd\n1234\nxy"); + m_cursorCol = 1; + m_cursorLineNo = -1; + editorAction(EA_DEL_LINE); + checkEqu(3, m_lines.lineCount()); + checkEqu("abcd", m_lines.lineAt(0)); + checkEqu("1234", m_lines.lineAt(1)); + checkEqu("xy", m_lines.lineAt(2)); + m_cursorLineNo = 3; + editorAction(EA_DEL_LINE); + checkEqu(3, m_lines.lineCount()); + checkEqu("abcd", m_lines.lineAt(0)); + checkEqu("1234", m_lines.lineAt(1)); + checkEqu("xy", m_lines.lineAt(2)); + + log("ok"); +} virtual void run() { + testDeleteLine(); + testDeleteText(); testEnterText(); testCursorMove(); testEnsureCursorVisible(); diff --git a/cunit/cuReFile.cpp b/cunit/cuReFile.cpp index c89fe5f..bf1bf80 100644 --- a/cunit/cuReFile.cpp +++ b/cunit/cuReFile.cpp @@ -17,7 +17,7 @@ class TestReFile: public ReTest { public: TestReFile() : - ReTest("ReFile") { + ReTest("ReFile") { doIt(); } @@ -25,7 +25,7 @@ public: void testBasic() { QByteArray fn(ReFile::tempFile("big.txt", NULL, true)); const char* content = - "123456789 123456789 123456789 123456789 123456789\n"; + "123456789 123456789 123456789 123456789 123456789\n"; int contentLength = strlen(content); ReFile::writeToFile(fn.constData(), content); ReFile file(fn.constData()); @@ -36,19 +36,19 @@ public: checkNN(ptr); checkEqu(4, length); checkEqu(0, - strncmp(content, reinterpret_cast(ptr), length)); + strncmp(content, reinterpret_cast(ptr), length)); int part = size / 2; ptr = file.remap(contentLength - part, size, length); checkEqu(size / 2, length); checkEqu(content + contentLength - part, - reinterpret_cast(ptr)); + reinterpret_cast(ptr)); for (int ix = 0; ix < contentLength - size; ix++) { ptr = file.remap(ix, size, length); checkNN(ptr); checkEqu(length, size); checkEqu(0, - strncmp(content + ix, reinterpret_cast(ptr), - length)); + strncmp(content + ix, reinterpret_cast(ptr), + length)); } } @@ -93,7 +93,7 @@ public: } double duration = double(clock() - start) / CLOCKS_PER_SEC; printf("linecount (ReFile, %d kB): %d lines %.3f sec\n", - int(blocksize / 1024), lines, duration); + int(blocksize / 1024), lines, duration); } void countLinesFopen(const char* filename) { @@ -213,8 +213,6 @@ public: // no remove because of wrong arguments: lines.removePart(-1, 3, 1, true); checkEqu(3, lines.lineCount()); - lines.removePart(0, 2, 1, true); - checkEqu(3, lines.lineCount()); lines.removePart(3, 1, 1, true); checkEqu(3, lines.lineCount()); checkEqu("3", lines.lineAt(0)); @@ -346,8 +344,8 @@ public: checkEqu("1", lines.lineAt(0)); checkEqu("23", lines.lineAt(1)); checkEqu("abcdefg", lines.lineAt(2)); - // at the end of the line: - lines.splitLine(1, 2, true); + // at the end of the line ""1\n23\abcdefg": + lines.splitLine(0, 2, true); checkEqu(4, lines.lineCount()); checkEqu("1", lines.lineAt(0)); checkEqu("", lines.lineAt(1)); diff --git a/gui/ReEdit.cpp b/gui/ReEdit.cpp index c2ec7ea..55fe958 100644 --- a/gui/ReEdit.cpp +++ b/gui/ReEdit.cpp @@ -424,7 +424,7 @@ void ReEdit::editorAction(ReEdit::EditorAction action) { } case EA_DEL_END_OF_LINE: { int lastIx = lastColOfCurrent(); - if (m_cursorCol < lastIx) { + if (m_cursorCol <= lastIx) { m_lines->removePart(m_cursorLineNo, m_cursorCol + 1, lastIx - m_cursorCol, true); ensureCursorVisible(); @@ -432,7 +432,7 @@ void ReEdit::editorAction(ReEdit::EditorAction action) { break; } case EA_DEL_BEGIN_OF_LINE: - if (m_cursorCol > 0) { + if (m_cursorCol >= 0) { m_lines->removePart(m_cursorLineNo, 0, m_cursorCol + 1, true); m_cursorCol = -1; ensureCursorVisible(); @@ -440,7 +440,9 @@ void ReEdit::editorAction(ReEdit::EditorAction action) { break; case EA_DEL_LINE: m_lines->removeLines(m_cursorLineNo, 1, true); + m_cursorLineNo = min(m_cursorLineNo, m_lines->lineCount() - 1); m_cursorCol = m_firstCol == 0 ? -1 : m_firstCol; + reposition(min(m_firstLine, m_firstLine - pageSize), m_firstCol - 1); ensureCursorVisible(); break; case EA_UNDO: @@ -504,8 +506,12 @@ void ReEdit::keyPressEvent(QKeyEvent* event) { editorAction(m_keyRaw[key]); break; default: + // the inserted char should be visible: + ensureCursorVisible(); m_lines->insertText(m_cursorLineNo, m_cursorCol + 1, keyText); m_cursorCol++; + // the new position should be visible too: + ensureCursorVisible(); break; } } else if (shift && !keyText.isEmpty() && key != Qt::Key_Delete @@ -653,14 +659,18 @@ void ReEdit::paintEvent(QPaintEvent* event) { painter.setBrush(*look->m_brush); QRect editArea(rect.left() + m_widthLineNumbers, rect.top(), rect.right() - m_widthVScrollBar, rect.bottom() - m_heightHScrollBar); + // Painting the frame of the edit field: painter.drawRect(editArea); + // Painting the edit field area (text...) draw(painter, rect.top(), rect.left() + m_widthLineNumbers); + // Painting the line numbers: int left = rect.left() + m_widthLineNumbers - 3; left = rect.left(); int y = 0; int lineNo = firstLine + 1; ReLook* lookStd = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD); - for (int ix = 0; ix < m_list.length(); ix++, lineNo++) { + int maxIx = min(m_list.length(), m_lines->lineCount() - m_firstLine); + for (int ix = 0; ix < maxIx; ix++, lineNo++) { QString number = QString::number(lineNo) + ":"; ReLook* look = lineNo == m_cursorLineNo + 1 ?