Editor: reduce complexity of TextDocumentManipulator

Move implementations either to the TextEditorWidget, TextDocument, or to
the caller side. This makes the TextDocumentManipulator basically a
repeater so we can easily replace it with a TextEditorWidget in the
next step.

Change-Id: I04de3cb295b56fbaae99145f8e579fe405b065a5
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2024-06-28 08:35:40 +02:00
parent f09a694cfc
commit 9ad0a5a641
15 changed files with 94 additions and 117 deletions

View File

@@ -288,7 +288,7 @@ void ClangdCompletionItem::apply(TextDocumentManipulator &manipulator,
int cursorOffset = 0; int cursorOffset = 0;
bool setAutoCompleteSkipPos = false; bool setAutoCompleteSkipPos = false;
int currentPos = manipulator.currentPosition(); int currentPos = manipulator.currentPosition();
const QTextDocument * const doc = manipulator.textCursorAt(currentPos).document(); const QTextDocument * const doc = manipulator.document();
const Range range = edit->range(); const Range range = edit->range();
const int rangeStart = range.start().toPositionInDocument(doc); const int rangeStart = range.start().toPositionInDocument(doc);
if (isFunctionLike && completionSettings.m_autoInsertBrackets) { if (isFunctionLike && completionSettings.m_autoInsertBrackets) {
@@ -383,13 +383,14 @@ void ClangdCompletionItem::apply(TextDocumentManipulator &manipulator,
textToBeInserted += extraCharacters; textToBeInserted += extraCharacters;
const int length = currentPos - rangeStart + extraLength; const int length = currentPos - rangeStart + extraLength;
const bool isReplaced = manipulator.replace(rangeStart, length, textToBeInserted); const int oldRevision = manipulator.document()->revision();
manipulator.replace(rangeStart, length, textToBeInserted);
manipulator.setCursorPosition(rangeStart + textToBeInserted.length()); manipulator.setCursorPosition(rangeStart + textToBeInserted.length());
if (isReplaced) { if (manipulator.document()->revision() != oldRevision) {
if (cursorOffset) if (cursorOffset)
manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset); manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset);
if (setAutoCompleteSkipPos) if (setAutoCompleteSkipPos)
manipulator.setAutoCompleteSkipPosition(manipulator.currentPosition()); manipulator.addAutoCompleteSkipPosition();
} }
if (auto additionalEdits = item.additionalTextEdits()) { if (auto additionalEdits = item.additionalTextEdits()) {

View File

@@ -51,8 +51,9 @@ void ClangPreprocessorAssistProposalItem::apply(TextEditor::TextDocumentManipula
extraCharacters += m_typedCharacter; extraCharacters += m_typedCharacter;
// Avoid inserting characters that are already there // Avoid inserting characters that are already there
const int endsPosition = manipulator.positionAt(TextEditor::EndOfLinePosition); QTextCursor c = manipulator.textCursor();
const QString existingText = manipulator.textAt(manipulator.currentPosition(), endsPosition - manipulator.currentPosition()); c.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
const QString existingText = c.selectedText();
int existLength = 0; int existLength = 0;
if (!existingText.isEmpty()) { if (!existingText.isEmpty()) {
// Calculate the exist length in front of the extra chars // Calculate the exist length in front of the extra chars

View File

@@ -1659,7 +1659,7 @@ void ClangdTestCompletion::testCompleteGlobals()
item->apply(manipulator, cursorPos); item->apply(manipulator, cursorPos);
QCOMPARE(manipulator.getLine(7), " globalFunction() /* COMPLETE HERE */"); QCOMPARE(manipulator.getLine(7), " globalFunction() /* COMPLETE HERE */");
QCOMPARE(manipulator.cursorPos(), Text::Position({7, 19})); QCOMPARE(manipulator.cursorPos(), Text::Position({7, 19}));
QCOMPARE(manipulator.skipPos(), -1); QVERIFY(manipulator.editor()->autoCompleteHighlightPositions().isEmpty());
} }
void ClangdTestCompletion::testCompleteMembers() void ClangdTestCompletion::testCompleteMembers()
@@ -1679,7 +1679,7 @@ void ClangdTestCompletion::testCompleteMembers()
item->apply(manipulator, cursorPos); item->apply(manipulator, cursorPos);
QCOMPARE(manipulator.getLine(7), " s.member /* COMPLETE HERE */"); QCOMPARE(manipulator.getLine(7), " s.member /* COMPLETE HERE */");
QCOMPARE(manipulator.cursorPos(), Text::Position({7, 12})); QCOMPARE(manipulator.cursorPos(), Text::Position({7, 12}));
QCOMPARE(manipulator.skipPos(), -1); QVERIFY(manipulator.editor()->autoCompleteHighlightPositions().isEmpty());
} }
void ClangdTestCompletion::testCompleteMembersFromInside() void ClangdTestCompletion::testCompleteMembersFromInside()
@@ -1697,7 +1697,7 @@ void ClangdTestCompletion::testCompleteMembersFromInside()
item->apply(manipulator, cursorPos); item->apply(manipulator, cursorPos);
QCOMPARE(manipulator.getLine(4), " privateFunc() /* COMPLETE HERE */"); QCOMPARE(manipulator.getLine(4), " privateFunc() /* COMPLETE HERE */");
QCOMPARE(manipulator.cursorPos(), Text::Position({4, 21})); QCOMPARE(manipulator.cursorPos(), Text::Position({4, 21}));
QCOMPARE(manipulator.skipPos(), -1); QVERIFY(manipulator.editor()->autoCompleteHighlightPositions().isEmpty());
} }
void ClangdTestCompletion::testCompleteMembersFromOutside() void ClangdTestCompletion::testCompleteMembersFromOutside()
@@ -1715,7 +1715,7 @@ void ClangdTestCompletion::testCompleteMembersFromOutside()
item->apply(manipulator, cursorPos); item->apply(manipulator, cursorPos);
QCOMPARE(manipulator.getLine(13), " c.publicFunc() /* COMPLETE HERE */"); QCOMPARE(manipulator.getLine(13), " c.publicFunc() /* COMPLETE HERE */");
QCOMPARE(manipulator.cursorPos(), Text::Position({13, 18})); QCOMPARE(manipulator.cursorPos(), Text::Position({13, 18}));
QCOMPARE(manipulator.skipPos(), -1); QVERIFY(manipulator.editor()->autoCompleteHighlightPositions().isEmpty());
} }
void ClangdTestCompletion::testCompleteMembersFromFriend() void ClangdTestCompletion::testCompleteMembersFromFriend()
@@ -1733,7 +1733,7 @@ void ClangdTestCompletion::testCompleteMembersFromFriend()
item->apply(manipulator, cursorPos); item->apply(manipulator, cursorPos);
QCOMPARE(manipulator.getLine(14), " C().privateFunc() /* COMPLETE HERE */"); QCOMPARE(manipulator.getLine(14), " C().privateFunc() /* COMPLETE HERE */");
QCOMPARE(manipulator.cursorPos(), Text::Position({14, 21})); QCOMPARE(manipulator.cursorPos(), Text::Position({14, 21}));
QCOMPARE(manipulator.skipPos(), -1); QVERIFY(manipulator.editor()->autoCompleteHighlightPositions().isEmpty());
} }
void ClangdTestCompletion::testFunctionAddress() void ClangdTestCompletion::testFunctionAddress()
@@ -1750,7 +1750,7 @@ void ClangdTestCompletion::testFunctionAddress()
item->apply(manipulator, cursorPos); item->apply(manipulator, cursorPos);
QCOMPARE(manipulator.getLine(7), " const auto p = &S::memberFunc /* COMPLETE HERE */;"); QCOMPARE(manipulator.getLine(7), " const auto p = &S::memberFunc /* COMPLETE HERE */;");
QCOMPARE(manipulator.cursorPos(), Text::Position({7, 33})); QCOMPARE(manipulator.cursorPos(), Text::Position({7, 33}));
QCOMPARE(manipulator.skipPos(), -1); QVERIFY(manipulator.editor()->autoCompleteHighlightPositions().isEmpty());
} }
void ClangdTestCompletion::testFunctionHints() void ClangdTestCompletion::testFunctionHints()
@@ -1814,7 +1814,7 @@ void ClangdTestCompletion::testCompleteClassAndConstructor()
item->apply(manipulator, cursorPos); item->apply(manipulator, cursorPos);
QCOMPARE(manipulator.getLine(7), " Foo( /* COMPLETE HERE */"); QCOMPARE(manipulator.getLine(7), " Foo( /* COMPLETE HERE */");
QCOMPARE(manipulator.cursorPos(), Text::Position({7, 8})); QCOMPARE(manipulator.cursorPos(), Text::Position({7, 8}));
QCOMPARE(manipulator.skipPos(), -1); QVERIFY(manipulator.editor()->autoCompleteHighlightPositions().isEmpty());
} }
void ClangdTestCompletion::testCompletePrivateFunctionDefinition() void ClangdTestCompletion::testCompletePrivateFunctionDefinition()
@@ -1841,7 +1841,7 @@ void ClangdTestCompletion::testCompleteWithDotToArrowCorrection()
item->apply(manipulator, cursorPos); item->apply(manipulator, cursorPos);
QCOMPARE(manipulator.getLine(4), " bar->member /* COMPLETE HERE */"); QCOMPARE(manipulator.getLine(4), " bar->member /* COMPLETE HERE */");
QCOMPARE(manipulator.cursorPos(), Text::Position({4, 15})); QCOMPARE(manipulator.cursorPos(), Text::Position({4, 15}));
QCOMPARE(manipulator.skipPos(), -1); QVERIFY(manipulator.editor()->autoCompleteHighlightPositions().isEmpty());
} }
void ClangdTestCompletion::testDontCompleteWithDotToArrowCorrectionForFloats() void ClangdTestCompletion::testDontCompleteWithDotToArrowCorrectionForFloats()
@@ -1872,7 +1872,7 @@ void ClangdTestCompletion::testCompleteCodeInGeneratedUiFile()
item->apply(manipulator, cursorPos); item->apply(manipulator, cursorPos);
QCOMPARE(manipulator.getLine(34), " ui->setupUi( /* COMPLETE HERE */"); QCOMPARE(manipulator.getLine(34), " ui->setupUi( /* COMPLETE HERE */");
QCOMPARE(manipulator.cursorPos(), Text::Position({34, 16})); QCOMPARE(manipulator.cursorPos(), Text::Position({34, 16}));
QCOMPARE(manipulator.skipPos(), -1); QVERIFY(manipulator.editor()->autoCompleteHighlightPositions().isEmpty());
} }
void ClangdTestCompletion::testSignalCompletion_data() void ClangdTestCompletion::testSignalCompletion_data()

