1 /*
2  This file is part of the Okteta Kasten Framework, made within the KDE community.
3 
4  SPDX-FileCopyrightText: 2009 Friedrich W. H. Kossebau <kossebau@kde.org>
5  SPDX-FileCopyrightText: 2009, 2012 Alex Richardson <alex.richardson@gmx.de>
6 
7  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
8  */
9 
10 #include "structuresmanagerview.hpp"
11 
12 // controller
13 #include "structuresselectiondialog.hpp"
14 #include "structureviewpreferences.h"
15 #include "../structuresmanager.hpp"
16 #include "../structurestool.hpp"
17 #include "../structlogging.hpp"
18 // KF
19 #include <KPluginSelector>
20 #include <KConfigDialogManager>
21 #include <KPluginInfo>
22 #include <KLocalizedString>
23 #include <KNS3/Button>
24 // Qt
25 #include <QPushButton>
26 #include <QListWidgetItem>
27 #include <QLayout>
28 #include <QSizePolicy>
29 
StructuresManagerView(Kasten::StructuresTool * tool,QWidget * parent)30 StructuresManagerView::StructuresManagerView(Kasten::StructuresTool* tool, QWidget* parent)
31     : QWidget(parent)
32     , mTool(tool)
33     , mRebuildingPluginsList(false)
34 {
35     mSelectedStructures = Kasten::StructureViewPreferences::loadedStructures();
36 
37     auto* pageLayout = new QVBoxLayout();
38     pageLayout->setContentsMargins(0, 0, 0, 0);
39     setLayout(pageLayout);
40 
41     rebuildPluginSelectorEntries();
42 
43     auto* buttonsLayout = new QHBoxLayout();
44     pageLayout->addLayout(buttonsLayout);
45 
46     mGetNewStructuresButton = new KNS3::Button(i18n("Get New Structures..."),
47                                                QStringLiteral("okteta-structures.knsrc"), this);
48     connect(mGetNewStructuresButton, &KNS3::Button::dialogFinished,
49             this, &StructuresManagerView::onGetNewStructuresClicked);
50     buttonsLayout->addWidget(mGetNewStructuresButton);
51 
52     mAdvancedSelectionButton = new QPushButton(QIcon::fromTheme(QStringLiteral("configure")), i18n("Advanced Selection..."), this);
53     connect(mAdvancedSelectionButton, &QPushButton::clicked, this, &StructuresManagerView::advancedSelection);
54     buttonsLayout->addWidget(mAdvancedSelectionButton);
55 }
56 
57 StructuresManagerView::~StructuresManagerView() = default;
58 
onGetNewStructuresClicked(const KNS3::Entry::List & changedEntries)59 void StructuresManagerView::onGetNewStructuresClicked(const KNS3::Entry::List& changedEntries)
60 {
61     for (const KNS3::Entry& e : changedEntries) {
62         qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "Changed Entry: " << e.name();
63         if (e.status() == KNS3::Entry::Installed) {
64             // new element installed
65             qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "installed files:" << e.installedFiles();
66         }
67         if (e.status() == KNS3::Entry::Deleted) {
68             // element uninstalled
69             qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "deleted files:" << e.uninstalledFiles();
70         }
71     }
72 
73     if (!changedEntries.isEmpty()) {
74         qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "installed structures changed ->  rebuilding list of installed structures";
75         mTool->manager()->reloadPaths();
76         rebuildPluginSelectorEntries();
77     }
78 }
79 
values() const80 QStringList StructuresManagerView::values() const
81 {
82     return mSelectedStructures;
83 }
84 
advancedSelection()85 void StructuresManagerView::advancedSelection()
86 {
87     auto* dialog = new StructuresSelectionDialog(mSelectedStructures, mTool, this);
88     connect(dialog, &StructuresSelectionDialog::structuresAccepted,
89             this, &StructuresManagerView::setSelectedStructures);
90     dialog->open();
91 }
92 
setSelectedStructures(const QStringList & selectedStructures)93 void StructuresManagerView::setSelectedStructures(const QStringList& selectedStructures)
94 {
95     if (selectedStructures == mSelectedStructures) {
96         return;
97     }
98 
99     qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES)
100         << "selection changed from " << mSelectedStructures << "to" << selectedStructures;
101     mSelectedStructures = selectedStructures;
102     emit changed(selectedStructures);
103 }
104 
onPluginSelectorChange(bool change)105 void StructuresManagerView::onPluginSelectorChange(bool change)
106 {
107     if (mRebuildingPluginsList) {
108         return;
109     }
110     qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES)
111         << "pluginselector changed: " << change;
112     if (!change) {
113         return;
114     }
115     mStructuresSelector->save();
116     reloadSelectedItems();
117 }
118 
reloadSelectedItems()119 void StructuresManagerView::reloadSelectedItems()
120 {
121     QStringList newVals;
122     const auto structureDefs = mTool->manager()->structureDefs();
123     for (const Kasten::StructureDefinitionFile* def : structureDefs) {
124         KPluginInfo info = def->pluginInfo();
125         if (info.isPluginEnabled()) {
126             newVals.append(QStringLiteral("\'%1\':\'*\'").arg(info.pluginName()));
127         }
128     }
129 
130     if (newVals != mSelectedStructures) {
131         qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES)
132             << "selection changed from " << mSelectedStructures << "to" << newVals;
133         mSelectedStructures = newVals;
134         emit changed(newVals);
135     } else {
136         qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "no change:" << mSelectedStructures;
137     }
138 }
139 
rebuildPluginSelectorEntries()140 void StructuresManagerView::rebuildPluginSelectorEntries()
141 {
142     mRebuildingPluginsList = true;
143     KPluginInfo::List plugins;
144     KPluginInfo::List dynamicPlugins;
145     const auto structureDefs = mTool->manager()->structureDefs();
146     for (const Kasten::StructureDefinitionFile* def : structureDefs) {
147         KPluginInfo info = def->pluginInfo();
148         if (info.category() == QLatin1String("structure")) {
149             plugins.append(info);
150         } else if (info.category() == QLatin1String("structure/js")) {
151             dynamicPlugins.append(info);
152         }
153     }
154 
155     // XXX is there any way to clear the plugins selector?
156     auto* layoutObj = qobject_cast<QBoxLayout*>(layout());
157     Q_CHECK_PTR(layoutObj);
158     if (mStructuresSelector) {
159         layoutObj->removeWidget(mStructuresSelector);
160         delete mStructuresSelector;
161     }
162     mStructuresSelector = new KPluginSelector(this);
163     connect(mStructuresSelector, &KPluginSelector::changed,
164             this, &StructuresManagerView::onPluginSelectorChange);
165     layoutObj->insertWidget(0, mStructuresSelector);
166 
167     mStructuresSelector->addPlugins(plugins, KPluginSelector::ReadConfigFile,
168                                     i18n("Structure Definitions"), QStringLiteral("structure"),
169                                     mTool->manager()->config());
170     mStructuresSelector->addPlugins(dynamicPlugins, KPluginSelector::ReadConfigFile,
171                                     i18n("Dynamic Structure Definitions"), QStringLiteral("structure/js"),
172                                     mTool->manager()->config());
173     mStructuresSelector->load();
174     mStructuresSelector->updatePluginsState();
175     mRebuildingPluginsList = false;
176     reloadSelectedItems();
177 }
178