Commit cc789f3a authored by Marco Martin's avatar Marco Martin
Browse files

Add KSysGuard::Sensors library

Summary:
This adds a new library for communicating with a new KSysGuard
DBus-based daemon that provides sensors. The daemon will be
posted by d_ed later on.

This new library pretty much maps the different objects from
the daemon to C++ objects.

Depends on D28333

Test Plan: None yet, needs the new daemon.

Reviewers: #plasma, davidedmundson

Reviewed By: #plasma, davidedmundson

Subscribers: ngraham, mart, zzag, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D28141
parent b1e9126e
......@@ -43,7 +43,9 @@ set_package_properties(Qt5WebChannel PROPERTIES
PURPOSE "Used by the HTML-based GUI ksysguard library"
)
find_package(KF5 REQUIRED COMPONENTS CoreAddons Config I18n JobWidgets WindowSystem Completion Auth WidgetsAddons IconThemes ConfigWidgets Service GlobalAccel KIO)
find_package(KF5 REQUIRED COMPONENTS CoreAddons Config I18n JobWidgets WindowSystem Completion Auth WidgetsAddons IconThemes ConfigWidgets Service GlobalAccel KIO Package Declarative)
find_package(KF5 OPTIONAL_COMPONENTS Plasma)
set_package_properties(KF5Plasma PROPERTIES
URL "https://cgit.kde.org/plasma-framework.git/"
......@@ -110,6 +112,8 @@ add_subdirectory( lsofui )
add_subdirectory( processcore )
add_subdirectory( processui )
add_subdirectory( sensors )
add_subdirectory( faces )
if (KF5Plasma_FOUND)
add_subdirectory( signalplotter )
endif()
......
set(KSYSGUARD_SENSORS_SOVERSION 1)
add_subdirectory(import)
add_subdirectory(facepackages)
add_subdirectory(packagestructure)
add_definitions(-DTRANSLATION_DOMAIN=\"ksysguard_faces\")
set(faces_LIB_SRCS
SensorFaceController.cpp
SensorFace.cpp
)
set(faces_LIB_HEADERS
SensorFace_p.h
SensorFaceController.h
)
ecm_qt_declare_logging_category(faces_LIB_SRCS
HEADER faces_logging.h
IDENTIFIER LIBKSYSGUARD_SENSORS
CATEGORY_NAME org.kde.libksysguard.faces
)
set_source_files_properties(org.kde.KSysGuardDaemon.xml PROPERTIES INCLUDE SensorInfo_p.h)
qt5_add_resources(RESOURCES resources.qrc)
add_library(SensorFaces ${faces_LIB_SRCS} ${RESOURCES})
add_library(KSysGuard::SensorFaces ALIAS SensorFaces)
target_include_directories(SensorFaces
PUBLIC
"$<BUILD_INTERFACE:${libksysguard_SOURCE_DIR}>"
"$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR}/ksysguard/>"
)
generate_export_header(SensorFaces)
target_link_libraries(SensorFaces
PUBLIC
Qt5::Qml
Qt5::Quick
KF5::ConfigCore
KF5::ConfigGui
KSysGuard::Formatter
KSysGuard::Sensors
PRIVATE
Qt5::Core
Qt5::DBus
KF5::I18n
KF5::Package
KF5::Declarative
)
set_target_properties(SensorFaces PROPERTIES
LIBRARY_OUTPUT_NAME KSysGuardSensorFaces
VERSION ${KSYSGUARD_VERSION_STRING}
SOVERSION ${KSYSGUARD_SENSORS_SOVERSION}
)
install(TARGETS SensorFaces EXPORT libksysguardLibraryTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES
${faces_LIB_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/sensorfaces_export.h
DESTINATION ${KDE_INSTALL_INCLUDEDIR}/ksysguard/faces
COMPONENT Devel
)
/*
* Copyright 2019 Marco Martin <mart@kde.org>
* Copyright 2019 David Edmundson <davidedmundson@kde.org>
* Copyright 2019 Arjen Hiemstra <ahiemstra@heimr.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import QtQuick 2.9
import QtQuick.Layouts 1.2
import QtQuick.Controls 2.2 as QQC2
import org.kde.kirigami 2.5 as Kirigami
import org.kde.kquickcontrols 2.0
import org.kde.kconfig 1.0 // for KAuthorized
import org.kde.newstuff 1.62 as NewStuff
import org.kde.quickcharts 1.0 as Charts
import org.kde.ksysguard.sensors 1.0 as Sensors
import org.kde.ksysguard.faces 1.0 as Faces
Kirigami.FormLayout {
id: root
signal configurationChanged
function saveConfig() {
controller.title = cfg_title;
controller.faceId = cfg_chartFace;
var preset = pendingPreset;
pendingPreset = "";
if (preset != "") {
controller.loadPreset(preset);
root.controller.highPrioritySensorColors = automaticColorSource.colors
}
}
property Faces.SensorFaceController controller
property alias cfg_title: titleField.text
property string cfg_chartFace
onCfg_titleChanged: configurationChanged();
onCfg_chartFaceChanged: configurationChanged();
// config keys of the selected preset to be applied on save
property string pendingPreset
Component.onCompleted: {
cfg_title = controller.title;
cfg_chartFace = controller.faceId;
}
Charts.ColorGradientSource {
id: automaticColorSource
baseColor: Kirigami.Theme.highlightColor
itemCount: root.controller.highPrioritySensorIds.length
}
Kirigami.OverlaySheet {
id: presetSheet
parent: root
ListView {
implicitWidth: Kirigami.Units.gridUnit * 15
model: controller.availablePresetsModel
delegate: Kirigami.SwipeListItem {
contentItem: QQC2.Label {
Layout.fillWidth: true
text: model.display
}
actions: Kirigami.Action {
icon.name: "delete"
visible: model.writable
onTriggered: controller.uninstallPreset(model.pluginId);
}
onClicked: {
cfg_title = model.display;
pendingPreset = model.pluginId;
if (model.config.chartFace) {
cfg_chartFace = model.config.chartFace;
}
root.configurationChanged();
presetSheet.close();
}
}
}
}
RowLayout {
Kirigami.FormData.label: i18n("Presets:")
QQC2.Button {
icon.name: "document-open"
text: i18n("Load Preset...")
onClicked: presetSheet.open()
}
NewStuff.Button {
Accessible.name: i18n("Get new presets...")
configFile: "systemmonitor-presets.knsrc"
text: ""
onChangedEntriesChanged: controller.availablePresetsModel.reload();
QQC2.ToolTip {
text: parent.Accessible.name
}
}
QQC2.Button {
id: saveButton
icon.name: "document-save"
text: i18n("Save Settings As Preset")
enabled: controller.currentPreset.length == 0
onClicked: controller.savePreset();
}
}
Kirigami.Separator {
Kirigami.FormData.isSection: true
}
QQC2.TextField {
id: titleField
Kirigami.FormData.label: i18n("Title:")
}
RowLayout {
Kirigami.FormData.label: i18n("Display Style:")
QQC2.ComboBox {
id: faceCombo
model: controller.availableFacesModel
textRole: "display"
currentIndex: {
// TODO just make an indexOf invokable on the model?
for (var i = 0; i < count; ++i) {
if (model.pluginId(i) === cfg_chartFace) {
return i;
}
}
return -1;
}
onActivated: {
cfg_chartFace = model.pluginId(index);
}
}
NewStuff.Button {
text: i18n("Get New Display Styles...")
configFile: "systemmonitor-faces.knsrc"
onChangedEntriesChanged: controller.availableFacesModel.reload();
}
}
}
/*
* Copyright 2019 Marco Martin <mart@kde.org>
* Copyright 2019 David Edmundson <davidedmundson@kde.org>
* Copyright 2019 Arjen Hiemstra <ahiemstra@heimr.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import QtQuick 2.9
import QtQuick.Layouts 1.2
import QtQuick.Controls 2.2 as QQC2
import QtQml.Models 2.12
import org.kde.kirigami 2.8 as Kirigami
import org.kde.kquickcontrols 2.0
import org.kde.kitemmodels 1.0 as KItemModels
import org.kde.quickcharts 1.0 as Charts
import org.kde.ksysguard.sensors 1.0 as Sensors
import org.kde.ksysguard.faces 1.0 as Faces
import "./" as Local
ColumnLayout {
id: root
readonly property int implicitHeight: 1 //HACK FIXME to disable external scrollbar
signal configurationChanged
property var cfg_totalSensors
property alias cfg_highPrioritySensorIds: usedSensorsView.sensorIds
property alias cfg_sensorColors: usedSensorsView.sensorColors
property alias cfg_lowPrioritySensorIds: lowPrioritySensorsView.sensorIds
onCfg_totalSensorsChanged: configurationChanged();
onCfg_highPrioritySensorIdsChanged: configurationChanged();
onCfg_sensorColorsChanged: configurationChanged();
onCfg_lowPrioritySensorIdsChanged: configurationChanged();
property Faces.SensorFaceController controller
Sensors.Sensor {
id: totalSensor
sensorId: cfg_totalSensors.length > 0 ? cfg_totalSensors[0] : ""
}
function saveConfig() {
controller.totalSensors = cfg_totalSensors;
controller.highPrioritySensorIds = cfg_highPrioritySensorIds;
controller.sensorColors = cfg_sensorColors;
controller.lowPrioritySensorIds = cfg_lowPrioritySensorIds;
}
function loadConfig() {
cfg_totalSensors = controller.totalSensors;
cfg_highPrioritySensorIds = controller.highPrioritySensorIds;
cfg_sensorColors = controller.sensorColors;
usedSensorsView.load();
cfg_lowPrioritySensorIds = controller.lowPrioritySensorIds;
lowPrioritySensorsView.load();
}
Component.onCompleted: loadConfig()
Connections {
target: controller
onTotalSensorsChanged: Qt.callLater(root.loadConfig)
onHighPrioritySensorIdsChanged: Qt.callLater(root.loadConfig)
onSensorColorsChanged: Qt.callLater(root.loadConfig)
onLowPrioritySensorIdsChanged: Qt.callLater(root.loadConfig)
}
Component {
id: delegateComponent
Kirigami.SwipeListItem {
id: listItem
width: usedSensorsView.width
actions: Kirigami.Action {
icon.name: "list-remove"
text: i18n("Remove")
onTriggered: {
usedSensorsModel.remove(index, 1);
usedSensorsModel.save();
}
}
contentItem: RowLayout {
Kirigami.ListItemDragHandle {
listItem: listItem
listView: usedSensorsView
onMoveRequested: {
usedSensorsModel.move(oldIndex, newIndex, 1)
usedSensorsModel.save();
}
}
ColorButton {
id: textColorButton
color: model.color
onColorChanged: {
usedSensorsModel.setProperty(index, "color", color.toString());
usedSensorsModel.save();
}
}
QQC2.Label {
Layout.fillWidth: true
text: sensor.name
Sensors.Sensor {
id: sensor
sensorId: model.sensorId
}
}
}
}
}
RowLayout {
Layout.preferredHeight: sensorListHeader.implicitHeight
visible: controller.supportsTotalSensors
QQC2.Label {
text: i18n("Total Sensor:")
}
QQC2.Label {
Layout.fillWidth: true
text: cfg_totalSensors.length > 0 ? totalSensor.name : i18n("Drop Sensor Here")
elide: Text.ElideRight
DropArea {
anchors.fill: parent
onEntered: {
if (drag.formats.indexOf("application/x-ksysguard") == -1) {
drag.accepted = false;
return;
}
}
onDropped: {
cfg_totalSensors = drop.getDataAsString("application/x-ksysguard")
}
}
}
QQC2.ToolButton {
icon.name: "list-remove"
opacity: cfg_totalSensors.length > 0
onClicked: cfg_totalSensors = [];
}
}
RowLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.minimumHeight: 0
Layout.preferredHeight: 0
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.preferredHeight: 0
Layout.preferredWidth: Kirigami.Units.gridUnit * 14
Kirigami.Heading {
Layout.preferredHeight: sensorListHeader.implicitHeight
level: 3
text: i18n("Chart Sensors")
}
Local.UsedSensorsView {
id: usedSensorsView
showColor: controller.supportsSensorsColors
sensorColors: root.controller.sensorColors
}
Kirigami.Heading {
Layout.preferredHeight: sensorListHeader.implicitHeight
text: i18n("Text Only Sensors")
level: 3
visible: lowPrioritySensorsView.visible
}
Local.UsedSensorsView {
id: lowPrioritySensorsView
visible: controller.supportsLowPrioritySensors
showColor: false
}
}
ColumnLayout {
RowLayout {
id: sensorListHeader
Layout.fillWidth: true
QQC2.ToolButton {
icon.name: "go-previous"
enabled: sensorsDelegateModel.rootIndex.valid
onClicked: sensorsDelegateModel.rootIndex = sensorsDelegateModel.parentModelIndex()
}
Kirigami.Heading {
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
level: 3
text: i18n("All Sensors")
}
}
Kirigami.SearchField {
id: searchQuery
Layout.fillWidth: true
}
QQC2.ScrollView {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.preferredWidth: Kirigami.Units.gridUnit * 14
ListView {
KItemModels.KSortFilterProxyModel {
id: sensorsSearchableModel
filterCaseSensitivity: Qt.CaseInsensitive
filterString: searchQuery.text
sourceModel: KItemModels.KSortFilterProxyModel {
filterRole: "SensorId"
filterRowCallback: function(row, value) {
return (value && value.length)
}
sourceModel: KItemModels.KDescendantsProxyModel {
model: allSensorsTreeModel
}
}
}
Sensors.SensorTreeModel {
id: allSensorsTreeModel
}
model: DelegateModel {
id: sensorsDelegateModel
model: searchQuery.text.length == 0 ? allSensorsTreeModel : sensorsSearchableModel
delegate: Kirigami.BasicListItem {
id: sensorTreeDelegate
text: model.display
icon: (model.SensorId.length == 0) ? "folder" : ""
Drag.active: model.SensorId.length > 0 && sensorTreeDelegate.pressed
Drag.dragType: Drag.Automatic
Drag.supportedActions: Qt.CopyAction
Drag.hotSpot.x: sensorTreeDelegate.pressX
Drag.hotSpot.y: sensorTreeDelegate.pressY
Drag.mimeData: {
"application/x-ksysguard": model.SensorId
}
//FIXME: better handling of Drag
onPressed: {
onPressed: grabToImage(function(result) {
Drag.imageSource = result.url
})
}
onClicked: {
if (model.SensorId.length == 0) {
sensorsDelegateModel.rootIndex = sensorsDelegateModel.modelIndex(index);
}
}
onDoubleClicked: {
if (model.SensorId) {
usedSensorsView.appendSensor(model.SensorId);
usedSensorsView.positionViewAtIndex(usedSensorsView.count - 1, ListView.Contain);
}
}
}
}
}
Component.onCompleted: background.visible = true;
QQC2.ScrollBar.horizontal.visible: false
}
}
}
}
/*
* Copyright 2019 Marco Martin <mart@kde.org>
* Copyright 2019 David Edmundson <davidedmundson@kde.org>
* Copyright 2019 Arjen Hiemstra <ahiemstra@heimr.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import QtQuick 2.9
import QtQuick.Layouts 1.2
import org.kde.kirigami 2.5 as Kirigami
import org.kde.kquickcontrols 2.0
import org.kde.ksysguard.sensors 1.0 as Sensors
import org.kde.ksysguard.faces 1.0 as Faces
Loader {
id: root
property Faces.SensorFaceController controller
signal configurationChanged
function saveConfig() {
if (item.saveConfig) {
item.saveConfig()
}
for (var key in root.controller.faceConfiguration) {
if (item.hasOwnProperty("cfg_" + key)) {
root.controller.faceConfiguration[key] = item["cfg_" + key]
}
}
}
onItemChanged: {
if (!item || !root.controller.faceConfiguration) {
return;
}
for (var key in root.controller.faceConfiguration) {
if (!item.hasOwnProperty("cfg_" + key)) {
continue;
}
item["cfg_" + key] = root.controller.faceConfiguration[key];
var changedSignal = item["cfg_" + key + "Changed"];
if (changedSignal) {
changedSignal.connect(root.configurationChanged);
}
}
}
}
/*
Copyright (C) 2020 Marco Martin <mart@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.