You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
7.5 KiB
199 lines
7.5 KiB
/* |
|
SPDX-FileCopyrightText: 2012-2013 Daniel Nicoletti <dantti12@gmail.com> |
|
SPDX-FileCopyrightText: 2013-2015 Kai Uwe Broulik <kde@privat.broulik.de> |
|
|
|
SPDX-License-Identifier: LGPL-2.0-or-later |
|
*/ |
|
|
|
import QtQuick 2.15 |
|
import QtQuick.Layouts 1.15 |
|
|
|
import org.kde.kcoreaddons 1.0 as KCoreAddons |
|
import org.kde.plasma.components 3.0 as PlasmaComponents3 |
|
import org.kde.plasma.core 2.1 as PlasmaCore |
|
import org.kde.plasma.extras 2.0 as PlasmaExtras |
|
import org.kde.plasma.workspace.components 2.0 |
|
|
|
import "logic.js" as Logic |
|
|
|
RowLayout { |
|
id: root |
|
|
|
// We'd love to use `required` properties, especially since the model provides role names for them; |
|
// but unfortunately some of those roles have whitespaces in their name, which QML doesn't have any |
|
// workaround for (raw identifiers like r#try in Rust would've helped here). |
|
// |
|
// type: { |
|
// Capacity: int, |
|
// Energy: real, |
|
// "Is Power Supply": bool, |
|
// Percent: int, |
|
// "Plugged In": bool, |
|
// "Pretty Name": string, |
|
// Product: string, |
|
// State: "Discharging"|"Charging"|"FullyCharged"|etc., |
|
// Type: string, |
|
// Vendor: string, |
|
// }? |
|
property var battery |
|
|
|
// NOTE: According to the UPower spec this property is only valid for primary batteries, however |
|
// UPower seems to set the Present property false when a device is added but not probed yet |
|
readonly property bool isPresent: root.battery["Plugged in"] |
|
|
|
readonly property bool isBroken: root.battery.Capacity > 0 && root.battery.Capacity < 50 |
|
|
|
property int remainingTime: 0 |
|
|
|
// Existing instance of a slider to use as a reference to calculate extra |
|
// margins for a progress bar, so that the row of labels on top of it |
|
// could visually look as if it were on the same distance from the bar as |
|
// they are from the slider. |
|
property PlasmaComponents3.Slider matchHeightOfSlider: PlasmaComponents3.Slider {} |
|
readonly property real extraMargin: Math.max(0, Math.floor((matchHeightOfSlider.height - chargeBar.height) / 2)) |
|
|
|
spacing: PlasmaCore.Units.gridUnit |
|
|
|
BatteryIcon { |
|
id: batteryIcon |
|
|
|
Layout.alignment: Qt.AlignTop |
|
Layout.preferredWidth: PlasmaCore.Units.iconSizes.medium |
|
Layout.preferredHeight: PlasmaCore.Units.iconSizes.medium |
|
|
|
batteryType: root.battery.Type |
|
percent: root.battery.Percent |
|
hasBattery: root.isPresent |
|
pluggedIn: root.battery.State === "Charging" && root.battery["Is Power Supply"] |
|
} |
|
|
|
ColumnLayout { |
|
Layout.fillWidth: true |
|
Layout.alignment: root.isPresent ? Qt.AlignTop : Qt.AlignVCenter |
|
spacing: 0 |
|
|
|
RowLayout { |
|
spacing: PlasmaCore.Units.smallSpacing |
|
|
|
PlasmaComponents3.Label { |
|
Layout.fillWidth: true |
|
elide: Text.ElideRight |
|
text: root.battery["Pretty Name"] |
|
} |
|
|
|
PlasmaComponents3.Label { |
|
text: Logic.stringForBatteryState(root.battery) |
|
visible: root.battery["Is Power Supply"] |
|
enabled: false |
|
} |
|
|
|
PlasmaComponents3.Label { |
|
horizontalAlignment: Text.AlignRight |
|
visible: root.isPresent |
|
text: i18nc("Placeholder is battery percentage", "%1%", root.battery.Percent) |
|
} |
|
} |
|
|
|
PlasmaComponents3.ProgressBar { |
|
id: chargeBar |
|
|
|
Layout.fillWidth: true |
|
Layout.topMargin: root.extraMargin |
|
Layout.bottomMargin: root.extraMargin |
|
|
|
from: 0 |
|
to: 100 |
|
visible: root.isPresent |
|
value: Number(root.battery.Percent) |
|
} |
|
|
|
// This gridLayout basically emulates an at-most-two-rows table with a |
|
// single wide fillWidth/columnSpan header. Not really worth it trying |
|
// to refactor it into some more clever fancy model-delegate stuff. |
|
GridLayout { |
|
id: details |
|
|
|
Layout.fillWidth: true |
|
Layout.topMargin: PlasmaCore.Units.smallSpacing |
|
|
|
columns: 2 |
|
columnSpacing: PlasmaCore.Units.smallSpacing |
|
rowSpacing: 0 |
|
|
|
component LeftLabel : PlasmaComponents3.Label { |
|
// fillWidth is true, so using internal alignment |
|
horizontalAlignment: Text.AlignLeft |
|
Layout.fillWidth: true |
|
font: PlasmaCore.Theme.smallestFont |
|
wrapMode: Text.WordWrap |
|
enabled: false |
|
} |
|
component RightLabel : PlasmaComponents3.Label { |
|
// fillWidth is false, so using external (grid-cell-internal) alignment |
|
Layout.alignment: Qt.AlignRight |
|
Layout.fillWidth: false |
|
font: PlasmaCore.Theme.smallestFont |
|
enabled: false |
|
} |
|
|
|
PlasmaComponents3.Label { |
|
Layout.fillWidth: true |
|
Layout.columnSpan: 2 |
|
|
|
text: root.isBroken && typeof root.battery.Capacity !== "undefined" |
|
? i18n("This battery's health is at only %1% and should be replaced. Please contact your hardware vendor for more details.", root.battery.Capacity) |
|
: "" |
|
font: PlasmaCore.Theme.smallestFont |
|
color: PlasmaCore.Theme.neutralTextColor |
|
visible: root.isBroken |
|
wrapMode: Text.WordWrap |
|
} |
|
|
|
readonly property bool remainingTimeRowVisible: root.battery !== null |
|
&& root.remainingTime > 0 |
|
&& root.battery["Is Power Supply"] |
|
&& ["Discharging", "Charging"].includes(root.battery.State) |
|
|
|
LeftLabel { |
|
text: root.battery.State === "Charging" |
|
? i18n("Time To Full:") |
|
: i18n("Remaining Time:") |
|
visible: details.remainingTimeRowVisible |
|
} |
|
|
|
RightLabel { |
|
text: KCoreAddons.Format.formatDuration(root.remainingTime, KCoreAddons.FormatTypes.HideSeconds) |
|
visible: details.remainingTimeRowVisible |
|
} |
|
|
|
readonly property bool healthRowVisible: root.battery !== null |
|
&& root.battery["Is Power Supply"] |
|
&& root.battery.Capacity !== "" |
|
&& typeof root.battery.Capacity === "number" |
|
&& !root.isBroken |
|
|
|
LeftLabel { |
|
text: i18n("Battery Health:") |
|
visible: details.healthRowVisible |
|
} |
|
|
|
RightLabel { |
|
text: details.healthRowVisible |
|
? i18nc("Placeholder is battery health percentage", "%1%", root.battery.Capacity) |
|
: "" |
|
visible: details.healthRowVisible |
|
} |
|
} |
|
|
|
InhibitionHint { |
|
Layout.fillWidth: true |
|
Layout.topMargin: PlasmaCore.Units.smallSpacing |
|
|
|
readonly property var chargeStopThreshold: pmSource.data["Battery"] ? pmSource.data["Battery"]["Charge Stop Threshold"] : undefined |
|
readonly property bool pluggedIn: pmSource.data["AC Adapter"] !== undefined && pmSource.data["AC Adapter"]["Plugged in"] |
|
visible: pluggedIn && typeof chargeStopThreshold === "number" && chargeStopThreshold > 0 && chargeStopThreshold < 100 |
|
iconSource: "kt-speed-limits" // FIXME good icon |
|
text: i18n("Your battery is configured to only charge up to %1%.", chargeStopThreshold || 0) |
|
} |
|
} |
|
}
|
|
|