diff options
author | mae <qt-info@nokia.com> | 2009-08-20 16:04:22 (GMT) |
---|---|---|
committer | mae <qt-info@nokia.com> | 2009-08-20 16:10:55 (GMT) |
commit | 735bed15d94c441c0d071bfbe26bc088791275b9 (patch) | |
tree | 75e0b5f3d01ffcc00a92d8a88c3cbd36f8b2e7db /src/gui/text | |
parent | 9933000d86bd9560769cb900b9e22083a073d837 (diff) | |
download | Qt-735bed15d94c441c0d071bfbe26bc088791275b9.zip Qt-735bed15d94c441c0d071bfbe26bc088791275b9.tar.gz Qt-735bed15d94c441c0d071bfbe26bc088791275b9.tar.bz2 |
Fix undo/redo of single-command edit blocks
(with QTextCursor::beginEditBlock() and QTextCursor::endEditBlock())
Previously QTextDocument would treat single command blocks as if there
was no block, i.e. command compression would occur, causing
tst_QTextDocument::testUndoBlocks() to fail. The patch completes the
insufficient block-flag of QTextUndoCommand with an addition flag block_end.
The block-flag itself is renamed to block_part.
Reviewed-by: con
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qtextdocument_p.cpp | 42 | ||||
-rw-r--r-- | src/gui/text/qtextdocument_p.h | 4 |
2 files changed, 27 insertions, 19 deletions
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 533ef46..e7aeed0 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -63,10 +63,10 @@ QT_BEGIN_NAMESPACE // The VxWorks DIAB compiler crashes when initializing the anonymouse union with { a7 } #if !defined(Q_CC_DIAB) # define QT_INIT_TEXTUNDOCOMMAND(c, a1, a2, a3, a4, a5, a6, a7, a8) \ - QTextUndoCommand c = { a1, a2, a3, a4, a5, a6, { a7 }, a8 } + QTextUndoCommand c = { a1, a2, 0, 0, a3, a4, a5, a6, { a7 }, a8 } #else # define QT_INIT_TEXTUNDOCOMMAND(c, a1, a2, a3, a4, a5, a6, a7, a8) \ - QTextUndoCommand c = { a1, a2, a3, a4, a5, a6 }; c.blockFormat = a7; c.revision = a8 + QTextUndoCommand c = { a1, a2, 0, 0, a3, a4, a5, a6 }; c.blockFormat = a7; c.revision = a8 #endif /* @@ -961,14 +961,18 @@ int QTextDocumentPrivate::undoRedo(bool undo) B->revision = c.revision; } - if (undo) { - if (undoState == 0 || !undoStack[undoState-1].block) - break; - } else { + if (!undo) ++undoState; - if (undoState == undoStack.size() || !undoStack[undoState-1].block) - break; - } + + bool inBlock = ( + undoState > 0 + && undoState < undoStack.size() + && undoStack[undoState].block_part + && undoStack[undoState-1].block_part + && !undoStack[undoState-1].block_end + ); + if (!inBlock) + break; } undoEnabled = true; int editPos = -1; @@ -993,7 +997,8 @@ void QTextDocumentPrivate::appendUndoItem(QAbstractUndoItem *item) QTextUndoCommand c; c.command = QTextUndoCommand::Custom; - c.block = editBlock != 0; + c.block_part = editBlock != 0; + c.block_end = 0; c.operation = QTextUndoCommand::MoveCursor; c.format = 0; c.strPos = 0; @@ -1014,9 +1019,10 @@ void QTextDocumentPrivate::appendUndoItem(const QTextUndoCommand &c) if (!undoStack.isEmpty() && modified) { QTextUndoCommand &last = undoStack[undoState - 1]; - if ( (last.block && c.block) // part of the same block => can merge - || (!c.block && !last.block // two single undo items => can merge - && (undoState < 2 || !undoStack[undoState-2].block))) { + + if ( (last.block_part && c.block_part && !last.block_end) // part of the same block => can merge + || (!c.block_part && !last.block_part)) { // two single undo items => can merge + if (last.tryMerge(c)) return; } @@ -1028,7 +1034,7 @@ void QTextDocumentPrivate::appendUndoItem(const QTextUndoCommand &c) emitUndoAvailable(true); emitRedoAvailable(false); - if (!c.block) + if (!c.block_part) emit document()->undoCommandAdded(); } @@ -1094,7 +1100,7 @@ void QTextDocumentPrivate::joinPreviousEditBlock() beginEditBlock(); if (undoEnabled && undoState) - undoStack[undoState - 1].block = true; + undoStack[undoState - 1].block_end = false; } void QTextDocumentPrivate::endEditBlock() @@ -1103,10 +1109,10 @@ void QTextDocumentPrivate::endEditBlock() return; if (undoEnabled && undoState > 0) { - const bool wasBlocking = undoStack[undoState - 1].block; - undoStack[undoState - 1].block = false; - if (wasBlocking) + if (undoStack[undoState - 1].block_part) { + undoStack[undoState - 1].block_end = true; emit document()->undoCommandAdded(); + } } finishEdit(); diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index 55aa17e..363309c 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -139,7 +139,9 @@ public: MoveCursor = 1 }; quint16 command; - quint8 block; ///< All undo commands that have this set to true are combined with the preceding command on undo/redo. + uint block_part : 1; // all commands that are part of an undo block (including the first and the last one) have this set to 1 + uint block_end : 1; // the last command in an undo block has this set to 1. + uint block_padding : 6; // padding since block used to be a quint8 quint8 operation; int format; quint32 strPos; |