summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@qt.io>2023-04-22 01:44:27 +0200
committerMarco Bubke <marco.bubke@qt.io>2023-05-11 15:55:30 +0000
commit3ff90526f5c84b40864fa467d0159cd14ac8baee (patch)
treed0d7a927a1588f562703fb71a64b94c461c3e887
parentdd5730d2a3cec20649563ca1dc777ee32c9882a7 (diff)
downloadqt-creator-3ff90526f5c84b40864fa467d0159cd14ac8baee.tar.gz
QmlDesigner: Introduce SkipIterator
Instead of having a cache using an iterator skipping entries is much easier because the cache has not to be anymore updated. When we get C++ 20 ranges use them instead. Change-Id: If5b45c53bbd0b12138328862ac152788ffd911b2 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
-rw-r--r--src/plugins/qmldesigner/CMakeLists.txt1
-rw-r--r--src/plugins/qmldesigner/designercore/model/abstractview.cpp6
-rw-r--r--src/plugins/qmldesigner/designercore/model/model.cpp13
-rw-r--r--src/plugins/qmldesigner/designercore/model/model_p.h41
-rw-r--r--src/plugins/qmldesigner/designercore/model/skipiterator.h77
5 files changed, 111 insertions, 27 deletions
diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt
index b9459aeb1b..c7989fda36 100644
--- a/src/plugins/qmldesigner/CMakeLists.txt
+++ b/src/plugins/qmldesigner/CMakeLists.txt
@@ -371,6 +371,7 @@ extend_qtc_library(QmlDesignerCore
rewriteactioncompressor.h
rewriterview.cpp
signalhandlerproperty.cpp
+ skipiterator.h
stylesheetmerger.cpp
textmodifier.cpp
texttomodelmerger.cpp
diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp
index 07692f4a10..a09db03dac 100644
--- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp
+++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp
@@ -143,9 +143,6 @@ The default implementation is setting the reference of the model to the view.
void AbstractView::modelAttached(Model *model)
{
setModel(model);
-
- if (model)
- model->d->updateEnabledViews();
}
/*!
@@ -617,9 +614,6 @@ bool AbstractView::isEnabled() const
void AbstractView::setEnabled(bool b)
{
m_enabled = b;
-
- if (model())
- model()->d->updateEnabledViews();
}
QList<ModelNode> AbstractView::allModelNodes() const
diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp
index e630cc96d8..fcdb66b802 100644
--- a/src/plugins/qmldesigner/designercore/model/model.cpp
+++ b/src/plugins/qmldesigner/designercore/model/model.cpp
@@ -96,7 +96,6 @@ void ModelPrivate::detachAllViews()
detachView(view.data(), true);
m_viewList.clear();
- updateEnabledViews();
if (m_nodeInstanceView) {
m_nodeInstanceView->modelAboutToBeDetached(m_model);
@@ -299,9 +298,9 @@ void ModelPrivate::removeNodeFromModel(const InternalNodePointer &node)
m_internalIdNodeHash.remove(node->internalId);
}
-const QList<QPointer<AbstractView>> ModelPrivate::enabledViews() const
+EnabledViewRange ModelPrivate::enabledViews() const
{
- return m_enabledViewList;
+ return EnabledViewRange{m_viewList};
}
void ModelPrivate::removeAllSubNodes(const InternalNodePointer &node)
@@ -754,7 +753,6 @@ void ModelPrivate::detachView(AbstractView *view, bool notifyView)
if (notifyView)
view->modelAboutToBeDetached(m_model);
m_viewList.removeOne(view);
- updateEnabledViews();
}
void ModelPrivate::notifyNodeCreated(const InternalNodePointer &newInternalNodePointer)
@@ -1317,13 +1315,6 @@ InternalNodePointer ModelPrivate::currentTimelineNode() const
return m_currentTimelineNode;
}
-void ModelPrivate::updateEnabledViews()
-{
- m_enabledViewList = Utils::filtered(m_viewList, [](QPointer<AbstractView> view) {
- return view->isEnabled();
- });
-}
-
InternalNodePointer ModelPrivate::nodeForId(const QString &id) const
{
return m_idNodeHash.value(id);
diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h
index d167819280..ce2a49fc42 100644
--- a/src/plugins/qmldesigner/designercore/model/model_p.h
+++ b/src/plugins/qmldesigner/designercore/model/model_p.h
@@ -3,17 +3,20 @@
#pragma once
+#include "qmldesignercorelib_global.h"
+
+#include "abstractview.h"
+#include "metainfo.h"
+#include "modelnode.h"
+#include "skipiterator.h"
+
#include <QList>
#include <QPointer>
#include <QSet>
#include <QUrl>
#include <QVector3D>
-#include "modelnode.h"
-#include "abstractview.h"
-#include "metainfo.h"
-
-#include "qmldesignercorelib_global.h"
+#include <algorithm>
QT_BEGIN_NAMESPACE
class QPlainTextEdit;
@@ -64,7 +67,28 @@ private:
QPointer<ModelPrivate> m_model;
};
-class ModelPrivate : public QObject {
+struct Increment
+{
+ using iterator = QList<QPointer<AbstractView>>::const_iterator;
+ auto operator()(iterator current) {
+ return std::find_if(std::next(current),
+ end,
+ [] (iterator::reference &view) { return view && view->isEnabled(); });
+ }
+
+ iterator end;
+};
+
+class EnabledViewRange : public SkipRange<QList<QPointer<AbstractView>>, Increment>
+{
+public:
+ EnabledViewRange(const container &views)
+ : base{views, Increment{views.end()}}
+ {}
+};
+
+class ModelPrivate : public QObject
+{
Q_OBJECT
friend Model;
@@ -249,8 +273,6 @@ public:
InternalNodePointer currentStateNode() const;
InternalNodePointer currentTimelineNode() const;
- void updateEnabledViews();
-
private:
void removePropertyWithoutNotification(const InternalPropertyPointer &property);
void removeAllSubNodes(const InternalNodePointer &node);
@@ -259,7 +281,7 @@ private:
QList<ModelNode> toModelNodeList(const QList<InternalNodePointer> &nodeList, AbstractView *view) const;
QVector<ModelNode> toModelNodeVector(const QVector<InternalNodePointer> &nodeVector, AbstractView *view) const;
QVector<InternalNodePointer> toInternalNodeVector(const QVector<ModelNode> &modelNodeVector) const;
- const QList<QPointer<AbstractView>> enabledViews() const;
+ EnabledViewRange enabledViews() const;
public:
NotNullPointer<ProjectStorageType> projectStorage = nullptr;
@@ -271,7 +293,6 @@ private:
Imports m_possibleImportList;
Imports m_usedImportList;
QList<QPointer<AbstractView>> m_viewList;
- QList<QPointer<AbstractView>> m_enabledViewList;
QList<InternalNodePointer> m_selectedInternalNodeList;
QHash<QString,InternalNodePointer> m_idNodeHash;
QHash<qint32, InternalNodePointer> m_internalIdNodeHash;
diff --git a/src/plugins/qmldesigner/designercore/model/skipiterator.h b/src/plugins/qmldesigner/designercore/model/skipiterator.h
new file mode 100644
index 0000000000..11efb7d97f
--- /dev/null
+++ b/src/plugins/qmldesigner/designercore/model/skipiterator.h
@@ -0,0 +1,77 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include <iterator>
+
+namespace QmlDesigner {
+
+template<typename BaseIterator, typename Increment>
+class SkipIterator
+{
+public:
+ using iterator_category = std::forward_iterator_tag;
+ using difference_type = qsizetype;
+ using value_type = typename BaseIterator::value_type;
+ using pointer = typename BaseIterator::pointer;
+ using reference = typename BaseIterator::reference;
+
+ SkipIterator() = default;
+ SkipIterator(BaseIterator current, Increment increment)
+ : m_current{current}
+ , m_increment{std::move(increment)}
+ {}
+
+ SkipIterator operator++()
+ {
+ m_current = m_increment(m_current);
+ return *this;
+ }
+
+ SkipIterator operator++(int)
+ {
+ auto tmp = *this;
+ m_current = m_increment(m_current);
+ return tmp;
+ }
+
+ reference operator*() const { return *m_current; }
+ pointer operator->() const { return m_current.operator->(); }
+
+ friend bool operator==(const SkipIterator &first, const SkipIterator &second)
+ {
+ return first.m_current == second.m_current;
+ }
+
+ friend bool operator!=(const SkipIterator &first, const SkipIterator &second)
+ {
+ return first.m_current != second.m_current;
+ }
+
+private:
+ BaseIterator m_current = {};
+ Increment m_increment;
+};
+
+template<typename Container, typename Increment>
+class SkipRange
+{
+public:
+ using container = Container;
+ using base = SkipRange<Container, Increment>;
+ using iterator = SkipIterator<typename Container::const_iterator, Increment>;
+
+ SkipRange(const Container &container, Increment increment)
+ : m_begin{container.begin(), increment}
+ , m_end{container.end(), increment}
+ {}
+
+ iterator begin() const { return m_begin; }
+ iterator end() const { return m_end; }
+
+private:
+ iterator m_begin;
+ iterator m_end;
+};
+} // namespace QmlDesigner