diff options
author | mae <qt-info@nokia.com> | 2010-04-07 11:13:15 (GMT) |
---|---|---|
committer | mae <qt-info@nokia.com> | 2010-04-07 11:54:03 (GMT) |
commit | 054950602a6675d01a9815a567b69157ee8ceff6 (patch) | |
tree | 8208e5557ca6db761d8f6b44fd4210a155b0a59d /src/gui/text/qtextdocument_p.cpp | |
parent | 0dd9960cbc533e377c8cc38b9e81b14108fac9be (diff) | |
download | Qt-054950602a6675d01a9815a567b69157ee8ceff6.zip Qt-054950602a6675d01a9815a567b69157ee8ceff6.tar.gz Qt-054950602a6675d01a9815a567b69157ee8ceff6.tar.bz2 |
Fix QTextDocument::undo() cursor positioning
When doing block undo operations, QTextDocument used the change
position of the last undo command for positioning the cursor.
This is incorrect if the last commands are of type
QTextUndoCommand::Removed but split because of the text
fragments. The bug is highly noticable in creator when
inserting snippets and doing undo afterwards.
The change adds an auto test.
Diffstat (limited to 'src/gui/text/qtextdocument_p.cpp')
-rw-r--r-- | src/gui/text/qtextdocument_p.cpp | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 302a349..e2bca04 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -870,6 +870,7 @@ int QTextDocumentPrivate::undoRedo(bool undo) undoEnabled = false; beginEditBlock(); int editPos = -1; + int editLength = -1; while (1) { if (undo) --undoState; @@ -882,12 +883,16 @@ int QTextDocumentPrivate::undoRedo(bool undo) PMDEBUG(" erase: from %d, length %d", c.pos, c.length); c.command = QTextUndoCommand::Removed; editPos = c.pos; + editLength = 0; break; case QTextUndoCommand::Removed: PMDEBUG(" insert: format %d (from %d, length %d, strpos=%d)", c.format, c.pos, c.length, c.strPos); insert_string(c.pos, c.strPos, c.length, c.format, (QTextUndoCommand::Operation)c.operation); c.command = QTextUndoCommand::Inserted; - editPos = c.pos + c.length; + if (editPos != (int)c.pos) + editLength = 0; + editPos = c.pos; + editLength += c.length; break; case QTextUndoCommand::BlockInserted: case QTextUndoCommand::BlockAdded: @@ -898,6 +903,7 @@ int QTextDocumentPrivate::undoRedo(bool undo) else c.command = QTextUndoCommand::BlockDeleted; editPos = c.pos; + editLength = 0; break; case QTextUndoCommand::BlockRemoved: case QTextUndoCommand::BlockDeleted: @@ -908,7 +914,10 @@ int QTextDocumentPrivate::undoRedo(bool undo) c.command = QTextUndoCommand::BlockInserted; else c.command = QTextUndoCommand::BlockAdded; - editPos = c.pos + 1; + if (editPos != (int)c.pos) + editLength = 0; + editPos = c.pos; + editLength += 1; break; case QTextUndoCommand::CharFormatChanged: { resetBlockRevision = -1; // ## TODO @@ -919,7 +928,10 @@ int QTextDocumentPrivate::undoRedo(bool undo) int oldFormat = it.value()->format; setCharFormat(c.pos, c.length, formats.charFormat(c.format)); c.format = oldFormat; - editPos = c.pos + c.length; + if (editPos != (int)c.pos) + editLength = 0; + editPos = c.pos; + editLength += c.length; break; } case QTextUndoCommand::BlockFormatChanged: { @@ -987,13 +999,19 @@ int QTextDocumentPrivate::undoRedo(bool undo) break; } undoEnabled = true; - if (editPos < 0 && docChangeFrom >= 0) { - editPos = qMin(docChangeFrom + docChangeLength, length() - 1); - } + + int newCursorPos = -1; + + if (editPos >=0) + newCursorPos = editPos + editLength; + else if (docChangeFrom >= 0) + newCursorPos= qMin(docChangeFrom + docChangeLength, length() - 1); + endEditBlock(); emitUndoAvailable(isUndoAvailable()); emitRedoAvailable(isRedoAvailable()); - return editPos; + + return newCursorPos; } /*! |