View File

@@ -322,7 +322,7 @@ void CppAssistProposalItem::applyContextualContent(TextDocumentManipulator &mani
if (cursorOffset) if (cursorOffset)
manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset); manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset);
if (setAutoCompleteSkipPos) if (setAutoCompleteSkipPos)
manipulator.setAutoCompleteSkipPosition(manipulator.currentPosition()); manipulator.addAutoCompleteSkipPosition();
} }
// -------------------- // --------------------

View File

@@ -105,7 +105,7 @@ void applyTextEdit(TextDocumentManipulator &manipulator,
bool newTextIsSnippet) bool newTextIsSnippet)
{ {
const Range range = edit.range(); const Range range = edit.range();
const QTextDocument *doc = manipulator.textCursorAt(manipulator.currentPosition()).document(); const QTextDocument *doc = manipulator.document();
const int start = Text::positionInText(doc, range.start().line() + 1, range.start().character() + 1); const int start = Text::positionInText(doc, range.start().line() + 1, range.start().character() + 1);
const int end = Text::positionInText(doc, range.end().line() + 1, range.end().character() + 1); const int end = Text::positionInText(doc, range.end().line() + 1, range.end().character() + 1);
if (newTextIsSnippet) { if (newTextIsSnippet) {

View File

@@ -388,7 +388,7 @@ void QmlJSAssistProposalItem::applyContextualContent(TextEditor::TextDocumentMan
manipulator.replace(basePosition, length, content); manipulator.replace(basePosition, length, content);
if (cursorOffset) { if (cursorOffset) {
manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset); manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset);
manipulator.setAutoCompleteSkipPosition(manipulator.currentPosition()); manipulator.addAutoCompleteSkipPosition();
} }
} }

View File

@@ -51,7 +51,7 @@ public:
TextEditorWidget::duplicateMimeData(m_mimeData.get())); TextEditorWidget::duplicateMimeData(m_mimeData.get()));
//Paste //Paste
manipulator.paste(); manipulator.editor()->paste();
} }
private: private:

