/* ============================================================ * KCMOpenRC - OpenRC Service Manager * Copyright (C) 2025 Juraj Oravec * * 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 . * ============================================================ */ #include "openrc_service_model.h" #include #include #include #include #include #ifdef OPENRC_SERVICE_MODEL_DEBUG #include #endif OpenRCServiceModel::OpenRCServiceModel(QObject* parent) : QAbstractItemModel(parent) , rootItem(std::make_unique(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(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(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(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(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(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("%1").arg(runlevelStr); rootItem.get()->appendChild(std::make_unique(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(serviceColumnData, parentItem)); } rc_stringlist_free(list_services); } rc_stringlist_free(list_runlevels); endResetModel(); }