diff -r 5dc02b23752f -r 3e2da88830cd src/gui/text/qtextdocument_p.cpp --- 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; } QListoldCursors = cursors; QT_TRY{ cursors.clear(); - changedCursors.clear(); QMap::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 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