View File

@@ -113,7 +113,7 @@ void AssistProposalItem::apply(TextDocumentManipulator &manipulator, int basePos
applyQuickFix(manipulator, basePosition); applyQuickFix(manipulator, basePosition);
} else { } else {
applyContextualContent(manipulator, basePosition); applyContextualContent(manipulator, basePosition);
manipulator.encourageApply(); manipulator.editor()->encourageApply();
} }
} }

View File

@@ -111,7 +111,7 @@ void KeywordsAssistProposalItem::applyContextualContent(TextDocumentManipulator
if (cursorOffset) if (cursorOffset)
manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset); manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset);
if (setAutoCompleteSkipPosition) if (setAutoCompleteSkipPosition)
manipulator.setAutoCompleteSkipPosition(manipulator.currentPosition()); manipulator.addAutoCompleteSkipPosition();
} }
// ------------------------- // -------------------------

View File

@@ -18,11 +18,6 @@ int TextDocumentManipulator::currentPosition() const
return m_textEditorWidget->position(); return m_textEditorWidget->position();
} }
int TextDocumentManipulator::positionAt(TextPositionOperation textPositionOperation) const
{
return m_textEditorWidget->position(textPositionOperation);
}
QChar TextDocumentManipulator::characterAt(int position) const QChar TextDocumentManipulator::characterAt(int position) const
{ {
return m_textEditorWidget->characterAt(position); return m_textEditorWidget->characterAt(position);
@@ -33,12 +28,24 @@ QString TextDocumentManipulator::textAt(int position, int length) const
return m_textEditorWidget->textAt(position, length); return m_textEditorWidget->textAt(position, length);
} }
QTextCursor TextDocumentManipulator::textCursor() const
{
return m_textEditorWidget->textCursor();
}
QTextCursor TextDocumentManipulator::textCursorAt(int position) const QTextCursor TextDocumentManipulator::textCursorAt(int position) const
{ {
auto cursor = m_textEditorWidget->textCursor(); return m_textEditorWidget->textCursorAt(position);
cursor.setPosition(position); }
return cursor; QTextDocument *TextDocumentManipulator::document() const
{
return m_textEditorWidget->document();
}
TextEditorWidget *TextDocumentManipulator::editor() const
{
return m_textEditorWidget;
} }
void TextDocumentManipulator::setCursorPosition(int position) void TextDocumentManipulator::setCursorPosition(int position)
@@ -46,101 +53,31 @@ void TextDocumentManipulator::setCursorPosition(int position)
m_textEditorWidget->setCursorPosition(position); m_textEditorWidget->setCursorPosition(position);
} }
void TextDocumentManipulator::setAutoCompleteSkipPosition(int position) void TextDocumentManipulator::addAutoCompleteSkipPosition()
{ {
QTextCursor cursor = m_textEditorWidget->textCursor(); m_textEditorWidget->setAutoCompleteSkipPosition(m_textEditorWidget->textCursor());
cursor.setPosition(position);
m_textEditorWidget->setAutoCompleteSkipPosition(cursor);
} }
bool TextDocumentManipulator::replace(int position, int length, const QString &text) void TextDocumentManipulator::replace(int position, int length, const QString &text)
{ {
bool textWillBeReplaced = textIsDifferentAt(position, length, text); m_textEditorWidget->replace(position, length, text);
if (textWillBeReplaced)
replaceWithoutCheck(position, length, text);
return textWillBeReplaced;
} }
void TextDocumentManipulator::insertCodeSnippet(int position, void TextDocumentManipulator::insertCodeSnippet(int position,
const QString &text, const QString &text,
const SnippetParser &parse) const SnippetParser &parse)
{ {
auto cursor = m_textEditorWidget->textCursor(); m_textEditorWidget->insertCodeSnippet(position, text, parse);
cursor.setPosition(position, QTextCursor::KeepAnchor);
m_textEditorWidget->insertCodeSnippet(cursor, text, parse);
}
void TextDocumentManipulator::paste()
{
m_textEditorWidget->paste();
}
void TextDocumentManipulator::encourageApply()
{
m_textEditorWidget->encourageApply();
}
namespace {
bool hasOnlyBlanksBeforeCursorInLine(QTextCursor textCursor)
{
textCursor.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor);
const auto textBeforeCursor = textCursor.selectedText();
const auto nonSpace = std::find_if(textBeforeCursor.cbegin(),
textBeforeCursor.cend(),
[] (const QChar &signBeforeCursor) {
return !signBeforeCursor.isSpace();
});
return nonSpace == textBeforeCursor.cend();
}
}
void TextDocumentManipulator::autoIndent(int position, int length)
{
auto cursor = m_textEditorWidget->textCursor();
cursor.setPosition(position);
if (hasOnlyBlanksBeforeCursorInLine(cursor)) {
cursor.setPosition(position + length, QTextCursor::KeepAnchor);
m_textEditorWidget->textDocument()->autoIndent(cursor);
}
} }
QString TextDocumentManipulator::getLine(int line) const QString TextDocumentManipulator::getLine(int line) const
{ {
return m_textEditorWidget->document()->findBlockByNumber(line - 1).text(); return m_textEditorWidget->textDocument()->blockText(line - 1);
} }
Utils::Text::Position TextDocumentManipulator::cursorPos() const Utils::Text::Position TextDocumentManipulator::cursorPos() const
{ {
return Utils::Text::Position::fromCursor(m_textEditorWidget->textCursor()); return m_textEditorWidget->lineColumn();
}
int TextDocumentManipulator::skipPos() const
{
const QList<QTextCursor> highlights = m_textEditorWidget->autoCompleteHighlightPositions();
return highlights.isEmpty() ? -1 : highlights.first().position();
}
bool TextDocumentManipulator::textIsDifferentAt(int position, int length, const QString &text) const
{
const auto textToBeReplaced = m_textEditorWidget->textAt(position, length);
return text != textToBeReplaced;
}
void TextDocumentManipulator::replaceWithoutCheck(int position, int length, const QString &text)
{
auto cursor = m_textEditorWidget->textCursor();
cursor.setPosition(position);
cursor.setPosition(position + length, QTextCursor::KeepAnchor);
cursor.insertText(text);
} }
} // namespace TextEditor } // namespace TextEditor

