Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
ddb9b6402e | |||
c95cef0bbd | |||
48d1cc30a8 | |||
c7035a96c7 | |||
4e875fc716 |
@ -47,6 +47,9 @@ AllowAllParametersOfDeclarationOnNextLine: false
|
||||
# no single line functions
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
|
||||
# no single line enums
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
|
||||
# always break before you encounter multi line strings
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
|
||||
|
@ -3,28 +3,32 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(kcm_openrc)
|
||||
|
||||
set(QT_MIN_VERSION "5.15.0")
|
||||
set(KF5_MIN_VERSION "5.88.0")
|
||||
set(QT_MIN_VERSION "6.4.0")
|
||||
set(KF_MIN_VERSION "6.4.0")
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
|
||||
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
||||
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
|
||||
set(GENERATE_MOC ON)
|
||||
|
||||
|
||||
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
|
||||
find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
|
||||
Core
|
||||
Quick
|
||||
Svg
|
||||
DBus
|
||||
)
|
||||
|
||||
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
|
||||
if (BUILD_TESTING)
|
||||
find_package(Qt6 ${QT_MIN_VERSION} REQUIRED COMPONENTS Test)
|
||||
add_compile_definitions("BUILD_TESTING")
|
||||
endif()
|
||||
|
||||
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS
|
||||
I18n
|
||||
KCMUtils
|
||||
Declarative
|
||||
Config
|
||||
ConfigWidgets
|
||||
Auth
|
||||
@ -32,44 +36,58 @@ find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
|
||||
|
||||
include(KDEInstallDirs)
|
||||
include(KDECMakeSettings)
|
||||
include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE)
|
||||
include(KDECompilerSettings NO_POLICY_SCOPE)
|
||||
include(FeatureSummary)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set(openrc_kcm_SRCS openrc_kcm.cpp)
|
||||
set(openrc_kcm_SRCS
|
||||
openrc_kcm.cpp
|
||||
openrc_tree_item.cpp
|
||||
openrc_service_model.cpp
|
||||
)
|
||||
|
||||
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
||||
|
||||
|
||||
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)
|
||||
target_link_libraries(openrc-actions-kauth
|
||||
Qt5::Core
|
||||
Qt5::DBus
|
||||
KF5::CoreAddons
|
||||
KF5::I18n
|
||||
KF5::Auth
|
||||
Qt6::Core
|
||||
Qt6::DBus
|
||||
|
||||
KF6::CoreAddons
|
||||
KF6::I18n
|
||||
KF6::AuthCore
|
||||
|
||||
rc
|
||||
)
|
||||
|
||||
|
||||
target_link_libraries(kcm_openrc
|
||||
Qt5::Core
|
||||
Qt5::DBus
|
||||
KF5::CoreAddons
|
||||
KF5::I18n
|
||||
KF5::QuickAddons
|
||||
KF5::ConfigCore
|
||||
KF5::ConfigWidgets
|
||||
KF5::Auth
|
||||
Qt6::Core
|
||||
Qt6::DBus
|
||||
|
||||
KF6::CoreAddons
|
||||
KF6::I18n
|
||||
KF6::KCMUtilsQuick
|
||||
KF6::ConfigCore
|
||||
KF6::ConfigWidgets
|
||||
KF6::AuthCore
|
||||
|
||||
rc
|
||||
)
|
||||
|
||||
install(TARGETS openrc-actions-kauth DESTINATION ${KAUTH_HELPER_INSTALL_DIR})
|
||||
install(TARGETS kcm_openrc DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/kcms/systemsettings)
|
||||
if (BUILD_TESTING)
|
||||
target_link_libraries(kcm_openrc Qt6::Test)
|
||||
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_actions(tridentu.auth.openrc.service tridentu.auth.openrc.service.actions)
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
{
|
||||
"KPlugin": {
|
||||
"Description": "Configure OpenRC",
|
||||
"FormFactors": [
|
||||
@ -6,12 +6,11 @@
|
||||
"mediacenter"
|
||||
],
|
||||
"Icon": "system-restart",
|
||||
"Id": "kcm_openrc",
|
||||
"Name": "OpenRC",
|
||||
"ServiceTypes": [
|
||||
"KCModule"
|
||||
]
|
||||
},
|
||||
"X-KDE-Keywords": "OpenRC",
|
||||
"X-KDE-Keywords": "OpenRC,service",
|
||||
"X-KDE-System-Settings-Parent-Category" : "system-administration"
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
[Project]
|
||||
CreatedFrom=CMakeLists.txt
|
||||
Manager=KDevCMakeManager
|
||||
Name=kcm_openrc
|
@ -1,12 +1,8 @@
|
||||
|
||||
|
||||
#include "openrc_actions.h"
|
||||
#include <KAuth/KAuthAction>
|
||||
#include <KAuth/KAuthExecuteJob>
|
||||
#include <KAuth/Action>
|
||||
#include <KAuth/ExecuteJob>
|
||||
#include <rc.h>
|
||||
#include <qprocess.h>
|
||||
|
||||
|
||||
#include <QProcess>
|
||||
|
||||
KAuth::ActionReply OpenRCHelper::removeservice( const QVariantMap& args )
|
||||
{
|
||||
|
@ -1,9 +1,8 @@
|
||||
#ifndef OPENRC_ACTIONS_H
|
||||
#define OPENRC_ACTIONS_H
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <KAuth/KAuthActionReply>
|
||||
#include <KAuth/KAuthHelperSupport>
|
||||
#include <KAuth/ActionReply>
|
||||
#include <KAuth/HelperSupport>
|
||||
|
||||
class OpenRCHelper: public QObject {
|
||||
Q_OBJECT
|
||||
@ -13,3 +12,5 @@ public Q_SLOTS:
|
||||
KAuth::ActionReply restartservice(const QVariantMap& args);
|
||||
|
||||
};
|
||||
|
||||
#endif /* OPENRC_ACTIONS_H */
|
||||
|
@ -1,29 +1,28 @@
|
||||
|
||||
#include "openrc_kcm.h"
|
||||
#include "openrc_service_model.h"
|
||||
|
||||
#include <KPluginFactory>
|
||||
#include <KLocalizedString>
|
||||
#include "openrckcmsettings.h"
|
||||
#include <sys/queue.h>
|
||||
#include <QString>
|
||||
#include <KAuth/KAuthAction>
|
||||
#include <KAuth/KAuthExecuteJob>
|
||||
#include <KAuth/Action>
|
||||
#include <KAuth/ExecuteJob>
|
||||
#include <rc.h>
|
||||
|
||||
K_PLUGIN_CLASS_WITH_JSON(OpenRCKCM, "package/kcm_openrc.json");
|
||||
K_PLUGIN_CLASS_WITH_JSON(OpenRCKCM, "kcm_openrc.json");
|
||||
|
||||
OpenRCKCM::OpenRCKCM(QObject* parent, const KPluginMetaData& data, const QVariantList& args)
|
||||
: KQuickAddons::ManagedConfigModule(parent, data, args)
|
||||
OpenRCKCM::OpenRCKCM(QObject *parent, const KPluginMetaData &metaData)
|
||||
: KQuickManagedConfigModule(parent, metaData)
|
||||
{
|
||||
constexpr const char *uri = "org.kde.plasma.kcm.openrc";
|
||||
|
||||
qmlRegisterType<OpenRCServiceModel>(uri, 1, 0, "OpenRCServiceModel");
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
QStringList OpenRCKCM::getAllServiceTitles(){
|
||||
const QStringList OpenRCKCM::getAllServiceTitles() {
|
||||
QStringList list;
|
||||
{
|
||||
RC_STRINGLIST* listS = rc_services_in_runlevel("default");
|
||||
@ -39,7 +38,7 @@ QStringList OpenRCKCM::getAllServiceTitles(){
|
||||
return list;
|
||||
}
|
||||
|
||||
QStringList OpenRCKCM::getAllServices(){
|
||||
const QStringList OpenRCKCM::getAllServices() {
|
||||
QStringList list;
|
||||
{
|
||||
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
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <KQuickAddons/ManagedConfigModule>
|
||||
#include <rc.h>
|
||||
#include <KQuickManagedConfigModule>
|
||||
#include <QSettings>
|
||||
#include "openrckcmsettings.h"
|
||||
#include <KAboutData>
|
||||
|
||||
class OpenRCKCM : public KQuickAddons::ManagedConfigModule {
|
||||
Q_OBJECT
|
||||
class OpenRCKCM : public KQuickManagedConfigModule {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OpenRCKCM(QObject* parent, const KPluginMetaData& data, const QVariantList& args);
|
||||
OpenRCKCM(QObject *parent, const KPluginMetaData &metaData);
|
||||
|
||||
public:
|
||||
Q_PROPERTY(QStringList allServiceTitles READ getAllServiceTitles)
|
||||
Q_PROPERTY(QStringList allServices READ getAllServices)
|
||||
Q_PROPERTY(QStringList allServiceTitles READ getAllServiceTitles CONSTANT)
|
||||
Q_PROPERTY(QStringList allServices READ getAllServices CONSTANT)
|
||||
|
||||
Q_INVOKABLE void tryDisableService(QString serviceName);
|
||||
Q_INVOKABLE void tryStopService(QString serviceName);
|
||||
QStringList getAllServiceTitles();
|
||||
QStringList getAllServices();
|
||||
const QStringList getAllServiceTitles();
|
||||
const QStringList getAllServices();
|
||||
Q_INVOKABLE void tryRestartService(QString serviceName);
|
||||
|
||||
private:
|
||||
QSettings settings;
|
||||
};
|
||||
|
||||
#endif /* OPENRC_KCM_H */
|
149
openrc_service_model.cpp
Normal file
149
openrc_service_model.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
/* ============================================================
|
||||
* 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();
|
||||
}
|
89
openrc_service_model.h
Normal file
89
openrc_service_model.h
Normal file
@ -0,0 +1,89 @@
|
||||
/* ============================================================
|
||||
* 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 */
|
68
openrc_tree_item.cpp
Normal file
68
openrc_tree_item.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
/* ============================================================
|
||||
* 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;
|
||||
}
|
44
openrc_tree_item.h
Normal file
44
openrc_tree_item.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* ============================================================
|
||||
* 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
|
@ -1,9 +0,0 @@
|
||||
|
||||
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
|
@ -1,117 +0,0 @@
|
||||
|
||||
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 +0,0 @@
|
||||
|
164
ui/main.qml
Normal file
164
ui/main.qml
Normal file
@ -0,0 +1,164 @@
|
||||
|
||||
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