void QTextFramePrivate::remove_me() { Q_Q(QTextFrame); if (fragment_start == 0 && fragment_end == 0 && !parentFrame) { q->document()->docHandle()->deleteObject(q); return; } if (!parentFrame) return; int index = parentFrame->d_func()->childFrames.indexOf(q); // iterator over all children and move them to the parent for (int i = 0; i < childFrames.size(); ++i) { QTextFrame *c = childFrames.at(i); parentFrame->d_func()->childFrames.insert(index, c); c->d_func()->parentFrame = parentFrame; ++index; } Q_ASSERT(parentFrame->d_func()->childFrames.at(index) == q); parentFrame->d_func()->childFrames.removeAt(index); childFrames.clear(); parentFrame = 0; }
int QTextDocumentPrivate::remove_string(int pos, uint length, QTextUndoCommand::Operation op) { Q_ASSERT(pos >= 0); Q_ASSERT(blocks.length() == fragments.length()); Q_ASSERT(blocks.length() >= pos+(int)length); int b = blocks.findNode(pos); uint x = fragments.findNode(pos); Q_ASSERT(blocks.size(b) > length); Q_ASSERT(x && fragments.position(x) == (uint)pos && fragments.size(x) == length); Q_ASSERT(noBlockInString(text.mid(fragments.fragment(x)->stringPosition, length))); blocks.setSize(b, blocks.size(b)-length); QTextFrame *frame = qobject_cast<QTextFrame *>(objectForFormat(fragments.fragment(x)->format)); if (frame) { frame->d_func()->fragmentRemoved(text.at(fragments.fragment(x)->stringPosition), x); framesDirty = true; } const int w = fragments.erase_single(x); if (!undoEnabled) unreachableCharacterCount += length; adjustDocumentChangesAndCursors(pos, -int(length), op); return w; }
void QTextDocumentPrivate::insert_string(int pos, uint strPos, uint length, int format, QTextUndoCommand::Operation op) { // ##### optimise when only appending to the fragment! Q_ASSERT(noBlockInString(text.mid(strPos, length))); split(pos); uint x = fragments.insert_single(pos, length); QTextFragmentData *X = fragments.fragment(x); X->format = format; X->stringPosition = strPos; uint w = fragments.previous(x); if (w) unite(w); int b = blocks.findNode(pos); blocks.setSize(b, blocks.size(b)+length); Q_ASSERT(blocks.length() == fragments.length()); QTextFrame *frame = qobject_cast<QTextFrame *>(objectForFormat(format)); if (frame) { frame->d_func()->fragmentAdded(text.at(strPos), x); framesDirty = true; } adjustDocumentChangesAndCursors(pos, length, op); }
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::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; }
int QTextDocumentPrivate::remove_block(int pos, int *blockFormat, int command, QTextUndoCommand::Operation op) { Q_ASSERT(pos >= 0); Q_ASSERT(blocks.length() == fragments.length()); Q_ASSERT(blocks.length() > pos); int b = blocks.findNode(pos); uint x = fragments.findNode(pos); Q_ASSERT(x && (int)fragments.position(x) == pos); Q_ASSERT(fragments.size(x) == 1); Q_ASSERT(isValidBlockSeparator(text.at(fragments.fragment(x)->stringPosition))); Q_ASSERT(b); if (blocks.size(b) == 1 && command == QTextUndoCommand::BlockAdded) { Q_ASSERT((int)blocks.position(b) == pos); // qDebug("removing empty block"); // empty block remove the block itself } else { // non empty block, merge with next one into this block // qDebug("merging block with next"); int n = blocks.next(b); Q_ASSERT((int)blocks.position(n) == pos + 1); blocks.setSize(b, blocks.size(b) + blocks.size(n) - 1); b = n; } *blockFormat = blocks.fragment(b)->format; QTextBlockGroup *group = qobject_cast<QTextBlockGroup *>(objectForFormat(blocks.fragment(b)->format)); if (group) group->blockRemoved(QTextBlock(this, b)); QTextFrame *frame = qobject_cast<QTextFrame *>(objectForFormat(fragments.fragment(x)->format)); if (frame) { frame->d_func()->fragmentRemoved(text.at(fragments.fragment(x)->stringPosition), x); framesDirty = true; } blocks.erase_single(b); const int w = fragments.erase_single(x); adjustDocumentChangesAndCursors(pos, -1, op); return w; }
int QTextDocumentPrivate::insert_block(int pos, uint strPos, int format, int blockFormat, QTextUndoCommand::Operation op, int command) { split(pos); uint x = fragments.insert_single(pos, 1); QTextFragmentData *X = fragments.fragment(x); X->format = format; X->stringPosition = strPos; // no need trying to unite, since paragraph separators are always in a fragment of their own Q_ASSERT(isValidBlockSeparator(text.at(strPos))); Q_ASSERT(blocks.length()+1 == fragments.length()); int block_pos = pos; if (blocks.length() && command == QTextUndoCommand::BlockRemoved) ++block_pos; int size = 1; int n = blocks.findNode(block_pos); int key = n ? blocks.position(n) : blocks.length(); Q_ASSERT(n || (!n && block_pos == blocks.length())); if (key != block_pos) { Q_ASSERT(key < block_pos); int oldSize = blocks.size(n); blocks.setSize(n, block_pos-key); size += oldSize - (block_pos-key); } int b = blocks.insert_single(block_pos, size); QTextBlockData *B = blocks.fragment(b); B->format = blockFormat; Q_ASSERT(blocks.length() == fragments.length()); QTextBlockGroup *group = qobject_cast<QTextBlockGroup *>(objectForFormat(blockFormat)); if (group) group->blockInserted(QTextBlock(this, b)); QTextFrame *frame = qobject_cast<QTextFrame *>(objectForFormat(formats.format(format))); if (frame) { frame->d_func()->fragmentAdded(text.at(strPos), x); framesDirty = true; } adjustDocumentChangesAndCursors(pos, 1, op); return x; }
void QTextDocumentPrivate::scan_frames(int pos, int charsRemoved, int charsAdded) { // ###### optimise Q_UNUSED(pos); Q_UNUSED(charsRemoved); Q_UNUSED(charsAdded); QTextFrame *f = rootFrame(); 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 == rtFrame); framesDirty = false; }