⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qtextdocument_p.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//  	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;}#if !defined(QT_NO_DEBUG)static bool isAncestorFrame(QTextFrame *possibleAncestor, QTextFrame *child){    while (child) {        if (child == possibleAncestor)            return true;        child = child->parentFrame();    }    return false;}#endifvoid QTextDocumentPrivate::remove(int pos, int length, QTextUndoCommand::Operation op){    Q_ASSERT(pos >= 0 && pos+length <= fragments.length());    Q_ASSERT(blocks.length() == fragments.length());#if !defined(QT_NO_DEBUG)    const bool startAndEndInSameFrame = (frameAt(pos) == frameAt(pos + length - 1));    const bool endIsEndOfChildFrame = (isAncestorFrame(frameAt(pos), frameAt(pos + length - 1))                                       && text.at(find(pos + length - 1)->stringPosition) == QTextEndOfFrame);    const bool startIsStartOfFrameAndEndIsEndOfFrameWithCommonParent               = (text.at(find(pos)->stringPosition) == QTextBeginningOfFrame                  && text.at(find(pos + length - 1)->stringPosition) == QTextEndOfFrame                  && frameAt(pos)->parentFrame() == frameAt(pos + length - 1)->parentFrame());    Q_ASSERT(startAndEndInSameFrame || endIsEndOfChildFrame || startIsStartOfFrameAndEndIsEndOfFrameWithCommonParent);#endif    beginEditBlock();    split(pos);    split(pos+length);    uint x = fragments.findNode(pos);    uint end = fragments.findNode(pos+length);    uint w = 0;    while (x != end) {        uint n = fragments.next(x);        uint key = fragments.position(x);        uint b = blocks.findNode(key+1);        QTextFragmentData *X = fragments.fragment(x);        QTextUndoCommand c = { QTextUndoCommand::Removed, true,                          op, X->format, X->stringPosition, key, { X->size } };        if (key+1 != blocks.position(b)) {//	    qDebug("remove_string from %d length %d", key, X->size);            Q_ASSERT(noBlockInString(text.mid(X->stringPosition, X->size)));            w = remove_string(key, X->size, op);        } else {//	    qDebug("remove_block at %d", key);            Q_ASSERT(X->size == 1 && isValidBlockSeparator(text.at(X->stringPosition)));            b = blocks.previous(b);            c.command = blocks.size(b) == 1 ? QTextUndoCommand::BlockDeleted : QTextUndoCommand::BlockRemoved;            w = remove_block(key, &c.blockFormat, QTextUndoCommand::BlockAdded, op);        }        appendUndoItem(c);        x = n;    }    if (w)        unite(w);    Q_ASSERT(blocks.length() == fragments.length());    endEditBlock();}void QTextDocumentPrivate::setCharFormat(int pos, int length, const QTextCharFormat &newFormat, FormatChangeMode mode){    Q_ASSERT(newFormat.isValid());    beginEditBlock();    int newFormatIdx = -1;    if (mode == SetFormat)        newFormatIdx = formats.indexForFormat(newFormat);    if (pos == -1) {        if (mode == MergeFormat) {            QTextFormat format = formats.format(initialBlockCharFormatIndex);            format.merge(newFormat);            initialBlockCharFormatIndex = formats.indexForFormat(format);        } else {            initialBlockCharFormatIndex = newFormatIdx;        }        ++pos;        --length;    }    const int startPos = pos;    const int endPos = pos + length;    split(startPos);    split(endPos);    while (pos < endPos) {        FragmentMap::Iterator it = fragments.find(pos);        Q_ASSERT(!it.atEnd());        QTextFragmentData *fragment = it.value();        Q_ASSERT(formats.format(fragment->format).type() == QTextFormat::CharFormat);        int offset = pos - it.position();        int length = qMin(endPos - pos, int(fragment->size - offset));        int oldFormat = fragment->format;        if (mode == MergeFormat) {            QTextFormat format = formats.format(fragment->format);            format.merge(newFormat);            fragment->format = formats.indexForFormat(format);        } else {            fragment->format = newFormatIdx;        }        QTextUndoCommand c = { QTextUndoCommand::CharFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat,                          0, pos, { length } };        appendUndoItem(c);        pos += length;        Q_ASSERT(pos == (int)(it.position() + fragment->size) || pos >= endPos);    }    int n = fragments.findNode(startPos - 1);    if (n)        unite(n);    n = fragments.findNode(endPos);    if (n)        unite(n);    QTextBlock blockIt = blocksFind(startPos);    QTextBlock endIt = blocksFind(endPos);    if (endIt.isValid())        endIt = endIt.next();    for (; blockIt.isValid() && blockIt != endIt; blockIt = blockIt.next())        QTextDocumentPrivate::block(blockIt)->invalidate();    documentChange(startPos, length);    endEditBlock();}void QTextDocumentPrivate::setBlockFormat(const QTextBlock &from, const QTextBlock &to,				     const QTextBlockFormat &newFormat, FormatChangeMode mode){    beginEditBlock();    Q_ASSERT(newFormat.isValid());    int newFormatIdx = -1;    if (mode == SetFormat)        newFormatIdx = formats.indexForFormat(newFormat);    QTextBlockGroup *group = qobject_cast<QTextBlockGroup *>(objectForFormat(newFormat));    QTextBlock it = from;    QTextBlock end = to;    if (end.isValid())	end = end.next();    for (; it != end; it = it.next()) {        int oldFormat = block(it)->format;        QTextBlockFormat format = formats.blockFormat(oldFormat);        QTextBlockGroup *oldGroup = qobject_cast<QTextBlockGroup *>(objectForFormat(format));        if (mode == MergeFormat) {            format.merge(newFormat);            newFormatIdx = formats.indexForFormat(format);            group = qobject_cast<QTextBlockGroup *>(objectForFormat(format));        }        block(it)->format = newFormatIdx;        block(it)->invalidate();        QTextUndoCommand c = { QTextUndoCommand::BlockFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat,                              0, it.position(), { 1 } };        appendUndoItem(c);        if (group != oldGroup) {            if (oldGroup)                oldGroup->blockRemoved(it);            if (group)                group->blockInserted(it);        } else if (group) {	    group->blockFormatChanged(it);	}    }    documentChange(from.position(), to.position() + to.length() - from.position());    endEditBlock();}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;}void 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;    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;    endEditBlock();    Q_Q(QTextDocument);    emit q->undoAvailable(isUndoAvailable());    emit q->redoAvailable(isRedoAvailable());}/*!    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){    Q_Q(QTextDocument);    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++;    emit q->undoAvailable(true);    emit q->redoAvailable(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;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -