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