move SolidUiServer::showActionsDialog to hotplug dataengine

Summary:
it was the only remaining user of that dialog helper.
the connection between the two was fairly meh. the engine would invoke the
kded module over dbus, the module would then process the request, find that
only one desktop entry is specified, resulting in one action being found
and then running that action on behalf of the engine. this is overly
complicated for no additional gain. the engine is the sole user of this
functionality AND it already had knowledge of the service system, so
soliduiserver in this case doesn't actually add anything. it's just a more
involved call chain.

the useful code of soliduiserver is now in the hotplug dataengine directly
and the soliduiserver no longer supports the actions dialog. hotplug is now
the sole authority for hotplugging.

soliduiserver:
- include cleanup
- all classes no longer in use have been removed
- kdelibs4support is no longer a link target
- new link targets i18n + widgetsaddons (previously pulled in by
  kdelibs4support)

hotplug:
- hotplugjob now directly executes service actions using classes imported
  from soliduiserver
- no longer links qtdbus
- new translation domain plasma_engine_hotplug (for i18n call in imported
  service classes)
- new link against ki18n for that reason

Test Plan: running an action works same as before, internally it no longer relies on dbus/kded

Reviewers: broulik

Reviewed By: broulik

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D21761
wilder-5.17
Harald Sitter 7 years ago
parent 8c3838eda4
commit f67d61b391
  1. 24
      dataengines/hotplug/CMakeLists.txt
  2. 2
      dataengines/hotplug/Messages.sh
  3. 0
      dataengines/hotplug/deviceaction.cpp
  4. 0
      dataengines/hotplug/deviceaction.h
  5. 1
      dataengines/hotplug/deviceserviceaction.cpp
  6. 0
      dataengines/hotplug/deviceserviceaction.h
  7. 44
      dataengines/hotplug/hotplugjob.cpp
  8. 16
      soliduiserver/CMakeLists.txt
  9. 125
      soliduiserver/deviceactionsdialog.cpp
  10. 57
      soliduiserver/deviceactionsdialog.h
  11. 94
      soliduiserver/deviceactionsdialogview.ui
  12. 38
      soliduiserver/devicenothingaction.cpp
  13. 34
      soliduiserver/devicenothingaction.h
  14. 78
      soliduiserver/soliduiserver.cpp
  15. 16
      soliduiserver/soliduiserver.h

