kdeconnect-kde/plugins/runcommand/runcommand_config.cpp
Waldo Lemmer 2dc5d53ec4 Support init systems other than systemd with Run Command's samples
`systemctl reboot`, `systemctl poweroff` and `systemctl suspend` only work on Systemd

I replaced them with the more universal versions (`reboot`, `poweroff`, and `suspend`) which work on Systemd, OpenRC, runit, SysVinit, and GNU Shepherd. These commands show up here:

![image](/uploads/b10ae0397974c90971d8cd054d13e1b4/image.png)
2022-04-21 01:02:10 +00:00

183 lines
6.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* SPDX-FileCopyrightText: 2015 David Edmundson <davidedmundson@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "runcommand_config.h"
#include <QTableView>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QPushButton>
#include <QMenu>
#include <QStandardItemModel>
#include <QDebug>
#include <QUuid>
#include <QJsonDocument>
#include <QStandardPaths>
#include <KLocalizedString>
#include <KPluginFactory>
#include <dbushelper.h>
K_PLUGIN_FACTORY(ShareConfigFactory, registerPlugin<RunCommandConfig>();)
RunCommandConfig::RunCommandConfig(QWidget* parent, const QVariantList& args)
: KdeConnectPluginKcm(parent, args, QStringLiteral("kdeconnect_runcommand"))
{
// The qdbus executable name is different on some systems
QString qdbusExe = QStringLiteral("qdbus-qt5");
if (QStandardPaths::findExecutable(qdbusExe).isEmpty()) {
qdbusExe = QStringLiteral("qdbus");
}
QMenu* defaultMenu = new QMenu(this);
#ifdef Q_OS_WIN
addSuggestedCommand(defaultMenu, i18n("Schedule a shutdown"), QStringLiteral("shutdown /s /t 60"));
addSuggestedCommand(defaultMenu, i18n("Shutdown now"), QStringLiteral("shutdown /s /t 0"));
addSuggestedCommand(defaultMenu, i18n("Cancel last shutdown"), QStringLiteral("shutdown /a"));
addSuggestedCommand(defaultMenu, i18n("Schedule a reboot"), QStringLiteral("shutdown /r /t 60"));
addSuggestedCommand(defaultMenu, i18n("Suspend"), QStringLiteral("rundll32.exe powrprof.dll,SetSuspendState 0,1,0"));
addSuggestedCommand(defaultMenu, i18n("Lock Screen"), QStringLiteral("rundll32.exe user32.dll,LockWorkStation"));
addSuggestedCommand(defaultMenu, i18n("Say Hello"), QStringLiteral("PowerShell -Command \"Add-Type AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak('hello');\""));
#else
addSuggestedCommand(defaultMenu, i18n("Shutdown"), QStringLiteral("poweroff"));
addSuggestedCommand(defaultMenu, i18n("Reboot"), QStringLiteral("reboot"));
addSuggestedCommand(defaultMenu, i18n("Suspend"), QStringLiteral("suspend"));
addSuggestedCommand(defaultMenu, i18n("Maximum Brightness"), QStringLiteral("%0 org.kde.Solid.PowerManagement /org/kde/Solid/PowerManagement/Actions/BrightnessControl org.kde.Solid.PowerManagement.Actions.BrightnessControl.setBrightness `%0 org.kde.Solid.PowerManagement /org/kde/Solid/PowerManagement/Actions/BrightnessControl org.kde.Solid.PowerManagement.Actions.BrightnessControl.brightnessMax`").arg(qdbusExe));
addSuggestedCommand(defaultMenu, i18n("Lock Screen"), QStringLiteral("loginctl lock-session"));
addSuggestedCommand(defaultMenu, i18n("Unlock Screen"), QStringLiteral("loginctl unlock-session"));
addSuggestedCommand(defaultMenu, i18n("Close All Vaults"), QStringLiteral("%0 org.kde.kded5 /modules/plasmavault closeAllVaults").arg(qdbusExe));
addSuggestedCommand(defaultMenu, i18n("Forcefully Close All Vaults"), QStringLiteral("%0 org.kde.kded5 /modules/plasmavault forceCloseAllVaults").arg(qdbusExe));
#endif
QTableView* table = new QTableView(this);
table->horizontalHeader()->setStretchLastSection(true);
table->verticalHeader()->setVisible(false);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(table);
QPushButton* button = new QPushButton(QIcon::fromTheme(QStringLiteral("list-add")), i18n("Sample commands"), this);
button->setMenu(defaultMenu);
layout->addWidget(button);
setLayout(layout);
m_entriesModel = new QStandardItemModel(this);
table->setModel(m_entriesModel);
m_entriesModel->setHorizontalHeaderLabels(QStringList() << i18n("Name") << i18n("Command"));
}
RunCommandConfig::~RunCommandConfig()
{
}
void RunCommandConfig::addSuggestedCommand(QMenu* menu, const QString &name, const QString &command)
{
auto action = new QAction(name);
connect(action, &QAction::triggered, action, [this, name, command]() {
insertRow(0, name, command);
Q_EMIT changed(true);
});
menu->addAction(action);
}
void RunCommandConfig::defaults()
{
KCModule::defaults();
m_entriesModel->removeRows(0,m_entriesModel->rowCount());
Q_EMIT changed(true);
}
void RunCommandConfig::load()
{
KCModule::load();
QJsonDocument jsonDocument = QJsonDocument::fromJson(config()->getByteArray(QStringLiteral("commands"), "{}"));
QJsonObject jsonConfig = jsonDocument.object();
const QStringList keys = jsonConfig.keys();
for (const QString& key : keys) {
const QJsonObject entry = jsonConfig[key].toObject();
const QString name = entry[QStringLiteral("name")].toString();
const QString command = entry[QStringLiteral("command")].toString();
QStandardItem* newName = new QStandardItem(name);
newName->setEditable(true);
newName->setData(key);
QStandardItem* newCommand = new QStandardItem(command);
newName->setEditable(true);
m_entriesModel->appendRow(QList<QStandardItem*>() << newName << newCommand);
}
m_entriesModel->sort(0);
insertEmptyRow();
connect(m_entriesModel, &QAbstractItemModel::dataChanged, this, &RunCommandConfig::onDataChanged);
Q_EMIT changed(false);
}
void RunCommandConfig::save()
{
QJsonObject jsonConfig;
for (int i=0;i < m_entriesModel->rowCount(); i++) {
QString key = m_entriesModel->item(i, 0)->data().toString();
const QString name = m_entriesModel->item(i, 0)->text();
const QString command = m_entriesModel->item(i, 1)->text();
if (name.isEmpty() || command.isEmpty()) {
continue;
}
if (key.isEmpty()) {
key = QUuid::createUuid().toString();
DBusHelper::filterNonExportableCharacters(key);
}
QJsonObject entry;
entry[QStringLiteral("name")] = name;
entry[QStringLiteral("command")] = command;
jsonConfig[key] = entry;
}
QJsonDocument document;
document.setObject(jsonConfig);
config()->set(QStringLiteral("commands"), document.toJson(QJsonDocument::Compact));
KCModule::save();
Q_EMIT changed(false);
}
void RunCommandConfig::insertEmptyRow()
{
insertRow(m_entriesModel->rowCount(), {}, {});
}
void RunCommandConfig::insertRow(int i, const QString& name, const QString& command)
{
QStandardItem* newName = new QStandardItem(name);
newName->setEditable(true);
QStandardItem* newCommand = new QStandardItem(command);
newName->setEditable(true);
m_entriesModel->insertRow(i, QList<QStandardItem*>() << newName << newCommand);
}
void RunCommandConfig::onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
Q_EMIT changed(true);
Q_UNUSED(topLeft);
if (bottomRight.row() == m_entriesModel->rowCount() - 1) {
//TODO check both entries are still empty
insertEmptyRow();
}
}
#include "runcommand_config.moc"