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>
24import QMenuModel 1.0 as QMenuModel
25import Lomiri.Indicators 0.1 as Indicators
33 property bool supportsMultiColorLed: true
35 property string indicatorState: "INDICATOR_OFF"
37 property color color: "darkgreen"
38 property int onMillisec: 1000
39 property int offMillisec: 3000
41 property double batteryLevel: 0
42 property string deviceState: ""
43 property alias hasMessages: _rootState.hasMessages
45 property string batteryIconName: Status.batteryIcon
46 property string displayStatus: Powerd.status
48 onSupportsMultiColorLedChanged: {
49 updateLightState("onSupportsMultiColorLedChanged")
52 onDisplayStatusChanged: {
53 updateLightState("onDisplayStatusChanged")
56 onBatteryIconNameChanged: {
57 updateLightState("onBatteryIconNameChanged")
60 function updateLightState(msg) {
61 console.log("updateLightState: " + msg
62 + ", indicatorState: " + indicatorState
63 + ", supportsMultiColorLed: " + supportsMultiColorLed
64 + ", hasMessages: " + hasMessages
65 + ", icon: " + batteryIconName
66 + ", displayStatus: " + displayStatus
67 + ", deviceState: " + deviceState
68 + ", batteryLevel: " + batteryLevel)
72 // unread messsages (highest), full&charging, charging, low
74 // Icons: (see device.s from indicator-power)
75 // %s-empty-symbolic empty
76 // %s-caution-charging-symbolic charging [ 0..10)
77 // %s-low-charging-symbolic charging [10..30)
78 // %s-good-charging-symbolic charging [30..60)
79 // %s-full-charging-symbolic charging [60..100]
80 // %s-full-charged-symbolic fully charged
84 // device-state: (see system-settings\plugins\battery)
90 // unread notifications : darkgreen pulsing (1000/3000)
91 // charging : white continuously
92 // battery full : green continuously
93 // battery low : orangered pulsing (500/3000)
96 // Icon name 'full-charged' comes late (45m after 100%)
97 // so also check device-state and battery-level
99 // Battery low warning dialog on screen shows up at 10%
100 // but 'caution' icon at 9%.
103 // only show led when display is off
104 if (displayStatus == Powerd.On) {
105 indicatorState = "INDICATOR_OFF"
109 // unread messsages have highest priority
111 indicatorState = "HAS_MESSAGES"
115 // if device does not support a multi color led set led off
116 if(!supportsMultiColorLed) {
117console.log("no support for Multicolor LED. " + indicatorState)
118 indicatorState = "INDICATOR_OFF"
122 var isCharging = batteryIconName.indexOf("charging") >= 0
123 || deviceState == "charging"
124 || deviceState == "fully-charged"
126 var isFull = batteryIconName.indexOf("full-charged") >= 0
127 || deviceState == "fully-charged"
128 || batteryLevel >= 100
130 if (isCharging && isFull) {
131 indicatorState = "BATTERY_FULL"
132 } else if (isCharging) {
133 indicatorState = "BATTERY_CHARGING"
134 } else if (batteryIconName.indexOf("caution") >= 0
135 || batteryIconName.indexOf("empty") >= 0) {
136 indicatorState = "BATTERY_LOW"
138 indicatorState = "INDICATOR_OFF"
142 onIndicatorStateChanged: {
143 console.log("onIndicatorStateChange: " + indicatorState)
145 switch (indicatorState) {
146 case "INDICATOR_OFF":
158 case "BATTERY_CHARGING":
169 console.log("ERROR onIndicatorStateChange: unknown state: " + indicatorState)
173 // HACK: led is only updated after turn on so first always turn off
174 Leds.state = Leds.Off
175 if (indicatorState != "INDICATOR_OFF")
179 // Existence of unread notifications is determined by checking for a specific icon name in a dbus signal.
180 property var _actionGroup: QMenuModel.QDBusActionGroup {
182 busName: "org.ayatana.indicator.messages"
183 objectPath: "/org/ayatana/indicator/messages"
186 Indicators.ActionRootState {
188 actionGroup: _actionGroup
189 actionName: "messages"
190 Component.onCompleted: actionGroup.start()
191 property bool hasMessages: (String(icons).indexOf("indicator-messages-new") != -1) && valid
192 onHasMessagesChanged: updateLightState("onHasMessagesChanged")
195 // Charging state and battery level are determined by listening to dbus signals from upower.
196 // See also system-settings battery plugin.
197 property var _ipag: QMenuModel.QDBusActionGroup {
199 busName: "org.ayatana.indicator.power"
200 objectPath: "/org/ayatana/indicator/power"
201 property variant batteryLevel: action("battery-level").state
202 property variant deviceState: action("device-state").state
203 Component.onCompleted: start()
204 onBatteryLevelChanged: {
205 root.batteryLevel = batteryLevel ? batteryLevel : 0.00
206 updateLightState("onBatteryLevelChanged")
208 onDeviceStateChanged: {
209 root.deviceState = deviceState ? deviceState : "unknown"
210 updateLightState("onDeviceStateChanged")
214 Component.onCompleted: Leds.state = Leds.Off
215 Component.onDestruction: Leds.state = Leds.Off
217 property var _colorBinding: Binding {
223 property var _onMillisecBinding: Binding {
225 property: "onMillisec"
226 value: root.onMillisec
229 property var _offMillisecBinding: Binding {
231 property: "offMillisec"
232 value: root.offMillisec