From 694643418f0e607844b8ce0a56e8d39daaaac7f5 Mon Sep 17 00:00:00 2001 From: Przemyslaw Brudny Date: Thu, 24 Jun 2021 17:19:51 +0200 Subject: [PATCH] [EGD-7018] Fixed text empty block removal at end Fixed text empty block removal at end. --- module-gui/gui/widgets/TextBlockCursor.cpp | 30 ++++++++++++++----- module-gui/gui/widgets/TextBlockCursor.hpp | 17 ++++++----- .../test/test-catch-text/test-gui-Text.cpp | 25 ++++++++++++++++ 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/module-gui/gui/widgets/TextBlockCursor.cpp b/module-gui/gui/widgets/TextBlockCursor.cpp index 08ba91b5c584fed811843b91b1d3b22d46bb9fff..7e9e213868107845433a6dfa66b10e371d30e78f 100644 --- a/module-gui/gui/widgets/TextBlockCursor.cpp +++ b/module-gui/gui/widgets/TextBlockCursor.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "TextBlockCursor.hpp" @@ -15,7 +15,7 @@ static const int last_char_inclusive = 0; // if then -1 / else 0 namespace gui { - auto BlockCursor::currentBlock() const -> std::_List_iterator + auto BlockCursor::currentBlock() const -> std::list::iterator { if (currentBlockNumber == text::npos) { return document->blocks.end(); @@ -23,12 +23,12 @@ namespace gui return std::next(document->blocks.begin(), currentBlockNumber); } - auto BlockCursor::blocksEnd() const -> std::_List_iterator + auto BlockCursor::blocksEnd() const -> std::list::iterator { return std::end(document->blocks); } - auto BlockCursor::blocksBegin() const -> std::_List_iterator + auto BlockCursor::blocksBegin() const -> std::list::iterator { return std::begin(document->blocks); } @@ -267,7 +267,7 @@ namespace gui return false; } - if (nextBlock != blocksEnd() && nextBlock->isEmpty()) { + if (checkIfNextBlockEmpty(nextBlock)) { debug_cursor("Next empty block removed"); document->removeBlock(nextBlock); } @@ -280,14 +280,29 @@ namespace gui block->removeChar(pos); - if (block->isEmpty() && block == blocksBegin()) { - debug_cursor("Current empty block removed"); + if (checkIfBlockFirstAndEmpty(block)) { + debug_cursor("First empty block removed"); document->removeBlock(block); + + if (checkIfNextBlockEmpty(nextBlock)) { + debug_cursor("Next empty block removed"); + document->removeBlock(nextBlock); + } } return true; } + auto BlockCursor::checkIfBlockFirstAndEmpty(std::list::iterator block) -> bool + { + return block == blocksBegin() && block->isEmpty(); + } + + auto BlockCursor::checkIfNextBlockEmpty(std::list::iterator nextBlock) -> bool + { + return nextBlock != blocksEnd() && nextBlock->isEmpty() && checkCurrentBlockNoNewLine(); + } + const TextBlock &BlockCursor::operator*() { return *currentBlock(); @@ -323,5 +338,4 @@ namespace gui { return document->blocks.end(); } - } // namespace gui diff --git a/module-gui/gui/widgets/TextBlockCursor.hpp b/module-gui/gui/widgets/TextBlockCursor.hpp index d557b82d9bb662fa1d9d70bda000a4094d5ae3bf..a1801b55d55a17751bc2a1667b4e13da2f457e8a 100644 --- a/module-gui/gui/widgets/TextBlockCursor.hpp +++ b/module-gui/gui/widgets/TextBlockCursor.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -29,14 +29,14 @@ namespace gui { protected: TextDocument *document = nullptr; - [[nodiscard]] auto currentBlock() const -> std::_List_iterator; - [[nodiscard]] auto blocksEnd() const -> std::_List_iterator; - [[nodiscard]] auto blocksBegin() const -> std::_List_iterator; + [[nodiscard]] auto currentBlock() const -> std::list::iterator; + [[nodiscard]] auto blocksEnd() const -> std::list::iterator; + [[nodiscard]] auto blocksBegin() const -> std::list::iterator; RawFont *default_font = nullptr; private: - bool emptyNewLineAdded = false; - bool blockChanged = false; + bool emptyNewLineAdded = false; + bool blockChanged = false; unsigned int pos = text::npos; unsigned int currentBlockNumber = text::npos; @@ -50,7 +50,7 @@ namespace gui /// @note it does not select next block - to do so add another ctor based on operator+ /// and check if this one is needed BlockCursor(TextDocument *document, unsigned int pos, unsigned int block_nr, RawFont *default_font); - BlockCursor() = default; /// bad cursor + BlockCursor() = default; /// bad cursor virtual ~BlockCursor() = default; [[nodiscard]] auto getPosition() const -> unsigned int @@ -146,6 +146,9 @@ namespace gui auto goToNextBlock() -> BlockCursor &; auto goToPreviousBlock() -> BlockCursor &; + auto checkIfBlockFirstAndEmpty(std::list::iterator block) -> bool; + auto checkIfNextBlockEmpty(std::list::iterator nextBlock) -> bool; + auto operator+=(unsigned int) -> BlockCursor &; auto operator++() -> BlockCursor &; auto operator-=(unsigned int) -> BlockCursor &; diff --git a/module-gui/test/test-catch-text/test-gui-Text.cpp b/module-gui/test/test-catch-text/test-gui-Text.cpp index c1b5b1d92988166a818cb0c61aeec8f5f8838017..d3a8086cf1ad984d71ccf27bbfa60a314637c975 100644 --- a/module-gui/test/test-catch-text/test-gui-Text.cpp +++ b/module-gui/test/test-catch-text/test-gui-Text.cpp @@ -1202,6 +1202,31 @@ TEST_CASE("Text newline navigation and deletion tests") REQUIRE(text->linesSize() == 0); REQUIRE(text->linesGet().empty()); } + + SECTION("Empty new block at end and delete from text beginning") + { + mockup::fontManager(); + using namespace gui; + auto text = std::make_unique(); + text->setMaximumSize(600, 200); + + text->addRichText("" + testStringBlock1 + emptyParagraph + ""); + + REQUIRE(text->linesSize() == 2); + REQUIRE((*text->lineGet(0)).getText(0) == testStringBlock1 + "\n"); + REQUIRE((*text->lineGet(1)).getText(0) == ""); + + text->moveCursor(gui::NavigationDirection::LEFT, testStringBlock1.length()); + text->removeNCharacters(testStringBlock1.length()); + + REQUIRE(text->linesSize() == 2); + REQUIRE((*text->lineGet(0)).getText(0) == "\n"); + REQUIRE((*text->lineGet(1)).getText(0) == ""); + + text->removeNCharacters(1); + REQUIRE(text->linesSize() == 0); + REQUIRE(text->linesGet().empty()); + } } TEST_CASE("RichText newline and empty lines tests")