Quellcode durchsuchen

Merge branch 'master' of https://github.com/Maldela/Fancontrol-GUI

Malte Veerman vor 7 Jahren
Ursprung
Commit
526159b75e
67 geänderte Dateien mit 702 neuen und 440 gelöschten Zeilen
  1. 2 3
      CMakeLists.txt
  2. 3 2
      fancontrol-gui/CMakeLists.txt
  3. 17 0
      fancontrol-gui/org.kde.fancontrol.gui.appdata.xml
  4. 1 1
      fancontrol-gui/org.kde.fancontrol.gui.desktop
  5. 42 67
      fancontrol-gui/package/contents/ui/Application.qml
  6. 1 1
      fancontrol-gui/package/contents/ui/ConfigfileTab.qml
  7. 1 1
      fancontrol-gui/package/contents/ui/PwmFansTab.qml
  8. 11 9
      fancontrol-gui/package/contents/ui/SensorsTab.qml
  9. 64 3
      fancontrol-gui/package/contents/ui/SettingsTab.qml
  10. 3 3
      fancontrol-gui/package/metadata.desktop
  11. 5 3
      fancontrol-gui/src/main.cpp
  12. 1 1
      fancontrol-gui/src/windowconfig.cpp
  13. 1 1
      fancontrol-gui/src/windowconfig.h
  14. 131 42
      helper/src/helper.cpp
  15. 1 1
      helper/src/helper.h
  16. 2 2
      import/CMakeLists.txt
  17. 1 1
      import/qml/ErrorDialog.qml
  18. 2 6
      import/qml/FanItem.qml
  19. 1 1
      import/qml/OptionInput.qml
  20. 1 1
      import/qml/PwmPoint.qml
  21. 1 1
      import/qml/StatusPoint.qml
  22. 1 1
      import/qml/colors.js
  23. 1 1
      import/qml/math.js
  24. 1 1
      import/qml/units.js
  25. 1 1
      import/src/config.cpp
  26. 8 8
      import/src/config.h
  27. 4 4
      import/src/fan.cpp
  28. 2 2
      import/src/fan.h
  29. 2 2
      import/src/fancontrolaction.h
  30. 1 1
      import/src/fancontrolqmlextension.cpp
  31. 1 1
      import/src/fancontrolqmlextension.h
  32. 72 16
      import/src/guibase.cpp
  33. 8 9
      import/src/guibase.h
  34. 6 6
      import/src/hwmon.cpp
  35. 2 2
      import/src/hwmon.h
  36. 53 43
      import/src/loader.cpp
  37. 6 4
      import/src/loader.h
  38. 8 8
      import/src/pwmfan.cpp
  39. 2 2
      import/src/pwmfan.h
  40. 1 1
      import/src/pwmfanmodel.cpp
  41. 1 1
      import/src/pwmfanmodel.h
  42. 1 1
      import/src/sensor.cpp
  43. 2 2
      import/src/sensor.h
  44. 131 93
      import/src/systemdcommunicator.cpp
  45. 18 8
      import/src/systemdcommunicator.h
  46. 7 7
      import/src/temp.cpp
  47. 2 2
      import/src/temp.h
  48. 1 1
      import/src/tempmodel.cpp
  49. 2 2
      import/src/tempmodel.h
  50. 1 1
      import/tests/fantest.h
  51. 1 1
      import/tests/loadertest.h
  52. 1 1
      import/tests/pwmfantest.h
  53. 1 1
      import/tests/temptest.h
  54. 1 1
      import/tests/testfan.cpp
  55. 1 1
      import/tests/testfan.h
  56. 1 1
      import/tests/testpwmfan.cpp
  57. 1 1
      import/tests/testpwmfan.h
  58. 1 1
      import/tests/testtemp.cpp
  59. 1 1
      import/tests/testtemp.h
  60. 3 3
      kcm/CMakeLists.txt
  61. 0 0
      kcm/fancontrol-kcm.desktop
  62. 26 21
      kcm/package/contents/ui/KCM.qml
  63. 3 3
      kcm/package/metadata.desktop
  64. 7 7
      kcm/src/fancontrolkcm.cpp
  65. 13 13
      kcm/src/fancontrolkcm.h
  66. 3 3
      po/de/kcm_fancontrol.po
  67. 0 0
      sc-apps-fancontrol_gui.svg

+ 2 - 3
CMakeLists.txt

