Compare commits
No commits in common. "master" and "v0.1.0" have entirely different histories.
@ -47,9 +47,6 @@ AllowAllParametersOfDeclarationOnNextLine: false
|
|||||||
# no single line functions
|
# no single line functions
|
||||||
AllowShortFunctionsOnASingleLine: None
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
|
||||||
# no single line enums
|
|
||||||
AllowShortEnumsOnASingleLine: false
|
|
||||||
|
|
||||||
# always break before you encounter multi line strings
|
# always break before you encounter multi line strings
|
||||||
AlwaysBreakBeforeMultilineStrings: true
|
AlwaysBreakBeforeMultilineStrings: true
|
||||||
|
|
||||||
|
@ -3,32 +3,28 @@ cmake_minimum_required(VERSION 3.16)
|
|||||||
|
|
||||||
project(kcm_openrc)
|
project(kcm_openrc)
|
||||||
|
|
||||||
set(QT_MIN_VERSION "6.4.0")
|
set(QT_MIN_VERSION "5.15.0")
|
||||||
set(KF_MIN_VERSION "6.4.0")
|
set(KF5_MIN_VERSION "5.88.0")
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
|
|
||||||
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
|
||||||
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
|
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
|
||||||
set(GENERATE_MOC ON)
|
set(GENERATE_MOC ON)
|
||||||
|
|
||||||
|
|
||||||
find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
|
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
|
||||||
Core
|
Core
|
||||||
Quick
|
Quick
|
||||||
Svg
|
Svg
|
||||||
DBus
|
DBus
|
||||||
)
|
)
|
||||||
|
|
||||||
if (BUILD_TESTING)
|
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
|
||||||
find_package(Qt6 ${QT_MIN_VERSION} REQUIRED COMPONENTS Test)
|
|
||||||
add_compile_definitions("BUILD_TESTING")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS
|
|
||||||
I18n
|
I18n
|
||||||
KCMUtils
|
KCMUtils
|
||||||
|
Declarative
|
||||||
Config
|
Config
|
||||||
ConfigWidgets
|
ConfigWidgets
|
||||||
Auth
|
Auth
|
||||||
@ -36,58 +32,44 @@ find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS
|
|||||||
|
|
||||||
include(KDEInstallDirs)
|
include(KDEInstallDirs)
|
||||||
include(KDECMakeSettings)
|
include(KDECMakeSettings)
|
||||||
include(KDECompilerSettings NO_POLICY_SCOPE)
|
include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE)
|
||||||
include(FeatureSummary)
|
include(FeatureSummary)
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
set(openrc_kcm_SRCS
|
set(openrc_kcm_SRCS openrc_kcm.cpp)
|
||||||
openrc_kcm.cpp
|
|
||||||
openrc_tree_item.cpp
|
|
||||||
openrc_service_model.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
||||||
|
|
||||||
|
|
||||||
kconfig_add_kcfg_files(openrc_kcm_SRCS GENERATE_MOC openrckcmsettings.kcfgc)
|
kconfig_add_kcfg_files(openrc_kcm_SRCS GENERATE_MOC openrckcmsettings.kcfgc)
|
||||||
kcmutils_add_qml_kcm(kcm_openrc)
|
|
||||||
|
|
||||||
target_sources(kcm_openrc PRIVATE
|
|
||||||
${openrc_kcm_SRCS}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
add_library(kcm_openrc MODULE ${openrc_kcm_SRCS})
|
||||||
add_executable(openrc-actions-kauth openrc_actions.cpp)
|
add_executable(openrc-actions-kauth openrc_actions.cpp)
|
||||||
target_link_libraries(openrc-actions-kauth
|
target_link_libraries(openrc-actions-kauth
|
||||||
Qt6::Core
|
Qt5::Core
|
||||||
Qt6::DBus
|
Qt5::DBus
|
||||||
|
KF5::CoreAddons
|
||||||
KF6::CoreAddons
|
KF5::I18n
|
||||||
KF6::I18n
|
KF5::Auth
|
||||||
KF6::AuthCore
|
|
||||||
|
|
||||||
rc
|
rc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
target_link_libraries(kcm_openrc
|
target_link_libraries(kcm_openrc
|
||||||
Qt6::Core
|
Qt5::Core
|
||||||
Qt6::DBus
|
Qt5::DBus
|
||||||
|
KF5::CoreAddons
|
||||||
KF6::CoreAddons
|
KF5::I18n
|
||||||
KF6::I18n
|
KF5::QuickAddons
|
||||||
KF6::KCMUtilsQuick
|
KF5::ConfigCore
|
||||||
KF6::ConfigCore
|
KF5::ConfigWidgets
|
||||||
KF6::ConfigWidgets
|
KF5::Auth
|
||||||
KF6::AuthCore
|
|
||||||
|
|
||||||
rc
|
rc
|
||||||
)
|
)
|
||||||
|
|
||||||
if (BUILD_TESTING)
|
install(TARGETS openrc-actions-kauth DESTINATION ${KAUTH_HELPER_INSTALL_DIR})
|
||||||
target_link_libraries(kcm_openrc Qt6::Test)
|
install(TARGETS kcm_openrc DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/kcms/systemsettings)
|
||||||
endif()
|
|
||||||
|
|
||||||
# install(TARGETS openrc-actions-kauth DESTINATION ${KAUTH_HELPER_INSTALL_DIR})
|
|
||||||
# install(TARGETS kcm_openrc DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/kcms/systemsettings)
|
|
||||||
|
|
||||||
|
kpackage_install_package(package kcm_openrc kcms)
|
||||||
kauth_install_helper_files(openrc-actions-kauth tridentu.auth.openrc.service root)
|
kauth_install_helper_files(openrc-actions-kauth tridentu.auth.openrc.service root)
|
||||||
kauth_install_actions(tridentu.auth.openrc.service tridentu.auth.openrc.service.actions)
|
kauth_install_actions(tridentu.auth.openrc.service tridentu.auth.openrc.service.actions)
|
||||||
|
4
kcm_openrc.kdev4
Normal file
4
kcm_openrc.kdev4
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[Project]
|
||||||
|
CreatedFrom=CMakeLists.txt
|
||||||
|
Manager=KDevCMakeManager
|
||||||
|
Name=kcm_openrc
|
@ -1,8 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "openrc_actions.h"
|
#include "openrc_actions.h"
|
||||||
#include <KAuth/Action>
|
#include <KAuth/KAuthAction>
|
||||||
#include <KAuth/ExecuteJob>
|
#include <KAuth/KAuthExecuteJob>
|
||||||
#include <rc.h>
|
#include <rc.h>
|
||||||
#include <QProcess>
|
#include <qprocess.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
KAuth::ActionReply OpenRCHelper::removeservice( const QVariantMap& args )
|
KAuth::ActionReply OpenRCHelper::removeservice( const QVariantMap& args )
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#ifndef OPENRC_ACTIONS_H
|
|
||||||
#define OPENRC_ACTIONS_H
|
|
||||||
|
|
||||||
#include <KAuth/ActionReply>
|
|
||||||
#include <KAuth/HelperSupport>
|
#pragma once
|
||||||
|
|
||||||
|
#include <KAuth/KAuthActionReply>
|
||||||
|
#include <KAuth/KAuthHelperSupport>
|
||||||
|
|
||||||
class OpenRCHelper: public QObject {
|
class OpenRCHelper: public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -12,5 +13,3 @@ public Q_SLOTS:
|
|||||||
KAuth::ActionReply restartservice(const QVariantMap& args);
|
KAuth::ActionReply restartservice(const QVariantMap& args);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* OPENRC_ACTIONS_H */
|
|
||||||
|
@ -1,28 +1,29 @@
|
|||||||
#include "openrc_kcm.h"
|
|
||||||
#include "openrc_service_model.h"
|
|
||||||
|
|
||||||
|
#include "openrc_kcm.h"
|
||||||
#include <KPluginFactory>
|
#include <KPluginFactory>
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include "openrckcmsettings.h"
|
#include "openrckcmsettings.h"
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <KAuth/Action>
|
#include <KAuth/KAuthAction>
|
||||||
#include <KAuth/ExecuteJob>
|
#include <KAuth/KAuthExecuteJob>
|
||||||
#include <rc.h>
|
|
||||||
|
|
||||||
K_PLUGIN_CLASS_WITH_JSON(OpenRCKCM, "kcm_openrc.json");
|
K_PLUGIN_CLASS_WITH_JSON(OpenRCKCM, "package/kcm_openrc.json");
|
||||||
|
|
||||||
OpenRCKCM::OpenRCKCM(QObject *parent, const KPluginMetaData &metaData)
|
OpenRCKCM::OpenRCKCM(QObject* parent, const KPluginMetaData& data, const QVariantList& args)
|
||||||
: KQuickManagedConfigModule(parent, metaData)
|
: KQuickAddons::ManagedConfigModule(parent, data, args)
|
||||||
{
|
{
|
||||||
constexpr const char *uri = "org.kde.plasma.kcm.openrc";
|
|
||||||
|
|
||||||
qmlRegisterType<OpenRCServiceModel>(uri, 1, 0, "OpenRCServiceModel");
|
|
||||||
|
|
||||||
setButtons(Help | Apply | Default);
|
setButtons(Help | Apply | Default);
|
||||||
|
KAboutData * aboutData = new KAboutData(QStringLiteral("kcm_openrc"), i18n("OpenRC Settings"));
|
||||||
|
aboutData->addAuthor(QStringLiteral("Tridentu Group"));
|
||||||
|
aboutData->addLicense(KAboutLicense::LGPL_V2);
|
||||||
|
aboutData->setHomepage(QStringLiteral("https://tridentu.github.io/openrc-settings"));
|
||||||
|
|
||||||
|
setAboutData(aboutData);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QStringList OpenRCKCM::getAllServiceTitles() {
|
QStringList OpenRCKCM::getAllServiceTitles(){
|
||||||
QStringList list;
|
QStringList list;
|
||||||
{
|
{
|
||||||
RC_STRINGLIST* listS = rc_services_in_runlevel("default");
|
RC_STRINGLIST* listS = rc_services_in_runlevel("default");
|
||||||
@ -38,7 +39,7 @@ const QStringList OpenRCKCM::getAllServiceTitles() {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QStringList OpenRCKCM::getAllServices() {
|
QStringList OpenRCKCM::getAllServices(){
|
||||||
QStringList list;
|
QStringList list;
|
||||||
{
|
{
|
||||||
RC_STRINGLIST* listS = rc_services_in_runlevel("default");
|
RC_STRINGLIST* listS = rc_services_in_runlevel("default");
|
||||||
|
24
openrc_kcm.h
24
openrc_kcm.h
@ -1,28 +1,28 @@
|
|||||||
#ifndef OPENRC_KCM_H
|
|
||||||
#define OPENRC_KCM_H
|
|
||||||
|
|
||||||
#include <KQuickManagedConfigModule>
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <KQuickAddons/ManagedConfigModule>
|
||||||
|
#include <rc.h>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include "openrckcmsettings.h"
|
#include "openrckcmsettings.h"
|
||||||
#include <KAboutData>
|
#include <KAboutData>
|
||||||
|
|
||||||
class OpenRCKCM : public KQuickManagedConfigModule {
|
class OpenRCKCM : public KQuickAddons::ManagedConfigModule {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
OpenRCKCM(QObject *parent, const KPluginMetaData &metaData);
|
OpenRCKCM(QObject* parent, const KPluginMetaData& data, const QVariantList& args);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Q_PROPERTY(QStringList allServiceTitles READ getAllServiceTitles CONSTANT)
|
Q_PROPERTY(QStringList allServiceTitles READ getAllServiceTitles)
|
||||||
Q_PROPERTY(QStringList allServices READ getAllServices CONSTANT)
|
Q_PROPERTY(QStringList allServices READ getAllServices)
|
||||||
|
|
||||||
Q_INVOKABLE void tryDisableService(QString serviceName);
|
Q_INVOKABLE void tryDisableService(QString serviceName);
|
||||||
Q_INVOKABLE void tryStopService(QString serviceName);
|
Q_INVOKABLE void tryStopService(QString serviceName);
|
||||||
const QStringList getAllServiceTitles();
|
QStringList getAllServiceTitles();
|
||||||
const QStringList getAllServices();
|
QStringList getAllServices();
|
||||||
Q_INVOKABLE void tryRestartService(QString serviceName);
|
Q_INVOKABLE void tryRestartService(QString serviceName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* OPENRC_KCM_H */
|
|
@ -1,149 +0,0 @@
|
|||||||
/* ============================================================
|
|
||||||
* KCMOpenRC - OpenRC Service Manager
|
|
||||||
* Copyright (C) 2025 Juraj Oravec <jurajoravec@mailo.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* ============================================================ */
|
|
||||||
#include "openrc_service_model.h"
|
|
||||||
|
|
||||||
#include <QBrush>
|
|
||||||
#include <QColor>
|
|
||||||
#include <QFont>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#include <sys/queue.h>
|
|
||||||
|
|
||||||
#ifdef OPENRC_SERVICE_MODEL_DEBUG
|
|
||||||
#include <QAbstractItemModelTester>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
OpenRCServiceModel::OpenRCServiceModel(QObject* parent)
|
|
||||||
: QAbstractItemModel(parent)
|
|
||||||
, rootItem(std::make_unique<OpenRCTreeItem>(QVariantList{tr("Service")}))
|
|
||||||
{
|
|
||||||
#ifdef OPENRC_SERVICE_MODEL_DEBUG
|
|
||||||
m_tester = new QAbstractItemModelTester(this, QAbstractItemModelTester::FailureReportingMode::Fatal, this);
|
|
||||||
#endif
|
|
||||||
reload_services();
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenRCServiceModel::~OpenRCServiceModel() noexcept = default;
|
|
||||||
|
|
||||||
int OpenRCServiceModel::columnCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
if (parent.isValid())
|
|
||||||
return static_cast<OpenRCTreeItem*>(parent.internalPointer())->columnCount();
|
|
||||||
return rootItem->columnCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant OpenRCServiceModel::data(const QModelIndex &index, int role) const
|
|
||||||
{
|
|
||||||
if (!index.isValid() || role != Qt::DisplayRole)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
const auto *item = static_cast<const OpenRCTreeItem*>(index.internalPointer());
|
|
||||||
return item->data(index.column());
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::ItemFlags OpenRCServiceModel::flags(const QModelIndex &index) const
|
|
||||||
{
|
|
||||||
return index.isValid()
|
|
||||||
? QAbstractItemModel::flags(index) : Qt::ItemFlags(Qt::NoItemFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant OpenRCServiceModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
||||||
{
|
|
||||||
if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole)) {
|
|
||||||
return rootItem->data(section);
|
|
||||||
}
|
|
||||||
return QVariant{};
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex OpenRCServiceModel::index(int row, int column, const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
if (!hasIndex(row, column, parent))
|
|
||||||
return {};
|
|
||||||
|
|
||||||
OpenRCTreeItem *parentItem = parent.isValid()
|
|
||||||
? static_cast<OpenRCTreeItem*>(parent.internalPointer())
|
|
||||||
: rootItem.get();
|
|
||||||
|
|
||||||
if (auto *childItem = parentItem->child(row))
|
|
||||||
return createIndex(row, column, childItem);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex OpenRCServiceModel::parent(const QModelIndex &index) const
|
|
||||||
{
|
|
||||||
if (!index.isValid())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
auto *childItem = static_cast<OpenRCTreeItem*>(index.internalPointer());
|
|
||||||
OpenRCTreeItem *parentItem = childItem->parentItem();
|
|
||||||
|
|
||||||
if (parentItem != rootItem.get()) {
|
|
||||||
return createIndex(parentItem->row(), 0, parentItem);
|
|
||||||
}
|
|
||||||
return QModelIndex{};
|
|
||||||
}
|
|
||||||
|
|
||||||
int OpenRCServiceModel::rowCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
if (parent.column() > 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
|
||||||
const OpenRCTreeItem *parentItem = parent.isValid()
|
|
||||||
? static_cast<const OpenRCTreeItem*>(parent.internalPointer())
|
|
||||||
: rootItem.get();
|
|
||||||
|
|
||||||
return parentItem->childCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OpenRCServiceModel::reload_services()
|
|
||||||
{
|
|
||||||
beginResetModel();
|
|
||||||
|
|
||||||
m_runlevels.clear();
|
|
||||||
|
|
||||||
RC_STRINGLIST* list_runlevels = rc_runlevel_list();
|
|
||||||
RC_STRING* runlevel;
|
|
||||||
TAILQ_FOREACH(runlevel, list_runlevels, entries) {
|
|
||||||
std::string standard_string_name(runlevel->value);
|
|
||||||
QString runlevelStr = QString::fromStdString(standard_string_name);
|
|
||||||
|
|
||||||
QVariantList columnData;
|
|
||||||
columnData << QStringLiteral("<strong>%1</strong>").arg(runlevelStr);
|
|
||||||
|
|
||||||
rootItem.get()->appendChild(std::make_unique<OpenRCTreeItem>(columnData, rootItem.get()));
|
|
||||||
OpenRCTreeItem *parentItem = rootItem.get()->child(rootItem.get()->childCount() -1);
|
|
||||||
|
|
||||||
RC_STRINGLIST* list_services = rc_services_in_runlevel(runlevel->value);
|
|
||||||
RC_STRING* service;
|
|
||||||
TAILQ_FOREACH(service, list_services, entries) {
|
|
||||||
std::string standard_string_name(service->value);
|
|
||||||
QString serviceStr = QString::fromStdString(standard_string_name);
|
|
||||||
|
|
||||||
QVariantList serviceColumnData;
|
|
||||||
serviceColumnData << serviceStr;
|
|
||||||
|
|
||||||
parentItem->appendChild(std::make_unique<OpenRCTreeItem>(serviceColumnData, parentItem));
|
|
||||||
}
|
|
||||||
rc_stringlist_free(list_services);
|
|
||||||
}
|
|
||||||
rc_stringlist_free(list_runlevels);
|
|
||||||
|
|
||||||
endResetModel();
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
/* ============================================================
|
|
||||||
* KCMOpenRC - OpenRC Service Manager
|
|
||||||
* Copyright (C) 2025 Juraj Oravec <jurajoravec@mailo.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* ============================================================ */
|
|
||||||
#ifndef OPENRC_SERVICE_MODEL_H
|
|
||||||
#define OPENRC_SERVICE_MODEL_H
|
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
|
||||||
#include <QSortFilterProxyModel>
|
|
||||||
#include <QQmlEngine>
|
|
||||||
|
|
||||||
#include <rc.h>
|
|
||||||
|
|
||||||
#include "openrc_tree_item.h"
|
|
||||||
|
|
||||||
class QTimer;
|
|
||||||
|
|
||||||
#ifdef BUILD_TESTING
|
|
||||||
#define OPENRC_SERVICE_MODEL_DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef OPENRC_SERVICE_MODEL_DEBUG
|
|
||||||
class QAbstractItemModelTester;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class OpenRCServiceModel : public QAbstractItemModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
QML_NAMED_ELEMENT(OpenRCServiceModel)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_DISABLE_COPY_MOVE(OpenRCServiceModel)
|
|
||||||
|
|
||||||
OpenRCServiceModel(QObject *parent = nullptr);
|
|
||||||
~OpenRCServiceModel() override;
|
|
||||||
|
|
||||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
|
||||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
|
||||||
QModelIndex index(int row, int column, const QModelIndex &parent = {}) const override;
|
|
||||||
QModelIndex parent(const QModelIndex &index) const override;
|
|
||||||
int rowCount(const QModelIndex &parent = {}) const override;
|
|
||||||
int columnCount(const QModelIndex &parent = {}) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void reload_services();
|
|
||||||
|
|
||||||
std::unique_ptr<OpenRCTreeItem> rootItem;
|
|
||||||
QStringList m_runlevels;
|
|
||||||
|
|
||||||
#ifdef OPENRC_SERVICE_MODEL_DEBUG
|
|
||||||
QAbstractItemModelTester *m_tester;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
class FALKON_EXPORT AdBlockFilterModel : public QSortFilterProxyModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit AdBlockFilterModel(QAbstractItemModel *parent);
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
void setFilterFixedString(const QString &pattern);
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void startFiltering();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString m_pattern;
|
|
||||||
QTimer *m_filterTimer;
|
|
||||||
};
|
|
||||||
#endif /* 0 - disabled */
|
|
||||||
|
|
||||||
#endif /* OPENRC_SERVICE_MODEL_H */
|
|
@ -1,68 +0,0 @@
|
|||||||
/* ============================================================
|
|
||||||
* KCMOpenRC - OpenRC Service Manager
|
|
||||||
* Copyright (C) 2025 Juraj Oravec <jurajoravec@mailo.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* ============================================================ */
|
|
||||||
#include "openrc_tree_item.h"
|
|
||||||
|
|
||||||
OpenRCTreeItem::OpenRCTreeItem(QVariantList data, OpenRCTreeItem *parent)
|
|
||||||
: m_itemData(std::move(data))
|
|
||||||
, m_parentItem(parent)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void OpenRCTreeItem::appendChild(std::unique_ptr<OpenRCTreeItem> &&child)
|
|
||||||
{
|
|
||||||
m_childItems.push_back(std::move(child));
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenRCTreeItem *OpenRCTreeItem::child(int row)
|
|
||||||
{
|
|
||||||
return row >= 0 && row < childCount() ? m_childItems.at(row).get() : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int OpenRCTreeItem::childCount() const
|
|
||||||
{
|
|
||||||
return int(m_childItems.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
int OpenRCTreeItem::columnCount() const
|
|
||||||
{
|
|
||||||
return int(m_itemData.count());
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant OpenRCTreeItem::data(int column) const
|
|
||||||
{
|
|
||||||
return m_itemData.value(column);
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenRCTreeItem *OpenRCTreeItem::parentItem()
|
|
||||||
{
|
|
||||||
return m_parentItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
int OpenRCTreeItem::row() const
|
|
||||||
{
|
|
||||||
if (m_parentItem == nullptr)
|
|
||||||
return 0;
|
|
||||||
const auto it = std::find_if(m_parentItem->m_childItems.cbegin(), m_parentItem->m_childItems.cend(),
|
|
||||||
[this](const std::unique_ptr<OpenRCTreeItem> &treeItem) {
|
|
||||||
return treeItem.get() == this;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (it != m_parentItem->m_childItems.cend())
|
|
||||||
return std::distance(m_parentItem->m_childItems.cbegin(), it);
|
|
||||||
Q_ASSERT(false); // should not happen
|
|
||||||
return -1;
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/* ============================================================
|
|
||||||
* KCMOpenRC - OpenRC Service Manager
|
|
||||||
* Copyright (C) 2025 Juraj Oravec <jurajoravec@mailo.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* ============================================================ */
|
|
||||||
#ifndef OPENRC_TREE_ITEM_H
|
|
||||||
#define OPENRC_TREE_ITEM_H
|
|
||||||
|
|
||||||
#include <QVariant>
|
|
||||||
#include <QList>
|
|
||||||
|
|
||||||
class OpenRCTreeItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit OpenRCTreeItem(QVariantList data, OpenRCTreeItem *parentItem = nullptr);
|
|
||||||
|
|
||||||
void appendChild(std::unique_ptr<OpenRCTreeItem> &&child);
|
|
||||||
|
|
||||||
OpenRCTreeItem *child(int row);
|
|
||||||
int childCount() const;
|
|
||||||
int columnCount() const;
|
|
||||||
QVariant data(int column) const;
|
|
||||||
int row() const;
|
|
||||||
OpenRCTreeItem *parentItem();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::unique_ptr<OpenRCTreeItem>> m_childItems;
|
|
||||||
QVariantList m_itemData;
|
|
||||||
OpenRCTreeItem *m_parentItem;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // OPENRC_TREE_ITEM_H
|
|
9
package/contents/ui/OpenRCPanel.qml
Normal file
9
package/contents/ui/OpenRCPanel.qml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15 as Controls
|
||||||
|
import QtQuick.Layouts 1.11
|
||||||
|
|
||||||
|
import org.kde.kirigami 2.16 as Kirigami
|
||||||
|
import org.kde.kcm 1.4
|
||||||
|
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
117
package/contents/ui/main.qml
Normal file
117
package/contents/ui/main.qml
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15 as Controls
|
||||||
|
import QtQuick.Layouts 1.11
|
||||||
|
|
||||||
|
import org.kde.kirigami 2.16 as Kirigami
|
||||||
|
import org.kde.kcm 1.4
|
||||||
|
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 3.0 as PlasmaComponents3
|
||||||
|
|
||||||
|
ScrollViewKCM {
|
||||||
|
id: rootKCM
|
||||||
|
implicitWidth: units.gridUnit * 60
|
||||||
|
implicitHeight: units.gridUnit * 25
|
||||||
|
ColumnLayout{
|
||||||
|
id: root
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: units.gridUnit * 2
|
||||||
|
anchors.rightMargin: units.gridUnit * 2
|
||||||
|
anchors.topMargin: units.gridUnit * 2
|
||||||
|
anchors.bottomMargin: units.gridUnit * 2
|
||||||
|
|
||||||
|
PlasmaExtras.Heading {
|
||||||
|
level: 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter;
|
||||||
|
text: i18n("Configure OpenRC")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: openRCPanel
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
PlasmaExtras.Heading {
|
||||||
|
level: 2
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: i18n("Available Services")
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: serviceView
|
||||||
|
model: serviceModel
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
spacing: units.gridUnit * 1.5
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
implicitWidth: rootKCM.implicitWidth
|
||||||
|
color: "#3b4252"
|
||||||
|
border.color: "#a3be8c"
|
||||||
|
implicitHeight: units.gridUnit * 2
|
||||||
|
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: toolbar
|
||||||
|
Layout.minimumWidth: parent.implicitWidth
|
||||||
|
anchors.fill: parent
|
||||||
|
PlasmaComponents3.Label {
|
||||||
|
id: headerItem
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: title
|
||||||
|
Layout.leftMargin: 1 * units.gridUnit
|
||||||
|
}
|
||||||
|
Controls.ToolButton {
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
id: deleteButton
|
||||||
|
icon.name: "delete"
|
||||||
|
text: i18n("Remove")
|
||||||
|
Controls.ToolTip.text: i18n("Removes this service from the default runlevel (for OpenRC).")
|
||||||
|
onClicked: {
|
||||||
|
console.log("Start remove " + name);
|
||||||
|
kcm.tryDisableService(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Controls.ToolButton {
|
||||||
|
id: stopButton
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
icon.name: "delete"
|
||||||
|
text: i18n("Stop")
|
||||||
|
Controls.ToolTip.text: i18n("Stops the current service.")
|
||||||
|
onClicked: {
|
||||||
|
kcm.tryStopService(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Controls.ToolButton {
|
||||||
|
id: restartButton
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
icon.name: "system-restart"
|
||||||
|
text: i18n("Restart")
|
||||||
|
Controls.ToolTip.text: i18n("Restarts the current service.")
|
||||||
|
onClicked: {
|
||||||
|
kcm.tryRestartService(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: serviceModel
|
||||||
|
Component.onCompleted: {
|
||||||
|
for (var i = 0; i < kcm.allServices.length; i++){
|
||||||
|
serviceModel.append({"name": kcm.allServices[i], "title": kcm.allServiceTitles[i]});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
1
package/contents/ui/qmldir
Normal file
1
package/contents/ui/qmldir
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"KPlugin": {
|
"KPlugin": {
|
||||||
"Description": "Configure OpenRC",
|
"Description": "Configure OpenRC",
|
||||||
"FormFactors": [
|
"FormFactors": [
|
||||||
@ -6,11 +6,12 @@
|
|||||||
"mediacenter"
|
"mediacenter"
|
||||||
],
|
],
|
||||||
"Icon": "system-restart",
|
"Icon": "system-restart",
|
||||||
|
"Id": "kcm_openrc",
|
||||||
"Name": "OpenRC",
|
"Name": "OpenRC",
|
||||||
"ServiceTypes": [
|
"ServiceTypes": [
|
||||||
"KCModule"
|
"KCModule"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"X-KDE-Keywords": "OpenRC,service",
|
"X-KDE-Keywords": "OpenRC",
|
||||||
"X-KDE-System-Settings-Parent-Category" : "system-administration"
|
"X-KDE-System-Settings-Parent-Category" : "system-administration"
|
||||||
}
|
}
|
164
ui/main.qml
164
ui/main.qml
@ -1,164 +0,0 @@
|
|||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls as Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
import org.kde.kcmutils as KCMUtils
|
|
||||||
import org.kde.plasma.extras as PlasmaExtras
|
|
||||||
import org.kde.plasma.core as PlasmaCore
|
|
||||||
import org.kde.plasma.components as PlasmaComponents3
|
|
||||||
|
|
||||||
import org.kde.plasma.kcm.openrc
|
|
||||||
|
|
||||||
KCMUtils.ScrollViewKCM {
|
|
||||||
id: rootKCM
|
|
||||||
ColumnLayout{
|
|
||||||
id: root
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
PlasmaExtras.Heading {
|
|
||||||
level: 1
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter;
|
|
||||||
text: i18n("Configure OpenRC")
|
|
||||||
}
|
|
||||||
ColumnLayout {
|
|
||||||
id: openRCPanel
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
PlasmaExtras.Heading {
|
|
||||||
level: 2
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: i18n("Available Services")
|
|
||||||
}
|
|
||||||
|
|
||||||
Controls.Frame {
|
|
||||||
clip: true
|
|
||||||
id: serviceViewFrame
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
Controls.ScrollView {
|
|
||||||
id: serviceScrollArea
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
TreeView {
|
|
||||||
id: treeView
|
|
||||||
clip: true
|
|
||||||
width: openRCPanel.width
|
|
||||||
|
|
||||||
selectionModel: ItemSelectionModel {}
|
|
||||||
|
|
||||||
model: OpenRCServiceModel { }
|
|
||||||
|
|
||||||
delegate: Item {
|
|
||||||
// implicitWidth: openRCPanel.width
|
|
||||||
implicitWidth: treeView.width
|
|
||||||
// implicitWidth: padding + label.x + label.implicitWidth + padding
|
|
||||||
implicitHeight: label.implicitHeight * 1.5
|
|
||||||
|
|
||||||
readonly property real indentation: 20
|
|
||||||
readonly property real padding: 5
|
|
||||||
|
|
||||||
// Assigned to by TreeView:
|
|
||||||
required property TreeView treeView
|
|
||||||
required property bool isTreeNode
|
|
||||||
required property bool expanded
|
|
||||||
required property bool hasChildren
|
|
||||||
required property int depth
|
|
||||||
required property int row
|
|
||||||
required property int column
|
|
||||||
required property bool current
|
|
||||||
|
|
||||||
// Rotate indicator when expanded by the user
|
|
||||||
// (requires TreeView to have a selectionModel)
|
|
||||||
property Animation indicatorAnimation: NumberAnimation {
|
|
||||||
target: indicator
|
|
||||||
property: "rotation"
|
|
||||||
from: expanded ? 0 : 90
|
|
||||||
to: expanded ? 90 : 0
|
|
||||||
duration: 100
|
|
||||||
easing.type: Easing.OutQuart
|
|
||||||
}
|
|
||||||
TableView.onPooled: indicatorAnimation.complete()
|
|
||||||
TableView.onReused: if (current) indicatorAnimation.start()
|
|
||||||
onExpandedChanged: indicator.rotation = expanded ? 90 : 0
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: background
|
|
||||||
anchors.fill: parent
|
|
||||||
color: row === treeView.currentRow ? palette.highlight : "black"
|
|
||||||
opacity: (treeView.alternatingRows && row % 2 !== 0) ? 0.3 : 0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
Controls.Label {
|
|
||||||
id: indicator
|
|
||||||
x: padding + (depth * indentation)
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: isTreeNode && hasChildren
|
|
||||||
text: "▶"
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
onSingleTapped: {
|
|
||||||
let index = treeView.index(row, column)
|
|
||||||
treeView.selectionModel.setCurrentIndex(index, ItemSelectionModel.NoUpdate)
|
|
||||||
treeView.toggleExpanded(row)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controls.Label {
|
|
||||||
id: label
|
|
||||||
x: padding + (isTreeNode ? (depth + 1) * indentation : 0)
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
width: parent.width - padding - x
|
|
||||||
clip: true
|
|
||||||
text: model.display
|
|
||||||
}
|
|
||||||
|
|
||||||
Controls.ToolButton {
|
|
||||||
id: restartButton
|
|
||||||
anchors.right: parent.right
|
|
||||||
visible: !hasChildren
|
|
||||||
icon.name: "system-restart"
|
|
||||||
text: i18n("Restart")
|
|
||||||
Controls.ToolTip.visible: hovered
|
|
||||||
Controls.ToolTip.text: i18n("Restarts the current service.")
|
|
||||||
onClicked: {
|
|
||||||
kcm.tryRestartService(model.display);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Controls.ToolButton {
|
|
||||||
id: stopButton
|
|
||||||
anchors.right: restartButton.left
|
|
||||||
visible: !hasChildren
|
|
||||||
icon.name: "delete"
|
|
||||||
text: i18n("Stop")
|
|
||||||
Controls.ToolTip.visible: hovered
|
|
||||||
Controls.ToolTip.text: i18n("Stops the current service.")
|
|
||||||
onClicked: {
|
|
||||||
kcm.tryStopService(model.display);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Controls.ToolButton {
|
|
||||||
id: deleteButton
|
|
||||||
anchors.right: stopButton.left
|
|
||||||
visible: !hasChildren
|
|
||||||
icon.name: "delete"
|
|
||||||
text: i18n("Remove")
|
|
||||||
Controls.ToolTip.visible: hovered
|
|
||||||
Controls.ToolTip.text: i18n("Removes this service from the default runlevel (for OpenRC).")
|
|
||||||
onClicked: {
|
|
||||||
console.log("Start remove " + model.display);
|
|
||||||
kcm.tryDisableService(model.display);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user