Parcourir la source

Merge remote-tracking branch 'refs/remotes/origin/0.4'

Malte Veerman il y a 9 ans
Parent
commit
d3fa5d7df0
52 fichiers modifiés avec 1107 ajouts et 862 suppressions
  1. 8 15
      CMakeLists.txt
  2. 7 4
      fancontrol-gui/CMakeLists.txt
  3. 24 29
      fancontrol-gui/package/contents/ui/Application.qml
  4. 3 2
      fancontrol-gui/package/contents/ui/ConfigfileTab.qml
  5. 23 17
      fancontrol-gui/package/contents/ui/PwmFansTab.qml
  6. 7 7
      fancontrol-gui/package/contents/ui/SensorsTab.qml
  7. 21 33
      fancontrol-gui/package/contents/ui/SettingsTab.qml
  8. 16 0
      fancontrol-gui/package/metadata.desktop
  9. 6 40
      fancontrol-gui/src/main.cpp
  10. 6 5
      helper/CMakeLists.txt
  11. 19 12
      import/CMakeLists.txt
  12. 9 0
      import/qml/ErrorDialog.qml
  13. 22 19
      import/qml/FanItem.qml
  14. 0 0
      import/qml/OptionInput.qml
  15. 4 6
      import/qml/PwmPoint.qml
  16. 5 7
      import/qml/StatusPoint.qml
  17. 0 0
      import/qml/colors.js
  18. 8 0
      import/qml/math.js
  19. 9 0
      import/qml/qmldir
  20. 7 7
      import/qml/units.js
  21. 0 0
      import/src/config.cpp
  22. 0 0
      import/src/config.h
  23. 4 0
      import/src/fan.cpp
  24. 0 0
      import/src/fan.h
  25. 0 0
      import/src/fancontrolaction.h
  26. 68 0
      import/src/fancontrolqmlextension.cpp
  27. 52 0
      import/src/fancontrolqmlextension.h
  28. 17 13
      import/src/guibase.cpp
  29. 12 20
      import/src/guibase.h
  30. 28 8
      import/src/hwmon.cpp
  31. 7 6
      import/src/hwmon.h
  32. 148 68
      import/src/loader.cpp
  33. 14 9
      import/src/loader.h
  34. 105 106
      import/src/pwmfan.cpp
  35. 18 17
      import/src/pwmfan.h
  36. 0 0
      import/src/pwmfanmodel.cpp
  37. 0 0
      import/src/pwmfanmodel.h
  38. 2 2
      import/src/sensor.cpp
  39. 1 1
      import/src/sensor.h
  40. 5 4
      import/src/systemdcommunicator.cpp
  41. 1 3
      import/src/systemdcommunicator.h
  42. 3 0
      import/src/temp.cpp
  43. 0 0
      import/src/temp.h
  44. 2 4
      import/src/tempmodel.cpp
  45. 3 3
      import/src/tempmodel.h
  46. 8 6
      kcm/CMakeLists.txt
  47. 71 46
      kcm/package/contents/ui/KCM.qml
  48. 2 2
      kcm/package/metadata.desktop
  49. 8 37
      kcm/src/fancontrolkcm.cpp
  50. 3 16
      kcm/src/fancontrolkcm.h
  51. 179 158
      po/de/kcm_fancontrol.po
  52. 142 130
      po/kcm_fancontrol.pot

+ 8 - 15
CMakeLists.txt

@@ -7,8 +7,8 @@ project(fancontroller)
 option(NO_SYSTEMD "Compile without Systemd support. Reduces functionality significantly!" OFF)
 option(BUILD_GUI "Build the standalone application" ON)
 option(BUILD_KCM "Build the KCM" OFF)
+option(BUILD_HELPER "Build the KHelper" ON)
 option(INSTALL_SHARED "Install the shared parts" ON)
-option(INSTALL_HELPER "Install the KHelper" ON)
 
 #variables
 set(STANDARD_SERVICE_NAME "fancontrol" CACHE STRING "The name of the systemd service for the fancontrol script")
@@ -43,11 +43,10 @@ find_package(Qt5Core REQUIRED)
 
 
 #Find KF5
-find_package(KF5 COMPONENTS I18n Package REQUIRED)
+find_package(KF5 COMPONENTS I18n REQUIRED)
 
 
 #includes
-include(GenerateExportHeader)
 include(KDEInstallDirs)
 include(KDECMakeSettings)
 include(KDECompilerSettings)
@@ -60,8 +59,6 @@ include_directories (${CMAKE_SOURCE_DIR})
 if(NOT NO_SYSTEMD)
 
     message(STATUS "Compiling for Systemd")
-    find_package(Qt5DBus REQUIRED)
-    include_directories(${Qt5DBus_INCLUDE_DIRS})
 
 else(NOT NO_SYSTEMD)
 
@@ -72,16 +69,12 @@ else(NOT NO_SYSTEMD)
 endif(NOT NO_SYSTEMD)
 
 
-#Shared library
-add_subdirectory(lib)
-
-
 #KHelper for actions that require superuser rights
-if(INSTALL_HELPER)
+if(BUILD_HELPER)
 
     add_subdirectory(helper)
 
-endif(INSTALL_HELPER)
+endif(BUILD_HELPER)
 
 
 #Build the standalone application
@@ -102,15 +95,15 @@ if(BUILD_KCM)
 endif(BUILD_KCM)
 
 
-#install the shared parts
+#build and install the shared parts
 if(INSTALL_SHARED)
 
-    #KPackage containing the QML and javascript files
-    kpackage_install_package(package kcm_fancontrol kcms)
+    #qml plugin
+    add_subdirectory(import)
 
 
     #icon
-    install(FILES icon.svg RENAME "fancontrol_gui.svg" DESTINATION "${ICON_INSTALL_DIR}/hicolor/scalable/apps")
+    install(FILES icon.svg RENAME "fancontrol_gui.svg" DESTINATION "${KDE_INSTALL_ICONDIR}/hicolor/scalable/apps")
 
 
     #translations

+ 7 - 4
fancontrol-gui/CMakeLists.txt

@@ -1,15 +1,16 @@
 set(Fancontrol_GUI_SRCS src/main.cpp
                         src/windowconfig.cpp)
 
-set(LIBRARIES fancontrol_gui_lib
+set(LIBRARIES Qt5::Gui
               Qt5::Widgets
+              KF5::CoreAddons
               KF5::Declarative
               KF5::I18n
               KF5::ConfigGui
               KF5::ConfigCore)
 
-find_package(Qt5 COMPONENTS Widgets REQUIRED)
-find_package(KF5 COMPONENTS Declarative Config REQUIRED)
+find_package(Qt5 COMPONENTS Gui Widgets REQUIRED)
+find_package(KF5 COMPONENTS CoreAddons Package Declarative Config REQUIRED)
 
 include_directories(${Qt5Widgets_INCLUDE_DIRS})
 add_definitions(${Qt5Widgets_DEFINITIONS})
@@ -18,4 +19,6 @@ 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 ${XDG_APPS_INSTALL_DIR})
+install(FILES metadata.desktop RENAME "fancontrol_gui.desktop" DESTINATION ${KDE_INSTALL_APPDIR})
+
+kpackage_install_package(package fancontrol-gui genericqml)

+ 24 - 29
package/contents/ui/Application.qml → fancontrol-gui/package/contents/ui/Application.qml

