forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -371,6 +371,7 @@ extend_qtc_library(QmlDesignerCore
|
||||
rewriteactioncompressor.h
|
||||
rewriterview.cpp
|
||||
signalhandlerproperty.cpp
|
||||
skipiterator.h
|
||||
stylesheetmerger.cpp
|
||||
textmodifier.cpp
|
||||
texttomodelmerger.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
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
77
src/plugins/qmldesigner/designercore/model/skipiterator.h
Normal file
77
src/plugins/qmldesigner/designercore/model/skipiterator.h
Normal file
@@ -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
|
Reference in New Issue
Block a user