summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormae <qt-info@nokia.com>2009-09-24 10:31:51 (GMT)
committermae <qt-info@nokia.com>2009-09-24 10:33:20 (GMT)
commit06aa9b6704637864130e318e8700f1b0b4f8a5e3 (patch)
treef2140e2d31b62570bcd278a088670bbc9cf87234
parent135e02d11becc8ee434524756d85221244c185ee (diff)
downloadQt-06aa9b6704637864130e318e8700f1b0b4f8a5e3.zip
Qt-06aa9b6704637864130e318e8700f1b0b4f8a5e3.tar.gz
Qt-06aa9b6704637864130e318e8700f1b0b4f8a5e3.tar.bz2
Fix QTextDocument::revision()
The revision was bound to the current depth of the undo stack. This had the negative side effect, that equal revisions could point to different documents, and sometimes changes would not even increase the revision (in the case of undo command merging). Reviewed-by: Roberto Raggi
-rw-r--r--src/gui/text/qtextdocument.cpp2
-rw-r--r--src/gui/text/qtextdocument_p.cpp33
-rw-r--r--src/gui/text/qtextdocument_p.h5
-rw-r--r--tests/auto/qtextdocument/tst_qtextdocument.cpp39
4 files changed, 56 insertions, 23 deletions
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 57d4b7a..5540958 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -985,7 +985,7 @@ bool QTextDocument::isRedoAvailable() const
int QTextDocument::revision() const
{
Q_D(const QTextDocument);
- return d->undoState;
+ return d->revision;
}
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp
index 7bfdf6c..2ad6512 100644
--- a/src/gui/text/qtextdocument_p.cpp
+++ b/src/gui/text/qtextdocument_p.cpp
@@ -195,6 +195,7 @@ QTextDocumentPrivate::QTextDocumentPrivate()
docChangeFrom = -1;
undoState = 0;
+ revision = -1; // init() inserts a block, bringing it to 0
lout = 0;
@@ -203,7 +204,6 @@ QTextDocumentPrivate::QTextDocumentPrivate()
undoEnabled = true;
inContentsChange = false;
- inEdit = false;
defaultTextOption.setTabStop(80); // same as in qtextengine.cpp
defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
@@ -429,11 +429,11 @@ int QTextDocumentPrivate::insertBlock(const QChar &blockSeparator,
Q_ASSERT(undoState == undoStack.size());
// update revision numbers of the modified blocks.
- B->revision = (atBlockEnd && !atBlockStart)? oldRevision : undoState;
+ B->revision = (atBlockEnd && !atBlockStart)? oldRevision : revision;
b = blocks.next(b);
if (b) {
B = blocks.fragment(b);
- B->revision = atBlockStart ? oldRevision : undoState;
+ B->revision = atBlockStart ? oldRevision : revision;
}
if (formats.charFormat(charFormat).objectIndex() == -1)
@@ -456,7 +456,6 @@ void QTextDocumentPrivate::insert(int pos, int strPos, int strLength, int format
Q_ASSERT(pos >= 0 && pos < fragments.length());
Q_ASSERT(formats.format(format).isCharFormat());
- beginEdit();
insert_string(pos, strPos, strLength, format, QTextUndoCommand::MoveCursor);
if (undoEnabled) {
int b = blocks.findNode(pos);
@@ -466,7 +465,7 @@ void QTextDocumentPrivate::insert(int pos, int strPos, int strLength, int format
QTextUndoCommand::MoveCursor, format, strPos, pos, strLength,
B->revision);
appendUndoItem(c);
- B->revision = undoState;
+ B->revision = revision;
Q_ASSERT(undoState == undoStack.size());
}
finishEdit();
@@ -582,7 +581,6 @@ void QTextDocumentPrivate::move(int pos, int to, int length, QTextUndoCommand::O
if (pos == to)
return;
- beginEdit();
const bool needsInsert = to != -1;
#if !defined(QT_NO_DEBUG)
@@ -653,7 +651,7 @@ void QTextDocumentPrivate::move(int pos, int to, int length, QTextUndoCommand::O
}
appendUndoItem(c);
if (B)
- B->revision = undoState;
+ B->revision = revision;
x = n;
if (needsInsert)
@@ -1111,6 +1109,7 @@ void QTextDocumentPrivate::joinPreviousEditBlock()
void QTextDocumentPrivate::endEditBlock()
{
+ Q_ASSERT(editBlock > 0);
if (--editBlock)
return;
@@ -1131,8 +1130,6 @@ void QTextDocumentPrivate::finishEdit()
if (editBlock)
return;
- inEdit = false;
-
if (framesDirty)
scan_frames(docChangeFrom, docChangeOldLength, docChangeLength);
@@ -1195,19 +1192,19 @@ void QTextDocumentPrivate::documentChange(int from, int length)
adjustDocumentChangesAndCursors is called whenever there is an insert or remove of characters.
param from is the cursor position in the document
param addedOrRemoved is the amount of characters added or removed. A negative number means characters are removed.
+
+ The function stores information to be emitted when finishEdit() is called.
*/
void QTextDocumentPrivate::adjustDocumentChangesAndCursors(int from, int addedOrRemoved, QTextUndoCommand::Operation op)
{
- Q_Q(QTextDocument);
+ if (!editBlock)
+ ++revision;
+
for (int i = 0; i < cursors.size(); ++i) {
QTextCursorPrivate *curs = cursors.at(i);
if (curs->adjustPosition(from, addedOrRemoved, op) == QTextCursorPrivate::CursorMoved) {
- if (editBlock || inEdit) {
- if (!changedCursors.contains(curs))
- changedCursors.append(curs);
- } else {
- emit q->cursorPositionChanged(QTextCursor(curs));
- }
+ if (!changedCursors.contains(curs))
+ changedCursors.append(curs);
}
}
@@ -1223,7 +1220,6 @@ void QTextDocumentPrivate::adjustDocumentChangesAndCursors(int from, int addedOr
}
// qDebug("adjustDocumentChanges:");
// qDebug(" -> %d %d %d", docChangeFrom, docChangeOldLength, docChangeLength);
- contentsChanged();
return;
}
@@ -1248,7 +1244,6 @@ void QTextDocumentPrivate::adjustDocumentChangesAndCursors(int from, int addedOr
docChangeLength += added - removedInside + diff;
// qDebug(" -> %d %d %d", docChangeFrom, docChangeOldLength, docChangeLength);
- contentsChanged();
}
@@ -1541,7 +1536,7 @@ void QTextDocumentPrivate::deleteObject(QTextObject *object)
void QTextDocumentPrivate::contentsChanged()
{
Q_Q(QTextDocument);
- if (editBlock || inEdit)
+ if (editBlock)
return;
bool m = undoEnabled ? (modifiedState != undoState) : true;
diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h
index 36f3241..ce25c57 100644
--- a/src/gui/text/qtextdocument_p.h
+++ b/src/gui/text/qtextdocument_p.h
@@ -201,10 +201,9 @@ public:
inline void undo() { undoRedo(true); }
inline void redo() { undoRedo(false); }
void appendUndoItem(QAbstractUndoItem *);
- inline void beginEditBlock() { editBlock++; }
+ inline void beginEditBlock() { if (0 == editBlock++) ++revision; }
void joinPreviousEditBlock();
void endEditBlock();
- inline void beginEdit() { inEdit = true; }
void finishEdit();
inline bool isInEditBlock() const { return editBlock; }
void enableUndoRedo(bool enable);
@@ -306,6 +305,7 @@ private:
QVector<QTextUndoCommand> undoStack;
bool undoEnabled;
int undoState;
+ int revision;
// position in undo stack of the last setModified(false) call
int modifiedState;
bool modified;
@@ -340,7 +340,6 @@ public:
int maximumBlockCount;
uint needsEnsureMaximumBlockCount : 1;
uint inContentsChange : 1;
- uint inEdit : 1; // between beginEdit() and finishEdit()
QSizeF pageSize;
QString title;
QString url;
diff --git a/tests/auto/qtextdocument/tst_qtextdocument.cpp b/tests/auto/qtextdocument/tst_qtextdocument.cpp
index 323df58..c0d7ed3 100644
--- a/tests/auto/qtextdocument/tst_qtextdocument.cpp
+++ b/tests/auto/qtextdocument/tst_qtextdocument.cpp
@@ -168,6 +168,7 @@ private slots:
void characterAt();
void revisions();
+ void revisionWithUndoCompressionAndUndo();
void testUndoCommandAdded();
@@ -2499,6 +2500,44 @@ void tst_QTextDocument::revisions()
QCOMPARE(cursor.block().revision(), 5);
}
+void tst_QTextDocument::revisionWithUndoCompressionAndUndo()
+{
+ QTextDocument doc;
+ QTextCursor cursor(&doc);
+ cursor.insertText("This is the beginning of it all.");
+ QCOMPARE(doc.firstBlock().revision(), 1);
+ QCOMPARE(doc.revision(), 1);
+ cursor.insertBlock();
+ QCOMPARE(doc.revision(), 2);
+ cursor.insertText("this");
+ QCOMPARE(doc.revision(), 3);
+ cursor.insertText("is");
+ QCOMPARE(doc.revision(), 4);
+ cursor.insertText("compressed");
+ QCOMPARE(doc.revision(), 5);
+ doc.undo();
+ QCOMPARE(doc.revision(), 6);
+ QCOMPARE(doc.toPlainText(), QString("This is the beginning of it all.\n")) ;
+ cursor.setPosition(0);
+ QCOMPARE(doc.firstBlock().revision(), 1);
+ cursor.insertText("Very beginnig");
+ QCOMPARE(doc.firstBlock().revision(), 7);
+ doc.undo();
+ QCOMPARE(doc.revision(), 8);
+ QCOMPARE(doc.firstBlock().revision(), 1);
+
+ cursor.beginEditBlock();
+ cursor.insertText("Hello");
+ cursor.insertBlock();
+ cursor.insertText("world");
+ cursor.endEditBlock();
+ QCOMPARE(doc.revision(), 9);
+ doc.undo();
+ QCOMPARE(doc.revision(), 10);
+
+
+}
+
void tst_QTextDocument::testUndoCommandAdded()
{
QVERIFY(doc);