#ifndef VEDITUTILS_H #define VEDITUTILS_H #include #include class QTextDocument; class QTextEdit; class QPlainTextEdit; // Utils for text edit. class VEditUtils { public: // Remove the whole block @p_block. // If @p_text is not NULL, return the deleted text here. static void removeBlock(QTextBlock &p_block, QString *p_text = NULL); // Remove the whole block under @p_cursor. // If @p_text is not NULL, return the deleted text here. // Need to call setTextCursor() to make it take effect. static void removeBlock(QTextCursor &p_cursor, QString *p_text = NULL); // Move @p_cursor to the first non-space character of current block. // Need to call setTextCursor() to make it take effect. static void moveCursorFirstNonSpaceCharacter(QTextCursor &p_cursor, QTextCursor::MoveMode p_mode); // Indent current block as next/previous block. // Return true if some changes have been made. // @p_cursor will be placed at the position after inserting leading spaces. // @p_next: indent as next block or previous block. static bool indentBlockAsBlock(QTextCursor &p_cursor, bool p_next); // Indent current block as @p_refBlock. static bool indentBlockAsBlock(QTextCursor &p_cursor, const QTextBlock &p_refBlock); // Returns true if two blocks has the same indent. static bool hasSameIndent(const QTextBlock &p_blocka, const QTextBlock &p_blockb); // Insert a new block at current position with the same indentation as // current block. Should clear the selection before calling this. // Returns true if non-empty indentation has been inserted. // Need to call setTextCursor() to make it take effect. static bool insertBlockWithIndent(QTextCursor &p_cursor); // Fetch the list mark of previous block, and insert it at current position. // Returns true if list mark has been inserted. // Need to call setTextCursor() to make it take effect. static bool insertListMarkAsPreviousBlock(QTextCursor &p_cursor); // Fetch the block quote mark of previous block, and insert it at current position. // Returns true if quote mark has been inserted. // Need to call setTextCursor() to make it take effect. static bool insertQuoteMarkAsPreviousBlock(QTextCursor &p_cursor); // Remove ObjectReplaceCharacter in p_text. // If the ObjectReplaceCharacter is in a block with only other spaces, remove the // whole block. static void removeObjectReplacementCharacter(QString &p_text); // p_cursor.selectedText() will use U+2029 (QChar::ParagraphSeparator) // instead of \n for a new line. // This function will translate it to \n. static QString selectedText(const QTextCursor &p_cursor); // Indent selected blocks. If no selection, indent current block. // Cursor position and selection is not changed. // @p_isIndent: whether it is indentation or unindentation. static void indentSelectedBlocks(const QTextCursor &p_cursor, const QString &p_indentationText, bool p_isIndent); // Indent seleced block as next/previous block. // Cursor position and selection is not changed. // Return true if some changes have been made. // @p_next: indent as next block or previous block. static void indentSelectedBlocksAsBlock(const QTextCursor &p_cursor, bool p_next); // Indent current block. // @p_skipEmpty: skip empty block. static void indentBlock(QTextCursor &p_cursor, const QString &p_indentationText, bool p_skipEmpty = true); static void unindentBlock(QTextCursor &p_cursor, const QString &p_indentationText); // Find @p_repeat th occurence of a char within a block. // Returns true if target is found. // Please pay attention to the one-step-forward/backward in KeepAnchor mode // and exclusive case. static bool findTargetWithinBlock(QTextCursor &p_cursor, QTextCursor::MoveMode p_mode, QChar p_target, bool p_forward, bool p_inclusive, bool p_leftSideOfCursor, int p_repeat); // Find th first occurence of a char in @p_targets within a block. // Returns the index of the found char in @p_targets if found. // Returns -1 if none of the @p_targets is found. // Different from findTargetWithinBlock(), will not modify the ucrsor position // even in KeepAnchor mode. static int findTargetsWithinBlock(QTextCursor &p_cursor, const QList &p_targets, bool p_forward, bool p_leftSideOfCursor, bool p_inclusive); // Find a pair target (@p_opening, @p_closing) containing current cursor and // select the range between them. // Need to call setTextCursor() to make it take effect. // Returns true if target is found. static bool selectPairTargetAround(QTextCursor &p_cursor, QChar p_opening, QChar p_closing, bool p_inclusive, bool p_crossBlock, int p_repeat); // Get the count of blocks selected. static int selectedBlockCount(const QTextCursor &p_cursor); // Scroll block @p_blockNum into the visual window. // @p_dest is the position of the window: 0 for top, 1 for center, 2 for bottom. // @p_blockNum is based on 0. // Will set the cursor to the block. static void scrollBlockInPage(QTextEdit *p_edit, int p_blockNum, int p_dest); // Scroll block @p_blockNum into the visual window. // @p_dest is the position of the window: 0 for top, 1 for center, 2 for bottom. // @p_blockNum is based on 0. // Will set the cursor to the block. static void scrollBlockInPage(QPlainTextEdit *p_edit, int p_blockNum, int p_dest); // Check if @p_block is a auto list block. // @p_seq will be the seq number of the ordered list, or -1. // Returns true if it is an auto list block. static bool isListBlock(const QTextBlock &p_block, int *p_seq = NULL); static bool isListBullet(const QString &p_str); static bool isBlockQuoteBlock(const QTextBlock &p_block); // If the start of @p_block to postition @p_posInBlock are spaces. static bool isSpaceToBlockStart(const QTextBlock &p_block, int p_posInBlock); // If block @p_block only contains spaces. static bool isSpaceBlock(const QTextBlock &p_block); // @p_cursor is positioned right after auto indetn and auto list. // Need to call setTextCursor() to make it take effect. static void deleteIndentAndListMark(QTextCursor &p_cursor); // Find next @p_repeat empty block. // Returns the position of that block if found. Otherwise, returns -1. static int findNextEmptyBlock(const QTextCursor &p_cursor, bool p_forward, int p_repeat); // Check if we need to cancel auto indent. // @p_autoIndentPos: the position of the cursor after auto indent. static bool needToCancelAutoIndent(int p_autoIndentPos, const QTextCursor &p_cursor); // Insert title Mark at level @p_level in front of block @p_block // If there already exists title marks, remove it first. // Move cursor at the end of the block after insertion. // If @p_level is 0, remove the title mark. static void insertTitleMark(QTextCursor &p_cursor, const QTextBlock &p_block, int p_level); // Find the start and end of the word @p_cursor locates in (within a single block). // @p_start and @p_end will be the global position of the start and end of the word. // @p_start will equals to @p_end if @p_cursor is a space. static void findCurrentWord(QTextCursor p_cursor, int &p_start, int &p_end); // Find the start and end of the WORD @p_cursor locates in (within a single block). // @p_start and @p_end will be the global position of the start and end of the WORD. // @p_start will equals to @p_end if @p_cursor is a space. static void findCurrentWORD(const QTextCursor &p_cursor, int &p_start, int &p_end); // Return the leading spaces of @p_block. static QString fetchIndentSpaces(const QTextBlock &p_block); static int fetchIndentation(const QString &p_text); static int fetchIndentation(const QTextBlock &p_block); // Insert a block above/below current block. Move the cursor to the start of // the new block after insertion. static void insertBlock(QTextCursor &p_cursor, bool p_above); // Insert @p_str in the front of each line of @p_text. static void insertBeforeEachLine(QString &p_text, const QString &p_str); // Whether @p_block is empty. static bool isEmptyBlock(const QTextBlock &p_block); static bool isWordSeparator(QChar p_char); // Remove the fence of fenced code block. static QString removeCodeBlockFence(const QString &p_text); private: VEditUtils() {} }; #endif // VEDITUTILS_H