Warning, /plasma/plasma-workspace/applets/batterymonitor/package/contents/ui/PowerProfileItem.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  *   SPDX-FileCopyrightText: 2021 Kai Uwe Broulik <kde@broulik.de>
0003  *   SPDX-FileCopyrightText: 2021 David Redondo <kde@david-redondo.de>
0004  *
0005  *   SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 import QtQuick
0009 import QtQuick.Layouts
0010 
0011 import org.kde.plasma.components as PlasmaComponents3
0012 import org.kde.kirigami as Kirigami
0013 
0014 PlasmaComponents3.ItemDelegate {
0015     id: root
0016 
0017     property alias slider: slider
0018 
0019     property bool profilesInstalled
0020     property bool profilesAvailable
0021 
0022     property string activeProfile
0023 
0024     property string inhibitionReason
0025     readonly property bool inhibited: inhibitionReason !== ""
0026 
0027     property string degradationReason
0028 
0029     // type: [{ Name: string, Icon: string, Profile: string, Reason: string }]
0030     required property var profileHolds
0031 
0032     // The canBeInhibited property mean that this profile's availability
0033     // depends on root.inhibited value (and thus on the
0034     // inhibitionReason string).
0035     readonly property var profileData: [
0036         {
0037             label: i18n("Power Save"),
0038             profile: "power-saver",
0039             canBeInhibited: false,
0040         }, {
0041             label: i18n("Balanced"),
0042             profile: "balanced",
0043             canBeInhibited: false,
0044         }, {
0045             label: i18n("Performance"),
0046             profile: "performance",
0047             canBeInhibited: true,
0048         }
0049     ]
0050 
0051     readonly property int activeProfileIndex: profileData.findIndex(data => data.profile === activeProfile)
0052     // type: typeof(profileData[])?
0053     readonly property var activeProfileData: activeProfileIndex !== -1 ? profileData[activeProfileIndex] : undefined
0054     // type: typeof(profileHolds)
0055     readonly property var activeHolds: profileHolds.filter(hold => hold.Profile === activeProfile)
0056 
0057     signal activateProfileRequested(string profile)
0058 
0059     background.visible: highlighted
0060     highlighted: activeFocus
0061     hoverEnabled: false
0062     text: i18n("Power Profile")
0063 
0064     Accessible.description: activeProfileLabel.text
0065     Accessible.role: Accessible.Slider
0066     Keys.forwardTo: [slider]
0067 
0068     contentItem: RowLayout {
0069         spacing: Kirigami.Units.gridUnit
0070 
0071         Kirigami.Icon {
0072             source: "speedometer"
0073             Layout.alignment: Qt.AlignTop
0074             Layout.preferredWidth: Kirigami.Units.iconSizes.medium
0075             Layout.preferredHeight: Kirigami.Units.iconSizes.medium
0076         }
0077 
0078         ColumnLayout {
0079             Layout.fillWidth: true
0080             Layout.alignment: Qt.AlignTop
0081             spacing: 0
0082 
0083             RowLayout {
0084                 Layout.fillWidth: true
0085                 spacing: Kirigami.Units.smallSpacing
0086 
0087                 PlasmaComponents3.Label {
0088                     Layout.fillWidth: true
0089                     elide: Text.ElideRight
0090                     text: root.text
0091                     textFormat: Text.PlainText
0092                 }
0093 
0094                 PlasmaComponents3.Label {
0095                     id: activeProfileLabel
0096                     Layout.alignment: Qt.AlignRight
0097                     text: !root.profilesAvailable ? i18nc("Power profile", "Not available") : activeProfileData ? activeProfileData.label : ""
0098                     textFormat: Text.PlainText
0099                     enabled: root.profilesAvailable
0100                 }
0101             }
0102 
0103             PlasmaComponents3.Slider {
0104                 id: slider
0105                 visible: root.profilesAvailable
0106                 Layout.fillWidth: true
0107 
0108                 activeFocusOnTab: false
0109                 from: 0
0110                 to: 2
0111                 stepSize: 1
0112                 value: root.activeProfileIndex
0113                 snapMode: PlasmaComponents3.Slider.SnapAlways
0114                 onMoved: {
0115                     const { canBeInhibited, profile } = root.profileData[value];
0116                     if (!(canBeInhibited && root.inhibited)) {
0117                         activateProfileRequested(profile);
0118                     } else {
0119                         value = Qt.binding(() => root.activeProfileIndex);
0120                     }
0121                 }
0122 
0123                 // fake having a disabled second half
0124                 Rectangle {
0125                     z: -1
0126                     visible: root.inhibited
0127                     color: Kirigami.Theme.backgroundColor
0128                     anchors {
0129                         top: parent.background.top
0130                         left: parent.horizontalCenter
0131                         leftMargin: 1
0132                         right: parent.right
0133                         bottom: parent.background.bottom
0134                     }
0135                     opacity: 0.4
0136                 }
0137             }
0138 
0139             RowLayout {
0140                 spacing: 0
0141                 visible: root.profilesAvailable
0142                 Layout.topMargin: Kirigami.Units.smallSpacing
0143                 Layout.bottomMargin: Kirigami.Units.smallSpacing
0144                 Layout.fillWidth: true
0145 
0146                 Kirigami.Icon {
0147                     Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium
0148                     Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium
0149                     source: "battery-profile-powersave-symbolic"
0150 
0151                     HoverHandler {
0152                         id: powersaveIconHover
0153                     }
0154 
0155                     PlasmaComponents3.ToolTip {
0156                         text: root.profileData.find(profile => profile.profile === "power-saver").label
0157                         visible: powersaveIconHover.hovered
0158                     }
0159                 }
0160 
0161                 Item {
0162                     Layout.fillWidth: true
0163                 }
0164 
0165                 Kirigami.Icon {
0166                     Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium
0167                     Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium
0168                     source: "battery-profile-performance-symbolic"
0169 
0170                     HoverHandler {
0171                         id: performanceIconHover
0172                     }
0173 
0174                     PlasmaComponents3.ToolTip {
0175                         text: root.profileData.find(profile => profile.profile === "performance").label
0176                         visible: performanceIconHover.hovered
0177                     }
0178                 }
0179             }
0180 
0181             // NOTE Only one of these will be visible at a time since the daemon will only set one depending
0182             // on its version
0183             InhibitionHint {
0184                 id: inhibitionReasonHint
0185 
0186                 Layout.fillWidth: true
0187 
0188                 visible: root.inhibited
0189                 iconSource: "dialog-information"
0190                 text: switch(root.inhibitionReason) {
0191                     case "lap-detected":
0192                         return i18n("Performance mode has been disabled to reduce heat generation because the computer has detected that it may be sitting on your lap.")
0193                     case "high-operating-temperature":
0194                         return i18n("Performance mode is unavailable because the computer is running too hot.")
0195                     default:
0196                         return i18n("Performance mode is unavailable.")
0197                 }
0198             }
0199 
0200             InhibitionHint {
0201                 id: inhibitionPerformanceHint
0202 
0203                 Layout.fillWidth: true
0204 
0205                 visible: root.activeProfile === "performance" && root.degradationReason !== ""
0206                 iconSource: "dialog-information"
0207                 text: switch(root.degradationReason) {
0208                     case "lap-detected":
0209                         return i18n("Performance may be lowered to reduce heat generation because the computer has detected that it may be sitting on your lap.")
0210                     case "high-operating-temperature":
0211                         return i18n("Performance may be reduced because the computer is running too hot.")
0212                     default:
0213                         return i18n("Performance may be reduced.")
0214                 }
0215             }
0216 
0217             InhibitionHint {
0218                 id: inhibitionHoldersHint
0219 
0220                 Layout.fillWidth: true
0221 
0222                 visible: root.activeHolds.length > 0 && root.activeProfileData !== undefined
0223                 text: root.activeProfileData !== undefined
0224                     ? i18np("One application has requested activating %2:",
0225                             "%1 applications have requested activating %2:",
0226                             root.activeHolds.length,
0227                             i18n(root.activeProfileData.label))
0228                     : ""
0229             }
0230 
0231             Repeater {
0232                 id: repeater
0233 
0234                 model: root.activeHolds
0235 
0236                 InhibitionHint {
0237                     Layout.fillWidth: true
0238 
0239                     x: Kirigami.Units.smallSpacing
0240                     iconSource: modelData.Icon
0241                     text: i18nc("%1 is the name of the application, %2 is the reason provided by it for activating performance mode",
0242                                 "%1: %2", modelData.Name, modelData.Reason)
0243                 }
0244             }
0245 
0246             Item {
0247                 Layout.fillWidth: true
0248                 Layout.preferredHeight: Kirigami.Units.smallSpacing
0249 
0250                 visible: repeater.visibleChildren > 0
0251                     || inhibitionReasonHint.visible
0252                     || inhibitionPerformanceHint.visible
0253                     || inhibitionHoldersHint.visible
0254             }
0255 
0256             RowLayout {
0257                 visible: !root.profilesInstalled
0258                 spacing: Kirigami.Units.smallSpacing
0259 
0260                 PlasmaComponents3.Label {
0261                     text: xi18n("Power profiles may be supported on your device.<nl/>Try installing the <command>power-profiles-daemon</command> package using your distribution's package manager and restarting the system.")
0262                     textFormat: Text.PlainText
0263                     enabled: false
0264                     font: Kirigami.Theme.smallFont
0265                     wrapMode: Text.Wrap
0266                     Layout.fillWidth: true
0267                 }
0268             }
0269 
0270         }
0271     }
0272 }