diff options
author | Marco Bubke <marco.bubke@qt.io> | 2023-04-22 01:44:27 +0200 |
---|---|---|
committer | Marco Bubke <marco.bubke@qt.io> | 2023-05-11 15:55:30 +0000 |
commit | 3ff90526f5c84b40864fa467d0159cd14ac8baee (patch) | |
tree | d0d7a927a1588f562703fb71a64b94c461c3e887 | |
parent | dd5730d2a3cec20649563ca1dc777ee32c9882a7 (diff) | |
download | qt-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>
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 |