~aleteoryx/muditaos

694643418f0e607844b8ce0a56e8d39daaaac7f5 — Przemyslaw Brudny 4 years ago d586e98
[EGD-7018] Fixed text empty block removal at end

Fixed text empty block removal at end.
M module-gui/gui/widgets/TextBlockCursor.cpp => module-gui/gui/widgets/TextBlockCursor.cpp +22 -8
@@ 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<TextBlock>
    auto BlockCursor::currentBlock() const -> std::list<TextBlock>::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<TextBlock>
    auto BlockCursor::blocksEnd() const -> std::list<TextBlock>::iterator
    {
        return std::end(document->blocks);
    }

    auto BlockCursor::blocksBegin() const -> std::_List_iterator<TextBlock>
    auto BlockCursor::blocksBegin() const -> std::list<TextBlock>::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<TextBlock>::iterator block) -> bool
    {
        return block == blocksBegin() && block->isEmpty();
    }

    auto BlockCursor::checkIfNextBlockEmpty(std::list<TextBlock>::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

M module-gui/gui/widgets/TextBlockCursor.hpp => module-gui/gui/widgets/TextBlockCursor.hpp +10 -7
@@ 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<TextBlock>;
        [[nodiscard]] auto blocksEnd() const -> std::_List_iterator<TextBlock>;
        [[nodiscard]] auto blocksBegin() const -> std::_List_iterator<TextBlock>;
        [[nodiscard]] auto currentBlock() const -> std::list<TextBlock>::iterator;
        [[nodiscard]] auto blocksEnd() const -> std::list<TextBlock>::iterator;
        [[nodiscard]] auto blocksBegin() const -> std::list<TextBlock>::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<TextBlock>::iterator block) -> bool;
        auto checkIfNextBlockEmpty(std::list<TextBlock>::iterator nextBlock) -> bool;

        auto operator+=(unsigned int) -> BlockCursor &;
        auto operator++() -> BlockCursor &;
        auto operator-=(unsigned int) -> BlockCursor &;

M module-gui/test/test-catch-text/test-gui-Text.cpp => module-gui/test/test-catch-text/test-gui-Text.cpp +25 -0
@@ 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<gui::TestText>();
        text->setMaximumSize(600, 200);

        text->addRichText("<text>" + testStringBlock1 + emptyParagraph + "</text>");

        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")