diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2016-07-05 16:27:22 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2018-02-02 08:49:45 +0000 |
commit | 4939f4dd65ea28268656682ffa1378a9697fe5ac (patch) | |
tree | 96b2b779005c65db846ac463b1134effbe7b3d5b /src/quick/items/qquicktextedit.cpp | |
parent | c260d3062de83d7f051e531007771455915285e5 (diff) |
QQuickTextEdit: Simplify node handling
We don't need to manually manage pointers to nodes as QList can do
that for us.
Change-Id: I0185db2d5909178b3e36c8d1b7921bdbb1858ca6
Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/quick/items/qquicktextedit.cpp')
-rw-r--r-- | src/quick/items/qquicktextedit.cpp | 74 |
1 files changed, 40 insertions, 34 deletions
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 8f3a8998f5..f8363b1e5a 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -1968,12 +1968,11 @@ void QQuickTextEdit::triggerPreprocess() } typedef QQuickTextEditPrivate::Node TextNode; -typedef QList<TextNode*>::iterator TextNodeIterator; +using TextNodeIterator = QQuickTextEditPrivate::TextNodeIterator; - -static bool comesBefore(TextNode* n1, TextNode* n2) +static inline bool operator<(const TextNode &n1, const TextNode &n2) { - return n1->startPos() < n2->startPos(); + return n1.startPos() < n2.startPos(); } static inline void updateNodeTransform(QQuickTextNode* node, const QPointF &topLeft) @@ -2026,13 +2025,12 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * if (!oldNode) { // If we had any QQuickTextNode node references, they were deleted along with the root node // But here we must delete the Node structures in textNodeMap - qDeleteAll(d->textNodeMap); d->textNodeMap.clear(); } RootNode *rootNode = static_cast<RootNode *>(oldNode); TextNodeIterator nodeIterator = d->textNodeMap.begin(); - while (nodeIterator != d->textNodeMap.end() && !(*nodeIterator)->dirty()) + while (nodeIterator != d->textNodeMap.end() && !nodeIterator->dirty()) ++nodeIterator; QQuickTextNodeEngine engine; @@ -2045,13 +2043,12 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * int firstDirtyPos = 0; if (nodeIterator != d->textNodeMap.end()) { - firstDirtyPos = (*nodeIterator)->startPos(); + firstDirtyPos = nodeIterator->startPos(); do { - rootNode->removeChildNode((*nodeIterator)->textNode()); - delete (*nodeIterator)->textNode(); - delete *nodeIterator; + rootNode->removeChildNode(nodeIterator->textNode()); + delete nodeIterator->textNode(); nodeIterator = d->textNodeMap.erase(nodeIterator); - } while (nodeIterator != d->textNodeMap.end() && (*nodeIterator)->dirty()); + } while (nodeIterator != d->textNodeMap.end() && nodeIterator->dirty()); } // FIXME: the text decorations could probably be handled separately (only updated for affected textFrames) @@ -2068,7 +2065,8 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * rootNode->setMatrix(basePositionMatrix); QPointF nodeOffset; - TextNode *firstCleanNode = (nodeIterator != d->textNodeMap.end()) ? *nodeIterator : 0; + const TextNode firstCleanNode = (nodeIterator != d->textNodeMap.end()) ? *nodeIterator + : TextNode(); QList<QTextFrame *> frames; frames.append(d->document->rootFrame()); @@ -2078,7 +2076,8 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * frames.append(textFrame->childFrames()); frameDecorationsEngine.addFrameDecorations(d->document, textFrame); - if (textFrame->lastPosition() < firstDirtyPos || (firstCleanNode && textFrame->firstPosition() >= firstCleanNode->startPos())) + if (textFrame->lastPosition() < firstDirtyPos + || textFrame->firstPosition() >= firstCleanNode.startPos()) continue; node = d->createTextNode(); resetEngine(&engine, d->color, d->selectedTextColor, d->selectionColor); @@ -2118,8 +2117,8 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * engine.addTextBlock(d->document, block, -nodeOffset, d->color, QColor(), selectionStart(), selectionEnd() - 1); currentNodeSize += block.length(); - if ((it.atEnd()) || (firstCleanNode && block.next().position() >= firstCleanNode->startPos())) // last node that needed replacing or last block of the frame - break; + if ((it.atEnd()) || block.next().position() >= firstCleanNode.startPos()) + break; // last node that needed replacing or last block of the frame QList<int>::const_iterator lowerBound = std::lower_bound(frameBoundaries.constBegin(), frameBoundaries.constEnd(), block.next().position()); if (currentNodeSize > nodeBreakingSize || lowerBound == frameBoundaries.constEnd() || *lowerBound > nodeStart) { @@ -2137,16 +2136,19 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * // Now prepend the frame decorations since we want them rendered first, with the text nodes and cursor in front. rootNode->prependChildNode(rootNode->frameDecorationsNode); - Q_ASSERT(nodeIterator == d->textNodeMap.end() || (*nodeIterator) == firstCleanNode); + Q_ASSERT(nodeIterator == d->textNodeMap.end() + || (nodeIterator->textNode() == firstCleanNode.textNode() + && nodeIterator->startPos() == firstCleanNode.startPos())); // Update the position of the subsequent text blocks. - if (firstCleanNode) { - QPointF oldOffset = firstCleanNode->textNode()->matrix().map(QPointF(0,0)); - QPointF currentOffset = d->document->documentLayout()->blockBoundingRect(d->document->findBlock(firstCleanNode->startPos())).topLeft(); + if (firstCleanNode.textNode() != nullptr) { + QPointF oldOffset = firstCleanNode.textNode()->matrix().map(QPointF(0,0)); + QPointF currentOffset = d->document->documentLayout()->blockBoundingRect( + d->document->findBlock(firstCleanNode.startPos())).topLeft(); QPointF delta = currentOffset - oldOffset; while (nodeIterator != d->textNodeMap.end()) { - QMatrix4x4 transformMatrix = (*nodeIterator)->textNode()->matrix(); + QMatrix4x4 transformMatrix = nodeIterator->textNode()->matrix(); transformMatrix.translate(delta.x(), delta.y()); - (*nodeIterator)->textNode()->setMatrix(transformMatrix); + nodeIterator->textNode()->setMatrix(transformMatrix); ++nodeIterator; } @@ -2154,7 +2156,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * // Since we iterate over blocks from different text frames that are potentially not sorted // we need to ensure that our list of nodes is sorted again: - std::sort(d->textNodeMap.begin(), d->textNodeMap.end(), &comesBefore); + std::sort(d->textNodeMap.begin(), d->textNodeMap.end()); } if (d->cursorComponent == 0) { @@ -2333,22 +2335,26 @@ void QQuickTextEdit::markDirtyNodesForRange(int start, int end, int charDelta) if (start == end) return; - TextNode dummyNode(start, 0); - TextNodeIterator it = std::lower_bound(d->textNodeMap.begin(), d->textNodeMap.end(), &dummyNode, &comesBefore); + TextNode dummyNode(start); + + const TextNodeIterator textNodeMapBegin = d->textNodeMap.begin(); + const TextNodeIterator textNodeMapEnd = d->textNodeMap.end(); + + TextNodeIterator it = std::lower_bound(textNodeMapBegin, textNodeMapEnd, dummyNode); // qLowerBound gives us the first node past the start of the affected portion, rewind to the first node // that starts at the last position before the edit position. (there might be several because of images) - if (it != d->textNodeMap.begin()) { + if (it != textNodeMapBegin) { --it; - TextNode otherDummy((*it)->startPos(), 0); - it = std::lower_bound(d->textNodeMap.begin(), d->textNodeMap.end(), &otherDummy, &comesBefore); + TextNode otherDummy(it->startPos()); + it = std::lower_bound(textNodeMapBegin, textNodeMapEnd, otherDummy); } // mark the affected nodes as dirty - while (it != d->textNodeMap.end()) { - if ((*it)->startPos() <= end) - (*it)->setDirty(); + while (it != textNodeMapEnd) { + if (it->startPos() <= end) + it->setDirty(); else if (charDelta) - (*it)->moveStartPos(charDelta); + it->moveStartPos(charDelta); else return; ++it; @@ -2533,8 +2539,8 @@ void QQuickTextEdit::updateWholeDocument() { Q_D(QQuickTextEdit); if (!d->textNodeMap.isEmpty()) { - for (TextNode* node : qAsConst(d->textNodeMap)) - node->setDirty(); + for (TextNode &node : d->textNodeMap) + node.setDirty(); } polish(); @@ -2678,7 +2684,7 @@ void QQuickTextEditPrivate::handleFocusEvent(QFocusEvent *event) void QQuickTextEditPrivate::addCurrentTextNodeToRoot(QQuickTextNodeEngine *engine, QSGTransformNode *root, QQuickTextNode *node, TextNodeIterator &it, int startPos) { engine->addToSceneGraph(node, QQuickText::Normal, QColor()); - it = textNodeMap.insert(it, new TextNode(startPos, node)); + it = textNodeMap.insert(it, TextNode(startPos, node)); ++it; root->appendChildNode(node); } |