]> cloud.milkyroute.net Git - dolphin.git/blob - src/settings/services/servicessettingspage.cpp
fe900bc5c9943ff50cc4ddcaf7777beb25e42a55
[dolphin.git] / src / settings / services / servicessettingspage.cpp
1 /***************************************************************************
2 * Copyright (C) 2009-2010 by Peter Penz <peter.penz19@gmail.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
19
20 #include "servicessettingspage.h"
21
22 #include "dolphin_generalsettings.h"
23 #include "dolphin_versioncontrolsettings.h"
24 #include "settings/serviceitemdelegate.h"
25 #include "settings/servicemodel.h"
26
27 #include <KDesktopFile>
28 #include <KLocalizedString>
29 #include <KMessageBox>
30 #include <KNS3/Button>
31 #include <KPluginMetaData>
32 #include <KService>
33 #include <KServiceTypeTrader>
34 #include <kdesktopfileactions.h>
35
36 #include <QGridLayout>
37 #include <QLabel>
38 #include <QListWidget>
39 #include <QShowEvent>
40 #include <QSortFilterProxyModel>
41
42 namespace
43 {
44 const bool ShowDeleteDefault = false;
45 const char VersionControlServicePrefix[] = "_version_control_";
46 const char DeleteService[] = "_delete";
47 const char CopyToMoveToService[] ="_copy_to_move_to";
48 }
49
50 ServicesSettingsPage::ServicesSettingsPage(QWidget* parent) :
51 SettingsPageBase(parent),
52 m_initialized(false),
53 m_serviceModel(nullptr),
54 m_sortModel(nullptr),
55 m_listView(nullptr),
56 m_enabledVcsPlugins()
57 {
58 QVBoxLayout* topLayout = new QVBoxLayout(this);
59
60 QLabel* label = new QLabel(i18nc("@label:textbox",
61 "Select which services should "
62 "be shown in the context menu:"), this);
63 label->setWordWrap(true);
64
65 m_listView = new QListView(this);
66 ServiceItemDelegate* delegate = new ServiceItemDelegate(m_listView, m_listView);
67 m_serviceModel = new ServiceModel(this);
68 m_sortModel = new QSortFilterProxyModel(this);
69 m_sortModel->setSourceModel(m_serviceModel);
70 m_sortModel->setSortRole(Qt::DisplayRole);
71 m_sortModel->setSortLocaleAware(true);
72 m_listView->setModel(m_sortModel);
73 m_listView->setItemDelegate(delegate);
74 m_listView->setVerticalScrollMode(QListView::ScrollPerPixel);
75 connect(m_listView, &QListView::clicked, this, &ServicesSettingsPage::changed);
76
77 KNS3::Button* downloadButton = new KNS3::Button(i18nc("@action:button", "Download New Services..."),
78 QStringLiteral("servicemenu.knsrc"),
79 this);
80 connect(downloadButton, &KNS3::Button::dialogFinished, this, &ServicesSettingsPage::loadServices);
81
82 topLayout->addWidget(label);
83 topLayout->addWidget(m_listView);
84 topLayout->addWidget(downloadButton);
85
86 m_enabledVcsPlugins = VersionControlSettings::enabledPlugins();
87 std::sort(m_enabledVcsPlugins.begin(), m_enabledVcsPlugins.end());
88 }
89
90 ServicesSettingsPage::~ServicesSettingsPage()
91 {
92 }
93
94 void ServicesSettingsPage::applySettings()
95 {
96 if (!m_initialized) {
97 return;
98 }
99
100 KConfig config(QStringLiteral("kservicemenurc"), KConfig::NoGlobals);
101 KConfigGroup showGroup = config.group("Show");
102
103 QStringList enabledPlugins;
104
105 const QAbstractItemModel* model = m_listView->model();
106 for (int i = 0; i < model->rowCount(); ++i) {
107 const QModelIndex index = model->index(i, 0);
108 const QString service = model->data(index, ServiceModel::DesktopEntryNameRole).toString();
109 const bool checked = model->data(index, Qt::CheckStateRole).toBool();
110
111 if (service.startsWith(VersionControlServicePrefix)) {
112 if (checked) {
113 enabledPlugins.append(model->data(index, Qt::DisplayRole).toString());
114 }
115 } else if (service == QLatin1String(DeleteService)) {
116 KSharedConfig::Ptr globalConfig = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::NoGlobals);
117 KConfigGroup configGroup(globalConfig, "KDE");
118 configGroup.writeEntry("ShowDeleteCommand", checked);
119 configGroup.sync();
120 } else if (service == QLatin1String(CopyToMoveToService)) {
121 GeneralSettings::setShowCopyMoveMenu(checked);
122 GeneralSettings::self()->save();
123 } else {
124 showGroup.writeEntry(service, checked);
125 }
126 }
127
128 showGroup.sync();
129
130 if (m_enabledVcsPlugins != enabledPlugins) {
131 VersionControlSettings::setEnabledPlugins(enabledPlugins);
132 VersionControlSettings::self()->save();
133
134 KMessageBox::information(window(),
135 i18nc("@info", "Dolphin must be restarted to apply the "
136 "updated version control systems settings."),
137 QString(), // default title
138 QStringLiteral("ShowVcsRestartInformation"));
139 }
140 }
141
142 void ServicesSettingsPage::restoreDefaults()
143 {
144 QAbstractItemModel* model = m_listView->model();
145 for (int i = 0; i < model->rowCount(); ++i) {
146 const QModelIndex index = model->index(i, 0);
147 const QString service = model->data(index, ServiceModel::DesktopEntryNameRole).toString();
148
149 const bool checked = !service.startsWith(VersionControlServicePrefix)
150 && service != QLatin1String(DeleteService)
151 && service != QLatin1String(CopyToMoveToService);
152 model->setData(index, checked, Qt::CheckStateRole);
153 }
154 }
155
156 void ServicesSettingsPage::showEvent(QShowEvent* event)
157 {
158 if (!event->spontaneous() && !m_initialized) {
159 loadServices();
160
161 loadVersionControlSystems();
162
163 // Add "Show 'Delete' command" as service
164 KSharedConfig::Ptr globalConfig = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::IncludeGlobals);
165 KConfigGroup configGroup(globalConfig, "KDE");
166 addRow(QStringLiteral("edit-delete"),
167 i18nc("@option:check", "Delete"),
168 DeleteService,
169 configGroup.readEntry("ShowDeleteCommand", ShowDeleteDefault));
170
171 // Add "Show 'Copy To' and 'Move To' commands" as service
172 addRow(QStringLiteral("edit-copy"),
173 i18nc("@option:check", "'Copy To' and 'Move To' commands"),
174 CopyToMoveToService,
175 GeneralSettings::showCopyMoveMenu());
176
177 m_sortModel->sort(Qt::DisplayRole);
178
179 m_initialized = true;
180 }
181 SettingsPageBase::showEvent(event);
182 }
183
184 void ServicesSettingsPage::loadServices()
185 {
186 const KConfig config(QStringLiteral("kservicemenurc"), KConfig::NoGlobals);
187 const KConfigGroup showGroup = config.group("Show");
188
189 // Load generic services
190 const KService::List entries = KServiceTypeTrader::self()->query(QStringLiteral("KonqPopupMenu/Plugin"));
191 foreach (const KService::Ptr& service, entries) {
192 const QString file = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kservices5/" % service->entryPath());
193 const QList<KServiceAction> serviceActions =
194 KDesktopFileActions::userDefinedServices(file, true);
195
196 KDesktopFile desktopFile(file);
197 const QString subMenuName = desktopFile.desktopGroup().readEntry("X-KDE-Submenu");
198
199 foreach (const KServiceAction& action, serviceActions) {
200 const QString serviceName = action.name();
201 const bool addService = !action.noDisplay()
202 && !action.isSeparator()
203 && !isInServicesList(serviceName);
204
205 if (addService) {
206 const QString itemName = subMenuName.isEmpty()
207 ? action.text()
208 : i18nc("@item:inmenu", "%1: %2", subMenuName, action.text());
209 const bool checked = showGroup.readEntry(serviceName, true);
210 addRow(action.icon(), itemName, serviceName, checked);
211 }
212 }
213 }
214
215 // Load service plugins that implement the KFileItemActionPlugin interface
216 const KService::List pluginServices = KServiceTypeTrader::self()->query(QStringLiteral("KFileItemAction/Plugin"));
217 foreach (const KService::Ptr& service, pluginServices) {
218 const QString desktopEntryName = service->desktopEntryName();
219 if (!isInServicesList(desktopEntryName)) {
220 const bool checked = showGroup.readEntry(desktopEntryName, true);
221 addRow(service->icon(), service->name(), desktopEntryName, checked);
222 }
223 }
224
225 // Load JSON-based plugins that implement the KFileItemActionPlugin interface
226 const auto jsonPlugins = KPluginLoader::findPlugins(QStringLiteral("kf5/kfileitemaction"), [](const KPluginMetaData& metaData) {
227 return metaData.serviceTypes().contains(QLatin1String("KFileItemAction/Plugin"));
228 });
229
230 foreach (const auto& jsonMetadata, jsonPlugins) {
231 const QString desktopEntryName = jsonMetadata.pluginId();
232 if (!isInServicesList(desktopEntryName)) {
233 const bool checked = showGroup.readEntry(desktopEntryName, true);
234 addRow(jsonMetadata.iconName(), jsonMetadata.name(), desktopEntryName, checked);
235 }
236 }
237
238 m_sortModel->sort(Qt::DisplayRole);
239 }
240
241 void ServicesSettingsPage::loadVersionControlSystems()
242 {
243 const QStringList enabledPlugins = VersionControlSettings::enabledPlugins();
244
245 // Create a checkbox for each available version control plugin
246 const KService::List pluginServices = KServiceTypeTrader::self()->query(QStringLiteral("FileViewVersionControlPlugin"));
247 for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) {
248 const QString pluginName = (*it)->name();
249 addRow(QStringLiteral("code-class"),
250 pluginName,
251 VersionControlServicePrefix + pluginName,
252 enabledPlugins.contains(pluginName));
253 }
254
255 m_sortModel->sort(Qt::DisplayRole);
256 }
257
258 bool ServicesSettingsPage::isInServicesList(const QString& service) const
259 {
260 for (int i = 0; i < m_serviceModel->rowCount(); ++i) {
261 const QModelIndex index = m_serviceModel->index(i, 0);
262 if (m_serviceModel->data(index, ServiceModel::DesktopEntryNameRole).toString() == service) {
263 return true;
264 }
265 }
266 return false;
267 }
268
269 void ServicesSettingsPage::addRow(const QString& icon,
270 const QString& text,
271 const QString& value,
272 bool checked)
273 {
274 m_serviceModel->insertRow(0);
275
276 const QModelIndex index = m_serviceModel->index(0, 0);
277 m_serviceModel->setData(index, icon, Qt::DecorationRole);
278 m_serviceModel->setData(index, text, Qt::DisplayRole);
279 m_serviceModel->setData(index, value, ServiceModel::DesktopEntryNameRole);
280 m_serviceModel->setData(index, checked, Qt::CheckStateRole);
281 }
282