@@ -16,8 +16,6 @@ set(STANDARD_CONFIG_FILE "/etc/fancontrol" CACHE STRING "The location of the sta
 add_definitions(-DSTANDARD_SERVICE_NAME="${STANDARD_SERVICE_NAME}")
 add_definitions(-DSTANDARD_CONFIG_FILE="${STANDARD_CONFIG_FILE}")
 
-set(KDE_INSTALL_USE_QT_SYS_PATHS ON CACHE BOOL "Use Qt install paths so the qml plugin is always found" FORCE)
-
 
 #KCM can't be build without systemd support
 if(BUILD_KCM AND NO_SYSTEMD)
@@ -104,7 +102,8 @@ if(INSTALL_SHARED)
 
 
     #icon
-    install(FILES icon.svg RENAME "fancontrol_gui.svg" DESTINATION "${KDE_INSTALL_ICONDIR}/hicolor/scalable/apps")
+    include(ECMInstallIcons)
+    ecm_install_icons(ICONS sc-apps-fancontrol_gui.svg DESTINATION "${KDE_INSTALL_ICONDIR}")
 
 
     #translations

+ 3 - 2
fancontrol-gui/CMakeLists.txt

@@ -19,6 +19,7 @@ add_executable(fancontrol_gui ${Fancontrol_GUI_SRCS})
 target_link_libraries(fancontrol_gui ${LIBRARIES})
 
 install(TARGETS fancontrol_gui ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
-install(FILES metadata.desktop RENAME "fancontrol_gui.desktop" DESTINATION ${KDE_INSTALL_APPDIR})
+install(PROGRAMS org.kde.fancontrol.gui.desktop DESTINATION ${KDE_INSTALL_APPDIR})
+install(FILES org.kde.fancontrol.gui.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
 
-kpackage_install_package(package org.kde.fancontrol.gui genericqml)
+kpackage_install_bundled_package(package org.kde.fancontrol.gui genericqml)

+ 17 - 0
fancontrol-gui/org.kde.fancontrol.gui.appdata.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<component type="desktop">
+    <id>org.fancontrol.gui.desktop</id>
+    <metadata_license>CC0-1.0</metadata_license>
+    <project_license>GPL-2.0</project_license>
+    <name>Fancontrol-GUI</name>
+    <summary>GUI frontend for the fancontrol script</summary>
+    <description>
+        <p>GUI frontend for the fancontrol script.</p>
+    </description>
+    <categories>
+        <category>System</category>
+    </categories>
+    <provides>
+        <binary>fancontrol_gui</binary>
+    </provides>
+</component>

+ 1 - 1
fancontrol-gui/metadata.desktop → fancontrol-gui/org.kde.fancontrol.gui.desktop

@@ -7,4 +7,4 @@ Exec=fancontrol_gui
 Icon=fancontrol_gui
 Terminal=false
 Categories=System;Settings;
-Keywords=pwmconfig;
+Keywords=pwmconfig;

+ 42 - 67
fancontrol-gui/package/contents/ui/Application.qml

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -20,13 +20,13 @@
 
 import QtQuick 2.4
 import QtQuick.Controls 1.3
-import QtQuick.Dialogs 1.2
 import QtQuick.Layouts 1.1
 import Fancontrol.Qml 1.0 as Fancontrol
 
 
 ApplicationWindow {
     id: window
+
     title: i18n("Fancontrol-GUI")
     width: 1024
     height: 768
@@ -34,7 +34,6 @@ ApplicationWindow {
     visible: true
 
     onClosing: {
-        Fancontrol.base.save();
         windowConfig.save(window);
     }
 
@@ -43,49 +42,28 @@ ApplicationWindow {
         windowConfig.restore(window);
     }
 
-    menuBar: MenuBar {
-        Menu {
-            title: i18n("File")
-
-            MenuItem { action: loadAction }
-            MenuItem { action: saveAction }
-            MenuItem {
-                text: i18n("Save configuration file as")
-                onTriggered: saveFileDialog.open()
-                shortcut: StandardKey.SaveAs
-            }
-            MenuItem {
-                text: i18n("Exit")
-                onTriggered: Qt.quit()
-                shortcut: StandardKey.Quit
-            }
-        }
-    }
-
     toolBar: ToolBar {
         RowLayout {
             anchors.fill: parent
 
-            ToolButton { action: loadAction }
-            ToolButton { action: saveAction }
+            ToolButton {
+                action: applyAction
+            }
+            ToolButton {
+                action: resetAction
+            }
             Loader {
-                active: Fancontrol.base.hasSystemdCommunicator()
+                active: !!Fancontrol.base.systemdCom
+
                 sourceComponent: ToolButton {
-                    iconName: Fancontrol.base.systemdCom.serviceActive ? "system-reboot" : "system-run"
-                    onClicked: {
-                        Fancontrol.base.loader.abortTestingFans();
-                        Fancontrol.base.systemdCom.serviceActive ? Fancontrol.base.systemdCom.restartService() : Fancontrol.base.systemdCom.serviceActive = true;
-                    }
-                    tooltip: Fancontrol.base.systemdCom.serviceActive ? i18n("Restart fancontrol") : i18n("Start fancontrol")
+                    action: startAction
                 }
             }
             Loader {
-                active: Fancontrol.base.hasSystemdCommunicator()
+                active: !!Fancontrol.base.systemdCom
+
                 sourceComponent: ToolButton {
-                    iconName: "system-shutdown"
-                    enabled: Fancontrol.base.systemdCom.serviceActive
-                    onClicked: Fancontrol.base.systemdCom.serviceActive = false;
-                    tooltip: i18n("Stop fancontrol")
+                    action: stopAction
                 }
             }
             Item {
@@ -126,43 +104,40 @@ ApplicationWindow {
     }
 
     Action {
-        id: loadAction
-        text: i18n("Load configuration file")
-        iconName: "document-open"
-        onTriggered: openFileDialog.open()
-        tooltip: i18n("Load configuration file")
-        shortcut: StandardKey.Open
+        id: applyAction
+        text: i18n("Apply")
+        enabled: Fancontrol.base.needsApply
+        onTriggered: Fancontrol.base.apply()
+        iconName: "dialog-ok-apply"
+        tooltip: i18n("Apply changes")
+        shortcut: StandardKey.Apply
     }
     Action {
-        id: saveAction
-        text: i18n("Save configuration file")
-        onTriggered: Fancontrol.base.save(true)
-        iconName: "document-save"
-        tooltip: i18n("Save configuration file") + " (" + Fancontrol.base.loader.configPath + ")"
-        shortcut: StandardKey.Save
+        id: resetAction
+        text: i18n("Reset")
+        enabled: Fancontrol.base.needsApply
+        onTriggered: Fancontrol.base.reset()
+        iconName: "edit-undo"
+        tooltip: i18n("Revert changes")
     }
+    Action {
+        id: startAction
+        text: i18n("Start")
+        enabled: !!Fancontrol.base.systemdCom && !Fancontrol.base.systemdCom.serviceActive
+        iconName: "media-playback-start"
+        tooltip: i18n("Enable manual control")
 
-    FileDialog {
-        id: openFileDialog
-        title: i18n("Please choose a configuration file")
-        folder: "file:///etc"
-        selectExisting: true
-        selectMultiple: false
-        modality: Qt.NonModal
-
-        onAccepted: Fancontrol.base.configUrl = fileUrl;
-    }
-    FileDialog {
-        id: saveFileDialog
-        title: i18n("Save configuration file as")
-        folder: "file:///etc"
-        selectExisting: false
-        selectMultiple: false
-        modality: Qt.NonModal
-
-        onAccepted: Fancontrol.base.save(true, fileUrl);
+        onTriggered: Fancontrol.base.systemdCom.serviceActive = true
     }
+    Action {
+        id: stopAction
+        text: i18n("Stop")
+        enabled: !!Fancontrol.base.systemdCom && Fancontrol.base.systemdCom.serviceActive
+        iconName: "media-playback-stop"
+        tooltip: i18n("Disable manual control")
 
+        onTriggered: Fancontrol.base.systemdCom.serviceActive = false
+    }
     SystemPalette {
         id: palette
     }

+ 1 - 1
fancontrol-gui/package/contents/ui/ConfigfileTab.qml

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by

+ 1 - 1
fancontrol-gui/package/contents/ui/PwmFansTab.qml

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by

+ 11 - 9
fancontrol-gui/package/contents/ui/SensorsTab.qml

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -25,9 +25,11 @@ import Fancontrol.Qml 1.0 as Fancontrol
 
 
 RowLayout {
+    id: root
+
+    property int padding: 10
     property QtObject loader: Fancontrol.base.loader
 
-    id: root
     anchors.fill: parent
     anchors.margins: 10
 
@@ -36,7 +38,6 @@ RowLayout {
 
         Rectangle {
             property QtObject hwmon: loader.hwmons[index]
-            property int padding: 10
 
             Layout.preferredWidth: root.width / loader.hwmons.length - root.spacing
             Layout.maximumWidth: 500
@@ -45,6 +46,7 @@ RowLayout {
             border.width: 1
             border.color: "black"
             radius: 5
+            clip: true
 
             Column {
                 id: column
@@ -65,15 +67,15 @@ RowLayout {
 
                         Label {
                             anchors.left: parent.left
-                            anchors.leftMargin: padding
-                            Layout.maximumWidth: parent.width - rpmValue.width - padding*2
+                            anchors.leftMargin: root.padding
+                            Layout.maximumWidth: parent.width - rpmValue.width - root.padding*2
                             clip: true
                             text: "Fan " + (index+1) + ":"
                         }
                         Label {
                             id: rpmValue
                             anchors.right: parent.right
-                            anchors.rightMargin: padding
+                            anchors.rightMargin: root.padding
                             text: hwmon.fans[index].rpm + " " + i18n("rpm")
                         }
                     }
@@ -86,15 +88,15 @@ RowLayout {
 
                         Label {
                             anchors.left: parent.left
-                            anchors.leftMargin: padding
+                            anchors.leftMargin: root.padding
                             text: hwmon.temps[index].name + ": "
-                            Layout.maximumWidth: parent.width - tempValue.width - padding*2
+                            Layout.maximumWidth: parent.width - tempValue.width - root.padding*2
                             clip: true
                         }
                         Label {
                             id: tempValue
                             anchors.right: parent.right
-                            anchors.rightMargin: padding
+                            anchors.rightMargin: root.padding
                             text: Units.fromCelsius(hwmon.temps[index].value, Fancontrol.base.unit) + " " + i18n(Fancontrol.base.unit)
                         }
                     }

+ 64 - 3
fancontrol-gui/package/contents/ui/SettingsTab.qml

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -21,12 +21,13 @@
 import QtQuick 2.4
 import QtQuick.Layouts 1.1
 import QtQuick.Controls 1.2
+import QtQuick.Dialogs 1.2
 import Fancontrol.Qml 1.0 as Fancontrol
 
 
 Item {
     property QtObject systemdCom: Fancontrol.base.hasSystemdCommunicator() ? Fancontrol.base.systemdCom : null
-    property QtObject loader : Fancontrol.base.loader
+    property QtObject loader: Fancontrol.base.loader
     property int padding: 10
     property real textWidth: 0
     property var locale: Qt.locale()
@@ -52,12 +53,19 @@ Item {
                 Component.onCompleted: root.textWidth = Math.max(root.textWidth, contentWidth)
             }
             SpinBox {
+                id: intervalSpinBox
+
                 Layout.minimumWidth: implicitWidth
                 Layout.fillWidth: true
                 value: loader.interval
                 suffix: " " + i18np("second", "seconds", loader.interval)
                 minimumValue: 1.0
                 onValueChanged: loader.interval = value
+
+                Connections {
+                    target: loader
+                    onIntervalChanged: if (loader.interval != intervalSpinBox.value) intervalSpinBox.value = loader.interval
+                }
             }
         }
         RowLayout {
@@ -72,6 +80,7 @@ Item {
             }
             SpinBox {
                 id: minTempBox
+
                 Layout.minimumWidth: implicitWidth
                 Layout.fillWidth: true
                 decimals: 2
@@ -83,6 +92,11 @@ Item {
                     Fancontrol.base.minTemp = Fancontrol.Units.toCelsius(value, Fancontrol.base.unit);
                     if (value > maxTempBox.value) maxTempBox.value = value;
                 }
+
+                Connections {
+                    target: Fancontrol.base
+                    onMinTempChanged: if (Fancontrol.base.minTemp != minTempBox.value) minTempBox.value = Fancontrol.base.minTemp
+                }
             }
         }
         RowLayout {
@@ -97,6 +111,7 @@ Item {
             }
             SpinBox {
                 id: maxTempBox
+
                 Layout.minimumWidth: implicitWidth
                 Layout.fillWidth: true
                 decimals: 2
@@ -108,6 +123,34 @@ Item {
                     Fancontrol.base.maxTemp = Fancontrol.Units.toCelsius(value, Fancontrol.base.unit);
                     if (value < minTempBox.value) minTempBox.value = value;
                 }
+
+                Connections {
+                    target: Fancontrol.base
+                    onMaxTempChanged: if (Fancontrol.base.maxTemp != maxTempBox.value) maxTempBox.value = Fancontrol.base.maxTemp
+                }
+            }
+        }
+        RowLayout {
+            width: parent.width
+
+            Label {
+                Layout.preferredWidth: root.textWidth
+                clip: true
+                text: i18n("Path to the fancontrol config file:")
+                horizontalAlignment: Text.AlignRight
+                Component.onCompleted: root.textWidth = Math.max(root.textWidth, contentWidth)
+            }
+            Fancontrol.OptionInput {
+                id: fileInput
+
+                Layout.fillWidth: true
+                value: Fancontrol.base.configUrl.toString().replace("file://", "")
+                onTextChanged: Fancontrol.base.configUrl = text;
+            }
+            Button {
+                iconName: "document-open"
+                tooltip: i18n("Open config file")
+                onClicked: openFileDialog.open();
             }
         }
         Loader {
@@ -123,6 +166,8 @@ Item {
                     Component.onCompleted: root.textWidth = Math.max(root.textWidth, contentWidth)
                 }
                 Fancontrol.OptionInput {
+                    id: serviceNameInput
+
                     Layout.minimumWidth: implicitWidth
                     Layout.fillWidth: true
                     color: !!systemdCom && systemdCom.serviceExists ? "green" : "red"
@@ -139,12 +184,13 @@ Item {
                 Label {
                     Layout.preferredWidth: root.textWidth
                     clip: true
-                    text: i18n("Fancontrol systemd service autostart:")
+                    text: i18n("Enable service at boot:")
                     horizontalAlignment: Text.AlignRight
                     Component.onCompleted: root.textWidth = Math.max(root.textWidth, contentWidth)
                 }
                 CheckBox {
                     id: autostartBox
+
                     Layout.minimumWidth: implicitWidth
                     Layout.fillWidth: true
                     checked: !!systemdCom ? systemdCom.serviceEnabled : false
@@ -153,8 +199,23 @@ Item {
                             systemdCom.serviceEnabled = checked;
                         }
                     }
+
+                    Connections {
+                        target: systemdCom
+                        onServiceEnabledChanged: if (systemdCom.serviceEnabled != autostartBox.checked) autostartBox.checked = systemdCom.serviceEnabled
+                    }
                 }
             }
         }
+        FileDialog {
+            id: openFileDialog
+            title: i18n("Please choose a configuration file")
+            folder: "file:///etc"
+            selectExisting: true
+            selectMultiple: false
+            modality: Qt.NonModal
+
+            onAccepted: fileInput.text = fileUrl;
+        }
     }
 }

+ 3 - 3
fancontrol-gui/package/metadata.desktop

@@ -6,11 +6,11 @@ Encoding=UTF-8
 Keywords=
 Type=Service
 X-KDE-PluginInfo-Author=Malte Veerman
-X-KDE-PluginInfo-Email=maldela@halloarsch.de
+X-KDE-PluginInfo-Email=malte.veerman@gmail.com
 X-KDE-PluginInfo-License=GPL
-X-KDE-PluginInfo-Name=fancontrol-gui
+X-KDE-PluginInfo-Name=org.kde.fancontrol.gui
 X-KDE-PluginInfo-Version=0.4
 X-KDE-PluginInfo-Website=
 X-KDE-ServiceTypes=Plasma/Generic
-X-Plasma-API=declarativeappletscript 
+X-Plasma-API=declarativeappletscript
 X-Plasma-MainScript=ui/Application.qml

+ 5 - 3
fancontrol-gui/src/main.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -29,6 +29,8 @@
 
 #include "windowconfig.h"
 
+#include <QDebug>
+
 
 Q_DECLARE_LOGGING_CATEGORY(FANCONTROL)
 Q_LOGGING_CATEGORY(FANCONTROL, "fancontrol-gui")
@@ -40,7 +42,7 @@ int main(int argc, char *argv[])
 
     KLocalizedString::setApplicationDomain("kcm_fancontrol");
 
-    auto about = KAboutData(QStringLiteral("fancontrol_gui"),
+    auto about = KAboutData(QStringLiteral("org.kde.fancontrol.gui"),
                             i18n("Fancontrol-GUI"),
                             QStringLiteral("0.4"),
                             i18n("Graphical user interface for fancontrol"),
@@ -49,7 +51,7 @@ int main(int argc, char *argv[])
                             QString(),
                             QStringLiteral("http://github.com/maldela/fancontrol-gui"),
                             QStringLiteral("http://github.com/maldela/fancontrol-gui/issues"));
-    about.addAuthor(i18n("Malte Veerman"), i18n("Main Developer"), QStringLiteral("maldela@halloarsch.de"));
+    about.addAuthor(i18n("Malte Veerman"), i18n("Main Developer"), QStringLiteral("malte.veerman@gmail.com"));
     KAboutData::setApplicationData(about);
 
     const auto parser = new QCommandLineParser;

+ 1 - 1
fancontrol-gui/src/windowconfig.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
fancontrol-gui/src/windowconfig.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by

+ 131 - 42
helper/src/helper.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -29,8 +29,41 @@
 
 #ifndef NO_SYSTEMD
 #include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusMetaType>
+#include <QtDBus/QDBusReply>
+#include <QtDBus/QDBusVariant>
+
+
+struct StringStruct
+{
+    QString type;
+    QString filename;
+    QString destination;
+};
+
+typedef QList<StringStruct> StringStructArray;
+
+Q_DECLARE_METATYPE(StringStruct)
+Q_DECLARE_METATYPE(StringStructArray)
+
+QDBusArgument &operator<<(QDBusArgument &argument, const StringStruct &structure)
+{
+    argument.beginStructure();
+    argument << structure.type << structure.filename << structure.destination;
+    argument.endStructure();
+    return argument;
+}
+
+const QDBusArgument &operator>>(const QDBusArgument &argument, StringStruct &structure)
+{
+    argument.beginStructure();
+    argument >> structure.type >> structure.filename >> structure.destination;
+    argument.endStructure();
+    return argument;
+}
 #endif
 
+
 ActionReply Helper::action(const QVariantMap &arguments)
 {
     ActionReply reply;
@@ -38,54 +71,116 @@ ActionReply Helper::action(const QVariantMap &arguments)
 #ifndef NO_SYSTEMD
     if (arguments[QStringLiteral("action")] == "dbusaction")
     {
+        qDBusRegisterMetaType<StringStruct>();
+        qDBusRegisterMetaType<StringStructArray>();
+
         const auto method = arguments[QStringLiteral("method")].toString();
         const auto argsForCall = arguments[QStringLiteral("arguments")].toList();
 
         const auto systembus = QDBusConnection::systemBus();
-
         const auto iface = new QDBusInterface (QStringLiteral("org.freedesktop.systemd1"),
                                                QStringLiteral("/org/freedesktop/systemd1"),
                                                QStringLiteral("org.freedesktop.systemd1.Manager"),
                                                systembus,
                                                this);
-
-        QDBusMessage dbusreply;
+        QDBusMessage dbusmessage;
 
         if (iface->isValid())
-            dbusreply = iface->callWithArgumentList(QDBus::AutoDetect, method, argsForCall);
-        delete iface;
-
-        if (method != QStringLiteral("Reexecute"))
         {
-            if (dbusreply.type() == QDBusMessage::ErrorMessage)
+            if (argsForCall.isEmpty())
+                dbusmessage = iface->call(QDBus::AutoDetect, method);
+            else
+                dbusmessage = iface->callWithArgumentList(QDBus::AutoDetect, method, argsForCall);
+
+            if (method != QStringLiteral("Reexecute"))
             {
-                reply.setErrorCode(ActionReply::DBusError);
-                reply.setErrorDescription(dbusreply.errorMessage());
+                if (dbusmessage.type() == QDBusMessage::ErrorMessage)
+                {
+                    reply.setErrorCode(ActionReply::DBusError);
+                    reply.setErrorDescription(dbusmessage.errorMessage());
+                }
+                else if (dbusmessage.type() == QDBusMessage::ReplyMessage)
+                {
+                    if (dbusmessage.signature() == QStringLiteral("a(sss)"))
+                    {
+                        QDBusReply<StringStructArray> dbusreply(dbusmessage);
+                        if (dbusreply.isValid())
+                        {
+                            QMap<QString, QVariant> map;
+                            map.insert(QStringLiteral("type"), dbusreply.value().value(0).type);
+                            map.insert(QStringLiteral("filename"), dbusreply.value().value(0).filename);
+                            map.insert(QStringLiteral("destination"), dbusreply.value().value(0).destination);
+                            reply.addData(QStringLiteral("reply"), map);
+                        }
+                        else
+                        {
+                            reply = ActionReply::HelperErrorReply();
+                            reply.setErrorDescription(dbusreply.error().message());
+                        }
+                    }
+                    else if (dbusmessage.signature() == QStringLiteral("ba(sss)"))
+                    {
+                        QDBusReply<bool> dbusreply(dbusmessage); //QDBusReply only extracts the first return argument("b")
+                        if (dbusreply.isValid())
+                        {
+                            QMap<QString, QVariant> map;
+                            map.insert(QStringLiteral("enableInfo"), dbusreply.value());
+                            auto changes = qdbus_cast<StringStructArray>(qvariant_cast<QDBusArgument>(dbusmessage.arguments().value(1))); //Extract the second argument("a(sss)")
+                            map.insert(QStringLiteral("type"), changes.value(0).type);
+                            map.insert(QStringLiteral("filename"), changes.value(0).filename);
+                            map.insert(QStringLiteral("destination"), changes.value(0).destination);
+                            reply.addData(QStringLiteral("reply"), map);
+                        }
+                        else
+                        {
+                            reply = ActionReply::HelperErrorReply();
+                            reply.setErrorDescription(dbusreply.error().message());
+                        }
+                    }
+                    else if (dbusmessage.signature() == QStringLiteral("o"))
+                    {
+                        QDBusReply<QDBusObjectPath> dbusreply(dbusmessage);
+                        if (dbusreply.isValid())
+                        {
+                            QMap<QString, QVariant> map;
+                            map.insert(QStringLiteral("job"), dbusreply.value().path());
+                            reply.addData(QStringLiteral("reply"), map);
+                        }
+                        else
+                        {
+                            reply = ActionReply::HelperErrorReply();
+                            reply.setErrorDescription(dbusreply.error().message());
+                        }
+                    }
+                }
             }
         }
+        else
+        {
+            reply = ActionReply::HelperErrorReply();
+            reply.setErrorDescription(i18n("Could not create dbus interface"));
+        }
+        delete iface;
     }
     else
 #endif
-        if (arguments[QStringLiteral("action")] == "read")
+    if (arguments[QStringLiteral("action")] == "read")
     {
         const auto filename = arguments[QStringLiteral("filename")].toString();
         QFile file(filename);
 
-        if (!file.open(QIODevice::ReadOnly))
+        if (file.open(QIODevice::ReadOnly))
         {
-           reply = ActionReply::HelperErrorType;
-           reply.setErrorDescription(file.errorString());
+            QTextStream stream(&file);
+            const auto content = stream.readAll();
 
-           return reply;
+            reply.addData(QStringLiteral("content"), content);
+        }
+        else
+        {
+            reply = ActionReply::HelperErrorReply();
+            reply.setErrorDescription(file.errorString());
         }
-
-        QTextStream stream(&file);
-        const auto content = stream.readAll();
-
-        QVariantMap returnData;
-        returnData[QStringLiteral("content")] = content;
-
-        reply.setData(returnData);
     }
 
     else if (arguments[QStringLiteral("action")] == "write")
@@ -93,16 +188,16 @@ ActionReply Helper::action(const QVariantMap &arguments)
         const auto filename = arguments[QStringLiteral("filename")].toString();
         QFile file(filename);
 
-        if (!file.open(QIODevice::WriteOnly))
+        if (file.open(QIODevice::WriteOnly))
         {
-           reply = ActionReply::HelperErrorType;
-           reply.setErrorDescription(file.errorString());
-
-           return reply;
+            QTextStream stream(&file);
+            stream << arguments[QStringLiteral("content")].toString();
+        }
+        else
+        {
+            reply = ActionReply::HelperErrorReply();
+            reply.setErrorDescription(file.errorString());
         }
-
-        QTextStream stream(&file);
-        stream << arguments[QStringLiteral("content")].toString();
     }
 
     else if (arguments[QStringLiteral("action")] == "detectSensors")
@@ -115,25 +210,19 @@ ActionReply Helper::action(const QVariantMap &arguments)
 
         if (!process.waitForStarted(1000))
         {
-            reply = ActionReply::HelperErrorType;
+            reply = ActionReply::HelperErrorReply();
             reply.setErrorDescription(process.errorString());
-
-            return reply;
         }
-
-        if (!process.waitForFinished(10000))
+        else if (!process.waitForFinished(10000))
         {
-            reply = ActionReply::HelperErrorType;
+            reply = ActionReply::HelperErrorReply();
             reply.setErrorDescription(process.errorString());
-
-            return reply;
         }
     }
 
     else
     {
-        reply.setType(ActionReply::HelperErrorType);
-        reply.setErrorCode(ActionReply::NoSuchActionError);
+        reply = ActionReply::HelperErrorReply();
         reply.setErrorDescription(i18n("This action does not exist!"));
     }
 

+ 1 - 1
helper/src/helper.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by

+ 2 - 2
import/CMakeLists.txt

@@ -48,8 +48,8 @@ include_directories(${Qt5Qml_INCLUDE_DIRS})
 add_library(fancontrol_qml_plugin SHARED ${LIB_SRCS})
 target_link_libraries(fancontrol_qml_plugin PRIVATE ${LIB_PRIVATE_LIBRARIES} PUBLIC ${LIB_PUBLIC_LIBRARIES})
 
-install(TARGETS fancontrol_qml_plugin DESTINATION "${KDE_INSTALL_QMLDIR}/Fancontrol/Qml/")
-install(FILES ${QML_FILES} DESTINATION "${KDE_INSTALL_QMLDIR}/Fancontrol/Qml/")
+install(TARGETS fancontrol_qml_plugin DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/qt/qml/Fancontrol/Qml/")
+install(FILES ${QML_FILES} DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/qt/qml/Fancontrol/Qml/")
 
 ecm_generate_qmltypes(Fancontrol.Qml 1.0 DESTINATION "${KDE_INSTALL_QMLDIR}/Fancontrol/Qml/")
 

+ 1 - 1
import/qml/ErrorDialog.qml

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by

+ 2 - 6
import/qml/FanItem.qml

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -78,11 +78,7 @@ Rectangle {
         font.pointSize: 14
         selectByMouse: true
 
-        onTextChanged: {
-            if (!!fan) {
-                fan.name = text;
-            }
-        }
+        onTextChanged: if (!!fan && fan.name != text) fan.name = text
 
         Connections {
             target: fan

+ 1 - 1
import/qml/OptionInput.qml

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by

+ 1 - 1
import/qml/PwmPoint.qml

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by

+ 1 - 1
import/qml/StatusPoint.qml

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by

+ 1 - 1
import/qml/colors.js

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by

+ 1 - 1
import/qml/math.js

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by

+ 1 - 1
import/qml/units.js

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by

+ 1 - 1
import/src/config.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 8 - 8
import/src/config.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -31,22 +31,22 @@ namespace Fancontrol
 
 class Config : public KCoreConfigSkeleton
 {
-    
+
 Q_OBJECT
 
 public:
-    
+
     static Config *instance();
-    
-    
+
+
 private:
-    
+
     Config(QObject *parent = Q_NULLPTR);
     ~Config() {}
     Q_DISABLE_COPY(Config)
-    
+
     static Config *m_instance;
-    
+
     double m_minTemp;
     double m_maxTemp;
     QString m_serviceName;

+ 4 - 4
import/src/fan.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -52,7 +52,7 @@ Fan::Fan(uint index, Hwmon *parent) : Sensor(parent, index, parent ? parent->nam
         }
         else
         {
-            emit error(i18n("Can't open rpm file: \"%1\"", rpmFile->fileName()));
+            emit error(i18n("Can't open rpm file: \'%1\'", rpmFile->fileName()));
             delete rpmFile;
         }
     }
@@ -90,7 +90,7 @@ void Fan::setName(const QString &name)
     }
 }
 
-void Fan::reset()
+void Fan::toDefault()
 {
     if (m_rpmStream->device() && m_parent)
     {
@@ -109,7 +109,7 @@ void Fan::reset()
             }
             else
             {
-                emit error(i18n("Can't open rpm file: \"%1\"", rpmFile->fileName()));
+                emit error(i18n("Can't open rpm file: \'%1\'", rpmFile->fileName()));
                 delete rpmFile;
             }
         }

+ 2 - 2
import/src/fan.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -43,7 +43,7 @@ public:
     int rpm() const { return m_rpm; }
     QString name() const Q_DECL_OVERRIDE;
     void setName(const QString &name) Q_DECL_OVERRIDE;
-    void reset() Q_DECL_OVERRIDE;
+    void toDefault() Q_DECL_OVERRIDE;
     bool isValid() const Q_DECL_OVERRIDE;
 
     virtual int pwm() const { return 255; }

+ 2 - 2
import/src/fancontrolaction.h

@@ -1,6 +1,6 @@
 /*
  * <one line to give the library's name and an idea of what it does.>
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -35,7 +35,7 @@ inline KAuth::Action newFancontrolAction()
 {
     KAuth::Action action(QStringLiteral("fancontrol.gui.helper.action"));
     action.setHelperId(QStringLiteral("fancontrol.gui.helper"));
-    
+
     return action;
 }
 

+ 1 - 1
import/src/fancontrolqmlextension.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright 2016  Malte Veerman <maldela@halloarsch.de>
+ * Copyright 2016  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
import/src/fancontrolqmlextension.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2016  Malte Veerman <maldela@halloarsch.de>
+ * Copyright 2016  Malte Veerman <malte.veerman@gmail.com>
  * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 72 - 16
import/src/guibase.cpp

@@ -1,6 +1,6 @@
 /*
  * <one line to give the library's name and an idea of what it does.>
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -29,6 +29,8 @@
 #include <QtCore/QLocale>
 #include <QtCore/QDebug>
 
+#include <KI18n/KLocalizedString>
+
 
 namespace Fancontrol
 {
@@ -42,14 +44,16 @@ GUIBase::GUIBase(QObject *parent) : QObject(parent),
 
     m_loader(new Loader(this)),
     m_configValid(false),
+    m_configChanged(false),
     m_pwmFanModel(new PwmFanModel(this)),
     m_tempModel(new TempModel(this))
 {
-    connect(m_config, &Config::configChanged, this, &GUIBase::emitConfigChanged);
     connect(this, &GUIBase::unitChanged, m_tempModel, &TempModel::setUnit);
+    connect(m_loader, &Loader::needsSaveChanged, this, &GUIBase::needsApplyChanged);
 
 #ifndef NO_SYSTEMD
     connect(m_loader, &Loader::requestSetServiceActive, m_com, &SystemdCommunicator::setServiceActive);
+    connect(m_com, &SystemdCommunicator::needsApplyChanged, this, &GUIBase::needsApplyChanged);
 #endif
 
     const auto locale = QLocale::system();
@@ -74,17 +78,13 @@ void GUIBase::load()
 
 #ifndef NO_SYSTEMD
     m_com->setServiceName(serviceName());
+    m_com->reset();
 #endif
 
-    emitConfigChanged();
-}
-
-void GUIBase::save(bool saveLoader, const QUrl &url)
-{
-    m_config->save();
-
-    if (saveLoader)
-        m_loader->save(url);
+    emit serviceNameChanged();
+    emit minTempChanged();
+    emit maxTempChanged();
+    emit configUrlChanged();
 }
 
 qreal GUIBase::maxTemp() const
@@ -113,6 +113,9 @@ void GUIBase::setMaxTemp(qreal temp)
     {
         m_config->findItem(QStringLiteral("MaxTemp"))->setProperty(temp);
         emit maxTempChanged();
+
+        m_configChanged = true;
+        emit needsApplyChanged();
     }
 }
 
@@ -122,6 +125,9 @@ void GUIBase::setMinTemp(qreal temp)
     {
         m_config->findItem(QStringLiteral("MinTemp"))->setProperty(temp);
         emit minTempChanged();
+
+        m_configChanged = true;
+        emit needsApplyChanged();
     }
 }
 
@@ -136,6 +142,9 @@ void GUIBase::setServiceName(const QString& name)
 #endif
 
         emit serviceNameChanged();
+
+        m_configChanged = true;
+        emit needsApplyChanged();
     }
 }
 
@@ -147,15 +156,19 @@ void GUIBase::setConfigUrl(const QUrl &url)
 
         m_config->findItem(QStringLiteral("ConfigUrl"))->setProperty(url.toString());
         emit configUrlChanged();
+
+        m_configChanged = true;
+        emit needsApplyChanged();
     }
 }
 
-void GUIBase::emitConfigChanged()
+bool GUIBase::needsApply() const
 {
-    emit serviceNameChanged();
-    emit minTempChanged();
-    emit maxTempChanged();
-    emit configUrlChanged();
+#ifndef NO_SYSTEMD
+    return m_loader->needsSave() || m_configChanged || m_com->needsApply();
+#else
+    return m_loader->needsSave() || m_configChanged;
+#endif
 }
 
 bool GUIBase::hasSystemdCommunicator() const
@@ -167,6 +180,40 @@ bool GUIBase::hasSystemdCommunicator() const
 #endif
 }
 
+void GUIBase::apply()
+{
+    qInfo() << i18n("Applying changes");
+
+    bool configChanged = m_loader->save();
+    m_config->save();
+
+#ifndef NO_SYSTEMD
+    m_com->apply(configChanged);
+#endif
+}
+
+void GUIBase::reset()
+{
+    qInfo() << i18n("Resetting changes");
+
+    m_config->load();
+    emit serviceNameChanged();
+    emit minTempChanged();
+    emit maxTempChanged();
+    emit configUrlChanged();
+    m_configChanged = false;
+
+    if (m_loader->needsSave() || configUrl() != m_loader->configUrl())
+        m_loader->load(configUrl());
+
+#ifndef NO_SYSTEMD
+    m_com->setServiceName(serviceName());
+    m_com->reset();
+#endif
+
+    emit needsApplyChanged();
+}
+
 void GUIBase::handleError(const QString &error, bool critical)
 {
     if (error.isEmpty() || error == m_error)
@@ -184,5 +231,14 @@ void GUIBase::handleError(const QString &error, bool critical)
         qWarning() << error;
 }
 
+void GUIBase::handleInfo(const QString &info)
+{
+    if (info.isEmpty())
+        return;
+
+    else
+        qInfo() << info;
+}
+
 
 }

+ 8 - 9
import/src/guibase.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -58,6 +58,7 @@ class GUIBase : public QObject
     Q_PROPERTY(QUrl configUrl READ configUrl WRITE setConfigUrl NOTIFY configUrlChanged)
     Q_PROPERTY(bool configValid READ configValid NOTIFY configUrlChanged)
     Q_PROPERTY(QString error READ error NOTIFY errorChanged)
+    Q_PROPERTY(bool needsApply READ needsApply NOTIFY needsApplyChanged)
 
 public:
 
@@ -81,18 +82,20 @@ public:
     void setServiceName(const QString &name);
     void setConfigUrl(const QUrl &url);
     void setUnit(const QString &unit) { if (unit != m_unit) { m_unit = unit; emit unitChanged(m_unit); } }
+    bool needsApply() const;
     PwmFanModel *pwmFanModel() const { return m_pwmFanModel; }
     TempModel *tempModel() const { return m_tempModel; }
 
     Q_INVOKABLE bool hasSystemdCommunicator() const;
+    Q_INVOKABLE void apply();
+    Q_INVOKABLE void reset();
 
 
 public slots:
 
-    void save(bool saveLoader = false, const QUrl &url = QUrl());
     void load();
     void handleError(const QString &error, bool critical = false);
-
+    void handleInfo(const QString &info);
 
 signals:
 
@@ -103,12 +106,7 @@ signals:
     void unitChanged(QString);
     void errorChanged();
     void criticalError();
-
-
-protected:
-
-    void emitConfigChanged();
-
+    void needsApplyChanged();
 
 private:
 
@@ -122,6 +120,7 @@ private:
     Loader *const m_loader;
     QString m_unit;
     bool m_configValid;
+    bool m_configChanged;
     PwmFanModel *m_pwmFanModel;
     TempModel *m_tempModel;
 };

+ 6 - 6
import/src/hwmon.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -91,7 +91,7 @@ void Hwmon::initialize()
 
         if (!success)
         {
-            emit error(i18n("Not a valid sensor: \"%1\"", entry));
+            emit error(i18n("Not a valid sensor: \'%1\'", entry));
             continue;
         }
 
@@ -138,7 +138,7 @@ void Hwmon::initialize()
                     if (fan->index() == index)
                     {
                         newFan = fan;
-                        newFan->reset();
+                        newFan->toDefault();
                         break;
                     }
                 }
@@ -162,7 +162,7 @@ void Hwmon::initialize()
                 if (temp->index() == index)
                 {
                     newTemp = temp;
-                    newTemp->reset();
+                    newTemp->toDefault();
                     break;
                 }
             }
@@ -251,10 +251,10 @@ bool Hwmon::testing() const
     return testing;
 }
 
-void Hwmon::reset() const
+void Hwmon::toDefault() const
 {
     for (const auto &pwmFan : m_pwmFans)
-        pwmFan->reset();
+        pwmFan->toDefault();
 }
 
 }

+ 2 - 2
import/src/hwmon.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -66,7 +66,7 @@ public:
     Temp * temp(int i) const;
     bool isValid() const { return m_valid; }
     bool testing() const;
-    void reset() const;
+    void toDefault() const;
 
 
 signals:

+ 53 - 43
import/src/loader.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -31,7 +31,6 @@
 #include <QtCore/QTextStream>
 #include <QtCore/QTimer>
 #include <QtCore/QProcess>
-#include <QtCore/QDebug>
 
 #include <KAuth/KAuthExecuteJob>
 #include <KI18n/KLocalizedString>
@@ -55,7 +54,10 @@ Loader::Loader(GUIBase *parent) : QObject(parent),
     m_sensorsDetected(false)
 {
     if (parent)
+    {
         connect(this, &Loader::error, parent, &GUIBase::handleError);
+        connect(this, &Loader::info, parent, &GUIBase::handleInfo);
+    }
 
     m_timer->setSingleShot(false);
     m_timer->start(1000);
@@ -72,12 +74,12 @@ void Loader::parseHwmons()
 
     else if (hwmonDir.exists())
     {
-        emit error(i18n("File is not readable: \"%1\"", QStringLiteral(HWMON_PATH)), true);
+        emit error(i18n("File is not readable: \'%1\'", QStringLiteral(HWMON_PATH)), true);
         return;
     }
     else
     {
-        emit error(i18n("File does not exist: \"%1\"", QStringLiteral(HWMON_PATH)), true);
+        emit error(i18n("File does not exist: \'%1\'", QStringLiteral(HWMON_PATH)), true);
         return;
     }
 
@@ -163,7 +165,7 @@ QPair<int, int> Loader::getEntryNumbers(const QString &entry)
     auto list = entry.split('/', QString::SkipEmptyParts);
     if (list.size() != 2)
     {
-        emit error(i18n("Invalid entry: \"%1\"", entry));
+        emit error(i18n("Invalid entry: \'%1\'", entry));
         return QPair<int, int>(-1, -1);
     }
     auto &hwmon = list[0];
@@ -171,12 +173,12 @@ QPair<int, int> Loader::getEntryNumbers(const QString &entry)
 
     if (!hwmon.startsWith(QStringLiteral("hwmon")))
     {
-        emit error(i18n("Invalid entry: \"%1\"", entry));
+        emit error(i18n("Invalid entry: \'%1\'", entry));
         return QPair<int, int>(-1, -1);
     }
     if (!sensor.contains(QRegExp("^(pwm|fan|temp)\\d+")))
     {
-        emit error(i18n("Invalid entry: \"%1\"", entry));
+        emit error(i18n("Invalid entry: \'%1\'", entry));
         return QPair<int, int>(-1, -1);
     }
 
@@ -189,13 +191,13 @@ QPair<int, int> Loader::getEntryNumbers(const QString &entry)
     const auto hwmonResult = hwmon.toInt(&success);
     if (!success)
     {
-        emit error(i18n("Invalid entry: \"%1\"", entry));
+        emit error(i18n("Invalid entry: \'%1\'", entry));
         return QPair<int, int>(-1, -1);
     }
     const auto sensorResult = sensor.toInt(&success);
     if (!success)
     {
-        emit error(i18n("Invalid entry: \"%1\"", entry));
+        emit error(i18n("Invalid entry: \'%1\'", entry));
         return QPair<int, int>(-1, -1);
     }
 
@@ -209,14 +211,9 @@ bool Loader::parseConfig(QString config)
     for (const auto &hwmon : m_hwmons)
     {
         disconnect(hwmon, &Hwmon::configUpdateNeeded, this, &Loader::updateConfig);
-        const auto pwmFans = hwmon->pwmFans();
-        for (const auto &pwmFan : pwmFans)
-        {
-            qobject_cast<PwmFan *>(pwmFan)->reset();
-        }
     }
 
-    reset();
+    toDefault();
 
     bool success = true;
     QTextStream stream;
@@ -252,7 +249,7 @@ bool Loader::parseConfig(QString config)
                 setInterval(interval, false);
             else
             {
-                emit error(i18n("Unable to parse interval line: \"%1\"", line), true);
+                emit error(i18n("Unable to parse interval line: \'%1\'", line), true);
                 success = false;
             }
         }
@@ -280,14 +277,14 @@ bool Loader::parseConfig(QString config)
                     else
                     {
                         if (!pwmPointer)
-                            emit error(i18n("Invalid fan entry: \"%1\"", pwmFanString), true);
+                            emit error(i18n("Invalid fan entry: \'%1\'", pwmFanString), true);
 
                         if (!tempPointer)
-                            emit error(i18n("Invalid temp entry: \"%1\"", tempString), true);
+                            emit error(i18n("Invalid temp entry: \'%1\'", tempString), true);
                     }
                 }
                 else
-                    emit error(i18n("Invalid entry: \"%1\"", fctemp), true);
+                    emit error(i18n("Invalid entry: \'%1\'", fctemp), true);
             }
         }
         else if (line.startsWith(QStringLiteral("DEVNAME=")))
@@ -309,13 +306,13 @@ bool Loader::parseConfig(QString config)
 
                     if (!intSuccess)
                     {
-                        emit error(i18n("Invalid DEVNAME: \"%1\"!", devname), true);
+                        emit error(i18n("Invalid DEVNAME: \'%1\'!", devname), true);
                         success = false;
                     }
 
                     if (!hwmonPointer)
                     {
-                        emit error(i18n("Invalid DEVNAME: \"%1\"! No hwmon with index %2", devname, index), true);
+                        emit error(i18n("Invalid DEVNAME: \'%1\'! No hwmon with index %2", devname, index), true);
                         success = false;
                     }
                     else if (hwmonPointer->name().split('.').first() != name)
@@ -325,7 +322,7 @@ bool Loader::parseConfig(QString config)
                     }
                 }
                 else
-                    emit error(i18n("Invalid DEVNAME: \"%1\"!", devname), true);
+                    emit error(i18n("Invalid DEVNAME: \'%1\'!", devname), true);
             }
         }
         else if (line.startsWith(QStringLiteral("MINTEMP=")))
@@ -361,7 +358,7 @@ bool Loader::parseConfig(QString config)
         else if (!line.startsWith(QStringLiteral("DEVPATH=")) &&
             !line.startsWith(QStringLiteral("FCFANS=")))
         {
-            emit error(i18n("Unrecognized line in config: \"%1\"", line), true);
+            emit error(i18n("Unrecognized line in config: \'%1\'", line), true);
             success = false;
         }
     }
@@ -398,13 +395,13 @@ void Loader::parseConfigLine(const QString &line, void (PwmFan::*memberSetFuncti
                 if (pwmFanPointer)
                     (pwmFanPointer->*memberSetFunction)(value);
                 else
-                    emit error(i18n("Invalid fan entry: \"%1\"", pwmFanString), true);
+                    emit error(i18n("Invalid fan entry: \'%1\'", pwmFanString), true);
             }
             else
                 emit error(i18n("%1 is not an integer!", valueString));
         }
         else
-            emit error(i18n("Invalid entry to parse: \"%1\"", entry));
+            emit error(i18n("Invalid entry to parse: \'%1\'", entry));
     }
 }
 
@@ -412,10 +409,7 @@ bool Loader::load(const QUrl &url)
 {
     QString fileName;
     if (url.isEmpty())
-    {
-//        qDebug() << "Given empty url. Fallback to" << m_configUrl;
         fileName = m_configUrl.toLocalFile();
-    }
     else if (url.isValid())
     {
         if (url.isLocalFile())
@@ -423,15 +417,16 @@ bool Loader::load(const QUrl &url)
 
         else
         {
-            emit error(i18n("%1 is not a local file!", url.toDisplayString()));
+            emit error(i18n("\'%1\' is not a local file!", url.toDisplayString()));
             return false;
         }
     }
     else
     {
-        emit error(i18n("%1 is not a valid url!", url.toDisplayString()));
+        emit error(i18n("\'%1\' is not a valid url!", url.toDisplayString()));
         return false;
     }
+    emit info(i18n("Loading config file: \'%1\'", fileName));
 
     QTextStream stream;
     QFile file(fileName);
@@ -440,7 +435,6 @@ bool Loader::load(const QUrl &url)
     {
         stream.setDevice(&file);
         m_configFileContent = stream.readAll();
-        emit configChanged();
     }
     else if (file.exists())
     {
@@ -457,7 +451,7 @@ bool Loader::load(const QUrl &url)
             {
                 if (reply->error() == 4)
                 {
-                    qDebug() << "Loading of file aborted by user";
+                    emit info(i18n("Loading of file aborted by user"));
                     return false;
                 }
 
@@ -465,17 +459,14 @@ bool Loader::load(const QUrl &url)
                 return false;
             }
             else
-            {
                 m_configFileContent = reply->data().value(QStringLiteral("content")).toString();
-                emit configChanged();
-            }
         }
         else
             emit error(i18n("Action not supported! Try running the application as root."), true);
     }
     else
     {
-        emit error(i18n("File does not exist: \"%1\"" ,fileName));
+        emit error(i18n("File does not exist: \'%1\'" ,fileName));
         return false;
     }
 
@@ -507,12 +498,26 @@ bool Loader::save(const QUrl &url)
     }
     else
     {
-        emit error(i18n("%1 is not a local file!", url.toDisplayString()), true);
+        emit error(i18n("\'%1\' is not a local file!", url.toDisplayString()), true);
         return false;
     }
-
     QFile file(fileName);
 
+    if (file.open(QFile::ReadOnly | QFile::Text))
+    {
+        QTextStream stream(&file);
+        QString fileContent = stream.readAll();
+
+        if (m_config == fileContent)
+        {
+            emit info(i18n("No changes made to config"));
+            return false;
+        }
+        else
+            file.close();
+    }
+
+    emit info(i18n("Saving config to \'%1\'", fileName));
     if (file.open(QFile::WriteOnly | QFile::Text))
     {
         QTextStream stream(&file);
@@ -536,7 +541,7 @@ bool Loader::save(const QUrl &url)
             {
                 if (reply->error() == 4)
                 {
-                    qDebug() << "Saving of file aborted by user";
+                    emit info(i18n("Saving of file aborted by user"));
                     return false;
                 }
 
@@ -565,6 +570,7 @@ void Loader::updateConfig()
     {
         m_config = config;
         emit configChanged();
+        emit needsSaveChanged();
     }
 }
 
@@ -736,6 +742,7 @@ void Loader::abortTestingFans()
 
 void Loader::detectSensors()
 {
+    emit info(i18n("Start detecting Sensors"));
     auto program = QStringLiteral("sensors-detect");
     auto arguments = QStringList() << QStringLiteral("--auto");
 
@@ -784,6 +791,8 @@ void Loader::handleDetectSensorsResult(int exitCode)
 
     if (process)
         process->deleteLater();
+
+    emit info(i18n("Finished detecting Sensors"));
 }
 
 void Loader::handleDetectSensorsResult(KJob *job)
@@ -808,6 +817,8 @@ void Loader::handleDetectSensorsResult(KJob *job)
 
         parseHwmons();
     }
+
+    emit info(i18n("Finished detecting Sensors"));
 }
 
 QList<QObject *> Loader::hwmonsAsObjects() const
@@ -847,10 +858,9 @@ void Loader::setRestartServiceAfterTesting(bool restart)
     emit restartServiceAfterTestingChanged();
 }
 
-void Loader::reset() const
+void Loader::toDefault()
 {
     for (const auto &hwmon : m_hwmons)
-        hwmon->reset();
-}
-
+        hwmon->toDefault();
+    }
 }

+ 6 - 4
import/src/loader.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -51,7 +51,7 @@ class Loader : public QObject
     Q_PROPERTY(int interval READ interval WRITE setInterval NOTIFY intervalChanged)
     Q_PROPERTY(bool sensorsDetected READ sensorsDetected NOTIFY sensorsDetectedChanged)
     Q_PROPERTY(bool restartServiceAfterTesting READ restartServiceAfterTesting WRITE setRestartServiceAfterTesting NOTIFY restartServiceAfterTestingChanged)
-    Q_PROPERTY(bool configEqualToLoadedFile READ configEqualToLoadedFile NOTIFY configChanged)
+    Q_PROPERTY(bool needsSave READ needsSave NOTIFY needsSaveChanged)
 
 
 public:
@@ -80,8 +80,8 @@ public:
     PwmFan *pwmFan(int hwmonIndex, int pwmFanIndex) const;
     Temp *temp(int hwmonIndex, int tempIndex) const;
     Fan *fan(int hwmonIndex, int fanIndex) const;
-    void reset() const;
-    bool configEqualToLoadedFile() const { return m_config == m_configFileContent; }
+    void toDefault();
+    bool needsSave() const { return m_config != m_configFileContent; }
 
 
 public slots:
@@ -120,11 +120,13 @@ signals:
     void hwmonsChanged();
     void intervalChanged();
     void error(QString, bool = false);
+    void info(QString);
     void sensorsUpdateNeeded();
     void invalidConfigUrl();
     void sensorsDetectedChanged();
     void restartServiceAfterTestingChanged();
     void requestSetServiceActive(bool);
+    void needsSaveChanged();
 };
 
 }

+ 8 - 8
import/src/pwmfan.cpp

@@ -1,6 +1,6 @@
 /*
  * <one line to give the library's name and an idea of what it does.>
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -88,7 +88,7 @@ PwmFan::PwmFan(uint index, Hwmon *parent) : Fan(index, parent),
             }
             else
             {
-                emit error(i18n("Can't open pwm file: \"%1\"", pwmFile->fileName()));
+                emit error(i18n("Can't open pwm file: \'%1\'", pwmFile->fileName()));
                 delete pwmFile;
             }
 
@@ -106,7 +106,7 @@ PwmFan::PwmFan(uint index, Hwmon *parent) : Fan(index, parent),
             }
             else
             {
-                emit error(i18n("Can't open pwm_enable file: \"%1\"", pwmEnableFile->fileName()));
+                emit error(i18n("Can't open pwm_enable file: \'%1\'", pwmEnableFile->fileName()));
                 delete pwmEnableFile;
             }
         }
@@ -134,9 +134,9 @@ void PwmFan::update()
     setPwmEnable(m_enableStream->readAll().toInt(), false);
 }
 
-void PwmFan::reset()
+void PwmFan::toDefault()
 {
-    Fan::reset();
+    Fan::toDefault();
 
     setHasTemp(false);
     setTemp(Q_NULLPTR);
@@ -180,7 +180,7 @@ void PwmFan::reset()
         }
         else
         {
-            emit error(i18n("Can't open pwm file: \"%1\"", pwmFile->fileName()));
+            emit error(i18n("Can't open pwm file: \'%1\'", pwmFile->fileName()));
             delete pwmFile;
         }
 
@@ -198,7 +198,7 @@ void PwmFan::reset()
         }
         else
         {
-            emit error(i18n("Can't open pwm_enable file: \"%1\"", pwmEnableFile->fileName()));
+            emit error(i18n("Can't open pwm_enable file: \'%1\'", pwmEnableFile->fileName()));
             delete pwmEnableFile;
         }
     }
@@ -426,7 +426,7 @@ void PwmFan::continueTest()
                 emit testStatusChanged();
                 return;
             }
-            
+
             setPwm(qMax(0, (int)qMin(m_pwm * 0.95, m_pwm - 5.0)));
             m_zeroRpm = 0;
         }

+ 2 - 2
import/src/pwmfan.h

@@ -1,6 +1,6 @@
 /*
  * <one line to give the library's name and an idea of what it does.>
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -93,7 +93,7 @@ public:
     void setMinStop(int minStop) { if (minStop != m_minStop) { m_minStop = minStop; emit minStopChanged(); } }
     bool setPwmEnable(int pwmEnable, bool write = true);
     void setActive(bool active);
-    void reset() Q_DECL_OVERRIDE;
+    void toDefault() Q_DECL_OVERRIDE;
     bool isValid() const Q_DECL_OVERRIDE;
     Q_INVOKABLE void test();
     Q_INVOKABLE void abortTest();

+ 1 - 1
import/src/pwmfanmodel.cpp

@@ -1,6 +1,6 @@
 /*
  * <one line to give the library's name and an idea of what it does.>
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
import/src/pwmfanmodel.h

@@ -1,6 +1,6 @@
 /*
  * <one line to give the library's name and an idea of what it does.>
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
import/src/sensor.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by

+ 2 - 2
import/src/sensor.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -44,7 +44,7 @@ public:
 
     virtual QString name() const = 0;
     virtual void setName(const QString &name) = 0;
-    virtual void reset() = 0;
+    virtual void toDefault() = 0;
     virtual bool isValid() const = 0;
     QString path() const { return m_path; }
     Hwmon * parent() const { return m_parent; }

+ 131 - 93
import/src/systemdcommunicator.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -26,6 +26,7 @@
 #include <QtCore/QTimer>
 #include <QtDBus/QDBusArgument>
 #include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusReply>
 
 #include <KAuth/KAuthExecuteJob>
 #include <KI18n/KLocalizedString>
@@ -74,8 +75,14 @@ SystemdCommunicator::SystemdCommunicator(GUIBase *parent, const QString &service
                                           this)),
     m_serviceInterface(Q_NULLPTR)
 {
+    if (!m_managerInterface)
+        emit error(i18n("Unable to init systemd dbus manager interface!"), true);
+
     if (parent)
+    {
         connect(this, &SystemdCommunicator::error, parent, &GUIBase::handleError);
+        connect(this, &SystemdCommunicator::info, parent, &GUIBase::handleInfo);
+    }
 
     if (serviceName.isEmpty())
         setServiceName(QStringLiteral(STANDARD_SERVICE_NAME));
@@ -83,8 +90,18 @@ SystemdCommunicator::SystemdCommunicator(GUIBase *parent, const QString &service
         setServiceName(serviceName);
 
     emit serviceNameChanged();
-    emit serviceEnabledChanged();
+
+    m_serviceActive = systemdServiceActive();
     emit serviceActiveChanged();
+
+    m_serviceEnabled = systemdServiceEnabled();
+    emit serviceEnabledChanged();
+}
+
+SystemdCommunicator::~SystemdCommunicator()
+{
+    delete m_managerInterface;
+    delete m_serviceInterface;
 }
 
 void SystemdCommunicator::setServiceName(const QString &name)
@@ -124,6 +141,9 @@ void SystemdCommunicator::setServiceName(const QString &name)
                                                         QStringLiteral("org.freedesktop.systemd1.Unit"),
                                                         QDBusConnection::systemBus(),
                                                         this);
+                if (!m_serviceInterface)
+                    emit error(i18n("Unable to init systemd dbus service interface!"), true);
+
                 QDBusConnection::systemBus().connect(QStringLiteral("org.freedesktop.systemd1"),
                                                      m_serviceObjectPath,
                                                      QStringLiteral("org.freedesktop.DBus.Properties"),
@@ -136,10 +156,12 @@ void SystemdCommunicator::setServiceName(const QString &name)
         emit serviceNameChanged();
         emit serviceEnabledChanged();
         emit serviceActiveChanged();
+
+        emit info(i18n("New srevice name: \'%1\'", m_serviceName));
     }
 }
 
-bool SystemdCommunicator::serviceExists()
+bool SystemdCommunicator::serviceExists() const
 {
     if (m_serviceInterface)
     {
@@ -165,11 +187,11 @@ bool SystemdCommunicator::serviceExists()
             return true;
     }
 
-    emit error(i18n("Service does not exist: \"%1\"", m_serviceName));
+    emit error(i18n("Service does not exist: \'%1\'", m_serviceName));
     return false;
 }
 
-bool SystemdCommunicator::serviceActive()
+bool SystemdCommunicator::systemdServiceActive() const
 {
     if (serviceExists() && m_serviceInterface)
     {
@@ -179,67 +201,58 @@ bool SystemdCommunicator::serviceActive()
     return false;
 }
 
-bool SystemdCommunicator::serviceEnabled()
+bool SystemdCommunicator::systemdServiceEnabled() const
 {
-    if (serviceExists() && m_serviceInterface)
+    if (serviceExists())
     {
-        if (m_serviceInterface->property("UnitFileState").toString() == QStringLiteral("enabled"))
-            return true;
-
+        QDBusReply<QString> reply = m_managerInterface->call(QDBus::AutoDetect, QStringLiteral("GetUnitFileState"), m_serviceName + ".service");
+        if (reply.isValid())
+            return reply.value() == QStringLiteral("enabled");
+        else
+            emit error(reply.error().message());
     }
     return false;
 }
 
-bool SystemdCommunicator::setServiceEnabled(bool enabled)
+void SystemdCommunicator::setServiceEnabled(bool enabled)
 {
-    if (serviceExists())
-    {
-        if (enabled != serviceEnabled())
-        {
-            const auto action = enabled ? QStringLiteral("EnableUnitFiles") : QStringLiteral("DisableUnitFiles");
-            const auto files = QStringList() << m_serviceName + ".service";
-            auto arguments = QVariantList() << files << false;
-            if (enabled)
-                arguments << true;
+    if (m_serviceEnabled == enabled)
+        return;
 
-            if (dbusAction(action, arguments))
-            {
-                if (dbusAction(QStringLiteral("Reload")))
-                {
-                    emit serviceEnabledChanged();
-                    return true;
-                }
-            }
-            return false;
-        }
-        return true;
-    }
-    return false;
+    m_serviceEnabled = enabled;
+    emit serviceEnabledChanged();
+    emit needsApplyChanged();
 }
 
-bool SystemdCommunicator::setServiceActive(bool active)
+void SystemdCommunicator::setServiceActive(bool active)
 {
-//    qDebug() << "Set service active:" << active;
+    if (m_serviceActive == active)
+        return;
 
+    m_serviceActive = active;
+    emit serviceActiveChanged();
+    emit needsApplyChanged();
+}
+
+bool SystemdCommunicator::restartService()
+{
     if (serviceExists())
     {
-        if (active != serviceActive())
-        {
-            auto args = QVariantList() << m_serviceName + ".service" << "replace";
-            const auto action = active ? QStringLiteral("ReloadOrRestartUnit") : QStringLiteral("StopUnit");
+        emit info(i18n("Restarting service: \'%1\'", m_serviceName));
 
-            if (dbusAction(action, args))
-            {
-                emit serviceActiveChanged();
-                return true;
-            }
-        }
-
-        return true;
+        auto args = QVariantList() << m_serviceName + ".service" << "replace";
+        return dbusAction(QStringLiteral("ReloadOrRestartUnit"), args);
     }
+
+    emit error(i18n("Service does not exist: \'%1\'", m_serviceName));
     return false;
 }
 
+bool SystemdCommunicator::needsApply() const
+{
+    return m_serviceActive != systemdServiceActive() || m_serviceEnabled != systemdServiceEnabled();
+}
+
 bool SystemdCommunicator::dbusAction(const QString &method, const QVariantList &arguments)
 {
     if (!m_managerInterface->isValid())
@@ -249,76 +262,101 @@ bool SystemdCommunicator::dbusAction(const QString &method, const QVariantList &
 
     }
 
-    const auto dbusreply = arguments.isEmpty() ? m_managerInterface->call(QDBus::AutoDetect, method) : m_managerInterface->callWithArgumentList(QDBus::AutoDetect, method, arguments);
-
-    if (dbusreply.type() != QDBusMessage::ErrorMessage)
-        return true;
+    auto action = newFancontrolAction();
+    QVariantMap map;
+    map[QStringLiteral("action")] = "dbusaction";
+    map[QStringLiteral("method")] = method;
+    map[QStringLiteral("arguments")] = arguments;
+    action.setArguments(map);
 
-    if (dbusreply.errorMessage() == QStringLiteral("Interactive authentication required."))
+    const auto job = action.execute();
+    bool success = job->exec();
+    if (success)
     {
-        auto action = newFancontrolAction();
-        QVariantMap map;
-        map[QStringLiteral("action")] = "dbusaction";
-        map[QStringLiteral("method")] = method;
-        map[QStringLiteral("arguments")] = arguments;
-        action.setArguments(map);
-
-        const auto job = action.execute();
-        connect(job, &KAuth::ExecuteJob::result, this, &SystemdCommunicator::handleDbusActionResult);
-        job->start();
-
-        return true;
+        if (method == QStringLiteral("EnableUnitFiles") || method == QStringLiteral("DisableUnitFiles"))
+        {
+            emit serviceEnabledChanged();
+            emit needsApplyChanged();
+        }
+        else if (method == QStringLiteral("StartUnit") || method == QStringLiteral("StopUnit"))
+        {
+            emit serviceActiveChanged();
+            emit needsApplyChanged();
+        }
     }
-
-    emit error(dbusreply.errorMessage());
-    return false;
-
+    else
+    {
+        emit error(i18n("Dbus error: %1", job->errorString()));
+    }
+    return success;
 }
 
-void SystemdCommunicator::handleDbusActionResult(KJob *job)
+void SystemdCommunicator::apply(bool serviceRestart)
 {
-    if (job->error())
+    if (serviceExists())
     {
-        if (job->error() == KAuth::ActionReply::HelperBusyError)
+        if (m_serviceEnabled != systemdServiceEnabled())
         {
-//            qDebug() << "Helper busy...";
-
-            const auto executeJob = static_cast<KAuth::ExecuteJob *>(job);
-            if (executeJob)
+            QString method;
+            if (m_serviceEnabled)
             {
-                const auto newJob = executeJob->action().execute();
-                connect(newJob, &KAuth::ExecuteJob::result, this, &SystemdCommunicator::handleDbusActionResult);
+                emit info(i18n("Enabling service autostart at boot:\'%1\'", m_serviceName));
+                method = QStringLiteral("EnableUnitFiles");
+            }
+            else
+            {
+                emit info(i18n("Disabling service autostart at boot: \'%1\'", m_serviceName));
+                method = QStringLiteral("DisableUnitFiles");
+            }
+            const auto files = QStringList() << m_serviceName + ".service";
+            auto args = QVariantList() << files << false;
+            if (m_serviceEnabled)
+                args << true;
 
-                QTimer::singleShot(50, newJob, &KAuth::ExecuteJob::start);
+            if (!dbusAction(method, args))
                 return;
-            }
         }
 
-        emit error(job->errorText());
+        if (m_serviceActive != systemdServiceActive())
+        {
+            QString method;
+            if (m_serviceActive)
+            {
+                emit info(i18n("Starting service: \'%1\'", m_serviceName));
+                method = QStringLiteral("StartUnit");
+            }
+            else
+            {
+                emit info(i18n("Stopping service: \'%1\'", m_serviceName));
+                method = QStringLiteral("StopUnit");
+            }
+            auto args = QVariantList() << m_serviceName + ".service" << "replace";
+
+            if (!dbusAction(method, args))
+                return;
+        }
+        else if (systemdServiceActive() && m_serviceActive && serviceRestart)
+            restartService();
     }
 }
 
-bool SystemdCommunicator::restartService()
+void SystemdCommunicator::reset()
 {
-    if (serviceExists())
-    {
-        QVariantList args;
-        args << m_serviceName + ".service" << "replace";
-
-        return dbusAction(QStringLiteral("ReloadOrRestartUnit"), args);
-    }
-
-    emit error(i18n("Service does not exist: \"%1\"", m_serviceName));
-    return false;
+    setServiceActive(systemdServiceActive());
+    setServiceEnabled(systemdServiceEnabled());
 }
 
 void SystemdCommunicator::updateServiceProperties(QString, QVariantMap propchanged, QStringList)
 {
     if (propchanged.value(QStringLiteral("ActiveState")).isValid())
-        emit serviceActiveChanged();
+    {
+        emit needsApplyChanged();
+    }
 
     if (propchanged.value(QStringLiteral("UnitFileState")).isValid())
-        emit serviceEnabledChanged();
+    {
+        emit needsApplyChanged();
+    }
 }
 
 }

+ 18 - 8
import/src/systemdcommunicator.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -41,19 +41,24 @@ class SystemdCommunicator : public QObject
     Q_PROPERTY(bool serviceExists READ serviceExists NOTIFY serviceNameChanged)
     Q_PROPERTY(bool serviceEnabled READ serviceEnabled WRITE setServiceEnabled NOTIFY serviceEnabledChanged)
     Q_PROPERTY(bool serviceActive READ serviceActive WRITE setServiceActive NOTIFY serviceActiveChanged)
+    Q_PROPERTY(bool needsApply READ needsApply NOTIFY needsApplyChanged)
 
 public:
 
     explicit SystemdCommunicator(GUIBase *parent = Q_NULLPTR, const QString &serviceName = QString());
+    virtual ~SystemdCommunicator();
 
     QString serviceName() const { return m_serviceName; }
     void setServiceName(const QString &name);
-    bool serviceExists();
-    bool serviceEnabled();
-    bool serviceActive();
-    bool setServiceEnabled(bool enabled);
-    bool setServiceActive(bool active);
+    bool serviceExists() const;
+    bool serviceEnabled() const { return m_serviceEnabled; }
+    bool serviceActive() const { return m_serviceActive; }
+    void setServiceEnabled(bool enabled);
+    void setServiceActive(bool active);
+    bool needsApply() const;
     Q_INVOKABLE bool restartService();
+    Q_INVOKABLE void apply(bool serviceRestart = false);
+    Q_INVOKABLE void reset();
 
 
 signals:
@@ -61,18 +66,21 @@ signals:
     void serviceNameChanged();
     void serviceEnabledChanged();
     void serviceActiveChanged();
-    void error(QString, bool = false);
+    void needsApplyChanged();
+    void error(QString, bool = false) const;
+    void info(QString) const;
 
 
 protected slots:
 
     void updateServiceProperties(QString, QVariantMap, QStringList);
-    void handleDbusActionResult(KJob *job);
 
 
 protected:
 
     bool dbusAction(const QString &method, const QVariantList &arguments = QVariantList());
+    bool systemdServiceActive() const;
+    bool systemdServiceEnabled() const;
 
 
 private:
@@ -81,6 +89,8 @@ private:
     QString m_serviceObjectPath;
     QDBusInterface * const m_managerInterface;
     QDBusInterface *m_serviceInterface;
+    bool m_serviceEnabled;
+    bool m_serviceActive;
 };
 
 }

+ 7 - 7
import/src/temp.cpp

@@ -1,6 +1,6 @@
 /*
  * <one line to give the library's name and an idea of what it does.>
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -58,7 +58,7 @@ Temp::Temp(uint index, Hwmon *parent) :
         else
         {
             delete valueFile;
-            emit error(i18n("Can't open value file: \"%1\"", parent->path() + "/temp" + QString::number(index) + "_input"));
+            emit error(i18n("Can't open value file: \'%1\'", parent->path() + "/temp" + QString::number(index) + "_input"));
         }
 
         if (labelFile->exists())
@@ -66,10 +66,10 @@ Temp::Temp(uint index, Hwmon *parent) :
             if (labelFile->open(QFile::ReadOnly))
                 m_label = QTextStream(labelFile).readLine();
             else
-                emit error(i18n("Can't open label file: \"%1\"", parent->path() + "/temp" + QString::number(index) + "_label"));
+                emit error(i18n("Can't open label file: \'%1\'", parent->path() + "/temp" + QString::number(index) + "_label"));
         }
         else
-            emit error(i18n("Temp has no label: \"%1\"", parent->path() + "/temp" + QString::number(index)));
+            emit error(i18n("Temp has no label: \'%1\'", parent->path() + "/temp" + QString::number(index)));
 
         delete labelFile;
     }
@@ -111,7 +111,7 @@ void Temp::setName(const QString &name)
     }
 }
 
-void Temp::reset()
+void Temp::toDefault()
 {
     if (m_valueStream->device() && m_parent)
     {
@@ -130,7 +130,7 @@ void Temp::reset()
                 m_value /= 1000;
             }
             else
-                emit error(i18n("Can't open value file: \"%1\"", m_parent->path() + "/temp" + QString::number(m_index) + "_input"));
+                emit error(i18n("Can't open value file: \'%1\'", m_parent->path() + "/temp" + QString::number(m_index) + "_input"));
         }
     }
 }
@@ -143,7 +143,7 @@ void Temp::update()
     const auto value = m_valueStream->readAll().toInt(&success) / 1000;
 
     if (!success)
-        emit error(i18n("Can't update value of temp: \"%1\"", m_parent->path() + "/temp" + QString::number(m_index)));
+        emit error(i18n("Can't update value of temp: \'%1\'", m_parent->path() + "/temp" + QString::number(m_index)));
 
     if (value != m_value)
     {

+ 2 - 2
import/src/temp.h

@@ -1,6 +1,6 @@
 /*
  * <one line to give the library's name and an idea of what it does.>
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -48,7 +48,7 @@ public:
     int value() const { return m_value; }
     QString name() const Q_DECL_OVERRIDE;
     void setName(const QString &name) Q_DECL_OVERRIDE;
-    void reset() Q_DECL_OVERRIDE;
+    void toDefault() Q_DECL_OVERRIDE;
     bool isValid() const Q_DECL_OVERRIDE;
 
 

+ 1 - 1
import/src/tempmodel.cpp

@@ -1,6 +1,6 @@
 /*
  * <one line to give the library's name and an idea of what it does.>
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 2 - 2
import/src/tempmodel.h

@@ -1,6 +1,6 @@
 /*
  * <one line to give the library's name and an idea of what it does.>
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -56,7 +56,7 @@ public slots:
 
     void updateTemp(Temp *temp);
     void setUnit(const QString &unit) { if (unit != m_unit) { m_unit = unit; updateAll(); } }
-    
+
 
 protected slots:
 

+ 1 - 1
import/tests/fantest.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
import/tests/loadertest.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
import/tests/pwmfantest.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
import/tests/temptest.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
import/tests/testfan.cpp

@@ -1,6 +1,6 @@
 /*
  * <one line to give the program's name and a brief idea of what it does.>
- * Copyright 2016  Malte Veerman <maldela@halloarsch.de>
+ * Copyright 2016  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
import/tests/testfan.h

@@ -1,6 +1,6 @@
 /*
  * <one line to give the program's name and a brief idea of what it does.>
- * Copyright 2016  Malte Veerman <maldela@halloarsch.de>
+ * Copyright 2016  Malte Veerman <malte.veerman@gmail.com>
  * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
import/tests/testpwmfan.cpp

@@ -1,6 +1,6 @@
 /*
  * <one line to give the program's name and a brief idea of what it does.>
- * Copyright 2016  Malte Veerman <maldela@halloarsch.de>
+ * Copyright 2016  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
import/tests/testpwmfan.h

@@ -1,6 +1,6 @@
 /*
  * <one line to give the program's name and a brief idea of what it does.>
- * Copyright 2016  Malte Veerman <maldela@halloarsch.de>
+ * Copyright 2016  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
import/tests/testtemp.cpp

@@ -1,6 +1,6 @@
 /*
  * <one line to give the program's name and a brief idea of what it does.>
- * Copyright 2016  Malte Veerman <maldela@halloarsch.de>
+ * Copyright 2016  Malte Veerman <malte.veerman@gmail.com>
  * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 1 - 1
import/tests/testtemp.h

@@ -1,6 +1,6 @@
 /*
  * <one line to give the program's name and a brief idea of what it does.>
- * Copyright 2016  Malte Veerman <maldela@halloarsch.de>
+ * Copyright 2016  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

+ 3 - 3
kcm/CMakeLists.txt

@@ -10,8 +10,8 @@ add_library(kcm_fancontrol MODULE src/fancontrolkcm.cpp)
 target_link_libraries(kcm_fancontrol ${LIBRARIES})
 
 install(TARGETS kcm_fancontrol DESTINATION "${KDE_INSTALL_QTPLUGINDIR}/kcms")
-install(FILES kcm_fancontrol.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
+install(PROGRAMS fancontrol-kcm.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
 
-kpackage_install_package(package kcm_fancontrol kcms)
+kpackage_install_bundled_package(package org.kde.fancontrol.kcm kcms)
 
-kcoreaddons_desktop_to_json(kcm_fancontrol "kcm_fancontrol.desktop" SERVICE_TYPES kcmodule.desktop)
+kcoreaddons_desktop_to_json(kcm_fancontrol "fancontrol-kcm.desktop" SERVICE_TYPES kcmodule.desktop)

+ 0 - 0
kcm/kcm_fancontrol.desktop → kcm/fancontrol-kcm.desktop


+ 26 - 21
kcm/package/contents/ui/KCM.qml

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015  Malte Veerman <maldela@halloarsch.de>
+ * Copyright (C) 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -39,33 +39,19 @@ Item {
     implicitWidth: 1024
     implicitHeight: 768
 
-    Connections {
-        target: loader
-        onConfigFileChanged: kcm.needsSave = true
-    }
-
     Connections {
         target: Fancontrol.base
-        onMinTempChanged: kcm.needsSave = true
-        onMaxTempChanged: kcm.needsSave = true
-        onServiceNameChanged: kcm.needsSave = true
-        onConfigUrlChanged: kcm.needsSave = true
+        onNeedsApplyChanged: kcm.needsSave = Fancontrol.base.needsApply
     }
 
     Connections {
         target: kcm
         onAboutToSave: {
-            Fancontrol.base.save(true);
-            if (systemdCom.serviceActive && enabledBox.checked) {
-                systemdCom.restartService();
-            } else {
-                systemdCom.serviceActive = enabledBox.checked;
-            }
-            systemdCom.serviceEnabled = enabledBox.checked;
+            Fancontrol.base.apply();
         }
         onAboutToLoad: {
             Fancontrol.base.load();
-            enabledBox.checked = systemdCom.serviceEnabled && systemdCom.serviceActive;
+            enabledBox.checked = systemdCom.serviceActive;
         }
         onAboutToDefault: enabledBox.checked = false
     }
@@ -100,9 +86,15 @@ Item {
         visible: pwmFans.length > 0
         text: i18n("Control fans manually")
         checked: systemdCom.serviceEnabled && systemdCom.serviceActive;
-        onCheckedChanged: if (checked !== systemdCom.serviceActive || checked !== systemdCom.serviceEnabled) {
-            kcm.needsSave = true;
+        onCheckedChanged: {
+            systemdCom.serviceActive = enabledBox.checked;
             loader.restartServiceAfterTesting = checked;
+            autostartBox.checked = true;
+        }
+
+        Connections {
+            target: systemdCom
+            onServiceActiveChanged: if (systemdCom.serviceActive != enabledBox.checked) enabledBox.checked = systemdCom.serviceActive
         }
     }
 
@@ -115,6 +107,19 @@ Item {
         anchors.bottomMargin: advancedButton.height / 4
         visible: enabledBox.checked
 
+        CheckBox {
+            id: autostartBox
+
+            text: i18n("Enable service at boot")
+            checked: systemdCom.serviceEnabled
+            onCheckedChanged: systemdCom.serviceEnabled = checked
+
+            Connections {
+                target: systemdCom
+                onServiceEnabledChanged: if (systemdCom.serviceEnabled != autostartBox.checked) autostartBox.checked = systemdCom.serviceEnabled
+            }
+        }
+
         RowLayout {
             visible: enabledBox.checked && pwmFans.length > 0
 
@@ -312,7 +317,7 @@ Item {
             Fancontrol.OptionInput {
                 Layout.minimumWidth: implicitWidth
                 Layout.fillWidth: true
-                text: Fancontrol.base.configUrl.toString().replace("file://", "")
+                value: Fancontrol.base.configUrl.toString().replace("file://", "")
                 color: Fancontrol.base.configValid ? "green" : "red"
                 onTextChanged: Fancontrol.base.configUrl = text
             }

+ 3 - 3
kcm/package/metadata.desktop

@@ -6,11 +6,11 @@ Encoding=UTF-8
 Keywords=
 Type=Service
 X-KDE-PluginInfo-Author=Malte Veerman
-X-KDE-PluginInfo-Email=maldela@halloarsch.de
+X-KDE-PluginInfo-Email=malte.veerman@gmail.com
 X-KDE-PluginInfo-License=GPL
-X-KDE-PluginInfo-Name=kcm_fancontrol
+X-KDE-PluginInfo-Name=org.kde.fancontrol.kcm
 X-KDE-PluginInfo-Version=0.4
 X-KDE-PluginInfo-Website=
 X-KDE-ServiceTypes=Plasma/Generic
-X-Plasma-API=declarativeappletscript 
+X-Plasma-API=declarativeappletscript
 X-Plasma-MainScript=ui/KCM.qml

+ 7 - 7
kcm/src/fancontrolkcm.cpp

@@ -1,6 +1,6 @@
 /*
  * <one line to give the library's name and an idea of what it does.>
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -27,13 +27,13 @@
 #include <KI18n/KLocalizedString>
 
 
-K_PLUGIN_FACTORY_WITH_JSON(FancontrolKCMFactory, "kcm_fancontrol.json", registerPlugin<FancontrolKCM>();)
+K_PLUGIN_FACTORY_WITH_JSON(FancontrolKCMFactory, "fancontrol-kcm.json", registerPlugin<FancontrolKCM>();)
 
 
 FancontrolKCM::FancontrolKCM(QObject *parent, const QVariantList& args)
     : ConfigModule(parent, args)
 {
-    auto about = new KAboutData(QStringLiteral("kcm_fancontrol"),
+    auto about = new KAboutData(QStringLiteral("org.kde.fancontrol.kcm"),
                                 i18n("Fancontrol-KCM"),
                                 QStringLiteral("0.3"),
                                 i18n("KDE Fancontrol Module"),
@@ -42,7 +42,7 @@ FancontrolKCM::FancontrolKCM(QObject *parent, const QVariantList& args)
                                 QString(),
                                 QStringLiteral("http://github.com/maldela/fancontrol-gui"),
                                 QStringLiteral("http://github.com/maldela/fancontrol-gui/issues"));
-    about->addAuthor(i18n("Malte Veerman"), i18n("Main Developer"), QStringLiteral("maldela@halloarsch.de"));
+    about->addAuthor(i18n("Malte Veerman"), i18n("Main Developer"), QStringLiteral("malte.veerman@gmail.com"));
     setAboutData(about);
 
     setButtons(Apply | Default);
@@ -52,21 +52,21 @@ FancontrolKCM::FancontrolKCM(QObject *parent, const QVariantList& args)
 void FancontrolKCM::save()
 {
     emit aboutToSave();
-    
+
     setNeedsSave(false);
 }
 
 void FancontrolKCM::load()
 {
     emit aboutToLoad();
-    
+
     setNeedsSave(false);
 }
 
 void FancontrolKCM::defaults()
 {
     emit aboutToDefault();
-    
+
     setNeedsSave(true);
 }
 

+ 13 - 13
kcm/src/fancontrolkcm.h

@@ -1,7 +1,7 @@
 /*
  * <one line to give the library's name and an idea of what it does.>
- * Copyright 2015  Malte Veerman maldela@halloarsch.de
- * 
+ * Copyright 2015  Malte Veerman <malte.veerman@gmail.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 2 of
@@ -9,15 +9,15 @@
  * accepted by the membership of KDE e.V. (or its successor approved
  * by the membership of KDE e.V.), which shall act as a proxy
  * defined in Section 14 of version 3 of the license.
- * 
+ *
  * 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 FANCONTROLKCM_H
@@ -31,21 +31,21 @@ using namespace KQuickAddons;
 class FancontrolKCM : public ConfigModule
 {
     Q_OBJECT
-    
+
 public:
-    
+
     explicit FancontrolKCM(QObject *parent, const QVariantList &args = QVariantList());
-    
-    
+
+
 public slots:
-    
+
     void load() Q_DECL_OVERRIDE;
     void save() Q_DECL_OVERRIDE;
     void defaults() Q_DECL_OVERRIDE;
-    
-    
+
+
 signals:
-    
+
     void aboutToSave();
     void aboutToLoad();
     void aboutToDefault();

+ 3 - 3
po/de/kcm_fancontrol.po

@@ -1,14 +1,14 @@
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
 #
-# Malte Veerman <maldela@halloarsch.de>, 2015, 2016.
+# Malte Veerman <malte.veerman@gmail.com>, 2015, 2016.
 msgid ""
 msgstr ""
 "Project-Id-Version: fancontrol-gui\n"
 "Report-Msgid-Bugs-To: http://github.com/maldela/fancontrol-gui\n"
 "POT-Creation-Date: 2016-06-10 15:20+0200\n"
 "PO-Revision-Date: 2016-06-10 15:23+0100\n"
-"Last-Translator: Malte Veerman <maldela@halloarsch.de>\n"
+"Last-Translator: Malte Veerman <malte.veerman@gmail.com>\n"
 "Language-Team: German <kde-i18n-de@kde.org>\n"
 "Language: de_DE\n"
 "MIME-Version: 1.0\n"
@@ -360,7 +360,7 @@ msgstr "Malte Veerman"
 #: po/rc.cpp:2 rc.cpp:2
 msgctxt "EMAIL OF TRANSLATORS"
 msgid "Your emails"
-msgstr "maldela@halloarsch.de"
+msgstr "malte.veerman@gmail.com"
 
 #, fuzzy
 #~ msgid "Can't open rpm file: %1"

+ 0 - 0
icon.svg → sc-apps-fancontrol_gui.svg