KCM.qml 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * Copyright (C) 2015 Malte Veerman <maldela@halloarsch.de>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public License along
  15. * with this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. *
  18. */
  19. import QtQuick 2.4
  20. import QtQuick.Controls 1.3
  21. import QtQuick.Layouts 1.1
  22. import QtQuick.Dialogs 1.2
  23. import org.kde.kcm 1.0
  24. import "../scripts/units.js" as Units
  25. Item {
  26. property QtObject base: kcm.base
  27. property QtObject loader: !!base ? base.loader : null
  28. property QtObject systemdCom: !!base ? base.systemdCom : null
  29. property QtObject pwmFanModel: !!base ? base.pwmFanModel : null
  30. property QtObject tempModel: !!base ? base.tempModel : null
  31. property var locale: Qt.locale()
  32. property real textWidth: 0
  33. property var pwmFans: pwmFanModel ? pwmFanModel.fans : null
  34. id: root
  35. implicitWidth: 1024
  36. implicitHeight: 768
  37. ColumnLayout {
  38. id: noFansInfo
  39. width: parent.width
  40. anchors.verticalCenter: parent.verticalCenter
  41. spacing: 20
  42. visible: pwmFanModel.count == 0
  43. Label {
  44. Layout.alignment: Qt.AlignCenter
  45. text: i18n("There are no pwm capable fans in your system.")
  46. font.pointSize: 14
  47. font.bold: true
  48. }
  49. Button {
  50. Layout.alignment: Qt.AlignCenter
  51. text: i18n("Detect fans")
  52. iconName: kcm.needsAuthorization ? "dialog-password" : ""
  53. onClicked: loader.detectSensors()
  54. }
  55. }
  56. CheckBox {
  57. id: enabledBox
  58. visible: pwmFanModel.count > 0
  59. Layout.alignment: Qt.AlignLeft | Qt.AlignTop
  60. text: i18n("Control fans manually")
  61. checked: kcm.manualControl
  62. onCheckedChanged: kcm.manualControl = checked
  63. Connections {
  64. target: kcm
  65. onManualControlChanged: enabledBox.checked = kcm.manualControl
  66. }
  67. }
  68. ColumnLayout {
  69. width: parent.width
  70. anchors.bottom: parent.bottom
  71. anchors.top: enabledBox.bottom
  72. visible: enabledBox.checked
  73. RowLayout {
  74. visible: enabledBox.checked && pwmFanModel.count > 0
  75. Label {
  76. text: i18n("Fan:")
  77. Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
  78. renderType: Text.NativeRendering
  79. }
  80. ComboBox {
  81. id: fanComboBox
  82. model: pwmFanModel
  83. textRole: "display"
  84. Layout.fillWidth: true
  85. Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
  86. }
  87. Button {
  88. Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
  89. text: i18n("Detect fans")
  90. iconName: kcm.needsAuthorization ? "dialog-password" : ""
  91. onClicked: loader.detectSensors()
  92. }
  93. }
  94. Loader {
  95. Layout.fillWidth: true
  96. Layout.fillHeight: true
  97. active: !!pwmFans[fanComboBox.currentIndex]
  98. sourceComponent: PwmFan {
  99. unit: base.unit
  100. fan: pwmFans[fanComboBox.currentIndex]
  101. systemdCom: root.systemdCom
  102. tempModel: root.tempModel
  103. minTemp: base.minTemp
  104. maxTemp: base.maxTemp
  105. }
  106. }
  107. Row {
  108. property bool expanded: false
  109. id: expand
  110. Image {
  111. id: arrow
  112. source: parent.expanded ? "image://icon/go-down" : "image://icon/go-next"
  113. fillMode: Image.PreserveAspectFit
  114. height: advancedLabel.implicitHeight
  115. }
  116. Label {
  117. id: advancedLabel
  118. text: i18n("Advanced settings")
  119. font.bold: true
  120. }
  121. }
  122. MouseArea {
  123. anchors.fill: expand
  124. onClicked: expand.expanded = expand.expanded ? false : true
  125. }
  126. RowLayout {
  127. visible: expand.expanded
  128. Label {
  129. Layout.preferredWidth: root.textWidth
  130. clip: true
  131. text: i18n("Interval:")
  132. horizontalAlignment: Text.AlignRight
  133. Component.onCompleted: root.textWidth = Math.max(root.textWidth, contentWidth)
  134. }
  135. SpinBox {
  136. Layout.minimumWidth: implicitWidth
  137. Layout.fillWidth: true
  138. value: !!loader ? loader.interval : 1
  139. suffix: " " + i18np("second", "seconds", loader.interval)
  140. minimumValue: 1.0
  141. onValueChanged: loader.interval = value
  142. }
  143. }
  144. RowLayout {
  145. visible: expand.expanded
  146. Label {
  147. Layout.preferredWidth: root.textWidth
  148. clip: true
  149. text: i18n("Minimum temperature for fan graphs:")
  150. horizontalAlignment: Text.AlignRight
  151. Component.onCompleted: root.textWidth = Math.max(root.textWidth, contentWidth)
  152. }
  153. SpinBox {
  154. id: minTempBox
  155. Layout.minimumWidth: implicitWidth
  156. Layout.fillWidth: true
  157. decimals: 2
  158. maximumValue: maxTempBox.value
  159. minimumValue: Units.fromKelvin(0, base.unit)
  160. value: Units.fromCelsius(base.minTemp, base.unit)
  161. suffix: base.unit == 0 ? i18n("°C") : base.unit == 1 ? i18n("K") : i18n("°F")
  162. onValueChanged: base.minTemp = value
  163. }
  164. }
  165. RowLayout {
  166. visible: expand.expanded
  167. Label {
  168. Layout.preferredWidth: root.textWidth
  169. clip: true
  170. text: i18n("Maximum temperature for fan graphs:")
  171. horizontalAlignment: Text.AlignRight
  172. Component.onCompleted: root.textWidth = Math.max(root.textWidth, contentWidth)
  173. }
  174. SpinBox {
  175. id: maxTempBox
  176. Layout.minimumWidth: implicitWidth
  177. Layout.fillWidth: true
  178. decimals: 2
  179. maximumValue: Number.POSITIVE_INFINITY
  180. minimumValue: minTempBox.value
  181. value: Units.fromCelsius(base.maxTemp, base.unit)
  182. suffix: base.unit == 0 ? i18n("°C") : base.unit == 1 ? i18n("K") : i18n("°F")
  183. onValueChanged: base.maxTemp = value
  184. }
  185. }
  186. RowLayout {
  187. visible: expand.expanded
  188. Label {
  189. Layout.preferredWidth: root.textWidth
  190. clip: true
  191. text: i18n("Name of the fancontrol systemd service:")
  192. horizontalAlignment: Text.AlignRight
  193. Component.onCompleted: root.textWidth = Math.max(root.textWidth, contentWidth)
  194. }
  195. OptionInput {
  196. Layout.minimumWidth: implicitWidth
  197. Layout.fillWidth: true
  198. color: systemdCom.serviceExists ? "green" : "red"
  199. value: base.serviceName
  200. onTextChanged: base.serviceName = text
  201. }
  202. }
  203. RowLayout {
  204. visible: expand.expanded
  205. Label {
  206. Layout.preferredWidth: root.textWidth
  207. clip: true
  208. text: i18n("Path to the fancontrol config file:")
  209. horizontalAlignment: Text.AlignRight
  210. Component.onCompleted: root.textWidth = Math.max(root.textWidth, contentWidth)
  211. }
  212. OptionInput {
  213. Layout.minimumWidth: implicitWidth
  214. Layout.fillWidth: true
  215. text: base.configUrl.toString().replace("file://", "")
  216. color: base.configValid ? "green" : "red"
  217. onTextChanged: base.configUrl = text
  218. }
  219. Button {
  220. action: loadAction
  221. }
  222. }
  223. }
  224. Action {
  225. id: loadAction
  226. iconName: "document-open"
  227. onTriggered: openFileDialog.open()
  228. tooltip: i18n("Load configuration file")
  229. shortcut: StandardKey.Open
  230. }
  231. FileDialog {
  232. id: openFileDialog
  233. title: i18n("Please choose a configuration file")
  234. folder: "file:///etc"
  235. selectExisting: true
  236. selectMultiple: false
  237. onAccepted: base.configUrl = fileUrl;
  238. }
  239. ErrorDialog {
  240. id: errorDialog
  241. modality: Qt.ApplicationModal
  242. text: loader.error
  243. }
  244. Connections {
  245. target: loader
  246. onCriticalError: errorDialog.open()
  247. }
  248. }