1// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#include "lifecycle.h"
6#include "pluginview.h"
7#include "pluginmetaobject.h"
8
9#include <QTreeWidget>
10#include <QAbstractItemModel>
11#include <QHeaderView>
12#include <QGridLayout>
13#include <QItemSelectionModel>
14#include <QTreeWidgetItem>
15#include <QStandardItem>
16
17DPF_BEGIN_NAMESPACE
18
19enum Columns { Name, LoadStatus };
20
21class PluginItem : public QTreeWidgetItem
22{
23public:
24 PluginItem(PluginMetaObjectPointer plugin, PluginView *view)
25 : name(""), plugin(plugin), view(view)
26 {}
27
28 QVariant data(int column, int role) const override
29 {
30 switch (column) {
31 case Name:
32 if (role == Qt::DisplayRole)
33 return plugin->name();
34 if (role == Qt::ToolTipRole) {
35 QString toolTip = PluginView::tr("Path: %1");
36 return toolTip.arg(QDir::toNativeSeparators(plugin->fileName()));
37 }
38 break;
39
40 case LoadStatus:
41 if (role == Qt::CheckStateRole)
42 return plugin->isEnabledBySettings() ? Qt::Checked : Qt::Unchecked;
43 if (role == Qt::ToolTipRole)
44 return PluginView::tr("Load the plugin at startup");
45 break;
46 }
47
48 return QVariant();
49 }
50
51 void setData(int column, int role, const QVariant &data) override
52 {
53 if (column == LoadStatus && role == Qt::CheckStateRole)
54 view->setPluginEnabled(plugin, data.toBool());
55 }
56
57public:
58 QString name;
59 PluginMetaObjectPointer plugin;
60 PluginView *view = nullptr;
61};
62
63class CollectionItem : public QTreeWidgetItem
64{
65public:
66 CollectionItem(const QString &name, QList<PluginMetaObjectPointer> plugins, PluginView *view)
67 : name(name), plugins(plugins), view(view)
68 {
69 for (PluginMetaObjectPointer plugin : plugins)
70 this->addChild(new PluginItem(plugin, view));
71 }
72
73 QVariant data(int column, int role) const override
74 {
75 if (column == Name) {
76 if (role == Qt::DisplayRole)
77 return name;
78 }
79
80 if (column == LoadStatus) {
81 if (role == Qt::ToolTipRole)
82 return PluginView::tr("Load the plugin at startup");
83 }
84
85 return QVariant();
86 }
87
88public:
89 QString name;
90 QList<PluginMetaObjectPointer> plugins;
91 PluginView *view = nullptr;
92};
93
94PluginView::PluginView(QWidget *parent)
95 : QWidget(parent)
96{
97 categoryWidegt = new QTreeWidget(this);
98 categoryWidegt->setIndentation(20);
99 categoryWidegt->setUniformRowHeights(true);
100 categoryWidegt->setSortingEnabled(true);
101 categoryWidegt->header()->setSortIndicator(0, Qt::AscendingOrder);
102 categoryWidegt->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
103 categoryWidegt->setSelectionMode(QAbstractItemView::SingleSelection);
104 categoryWidegt->setSelectionBehavior(QAbstractItemView::SelectRows);
105 categoryWidegt->setHeaderLabels({QObject::tr("Name"), QObject::tr("Load Status")});
106
107 auto *gridLayout = new QGridLayout(this);
108 gridLayout->setContentsMargins(2, 2, 2, 2);
109 gridLayout->addWidget(categoryWidegt);
110
111 QObject::connect(LifeCycle::getPluginManagerInstance(), &PluginManager::pluginsChanged, this,
112 &PluginView::updatePluginsWidegt);
113
114 QObject::connect(categoryWidegt, &QTreeWidget::clicked, [this](){
115 if (dynamic_cast<PluginItem *>(categoryWidegt->currentItem()))
116 emit currentPluginActived();
117 });
118
119 updatePluginsWidegt();
120}
121
122PluginMetaObjectPointer PluginView::currentPlugin() const
123{
124 QTreeWidgetItem *sourceItem = categoryWidegt->currentItem();
125 if (!sourceItem)
126 return nullptr;
127
128 CollectionItem *collectItem = static_cast<CollectionItem*>(sourceItem);
129 QString name = collectItem->name;
130 if (name.isEmpty()) {
131 PluginItem *plugitem = static_cast<PluginItem*>(sourceItem);
132 return plugitem ? plugitem->plugin : nullptr;
133 }
134
135 return nullptr;
136}
137
138void PluginView::updatePluginsWidegt()
139{
140 QList<CollectionItem *> collections;
141 const QHash<QString, QQueue<PluginMetaObjectPointer>> pluginCollections = LifeCycle::getPluginManagerInstance()->pluginCollections();
142 const auto end = pluginCollections.cend();
143 for (auto it = pluginCollections.begin(); it != end; ++it) {
144 const QString name = it.key();
145 if ("Core Plugins" != name)
146 collections.append(new CollectionItem(name, it.value(), this));
147 }
148
149 for (CollectionItem *collection : collections) {
150 categoryWidegt->invisibleRootItem()->addChild(collection);
151 }
152
153 categoryWidegt->expandAll();
154
155 categoryWidegt->setCurrentItem(categoryWidegt->topLevelItem(0)->child(0));
156}
157
158void PluginView::setPluginEnabled(PluginMetaObjectPointer plugin, bool enable)
159{
160 plugin->setEnabledBySettings(enable);
161 emit pluginSettingChanged(plugin);
162}
163
164DPF_END_NAMESPACE
165