📄 qtextdocument_p.cpp
字号:
} undoStack.resize(undoState);}void QTextDocumentPrivate::enableUndoRedo(bool enable){ Q_Q(QTextDocument); if (!enable) { undoState = 0; truncateUndoStack(); emit q->undoAvailable(false); emit q->redoAvailable(false); } modifiedState = modified ? -1 : undoState; undoEnabled = enable;}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();}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) 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();}QString QTextDocumentPrivate::plainText() const{ QString result; result.reserve(length()); for (QTextDocumentPrivate::FragmentIterator it = begin(); it != end(); ++it) { const QTextFragmentData *f = *it; result += QString::fromRawData(text.unicode() + f->stringPosition, f->size); } // remove trailing block separator result.chop(1); return result;}int QTextDocumentPrivate::blockCharFormatIndex(int node) const{ int pos = blocks.position(node); if (pos == 0) return initialBlockCharFormatIndex; return fragments.find(pos - 1)->format;}int QTextDocumentPrivate::nextCursorPosition(int position, QTextLayout::CursorMode mode) const{ if (position == length()-1) return position; QTextBlock it = blocksFind(position); int start = it.position(); int end = start + it.length() - 1; if (position == end) return end + 1; return it.layout()->nextCursorPosition(position-start, mode) + start;}int QTextDocumentPrivate::previousCursorPosition(int position, QTextLayout::CursorMode mode) const{ if (position == 0) return position; QTextBlock it = blocksFind(position); int start = it.position(); if (position == start) return start - 1; return it.layout()->previousCursorPosition(position-start, mode) + start;}void QTextDocumentPrivate::changeObjectFormat(QTextObject *obj, int format){ beginEditBlock(); int objectIndex = obj->objectIndex(); int oldFormatIndex = formats.objectFormatIndex(objectIndex); formats.setObjectFormatIndex(objectIndex, format); QTextBlockGroup *b = qobject_cast<QTextBlockGroup *>(obj); if (b) { QList<QTextBlock> blocks = b->blockList(); for (int i = 0; i < blocks.size(); ++i) { // invalidate blocks and tell layout const QTextBlock &block = blocks.at(i); documentChange(block.position(), block.length()); } } QTextFrame *f = qobject_cast<QTextFrame *>(obj); if (f) documentChange(f->firstPosition(), f->lastPosition() - f->firstPosition()); QTextUndoCommand c = { QTextUndoCommand::GroupFormatChange, true, QTextUndoCommand::MoveCursor, oldFormatIndex, 0, 0, { obj->d_func()->objectIndex } }; appendUndoItem(c); endEditBlock();}static QTextFrame *findChildFrame(QTextFrame *f, int pos){ // ##### use binary search QList<QTextFrame *> children = f->childFrames(); for (int i = 0; i < children.size(); ++i) { QTextFrame *c = children.at(i); if (pos >= c->firstPosition() && pos <= c->lastPosition()) return c; } return 0;}QTextFrame *QTextDocumentPrivate::frameAt(int pos) const{ QTextFrame *f = frame; while (1) { QTextFrame *c = findChildFrame(f, pos); if (!c) return f; f = c; }}void QTextDocumentPrivate::clearFrame(QTextFrame *f){ for (int i = 0; i < f->d_func()->childFrames.count(); ++i) clearFrame(f->d_func()->childFrames.at(i)); f->d_func()->childFrames.clear(); f->d_func()->parentFrame = 0;}void QTextDocumentPrivate::scan_frames(int pos, int charsRemoved, int charsAdded){ // ###### optimise Q_UNUSED(pos); Q_UNUSED(charsRemoved); Q_UNUSED(charsAdded); QTextFrame *f = frame; clearFrame(f); for (FragmentIterator it = begin(); it != end(); ++it) { // QTextFormat fmt = formats.format(it->format); QTextFrame *frame = qobject_cast<QTextFrame *>(objectForFormat(it->format)); if (!frame) continue; Q_ASSERT(it.size() == 1); QChar ch = text.at(it->stringPosition); if (ch == QTextBeginningOfFrame) { if (f != frame) { // f == frame happens for tables Q_ASSERT(frame->d_func()->fragment_start == it.n || frame->d_func()->fragment_start == 0); frame->d_func()->parentFrame = f; f->d_func()->childFrames.append(frame); f = frame; } } else if (ch == QTextEndOfFrame) { Q_ASSERT(f == frame); Q_ASSERT(frame->d_func()->fragment_end == it.n || frame->d_func()->fragment_end == 0); f = frame->d_func()->parentFrame; } else if (ch == QChar::ObjectReplacementCharacter) { Q_ASSERT(f != frame); Q_ASSERT(frame->d_func()->fragment_start == it.n || frame->d_func()->fragment_start == 0); Q_ASSERT(frame->d_func()->fragment_end == it.n || frame->d_func()->fragment_end == 0); frame->d_func()->parentFrame = f; f->d_func()->childFrames.append(frame); } else { Q_ASSERT(false); } } Q_ASSERT(f == frame); framesDirty = false;}void QTextDocumentPrivate::insert_frame(QTextFrame *f){ int start = f->firstPosition(); int end = f->lastPosition(); QTextFrame *parent = frameAt(start-1); Q_ASSERT(parent == frameAt(end+1)); if (start != end) { // iterator over the parent and move all children contained in my frame to myself for (int i = 0; i < parent->d_func()->childFrames.size(); ++i) { QTextFrame *c = parent->d_func()->childFrames.at(i); if (start < c->firstPosition() && end > c->lastPosition()) { parent->d_func()->childFrames.removeAt(i); f->d_func()->childFrames.append(c); c->d_func()->parentFrame = f; } } } // insert at the correct position int i = 0; for (; i < parent->d_func()->childFrames.size(); ++i) { QTextFrame *c = parent->d_func()->childFrames.at(i); if (c->firstPosition() > end) break; } parent->d_func()->childFrames.insert(i, f); f->d_func()->parentFrame = parent;}QTextFrame *QTextDocumentPrivate::insertFrame(int start, int end, const QTextFrameFormat &format){ Q_ASSERT(start >= 0 && start < length()); Q_ASSERT(end >= 0 && end < length()); Q_ASSERT(start <= end || end == -1); if (start != end && frameAt(start) != frameAt(end)) return 0; beginEditBlock(); QTextFrame *frame = qobject_cast<QTextFrame *>(createObject(format)); Q_ASSERT(frame); // #### using the default block and char format below might be wrong int idx = formats.indexForFormat(QTextBlockFormat()); QTextCharFormat cfmt; cfmt.setObjectIndex(frame->objectIndex()); int charIdx = formats.indexForFormat(cfmt); insertBlock(QTextBeginningOfFrame, start, idx, charIdx, QTextUndoCommand::MoveCursor); insertBlock(QTextEndOfFrame, ++end, idx, charIdx, QTextUndoCommand::KeepCursor); frame->d_func()->fragment_start = find(start).n; frame->d_func()->fragment_end = find(end).n; insert_frame(frame); endEditBlock(); return frame;}void QTextDocumentPrivate::removeFrame(QTextFrame *frame){ QTextFrame *parent = frame->d_func()->parentFrame; if (!parent) return; int start = frame->firstPosition(); int end = frame->lastPosition(); Q_ASSERT(end >= start); beginEditBlock(); // remove already removes the frames from the tree remove(end, 1); remove(start-1, 1); endEditBlock();}QTextObject *QTextDocumentPrivate::objectForIndex(int objectIndex) const{ if (objectIndex < 0) return 0; QTextObject *object = objects.value(objectIndex, 0); if (!object) { QTextDocumentPrivate *that = const_cast<QTextDocumentPrivate *>(this); QTextFormat fmt = formats.objectFormat(objectIndex); object = that->createObject(fmt, objectIndex); } return object;}QTextObject *QTextDocumentPrivate::objectForFormat(int formatIndex) const{ int objectIndex = formats.format(formatIndex).objectIndex(); return objectForIndex(objectIndex);}QTextObject *QTextDocumentPrivate::objectForFormat(const QTextFormat &f) const{ return objectForIndex(f.objectIndex());}QTextObject *QTextDocumentPrivate::createObject(const QTextFormat &f, int objectIndex){ QTextObject *obj = document()->createObject(f); if (obj) { obj->d_func()->pieceTable = this; obj->d_func()->objectIndex = objectIndex == -1 ? formats.createObjectIndex(f) : objectIndex; objects[obj->d_func()->objectIndex] = obj; } return obj;}void QTextDocumentPrivate::deleteObject(QTextObject *object){ const int objIdx = object->d_func()->objectIndex; objects.remove(objIdx); delete object;}void QTextDocumentPrivate::contentsChanged(){ Q_Q(QTextDocument); if (editBlock) return; bool m = undoEnabled ? (modifiedState != undoState) : true; if (modified != m) { modified = m; emit q->modificationChanged(modified); } emit q->contentsChanged();}void QTextDocumentPrivate::setModified(bool m){ Q_Q(QTextDocument); if (m == modified) return; modified = m; if (!modified) modifiedState = undoState; else modifiedState = -1; emit q->modificationChanged(modified);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -