src/gui/text/qtextdocument_p.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
--- a/src/gui/text/qtextdocument_p.cpp	Tue Jul 06 15:10:48 2010 +0300
+++ b/src/gui/text/qtextdocument_p.cpp	Wed Aug 18 10:37:55 2010 +0300
@@ -192,6 +192,7 @@
     initialBlockCharFormatIndex(-1) // set correctly later in init()
 {
     editBlock = 0;
+    editBlockCursorPosition = -1;
     docChangeFrom = -1;
 
     undoState = 0;
@@ -204,6 +205,7 @@
 
     undoEnabled = true;
     inContentsChange = false;
+    blockCursorAdjustment = false;
 
     defaultTextOption.setTabStop(80); // same as in qtextengine.cpp
     defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
@@ -233,17 +235,17 @@
 void QTextDocumentPrivate::clear()
 {
     Q_Q(QTextDocument);
-    for (int i = 0; i < cursors.count(); ++i) {
-        cursors.at(i)->setPosition(0);
-        cursors.at(i)->currentCharFormat = -1;
-        cursors.at(i)->anchor = 0;
-        cursors.at(i)->adjusted_anchor = 0;
+
+    foreach (QTextCursorPrivate *curs, cursors) {
+        curs->setPosition(0);
+        curs->currentCharFormat = -1;
+        curs->anchor = 0;
+        curs->adjusted_anchor = 0;
     }
 
     QList<QTextCursorPrivate *>oldCursors = cursors;
     QT_TRY{
         cursors.clear();
-        changedCursors.clear();
 
         QMap<int, QTextObject *>::Iterator objectIt = objects.begin();
         while (objectIt != objects.end()) {
@@ -286,8 +288,8 @@
 
 QTextDocumentPrivate::~QTextDocumentPrivate()
 {
-    for (int i = 0; i < cursors.count(); ++i)
-        cursors.at(i)->priv = 0;
+    foreach (QTextCursorPrivate *curs, cursors)
+        curs->priv = 0;
     cursors.clear();
     undoState = 0;
     undoEnabled = true;
@@ -668,7 +670,14 @@
 {
     if (length == 0)
         return;
+    blockCursorAdjustment = true;
     move(pos, -1, length, op);
+    blockCursorAdjustment = false;
+    foreach (QTextCursorPrivate *curs, cursors) {
+        if (curs->adjustPosition(pos, -length, op) == QTextCursorPrivate::CursorMoved) {
+            curs->changed = true;
+        }
+    }
 }
 
 void QTextDocumentPrivate::setCharFormat(int pos, int length, const QTextCharFormat &newFormat, FormatChangeMode mode)
@@ -967,6 +976,10 @@
             editPos = -1;
 	    break;
 	}
+        case QTextUndoCommand::CursorMoved:
+            editPos = c.pos;
+            editLength = 0;
+            break;
 	case QTextUndoCommand::Custom:
             resetBlockRevision = -1; // ## TODO
             if (undo)
@@ -1046,6 +1059,18 @@
     if (undoState < undoStack.size())
         clearUndoRedoStacks(QTextDocument::RedoStack);
 
+    if (editBlock != 0 && editBlockCursorPosition >= 0) { // we had a beginEditBlock() with a cursor position
+        if (c.pos != (quint32) editBlockCursorPosition) { // and that cursor position is different from the command
+            // generate a CursorMoved undo item
+            QT_INIT_TEXTUNDOCOMMAND(cc, QTextUndoCommand::CursorMoved, true, QTextUndoCommand::MoveCursor,
+                                    0, 0, editBlockCursorPosition, 0, 0);
+            undoStack.append(cc);
+            undoState++;
+            editBlockCursorPosition = -1;
+        }
+    }
+
+
     if (!undoStack.isEmpty() && modified) {
         QTextUndoCommand &last = undoStack[undoState - 1];
 
@@ -1167,6 +1192,8 @@
         }
     }
 
+    editBlockCursorPosition = -1;
+
     finishEdit();
 }
 
@@ -1202,10 +1229,15 @@
         }
     }
 
-    while (!changedCursors.isEmpty()) {
-        QTextCursorPrivate *curs = changedCursors.takeFirst();
-        emit q->cursorPositionChanged(QTextCursor(curs));
+    QList<QTextCursor> changedCursors;
+    foreach (QTextCursorPrivate *curs, cursors) {
+        if (curs->changed) {
+            curs->changed = false;
+            changedCursors.append(QTextCursor(curs));
+        }
     }
+    foreach (const QTextCursor &cursor, changedCursors)
+        emit q->cursorPositionChanged(cursor);
 
     contentsChanged();
 
@@ -1247,11 +1279,13 @@
     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 (!changedCursors.contains(curs))
-                changedCursors.append(curs);
+    if (blockCursorAdjustment)  {
+        ; // postpone, will be called again from QTextDocumentPrivate::remove()
+    } else {
+        foreach (QTextCursorPrivate *curs, cursors) {
+            if (curs->adjustPosition(from, addedOrRemoved, op) == QTextCursorPrivate::CursorMoved) {
+                curs->changed = true;
+            }
         }
     }
 
@@ -1615,7 +1649,7 @@
     int newLen = 0;
 
     for (FragmentMap::Iterator it = fragments.begin(); !it.atEnd(); ++it) {
-        qMemCopy(newTextPtr, text.constData() + it->stringPosition, it->size_array[0] * sizeof(QChar));
+        memcpy(newTextPtr, text.constData() + it->stringPosition, it->size_array[0] * sizeof(QChar));
         it->stringPosition = newLen;
         newTextPtr += it->size_array[0];
         newLen += it->size_array[0];
@@ -1674,8 +1708,8 @@
 void QTextDocumentPrivate::aboutToRemoveCell(int from, int to)
 {
     Q_ASSERT(from <= to);
-    for (int i = 0; i < cursors.size(); ++i)
-        cursors.at(i)->aboutToRemoveCell(from, to);
+    foreach (QTextCursorPrivate *curs, cursors)
+        curs->aboutToRemoveCell(from, to);
 }
 
 QT_END_NAMESPACE