View File

@@ -24,25 +24,22 @@ public:
TextDocumentManipulator(TextEditorWidget *textEditorWidget); TextDocumentManipulator(TextEditorWidget *textEditorWidget);
int currentPosition() const; int currentPosition() const;
int positionAt(TextPositionOperation textPositionOperation) const;
QChar characterAt(int position) const; QChar characterAt(int position) const;
QString textAt(int position, int length) const; QString textAt(int position, int length) const;
QTextCursor textCursor() const;
QTextCursor textCursorAt(int position) const; QTextCursor textCursorAt(int position) const;
QTextDocument *document() const;
TextEditorWidget *editor() const;
void setCursorPosition(int position); void setCursorPosition(int position);
void setAutoCompleteSkipPosition(int position); void addAutoCompleteSkipPosition();
bool replace(int position, int length, const QString &text); void replace(int position, int length, const QString &text);
void insertCodeSnippet(int position, const QString &text, const SnippetParser &parse); void insertCodeSnippet(int position, const QString &text, const SnippetParser &parse);
void paste();
void encourageApply();
void autoIndent(int position, int length);
QString getLine(int line) const; QString getLine(int line) const;
Utils::Text::Position cursorPos() const; Utils::Text::Position cursorPos() const;
int skipPos() const;
private: private:
bool textIsDifferentAt(int position, int length, const QString &text) const; bool textIsDifferentAt(int position, int length, const QString &text) const;
void replaceWithoutCheck(int position, int length, const QString &text); void replaceWithoutCheck(int position, int length, const QString &text);