@@ -22,6 +22,7 @@ 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 {
@@ -32,11 +33,14 @@ ApplicationWindow {
     visible: true
 
     onClosing: {
-        base.save();
+        Fancontrol.base.save();
         windowConfig.save(window);
     }
     
-    Component.onCompleted: windowConfig.restore(window)
+    Component.onCompleted: {
+        Fancontrol.base.load();
+        windowConfig.restore(window);
+    }
 
     menuBar: MenuBar {
         Menu {
@@ -63,22 +67,22 @@ ApplicationWindow {
             ToolButton { action: loadAction }
             ToolButton { action: saveAction }
             Loader {
-                active: base.hasSystemdCommunicator()
+                active: Fancontrol.base.hasSystemdCommunicator()
                 sourceComponent: ToolButton {
-                    iconName: base.systemdCom.serviceActive ? "system-reboot" : "system-run"
+                    iconName: Fancontrol.base.systemdCom.serviceActive ? "system-reboot" : "system-run"
                     onClicked: {
-                        base.loader.abortTestingFans();
-                        base.systemdCom.serviceActive ? base.systemdCom.restartService() : base.systemdCom.serviceActive = true;
+                        Fancontrol.base.loader.abortTestingFans();
+                        Fancontrol.base.systemdCom.serviceActive ? base.systemdCom.restartService() : base.systemdCom.serviceActive = true;
                     }
-                    tooltip: base.systemdCom.serviceActive ? i18n("Restart fancontrol") : i18n("Start fancontrol")
+                    tooltip: Fancontrol.base.systemdCom.serviceActive ? i18n("Restart fancontrol") : i18n("Start fancontrol")
                 }
             }
             Loader {
-                active: base.hasSystemdCommunicator()
+                active: Fancontrol.base.hasSystemdCommunicator()
                 sourceComponent: ToolButton {
                     iconName: "system-shutdown"
-                    enabled: base.systemdCom.serviceActive
-                    onClicked: base.systemdCom.serviceActive = false;
+                    enabled: Fancontrol.base.systemdCom.serviceActive
+                    onClicked: Fancontrol.base.systemdCom.serviceActive = false;
                     tooltip: i18n("Stop fancontrol")
                 }
             }
@@ -96,37 +100,28 @@ ApplicationWindow {
 
         Tab {
             title: i18n("Sensors")
-            SensorsTab {
-                loader: base.loader
-            }
+            SensorsTab {}
         }
         Tab {
             title: i18n("PwmFans")
-            PwmFansTab {
-                baseObject: base
-            }
+            PwmFansTab {}
         }
         Tab {
             title: i18n("Configfile")
-            ConfigfileTab {
-                loader: base.loader
-            }
+            ConfigfileTab {}
         }
         Tab {
             id: settingsTab
             title: i18n("Settings")
-            SettingsTab {
-                gui: base
-            }
+            SettingsTab {}
         }
     }
 
-    ErrorDialog {
+    Fancontrol.ErrorDialog {
         id: errorDialog
-        visible: !!base.loader.error
+        visible: false
         modality: Qt.ApplicationModal
-        text: base.loader.error
-        onTextChanged: show()
+        loader: Fancontrol.base.loader
     }
 
     Action {
@@ -142,7 +137,7 @@ ApplicationWindow {
         text: i18n("Save configuration file")
         onTriggered: base.save(true)
         iconName: "document-save"
-        tooltip: i18n("Save configuration file") + " (" + base.loader.configUrl.toString() + ")"
+        tooltip: i18n("Save configuration file") + " (" + Fancontrol.base.loader.configUrl.toString() + ")"
         shortcut: StandardKey.Save
     }
 
@@ -154,7 +149,7 @@ ApplicationWindow {
         selectMultiple: false
         modality: Qt.NonModal
 
-        onAccepted: base.configUrl = fileUrl;
+        onAccepted: Fancontrol.base.configUrl = fileUrl;
     }
     FileDialog {
         id: saveFileDialog
@@ -164,6 +159,6 @@ ApplicationWindow {
         selectMultiple: false
         modality: Qt.NonModal
 
-        onAccepted: base.save(true, fileUrl);
+        onAccepted: Fancontrol.base.save(true, fileUrl);
     }
 }

+ 3 - 2
package/contents/ui/ConfigfileTab.qml → fancontrol-gui/package/contents/ui/ConfigfileTab.qml

@@ -21,13 +21,14 @@
 import QtQuick 2.4
 import QtQuick.Controls 1.2
 import QtQuick.Layouts 1.1
+import Fancontrol.Qml 1.0 as Fancontrol
 
 
 ColumnLayout {
-    property QtObject loader
+    property QtObject loader: Fancontrol.base.loader
 
     anchors.fill: parent
-    anchors.topMargin: 5
+    anchors.margins: 10
 
     Label {
         anchors.top: parent.top

+ 23 - 17
package/contents/ui/PwmFansTab.qml → fancontrol-gui/package/contents/ui/PwmFansTab.qml

@@ -21,23 +21,27 @@
 import QtQuick 2.4
 import QtQuick.Controls 1.4
 import QtQuick.Layouts 1.2
+import Fancontrol.Qml 1.0 as Fancontrol
 
 
-ColumnLayout {
-    property QtObject baseObject
-    property QtObject loader: baseObject ? baseObject.loader : null
-    property QtObject systemdCom: baseObject && baseObject.hasSystemdCommunicator() ? baseObject.systemdCom : null
-    property QtObject pwmFanModel: baseObject ? baseObject.pwmFanModel : null
-    property QtObject tempModel: baseObject ? baseObject.tempModel : null
-    property var pwmFans: pwmFanModel ? pwmFanModel.fans : []
+Item {
+    property QtObject loader: Fancontrol.base.loader
+    property QtObject systemdCom: Fancontrol.base.hasSystemdCommunicator() ? Fancontrol.base.systemdCom : null
+    property QtObject pwmFanModel: Fancontrol.base.pwmFanModel
+    property QtObject tempModel: Fancontrol.base.tempModel
+    property var pwmFans: pwmFanModel.fans
 
     id: root
     anchors.fill: parent
-    anchors.topMargin: 5
+    anchors.margins: 10
 
     RowLayout {
+        id: fanRow
+
+        anchors.top: parent.top
         width: parent.width
-        visible: !!pwmFanModel && pwmFans.length > 0
+        height: childrenRect.height
+        visible: pwmFans.length > 0
 
         Label {
             text: i18n("Fan:")
@@ -58,17 +62,19 @@ ColumnLayout {
     }
 
     Loader {
-        Layout.fillHeight: true
-        Layout.fillWidth: true
-        active: !!tempModel && !!systemdCom && pwmFans.length < fanComboBox.currentIndex
+        width: parent.width
+        anchors.top: fanRow.bottom
+        anchors.bottom: parent.bottom
+        anchors.topMargin: parent.anchors.margins
+        active: pwmFans.length > fanComboBox.currentIndex && fanComboBox.currentIndex >= 0
 
-        sourceComponent: PwmFan {
-            unit: !!baseObject ? baseObject.unit : 0
+        sourceComponent: Fancontrol.FanItem {
+            unit: Fancontrol.base.unit
             fan: pwmFans[fanComboBox.currentIndex]
             tempModel: root.tempModel
             systemdCom: root.systemdCom
-            minTemp: !!baseObject ? baseObject.minTemp : 30
-            maxTemp: !!baseObject ? baseObject.maxTemp : 100
+            minTemp: Fancontrol.base.minTemp
+            maxTemp: Fancontrol.base.maxTemp
         }
     }
 
@@ -93,7 +99,7 @@ ColumnLayout {
 
     Action {
         id: detectFansAction
-        text: i18n("Detect fans")
+        text: loader.sensorsDetected ? i18n("Detect fans again") : i18n("Detect fans")
         iconName: "dialog-password"
         onTriggered: loader.detectSensors()
     }

+ 7 - 7
package/contents/ui/SensorsTab.qml → fancontrol-gui/package/contents/ui/SensorsTab.qml

@@ -21,18 +21,18 @@
 import QtQuick 2.4
 import QtQuick.Controls 1.2
 import QtQuick.Layouts 1.1
+import Fancontrol.Qml 1.0 as Fancontrol
 
 
 RowLayout {
-    property QtObject loader
+    property QtObject loader: Fancontrol.base.loader
 
     id: root
     anchors.fill: parent
-    anchors.margins: 2
-    anchors.topMargin: 10
+    anchors.margins: 10
 
     Repeater {
-        model: !!loader ? loader.hwmons.length : 0
+        model: loader.hwmons.length
 
         Rectangle {
             property QtObject hwmon: loader.hwmons[index]
@@ -68,13 +68,13 @@ RowLayout {
                             anchors.leftMargin: padding
                             Layout.maximumWidth: parent.width - rpmValue.width - padding*2
                             clip: true
-                            text: "Fan " + (index+1) + " RPM : "
+                            text: "Fan " + (index+1) + ":"
                         }
                         Label {
                             id: rpmValue
                             anchors.right: parent.right
                             anchors.rightMargin: padding
-                            text: hwmon.fans[index].rpm
+                            text: hwmon.fans[index].rpm + " " + i18n("rpm")
                         }
                     }
                 }
@@ -95,7 +95,7 @@ RowLayout {
                             id: tempValue
                             anchors.right: parent.right
                             anchors.rightMargin: padding
-                            text: hwmon.temps[index].value
+                            text: Units.fromCelsius(hwmon.temps[index].value, Fancontrol.base.unit) + " " + i18n(Fancontrol.base.unit)
                         }
                     }
                 }

+ 21 - 33
package/contents/ui/SettingsTab.qml → fancontrol-gui/package/contents/ui/SettingsTab.qml

@@ -21,21 +21,19 @@
 import QtQuick 2.4
 import QtQuick.Layouts 1.1
 import QtQuick.Controls 1.2
-import "../scripts/units.js" as Units
+import Fancontrol.Qml 1.0 as Fancontrol
 
 
 Item {
-    property QtObject gui
-    property QtObject systemdCom: !!gui && gui.hasSystemdCommunicator() ? gui.systemdCom : null
-    property QtObject loader : !!gui ? gui.loader : null
+    property QtObject systemdCom: Fancontrol.base.hasSystemdCommunicator() ? Fancontrol.base.systemdCom : null
+    property QtObject loader : Fancontrol.base.loader
     property int padding: 10
-    property int unit: !!gui ? gui.unit : 0
     property real textWidth: 0
     property var locale: Qt.locale()
 
     id: root
     anchors.fill: parent
-    anchors.topMargin: 5
+    anchors.margins: 10
 
     Column {
         id: column
@@ -56,14 +54,10 @@ Item {
             SpinBox {
                 Layout.minimumWidth: implicitWidth
                 Layout.fillWidth: true
-                value: !!loader ? loader.interval : 1
-                suffix: !!loader ? " " + i18np("second", "seconds", loader.interval): ""
+                value: loader.interval
+                suffix: " " + i18np("second", "seconds", loader.interval)
                 minimumValue: 1.0
-                onValueChanged: {
-                    if (!!loader) {
-                        loader.interval = value;
-                    }
-                }
+                onValueChanged: loader.interval = value
             }
         }
         RowLayout {
@@ -81,14 +75,13 @@ Item {
                 Layout.minimumWidth: implicitWidth
                 Layout.fillWidth: true
                 decimals: 2
-                maximumValue: maxTempBox.value
-                minimumValue: Units.fromKelvin(0, unit)
-                value: !!gui ? Units.fromCelsius(gui.minTemp, unit) : 0
-                suffix: unit == 0 ? i18n("°C") : unit == 1 ? i18n("K") : i18n("°F")
+                maximumValue: Number.POSITIVE_INFINITY
+                minimumValue: Fancontrol.Units.fromKelvin(0, Fancontrol.base.unit)
+                value: Fancontrol.Units.fromCelsius(Fancontrol.base.minTemp, Fancontrol.base.unit)
+                suffix: Fancontrol.base.unit
                 onValueChanged: {
-                    if (!!gui) {
-                        gui.minTemp = value;
-                    }
+                    Fancontrol.base.minTemp = value;
+                    if (value > maxTempBox.value) maxTempBox.value = value;
                 }
             }
         }
@@ -108,13 +101,12 @@ Item {
                 Layout.fillWidth: true
                 decimals: 2
                 maximumValue: Number.POSITIVE_INFINITY
-                minimumValue: minTempBox.value
-                value: !!gui ? Units.fromCelsius(gui.maxTemp, unit) : 0
-                suffix: unit == 0 ? i18n("°C") : unit == 1 ? i18n("K") : i18n("°F")
+                minimumValue: Fancontrol.Units.fromKelvin(0, Fancontrol.base.unit)
+                value: Fancontrol.Units.fromCelsius(Fancontrol.base.maxTemp, Fancontrol.base.unit)
+                suffix: Fancontrol.base.unit
                 onValueChanged: {
-                    if (!!gui) {
-                        gui.maxTemp = value;
-                    }
+                    Fancontrol.base.maxTemp = value;
+                    if (value < minTempBox.value) minTempBox.value = value;
                 }
             }
         }
@@ -130,16 +122,12 @@ Item {
                     horizontalAlignment: Text.AlignRight
                     Component.onCompleted: root.textWidth = Math.max(root.textWidth, contentWidth)
                 }
-                OptionInput {
+                Fancontrol.OptionInput {
                     Layout.minimumWidth: implicitWidth
                     Layout.fillWidth: true
                     color: !!systemdCom && systemdCom.serviceExists ? "green" : "red"
-                    value: !!gui ? gui.serviceName : ""
-                    onTextChanged: {
-                        if (!!gui) {
-                            gui.serviceName = text;
-                        }
-                    }
+                    value: Fancontrol.base.serviceName
+                    onTextChanged: Fancontrol.base.serviceName = text
                 }
             }
         }

+ 16 - 0
fancontrol-gui/package/metadata.desktop

@@ -0,0 +1,16 @@
+[Desktop Entry]
+Name=Fancontrol-GUI-QML-Package
+Comment=Control PWM-fans
+Icon=fancontrol_gui
+Encoding=UTF-8
+Keywords=
+Type=Service
+X-KDE-PluginInfo-Author=Malte Veerman
+X-KDE-PluginInfo-Email=maldela@halloarsch.de
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-Name=fancontrol-gui
+X-KDE-PluginInfo-Version=0.4
+X-KDE-PluginInfo-Website=
+X-KDE-ServiceTypes=Plasma/Generic
+X-Plasma-API=declarativeappletscript 
+X-Plasma-MainScript=ui/Application.qml

+ 6 - 40
fancontrol-gui/src/main.cpp

@@ -18,19 +18,15 @@
  */
 
 #include <QtWidgets/QApplication>
-#include <QtQml/QQmlApplicationEngine>
 #include <QtQml/QQmlContext>
 #include <QtCore/QCommandLineParser>
 #include <QtCore/QLoggingCategory>
-#include <QtCore/QFileInfo>
 #include <QtGui/QIcon>
 
-#include <KDeclarative/KDeclarative>
+#include <KDeclarative/QmlObject>
 #include <KI18n/KLocalizedString>
-#include <KPackage/PackageLoader>
 #include <KCoreAddons/KAboutData>
 
-#include "lib/src/guibase.h"
 #include "windowconfig.h"
 
 
@@ -46,7 +42,7 @@ int main(int argc, char *argv[])
 
     KAboutData about(QStringLiteral("fancontrol_gui"),
                      i18n("Fancontrol-GUI"),
-                     QStringLiteral("0.3"),
+                     QStringLiteral("0.4"),
                      i18n("Graphical user interface for fancontrol"),
                      KAboutLicense::KAboutLicense::GPL_V2,
                      QStringLiteral("Copyright (C) 2015 Malte Veerman"),
@@ -60,40 +56,10 @@ int main(int argc, char *argv[])
     parser.process(app);
     about.processCommandLine(&parser);
 
-    QQmlApplicationEngine engine;
-    QQmlContext *context = engine.rootContext();
+    KDeclarative::QmlObject qmlObject;
+    qmlObject.rootContext()->setContextProperty(QStringLiteral("windowConfig"), WindowConfig::instance());
 
-    KDeclarative::KDeclarative decl;
-    decl.setDeclarativeEngine(&engine);
-    decl.setupBindings();
-
-    Fancontrol::GUIBase base;
-    base.load();
-    context->setContextProperty(QStringLiteral("base"), &base);
-
-    WindowConfig *windowConfig = WindowConfig::instance();
-    context->setContextProperty(QStringLiteral("windowConfig"), windowConfig);
-
-    KPackage::Package package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("KPackage/GenericQML"));
-
-    QStringList possiblePackageLocations = QStringList() << QStringLiteral("/usr/share/kpackage/kcms")
-                                                         << QStringLiteral("/usr/local/share/kpackage/kcms")
-                                                         << QStringLiteral("kpackage/kcms")
-                                                         << QStringLiteral("/opt/share/kpackage/kcms");
-
-    foreach (const QString location, possiblePackageLocations)
-    {
-        package.setDefaultPackageRoot(location);
-        package.setPath(QStringLiteral("kcm_fancontrol"));
-        package.addFileDefinition("appqmlroot", QStringLiteral("ui/Application.qml"), i18n("The Application's root QML file"));
-        package.setRequired("appqmlroot", true);
-
-        if (package.isValid())
-        {
-            engine.load(QUrl::fromLocalFile(package.filePath("appqmlroot")));
-            return app.exec();
-        }
-    }   
+    qmlObject.loadPackage("fancontrol-gui");
     
-    return 1;
+    return app.exec();
 }

+ 6 - 5
helper/CMakeLists.txt

@@ -1,10 +1,14 @@
-set(LIBRARIES KF5::Auth
+set(LIBRARIES Qt5::Core
+              KF5::Auth
               KF5::I18n)
 
 if(NOT NO_SYSTEMD)
 
     set(LIBRARIES ${LIBRARIES}
                   Qt5::DBus)
+                  
+    find_package(Qt5DBus REQUIRED)
+    include_directories(${Qt5DBus_INCLUDE_DIRS})
 
 endif(NOT NO_SYSTEMD)
 
@@ -12,10 +16,7 @@ find_package(KF5Auth REQUIRED)
 
 add_executable(fancontrol-gui-helper src/helper.cpp)
 target_link_libraries(fancontrol-gui-helper ${LIBRARIES})
-install(TARGETS fancontrol-gui-helper DESTINATION ${KAUTH_HELPER_INSTALL_ABSOLUTE_DIR})
-
-set(SYSCONF_INSTALL_DIR "/etc")
-set(DBUS_SYSTEM_SERVICES_INSTALL_DIR "/usr/share/dbus-1/system-services")
+install(TARGETS fancontrol-gui-helper DESTINATION ${KAUTH_HELPER_INSTALL_DIR})
 
 kauth_install_helper_files(fancontrol-gui-helper fancontrol.gui.helper root)
 kauth_install_actions(fancontrol.gui.helper fancontrol_gui.actions)

+ 19 - 12
lib/CMakeLists.txt → import/CMakeLists.txt

@@ -7,7 +7,18 @@ set(LIB_SRCS src/hwmon.cpp
              src/guibase.cpp
              src/config.cpp
              src/pwmfanmodel.cpp
-             src/tempmodel.cpp)
+             src/tempmodel.cpp
+             src/fancontrolqmlextension.cpp)
+
+set(QML_FILES qml/qmldir
+              qml/ErrorDialog.qml
+              qml/OptionInput.qml
+              qml/FanItem.qml
+              qml/PwmPoint.qml
+              qml/StatusPoint.qml
+              qml/colors.js
+              qml/math.js
+              qml/units.js)
 
 set(LIB_PRIVATE_LIBRARIES Qt5::Qml
                           KF5::Auth
@@ -24,6 +35,9 @@ if(NOT NO_SYSTEMD)
     set(LIB_PRIVATE_LIBRARIES ${LIB_PRIVATE_LIBRARIES}
                               Qt5::DBus)
 
+    find_package(Qt5DBus REQUIRED)
+    include_directories(${Qt5DBus_INCLUDE_DIRS})
+
 endif(NOT NO_SYSTEMD)
 
 find_package(Qt5Qml REQUIRED)
@@ -31,15 +45,8 @@ find_package(KF5 COMPONENTS Auth Config REQUIRED)
 
 include_directories(${Qt5Qml_INCLUDE_DIRS})
 
-add_library(fancontrol_gui_lib SHARED ${LIB_SRCS})
-target_link_libraries(fancontrol_gui_lib PRIVATE ${LIB_PRIVATE_LIBRARIES} PUBLIC ${LIB_PUBLIC_LIBRARIES})
-
-target_compile_features(fancontrol_gui_lib PRIVATE cxx_lambdas)
-
-generate_export_header(fancontrol_gui_lib)
-
-if(INSTALL_SHARED)
-
-    install(TARGETS fancontrol_gui_lib ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
+add_library(fancontrol_qml_plugin SHARED ${LIB_SRCS})
+target_link_libraries(fancontrol_qml_plugin PRIVATE ${LIB_PRIVATE_LIBRARIES} PUBLIC ${LIB_PUBLIC_LIBRARIES})
 
-endif(INSTALL_SHARED)
+install(TARGETS fancontrol_qml_plugin DESTINATION "${KDE_INSTALL_QMLDIR}/Fancontrol/Qml/")
+install(FILES ${QML_FILES} DESTINATION "${KDE_INSTALL_QMLDIR}/Fancontrol/Qml/")

+ 9 - 0
package/contents/ui/ErrorDialog.qml → import/qml/ErrorDialog.qml

@@ -24,7 +24,10 @@ import QtQuick.Controls 1.2
 
 
 Dialog {
+    id: dialog
+
     property alias text: text.text
+    property QtObject loader
 
     title: i18n("Error")
     width: text.implicitWidth + 20
@@ -34,5 +37,11 @@ Dialog {
     Label {
         id: text
         anchors.centerIn: parent
+        text: !!loader ? loader.error : ""
+    }
+    
+    Connections {
+        target: loader
+        onCriticalError: dialog.open()
     }
 }

+ 22 - 19
package/contents/ui/PwmFan.qml → import/qml/FanItem.qml

@@ -21,9 +21,10 @@
 import QtQuick 2.4
 import QtQuick.Controls 1.4
 import QtQuick.Layouts 1.1
-import "../scripts/math.js" as MoreMath
-import "../scripts/units.js" as Units
-import "../scripts/colors.js" as Colors
+import Fancontrol.Qml 1.0 as Fancontrol
+import "math.js" as MoreMath
+import "units.js" as Units
+import "colors.js" as Colors
 
 
 Rectangle {
@@ -33,7 +34,7 @@ Rectangle {
     property real minTemp: 40.0
     property real maxTemp: 90.0
     property int margin: 5
-    property int unit: 0
+    property string unit: "°C"
     property real convertedMinTemp: Units.fromCelsius(minTemp, unit)
     property real convertedMaxTemp: Units.fromCelsius(maxTemp, unit)
 
@@ -59,6 +60,7 @@ Rectangle {
 
     TextEdit {
         id: nameField
+
         anchors {
             left: parent.left
             leftMargin: margin
@@ -82,6 +84,11 @@ Rectangle {
             }
         }
 
+        Connections {
+            target: fan
+            onNameChanged: if (fan.name != text) text = fan.name
+        }
+
         MouseArea {
             anchors.fill: parent
             cursorShape: Qt.IBeamCursor
@@ -94,7 +101,6 @@ Rectangle {
 
         property int fontSize: MoreMath.bound(8, height / 20 + 1, 16)
         property QtObject pal: !!fan ? fan.hasTemp ? palette : disabledPalette : disabledPalette
-        property string suffix: (root.unit == 0) ? "°C" : (root.unit == 1) ? "K" : "°F"
         property int verticalScalaCount: 6
         property var horIntervals: MoreMath.intervals(root.convertedMinTemp, root.convertedMaxTemp, 10)
 
@@ -114,18 +120,19 @@ Rectangle {
                 bottom: background.bottom
                 left: parent.left
             }
-            width: graph.fontSize * 3
+            width: MoreMath.maxWidth(children) + graph.fontSize
 
             Repeater {
+                id: verticalRepeater
+
                 model: graph.verticalScalaCount
 
                 Label {
-                    x: 0
-                    width: verticalScala.width - graph.fontSize / 3
-                    y: background.scaleY(255 / (graph.verticalScalaCount - 1) * index) - graph.fontSize / 2
+                    x: verticalScala.width - implicitWidth - graph.fontSize / 3
+                    y: background.height - background.height / (graph.verticalScalaCount - 1) * index - graph.fontSize / 2
                     horizontalAlignment: Text.AlignRight
                     color: graph.pal.text
-                    text: index * (100 / (graph.verticalScalaCount - 1)) + "%"
+                    text: i18n("%1\%", index * (100 / (graph.verticalScalaCount - 1)))
                     font.pixelSize: graph.fontSize
                 }
             }
@@ -144,10 +151,10 @@ Rectangle {
                 model: graph.horIntervals.length;
 
                 Label {
-                    x: Math.min(horizontalScala.width, background.scaleX(Units.toCelsius(graph.horIntervals[index]), root.unit)) - width / 2
-                    y: graph.fontSize / 2
+                    x: Math.min(horizontalScala.width, background.width / (graph.horIntervals.length - 1) * index) - width / 2
+                    y: horizontalScala.height / 2 - implicitHeight / 2
                     color: graph.pal.text
-                    text: graph.horIntervals[index] + graph.suffix
+                    text: i18n("%1" + unit, graph.horIntervals[index])
                     font.pixelSize: graph.fontSize
                 }
             }
@@ -442,25 +449,21 @@ Rectangle {
         }
 
         RowLayout {
-            visible: systemdCom
+            visible: !!systemdCom
 
             Item {
                 Layout.fillWidth: true
             }
             Button {
-                property bool reactivateAfterTesting
-
                 id: testButton
+
                 text: !!fan ? fan.testing ? i18n("Abort test") : i18n("Test start and stop values") : ""
                 iconName: "dialog-password"
                 anchors.right: parent.right
                 onClicked: {
                     if (fan.testing) {
-                        systemdCom.serviceActive = reactivateAfterTesting;
                         fan.abortTest();
                     } else {
-                        reactivateAfterTesting = systemdCom.serviceActive;
-                        systemdCom.serviceActive = false;
                         minStartInput.value = Qt.binding(function() { return Math.round(fan.minStart / 2.55) });
                         fan.test();
                     }

+ 0 - 0
package/contents/ui/OptionInput.qml → import/qml/OptionInput.qml


+ 4 - 6
package/contents/ui/PwmPoint.qml → import/qml/PwmPoint.qml

@@ -20,7 +20,7 @@
 
 import QtQuick 2.4
 import QtQuick.Controls 1.4
-import "../scripts/units.js" as Units
+import "units.js" as Units
 
 
 Rectangle {
@@ -32,7 +32,7 @@ Rectangle {
     readonly property point center: Qt.point(centerX, centerY)
     property alias drag: pwmMouse.drag
     property int size: 10
-    property int unit: 0
+    property string unit: "°C"
     property var locale: Qt.locale()
 
     signal positionChanged()
@@ -76,14 +76,12 @@ Rectangle {
             Label {
                 id: pwm
                 font.pixelSize: root.size * 1.5
-                text: Number(Math.round(background.scalePwm(root.centerY)) / 2.55).toLocaleString(locale, 'f', 1) + '%'
+                text: Number(Math.round(background.scalePwm(root.centerY)) / 2.55).toLocaleString(locale, 'f', 1) + i18n('%')
             }
             Label {
-                property string suffix: (unit == 0) ? "°C" : (unit == 1) ? "K" : "°F"
-
                 id: temp
                 font.pixelSize: root.size * 1.5
-                text: Math.round(Units.fromCelsius(background.scaleTemp(root.centerX)), unit) + suffix
+                text: Math.round(Units.fromCelsius(background.scaleTemp(root.centerX)), unit) + i18n(unit)
             }
         }
     }

+ 5 - 7
package/contents/ui/StatusPoint.qml → import/qml/StatusPoint.qml

@@ -20,8 +20,8 @@
 
 import QtQuick 2.4
 import QtQuick.Controls 1.2
-import "../scripts/units.js" as Units
-import "../scripts/math.js" as MoreMath
+import "units.js" as Units
+import "math.js" as MoreMath
 
 
 Rectangle {
@@ -36,7 +36,7 @@ Rectangle {
     readonly property real centerY: y + height / 2
     readonly property point center: Qt.point(centerX, centerY)
     property int size: 10
-    property int unit: 0
+    property string unit: "°C"
 
     width: size
     height: size
@@ -78,17 +78,15 @@ Rectangle {
 
         Column {
             Label {
-                property string suffix: (unit == 0) ? "°C" : (unit == 1) ? "K" : "°F"
-
                 id: temp
                 font.pixelSize: root.height * 1.5
-                text: (!!fan && fan.hasTemp ? Math.round(Units.fromCelsius(root.unscaledTemp, unit)) : "0") + suffix
+                text: (!!fan && fan.hasTemp ? Math.round(Units.fromCelsius(root.unscaledTemp, unit)) : "0") + i18n(unit)
 
             }
             Label {
                 id: pwm
                 font.pixelSize: root.height * 1.5
-                text: Number(Math.round(unscaledPwm / 2.55)).toLocaleString(locale, 'f', 1) + '%'
+                text: Number(Math.round(unscaledPwm / 2.55)).toLocaleString(locale, 'f', 1) + i18n('%')
             }
             Label {
                 id: rpm

+ 0 - 0
package/contents/scripts/colors.js → import/qml/colors.js


+ 8 - 0
package/contents/scripts/math.js → import/qml/math.js

@@ -35,3 +35,11 @@ function intervals(lower, upper, delta) {
     array.push(upper);
     return array;
 }
+
+function maxWidth(items) {
+    var maxWidth = 0;
+    for (var i=0; i<items.length; i++) {
+        maxWidth = Math.max(items[i].width, maxWidth);
+    }
+    return maxWidth;
+}

+ 9 - 0
import/qml/qmldir

@@ -0,0 +1,9 @@
+module Fancontrol.Qml
+plugin fancontrol_qml_plugin
+internal StatusPoint StatusPoint.qml
+internal PwmPoint PwmPoint.qml
+FanItem 1.0 FanItem.qml
+ErrorDialog 1.0 ErrorDialog.qml
+OptionInput 1.0 OptionInput.qml
+Units 1.0 units.js
+

+ 7 - 7
package/contents/scripts/units.js → import/qml/units.js

@@ -24,21 +24,21 @@ function round(number, dec) {
 
 function toCelsius(degrees, currentUnit) {
     var float = parseFloat(degrees);
-    if (currentUnit == 1) { return float - 273.15; }
-    if (currentUnit == 2) { return (float - 32) * 5 / 9; }
+    if (currentUnit == "K") { return float - 273.15; }
+    if (currentUnit == "°F") { return (float - 32) * 5 / 9; }
     return float;
 }
 
 function fromCelsius(degrees, newUnit) {
     var float = parseFloat(degrees);
-    if (newUnit == 1) { return float + 273.15; }
-    if (newUnit == 2) { return float * 9 / 5 + 32; }
+    if (newUnit == "K") { return float + 273.15; }
+    if (newUnit == "°F") { return float * 9 / 5 + 32; }
     return float;
 }
 
 function fromKelvin(degrees, newUnit) {
     var float = parseFloat(degrees);
-    if (newUnit == 0) { return float - 273.15; }
-    if (newUnit == 2) { return float * 9 / 5 - 459.67; }
+    if (newUnit == "°C") { return float - 273.15; }
+    if (newUnit == "°F") { return float * 9 / 5 - 459.67; }
     return float;
-}
+}    

+ 0 - 0
lib/src/config.cpp → import/src/config.cpp


+ 0 - 0
lib/src/config.h → import/src/config.h


+ 4 - 0
lib/src/fan.cpp → import/src/fan.cpp

@@ -62,8 +62,10 @@ QString Fan::name() const
     KConfigGroup names = KSharedConfig::openConfig(QStringLiteral("fancontrol-gui"))->group("names");
     KConfigGroup localNames = names.group(m_parent->name());
     QString name = localNames.readEntry("fan" + QString::number(m_index), QString());
+    
     if (name.isEmpty())
         return "fan" + QString::number(m_index);
+    
     return name;
 }
 
@@ -71,6 +73,7 @@ void Fan::setName(const QString &name)
 {
     KConfigGroup names = KSharedConfig::openConfig(QStringLiteral("fancontrol-gui"))->group("names");
     KConfigGroup localNames = names.group(m_parent->name());
+    
     if (name != localNames.readEntry("fan" + QString::number(m_index), QString())
         && !name.isEmpty())
     {
@@ -104,6 +107,7 @@ void Fan::update()
     m_rpmStream->seek(0);
     int rpm;
     *m_rpmStream >> rpm;
+    
     if (rpm != m_rpm)
     {
         m_rpm = rpm;

+ 0 - 0
lib/src/fan.h → import/src/fan.h


+ 0 - 0
lib/src/fancontrolaction.h → import/src/fancontrolaction.h


+ 68 - 0
import/src/fancontrolqmlextension.cpp

@@ -0,0 +1,68 @@
+/*
+ * Copyright 2016  Malte Veerman <maldela@halloarsch.de>
+ *
+ * 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
+ * the License or (at your option) version 3 or any later version
+ * 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/>.
+ *
+ */
+
+#include "fancontrolqmlextension.h"
+
+#include "fan.h"
+#include "pwmfan.h"
+#include "temp.h"
+#include "hwmon.h"
+#include "loader.h"
+#include "guibase.h"
+
+#ifndef NO_SYSTEMD
+#include "systemdcommunicator.h"
+#endif
+
+#include <QtQml/qqml.h>
+
+
+namespace Fancontrol
+{
+
+void FancontrolQmlExtension::registerTypes(const char* uri)
+{
+    Q_ASSERT(uri == QLatin1String("Fancontrol.Qml"));
+
+    qmlRegisterType<Fan>();
+    qmlRegisterUncreatableType<PwmFan>(uri, 1, 0, "PwmFan", QStringLiteral("PwmFan is not instantiable from QML!"));
+    qmlRegisterType<Temp>();
+    qmlRegisterType<Hwmon>();
+    qmlRegisterType<Loader>();
+
+#ifndef NO_SYSTEMD
+    qmlRegisterType<SystemdCommunicator>();
+#endif
+
+    qmlRegisterSingletonType<GUIBase>(uri, 1, 0, "base", base);
+}
+
+QObject * FancontrolQmlExtension::base(QQmlEngine *engine, QJSEngine *jsengine)
+{
+    Q_UNUSED(engine)
+    Q_UNUSED(jsengine)
+
+    return new GUIBase;
+}
+
+
+}
+

+ 52 - 0
import/src/fancontrolqmlextension.h

@@ -0,0 +1,52 @@
+/*
+ * Copyright 2016  Malte Veerman <maldela@halloarsch.de>
+ * 
+ * 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
+ * the License or (at your option) version 3 or any later version
+ * 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 FANCONTROLQMLEXTENSION_H
+#define FANCONTROLQMLEXTENSION_H
+
+
+#include <QtQml/QQmlExtensionPlugin>
+
+
+class QQmlEngine;
+class QJSEngine;
+
+namespace Fancontrol
+{
+
+class FancontrolQmlExtension : public QQmlExtensionPlugin
+{
+    Q_OBJECT
+    Q_PLUGIN_METADATA(IID "Fancontrol.Qml")
+    
+public:
+    
+    void registerTypes(const char *uri) Q_DECL_OVERRIDE;
+    
+    
+private:
+    
+    static QObject * base(QQmlEngine *engine, QJSEngine *jsengine);
+};
+
+}
+
+#endif // FANCONTROLQMLEXTENSION_H

+ 17 - 13
lib/src/guibase.cpp → import/src/guibase.cpp

@@ -26,7 +26,6 @@
 #include "config.h"
 #include "hwmon.h"
 
-#include <QtQml/qqml.h>
 #include <QtCore/QLocale>
 
 
@@ -46,22 +45,17 @@ GUIBase::GUIBase(QObject *parent) : QObject(parent),
     m_tempModel(new TempModel(this))
 {
     connect(m_config, &Config::configChanged, this, &GUIBase::emitConfigChanged);
-
-    QLocale locale = QLocale::system();
-    QLocale::MeasurementSystem system = locale.measurementSystem();
-    m_unit = (system != QLocale::ImperialUSSystem) ? 0 : 2;
-
-    qmlRegisterType<Loader>();
-    qmlRegisterType<Hwmon>();
-    qmlRegisterType<Fan>();
-    qmlRegisterType<PwmFan>();
-    qmlRegisterType<Temp>();
+    connect(this, &GUIBase::unitChanged, m_tempModel, &TempModel::setUnit);
 
 #ifndef NO_SYSTEMD
-    qmlRegisterType<SystemdCommunicator>();
+    connect(m_loader, &Loader::requestSetServiceActive, m_com, &SystemdCommunicator::setServiceActive);
 #endif
 
-    m_tempModel->setUnit(m_unit);
+    QLocale locale = QLocale::system();
+    QLocale::MeasurementSystem system = locale.measurementSystem();
+    m_unit = (system == QLocale::ImperialUSSystem) ? QStringLiteral("°F") : QStringLiteral("°C");
+    emit unitChanged(m_unit);
+
     foreach (Hwmon *hwmon, m_loader->hwmons())
     {
         m_pwmFanModel->addPwmFans(hwmon->pwmFans());
@@ -159,4 +153,14 @@ void GUIBase::emitConfigChanged()
     emit configUrlChanged();
 }
 
+bool GUIBase::hasSystemdCommunicator() const
+{
+#ifndef NO_SYSTEMD
+    return true;
+#else
+    return false;
+#endif
+}
+
+
 }

+ 12 - 20
lib/src/guibase.h → import/src/guibase.h

@@ -1,5 +1,4 @@
 /*
- * <one line to give the library's name and an idea of what it does.>
  * Copyright 2015  Malte Veerman maldela@halloarsch.de
  *
  * This program is free software; you can redistribute it and/or
@@ -25,7 +24,7 @@
 #define GUIBASE_H
 
 #include <QtCore/QObject>
-#include <QtCore/QStringListModel>
+#include <QtCore/QUrl>
 
 #include "loader.h"
 #include "pwmfanmodel.h"
@@ -33,38 +32,31 @@
 
 #ifndef NO_SYSTEMD
 #include "systemdcommunicator.h"
-
-#define SYSTEMD_BOOL true
-#else
-#define SYSTEMD_BOOL false
 #endif
 
-#include "fancontrol_gui_lib_export.h"
-
 
 namespace Fancontrol
 {
 
 class Config;
 
-class FANCONTROL_GUI_LIB_EXPORT GUIBase : public QObject
+class GUIBase : public QObject
 {
     Q_OBJECT
 
-    Q_PROPERTY(Loader* loader READ loader CONSTANT)
-
 #ifndef NO_SYSTEMD
     Q_PROPERTY(SystemdCommunicator* systemdCom READ systemdCommunicator CONSTANT)
 #endif
 
+    Q_PROPERTY(PwmFanModel *pwmFanModel READ pwmFanModel CONSTANT)
+    Q_PROPERTY(TempModel *tempModel READ tempModel CONSTANT)
+    Q_PROPERTY(Loader* loader READ loader CONSTANT)
     Q_PROPERTY(qreal minTemp READ minTemp WRITE setMinTemp NOTIFY minTempChanged)
     Q_PROPERTY(qreal maxTemp READ maxTemp WRITE setMaxTemp NOTIFY maxTempChanged)
-    Q_PROPERTY(int unit READ unit WRITE setUnit NOTIFY unitChanged)
+    Q_PROPERTY(QString unit READ unit WRITE setUnit NOTIFY unitChanged)
     Q_PROPERTY(QString serviceName READ serviceName WRITE setServiceName NOTIFY serviceNameChanged)
     Q_PROPERTY(QUrl configUrl READ configUrl WRITE setConfigUrl NOTIFY configUrlChanged)
     Q_PROPERTY(bool configValid READ configValid NOTIFY configUrlChanged)
-    Q_PROPERTY(PwmFanModel *pwmFanModel READ pwmFanModel CONSTANT)
-    Q_PROPERTY(TempModel *tempModel READ tempModel CONSTANT)
 
 public:
 
@@ -81,16 +73,16 @@ public:
     QString serviceName() const;
     QUrl configUrl() const;
     bool configValid() const { return m_configValid; }
-    int unit() const { return m_unit; }
+    QString unit() const { return m_unit; }
     void setMinTemp(qreal minTemp);
     void setMaxTemp(qreal maxTemp);
     void setServiceName(const QString &name);
     void setConfigUrl(const QUrl &url);
-    void setUnit(int unit) { if (unit != m_unit) { m_unit = unit; emit unitChanged(); m_tempModel->setUnit(unit); } }
+    void setUnit(const QString &unit) { if (unit != m_unit) { m_unit = unit; emit unitChanged(m_unit); } }
     PwmFanModel *pwmFanModel() const { return m_pwmFanModel; };
     TempModel *tempModel() const { return m_tempModel; };
     
-    Q_INVOKABLE bool hasSystemdCommunicator() const { return SYSTEMD_BOOL; }
+    Q_INVOKABLE bool hasSystemdCommunicator() const;
 
 
 public slots:
@@ -105,7 +97,7 @@ signals:
     void maxTempChanged();
     void serviceNameChanged();
     void configUrlChanged();
-    void unitChanged();
+    void unitChanged(QString);
 
 
 protected:
@@ -115,14 +107,14 @@ protected:
 
 private:
 
-    Config *m_config;
+    Config *const m_config;
 
 #ifndef NO_SYSTEMD
     SystemdCommunicator *const m_com;
 #endif
 
     Loader *const m_loader;
-    int m_unit;
+    QString m_unit;
     bool m_configValid;
     PwmFanModel *m_pwmFanModel;
     TempModel *m_tempModel;

+ 28 - 8
lib/src/hwmon.cpp → import/src/hwmon.cpp

@@ -20,6 +20,8 @@
 
 #include "hwmon.h"
 
+#include "loader.h"
+
 #include <QtCore/QDir>
 #include <QtCore/QTextStream>
 
@@ -27,7 +29,8 @@
 namespace Fancontrol
 {
 
-Hwmon::Hwmon(const QString &path, QObject *parent) : QObject(parent),
+Hwmon::Hwmon(const QString &path, Loader *parent) : QObject(parent),
+    m_parent(parent),
     m_path(path),
     m_valid(true)
 {
@@ -52,10 +55,10 @@ Hwmon::Hwmon(const QString &path, QObject *parent) : QObject(parent),
     else
         m_name = path.split('/').last();
 
-    connect(this, SIGNAL(configUpdateNeeded()), parent, SLOT(createConfigFile()));
-    connect(this, SIGNAL(pwmFansChanged()), parent, SLOT(emitAllPwmFansChanged()));
-    connect(this, SIGNAL(tempsChanged()), parent, SLOT(emitAllTempsChanged()));
-    connect(this, SIGNAL(errorChanged(QString)), parent, SLOT(setError(QString)));
+    connect(this, &Hwmon::configUpdateNeeded, parent, &Loader::createConfigFile);
+    connect(this, &Hwmon::pwmFansChanged, parent, &Loader::emitAllPwmFansChanged);
+    connect(this, &Hwmon::tempsChanged, parent, &Loader::emitAllTempsChanged);
+    connect(this, &Hwmon::errorChanged, parent, &Loader::setError);
 
     if (m_valid)
         initialize();
@@ -87,7 +90,8 @@ void Hwmon::initialize()
                 if (!newPwmFan)
                 {
                     newPwmFan = new PwmFan(this, index);
-                    connect(this, SIGNAL(sensorsUpdateNeeded()), newPwmFan, SLOT(update()));
+                    connect(this, &Hwmon::sensorsUpdateNeeded, newPwmFan, &PwmFan::update);
+                    connect(newPwmFan, &PwmFan::testStatusChanged, m_parent, &Loader::handleTestStatusChanged);
                     m_pwmFans << newPwmFan;
                     emit pwmFansChanged();
                 }
@@ -116,7 +120,7 @@ void Hwmon::initialize()
                 if (!newFan)
                 {
                     newFan = new Fan(this, index);
-                    connect(this, SIGNAL(sensorsUpdateNeeded()), newFan, SLOT(update()));
+                    connect(this, &Hwmon::sensorsUpdateNeeded, newFan, &Fan::update);
                     m_fans << newFan;
                     emit fansChanged();
                 }
@@ -140,7 +144,7 @@ void Hwmon::initialize()
             if (!newTemp)
             {
                 newTemp = new Temp(this, index);
-                connect(this, SIGNAL(sensorsUpdateNeeded()), newTemp, SLOT(update()));
+                connect(this, &Hwmon::sensorsUpdateNeeded, newTemp, &Temp::update);
                 m_temps << newTemp;
                 emit tempsChanged();
             }
@@ -214,4 +218,20 @@ void Hwmon::setError(const QString &error)
     emit errorChanged(error);
 }
 
+bool Hwmon::testing() const
+{
+    bool testing = false;
+
+    foreach(const PwmFan *fan, m_pwmFans)
+    {
+        if (fan->testing())
+        {
+            testing = true;
+            break;
+        }
+    }
+
+    return testing;
+}
+
 }

+ 7 - 6
lib/src/hwmon.h → import/src/hwmon.h

@@ -33,6 +33,8 @@
 namespace Fancontrol
 {
 
+class Loader;
+
 class Hwmon : public QObject
 {
     Q_OBJECT
@@ -46,7 +48,7 @@ class Hwmon : public QObject
 
 public:
 
-    explicit Hwmon(const QString &path, QObject *parent = Q_NULLPTR);
+    explicit Hwmon(const QString &path, Loader *parent = Q_NULLPTR);
 
     void initialize();
     QString name() const { return m_name; }
@@ -64,16 +66,13 @@ public:
     PwmFan * pwmFan(int i) const;
     Temp * temp(int i) const;
     bool isValid() const { return m_valid; }
+    bool testing() const;
 
 
 public slots:
 
     void updateConfig() { emit configUpdateNeeded(); }
     void updateSensors() { emit sensorsUpdateNeeded(); }
-
-
-protected slots:
-
     void setError(const QString &error);
 
 
@@ -84,11 +83,12 @@ signals:
     void tempsChanged();
     void configUpdateNeeded();
     void sensorsUpdateNeeded();
-    void errorChanged(QString);
+    void errorChanged(QString, bool = false);
 
 
 private:
 
+    Loader *m_parent;
     QString m_name;
     const QString m_path;
     bool m_valid;
@@ -100,4 +100,5 @@ private:
 
 }
 
+
 #endif // HWMON_H

+ 148 - 68
lib/src/loader.cpp → import/src/loader.cpp

@@ -27,6 +27,7 @@
 #include <QtCore/QDir>
 #include <QtCore/QTextStream>
 #include <QtCore/QTimer>
+#include <QtCore/QProcess>
 #include <QtCore/QDebug>
 
 #include <KAuth/KAuthExecuteJob>
@@ -44,16 +45,18 @@ namespace Fancontrol
 {
 
 Loader::Loader(QObject *parent) : QObject(parent),
+    m_reactivateAfterTesting(true),
     m_interval(10),
     m_configUrl(QUrl::fromLocalFile(QStringLiteral(STANDARD_CONFIG_FILE))),
-    m_timer(new QTimer(this))
+    m_timer(new QTimer(this)),
+    m_sensorsDetected(false)
 {
     parseHwmons();
 
     m_timer->setSingleShot(false);
     m_timer->start(1);
 
-    connect(m_timer, SIGNAL(timeout()), this, SLOT(updateSensors()));
+    connect(m_timer, &QTimer::timeout, this, &Loader::updateSensors);
 }
 
 void Loader::parseHwmons()
@@ -108,7 +111,7 @@ void Loader::parseHwmons()
             Hwmon *newHwmon = new Hwmon(hwmonPath, this);
             if (newHwmon->isValid())
             {
-                connect(this, SIGNAL(sensorsUpdateNeeded()), newHwmon, SLOT(updateSensors()));
+                connect(this, &Loader::sensorsUpdateNeeded, newHwmon, &Hwmon::updateSensors);
                 m_hwmons << newHwmon;
                 emit hwmonsChanged();
             }
@@ -265,33 +268,39 @@ bool Loader::load(const QUrl &url)
     else if (file.exists())
     {
         KAuth::Action action = newFancontrolAction();
-        QVariantMap map;
-        map[QStringLiteral("action")] = QVariant("read");
-        map[QStringLiteral("filename")] = fileName;
-        action.setArguments(map);
-        KAuth::ExecuteJob *reply = action.execute();
-        if (!reply->exec())
+
+        if (action.isValid())
         {
-            if (reply->error() == 4)
+            QVariantMap map;
+            map[QStringLiteral("action")] = QVariant("read");
+            map[QStringLiteral("filename")] = fileName;
+            action.setArguments(map);
+            KAuth::ExecuteJob *reply = action.execute();
+            if (!reply->exec())
             {
-                qDebug() << "Aborted by user";
+                if (reply->error() == 4)
+                {
+                    qDebug() << "Aborted by user";
+                    return false;
+                }
+
+                qDebug() << "Error while loading:" << reply->error();
+                setError(reply->errorString() + reply->errorText(), true);
                 return false;
             }
-            
-            qDebug() << "Error while loading:" << reply->error();
-            setError(reply->errorString() + reply->errorText(), true);
-            return false;
-        }
-        else
-        {
-            if (!url.isEmpty())
+            else
             {
-                m_configUrl = url;
-                emit configUrlChanged();
-            }
+                if (!url.isEmpty())
+                {
+                    m_configUrl = url;
+                    emit configUrlChanged();
+                }
 
-            fileContent = reply->data().value(QStringLiteral("content")).toString();
+                fileContent = reply->data().value(QStringLiteral("content")).toString();
+            }
         }
+        else
+            setError(i18n("Action not supported! Try running the application as root."), true);
     }
     else
     {
@@ -308,7 +317,7 @@ bool Loader::load(const QUrl &url)
     //They get reconnected later
     foreach (Hwmon *hwmon, m_hwmons)
     {
-        disconnect(hwmon, SIGNAL(configUpdateNeeded()), this, SLOT(createConfigFile()));
+        disconnect(hwmon, &Hwmon::configUpdateNeeded, this, &Loader::createConfigFile);
         foreach (QObject *pwmFan, hwmon->pwmFans())
         {
             qobject_cast<PwmFan *>(pwmFan)->reset();
@@ -345,7 +354,7 @@ bool Loader::load(const QUrl &url)
             {
                 //Connect hwmons again
                 foreach (Hwmon *hwmon, m_hwmons)
-                    connect(hwmon, SIGNAL(configUpdateNeeded()), this, SLOT(createConfigFile()));
+                    connect(hwmon, &Hwmon::configUpdateNeeded, this, &Loader::createConfigFile);
 
                 setError(i18n("Unable to parse interval line: \n %1", line), true);
                 return false;
@@ -393,7 +402,7 @@ bool Loader::load(const QUrl &url)
                     {
                         //Connect hwmons again
                         foreach (Hwmon *hwmon, m_hwmons)
-                            connect(hwmon, SIGNAL(configUpdateNeeded()), this, SLOT(createConfigFile()));
+                            connect(hwmon, &Hwmon::configUpdateNeeded, this, &Loader::createConfigFile);
 
                         setError(i18n("Can not parse %1", devname), true);
                         return false;
@@ -403,7 +412,7 @@ bool Loader::load(const QUrl &url)
                     {
                         //Connect hwmons again
                         foreach (Hwmon *hwmon, m_hwmons)
-                            connect(hwmon, SIGNAL(configUpdateNeeded()), this, SLOT(createConfigFile()));
+                            connect(hwmon, &Hwmon::configUpdateNeeded, this, &Loader::createConfigFile);
 
                         setError(i18n("Invalid config file!"), true);
                         return false;
@@ -446,7 +455,7 @@ bool Loader::load(const QUrl &url)
         {
             //Connect hwmons again
             foreach (Hwmon *hwmon, m_hwmons)
-                connect(hwmon, SIGNAL(configUpdateNeeded()), this, SLOT(createConfigFile()));
+                connect(hwmon, &Hwmon::configUpdateNeeded, this, &Loader::createConfigFile);
 
             setError(i18n("Unrecognized line in config:\n%1", line), true);
             return false;
@@ -457,7 +466,7 @@ bool Loader::load(const QUrl &url)
 
     //Connect hwmons again
     foreach (Hwmon *hwmon, m_hwmons)
-        connect(hwmon, SIGNAL(configUpdateNeeded()), this, SLOT(createConfigFile()));
+        connect(hwmon, &Hwmon::configUpdateNeeded, this, &Loader::createConfigFile);
 
     emit configUrlChanged();
 
@@ -491,26 +500,32 @@ bool Loader::save(const QUrl &url)
     else
     {
         KAuth::Action action = newFancontrolAction();
-        QVariantMap map;
-        map[QStringLiteral("action")] = QVariant("write");
-        map[QStringLiteral("filename")] = fileName;
-        map[QStringLiteral("content")] = m_configFile;
 
-        action.setArguments(map);
-        KAuth::ExecuteJob *reply = action.execute();
-
-        if (!reply->exec())
+        if (action.isValid())
         {
-            if (reply->error() == 4)
+            QVariantMap map;
+            map[QStringLiteral("action")] = QVariant("write");
+            map[QStringLiteral("filename")] = fileName;
+            map[QStringLiteral("content")] = m_configFile;
+
+            action.setArguments(map);
+            KAuth::ExecuteJob *reply = action.execute();
+
+            if (!reply->exec())
             {
-                qDebug() << "Aborted by user";
+                if (reply->error() == 4)
+                {
+                    qDebug() << "Aborted by user";
+                    return false;
+                }
+
+                qDebug() << "Error while saving:" << reply->error();
+                setError(reply->errorString() + reply->errorText(), true);
                 return false;
             }
-            
-            qDebug() << "Error while saving:" << reply->error();
-            setError(reply->errorString() + reply->errorText(), true);
-            return false;
         }
+        else
+            setError(i18n("Action not supported! Try running the application as root."), true);
     }
 
     return true;
@@ -552,14 +567,14 @@ void Loader::createConfigFile()
             configFile += QStringLiteral("hwmon") + QString::number(hwmon->index()) + "=" + sanitizedPath + QChar(QChar::Space);
         }
         configFile += QChar(QChar::LineFeed);
-        
+
         configFile += QStringLiteral("DEVNAME=");
         foreach (Hwmon *hwmon, usedHwmons)
         {
             configFile += QStringLiteral("hwmon") + QString::number(hwmon->index()) + "=" + hwmon->name().split('.').first() + QChar(QChar::Space);
         }
         configFile += QChar(QChar::LineFeed);
-        
+
         if (!usedFans.isEmpty())
         {
             configFile += QStringLiteral("FCTEMPS=");
@@ -571,7 +586,7 @@ void Loader::createConfigFile()
                 configFile += QStringLiteral("temp") + QString::number(pwmFan->temp()->index()) + QStringLiteral("_input ");
             }
             configFile += QChar(QChar::LineFeed);
-            
+
             configFile += QStringLiteral("FCFANS=");
             foreach (PwmFan *pwmFan, usedFans)
             {
@@ -581,7 +596,7 @@ void Loader::createConfigFile()
                 configFile += QStringLiteral("fan") + QString::number(pwmFan->index()) + QStringLiteral("_input ");
             }
             configFile += QChar(QChar::LineFeed);
-            
+
             configFile += QStringLiteral("MINTEMP=");
             foreach (PwmFan *pwmFan, usedFans)
             {
@@ -590,7 +605,7 @@ void Loader::createConfigFile()
                 configFile += QString::number(pwmFan->minTemp()) + QChar(QChar::Space);
             }
             configFile += QChar(QChar::LineFeed);
-            
+
             configFile += QStringLiteral("MAXTEMP=");
             foreach (PwmFan *pwmFan, usedFans)
             {
@@ -599,7 +614,7 @@ void Loader::createConfigFile()
                 configFile += QString::number(pwmFan->maxTemp()) + QChar(QChar::Space);
             }
             configFile += QChar(QChar::LineFeed);
-            
+
             configFile += QStringLiteral("MINSTART=");
             foreach (PwmFan *pwmFan, usedFans)
             {
@@ -608,7 +623,7 @@ void Loader::createConfigFile()
                 configFile += QString::number(pwmFan->minStart()) + QChar(QChar::Space);
             }
             configFile += QChar(QChar::LineFeed);
-            
+
             configFile += QStringLiteral("MINSTOP=");
             foreach (PwmFan *pwmFan, usedFans)
             {
@@ -675,15 +690,54 @@ void Loader::abortTestingFans()
 
 void Loader::detectSensors()
 {
-    KAuth::Action action = newFancontrolAction();
-    QVariantMap map;
-    map[QStringLiteral("action")] = QVariant("detectSensors");
+    QString program = QStringLiteral("sensors-detect");
+    QStringList arguments = QStringList() << QStringLiteral("--auto");
+
+    QProcess *process = new QProcess(this);
+    process->start(program, arguments);
+
+    connect(process, static_cast<void(QProcess::*)(int)>(&QProcess::finished),
+            this, static_cast<void(Loader::*)(int)>(&Loader::handleDetectSensorsResult));
+}
+
+void Loader::handleDetectSensorsResult(int exitCode)
+{
+    QProcess *process = qobject_cast<QProcess *>(sender());
+
+    if (exitCode)
+    {
+        if (process)
+            setError(process->readAllStandardOutput());
+
+        KAuth::Action action = newFancontrolAction();
+
+        if (action.isValid())
+        {
+            QVariantMap map;
+            map[QStringLiteral("action")] = QVariant("detectSensors");
+
+            action.setArguments(map);
+            KAuth::ExecuteJob *job = action.execute();
 
-    action.setArguments(map);
-    KAuth::ExecuteJob *job = action.execute();
+            connect(job, &KAuth::ExecuteJob::result, this, static_cast<void(Loader::*)(KJob *)>(&Loader::handleDetectSensorsResult));
+            job->start();
+        }
+        else
+            setError(i18n("Action not supported! Try running the application as root."), true);
+    }
+    else
+    {
+        if (!m_sensorsDetected)
+        {
+            m_sensorsDetected = true;
+            emit sensorsDetectedChanged();
+        }
 
-    connect(job, SIGNAL(result(KJob*)), this, SLOT(handleDetectSensorsResult(KJob*)));
-    job->start();
+        parseHwmons();
+    }
+
+    if (process)
+        process->deleteLater();
 }
 
 void Loader::handleDetectSensorsResult(KJob *job)
@@ -695,12 +749,20 @@ void Loader::handleDetectSensorsResult(KJob *job)
             qDebug() << "Aborted by user";
             return;
         }
-            
+
         qDebug() << "Error while detecting sensors:" << job->error();
         setError(job->errorString() + job->errorText(), true);
     }
     else
+    {
+        if (!m_sensorsDetected)
+        {
+            m_sensorsDetected = true;
+            emit sensorsDetectedChanged();
+        }
+
         parseHwmons();
+    }
 }
 
 QList<QObject *> Loader::hwmonsAsObjects() const
@@ -713,16 +775,6 @@ QList<QObject *> Loader::hwmonsAsObjects() const
     return list;
 }
 
-QList<QObject *> Loader::allTemps() const
-{
-    QList<QObject *> list;
-    foreach (const Hwmon *hwmon, m_hwmons)
-    {
-        list += hwmon->tempsAsObjects();
-    }
-    return list;
-}
-
 void Loader::setError (const QString &error, bool critical)
 {
     m_error = error;
@@ -737,4 +789,32 @@ void Loader::setError (const QString &error, bool critical)
         qWarning() << error;
 }
 
+void Loader::handleTestStatusChanged()
+{
+    bool testing = false;
+
+    foreach (const Hwmon *hwmon, m_hwmons)
+    {
+        if (hwmon->testing() == true)
+        {
+            testing = true;
+            break;
+        }
+    }
+
+    if (!testing && !m_reactivateAfterTesting)
+        return;
+
+    emit requestSetServiceActive(!testing);
+}
+
+void Loader::setRestartServiceAfterTesting(bool restart)
+{
+    if (m_reactivateAfterTesting == restart)
+        return;
+
+    m_reactivateAfterTesting = restart;
+    emit restartServiceAfterTestingChanged();
+}
+
 }

+ 14 - 9
lib/src/loader.h → import/src/loader.h

@@ -27,11 +27,10 @@
 #include <QtCore/QString>
 #include <QtCore/QPair>
 
-#include "fancontrol_gui_lib_export.h"
-
 
 class QTimer;
 class KJob;
+class QProcess;
 
 namespace Fancontrol
 {
@@ -40,15 +39,16 @@ class Hwmon;
 class PwmFan;
 class Temp;
 
-class FANCONTROL_GUI_LIB_EXPORT Loader : public QObject
+class Loader : public QObject
 {
     Q_OBJECT
     Q_PROPERTY(QUrl configUrl READ configUrl NOTIFY configUrlChanged)
     Q_PROPERTY(QString configFile READ configFile NOTIFY configFileChanged)
     Q_PROPERTY(QList<QObject *> hwmons READ hwmonsAsObjects NOTIFY hwmonsChanged)
-    Q_PROPERTY(QList<QObject *> allTemps READ allTemps NOTIFY allTempsChanged)
     Q_PROPERTY(int interval READ interval WRITE setInterval NOTIFY intervalChanged)
     Q_PROPERTY(QString error READ error NOTIFY errorChanged)
+    Q_PROPERTY(bool sensorsDetected READ sensorsDetected NOTIFY sensorsDetectedChanged)
+    Q_PROPERTY(bool restartServiceAfterTesting READ restartServiceAfterTesting WRITE setRestartServiceAfterTesting NOTIFY restartServiceAfterTestingChanged)
 
 
 public:
@@ -64,8 +64,10 @@ public:
     QUrl configUrl() const { return m_configUrl; }
     QString configFile() const { return m_configFile; }
     QList<Hwmon *> hwmons() const { return m_hwmons; }
+    bool sensorsDetected() const { return m_sensorsDetected; }
+    bool restartServiceAfterTesting() const { return m_reactivateAfterTesting; }
+    void setRestartServiceAfterTesting(bool restart);
     QList<QObject *> hwmonsAsObjects() const;
-    QList<QObject *> allTemps() const;
     int interval() const { return m_interval; }
     void setInterval(int interval, bool writeNewConfig = true);
     QString error() const { return m_error; }
@@ -76,15 +78,13 @@ public:
 public slots:
 
     void updateSensors() { emit sensorsUpdateNeeded(); }
-
-
-protected slots:
-
     void createConfigFile();
     void emitAllPwmFansChanged() { emit allPwmFansChanged(); }
     void emitAllTempsChanged() { emit allTempsChanged(); }
     void setError(const QString &error, bool critical = false);
     void handleDetectSensorsResult(KJob *job);
+    void handleDetectSensorsResult(int exitCode);
+    void handleTestStatusChanged();
 
 
 protected:
@@ -97,12 +97,14 @@ private:
     PwmFan *getPwmFan(const QPair<int, int> &indexPair) const;
     Temp *getTemp(const QPair<int, int> &indexPair) const;
 
+    bool m_reactivateAfterTesting;
     int m_interval;
     QList<Hwmon *> m_hwmons;
     QUrl m_configUrl;
     QString m_configFile;
     QString m_error;
     QTimer *m_timer;
+    bool m_sensorsDetected;
 
 
 signals:
@@ -117,6 +119,9 @@ signals:
     void allTempsChanged();
     void invalidConfigUrl();
     void criticalError();
+    void sensorsDetectedChanged();
+    void restartServiceAfterTestingChanged();
+    void requestSetServiceActive(bool);
 };
 
 }

+ 105 - 106
lib/src/pwmfan.cpp → import/src/pwmfan.cpp

@@ -58,15 +58,15 @@ PwmFan::PwmFan(Hwmon *parent, uint index) : Fan(parent, index),
     m_zeroRpm(0),
     m_testStatus(NotStarted)
 {
-    connect(this, SIGNAL(tempChanged()), parent, SLOT(updateConfig()));
-    connect(this, SIGNAL(hasTempChanged()), parent, SLOT(updateConfig()));
-    connect(this, SIGNAL(minTempChanged()), parent, SLOT(updateConfig()));
-    connect(this, SIGNAL(maxTempChanged()), parent, SLOT(updateConfig()));
-    connect(this, SIGNAL(minPwmChanged()), parent, SLOT(updateConfig()));
-    connect(this, SIGNAL(maxPwmChanged()), parent, SLOT(updateConfig()));
-    connect(this, SIGNAL(minStartChanged()), parent, SLOT(updateConfig()));
-    connect(this, SIGNAL(minStopChanged()), parent, SLOT(updateConfig()));
-    connect(this, SIGNAL(testingChanged()), parent, SLOT(updateConfig()));
+    connect(this, &PwmFan::tempChanged, parent, &Hwmon::updateConfig);
+    connect(this, &PwmFan::hasTempChanged, parent, &Hwmon::updateConfig);
+    connect(this, &PwmFan::minTempChanged, parent, &Hwmon::updateConfig);
+    connect(this, &PwmFan::maxTempChanged, parent, &Hwmon::updateConfig);
+    connect(this, &PwmFan::minPwmChanged, parent, &Hwmon::updateConfig);
+    connect(this, &PwmFan::maxPwmChanged, parent, &Hwmon::updateConfig);
+    connect(this, &PwmFan::minStartChanged, parent, &Hwmon::updateConfig);
+    connect(this, &PwmFan::minStopChanged, parent, &Hwmon::updateConfig);
+    connect(this, &PwmFan::testStatusChanged, parent, &Hwmon::updateConfig);
 
     if (QDir(parent->path()).isReadable())
     {
@@ -120,18 +120,18 @@ void PwmFan::update()
 void PwmFan::reset()
 {
     Fan::reset();
-    
+
     setHasTemp(false);
     setTemp(Q_NULLPTR);
-    
+
     QIODevice *oldFile = m_pwmStream->device();
     delete m_pwmStream;
     delete oldFile;
-    
+
     oldFile = m_modeStream->device();
     delete m_modeStream;
     delete oldFile;
-    
+
     QFile *pwmFile = new QFile(m_parent->path() + "/pwm" + QString::number(m_index), this);
         if (pwmFile->open(QFile::ReadWrite))
         {
@@ -171,44 +171,43 @@ bool PwmFan::setPwm(int pwm, bool write)
         if (write)
         {
             setPwmMode(1);
-            
+
             if (m_pwmStream->device()->isWritable())
                 *m_pwmStream << pwm;
             else
             {
                 KAuth::Action action = newFancontrolAction();
-                QVariantMap map;
-                map[QStringLiteral("action")] = "write";
-                map[QStringLiteral("filename")] = qobject_cast<QFile *>(m_pwmStream->device())->fileName();
-                map[QStringLiteral("content")] = QString::number(pwm);
-                action.setArguments(map);
-                KAuth::ExecuteJob *job = action.execute();
-                connect(job, SIGNAL(result(KJob*)), this, SLOT(handleSetPwmResult(KJob*)));
-                job->start();
+
+                if (action.isValid())
+                {
+                    QVariantMap map;
+                    map[QStringLiteral("action")] = "write";
+                    map[QStringLiteral("filename")] = qobject_cast<QFile *>(m_pwmStream->device())->fileName();
+                    map[QStringLiteral("content")] = QString::number(pwm);
+                    action.setArguments(map);
+
+                    KAuth::ExecuteJob *job = action.execute();
+                    if (!job->exec())
+                    {
+                        if (job->error() == KAuth::ActionReply::HelperBusyError)
+                        {
+                            qDebug() << "Helper busy...";
+
+                            QTimer::singleShot(50, this, [this] (){ setPwmMode(m_pwmMode); });
+                        }
+
+                        emit errorChanged(i18n("Could not set pwm: ") + job->errorText());
+                    }
+                    update();
+                }
+                else
+                    emit errorChanged(i18n("Action not supported! Try running the application as root."), true);
             }
         }
     }
     return true;
 }
 
-void PwmFan::handleSetPwmResult(KJob *job)
-{
-    if (job->error())
-    {
-        if (job->error() == KAuth::ActionReply::HelperBusyError)
-        {
-            qDebug() << "Helper busy...";
-            
-            QTimer::singleShot(50, this, [this] (){ setPwm(m_pwm); });
-            return;
-        }
-        
-        emit errorChanged(i18n("Could not set pwm: ") + job->errorText());
-        return;
-    }
-    update();
-}
-
 bool PwmFan::setPwmMode(int pwmMode, bool write)
 {
     if (m_pwmMode != pwmMode)
@@ -224,71 +223,68 @@ bool PwmFan::setPwmMode(int pwmMode, bool write)
             else
             {
                 KAuth::Action action = newFancontrolAction();
-                
-                QVariantMap map;
-                map[QStringLiteral("action")] = QVariant("write");
-                map[QStringLiteral("filename")] = qobject_cast<QFile *>(m_modeStream->device())->fileName();
-                map[QStringLiteral("content")] = QString::number(pwmMode);
-                action.setArguments(map);
-                KAuth::ExecuteJob *job = action.execute();
-                connect(job, SIGNAL(result(KJob*)), this, SLOT(handleSetPwmModeResult(KJob*)));
-                job->start();
+
+                if (action.isValid())
+                {
+                    QVariantMap map;
+                    map[QStringLiteral("action")] = QVariant("write");
+                    map[QStringLiteral("filename")] = qobject_cast<QFile *>(m_modeStream->device())->fileName();
+                    map[QStringLiteral("content")] = QString::number(pwmMode);
+                    action.setArguments(map);
+
+                    KAuth::ExecuteJob *job = action.execute();
+                    if (!job->exec())
+                    {
+                        if (job->error() == KAuth::ActionReply::HelperBusyError)
+                        {
+                            qDebug() << "Helper busy...";
+
+                            QTimer::singleShot(50, this, [this] (){ setPwmMode(m_pwmMode); });
+                        }
+
+                        emit errorChanged(i18n("Could not set pwm mode: ") + job->errorText());
+                    }
+                    update();
+                }
+                else
+                    emit errorChanged(i18n("Action not supported! Try running the application as root."), true);
             }
         }
     }
     return true;
 }
 
-void PwmFan::handleSetPwmModeResult(KJob *job)
+void PwmFan::test()
 {
-    if (job->error())
+    if (!m_modeStream->device()->isWritable() || !m_pwmStream->device()->isWritable())
     {
-        if (job->error() == KAuth::ActionReply::HelperBusyError)
-        {
-            qDebug() << "Helper busy...";
-            
-            QTimer::singleShot(50, this, [this] (){ setPwmMode(m_pwmMode); });
-            return;
-        }
-        
-        emit errorChanged(i18n("Could not set pwm mode: ") + job->errorText());
-        return;
-    }
-    update();
-}
+        KAuth::Action action = newFancontrolAction();
 
-void PwmFan::test()
-{
-    KAuth::Action action = newFancontrolAction();
-    KAuth::ExecuteJob *job = action.execute();
-    connect(job, SIGNAL(result(KJob*)), this, SLOT(handleTestAuthReply(KJob*)));
-    job->start();
-}
+        if (action.isValid())
+        {
+            KAuth::ExecuteJob *job = action.execute(KAuth::Action::AuthorizeOnlyMode);
 
-void PwmFan::handleTestAuthReply(KJob *job)
-{  
-    if (job->error())
-    {
-        if (job->error() == KAuth::ActionReply::HelperBusyError)
+            if (!job->exec())
+            {
+                emit errorChanged(i18n("Authorization error: ") + job->errorText());
+                m_testStatus = Error;
+                emit testStatusChanged();
+                return;
+            }
+        }
+        else
         {
-            qDebug() << "Helper busy...";
-            
-            QTimer::singleShot(100, this, &PwmFan::test);
+            emit errorChanged(i18n("Action not supported! Try running the application as root."), true);
             return;
         }
-        
-        emit errorChanged(i18n("Authorization error: ") + job->errorText());
-        m_testStatus = Error;
-        emit testingChanged();
-        return;
     }
-    
+
     setPwm(255);
-    
+
     m_testStatus = FindingStop1;
-    emit testingChanged();
-    
-    QTimer::singleShot(500, this, SLOT(continueTest()));
+    emit testStatusChanged();
+
+    QTimer::singleShot(500, this, &PwmFan::continueTest);
     qDebug() << "Start testing...";
 }
 
@@ -297,11 +293,9 @@ void PwmFan::abortTest()
     if (m_testStatus >= FindingStop1 && m_testStatus <= FindingStart)
     {
         qDebug() << "Abort testing";
-        
-        disconnect(this, 0, this, SLOT(continueTest()));
 
         m_testStatus = Cancelled;
-        emit testingChanged();
+        emit testStatusChanged();
 
         setPwm(255);
     }
@@ -309,16 +303,20 @@ void PwmFan::abortTest()
 
 void PwmFan::continueTest()
 {
-    KAuth::Action action = newFancontrolAction();
-    
-    if (action.status() != KAuth::Action::AuthorizedStatus)
+    if (!m_modeStream->device()->isWritable() || !m_pwmStream->device()->isWritable())
     {
-        m_testStatus = Error;
-        emit testingChanged();
-        return;
+        KAuth::Action action = newFancontrolAction();
+
+        if (action.status() != KAuth::Action::AuthorizedStatus)
+        {
+            m_testStatus = Error;
+            emit testStatusChanged();
+            return;
+        }
     }
-    
+
     update();
+
     switch (m_testStatus)
     {
     case FindingStop1:
@@ -340,7 +338,7 @@ void PwmFan::continueTest()
                 qDebug() << "Start finding start value...";
             }
         }
-        QTimer::singleShot(500, this, SLOT(continueTest()));
+        QTimer::singleShot(500, this, &PwmFan::continueTest);
         break;
 
     case FindingStart:
@@ -352,7 +350,7 @@ void PwmFan::continueTest()
             setMinStart(m_pwm);
             qDebug() << "Start finding stop value...";
         }
-        QTimer::singleShot(1000, this, SLOT(continueTest()));
+        QTimer::singleShot(1000, this, &PwmFan::continueTest);
         break;
 
     case FindingStop2:
@@ -360,22 +358,23 @@ void PwmFan::continueTest()
         {
             setPwm(m_pwm - 1);
             m_zeroRpm = 0;
-            QTimer::singleShot(1000, this, SLOT(continueTest()));
+            QTimer::singleShot(1000, this, &PwmFan::continueTest);
         }
         else
         {
             if (m_zeroRpm < MAX_ERRORS_FOR_RPM_ZERO)
             {
                 m_zeroRpm++;
-                QTimer::singleShot(500, this, SLOT(continueTest()));
+                QTimer::singleShot(500, this, &PwmFan::continueTest);
             }
             else
             {
                 m_testStatus = Finished;
-                emit testingChanged();
+                emit testStatusChanged();
                 m_zeroRpm = 0;
                 setMinStop(m_pwm + 5);
-                qDebug() << "Finished testing!";
+                setPwm(255);
+                qDebug() << "Finished testing PwmFan" << m_index;
             }
         }
         break;
@@ -408,4 +407,4 @@ void PwmFan::setActive(bool a)
     }
 }
 
-}
+}

+ 18 - 17
lib/src/pwmfan.h → import/src/pwmfan.h

@@ -48,11 +48,24 @@ class PwmFan : public Fan
     Q_PROPERTY(int minStart READ minStart WRITE setMinStart NOTIFY minStartChanged)
     Q_PROPERTY(int minStop READ minStop WRITE setMinStop NOTIFY minStopChanged)
     Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
-    Q_PROPERTY(bool testing READ testing NOTIFY testingChanged)
+    Q_PROPERTY(bool testing READ testing NOTIFY testStatusChanged)
+    Q_PROPERTY(TestStatus testStatus READ testStatus NOTIFY testStatusChanged)
     Q_PROPERTY(int pwmMode READ pwmMode WRITE setPwmMode NOTIFY pwmModeChanged)
+    Q_ENUMS(TestStatus)
 
 public:
 
+    enum TestStatus
+    {
+        NotStarted,
+        FindingStop1,
+        FindingStop2,
+        FindingStart,
+        Finished,
+        Cancelled,
+        Error
+    };
+
     explicit PwmFan(Hwmon *parent, uint index);
     virtual ~PwmFan();
 
@@ -66,6 +79,7 @@ public:
     int minStart() const { return m_minStart; }
     int minStop() const { return m_minStop; }
     int pwmMode() const { return m_pwmMode; }
+    TestStatus testStatus() const { return m_testStatus; }
     bool active() const;
     bool testing() const;
     bool setPwm(int pwm, bool write = true) Q_DECL_OVERRIDE;
@@ -96,17 +110,14 @@ signals:
     void minStartChanged();
     void minStopChanged();
     void activeChanged();
-    void testingChanged();
+    void testStatusChanged(bool = false);
     void pwmModeChanged();
 
 
-protected slots:
+public slots:
 
     void update() Q_DECL_OVERRIDE;
     void continueTest();
-    void handleSetPwmResult(KJob *job);
-    void handleSetPwmModeResult(KJob *job);
-    void handleTestAuthReply(KJob *job);
 
 
 private:
@@ -124,17 +135,7 @@ private:
     int m_minStop;
     int m_pwmMode;
     int m_zeroRpm;
-
-    enum
-    {
-        NotStarted,
-        FindingStop1,
-        FindingStop2,
-        FindingStart,
-        Finished,
-        Cancelled,
-        Error
-    } m_testStatus;
+    TestStatus m_testStatus;
 };
 
 }

+ 0 - 0
lib/src/pwmfanmodel.cpp → import/src/pwmfanmodel.cpp


+ 0 - 0
lib/src/pwmfanmodel.h → import/src/pwmfanmodel.h


+ 2 - 2
lib/src/sensor.cpp → import/src/sensor.cpp

@@ -31,7 +31,7 @@ Sensor::Sensor(Hwmon *parent, uint index, const QString &path) : QObject(parent)
     m_index(index),
     m_path(path)
 {
-    connect(this, SIGNAL(errorChanged(QString)), parent, SLOT(setError(QString)));
+    connect(this, &Sensor::errorChanged, parent, &Hwmon::setError);
 }
 
-}
+}

+ 1 - 1
lib/src/sensor.h → import/src/sensor.h

@@ -58,7 +58,7 @@ public slots:
 signals:
 
     void nameChanged();
-    void errorChanged(QString);
+    void errorChanged(QString, bool = false);
 
 
 protected:

+ 5 - 4
lib/src/systemdcommunicator.cpp → import/src/systemdcommunicator.cpp

@@ -268,11 +268,12 @@ bool SystemdCommunicator::dbusAction(const QString &method, const QVariantList &
             action.setArguments(map);
 
             KAuth::ExecuteJob *job = action.execute();
-            connect(job, SIGNAL(result(KJob*)), this, SLOT(handleDbusActionResult(KJob*)));
+            connect(job, &KAuth::ExecuteJob::result, this, &SystemdCommunicator::handleDbusActionResult);
             job->start();
 
             return true;
         }
+        
         setError(dbusreply.errorMessage());
         return false;
     }
@@ -292,9 +293,9 @@ void SystemdCommunicator::handleDbusActionResult(KJob *job)
             if (executeJob)
             {
                 KAuth::ExecuteJob *newJob = executeJob->action().execute();
-                connect(newJob, SIGNAL(result(KJob*)), this, SLOT(handleDbusActionResult(KJob*)));
-
-                QTimer::singleShot(50, this, [newJob] (){ newJob->start(); });
+                connect(newJob, &KAuth::ExecuteJob::result, this, &SystemdCommunicator::handleDbusActionResult);
+                
+                QTimer::singleShot(50, newJob, &KAuth::ExecuteJob::start);
                 return;
             }
         }

+ 1 - 3
lib/src/systemdcommunicator.h → import/src/systemdcommunicator.h

@@ -23,8 +23,6 @@
 
 #include <QtCore/QObject>
 
-#include "fancontrol_gui_lib_export.h"
-
 
 class QDBusInterface;
 class KJob;
@@ -32,7 +30,7 @@ class KJob;
 namespace Fancontrol
 {
 
-class FANCONTROL_GUI_LIB_EXPORT SystemdCommunicator : public QObject
+class SystemdCommunicator : public QObject
 {
     Q_OBJECT
     Q_PROPERTY(QString error READ error NOTIFY errorChanged)

+ 3 - 0
lib/src/temp.cpp → import/src/temp.cpp

@@ -70,10 +70,12 @@ QString Temp::name() const
     KConfigGroup names = KSharedConfig::openConfig(QStringLiteral("fancontrol-gui"))->group("names");
     KConfigGroup localNames = names.group(m_parent->name());
     QString name = localNames.readEntry("temp" + QString::number(m_index), QString());
+    
     if (name.isEmpty())
     {
         if (m_label.isEmpty())
             return "temp" + QString::number(m_index);
+        
         return m_label;
     }
     return name;
@@ -118,6 +120,7 @@ void Temp::update()
     int value;
     *m_valueStream >> value;
     value /= 1000;
+    
     if (value != m_value)
     {
         m_value = value;

+ 0 - 0
lib/src/temp.h → import/src/temp.h


+ 2 - 4
lib/src/tempmodel.cpp → import/src/tempmodel.cpp

@@ -31,15 +31,13 @@ namespace Fancontrol
 {
 
 TempModel::TempModel(QObject *parent) : QStringListModel(parent),
-m_unit(0)
+m_unit(QStringLiteral("°C"))
 {
 }
 
 QString TempModel::composeText(Temp *temp)
 {
-    QString suffix = m_unit == 0 ? QStringLiteral("°C") : m_unit == 2 ? QStringLiteral("°F") : QStringLiteral("K");
-
-    return temp->name() + ": " + QString::number(temp->value()) + suffix + "   (" + temp->path() + ")";
+    return temp->name() + ": " + QString::number(temp->value()) + m_unit + "   (" + temp->path() + ")";
 }
 
 

+ 3 - 3
lib/src/tempmodel.h → import/src/tempmodel.h

@@ -45,7 +45,6 @@ public:
     void setTemps(const QList<Temp *> &temps);
     void addTemps(const QList<Temp *> &temps);
     QList<QObject *> temps() const;
-    void setUnit(int unit) { if (unit != m_unit) { m_unit = unit; updateAll(); } }
 
 
 protected:
@@ -56,7 +55,8 @@ protected:
 public slots:
 
     void updateTemp(Temp *temp);
-
+    void setUnit(const QString &unit) { if (unit != m_unit) { m_unit = unit; updateAll(); } }
+    
 
 protected slots:
 
@@ -76,7 +76,7 @@ signals:
 private:
 
     QList<Temp *> m_temps;
-    int m_unit;
+    QString m_unit;
 };
 
 }

+ 8 - 6
kcm/CMakeLists.txt

@@ -1,15 +1,17 @@
-set(LIBRARIES KF5::QuickAddons
+set(LIBRARIES Qt5::Core
+              KF5::QuickAddons
               KF5::CoreAddons
-              KF5::I18n
-              fancontrol_gui_lib)
+              KF5::I18n)
 
-find_package(KF5Declarative REQUIRED)
+find_package(KF5 COMPONENTS CoreAddons Package Declarative REQUIRED)
 
 add_library(kcm_fancontrol MODULE src/fancontrolkcm.cpp)
 
 target_link_libraries(kcm_fancontrol ${LIBRARIES})
 
-install(TARGETS kcm_fancontrol DESTINATION "${CMAKE_INSTALL_PLUGINDIR}/kcms")
-install(FILES kcm_fancontrol.desktop DESTINATION ${SERVICES_INSTALL_DIR})
+install(TARGETS kcm_fancontrol DESTINATION "${KDE_INSTALL_QTPLUGINDIR}/kcms")
+install(FILES kcm_fancontrol.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
+
+kpackage_install_package(package kcm_fancontrol kcms)
 
 kcoreaddons_desktop_to_json(kcm_fancontrol "kcm_fancontrol.desktop")

+ 71 - 46
package/contents/ui/KCM.qml → kcm/package/contents/ui/KCM.qml

@@ -20,33 +20,63 @@
 
 import QtQuick 2.4
 import QtQuick.Controls 1.3
-import QtQuick.Layouts 1.1
+import QtQuick.Layouts 1.2
 import QtQuick.Dialogs 1.2
 import org.kde.kcm 1.0
-import "../scripts/units.js" as Units
+import Fancontrol.Qml 1.0 as Fancontrol
 
 
 Item {
-    property QtObject base: kcm.base
-    property QtObject loader: !!base ? base.loader : null
-    property QtObject systemdCom: !!base ? base.systemdCom : null
-    property QtObject pwmFanModel: !!base ? base.pwmFanModel : null
-    property QtObject tempModel: !!base ? base.tempModel : null
+    property QtObject loader: Fancontrol.base.loader
+    property QtObject systemdCom: Fancontrol.base.systemdCom
+    property QtObject pwmFanModel: Fancontrol.base.pwmFanModel
+    property QtObject tempModel: Fancontrol.base.tempModel
     property var locale: Qt.locale()
     property real textWidth: 0
-    property var pwmFans: pwmFanModel ? pwmFanModel.fans : null
+    property var pwmFans: pwmFanModel.fans
 
     id: root
     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
+    }
+
+    Connections {
+        target: kcm
+        onAboutToSave: {
+            Fancontrol.base.save(true);
+            if (systemdCom.serviceActive && enabledBox.checked) {
+                systemdCom.restartService();
+            } else {
+                systemdCom.serviceActive = enabledBox.checked;
+            }
+            systemdCom.serviceEnabled = enabledBox.checked;
+        }
+        onAboutToLoad: {
+            Fancontrol.base.load();
+            enabledBox.checked = systemdCom.serviceEnabled && systemdCom.serviceActive;
+        }
+        onAboutToDefault: enabledBox.checked = false
+    }
+
     ColumnLayout {
         id: noFansInfo
 
         width: parent.width
         anchors.verticalCenter: parent.verticalCenter
         spacing: 20
-        visible: pwmFanModel.count == 0
+        visible: pwmFans.length === 0
 
         Label {
             Layout.alignment: Qt.AlignCenter
@@ -57,7 +87,7 @@ Item {
 
         Button {
             Layout.alignment: Qt.AlignCenter
-            text: i18n("Detect fans")
+            text: loader.sensorsDetected ? i18n("Detect fans again") : i18n("Detect fans")
             iconName: kcm.needsAuthorization ? "dialog-password" : ""
             onClicked: loader.detectSensors()
         }
@@ -67,14 +97,12 @@ Item {
         id: enabledBox
 
         anchors.top: parent.top
-        visible: pwmFanModel.count > 0
+        visible: pwmFans.length > 0
         text: i18n("Control fans manually")
-        checked: kcm.manualControl
-        onCheckedChanged: kcm.manualControl = checked
-
-        Connections {
-            target: kcm
-            onManualControlChanged: enabledBox.checked = kcm.manualControl
+        checked: systemdCom.serviceEnabled && systemdCom.serviceActive;
+        onCheckedChanged: if (checked !== systemdCom.serviceActive || checked !== systemdCom.serviceEnabled) {
+            kcm.needsSave = true;
+            loader.restartServiceAfterTesting = checked;
         }
     }
 
@@ -88,7 +116,7 @@ Item {
         visible: enabledBox.checked
 
         RowLayout {
-            visible: enabledBox.checked && pwmFanModel.count > 0
+            visible: enabledBox.checked && pwmFans.length > 0
 
             Label {
                 text: i18n("Fan:")
@@ -113,14 +141,14 @@ Item {
         Loader {
             Layout.fillWidth: true
             Layout.fillHeight: true
-            active: !!pwmFans[fanComboBox.currentIndex]
-            sourceComponent: PwmFan {
-                unit: base.unit
+            active: pwmFans.length > fanComboBox.currentIndex && fanComboBox.currentIndex >= 0
+            sourceComponent: Fancontrol.FanItem {
+                unit: Fancontrol.base.unit
                 fan: pwmFans[fanComboBox.currentIndex]
                 systemdCom: root.systemdCom
                 tempModel: root.tempModel
-                minTemp: base.minTemp
-                maxTemp: base.maxTemp
+                minTemp: Fancontrol.base.minTemp
+                maxTemp: Fancontrol.base.maxTemp
             }
         }
     }
@@ -133,6 +161,7 @@ Item {
         anchors.bottom: settingsArea.top
         width: parent.width
         height: advancedArrow.height
+        visible: enabledBox.checked
 
         Image {
             id: advancedArrow
@@ -157,7 +186,7 @@ Item {
     ColumnLayout {
         id: settingsArea
 
-        visible: enabledBox.checked && parent.height - enabledBox.height - bodyLayout.height > height
+        visible: enabledBox.checked && parent.height - enabledBox.height - bodyLayout.height - advancedButton.height > height
         width: parent.width
         anchors.bottom: parent.bottom
         clip: true
@@ -202,7 +231,7 @@ Item {
             SpinBox {
                 Layout.minimumWidth: implicitWidth
                 Layout.fillWidth: true
-                value: !!loader ? loader.interval : 1
+                value: loader.interval
                 suffix: " " + i18np("second", "seconds", loader.interval)
                 minimumValue: 1.0
                 onValueChanged: loader.interval = value
@@ -224,10 +253,10 @@ Item {
                 Layout.fillWidth: true
                 decimals: 2
                 maximumValue: maxTempBox.value
-                minimumValue: Units.fromKelvin(0, base.unit)
-                value: Units.fromCelsius(base.minTemp, base.unit)
-                suffix: base.unit == 0 ? i18n("°C") : base.unit == 1 ? i18n("K") : i18n("°F")
-                onValueChanged: base.minTemp = value
+                minimumValue: Units.fromKelvin(0, Fancontrol.base.unit)
+                value: Units.fromCelsius(Fancontrol.base.minTemp, Fancontrol.base.unit)
+                suffix: Fancontrol.base.unit
+                onValueChanged: Fancontrol.base.minTemp = value
             }
         }
         RowLayout {
@@ -247,9 +276,9 @@ Item {
                 decimals: 2
                 maximumValue: Number.POSITIVE_INFINITY
                 minimumValue: minTempBox.value
-                value: Units.fromCelsius(base.maxTemp, base.unit)
-                suffix: base.unit == 0 ? i18n("°C") : base.unit == 1 ? i18n("K") : i18n("°F")
-                onValueChanged: base.maxTemp = value
+                value: Units.fromCelsius(Fancontrol.base.maxTemp, Fancontrol.base.unit)
+                suffix: Fancontrol.base.unit
+                onValueChanged: Fancontrol.base.maxTemp = value
             }
         }
         RowLayout {
@@ -262,12 +291,12 @@ Item {
                 horizontalAlignment: Text.AlignRight
                 Component.onCompleted: root.textWidth = Math.max(root.textWidth, contentWidth)
             }
-            OptionInput {
+            Fancontrol.OptionInput {
                 Layout.minimumWidth: implicitWidth
                 Layout.fillWidth: true
                 color: systemdCom.serviceExists ? "green" : "red"
-                value: base.serviceName
-                onTextChanged: base.serviceName = text
+                value: Fancontrol.base.serviceName
+                onTextChanged: Fancontrol.base.serviceName = text
             }
         }
         RowLayout {
@@ -280,12 +309,12 @@ Item {
                 horizontalAlignment: Text.AlignRight
                 Component.onCompleted: root.textWidth = Math.max(root.textWidth, contentWidth)
             }
-            OptionInput {
+            Fancontrol.OptionInput {
                 Layout.minimumWidth: implicitWidth
                 Layout.fillWidth: true
-                text: base.configUrl.toString().replace("file://", "")
-                color: base.configValid ? "green" : "red"
-                onTextChanged: base.configUrl = text
+                text: Fancontrol.base.configUrl.toString().replace("file://", "")
+                color: Fancontrol.base.configValid ? "green" : "red"
+                onTextChanged: Fancontrol.base.configUrl = text
             }
             Button {
                 action: loadAction
@@ -308,16 +337,12 @@ Item {
         selectExisting: true
         selectMultiple: false
 
-        onAccepted: base.configUrl = fileUrl;
+        onAccepted: Fancontrol.base.configUrl = fileUrl;
     }
 
-    ErrorDialog {
+    Fancontrol.ErrorDialog {
         id: errorDialog
         modality: Qt.ApplicationModal
-        text: loader.error
-    }
-    Connections {
-        target: loader
-        onCriticalError: errorDialog.open()
+        loader: root.loader
     }
 }

+ 2 - 2
package/metadata.desktop → kcm/package/metadata.desktop

@@ -9,8 +9,8 @@ X-KDE-PluginInfo-Author=Malte Veerman
 X-KDE-PluginInfo-Email=maldela@halloarsch.de
 X-KDE-PluginInfo-License=GPL
 X-KDE-PluginInfo-Name=kcm_fancontrol
-X-KDE-PluginInfo-Version=0.1
+X-KDE-PluginInfo-Version=0.4
 X-KDE-PluginInfo-Website=
 X-KDE-ServiceTypes=Plasma/Generic
 X-Plasma-API=declarativeappletscript 
-X-Plasma-MainScript=ui/KCM.qml
+X-Plasma-MainScript=ui/KCM.qml

+ 8 - 37
kcm/src/fancontrolkcm.cpp

@@ -22,8 +22,6 @@
 
 #include "fancontrolkcm.h"
 
-#include <QtQml/qqml.h>
-
 #include <KCoreAddons/KAboutData>
 #include <KCoreAddons/KPluginFactory>
 #include <KI18n/KLocalizedString>
@@ -33,16 +31,11 @@ K_PLUGIN_FACTORY_WITH_JSON(FancontrolKCMFactory, "kcm_fancontrol.json", register
 
 
 FancontrolKCM::FancontrolKCM(QObject *parent, const QVariantList& args)
-    : ConfigModule(parent, args),
-    m_base(new GUIBase(this)),
-    m_manualControl(false)
+    : ConfigModule(parent, args)
 {
-    if (!m_base->hasSystemdCommunicator())
-        qFatal("Fancontrol-gui-lib was compiled without systemd support!");
-
     KAboutData *about = new KAboutData(QStringLiteral("kcm_fancontrol"),
                                        i18n("Fancontrol-KCM"),
-                                       QStringLiteral("0.1"),
+                                       QStringLiteral("0.3"),
                                        i18n("KDE Fancontrol Module"),
                                        KAboutLicense::KAboutLicense::GPL_V2,
                                        QStringLiteral("Copyright (C) 2015 Malte Veerman"),
@@ -54,50 +47,28 @@ FancontrolKCM::FancontrolKCM(QObject *parent, const QVariantList& args)
 
     setButtons(Apply | Default);
     setAuthActionName(QStringLiteral("fancontrol.gui.helper.action"));
-
-    connect(m_base->loader(), &Loader::configFileChanged, [this] () { setNeedsSave(true); });
-    connect(m_base, &GUIBase::minTempChanged, [this] () { setNeedsSave(true); });
-    connect(m_base, &GUIBase::maxTempChanged, [this] () { setNeedsSave(true); });
-    connect(m_base, &GUIBase::serviceNameChanged, [this] () { setNeedsSave(true); });
-
-    qmlRegisterType<GUIBase>();
 }
 
 void FancontrolKCM::save()
 {
-    m_base->save(true);
-
-    if (m_base->systemdCommunicator()->serviceActive() && m_manualControl)
-        m_base->systemdCommunicator()->restartService();
-    else
-        m_base->systemdCommunicator()->setServiceActive(m_manualControl);
-
-    m_base->systemdCommunicator()->setServiceEnabled(m_manualControl);
+    emit aboutToSave();
+    
     setNeedsSave(false);
 }
 
 void FancontrolKCM::load()
 {
-    m_base->load();
-    setManualControl(m_base->systemdCommunicator()->serviceEnabled() || m_base->systemdCommunicator()->serviceActive());
+    emit aboutToLoad();
+    
     setNeedsSave(false);
 }
 
 void FancontrolKCM::defaults()
 {
-    setManualControl(false);
+    emit aboutToDefault();
+    
     setNeedsSave(true);
 }
 
-void FancontrolKCM::setManualControl(bool manualControl)
-{
-    if (m_manualControl != manualControl)
-    {
-        m_manualControl = manualControl;
-        emit manualControlChanged();
-        setNeedsSave(true);
-    }
-}
-
 
 #include "fancontrolkcm.moc"

+ 3 - 16
kcm/src/fancontrolkcm.h

@@ -25,26 +25,17 @@
 
 #include <KDeclarative/KQuickAddons/ConfigModule>
 
-#include "lib/src/guibase.h"
-
 
 using namespace KQuickAddons;
-using namespace Fancontrol;
 
 class FancontrolKCM : public ConfigModule
 {
     Q_OBJECT
-    Q_PROPERTY(GUIBase *base READ base CONSTANT)
-    Q_PROPERTY(bool manualControl READ manualControl WRITE setManualControl NOTIFY manualControlChanged)
     
 public:
     
     explicit FancontrolKCM(QObject *parent, const QVariantList &args = QVariantList());
     
-    GUIBase *base() const { return m_base; }
-    bool manualControl() const { return m_manualControl; }
-    void setManualControl(bool manualControl);
-    
     
 public slots:
     
@@ -55,13 +46,9 @@ public slots:
     
 signals:
     
-    void manualControlChanged();
-    
-
-private:
-    
-    GUIBase *const m_base;
-    bool m_manualControl;
+    void aboutToSave();
+    void aboutToLoad();
+    void aboutToDefault();
 };
 
 #endif // FANCONTROLKCM_H

+ 179 - 158
po/de/kcm_fancontrol.po

@@ -6,8 +6,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: fancontrol-gui\n"
 "Report-Msgid-Bugs-To: http://github.com/maldela/fancontrol-gui\n"
-"POT-Creation-Date: 2016-01-09 16:51+0100\n"
-"PO-Revision-Date: 2016-01-03 15:45+0100\n"
+"POT-Creation-Date: 2016-03-28 22:10+0200\n"
+"PO-Revision-Date: 2016-03-28 22:12+0100\n"
 "Last-Translator: Malte Veerman <maldela@halloarsch.de>\n"
 "Language-Team: German <kde-i18n-de@kde.org>\n"
 "Language: de_DE\n"
@@ -17,249 +17,261 @@ msgstr ""
 "X-Generator: Lokalize 2.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: fancontrol-gui/src/main.cpp:40 package/contents/ui/Application.qml:29
+#: fancontrol-gui/package/contents/ui/Application.qml:30
+#: fancontrol-gui/src/main.cpp:44
 msgid "Fancontrol-GUI"
 msgstr "Fancontrol-GUI"
 
-#: fancontrol-gui/src/main.cpp:42
-msgid "Graphical user interface for fancontrol"
-msgstr "Graphische Benutzeroberfläche für fanontrol"
-
-#: fancontrol-gui/src/main.cpp:48 kcm/src/fancontrolkcm.cpp:52
-msgid "Malte Veerman"
-msgstr "Malte Veerman"
-
-#: fancontrol-gui/src/main.cpp:48 kcm/src/fancontrolkcm.cpp:52
-msgid "Main Developer"
-msgstr "Hauptentwickler"
-
-#: helper/src/helper.cpp:136
-msgid "This action does not exist!"
-msgstr "Die Aktion existiert nicht!"
-
-#: kcm/src/fancontrolkcm.cpp:44
-msgid "Fancontrol-KCM"
-msgstr "Fancontrol-KCM"
-
-#: kcm/src/fancontrolkcm.cpp:46
-msgid "KDE Fancontrol Module"
-msgstr "KDE Fancontrol Modul"
-
-#: lib/src/loader.cpp:68
-msgid "%1 is not readable!"
-msgstr "%1 ist nicht lesbar!"
-
-#: lib/src/loader.cpp:73 lib/src/loader.cpp:295
-msgid "%1 does not exist!"
-msgstr "%1 existiert nicht!"
-
-#: lib/src/loader.cpp:240 lib/src/loader.cpp:474
-msgid "%1 is not a local file!"
-msgstr "%1 ist keine lokale Datei!"
-
-#: lib/src/loader.cpp:246
-msgid "%1 is not a valid url!"
-msgstr "%1 ist keine gültige Url!"
-
-#: lib/src/loader.cpp:344
-msgid ""
-"Unable to parse interval line: \n"
-" %1"
-msgstr ""
-"Konnte Zeile nicht verstehen: \n"
-"%1"
-
-#: lib/src/loader.cpp:392
-msgid "Can not parse %1"
-msgstr "%1 konnte nicht verstanden werden"
-
-#: lib/src/loader.cpp:402
-msgid "Invalid config file!"
-msgstr "Ungültige Konfigurationsdatei!"
-
-#: lib/src/loader.cpp:445
-msgid ""
-"Unrecognized line in config:\n"
-"%1"
-msgstr ""
-"Unbekannte Zeile in Konfiguration:\n"
-"%1"
-
-#: lib/src/pwmfan.cpp:206
-msgid "Could not set pwm: "
-msgstr "Konnte pwm nicht ändern:"
-
-#: lib/src/pwmfan.cpp:254
-msgid "Could not set pwm mode: "
-msgstr "Konnte pwm Modus nicht ändern:"
-
-#: lib/src/pwmfan.cpp:280
-msgid "Authorization error: "
-msgstr "Authorisationsfehler:"
-
-#: lib/src/systemdcommunicator.cpp:167
-msgid "Service %1 doesn't exist"
-msgstr "Service %1 existiert nicht!"
-
-#: lib/src/systemdcommunicator.cpp:315
-msgid "Service does not exist"
-msgstr "Service existiert nicht!"
-
-#: package/contents/ui/Application.qml:43
+#: fancontrol-gui/package/contents/ui/Application.qml:47
 msgid "File"
 msgstr "Datei"
 
-#: package/contents/ui/Application.qml:47
-#: package/contents/ui/Application.qml:161
+#: fancontrol-gui/package/contents/ui/Application.qml:51
+#: fancontrol-gui/package/contents/ui/Application.qml:156
 msgid "Save configuration file as"
 msgstr "Konfigurationsdatei speichern unter..."
 
-#: package/contents/ui/Application.qml:52
+#: fancontrol-gui/package/contents/ui/Application.qml:56
 msgid "Exit"
 msgstr "Schließen"
 
-#: package/contents/ui/Application.qml:73
+#: fancontrol-gui/package/contents/ui/Application.qml:77
 msgid "Restart fancontrol"
 msgstr "Fancontrol neustarten"
 
-#: package/contents/ui/Application.qml:73
+#: fancontrol-gui/package/contents/ui/Application.qml:77
 msgid "Start fancontrol"
 msgstr "Fancontrol starten"
 
-#: package/contents/ui/Application.qml:82
+#: fancontrol-gui/package/contents/ui/Application.qml:86
 msgid "Stop fancontrol"
 msgstr "Fancontrol stoppen"
 
-#: package/contents/ui/Application.qml:98
+#: fancontrol-gui/package/contents/ui/Application.qml:102
 msgid "Sensors"
 msgstr "Sensoren"
 
-#: package/contents/ui/Application.qml:104
+#: fancontrol-gui/package/contents/ui/Application.qml:106
 msgid "PwmFans"
 msgstr "PwmLüfter"
 
-#: package/contents/ui/Application.qml:110
+#: fancontrol-gui/package/contents/ui/Application.qml:110
 msgid "Configfile"
 msgstr "Konfigurationsdatei"
 
-#: package/contents/ui/Application.qml:117
+#: fancontrol-gui/package/contents/ui/Application.qml:115
 msgid "Settings"
 msgstr "Einstellungen"
 
-#: package/contents/ui/Application.qml:134
-#: package/contents/ui/Application.qml:137 package/contents/ui/KCM.qml:252
+#: fancontrol-gui/package/contents/ui/Application.qml:129
+#: fancontrol-gui/package/contents/ui/Application.qml:132
+#: kcm/package/contents/ui/KCM.qml:329
 msgid "Load configuration file"
 msgstr "Konfigurationsdatei öffnen"
 
-#: package/contents/ui/Application.qml:142
-#: package/contents/ui/Application.qml:145
+#: fancontrol-gui/package/contents/ui/Application.qml:137
+#: fancontrol-gui/package/contents/ui/Application.qml:140
 msgid "Save configuration file"
 msgstr "Konfigurationsdatei speichern"
 
-#: package/contents/ui/Application.qml:151 package/contents/ui/KCM.qml:258
+#: fancontrol-gui/package/contents/ui/Application.qml:146
+#: kcm/package/contents/ui/KCM.qml:335
 msgid "Please choose a configuration file"
 msgstr "Konfigurationsdatei auswählen"
 
-#: package/contents/ui/ErrorDialog.qml:29
-msgid "Error"
-msgstr "Fehler"
+#: fancontrol-gui/package/contents/ui/PwmFansTab.qml:43
+#: kcm/package/contents/ui/KCM.qml:122
+msgid "Fan:"
+msgstr "Lüfter:"
 
-#: package/contents/ui/KCM.qml:52 package/contents/ui/PwmFansTab.qml:83
+#: fancontrol-gui/package/contents/ui/PwmFansTab.qml:83
+#: kcm/package/contents/ui/KCM.qml:83
 msgid "There are no pwm capable fans in your system."
 msgstr "Es gibt keine pwm-fähigen Lüfter in ihrem System."
 
-#: package/contents/ui/KCM.qml:59 package/contents/ui/KCM.qml:102
-#: package/contents/ui/PwmFansTab.qml:96
+#: fancontrol-gui/package/contents/ui/PwmFansTab.qml:96
+#: kcm/package/contents/ui/KCM.qml:90
+msgid "Detect fans again"
+msgstr "Finde Lüfter nochmal"
+
+#: fancontrol-gui/package/contents/ui/PwmFansTab.qml:96
+#: kcm/package/contents/ui/KCM.qml:90 kcm/package/contents/ui/KCM.qml:135
 msgid "Detect fans"
 msgstr "Finde Lüfter"
 
-#: package/contents/ui/KCM.qml:69
-msgid "Control fans manually"
-msgstr "Lüfter manuell kontrollieren"
-
-#: package/contents/ui/KCM.qml:89 package/contents/ui/PwmFansTab.qml:43
-msgid "Fan:"
-msgstr "Lüfter:"
-
-#: package/contents/ui/KCM.qml:135
-msgid "Advanced settings"
-msgstr "Erweiterte Einstellungen"
+#: fancontrol-gui/package/contents/ui/SensorsTab.qml:77
+#: import/qml/StatusPoint.qml:94
+msgid "rpm"
+msgstr "rpm"
 
-#: package/contents/ui/KCM.qml:150 package/contents/ui/SettingsTab.qml:52
+#: fancontrol-gui/package/contents/ui/SettingsTab.qml:50
+#: kcm/package/contents/ui/KCM.qml:227
 msgid "Interval:"
 msgstr "Intervall:"
 
-#: package/contents/ui/KCM.qml:158 package/contents/ui/SettingsTab.qml:60
+#: fancontrol-gui/package/contents/ui/SettingsTab.qml:58
+#: kcm/package/contents/ui/KCM.qml:235
 msgid "second"
 msgid_plural "seconds"
 msgstr[0] "Sekunde"
 msgstr[1] "Sekunden"
 
-#: package/contents/ui/KCM.qml:169 package/contents/ui/SettingsTab.qml:75
+#: fancontrol-gui/package/contents/ui/SettingsTab.qml:69
+#: kcm/package/contents/ui/KCM.qml:246
 msgid "Minimum temperature for fan graphs:"
 msgstr "Minimale Temperatur für Lüftergraphen:"
 
-#: package/contents/ui/KCM.qml:181 package/contents/ui/KCM.qml:203
-#: package/contents/ui/SettingsTab.qml:87
-#: package/contents/ui/SettingsTab.qml:113
-msgid "°C"
-msgstr "°C"
-
-#: package/contents/ui/KCM.qml:181 package/contents/ui/KCM.qml:203
-#: package/contents/ui/SettingsTab.qml:87
-#: package/contents/ui/SettingsTab.qml:113
-msgid "K"
-msgstr "K"
-
-#: package/contents/ui/KCM.qml:181 package/contents/ui/KCM.qml:203
-#: package/contents/ui/SettingsTab.qml:87
-#: package/contents/ui/SettingsTab.qml:113
-msgid "°F"
-msgstr "°F"
-
-#: package/contents/ui/KCM.qml:191 package/contents/ui/SettingsTab.qml:101
+#: fancontrol-gui/package/contents/ui/SettingsTab.qml:94
+#: kcm/package/contents/ui/KCM.qml:268
 msgid "Maximum temperature for fan graphs:"
 msgstr "Maximale Temperatur für Lüftergraphen:"
 
-#: package/contents/ui/KCM.qml:213 package/contents/ui/SettingsTab.qml:129
+#: fancontrol-gui/package/contents/ui/SettingsTab.qml:121
+#: kcm/package/contents/ui/KCM.qml:290
 msgid "Name of the fancontrol systemd service:"
 msgstr "Name des fancontrol systemd services:"
 
-#: package/contents/ui/KCM.qml:231
-msgid "Path to the fancontrol config file:"
-msgstr "Pfad der fancontrol Konfigurationsdatei:"
+#: fancontrol-gui/package/contents/ui/SettingsTab.qml:142
+msgid "Fancontrol systemd service autostart:"
+msgstr "Fancontrol systemd service Autostart:"
 
-#: package/contents/ui/PwmFan.qml:352
+#: fancontrol-gui/src/main.cpp:46
+msgid "Graphical user interface for fancontrol"
+msgstr "Graphische Benutzeroberfläche für fanontrol"
+
+#: fancontrol-gui/src/main.cpp:52 kcm/src/fancontrolkcm.cpp:45
+msgid "Malte Veerman"
+msgstr "Malte Veerman"
+
+#: fancontrol-gui/src/main.cpp:52 kcm/src/fancontrolkcm.cpp:45
+msgid "Main Developer"
+msgstr "Hauptentwickler"
+
+#: helper/src/helper.cpp:137
+msgid "This action does not exist!"
+msgstr "Die Aktion existiert nicht!"
+
+#: import/qml/ErrorDialog.qml:32
+msgid "Error"
+msgstr "Fehler"
+
+#: import/qml/FanItem.qml:135
+msgid "%1%"
+msgstr "%1%"
+
+#: import/qml/FanItem.qml:157
+msgid "%1"
+msgstr "%1"
+
+#: import/qml/FanItem.qml:359
 msgid "Controlled by:"
 msgstr "Kontrolliert von:"
 
-#: package/contents/ui/PwmFan.qml:400
+#: import/qml/FanItem.qml:407
 msgid "Turn Fan off if temp < MINTEMP"
 msgstr "Lüfter abschalten, wenn MINTEMP unterschritten"
 
-#: package/contents/ui/PwmFan.qml:424
+#: import/qml/FanItem.qml:431
 msgid "Pwm value for fan to start:"
 msgstr "Wert ab dem der Lüfter startet:"
 
-#: package/contents/ui/PwmFan.qml:435
+#: import/qml/FanItem.qml:442
 msgid "%"
 msgstr "%"
 
-#: package/contents/ui/PwmFan.qml:454
+#: import/qml/FanItem.qml:460
 msgid "Abort test"
 msgstr "Test abbrechen"
 
-#: package/contents/ui/PwmFan.qml:454
+#: import/qml/FanItem.qml:460
 msgid "Test start and stop values"
 msgstr "Start und Stopwerte testen"
 
-#: package/contents/ui/SettingsTab.qml:154
-msgid "Fancontrol systemd service autostart:"
-msgstr "Fancontrol systemd service Autostart:"
+#: import/src/loader.cpp:71
+msgid "%1 is not readable!"
+msgstr "%1 ist nicht lesbar!"
 
-#: package/contents/ui/StatusPoint.qml:96
-msgid "rpm"
-msgstr "rpm"
+#: import/src/loader.cpp:76 import/src/loader.cpp:310
+msgid "%1 does not exist!"
+msgstr "%1 existiert nicht!"
+
+#: import/src/loader.cpp:243 import/src/loader.cpp:489
+msgid "%1 is not a local file!"
+msgstr "%1 ist keine lokale Datei!"
+
+#: import/src/loader.cpp:249
+msgid "%1 is not a valid url!"
+msgstr "%1 ist keine gültige Url!"
+
+#: import/src/loader.cpp:303 import/src/loader.cpp:528
+#: import/src/loader.cpp:726 import/src/pwmfan.cpp:204
+#: import/src/pwmfan.cpp:250 import/src/pwmfan.cpp:277
+msgid "Action not supported! Try running the application as root."
+msgstr "Aktion nicht unterstützt! Starten sie die Anwendung als root."
+
+#: import/src/loader.cpp:359
+msgid ""
+"Unable to parse interval line: \n"
+" %1"
+msgstr ""
+"Konnte Zeile nicht verstehen: \n"
+"%1"
+
+#: import/src/loader.cpp:407
+msgid "Can not parse %1"
+msgstr "%1 konnte nicht verstanden werden"
+
+#: import/src/loader.cpp:417
+msgid "Invalid config file!"
+msgstr "Ungültige Konfigurationsdatei!"
+
+#: import/src/loader.cpp:460
+msgid ""
+"Unrecognized line in config:\n"
+"%1"
+msgstr ""
+"Unbekannte Zeile in Konfiguration:\n"
+"%1"
+
+#: import/src/pwmfan.cpp:199
+msgid "Could not set pwm: "
+msgstr "Konnte pwm nicht ändern:"
+
+#: import/src/pwmfan.cpp:245
+msgid "Could not set pwm mode: "
+msgstr "Konnte pwm Modus nicht ändern:"
+
+#: import/src/pwmfan.cpp:269
+msgid "Authorization error: "
+msgstr "Authorisationsfehler:"
+
+#: import/src/systemdcommunicator.cpp:167
+msgid "Service %1 doesn't exist"
+msgstr "Service %1 existiert nicht!"
+
+#: import/src/systemdcommunicator.cpp:316
+msgid "Service does not exist"
+msgstr "Service existiert nicht!"
+
+#: kcm/package/contents/ui/KCM.qml:101
+msgid "Control fans manually"
+msgstr "Lüfter manuell kontrollieren"
+
+#: kcm/package/contents/ui/KCM.qml:177
+msgid "Advanced settings"
+msgstr "Erweiterte Einstellungen"
+
+#: kcm/package/contents/ui/KCM.qml:308
+msgid "Path to the fancontrol config file:"
+msgstr "Pfad der fancontrol Konfigurationsdatei:"
+
+#: kcm/src/fancontrolkcm.cpp:37
+msgid "Fancontrol-KCM"
+msgstr "Fancontrol-KCM"
+
+#: kcm/src/fancontrolkcm.cpp:39
+msgid "KDE Fancontrol Module"
+msgstr "KDE Fancontrol Modul"
 
 #: po/rc.cpp:1 rc.cpp:1
 msgctxt "NAME OF TRANSLATORS"
@@ -271,6 +283,15 @@ msgctxt "EMAIL OF TRANSLATORS"
 msgid "Your emails"
 msgstr "maldela@halloarsch.de"
 
+#~ msgid "°C"
+#~ msgstr "°C"
+
+#~ msgid "K"
+#~ msgstr "K"
+
+#~ msgid "°F"
+#~ msgstr "°F"
+
 #~ msgid "seconds"
 #~ msgstr "Sekunden"
 

+ 142 - 130
po/kcm_fancontrol.pot

@@ -8,254 +8,266 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: http://github.com/maldela/fancontrol-gui\n"
-"POT-Creation-Date: 2016-01-09 16:51+0100\n"
+"POT-Creation-Date: 2016-03-28 22:10+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language: \n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
 
-#: fancontrol-gui/src/main.cpp:40 package/contents/ui/Application.qml:29
+#: fancontrol-gui/package/contents/ui/Application.qml:30
+#: fancontrol-gui/src/main.cpp:44
 msgid "Fancontrol-GUI"
 msgstr ""
 
-#: fancontrol-gui/src/main.cpp:42
-msgid "Graphical user interface for fancontrol"
+#: fancontrol-gui/package/contents/ui/Application.qml:47
+msgid "File"
 msgstr ""
 
-#: fancontrol-gui/src/main.cpp:48 kcm/src/fancontrolkcm.cpp:52
-msgid "Malte Veerman"
+#: fancontrol-gui/package/contents/ui/Application.qml:51
+#: fancontrol-gui/package/contents/ui/Application.qml:156
+msgid "Save configuration file as"
 msgstr ""
 
-#: fancontrol-gui/src/main.cpp:48 kcm/src/fancontrolkcm.cpp:52
-msgid "Main Developer"
+#: fancontrol-gui/package/contents/ui/Application.qml:56
+msgid "Exit"
 msgstr ""
 
-#: helper/src/helper.cpp:136
-msgid "This action does not exist!"
+#: fancontrol-gui/package/contents/ui/Application.qml:77
+msgid "Restart fancontrol"
 msgstr ""
 
-#: kcm/src/fancontrolkcm.cpp:44
-msgid "Fancontrol-KCM"
+#: fancontrol-gui/package/contents/ui/Application.qml:77
+msgid "Start fancontrol"
 msgstr ""
 
-#: kcm/src/fancontrolkcm.cpp:46
-msgid "KDE Fancontrol Module"
+#: fancontrol-gui/package/contents/ui/Application.qml:86
+msgid "Stop fancontrol"
 msgstr ""
 
-#: lib/src/loader.cpp:68
-msgid "%1 is not readable!"
+#: fancontrol-gui/package/contents/ui/Application.qml:102
+msgid "Sensors"
 msgstr ""
 
-#: lib/src/loader.cpp:73 lib/src/loader.cpp:295
-msgid "%1 does not exist!"
+#: fancontrol-gui/package/contents/ui/Application.qml:106
+msgid "PwmFans"
 msgstr ""
 
-#: lib/src/loader.cpp:240 lib/src/loader.cpp:474
-msgid "%1 is not a local file!"
+#: fancontrol-gui/package/contents/ui/Application.qml:110
+msgid "Configfile"
 msgstr ""
 
-#: lib/src/loader.cpp:246
-msgid "%1 is not a valid url!"
+#: fancontrol-gui/package/contents/ui/Application.qml:115
+msgid "Settings"
 msgstr ""
 
-#: lib/src/loader.cpp:344
-msgid ""
-"Unable to parse interval line: \n"
-" %1"
+#: fancontrol-gui/package/contents/ui/Application.qml:129
+#: fancontrol-gui/package/contents/ui/Application.qml:132
+#: kcm/package/contents/ui/KCM.qml:329
+msgid "Load configuration file"
 msgstr ""
 
-#: lib/src/loader.cpp:392
-msgid "Can not parse %1"
+#: fancontrol-gui/package/contents/ui/Application.qml:137
+#: fancontrol-gui/package/contents/ui/Application.qml:140
+msgid "Save configuration file"
 msgstr ""
 
-#: lib/src/loader.cpp:402
-msgid "Invalid config file!"
+#: fancontrol-gui/package/contents/ui/Application.qml:146
+#: kcm/package/contents/ui/KCM.qml:335
+msgid "Please choose a configuration file"
 msgstr ""
 
-#: lib/src/loader.cpp:445
-msgid ""
-"Unrecognized line in config:\n"
-"%1"
+#: fancontrol-gui/package/contents/ui/PwmFansTab.qml:43
+#: kcm/package/contents/ui/KCM.qml:122
+msgid "Fan:"
 msgstr ""
 
-#: lib/src/pwmfan.cpp:206
-msgid "Could not set pwm: "
+#: fancontrol-gui/package/contents/ui/PwmFansTab.qml:83
+#: kcm/package/contents/ui/KCM.qml:83
+msgid "There are no pwm capable fans in your system."
 msgstr ""
 
-#: lib/src/pwmfan.cpp:254
-msgid "Could not set pwm mode: "
+#: fancontrol-gui/package/contents/ui/PwmFansTab.qml:96
+#: kcm/package/contents/ui/KCM.qml:90
+msgid "Detect fans again"
 msgstr ""
 
-#: lib/src/pwmfan.cpp:280
-msgid "Authorization error: "
+#: fancontrol-gui/package/contents/ui/PwmFansTab.qml:96
+#: kcm/package/contents/ui/KCM.qml:90 kcm/package/contents/ui/KCM.qml:135
+msgid "Detect fans"
 msgstr ""
 
-#: lib/src/systemdcommunicator.cpp:167
-msgid "Service %1 doesn't exist"
+#: fancontrol-gui/package/contents/ui/SensorsTab.qml:77
+#: import/qml/StatusPoint.qml:94
+msgid "rpm"
 msgstr ""
 
-#: lib/src/systemdcommunicator.cpp:315
-msgid "Service does not exist"
+#: fancontrol-gui/package/contents/ui/SettingsTab.qml:50
+#: kcm/package/contents/ui/KCM.qml:227
+msgid "Interval:"
 msgstr ""
 
-#: package/contents/ui/Application.qml:43
-msgid "File"
+#: fancontrol-gui/package/contents/ui/SettingsTab.qml:58
+#: kcm/package/contents/ui/KCM.qml:235
+msgid "second"
+msgid_plural "seconds"
+msgstr[0] ""
+msgstr[1] ""
+
+#: fancontrol-gui/package/contents/ui/SettingsTab.qml:69
+#: kcm/package/contents/ui/KCM.qml:246
+msgid "Minimum temperature for fan graphs:"
 msgstr ""
 
-#: package/contents/ui/Application.qml:47
-#: package/contents/ui/Application.qml:161
-msgid "Save configuration file as"
+#: fancontrol-gui/package/contents/ui/SettingsTab.qml:94
+#: kcm/package/contents/ui/KCM.qml:268
+msgid "Maximum temperature for fan graphs:"
 msgstr ""
 
-#: package/contents/ui/Application.qml:52
-msgid "Exit"
+#: fancontrol-gui/package/contents/ui/SettingsTab.qml:121
+#: kcm/package/contents/ui/KCM.qml:290
+msgid "Name of the fancontrol systemd service:"
 msgstr ""
 
-#: package/contents/ui/Application.qml:73
-msgid "Restart fancontrol"
+#: fancontrol-gui/package/contents/ui/SettingsTab.qml:142
+msgid "Fancontrol systemd service autostart:"
 msgstr ""
 
-#: package/contents/ui/Application.qml:73
-msgid "Start fancontrol"
+#: fancontrol-gui/src/main.cpp:46
+msgid "Graphical user interface for fancontrol"
 msgstr ""
 
-#: package/contents/ui/Application.qml:82
-msgid "Stop fancontrol"
+#: fancontrol-gui/src/main.cpp:52 kcm/src/fancontrolkcm.cpp:45
+msgid "Malte Veerman"
 msgstr ""
 
-#: package/contents/ui/Application.qml:98
-msgid "Sensors"
+#: fancontrol-gui/src/main.cpp:52 kcm/src/fancontrolkcm.cpp:45
+msgid "Main Developer"
 msgstr ""
 
-#: package/contents/ui/Application.qml:104
-msgid "PwmFans"
+#: helper/src/helper.cpp:137
+msgid "This action does not exist!"
 msgstr ""
 
-#: package/contents/ui/Application.qml:110
-msgid "Configfile"
+#: import/qml/ErrorDialog.qml:32
+msgid "Error"
 msgstr ""
 
-#: package/contents/ui/Application.qml:117
-msgid "Settings"
+#: import/qml/FanItem.qml:135
+msgid "%1%"
 msgstr ""
 
-#: package/contents/ui/Application.qml:134
-#: package/contents/ui/Application.qml:137 package/contents/ui/KCM.qml:252
-msgid "Load configuration file"
+#: import/qml/FanItem.qml:157
+msgid "%1"
 msgstr ""
 
-#: package/contents/ui/Application.qml:142
-#: package/contents/ui/Application.qml:145
-msgid "Save configuration file"
+#: import/qml/FanItem.qml:359
+msgid "Controlled by:"
 msgstr ""
 
-#: package/contents/ui/Application.qml:151 package/contents/ui/KCM.qml:258
-msgid "Please choose a configuration file"
+#: import/qml/FanItem.qml:407
+msgid "Turn Fan off if temp < MINTEMP"
 msgstr ""
 
-#: package/contents/ui/ErrorDialog.qml:29
-msgid "Error"
+#: import/qml/FanItem.qml:431
+msgid "Pwm value for fan to start:"
 msgstr ""
 
-#: package/contents/ui/KCM.qml:52 package/contents/ui/PwmFansTab.qml:83
-msgid "There are no pwm capable fans in your system."
+#: import/qml/FanItem.qml:442
+msgid "%"
 msgstr ""
 
-#: package/contents/ui/KCM.qml:59 package/contents/ui/KCM.qml:102
-#: package/contents/ui/PwmFansTab.qml:96
-msgid "Detect fans"
+#: import/qml/FanItem.qml:460
+msgid "Abort test"
 msgstr ""
 
-#: package/contents/ui/KCM.qml:69
-msgid "Control fans manually"
+#: import/qml/FanItem.qml:460
+msgid "Test start and stop values"
 msgstr ""
 
-#: package/contents/ui/KCM.qml:89 package/contents/ui/PwmFansTab.qml:43
-msgid "Fan:"
+#: import/src/loader.cpp:71
+msgid "%1 is not readable!"
 msgstr ""
 
-#: package/contents/ui/KCM.qml:135
-msgid "Advanced settings"
+#: import/src/loader.cpp:76 import/src/loader.cpp:310
+msgid "%1 does not exist!"
 msgstr ""
 
-#: package/contents/ui/KCM.qml:150 package/contents/ui/SettingsTab.qml:52
-msgid "Interval:"
+#: import/src/loader.cpp:243 import/src/loader.cpp:489
+msgid "%1 is not a local file!"
 msgstr ""
 
-#: package/contents/ui/KCM.qml:158 package/contents/ui/SettingsTab.qml:60
-msgid "second"
-msgid_plural "seconds"
-msgstr[0] ""
-msgstr[1] ""
+#: import/src/loader.cpp:249
+msgid "%1 is not a valid url!"
+msgstr ""
 
-#: package/contents/ui/KCM.qml:169 package/contents/ui/SettingsTab.qml:75
-msgid "Minimum temperature for fan graphs:"
+#: import/src/loader.cpp:303 import/src/loader.cpp:528
+#: import/src/loader.cpp:726 import/src/pwmfan.cpp:204
+#: import/src/pwmfan.cpp:250 import/src/pwmfan.cpp:277
+msgid "Action not supported! Try running the application as root."
 msgstr ""
 
-#: package/contents/ui/KCM.qml:181 package/contents/ui/KCM.qml:203
-#: package/contents/ui/SettingsTab.qml:87
-#: package/contents/ui/SettingsTab.qml:113
-msgid "°C"
+#: import/src/loader.cpp:359
+msgid ""
+"Unable to parse interval line: \n"
+" %1"
 msgstr ""
 
-#: package/contents/ui/KCM.qml:181 package/contents/ui/KCM.qml:203
-#: package/contents/ui/SettingsTab.qml:87
-#: package/contents/ui/SettingsTab.qml:113
-msgid "K"
+#: import/src/loader.cpp:407
+msgid "Can not parse %1"
 msgstr ""
 
-#: package/contents/ui/KCM.qml:181 package/contents/ui/KCM.qml:203
-#: package/contents/ui/SettingsTab.qml:87
-#: package/contents/ui/SettingsTab.qml:113
-msgid "°F"
+#: import/src/loader.cpp:417
+msgid "Invalid config file!"
 msgstr ""
 
-#: package/contents/ui/KCM.qml:191 package/contents/ui/SettingsTab.qml:101
-msgid "Maximum temperature for fan graphs:"
+#: import/src/loader.cpp:460
+msgid ""
+"Unrecognized line in config:\n"
+"%1"
 msgstr ""
 
-#: package/contents/ui/KCM.qml:213 package/contents/ui/SettingsTab.qml:129
-msgid "Name of the fancontrol systemd service:"
+#: import/src/pwmfan.cpp:199
+msgid "Could not set pwm: "
 msgstr ""
 
-#: package/contents/ui/KCM.qml:231
-msgid "Path to the fancontrol config file:"
+#: import/src/pwmfan.cpp:245
+msgid "Could not set pwm mode: "
 msgstr ""
 
-#: package/contents/ui/PwmFan.qml:352
-msgid "Controlled by:"
+#: import/src/pwmfan.cpp:269
+msgid "Authorization error: "
 msgstr ""
 
-#: package/contents/ui/PwmFan.qml:400
-msgid "Turn Fan off if temp < MINTEMP"
+#: import/src/systemdcommunicator.cpp:167
+msgid "Service %1 doesn't exist"
 msgstr ""
 
-#: package/contents/ui/PwmFan.qml:424
-msgid "Pwm value for fan to start:"
+#: import/src/systemdcommunicator.cpp:316
+msgid "Service does not exist"
 msgstr ""
 
-#: package/contents/ui/PwmFan.qml:435
-msgid "%"
+#: kcm/package/contents/ui/KCM.qml:101
+msgid "Control fans manually"
 msgstr ""
 
-#: package/contents/ui/PwmFan.qml:454
-msgid "Abort test"
+#: kcm/package/contents/ui/KCM.qml:177
+msgid "Advanced settings"
 msgstr ""
 
-#: package/contents/ui/PwmFan.qml:454
-msgid "Test start and stop values"
+#: kcm/package/contents/ui/KCM.qml:308
+msgid "Path to the fancontrol config file:"
 msgstr ""
 
-#: package/contents/ui/SettingsTab.qml:154
-msgid "Fancontrol systemd service autostart:"
+#: kcm/src/fancontrolkcm.cpp:37
+msgid "Fancontrol-KCM"
 msgstr ""
 
-#: package/contents/ui/StatusPoint.qml:96
-msgid "rpm"
+#: kcm/src/fancontrolkcm.cpp:39
+msgid "KDE Fancontrol Module"
 msgstr ""
 
 #: po/rc.cpp:1 rc.cpp:1