2 * Copyright 2014 Canonical Ltd.
3 * Copyright 2019 UBports Foundation
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation; version 3.
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.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * Renato Araujo Oliveira Filho <renato@canonical.com>
25import QMenuModel 1.0 as QMenuModel
26import Lomiri.Indicators 0.1 as Indicators
34 property bool supportsMultiColorLed: true
36 property string indicatorState: "INDICATOR_OFF"
38 property color color: "darkgreen"
39 property int onMillisec: 1000
40 property int offMillisec: 3000
42 property double batteryLevel: 0
43 property string deviceState: ""
44 property alias hasMessages: _rootState.hasMessages
46 property string batteryIconName: Status.batteryIcon
47 property string displayStatus: Powerd.status
49 onSupportsMultiColorLedChanged: {
50 updateLightState("onSupportsMultiColorLedChanged")
53 onDisplayStatusChanged: {
54 updateLightState("onDisplayStatusChanged")
57 onBatteryIconNameChanged: {
58 updateLightState("onBatteryIconNameChanged")
61 function updateLightState(msg) {
62 console.log("updateLightState: " + msg
63 + ", indicatorState: " + indicatorState
64 + ", supportsMultiColorLed: " + supportsMultiColorLed
65 + ", hasMessages: " + hasMessages
66 + ", icon: " + batteryIconName
67 + ", displayStatus: " + displayStatus
68 + ", deviceState: " + deviceState
69 + ", batteryLevel: " + batteryLevel)
73 // unread messsages (highest), full&charging, charging, low
75 // Icons: (see device.s from indicator-power)
76 // %s-empty-symbolic empty
77 // %s-caution-charging-symbolic charging [ 0..10)
78 // %s-low-charging-symbolic charging [10..30)
79 // %s-good-charging-symbolic charging [30..60)
80 // %s-full-charging-symbolic charging [60..100]
81 // %s-full-charged-symbolic fully charged
85 // device-state: (see system-settings\plugins\battery)
91 // unread notifications : darkgreen pulsing (1000/3000)
92 // charging : white continuously
93 // battery full : green continuously
94 // battery low : orangered pulsing (500/3000)
97 // Icon name 'full-charged' comes late (45m after 100%)
98 // so also check device-state and battery-level
100 // Battery low warning dialog on screen shows up at 10%
101 // but 'caution' icon at 9%.
104 // only show led when display is off
105 if (displayStatus == Powerd.On) {
106 indicatorState = "INDICATOR_OFF"
110 // unread messsages have highest priority
112 indicatorState = "HAS_MESSAGES"
116 // if device does not support a multi color led set led off
117 if(!supportsMultiColorLed) {
118console.log("no support for Multicolor LED. " + indicatorState)
119 indicatorState = "INDICATOR_OFF"
123 var isCharging = batteryIconName.indexOf("charging") >= 0
124 || deviceState == "charging"
125 || deviceState == "fully-charged"
127 var isFull = batteryIconName.indexOf("full-charged") >= 0
128 || deviceState == "fully-charged"
129 || batteryLevel >= 100
131 if (isCharging && isFull) {
132 indicatorState = "BATTERY_FULL"
133 } else if (isCharging) {
134 indicatorState = "BATTERY_CHARGING"
135 } else if (batteryIconName.indexOf("caution") >= 0
136 || batteryIconName.indexOf("empty") >= 0) {
137 indicatorState = "BATTERY_LOW"
139 indicatorState = "INDICATOR_OFF"
143 onIndicatorStateChanged: {
144 console.log("onIndicatorStateChange: " + indicatorState)
146 switch (indicatorState) {
147 case "INDICATOR_OFF":
159 case "BATTERY_CHARGING":
170 console.log("ERROR onIndicatorStateChange: unknown state: " + indicatorState)
174 // HACK: led is only updated after turn on so first always turn off
175 Leds.state = Leds.Off
176 if (indicatorState != "INDICATOR_OFF")
180 // Existence of unread notifications is determined by checking for a specific icon name in a dbus signal.
181 property var _actionGroup: QMenuModel.QDBusActionGroup {
183 busName: "org.ayatana.indicator.messages"
184 objectPath: "/org/ayatana/indicator/messages"
187 Indicators.ActionRootState {
189 actionGroup: _actionGroup
190 actionName: "messages"
191 Component.onCompleted: actionGroup.start()
192 property bool hasMessages: (String(icons).indexOf("indicator-messages-new") != -1) && valid
193 onHasMessagesChanged: updateLightState("onHasMessagesChanged")
196 // Charging state and battery level are determined by listening to dbus signals from upower.
197 // See also system-settings battery plugin.
198 property var _ipag: QMenuModel.QDBusActionGroup {
200 busName: "org.ayatana.indicator.power"
201 objectPath: "/org/ayatana/indicator/power"
202 property variant batteryLevel: action("battery-level").state
203 property variant deviceState: action("device-state").state
204 Component.onCompleted: start()
205 onBatteryLevelChanged: {
206 root.batteryLevel = batteryLevel ? batteryLevel : 0.00
207 updateLightState("onBatteryLevelChanged")
209 onDeviceStateChanged: {
210 root.deviceState = deviceState ? deviceState : "unknown"
211 updateLightState("onDeviceStateChanged")
215 Component.onCompleted: Leds.state = Leds.Off
216 Component.onDestruction: Leds.state = Leds.Off
218 property var _colorBinding: Binding {
220 restoreMode: Binding.RestoreBinding
225 property var _onMillisecBinding: Binding {
227 restoreMode: Binding.RestoreBinding
228 property: "onMillisec"
229 value: root.onMillisec
232 property var _offMillisecBinding: Binding {
234 restoreMode: Binding.RestoreBinding
235 property: "offMillisec"
236 value: root.offMillisec