From e4366d34934aa79ca9120ed88803a1d3927f6c4e Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Fri, 8 Sep 2023 19:25:44 +0300 Subject: [PATCH] soliduiserver: implement feature to execute actions under certain conditions can implement condition for when device changes occurs too but I have no plans to use it for something, not yet that is. the remove condition can (and probably will be) used to start kvkbd when there is no keyboard plugged in altough that will require program to check when to do that Signed-off-by: Ivailo Monev --- kcontrol/input/mouse_new.desktop | 1 + kcontrol/joystick/joystick_new.desktop | 1 + kcontrol/keyboard/keyboard_new.desktop | 1 + kioslave/camera/solid_camera.desktop | 1 + kioslave/mtp/solid_mtp.desktop | 1 + plasma/runners/solid/solidrunner.cpp | 11 ++++++++-- soliduiserver/actions/openinwindow.desktop | 1 + soliduiserver/soliduidialog.cpp | 4 +++- soliduiserver/soliduidialog.h | 2 ++ soliduiserver/soliduiserver.cpp | 25 ++++++++++++++-------- soliduiserver/soliduiserver_common.h | 8 +++---- 11 files changed, 40 insertions(+), 16 deletions(-) diff --git a/kcontrol/input/mouse_new.desktop b/kcontrol/input/mouse_new.desktop index 58ae4941..a287d549 100644 --- a/kcontrol/input/mouse_new.desktop +++ b/kcontrol/input/mouse_new.desktop @@ -1,5 +1,6 @@ [Desktop Entry] X-KDE-Solid-Predicate=Input.inputType == 'Mouse' +X-KDE-Solid-When=Add Type=Service Actions=configure; diff --git a/kcontrol/joystick/joystick_new.desktop b/kcontrol/joystick/joystick_new.desktop index 712f4eb6..7096524e 100644 --- a/kcontrol/joystick/joystick_new.desktop +++ b/kcontrol/joystick/joystick_new.desktop @@ -1,5 +1,6 @@ [Desktop Entry] X-KDE-Solid-Predicate=Input.inputType == 'Joystick' +X-KDE-Solid-When=Add Type=Service Actions=configure; diff --git a/kcontrol/keyboard/keyboard_new.desktop b/kcontrol/keyboard/keyboard_new.desktop index 2ee3d503..f0d2903c 100644 --- a/kcontrol/keyboard/keyboard_new.desktop +++ b/kcontrol/keyboard/keyboard_new.desktop @@ -1,5 +1,6 @@ [Desktop Entry] X-KDE-Solid-Predicate=Input.inputType == 'Keyboard' +X-KDE-Solid-When=Add Type=Service Actions=configure; diff --git a/kioslave/camera/solid_camera.desktop b/kioslave/camera/solid_camera.desktop index ce419407..f9539fe4 100644 --- a/kioslave/camera/solid_camera.desktop +++ b/kioslave/camera/solid_camera.desktop @@ -1,5 +1,6 @@ [Desktop Entry] X-KDE-Solid-Predicate=Camera.supportedDrivers == 'gphoto' +X-KDE-Solid-When=Add,Search Type=Service Actions=open; diff --git a/kioslave/mtp/solid_mtp.desktop b/kioslave/mtp/solid_mtp.desktop index a4fe5a3a..408654a5 100644 --- a/kioslave/mtp/solid_mtp.desktop +++ b/kioslave/mtp/solid_mtp.desktop @@ -1,5 +1,6 @@ [Desktop Entry] X-KDE-Solid-Predicate=PortableMediaPlayer.supportedProtocols == 'mtp' +X-KDE-Solid-When=Add,Search Type=Service Actions=open; diff --git a/plasma/runners/solid/solidrunner.cpp b/plasma/runners/solid/solidrunner.cpp index e1566248..d62b01e7 100644 --- a/plasma/runners/solid/solidrunner.cpp +++ b/plasma/runners/solid/solidrunner.cpp @@ -34,6 +34,7 @@ #include static const QChar s_actionidseparator = QChar::fromLatin1('#'); +static const QString s_whensearch = QString::fromLatin1("Search"); static QString kSolidUDI(const QString &matchid) { @@ -98,7 +99,13 @@ QList SolidRunner::actionsForMatch(const Plasma::QueryMatch &match) const QStringList solidactions = KGlobal::dirs()->findAllResources("data", "solid/actions/"); foreach (const QString &solidaction, solidactions) { KDesktopFile kdestopfile(solidaction); - const QString solidpredicatestring = kdestopfile.desktopGroup().readEntry("X-KDE-Solid-Predicate"); + KConfigGroup kconfiggroup = kdestopfile.desktopGroup(); + const QStringList solidwhenlist = kconfiggroup.readEntry("X-KDE-Solid-When", QStringList()); + if (!solidwhenlist.contains(s_whensearch)) { + continue; + } + + const QString solidpredicatestring = kconfiggroup.readEntry("X-KDE-Solid-Predicate"); const Solid::Predicate solidpredicate = Solid::Predicate::fromString(solidpredicatestring); if (solidpredicate.matches(soliddevice)) { const QList kserviceactions = KDesktopFileActions::userDefinedServices(solidaction, true); @@ -214,7 +221,7 @@ void SolidRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryM const QList kserviceactions = KDesktopFileActions::userDefinedServices(actionfilepath, true); foreach (const KServiceAction &kserviceaction, kserviceactions) { if (kserviceaction.name() == actionname) { - QStringList actioncommand = kSolidActionCommand(kserviceaction.exec(), kSolidUDI(match.id())); + QStringList actioncommand = kSolidActionCommand(kserviceaction.exec(), kSolidUDI(match.id()), true); if (actioncommand.size() == 0) { kWarning() << "invalid action command" << actionname << "in" << actionfilepath; return; diff --git a/soliduiserver/actions/openinwindow.desktop b/soliduiserver/actions/openinwindow.desktop index 973cbd99..0e0ae44e 100644 --- a/soliduiserver/actions/openinwindow.desktop +++ b/soliduiserver/actions/openinwindow.desktop @@ -1,5 +1,6 @@ [Desktop Entry] X-KDE-Solid-Predicate=[ [ [ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ] ] OR [ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ] ] OR StorageAccess.ignored == false ] +X-KDE-Solid-When=Add,Search Type=Service Actions=open; diff --git a/soliduiserver/soliduidialog.cpp b/soliduiserver/soliduidialog.cpp index c76f0b38..02c56411 100644 --- a/soliduiserver/soliduidialog.cpp +++ b/soliduiserver/soliduidialog.cpp @@ -26,10 +26,12 @@ SolidUiDialog::SolidUiDialog(const Solid::Device &soliddevice, const QList &kserviceactions, + const bool mount, QWidget *parent) : KDialog(parent), m_soliddevice(soliddevice), m_serviceactions(kserviceactions), + m_mount(mount), m_mainwidget(nullptr), m_mainlayout(nullptr), m_devicepixmap(nullptr), @@ -111,7 +113,7 @@ void SolidUiDialog::slotOkClicked() const QListWidgetItem* selecteditem = selecteditems.first(); const int kserviceactionindex = selecteditem->data(Qt::UserRole).toInt(); Q_ASSERT(kserviceactionindex >= 0 && kserviceactionindex < m_serviceactions.size()); - kExecuteAction(m_serviceactions.at(kserviceactionindex), m_soliddevice.udi()); + kExecuteAction(m_serviceactions.at(kserviceactionindex), m_soliddevice.udi(), m_mount); } #include "moc_soliduidialog.cpp" diff --git a/soliduiserver/soliduidialog.h b/soliduiserver/soliduidialog.h index d6050f43..e07b1247 100644 --- a/soliduiserver/soliduidialog.h +++ b/soliduiserver/soliduidialog.h @@ -33,6 +33,7 @@ class SolidUiDialog : public KDialog public: SolidUiDialog(const Solid::Device &soliddevce, const QList &kserviceactions, + const bool mount, QWidget *parent = nullptr); ~SolidUiDialog(); @@ -43,6 +44,7 @@ private Q_SLOTS: private: Solid::Device m_soliddevice; QList m_serviceactions; + bool m_mount; QWidget* m_mainwidget; QGridLayout* m_mainlayout; KPixmapWidget* m_devicepixmap; diff --git a/soliduiserver/soliduiserver.cpp b/soliduiserver/soliduiserver.cpp index 2aef416e..21189047 100644 --- a/soliduiserver/soliduiserver.cpp +++ b/soliduiserver/soliduiserver.cpp @@ -42,8 +42,9 @@ #include -K_PLUGIN_FACTORY(SolidUiServerFactory, registerPlugin();) -K_EXPORT_PLUGIN(SolidUiServerFactory("soliduiserver")) + +static const QString s_whenadd = QString::fromLatin1("Add"); +static const QString s_whenremove = QString::fromLatin1("Remove"); static void kNotifyError(const Solid::ErrorType error, const bool unmount) { @@ -51,6 +52,9 @@ static void kNotifyError(const Solid::ErrorType error, const bool unmount) KNotification::event("soliduiserver/mounterror", title, Solid::errorString(error)); } +K_PLUGIN_FACTORY(SolidUiServerFactory, registerPlugin();) +K_EXPORT_PLUGIN(SolidUiServerFactory("soliduiserver")) + SolidUiServer::SolidUiServer(QObject* parent, const QList&) : KDEDModule(parent) { @@ -250,22 +254,26 @@ QString SolidUiServer::errorString(const int error) void SolidUiServer::handleActions(const Solid::Device &soliddevice, const bool added) { - // TODO: check if the actions are for when device is added or removed - Q_UNUSED(added); QList kserviceactions; const QStringList solidactions = KGlobal::dirs()->findAllResources("data", "solid/actions/"); foreach (const QString &solidaction, solidactions) { KDesktopFile kdestopfile(solidaction); - const QString solidpredicatestring = kdestopfile.desktopGroup().readEntry("X-KDE-Solid-Predicate"); + KConfigGroup kconfiggroup = kdestopfile.desktopGroup(); + const QStringList solidwhenlist = kconfiggroup.readEntry("X-KDE-Solid-When", QStringList()); + if (!solidwhenlist.contains(added ? s_whenadd : s_whenremove)) { + continue; + } + + const QString solidpredicatestring = kconfiggroup.readEntry("X-KDE-Solid-Predicate"); const Solid::Predicate solidpredicate = Solid::Predicate::fromString(solidpredicatestring); if (solidpredicate.matches(soliddevice)) { kserviceactions.append(KDesktopFileActions::userDefinedServices(solidaction, true)); } } if (kserviceactions.size() == 1) { - kExecuteAction(kserviceactions.first(), soliddevice.udi()); + kExecuteAction(kserviceactions.first(), soliddevice.udi(), added); } else if (!kserviceactions.isEmpty()) { - SolidUiDialog* soliddialog = new SolidUiDialog(soliddevice, kserviceactions); + SolidUiDialog* soliddialog = new SolidUiDialog(soliddevice, kserviceactions, added); connect(soliddialog, SIGNAL(finished(int)), this, SLOT(slotDialogFinished())); m_soliddialogs.append(soliddialog); soliddialog->show(); @@ -285,8 +293,7 @@ void SolidUiServer::slotDeviceRemoved(const QString &udi) QMutableListIterator iter(m_soliddevices); while (iter.hasNext()) { Solid::Device soliddevice = iter.next(); - // TODO: enable once add and remove are checked for, see above - // handleActions(soliddevice, false); + handleActions(soliddevice, false); if (soliddevice.udi() == udi) { iter.remove(); } diff --git a/soliduiserver/soliduiserver_common.h b/soliduiserver/soliduiserver_common.h index e99a45b1..e6c79d5b 100644 --- a/soliduiserver/soliduiserver_common.h +++ b/soliduiserver/soliduiserver_common.h @@ -61,11 +61,11 @@ static void kSolidEjectUDI(const QString &solidudi) } // simplified version of KMacroExpander specialized for solid actions -static QStringList kSolidActionCommand(const QString &command, const QString &solidudi) +static QStringList kSolidActionCommand(const QString &command, const QString &solidudi, const bool mount) { Solid::Device soliddevice(solidudi); Solid::StorageAccess* solidstorageacces = soliddevice.as(); - if (solidstorageacces && !solidstorageacces->isAccessible()) { + if (mount && solidstorageacces && !solidstorageacces->isAccessible()) { kSolidMountUDI(solidudi); } @@ -97,9 +97,9 @@ static QStringList kSolidActionCommand(const QString &command, const QString &so return KShell::splitArgs(actioncommand); } -static void kExecuteAction(const KServiceAction &kserviceaction, const QString &solidudi) +static void kExecuteAction(const KServiceAction &kserviceaction, const QString &solidudi, const bool mount) { - QStringList actioncommand = kSolidActionCommand(kserviceaction.exec(), solidudi); + QStringList actioncommand = kSolidActionCommand(kserviceaction.exec(), solidudi, mount); if (actioncommand.size() == 0) { kWarning() << "invalid action command" << kserviceaction.name(); return;