// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once #include #include #include "TextBlock.hpp" #include "TextBlockCursor.hpp" namespace gui { class TextLine; class TextDocument { friend BlockCursor; static const std::string newline; std::list blocks; public: TextDocument(const std::list &blocks); ~TextDocument(); void destroy(); void append(std::list &&blocks); void append(TextBlock &&text); void addNewline(BlockCursor &cursor, TextBlock::End eol); [[nodiscard]] auto getText() const -> UTF8; /// --- in progress BlockCursor getBlockCursor(unsigned int position); /// get part of TextBlock based on cursor std::string getText(BlockCursor cursor); /// needed for tests, alternatively could be mocked in test... [[nodiscard]] const std::list &getBlocks() const; [[nodiscard]] const TextBlock *getBlock(BlockCursor *cursor) const; /// note just for creating line for easy current block under cursor access /// remove - use getTextPart instead? /// or remove getTextPart and always use cursor... const TextBlock &operator()(const BlockCursor &cursor) const; void removeBlock(unsigned int block_nr); void removeBlock(std::list::iterator it); // TODO this is very unoptimal... bool isEmpty() const { return getText().length() == 0; } private: /// splits text block in document and returns two new blocks (in place of last one) auto split(BlockCursor &cursor) -> std::pair; }; }; // namespace gui