ExtensionSystem: Split PluginView in PluginData and view

Change-Id: I7337b83eafe391b4fc46ef9c2e2617a76adf0f5f
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
hjk
2024-06-25 15:50:22 +02:00
parent 44e36686c8
commit 828c50d33d
2 changed files with 59 additions and 37 deletions

View File

@@ -89,8 +89,8 @@ static const QIcon &icon(IconIndex icon)
class PluginItem : public TreeItem class PluginItem : public TreeItem
{ {
public: public:
PluginItem(PluginSpec *spec, PluginView *view) PluginItem(PluginSpec *spec, PluginData *data)
: m_spec(spec), m_view(view) : m_spec(spec), m_data(data)
{} {}
QVariant data(int column, int role) const override QVariant data(int column, int role) const override
@@ -167,7 +167,7 @@ public:
bool setData(int column, const QVariant &data, int role) override bool setData(int column, const QVariant &data, int role) override
{ {
if (column == LoadedColumn && role == Qt::CheckStateRole) if (column == LoadedColumn && role == Qt::CheckStateRole)
return m_view->setPluginsEnabled({m_spec}, data.toBool()); return m_data->setPluginsEnabled({m_spec}, data.toBool());
return false; return false;
} }
@@ -193,19 +193,19 @@ public:
public: public:
PluginSpec *m_spec; // Not owned. PluginSpec *m_spec; // Not owned.
PluginView *m_view; // Not owned. PluginData *m_data; // Not owned.
}; };
class CollectionItem : public TreeItem class CollectionItem : public TreeItem
{ {
public: public:
CollectionItem(const QString &name, const PluginSpecs &plugins, PluginView *view) CollectionItem(const QString &name, const PluginSpecs &plugins, PluginData *data)
: m_name(name) : m_name(name)
, m_plugins(plugins) , m_plugins(plugins)
, m_view(view) , m_data(data)
{ {
for (PluginSpec *spec : plugins) for (PluginSpec *spec : plugins)
appendChild(new PluginItem(spec, view)); appendChild(new PluginItem(spec, data));
} }
QVariant data(int column, int role) const override QVariant data(int column, int role) const override
@@ -241,7 +241,7 @@ public:
if (column == LoadedColumn && role == Qt::CheckStateRole) { if (column == LoadedColumn && role == Qt::CheckStateRole) {
const PluginSpecs affectedPlugins const PluginSpecs affectedPlugins
= Utils::filtered(m_plugins, [](PluginSpec *spec) { return !spec->isRequired(); }); = Utils::filtered(m_plugins, [](PluginSpec *spec) { return !spec->isRequired(); });
if (m_view->setPluginsEnabled(toSet(affectedPlugins), data.toBool())) { if (m_data->setPluginsEnabled(toSet(affectedPlugins), data.toBool())) {
update(); update();
return true; return true;
} }
@@ -260,19 +260,31 @@ public:
public: public:
QString m_name; QString m_name;
const PluginSpecs m_plugins; const PluginSpecs m_plugins;
PluginView *m_view; // Not owned. PluginData *m_data; // Not owned.
}; };
} // Internal } // Internal
using namespace ExtensionSystem::Internal; using namespace ExtensionSystem::Internal;
PluginData::PluginData(QWidget *parent, PluginView *owner)
: m_parent(parent), m_pluginView(owner)
{
m_model = new TreeModel<TreeItem, CollectionItem, PluginItem>(parent);
m_model->setHeader({ Tr::tr("Name"), Tr::tr("Load"), Tr::tr("Version"), Tr::tr("Vendor") });
m_sortModel = new CategorySortFilterModel(parent);
m_sortModel->setSourceModel(m_model);
m_sortModel->setSortRole(SortRole);
m_sortModel->setFilterKeyColumn(-1/*all*/);
}
/*! /*!
Constructs a plugin view with \a parent that displays a list of plugins Constructs a plugin view with \a parent that displays a list of plugins
from a plugin manager. from a plugin manager.
*/ */
PluginView::PluginView(QWidget *parent) PluginView::PluginView(QWidget *parent)
: QWidget(parent) : QWidget(parent), m_data(this, this)
{ {
m_categoryView = new TreeView(this); m_categoryView = new TreeView(this);
m_categoryView->setAlternatingRowColors(true); m_categoryView->setAlternatingRowColors(true);
@@ -282,14 +294,7 @@ PluginView::PluginView(QWidget *parent)
m_categoryView->setSelectionMode(QAbstractItemView::SingleSelection); m_categoryView->setSelectionMode(QAbstractItemView::SingleSelection);
m_categoryView->setSelectionBehavior(QAbstractItemView::SelectRows); m_categoryView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_model = new TreeModel<TreeItem, CollectionItem, PluginItem>(this); m_categoryView->setModel(m_data.m_sortModel);
m_model->setHeader({ Tr::tr("Name"), Tr::tr("Load"), Tr::tr("Version"), Tr::tr("Vendor") });
m_sortModel = new CategorySortFilterModel(this);
m_sortModel->setSourceModel(m_model);
m_sortModel->setSortRole(SortRole);
m_sortModel->setFilterKeyColumn(-1/*all*/);
m_categoryView->setModel(m_sortModel);
auto *gridLayout = new QGridLayout(this); auto *gridLayout = new QGridLayout(this);
gridLayout->setContentsMargins(2, 2, 2, 2); gridLayout->setContentsMargins(2, 2, 2, 2);
@@ -329,7 +334,7 @@ PluginSpec *PluginView::currentPlugin() const
*/ */
void PluginView::setFilter(const QString &filter) void PluginView::setFilter(const QString &filter)
{ {
m_sortModel->setFilterRegularExpression( m_data.m_sortModel->setFilterRegularExpression(
QRegularExpression(QRegularExpression::escape(filter), QRegularExpression(QRegularExpression::escape(filter),
QRegularExpression::CaseInsensitiveOption)); QRegularExpression::CaseInsensitiveOption));
m_categoryView->expandAll(); m_categoryView->expandAll();
@@ -337,15 +342,15 @@ void PluginView::setFilter(const QString &filter)
PluginSpec *PluginView::pluginForIndex(const QModelIndex &index) const PluginSpec *PluginView::pluginForIndex(const QModelIndex &index) const
{ {
const QModelIndex &sourceIndex = m_sortModel->mapToSource(index); const QModelIndex &sourceIndex = m_data.m_sortModel->mapToSource(index);
PluginItem *item = m_model->itemForIndexAtLevel<2>(sourceIndex); PluginItem *item = m_data.m_model->itemForIndexAtLevel<2>(sourceIndex);
return item ? item->m_spec: nullptr; return item ? item->m_spec: nullptr;
} }
void PluginView::updatePlugins() void PluginView::updatePlugins()
{ {
// Model. // Model.
m_model->clear(); m_data.m_model->clear();
const QHash<QString, PluginSpecs> pluginCollections const QHash<QString, PluginSpecs> pluginCollections
= PluginManager::pluginCollections(); = PluginManager::pluginCollections();
@@ -353,14 +358,14 @@ void PluginView::updatePlugins()
const auto end = pluginCollections.cend(); const auto end = pluginCollections.cend();
for (auto it = pluginCollections.cbegin(); it != end; ++it) { for (auto it = pluginCollections.cbegin(); it != end; ++it) {
const QString name = it.key().isEmpty() ? Tr::tr("Utilities") : it.key(); const QString name = it.key().isEmpty() ? Tr::tr("Utilities") : it.key();
collections.push_back(new CollectionItem(name, it.value(), this)); collections.push_back(new CollectionItem(name, it.value(), &m_data));
} }
Utils::sort(collections, &CollectionItem::m_name); Utils::sort(collections, &CollectionItem::m_name);
for (CollectionItem *collection : std::as_const(collections)) for (CollectionItem *collection : std::as_const(collections))
m_model->rootItem()->appendChild(collection); m_data.m_model->rootItem()->appendChild(collection);
emit m_model->layoutChanged(); emit m_data.m_model->layoutChanged();
m_categoryView->expandAll(); m_categoryView->expandAll();
} }
@@ -371,7 +376,7 @@ static QString pluginListString(const QSet<PluginSpec *> &plugins)
return names.join(QLatin1Char('\n')); return names.join(QLatin1Char('\n'));
} }
bool PluginView::setPluginsEnabled(const QSet<PluginSpec *> &plugins, bool enable) bool PluginData::setPluginsEnabled(const QSet<PluginSpec *> &plugins, bool enable)
{ {
QSet<PluginSpec *> additionalPlugins; QSet<PluginSpec *> additionalPlugins;
if (enable) { if (enable) {
@@ -383,7 +388,7 @@ bool PluginView::setPluginsEnabled(const QSet<PluginSpec *> &plugins, bool enabl
} }
additionalPlugins.subtract(plugins); additionalPlugins.subtract(plugins);
if (!additionalPlugins.isEmpty()) { if (!additionalPlugins.isEmpty()) {
if (QMessageBox::question(this, Tr::tr("Enabling Plugins"), if (QMessageBox::question(m_parent, Tr::tr("Enabling Plugins"),
Tr::tr("Enabling\n%1\nwill also enable the following plugins:\n\n%2") Tr::tr("Enabling\n%1\nwill also enable the following plugins:\n\n%2")
.arg(pluginListString(plugins), pluginListString(additionalPlugins)), .arg(pluginListString(plugins), pluginListString(additionalPlugins)),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok | QMessageBox::Cancel,
@@ -400,7 +405,7 @@ bool PluginView::setPluginsEnabled(const QSet<PluginSpec *> &plugins, bool enabl
} }
additionalPlugins.subtract(plugins); additionalPlugins.subtract(plugins);
if (!additionalPlugins.isEmpty()) { if (!additionalPlugins.isEmpty()) {
if (QMessageBox::question(this, Tr::tr("Disabling Plugins"), if (QMessageBox::question(m_parent, Tr::tr("Disabling Plugins"),
Tr::tr("Disabling\n%1\nwill also disable the following plugins:\n\n%2") Tr::tr("Disabling\n%1\nwill also disable the following plugins:\n\n%2")
.arg(pluginListString(plugins), pluginListString(additionalPlugins)), .arg(pluginListString(plugins), pluginListString(additionalPlugins)),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok | QMessageBox::Cancel,
@@ -422,13 +427,16 @@ bool PluginView::setPluginsEnabled(const QSet<PluginSpec *> &plugins, bool enabl
item->updateColumn(LoadedColumn); item->updateColumn(LoadedColumn);
item->parent()->updateColumn(LoadedColumn); item->parent()->updateColumn(LoadedColumn);
} }
emit pluginsChanged(affectedPlugins, enable);
if (m_pluginView)
emit m_pluginView->pluginsChanged(affectedPlugins, enable);
return true; return true;
} }
void PluginView::cancelChanges() void PluginView::cancelChanges()
{ {
for (auto element : m_affectedPlugins) for (auto element : m_data.m_affectedPlugins)
element.first->setEnabledBySettings(element.second); element.first->setEnabledBySettings(element.second);
} }

View File

@@ -22,12 +22,32 @@ class TreeView;
namespace ExtensionSystem { namespace ExtensionSystem {
class PluginSpec; class PluginSpec;
class PluginView;
namespace Internal { namespace Internal {
class CollectionItem; class CollectionItem;
class PluginItem; class PluginItem;
} // Internal } // Internal
class EXTENSIONSYSTEM_EXPORT PluginData
{
public:
explicit PluginData(QWidget *parent, PluginView *pluginView = nullptr);
bool setPluginsEnabled(const QSet<PluginSpec *> &plugins, bool enable);
private:
QWidget *m_parent = nullptr;
PluginView *m_pluginView = nullptr;
Utils::TreeModel<Utils::TreeItem, Internal::CollectionItem, Internal::PluginItem> *m_model;
Utils::CategorySortFilterModel *m_sortModel;
std::unordered_map<PluginSpec *, bool> m_affectedPlugins;
friend class Internal::CollectionItem;
friend class Internal::PluginItem;
friend class PluginView;
};
class EXTENSIONSYSTEM_EXPORT PluginView : public QWidget class EXTENSIONSYSTEM_EXPORT PluginView : public QWidget
{ {
Q_OBJECT Q_OBJECT
@@ -38,7 +58,6 @@ public:
PluginSpec *currentPlugin() const; PluginSpec *currentPlugin() const;
void setFilter(const QString &filter); void setFilter(const QString &filter);
bool setPluginsEnabled(const QSet<PluginSpec *> &plugins, bool enable);
void cancelChanges(); void cancelChanges();
signals: signals:
@@ -50,13 +69,8 @@ private:
PluginSpec *pluginForIndex(const QModelIndex &index) const; PluginSpec *pluginForIndex(const QModelIndex &index) const;
void updatePlugins(); void updatePlugins();
PluginData m_data;
Utils::TreeView *m_categoryView; Utils::TreeView *m_categoryView;
Utils::TreeModel<Utils::TreeItem, Internal::CollectionItem, Internal::PluginItem> *m_model;
Utils::CategorySortFilterModel *m_sortModel;
std::unordered_map<PluginSpec *, bool> m_affectedPlugins;
friend class Internal::CollectionItem;
friend class Internal::PluginItem;
}; };
} // namespace ExtensionSystem } // namespace ExtensionSystem