View File

@@ -340,6 +340,11 @@ QChar TextDocument::characterAt(int pos) const
return document()->characterAt(pos); return document()->characterAt(pos);
} }
QString TextDocument::blockText(int blockNumber) const
{
return document()->findBlockByNumber(blockNumber).text();
}
void TextDocument::setTypingSettings(const TypingSettings &typingSettings) void TextDocument::setTypingSettings(const TypingSettings &typingSettings)
{ {
d->m_typingSettings = typingSettings; d->m_typingSettings = typingSettings;

View File

@@ -59,6 +59,7 @@ public:
virtual QString plainText() const; virtual QString plainText() const;
virtual QString textAt(int pos, int length) const; virtual QString textAt(int pos, int length) const;
virtual QChar characterAt(int pos) const; virtual QChar characterAt(int pos) const;
QString blockText(int blockNumber) const;
void setTypingSettings(const TypingSettings &typingSettings); void setTypingSettings(const TypingSettings &typingSettings);
void setStorageSettings(const StorageSettings &storageSettings); void setStorageSettings(const StorageSettings &storageSettings);

View File

@@ -3226,7 +3226,7 @@ public:
QTextCursor cursor; QTextCursor cursor;
}; };
void TextEditorWidget::insertCodeSnippet(const QTextCursor &cursor_arg, void TextEditorWidget::insertCodeSnippet(int basePosition,
const QString &snippet, const QString &snippet,
const SnippetParser &parse) const SnippetParser &parse)
{ {
@@ -3239,7 +3239,8 @@ void TextEditorWidget::insertCodeSnippet(const QTextCursor &cursor_arg,
QTC_ASSERT(std::holds_alternative<ParsedSnippet>(result), return); QTC_ASSERT(std::holds_alternative<ParsedSnippet>(result), return);
ParsedSnippet data = std::get<ParsedSnippet>(result); ParsedSnippet data = std::get<ParsedSnippet>(result);
QTextCursor cursor = cursor_arg; QTextCursor cursor = textCursor();
cursor.setPosition(basePosition, QTextCursor::KeepAnchor);
cursor.beginEditBlock(); cursor.beginEditBlock();
cursor.removeSelectedText(); cursor.removeSelectedText();
const int startCursorPosition = cursor.position(); const int startCursorPosition = cursor.position();
@@ -3433,6 +3434,18 @@ int TextEditorWidget::position(TextPositionOperation posOp, int at) const
return -1; return -1;
} }
QTextCursor TextEditorWidget::textCursorAt(int position) const
{
QTextCursor c = textCursor();
c.setPosition(position);
return c;
}
Text::Position TextEditorWidget::lineColumn() const
{
return Utils::Text::Position::fromCursor(textCursor());
}
QRect TextEditorWidget::cursorRect(int pos) const QRect TextEditorWidget::cursorRect(int pos) const
{ {
QTextCursor tc = textCursor(); QTextCursor tc = textCursor();
@@ -9583,6 +9596,22 @@ void TextEditorWidget::replace(int length, const QString &string)
tc.insertText(string); tc.insertText(string);
} }
void TextEditorWidget::replace(int pos, int length, const QString &string)
{
if (length == string.length()) {
bool different = false;
for (int i = 0; !different && pos < length; ++i)
different = document()->characterAt(pos) != string.at(i);
if (!different)
return;
}
QTextCursor tc = textCursor();
tc.setPosition(pos);
tc.setPosition(pos + length, QTextCursor::KeepAnchor);
tc.insertText(string);
}
void BaseTextEditor::setCursorPosition(int pos) void BaseTextEditor::setCursorPosition(int pos)
{ {
editorWidget()->setCursorPosition(pos); editorWidget()->setCursorPosition(pos);

View File

@@ -18,6 +18,7 @@
#include <utils/elidinglabel.h> #include <utils/elidinglabel.h>
#include <utils/link.h> #include <utils/link.h>
#include <utils/multitextcursor.h> #include <utils/multitextcursor.h>
#include <utils/textutils.h>
#include <utils/uncommentselection.h> #include <utils/uncommentselection.h>
#include <QPlainTextEdit> #include <QPlainTextEdit>
@@ -196,6 +197,8 @@ public:
void gotoLine(int line, int column = 0, bool centerLine = true, bool animate = false); void gotoLine(int line, int column = 0, bool centerLine = true, bool animate = false);
int position(TextPositionOperation posOp = CurrentPosition, int position(TextPositionOperation posOp = CurrentPosition,
int at = -1) const; int at = -1) const;
QTextCursor textCursorAt(int position) const;
Utils::Text::Position lineColumn() const;
void convertPosition(int pos, int *line, int *column) const; void convertPosition(int pos, int *line, int *column) const;
using QPlainTextEdit::cursorRect; using QPlainTextEdit::cursorRect;
QRect cursorRect(int pos) const; QRect cursorRect(int pos) const;
@@ -268,7 +271,9 @@ public:
void setReadOnly(bool b); void setReadOnly(bool b);
void insertCodeSnippet(const QTextCursor &cursor, // replaces the text from the current cursor position to the base position with the snippet
// and starts the snippet replacement mode
void insertCodeSnippet(int basePosition,
const QString &snippet, const QString &snippet,
const SnippetParser &parse); const SnippetParser &parse);
@@ -609,6 +614,7 @@ public:
void remove(int length); void remove(int length);
void replace(int length, const QString &string); void replace(int length, const QString &string);
void replace(int pos, int length, const QString &string);
QChar characterAt(int pos) const; QChar characterAt(int pos) const;
QString textAt(int from, int to) const; QString textAt(int from, int to) const;