@ -1,4 +1,8 @@
add_definitions(-DTRANSLATION_DOMAIN=\"plasma_engine_hotplug\")
set(hotplug_engine_SRCS
deviceaction.cpp
deviceserviceaction.cpp
hotplugengine.cpp
hotplugservice.cpp
hotplugjob.cpp
@ -6,17 +10,17 @@ set(hotplug_engine_SRCS
add_library(plasma_engine_hotplug MODULE ${hotplug_engine_SRCS})
target_link_libraries(plasma_engine_hotplug
Qt5::DBus
KF5::CoreAddons
KF5::Plasma
KF5::Solid
KF5::Service
KF5::KIOCore
KF5::KIOWidgets
)
KF5::CoreAddons
KF5::Plasma
KF5::Solid
KF5::Service
KF5::KIOCore
KF5::KIOWidgets
KF5::I18n
)
kcoreaddons_desktop_to_json(plasma_engine_hotplug plasma-dataengine-hotplug.desktop)
install(TARGETS plasma_engine_hotplug DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/dataengine)
install(FILES plasma-dataengine-hotplug.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} )
install(FILES hotplug.operations DESTINATION ${PLASMA_DATA_INSTALL_DIR}/services )
install(FILES plasma-dataengine-hotplug.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
install(FILES hotplug.operations DESTINATION ${PLASMA_DATA_INSTALL_DIR}/services)

@ -0,0 +1,2 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/plasma_engine_hotplug.pot

@ -27,7 +27,6 @@
#include <solid/storageaccess.h>
#include <solid/block.h>
class MacroExpander : public KMacroExpanderBase
{
public:

@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Viranch Mehta <viranch.mehta@gmail.com>
* Copyright (C) 2019 Harald Sitter <sitter@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
@ -19,29 +20,36 @@
#include "hotplugjob.h"
#include "hotplugengine.h"
#include <QDBusInterface>
#include <QDBusReply>
#include "deviceserviceaction.h"
#include <QDebug>
#include <QStandardPaths>
#include <KDesktopFileActions>
#include <KLocalizedString>
void HotplugJob::start()
{
QString udi (m_dest);
QString operation = operationName();
if (operation == QLatin1String("invokeAction")) {
QString action = parameters()[QStringLiteral("predicate")].toString();
QStringList desktopFiles;
desktopFiles << action;
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kded5"),
QStringLiteral("/modules/soliduiserver"),
QStringLiteral("org.kde.SolidUiServer"),
QStringLiteral("showActionsDialog"));
msg.setArguments(QList<QVariant>() << udi << desktopFiles);
QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
if (operationName() == QLatin1String("invokeAction")) {
const QString desktopFile = parameters()[QStringLiteral("predicate")].toString();
const QString filePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "solid/actions/" + desktopFile);
QList<KServiceAction> services = KDesktopFileActions::userDefinedServices(filePath, true);
if (services.size() < 1) {
qWarning() << "Failed to resolve hotplugjob action" << desktopFile << filePath;
setError(KJob::UserDefinedError);
setErrorText(i18nc("error; %1 is the desktop file name of the service",
"Failed to resolve service action for %1.", desktopFile));
setResult(false); // calls emitResult internally.
return;
}
// Cannot be > 1, we only have one filePath, and < 1 was handled as error.
Q_ASSERT(services.size() == 1);
DeviceServiceAction action;
action.setService(services.takeFirst());
Solid::Device device(m_dest);
action.execute(device);
}
emitResult();

@ -3,17 +3,19 @@ add_definitions(-DTRANSLATION_DOMAIN=\"soliduiserver5\")
set(kded_soliduiserver_SRCS
soliduiserver.cpp
deviceactionsdialog.cpp
deviceaction.cpp
devicenothingaction.cpp
deviceserviceaction.cpp
)
ki18n_wrap_ui(kded_soliduiserver_SRCS deviceactionsdialogview.ui)
add_library(soliduiserver MODULE ${kded_soliduiserver_SRCS})
kcoreaddons_desktop_to_json(soliduiserver soliduiserver.desktop)
target_link_libraries(soliduiserver KF5::Solid KF5::DBusAddons KF5::Wallet KF5::KIOCore KF5::WindowSystem KF5::KDELibs4Support)
target_link_libraries(soliduiserver
KF5::Solid
KF5::DBusAddons
KF5::Wallet
KF5::KIOCore
KF5::WindowSystem
KF5::I18n
KF5::WidgetsAddons
)
install(TARGETS soliduiserver DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/kded)

@ -1,125 +0,0 @@
/* This file is part of the KDE Project
Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net>
Copyright (c) 2005-2007 Kevin Ottens <ervin@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "deviceactionsdialog.h"
#include <QIcon>
#include <QCheckBox>
#include <QDebug>
#include "deviceaction.h"
#include "ui_deviceactionsdialogview.h"
DeviceActionsDialog::DeviceActionsDialog(QWidget *parent)
: KDialog(parent)
{
qDebug() << Q_FUNC_INFO;
setModal(false);
setButtons(Ok|Cancel);
setDefaultButton(Ok);
QWidget *page = new QWidget(this);
m_view.setupUi(page);
setMainWidget(page);
updateActionsListBox();
resize(QSize(400,400).expandedTo(minimumSizeHint()));
connect(this, &DeviceActionsDialog::okClicked, this, &DeviceActionsDialog::slotOk);
connect(m_view.actionsList, &QListWidget::doubleClicked, this, &DeviceActionsDialog::slotOk);
connect(this, &DeviceActionsDialog::finished, this, &DeviceActionsDialog::delayedDestruct);
}
DeviceActionsDialog::~DeviceActionsDialog()
{
}
void DeviceActionsDialog::setDevice(const Solid::Device &device)
{
m_device = device;
QString label = device.vendor();
if (!label.isEmpty()) label+=' ';
label+= device.product();
setWindowTitle(label);
m_view.iconLabel->setPixmap(QIcon::fromTheme(device.icon()).pixmap(64));
m_view.descriptionLabel->setText(device.vendor()+' '+device.product());
setWindowIcon(QIcon::fromTheme(device.icon()));
}
Solid::Device DeviceActionsDialog::device() const
{
return m_device;
}
void DeviceActionsDialog::setActions(const QList<DeviceAction*> &actions)
{
qDeleteAll(m_actions);
m_actions.clear();
m_actions = actions;
updateActionsListBox();
}
QList<DeviceAction*> DeviceActionsDialog::actions() const
{
return m_actions;
}
void DeviceActionsDialog::updateActionsListBox()
{
m_view.actionsList->clear();
foreach (DeviceAction *action, m_actions) {
QListWidgetItem *item = new QListWidgetItem(QIcon::fromTheme(action->iconName()),
action->label());
item->setData(Qt::UserRole, action->id());
m_view.actionsList->addItem(item);
}
if (m_view.actionsList->count()>0)
m_view.actionsList->item(0)->setSelected(true);
}
void DeviceActionsDialog::slotOk()
{
QListWidgetItem *item = m_view.actionsList->selectedItems().value(0);
if (item) {
const QString id = item->data(Qt::UserRole).toString();
foreach (DeviceAction *action, m_actions) {
if (action->id()==id) {
launchAction(action);
return;
}
}
}
}
void DeviceActionsDialog::launchAction(DeviceAction *action)
{
action->execute(m_device);
accept();
}

@ -1,57 +0,0 @@
/* This file is part of the KDE Project
Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net>
Copyright (c) 2005-2007 Kevin Ottens <ervin@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef DEVICEACTIONSDIALOG_H
#define DEVICEACTIONSDIALOG_H
#include <kdialog.h>
#include <solid/device.h>
#include "ui_deviceactionsdialogview.h"
class DeviceAction;
class DeviceActionsDialog : public KDialog
{
Q_OBJECT
public:
explicit DeviceActionsDialog(QWidget *parent=nullptr);
~DeviceActionsDialog() override;
void setDevice(const Solid::Device &device);
Solid::Device device() const;
void setActions(const QList<DeviceAction*> &actions);
QList<DeviceAction*> actions() const;
private Q_SLOTS:
void slotOk();
private:
void launchAction(DeviceAction *action);
void updateActionsListBox();
Ui::DeviceActionsDialogView m_view;
Solid::Device m_device;
QList<DeviceAction*> m_actions;
};
#endif

@ -1,94 +0,0 @@
<ui version="4.0" >
<class>DeviceActionsDialogView</class>
<widget class="QWidget" name="DeviceActionsDialogView" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>508</width>
<height>480</height>
</rect>
</property>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>15</number>
</property>
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>20</number>
</property>
<item>
<widget class="QLabel" name="iconLabel" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="scaledContents" >
<bool>true</bool>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="textLabel1" >
<property name="text" >
<string>A new device has been detected.&lt;br>&lt;b>What do you want to do?&lt;/b></string>
</property>
<property name="textFormat" >
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="descriptionLabel" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Minimum" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>...</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="actionsList" >
<property name="iconSize" >
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

@ -1,38 +0,0 @@
/* This file is part of the KDE Project
Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net>
Copyright (c) 2005-2007 Kevin Ottens <ervin@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "devicenothingaction.h"
#include <KLocalizedString>
DeviceNothingAction::DeviceNothingAction()
: DeviceAction()
{
setIconName(QStringLiteral("dialog-cancel"));
setLabel(i18n("Do nothing"));
}
QString DeviceNothingAction::id() const
{
return QStringLiteral("#NothingAction");
}
void DeviceNothingAction::execute(Solid::Device &/*device*/)
{
}

@ -1,34 +0,0 @@
/* This file is part of the KDE Project
Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net>
Copyright (c) 2005-2007 Kevin Ottens <ervin@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef DEVICENOTHINGACTION_H
#define DEVICENOTHINGACTION_H
#include "deviceaction.h"
class DeviceNothingAction : public DeviceAction
{
public:
DeviceNothingAction();
QString id() const override;
void execute(Solid::Device &device) override;
};
#endif

@ -22,24 +22,25 @@
#include "soliduiserver.h"
#include "config-X11.h"
#include <QStandardPaths>
#include <QDebug>
#include <QDBusInterface>
#include <QDBusReply>
#include <QIcon>
#include <KPluginFactory>
#include <KLocalizedString>
#include <KUserTimestamp>
#include <kdesktopfileactions.h>
#include <kwindowsystem.h>
#include <kpassworddialog.h>
#include <kwallet.h>
#include <solid/storagevolume.h>
#include "deviceactionsdialog.h"
#include "deviceaction.h"
#include "deviceserviceaction.h"
#include "devicenothingaction.h"
// solid specific includes
#include <solid/devicenotifier.h>
#include <solid/device.h>
#include <solid/deviceinterface.h>
#include <solid/predicate.h>
#include <solid/storagevolume.h>
K_PLUGIN_CLASS_WITH_JSON(SolidUiServer, "soliduiserver.json")
@ -52,69 +53,6 @@ SolidUiServer::~SolidUiServer()
{
}
void SolidUiServer::showActionsDialog(const QString &udi,
const QStringList &desktopFiles)
{
if (m_udiToActionsDialog.contains(udi)) {
DeviceActionsDialog *dialog = m_udiToActionsDialog[udi];
dialog->activateWindow();
return;
}
QList<DeviceAction*> actions;
foreach (const QString &desktop, desktopFiles) {
const QString filePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "solid/actions/"+desktop);
QList<KServiceAction> services = KDesktopFileActions::userDefinedServices(filePath, true);
foreach (const KServiceAction &service, services) {
DeviceServiceAction *action = new DeviceServiceAction();
action->setService(service);
actions << action;
}
}
// Only one action, execute directly
if (actions.size()==1) {
DeviceAction *action = actions.takeFirst();
Solid::Device device(udi);
action->execute(device);
delete action;
return;
}
actions << new DeviceNothingAction();
DeviceActionsDialog *dialog = new DeviceActionsDialog();
dialog->setDevice(Solid::Device(udi));
dialog->setActions(actions);
connect(dialog, &DeviceActionsDialog::finished, this, &SolidUiServer::onActionDialogFinished);
m_udiToActionsDialog[udi] = dialog;
// Update user activity timestamp, otherwise the notification dialog will be shown
// in the background due to focus stealing prevention. Entering a new media can
// be seen as a kind of user activity after all. It'd be better to update the timestamp
// as soon as the media is entered, but it apparently takes some time to get here.
KUserTimestamp::updateUserTimestamp();
dialog->show();
}
void SolidUiServer::onActionDialogFinished()
{
DeviceActionsDialog *dialog = qobject_cast<DeviceActionsDialog*>(sender());
if (dialog) {
QString udi = dialog->device().udi();
m_udiToActionsDialog.remove(udi);
}
}
void SolidUiServer::showPassphraseDialog(const QString &udi,
const QString &returnService, const QString &returnObject,
uint wId, const QString &appId)

@ -21,20 +21,13 @@
#define SOLIDUISERVER_H
#include <kdedmodule.h>
#include <kfileitem.h>
#include <kio/job.h>
#include <QWidget>
#include <qwindowdefs.h>
#include <QMap>
//solid specific includes
#include <solid/devicenotifier.h>
#include <solid/device.h>
#include <solid/deviceinterface.h>
#include <solid/predicate.h>
class DeviceActionsDialog;
class KPasswordDialog;
class QWidget;
class SolidUiServer : public KDEDModule
{
@ -46,23 +39,18 @@ public:
~SolidUiServer() override;
public Q_SLOTS:
Q_SCRIPTABLE void showActionsDialog(const QString &udi,
const QStringList &desktopFiles);
Q_SCRIPTABLE void showPassphraseDialog(const QString &udi,
const QString &returnService, const QString &returnObject,
uint wId, const QString &appId);
private Q_SLOTS:
void onActionDialogFinished();
void onPassphraseDialogCompleted(const QString &pass, bool keep);
void onPassphraseDialogRejected();
private:
void reparentDialog(QWidget *dialog, WId wId, const QString &appId, bool modal);
QMap<QString, DeviceActionsDialog*> m_udiToActionsDialog;
QMap<QString, KPasswordDialog*> m_idToPassphraseDialog;
};
#endif

Loading…
Cancel
Save