📄 qtextdocument_p.cpp
字号:
}bool QTextDocumentPrivate::split(int pos){ uint x = fragments.findNode(pos); if (x) { int k = fragments.position(x);// qDebug("found fragment with key %d, size_left=%d, size=%d to split at %d",// k, (*it)->size_left, (*it)->size, pos); if (k != pos) { Q_ASSERT(k <= pos); // need to resize the first fragment and add a new one QTextFragmentData *X = fragments.fragment(x); int oldsize = X->size; fragments.setSize(x, pos-k); uint n = fragments.insert_single(pos, oldsize-(pos-k)); X = fragments.fragment(x); QTextFragmentData *N = fragments.fragment(n); N->stringPosition = X->stringPosition + pos-k; N->format = X->format; return true; } } return false;}bool QTextDocumentPrivate::unite(uint f){ uint n = fragments.next(f); if (!n) return false; QTextFragmentData *ff = fragments.fragment(f); QTextFragmentData *nf = fragments.fragment(n); if (nf->format == ff->format && (ff->stringPosition + (int)ff->size == nf->stringPosition)) { if (isValidBlockSeparator(text.at(ff->stringPosition)) || isValidBlockSeparator(text.at(nf->stringPosition))) return false; fragments.setSize(f, ff->size + nf->size); fragments.erase_single(n); return true; } return false;}int QTextDocumentPrivate::undoRedo(bool undo){ PMDEBUG("%s, undoState=%d, undoStack size=%d", undo ? "undo:" : "redo:", undoState, undoStack.size()); if (!undoEnabled || (undo && undoState == 0) || (!undo && undoState == undoStack.size())) return -1; undoEnabled = false; beginEditBlock(); while (1) { if (undo) --undoState; QTextUndoCommand &c = undoStack[undoState]; switch(c.command) { case QTextUndoCommand::Inserted: remove(c.pos, c.length, (QTextUndoCommand::Operation)c.operation); PMDEBUG(" erase: from %d, length %d", c.pos, c.length); c.command = QTextUndoCommand::Removed; break; case QTextUndoCommand::Removed: PMDEBUG(" insert: format %d (from %d, length %d, strpos=%d)", c.format, c.pos, c.length, c.strPos); insert_string(c.pos, c.strPos, c.length, c.format, (QTextUndoCommand::Operation)c.operation); c.command = QTextUndoCommand::Inserted; break; case QTextUndoCommand::BlockInserted: case QTextUndoCommand::BlockAdded: remove_block(c.pos, &c.blockFormat, c.command, (QTextUndoCommand::Operation)c.operation); PMDEBUG(" blockremove: from %d", c.pos); if (c.command == QTextUndoCommand::BlockInserted) c.command = QTextUndoCommand::BlockRemoved; else c.command = QTextUndoCommand::BlockDeleted; break; case QTextUndoCommand::BlockRemoved: case QTextUndoCommand::BlockDeleted: PMDEBUG(" blockinsert: charformat %d blockformat %d (pos %d, strpos=%d)", c.format, c.blockFormat, c.pos, c.strPos); insert_block(c.pos, c.strPos, c.format, c.blockFormat, (QTextUndoCommand::Operation)c.operation, c.command); if (c.command == QTextUndoCommand::BlockRemoved) c.command = QTextUndoCommand::BlockInserted; else c.command = QTextUndoCommand::BlockAdded; break; case QTextUndoCommand::CharFormatChanged: { PMDEBUG(" charFormat: format %d (from %d, length %d)", c.format, c.pos, c.length); FragmentIterator it = find(c.pos); Q_ASSERT(!it.atEnd()); int oldFormat = it.value()->format; setCharFormat(c.pos, c.length, formats.charFormat(c.format)); c.format = oldFormat; break; } case QTextUndoCommand::BlockFormatChanged: { PMDEBUG(" blockformat: format %d pos %d", c.format, c.pos); QTextBlock it = blocksFind(c.pos); Q_ASSERT(it.isValid()); int oldFormat = block(it)->format; block(it)->format = c.format; QTextBlockGroup *oldGroup = qobject_cast<QTextBlockGroup *>(objectForFormat(formats.blockFormat(oldFormat))); QTextBlockGroup *group = qobject_cast<QTextBlockGroup *>(objectForFormat(formats.blockFormat(c.format))); c.format = oldFormat; if (group != oldGroup) { if (oldGroup) oldGroup->blockRemoved(it); if (group) group->blockInserted(it); } else if (group) { group->blockFormatChanged(it); } documentChange(it.position(), it.length()); break; } case QTextUndoCommand::GroupFormatChange: { PMDEBUG(" group format change"); QTextObject *object = objectForIndex(c.objectIndex); int oldFormat = formats.objectFormatIndex(c.objectIndex); changeObjectFormat(object, c.format); c.format = oldFormat; break; } case QTextUndoCommand::Custom: if (undo) c.custom->undo(); else c.custom->redo(); break; default: Q_ASSERT(false); } if (undo) { if (undoState == 0 || !undoStack[undoState-1].block) break; } else { ++undoState; if (undoState == undoStack.size() || !undoStack[undoState-1].block) break; } } undoEnabled = true; int editPos = -1; if (docChangeFrom >= 0) { editPos = qMin(docChangeFrom + docChangeLength, length() - 1); } endEditBlock(); emitUndoAvailable(isUndoAvailable()); emitRedoAvailable(isRedoAvailable()); return editPos;}/*! Appends a custom undo \a item to the undo stack.*/void QTextDocumentPrivate::appendUndoItem(QAbstractUndoItem *item){ if (!undoEnabled) { delete item; return; } QTextUndoCommand c; c.command = QTextUndoCommand::Custom; c.block = editBlock != 0; c.operation = QTextUndoCommand::MoveCursor; c.format = 0; c.strPos = 0; c.pos = 0; c.blockFormat = 0; c.custom = item; appendUndoItem(c);}void QTextDocumentPrivate::appendUndoItem(const QTextUndoCommand &c){ PMDEBUG("appendUndoItem, command=%d enabled=%d", c.command, undoEnabled); if (!undoEnabled) return; if (undoState < undoStack.size()) truncateUndoStack(); if (!undoStack.isEmpty() && modified) { QTextUndoCommand &last = undoStack[undoState - 1]; if (last.tryMerge(c)) return; } undoStack.append(c); undoState++; emitUndoAvailable(true); emitRedoAvailable(false);}void QTextDocumentPrivate::truncateUndoStack() { if (undoState == undoStack.size()) return; for (int i = undoState; i < undoStack.size(); ++i) { QTextUndoCommand c = undoStack[i]; if (c.command & QTextUndoCommand::Removed) { // ########// QTextFragment *f = c.fragment_list;// while (f) {// QTextFragment *n = f->right;// delete f;// f = n;// } } else if (c.command & QTextUndoCommand::Custom) { delete c.custom; } } undoStack.resize(undoState);}void QTextDocumentPrivate::emitUndoAvailable(bool available){ if (available != wasUndoAvailable) { Q_Q(QTextDocument); emit q->undoAvailable(available); wasUndoAvailable = available; }}void QTextDocumentPrivate::emitRedoAvailable(bool available){ if (available != wasRedoAvailable) { Q_Q(QTextDocument); emit q->redoAvailable(available); wasRedoAvailable = available; }}void QTextDocumentPrivate::enableUndoRedo(bool enable){ if (!enable) { undoState = 0; truncateUndoStack(); emitUndoAvailable(false); emitRedoAvailable(false); } modifiedState = modified ? -1 : undoState; undoEnabled = enable; if (!undoEnabled) compressPieceTable();}void QTextDocumentPrivate::joinPreviousEditBlock(){ beginEditBlock(); if (undoEnabled && undoState) undoStack[undoState - 1].block = true;}void QTextDocumentPrivate::endEditBlock(){ Q_Q(QTextDocument); if (--editBlock) return; if (undoEnabled && undoState > 0) undoStack[undoState - 1].block = false; if (framesDirty) scan_frames(docChangeFrom, docChangeOldLength, docChangeLength); if (lout && docChangeFrom >= 0) { if (!inContentsChange) { inContentsChange = true; emit q->contentsChange(docChangeFrom, docChangeOldLength, docChangeLength); inContentsChange = false; } lout->documentChanged(docChangeFrom, docChangeOldLength, docChangeLength); } docChangeFrom = -1; while (!changedCursors.isEmpty()) { QTextCursorPrivate *curs = changedCursors.takeFirst(); emit q->cursorPositionChanged(QTextCursor(curs)); } contentsChanged(); if (blocks.numNodes() != lastBlockCount) { lastBlockCount = blocks.numNodes(); emit q->blockCountChanged(lastBlockCount); } if (!undoEnabled && unreachableCharacterCount) compressPieceTable();}void QTextDocumentPrivate::documentChange(int from, int length){// qDebug("QTextDocumentPrivate::documentChange: from=%d,length=%d", from, length); if (docChangeFrom < 0) { docChangeFrom = from; docChangeOldLength = length; docChangeLength = length; return; } int start = qMin(from, docChangeFrom); int end = qMax(from + length, docChangeFrom + docChangeLength); int diff = qMax(0, end - start - docChangeLength); docChangeFrom = start; docChangeOldLength += diff; docChangeLength += diff;}void QTextDocumentPrivate::adjustDocumentChangesAndCursors(int from, int addedOrRemoved, QTextUndoCommand::Operation op){ Q_Q(QTextDocument); for (int i = 0; i < cursors.size(); ++i) { QTextCursorPrivate *curs = cursors.at(i); if (curs->adjustPosition(from, addedOrRemoved, op) == QTextCursorPrivate::CursorMoved) { if (editBlock) { if (!changedCursors.contains(curs)) changedCursors.append(curs); } else { emit q->cursorPositionChanged(QTextCursor(curs)); } } }// qDebug("QTextDocumentPrivate::adjustDocumentChanges: from=%d,addedOrRemoved=%d", from, addedOrRemoved); if (docChangeFrom < 0) { docChangeFrom = from; if (addedOrRemoved > 0) { docChangeOldLength = 0; docChangeLength = addedOrRemoved; } else { docChangeOldLength = -addedOrRemoved; docChangeLength = 0; }// qDebug("adjustDocumentChanges:");// qDebug(" -> %d %d %d", docChangeFrom, docChangeOldLength, docChangeLength); contentsChanged(); return; } // have to merge the new change with the already existing one. int added = qMax(0, addedOrRemoved); int removed = qMax(0, -addedOrRemoved); int diff = 0; if(from + removed < docChangeFrom) diff = docChangeFrom - from - removed; else if(from > docChangeFrom + docChangeLength) diff = from - (docChangeFrom + docChangeLength); int overlap_start = qMax(from, docChangeFrom); int overlap_end = qMin(from + removed, docChangeFrom + docChangeLength); int removedInside = qMax(0, overlap_end - overlap_start); removed -= removedInside;// qDebug("adjustDocumentChanges: from=%d, addedOrRemoved=%d, diff=%d, removedInside=%d", from, addedOrRemoved, diff, removedInside); docChangeFrom = qMin(docChangeFrom, from); docChangeOldLength += removed + diff; docChangeLength += added - removedInside + diff;// qDebug(" -> %d %d %d", docChangeFrom, docChangeOldLength, docChangeLength); contentsChanged();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -