1 /*
2   SPDX-FileCopyrightText: 2016-2021 Laurent Montel <montel@kde.org>
3 
4   SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "configurepluginslistwidget.h"
8 
9 #include <KLocalizedString>
10 #include <KSharedConfig>
11 #include <KTreeWidgetSearchLineWidget>
12 
13 #include <QAction>
14 #include <QHeaderView>
15 #include <QPushButton>
16 #include <QToolButton>
17 #include <QTreeWidget>
18 #include <QVBoxLayout>
19 
20 using namespace PimCommon;
ConfigurePluginsListWidget(QWidget * parent)21 ConfigurePluginsListWidget::ConfigurePluginsListWidget(QWidget *parent)
22     : QWidget(parent)
23     , mListWidget(new QTreeWidget(this))
24 {
25     auto mainLayout = new QVBoxLayout(this);
26     mainLayout->setObjectName(QStringLiteral("mainlayout"));
27     mainLayout->setContentsMargins({});
28 
29     mListWidget->setSortingEnabled(true);
30     mListWidget->sortItems(0, Qt::AscendingOrder);
31     mListWidget->setObjectName(QStringLiteral("listwidget"));
32     mListWidget->setHeaderHidden(true);
33     mListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
34     mListWidget->setColumnCount(2);
35     mListWidget->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
36     mListWidget->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
37     mListWidget->header()->setStretchLastSection(false);
38 
39     mTreeWidgetSearchLineEdit = new KTreeWidgetSearchLineWidget(this, mListWidget);
40     mTreeWidgetSearchLineEdit->setObjectName(QStringLiteral("mTreeWidgetSearchLineEdit"));
41 
42     connect(mListWidget, &QTreeWidget::itemSelectionChanged, this, &ConfigurePluginsListWidget::slotItemSelectionChanged);
43     connect(mListWidget, &QTreeWidget::itemChanged, this, &ConfigurePluginsListWidget::slotItemChanged);
44 
45     mainLayout->addWidget(mTreeWidgetSearchLineEdit);
46     mainLayout->addWidget(mListWidget);
47 }
48 
~ConfigurePluginsListWidget()49 ConfigurePluginsListWidget::~ConfigurePluginsListWidget()
50 {
51 }
52 
slotItemChanged(QTreeWidgetItem * item,int column)53 void ConfigurePluginsListWidget::slotItemChanged(QTreeWidgetItem *item, int column)
54 {
55     Q_UNUSED(item)
56     if (mInitializeDone) {
57         if (column == 0) {
58             Q_EMIT changed();
59         }
60     }
61 }
62 
slotItemSelectionChanged()63 void ConfigurePluginsListWidget::slotItemSelectionChanged()
64 {
65     QTreeWidgetItem *item = mListWidget->currentItem();
66     if (auto pluginItem = dynamic_cast<PluginItem *>(item)) {
67         Q_EMIT descriptionChanged(pluginItem->mDescription);
68     }
69 }
70 
save()71 void ConfigurePluginsListWidget::save()
72 {
73 }
74 
doLoadFromGlobalSettings()75 void ConfigurePluginsListWidget::doLoadFromGlobalSettings()
76 {
77     initialize();
78     initializeDone();
79 }
80 
doResetToDefaultsOther()81 void ConfigurePluginsListWidget::doResetToDefaultsOther()
82 {
83 }
84 
defaults()85 void ConfigurePluginsListWidget::defaults()
86 {
87 }
88 
initialize()89 void ConfigurePluginsListWidget::initialize()
90 {
91 }
92 
initializeDone()93 void ConfigurePluginsListWidget::initializeDone()
94 {
95     mInitializeDone = true;
96 }
97 
savePlugins(const QString & groupName,const QString & prefixSettingKey,const QVector<PluginItem * > & listItems)98 void ConfigurePluginsListWidget::savePlugins(const QString &groupName, const QString &prefixSettingKey, const QVector<PluginItem *> &listItems)
99 {
100     if (listItems.isEmpty()) {
101         return;
102     }
103     QStringList enabledPlugins;
104     QStringList disabledPlugins;
105     for (PluginItem *item : listItems) {
106         if (item->checkState(0) == Qt::Checked) {
107             enabledPlugins << item->mIdentifier;
108         } else {
109             disabledPlugins << item->mIdentifier;
110         }
111     }
112     PimCommon::PluginUtil::savePluginSettings(groupName, prefixSettingKey, enabledPlugins, disabledPlugins);
113 }
114 
fillTopItems(const QVector<PimCommon::PluginUtilData> & lst,const QString & topLevelItemName,const QString & groupName,const QString & prefixKey,QVector<PluginItem * > & itemsList,const QString & configureGroupName,bool checkable)115 void ConfigurePluginsListWidget::fillTopItems(const QVector<PimCommon::PluginUtilData> &lst,
116                                               const QString &topLevelItemName,
117                                               const QString &groupName,
118                                               const QString &prefixKey,
119                                               QVector<PluginItem *> &itemsList,
120                                               const QString &configureGroupName,
121                                               bool checkable)
122 {
123     itemsList.clear();
124     if (!lst.isEmpty()) {
125         auto topLevel = new QTreeWidgetItem(mListWidget, {topLevelItemName});
126         topLevel->setFlags(topLevel->flags() & ~Qt::ItemIsSelectable);
127         const QPair<QStringList, QStringList> pair = PimCommon::PluginUtil::loadPluginSetting(groupName, prefixKey);
128         for (const PimCommon::PluginUtilData &data : lst) {
129             auto subItem = new PluginItem(topLevel);
130             subItem->setText(0, data.mName);
131             subItem->mIdentifier = data.mIdentifier;
132             subItem->mDescription = data.mDescription;
133             subItem->mEnableByDefault = data.mEnableByDefault;
134             subItem->mHasConfigureSupport = data.mHasConfigureDialog;
135             if (checkable) {
136                 const bool isPluginActivated = PimCommon::PluginUtil::isPluginActivated(pair.first, pair.second, data.mEnableByDefault, data.mIdentifier);
137                 subItem->mEnableFromUserSettings = isPluginActivated;
138                 subItem->setCheckState(0, isPluginActivated ? Qt::Checked : Qt::Unchecked);
139             }
140             if (data.mHasConfigureDialog) {
141                 auto but = new QToolButton(mListWidget);
142                 auto act = new QAction(but);
143                 const QStringList actData{configureGroupName, data.mIdentifier};
144                 act->setData(actData);
145                 but->setDefaultAction(act);
146                 but->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
147                 but->setText(i18n("..."));
148                 but->setFixedWidth(28);
149                 but->setToolTip(i18n("Configure"));
150                 but->setAutoFillBackground(true);
151                 but->setEnabled(subItem->mHasConfigureSupport);
152                 mListWidget->setItemWidget(subItem, 1, but);
153                 connect(but, &QToolButton::triggered, this, &ConfigurePluginsListWidget::slotConfigureClicked);
154             }
155             itemsList.append(subItem);
156         }
157     }
158 }
159 
slotConfigureClicked(QAction * act)160 void ConfigurePluginsListWidget::slotConfigureClicked(QAction *act)
161 {
162     if (act) {
163         const QStringList lst = act->data().toStringList();
164         if (lst.count() == 2) {
165             Q_EMIT configureClicked(lst.at(0), lst.at(1));
166         }
167     }
168 }
169 
changeState(const QVector<PluginItem * > & items)170 void ConfigurePluginsListWidget::changeState(const QVector<PluginItem *> &items)
171 {
172     for (PluginItem *item : items) {
173         item->setCheckState(0, item->mEnableByDefault ? Qt::Checked : Qt::Unchecked);
174     }
175 }
176 
resetToUserSettings(const QVector<PluginItem * > & items)177 void ConfigurePluginsListWidget::resetToUserSettings(const QVector<PluginItem *> &items)
178 {
179     for (PluginItem *item : items) {
180         item->setCheckState(0, item->mEnableFromUserSettings ? Qt::Checked : Qt::Unchecked);
181     }
182 }
183