Summary: | stange text editing behaviour on undo | ||
---|---|---|---|
Product: | kword | Reporter: | T Zachmann <t.zachmann> |
Component: | general | Assignee: | Thomas Zander <zander> |
Status: | RESOLVED UPSTREAM | ||
Severity: | normal | CC: | pstirnweiss |
Priority: | NOR | ||
Version: | git | ||
Target Milestone: | --- | ||
Platform: | Compiled Sources | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: |
Description
T Zachmann
2009-01-10 12:56:13 UTC
This problem is caused by a bug in Qt: when a selection is "replaced" by new text, the following happens within QTextDocumentPrivate: - a call to remove is made, which creates a number of commands (depending whether the selection contains a linebreak or not) - new characters are inserted, which also create a command These commands are grouped together in the stack by a beginEditBlock/endEditBlock, so that when undo is requested, they are ALL undone. The problem lies in that on each push of these commands, the signal undoCommandAdded is emited. KOffice creates one undoCommand per signal on its own stack. All these are also grouped in a parent command. When we hit undo, calls to QTextDocument::undo are done for each child undoCommands. The first time, QTextDocument undoes ALL the internal grouped commands, undoing the "replace" action completly. The second time QTextDocument::undo is called, the QTextDocument undoes the previous change (which in the case of the present bug was "type ddd". A further time would undo the previous command again (in this case the linebreak), and so on. The signal undoCommandAdded should be emitted only once per beginEditBlock/endEditBlock. Perhaps by moving the emission from the appendUndoCommand method to the endEditBlock method somewhere? I wrote a fix for Qt and this patch fixes the issue (Will be in the 4.5 snapshots tonight) diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 308e206..b141427 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -978,7 +978,6 @@ void QTextDocumentPrivate::appendUndoItem(const QTextUndoCommand &c) undoState++; emitUndoAvailable(true); emitRedoAvailable(false); - emit document()->undoCommandAdded(); } void QTextDocumentPrivate::truncateUndoStack() { @@ -1051,8 +1050,10 @@ void QTextDocumentPrivate::endEditBlock() if (--editBlock) return; - if (undoEnabled && undoState > 0) + if (undoEnabled && undoState > 0) { undoStack[undoState - 1].block = false; + emit document()->undoCommandAdded(); + } if (framesDirty) scan_frames(docChangeFrom, docChangeOldLength, docChangeLength); |