From e8df914ef25ed56cfbfd5fbf52f1983b90f8317e Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 9 Jan 2019 16:47:54 +0100 Subject: QmlDesigner: Use proper canocial ordering for auxiliary data When saving auxiliary data we haver to use a proper ordering of the node to generate an index. Change-Id: I54101c4770eec359de4fdaffbbe37308416a5714 Reviewed-by: Alessandro Portale --- .../designercore/include/rewriterview.h | 6 +++ .../designercore/model/rewriterview.cpp | 46 ++++++++++++++++++++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/include/rewriterview.h b/src/plugins/qmldesigner/designercore/include/rewriterview.h index fa2147f9b6..c9d2e6dd01 100644 --- a/src/plugins/qmldesigner/designercore/include/rewriterview.h +++ b/src/plugins/qmldesigner/designercore/include/rewriterview.h @@ -171,6 +171,8 @@ public: QString getRawAuxiliaryData() const; QString auxiliaryDataAsQML() const; + ModelNode getNodeForCanonicalIndex(int index); + protected: // functions void importAdded(const Import &import); void importRemoved(const Import &import); @@ -186,6 +188,7 @@ protected: // functions private: //variables ModelNode nodeAtTextCursorPositionRekursive(const ModelNode &root, int cursorPosition) const; + void setupCanonicalHashes() const; TextModifier *m_textModifier = nullptr; int transactionLevel = 0; @@ -205,6 +208,9 @@ private: //variables bool m_instantQmlTextUpdate = false; std::function m_setWidgetStatusCallback; bool m_hasIncompleteTypeInformation = false; + + mutable QHash m_canonicalIntModelNode; + mutable QHash m_canonicalModelNodeInt; }; } //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp index 72f8ff1e3a..131ffe8fe5 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp @@ -53,6 +53,9 @@ #include #include +#include +#include + using namespace QmlDesigner::Internal; namespace QmlDesigner { @@ -476,6 +479,8 @@ QString RewriterView::auxiliaryDataAsQML() const { bool hasAuxData = false; + setupCanonicalHashes(); + QString str = "Designer {\n "; int columnCount = 0; @@ -490,7 +495,8 @@ QString RewriterView::auxiliaryDataAsQML() const const int startLen = str.length(); str += "D{"; str += "i:"; - str += QString::number(node.internalId()); + + str += QString::number(m_canonicalModelNodeInt.value(node)); str += ";"; QStringList keys = Utils::transform(data.keys(), [](const PropertyName &name) { @@ -540,6 +546,11 @@ QString RewriterView::auxiliaryDataAsQML() const return {}; } +ModelNode RewriterView::getNodeForCanonicalIndex(int index) +{ + return m_canonicalIntModelNode.value(index); +} + Internal::ModelNodePositionStorage *RewriterView::positionStorage() const { return m_positionStorage.data(); @@ -705,6 +716,29 @@ ModelNode RewriterView::nodeAtTextCursorPositionRekursive(const ModelNode &root, return root; } +void RewriterView::setupCanonicalHashes() const +{ + m_canonicalIntModelNode.clear(); + m_canonicalModelNodeInt.clear(); + + using myPair = std::pair; + std::vector data; + + for (const ModelNode &node : allModelNodes()) + data.emplace_back(std::make_pair(node, nodeOffset(node))); + + std::sort(data.begin(), data.end(), [](myPair a, myPair b) { + return a.second < b.second; + }); + + int i = 0; + for (const myPair &pair : data) { + m_canonicalIntModelNode.insert(i, pair.first); + m_canonicalModelNodeInt.insert(pair.first, i); + ++i; + } +} + ModelNode RewriterView::nodeAtTextCursorPosition(int cursorPosition) const { return nodeAtTextCursorPositionRekursive(rootModelNode(), cursorPosition); @@ -996,7 +1030,7 @@ static QString fixUpIllegalChars(const QString &str) return ret; } -static void checkNode(const QmlJS::SimpleReaderNode::Ptr &node, RewriterView *view) +void checkNode(const QmlJS::SimpleReaderNode::Ptr &node, RewriterView *view) { if (!node) return; @@ -1004,8 +1038,10 @@ static void checkNode(const QmlJS::SimpleReaderNode::Ptr &node, RewriterView *vi if (!node->propertyNames().contains("i")) return; - const int internalId = node->property("i").toInt(); - const ModelNode modelNode = view->modelNodeForInternalId(internalId); + const int index = node->property("i").toInt(); + + const ModelNode modelNode = view->getNodeForCanonicalIndex(index); + if (!modelNode.isValid()) return; @@ -1023,6 +1059,8 @@ void RewriterView::restoreAuxiliaryData() { QTC_ASSERT(m_textModifier, return); + setupCanonicalHashes(); + const QString text = m_textModifier->text(); int startIndex = text.indexOf(annotationsStart()); -- cgit v1.2.3