src/gui/text/qtextdocument_p.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
   190     framesDirty(true),
   190     framesDirty(true),
   191     rtFrame(0),
   191     rtFrame(0),
   192     initialBlockCharFormatIndex(-1) // set correctly later in init()
   192     initialBlockCharFormatIndex(-1) // set correctly later in init()
   193 {
   193 {
   194     editBlock = 0;
   194     editBlock = 0;
       
   195     editBlockCursorPosition = -1;
   195     docChangeFrom = -1;
   196     docChangeFrom = -1;
   196 
   197 
   197     undoState = 0;
   198     undoState = 0;
   198     revision = -1; // init() inserts a block, bringing it to 0
   199     revision = -1; // init() inserts a block, bringing it to 0
   199 
   200 
   202     modified = false;
   203     modified = false;
   203     modifiedState = 0;
   204     modifiedState = 0;
   204 
   205 
   205     undoEnabled = true;
   206     undoEnabled = true;
   206     inContentsChange = false;
   207     inContentsChange = false;
       
   208     blockCursorAdjustment = false;
   207 
   209 
   208     defaultTextOption.setTabStop(80); // same as in qtextengine.cpp
   210     defaultTextOption.setTabStop(80); // same as in qtextengine.cpp
   209     defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
   211     defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
   210 
   212 
   211     indentWidth = 40;
   213     indentWidth = 40;
   231 }
   233 }
   232 
   234 
   233 void QTextDocumentPrivate::clear()
   235 void QTextDocumentPrivate::clear()
   234 {
   236 {
   235     Q_Q(QTextDocument);
   237     Q_Q(QTextDocument);
   236     for (int i = 0; i < cursors.count(); ++i) {
   238 
   237         cursors.at(i)->setPosition(0);
   239     foreach (QTextCursorPrivate *curs, cursors) {
   238         cursors.at(i)->currentCharFormat = -1;
   240         curs->setPosition(0);
   239         cursors.at(i)->anchor = 0;
   241         curs->currentCharFormat = -1;
   240         cursors.at(i)->adjusted_anchor = 0;
   242         curs->anchor = 0;
       
   243         curs->adjusted_anchor = 0;
   241     }
   244     }
   242 
   245 
   243     QList<QTextCursorPrivate *>oldCursors = cursors;
   246     QList<QTextCursorPrivate *>oldCursors = cursors;
   244     QT_TRY{
   247     QT_TRY{
   245         cursors.clear();
   248         cursors.clear();
   246         changedCursors.clear();
       
   247 
   249 
   248         QMap<int, QTextObject *>::Iterator objectIt = objects.begin();
   250         QMap<int, QTextObject *>::Iterator objectIt = objects.begin();
   249         while (objectIt != objects.end()) {
   251         while (objectIt != objects.end()) {
   250             if (*objectIt != rtFrame) {
   252             if (*objectIt != rtFrame) {
   251                 delete *objectIt;
   253                 delete *objectIt;
   284     }
   286     }
   285 }
   287 }
   286 
   288 
   287 QTextDocumentPrivate::~QTextDocumentPrivate()
   289 QTextDocumentPrivate::~QTextDocumentPrivate()
   288 {
   290 {
   289     for (int i = 0; i < cursors.count(); ++i)
   291     foreach (QTextCursorPrivate *curs, cursors)
   290         cursors.at(i)->priv = 0;
   292         curs->priv = 0;
   291     cursors.clear();
   293     cursors.clear();
   292     undoState = 0;
   294     undoState = 0;
   293     undoEnabled = true;
   295     undoEnabled = true;
   294     clearUndoRedoStacks(QTextDocument::RedoStack);
   296     clearUndoRedoStacks(QTextDocument::RedoStack);
   295 }
   297 }
   666 
   668 
   667 void QTextDocumentPrivate::remove(int pos, int length, QTextUndoCommand::Operation op)
   669 void QTextDocumentPrivate::remove(int pos, int length, QTextUndoCommand::Operation op)
   668 {
   670 {
   669     if (length == 0)
   671     if (length == 0)
   670         return;
   672         return;
       
   673     blockCursorAdjustment = true;
   671     move(pos, -1, length, op);
   674     move(pos, -1, length, op);
       
   675     blockCursorAdjustment = false;
       
   676     foreach (QTextCursorPrivate *curs, cursors) {
       
   677         if (curs->adjustPosition(pos, -length, op) == QTextCursorPrivate::CursorMoved) {
       
   678             curs->changed = true;
       
   679         }
       
   680     }
   672 }
   681 }
   673 
   682 
   674 void QTextDocumentPrivate::setCharFormat(int pos, int length, const QTextCharFormat &newFormat, FormatChangeMode mode)
   683 void QTextDocumentPrivate::setCharFormat(int pos, int length, const QTextCharFormat &newFormat, FormatChangeMode mode)
   675 {
   684 {
   676     beginEditBlock();
   685     beginEditBlock();
   965             changeObjectFormat(object, c.format);
   974             changeObjectFormat(object, c.format);
   966             c.format = oldFormat;
   975             c.format = oldFormat;
   967             editPos = -1;
   976             editPos = -1;
   968 	    break;
   977 	    break;
   969 	}
   978 	}
       
   979         case QTextUndoCommand::CursorMoved:
       
   980             editPos = c.pos;
       
   981             editLength = 0;
       
   982             break;
   970 	case QTextUndoCommand::Custom:
   983 	case QTextUndoCommand::Custom:
   971             resetBlockRevision = -1; // ## TODO
   984             resetBlockRevision = -1; // ## TODO
   972             if (undo)
   985             if (undo)
   973                 c.custom->undo();
   986                 c.custom->undo();
   974             else
   987             else
  1043     PMDEBUG("appendUndoItem, command=%d enabled=%d", c.command, undoEnabled);
  1056     PMDEBUG("appendUndoItem, command=%d enabled=%d", c.command, undoEnabled);
  1044     if (!undoEnabled)
  1057     if (!undoEnabled)
  1045         return;
  1058         return;
  1046     if (undoState < undoStack.size())
  1059     if (undoState < undoStack.size())
  1047         clearUndoRedoStacks(QTextDocument::RedoStack);
  1060         clearUndoRedoStacks(QTextDocument::RedoStack);
       
  1061 
       
  1062     if (editBlock != 0 && editBlockCursorPosition >= 0) { // we had a beginEditBlock() with a cursor position
       
  1063         if (c.pos != (quint32) editBlockCursorPosition) { // and that cursor position is different from the command
       
  1064             // generate a CursorMoved undo item
       
  1065             QT_INIT_TEXTUNDOCOMMAND(cc, QTextUndoCommand::CursorMoved, true, QTextUndoCommand::MoveCursor,
       
  1066                                     0, 0, editBlockCursorPosition, 0, 0);
       
  1067             undoStack.append(cc);
       
  1068             undoState++;
       
  1069             editBlockCursorPosition = -1;
       
  1070         }
       
  1071     }
       
  1072 
  1048 
  1073 
  1049     if (!undoStack.isEmpty() && modified) {
  1074     if (!undoStack.isEmpty() && modified) {
  1050         QTextUndoCommand &last = undoStack[undoState - 1];
  1075         QTextUndoCommand &last = undoStack[undoState - 1];
  1051 
  1076 
  1052         if ( (last.block_part && c.block_part && !last.block_end) // part of the same block => can merge
  1077         if ( (last.block_part && c.block_part && !last.block_end) // part of the same block => can merge
  1165             if (wasBlocking)
  1190             if (wasBlocking)
  1166                 emit document()->undoCommandAdded();
  1191                 emit document()->undoCommandAdded();
  1167         }
  1192         }
  1168     }
  1193     }
  1169 
  1194 
       
  1195     editBlockCursorPosition = -1;
       
  1196 
  1170     finishEdit();
  1197     finishEdit();
  1171 }
  1198 }
  1172 
  1199 
  1173 void QTextDocumentPrivate::finishEdit()
  1200 void QTextDocumentPrivate::finishEdit()
  1174 {
  1201 {
  1200             // to prevent getting two contentsChanged emits
  1227             // to prevent getting two contentsChanged emits
  1201             return;
  1228             return;
  1202         }
  1229         }
  1203     }
  1230     }
  1204 
  1231 
  1205     while (!changedCursors.isEmpty()) {
  1232     QList<QTextCursor> changedCursors;
  1206         QTextCursorPrivate *curs = changedCursors.takeFirst();
  1233     foreach (QTextCursorPrivate *curs, cursors) {
  1207         emit q->cursorPositionChanged(QTextCursor(curs));
  1234         if (curs->changed) {
  1208     }
  1235             curs->changed = false;
       
  1236             changedCursors.append(QTextCursor(curs));
       
  1237         }
       
  1238     }
       
  1239     foreach (const QTextCursor &cursor, changedCursors)
       
  1240         emit q->cursorPositionChanged(cursor);
  1209 
  1241 
  1210     contentsChanged();
  1242     contentsChanged();
  1211 
  1243 
  1212     if (blocks.numNodes() != lastBlockCount) {
  1244     if (blocks.numNodes() != lastBlockCount) {
  1213         lastBlockCount = blocks.numNodes();
  1245         lastBlockCount = blocks.numNodes();
  1245 void QTextDocumentPrivate::adjustDocumentChangesAndCursors(int from, int addedOrRemoved, QTextUndoCommand::Operation op)
  1277 void QTextDocumentPrivate::adjustDocumentChangesAndCursors(int from, int addedOrRemoved, QTextUndoCommand::Operation op)
  1246 {
  1278 {
  1247     if (!editBlock)
  1279     if (!editBlock)
  1248         ++revision;
  1280         ++revision;
  1249 
  1281 
  1250     for (int i = 0; i < cursors.size(); ++i) {
  1282     if (blockCursorAdjustment)  {
  1251         QTextCursorPrivate *curs = cursors.at(i);
  1283         ; // postpone, will be called again from QTextDocumentPrivate::remove()
  1252         if (curs->adjustPosition(from, addedOrRemoved, op) == QTextCursorPrivate::CursorMoved) {
  1284     } else {
  1253             if (!changedCursors.contains(curs))
  1285         foreach (QTextCursorPrivate *curs, cursors) {
  1254                 changedCursors.append(curs);
  1286             if (curs->adjustPosition(from, addedOrRemoved, op) == QTextCursorPrivate::CursorMoved) {
       
  1287                 curs->changed = true;
       
  1288             }
  1255         }
  1289         }
  1256     }
  1290     }
  1257 
  1291 
  1258 //     qDebug("QTextDocumentPrivate::adjustDocumentChanges: from=%d,addedOrRemoved=%d", from, addedOrRemoved);
  1292 //     qDebug("QTextDocumentPrivate::adjustDocumentChanges: from=%d,addedOrRemoved=%d", from, addedOrRemoved);
  1259     if (docChangeFrom < 0) {
  1293     if (docChangeFrom < 0) {
  1613     newText.resize(text.size());
  1647     newText.resize(text.size());
  1614     QChar *newTextPtr = newText.data();
  1648     QChar *newTextPtr = newText.data();
  1615     int newLen = 0;
  1649     int newLen = 0;
  1616 
  1650 
  1617     for (FragmentMap::Iterator it = fragments.begin(); !it.atEnd(); ++it) {
  1651     for (FragmentMap::Iterator it = fragments.begin(); !it.atEnd(); ++it) {
  1618         qMemCopy(newTextPtr, text.constData() + it->stringPosition, it->size_array[0] * sizeof(QChar));
  1652         memcpy(newTextPtr, text.constData() + it->stringPosition, it->size_array[0] * sizeof(QChar));
  1619         it->stringPosition = newLen;
  1653         it->stringPosition = newLen;
  1620         newTextPtr += it->size_array[0];
  1654         newTextPtr += it->size_array[0];
  1621         newLen += it->size_array[0];
  1655         newLen += it->size_array[0];
  1622     }
  1656     }
  1623 
  1657 
  1672 
  1706 
  1673 /// This method is called from QTextTable when it is about to remove a table-cell to allow cursors to update their selection.
  1707 /// This method is called from QTextTable when it is about to remove a table-cell to allow cursors to update their selection.
  1674 void QTextDocumentPrivate::aboutToRemoveCell(int from, int to)
  1708 void QTextDocumentPrivate::aboutToRemoveCell(int from, int to)
  1675 {
  1709 {
  1676     Q_ASSERT(from <= to);
  1710     Q_ASSERT(from <= to);
  1677     for (int i = 0; i < cursors.size(); ++i)
  1711     foreach (QTextCursorPrivate *curs, cursors)
  1678         cursors.at(i)->aboutToRemoveCell(from, to);
  1712         curs->aboutToRemoveCell(from, to);
  1679 }
  1713 }
  1680 
  1714 
  1681 QT_END_NAMESPACE
  1715 QT_END_NAMESPACE