]> git.pld-linux.org Git - packages/kde4-kdebase-workspace.git/blob - kde4-kdebase-workspace-multibattery.patch
970fb96692d87b1a30090c22586952c97cfa4105
[packages/kde4-kdebase-workspace.git] / kde4-kdebase-workspace-multibattery.patch
1 diff --git a/plasma/generic/dataengines/powermanagement/powermanagementengine.cpp b/plasma/generic/dataengines/powermanagement/powermanagementengine.cpp
2 index 33a6e03..f3a918a 100644
3 --- a/plasma/generic/dataengines/powermanagement/powermanagementengine.cpp
4 +++ b/plasma/generic/dataengines/powermanagement/powermanagementengine.cpp
5 @@ -34,6 +34,7 @@
6  #include <KIdleTime>
7  
8  #include <QtDBus/QDBusConnectionInterface>
9 +#include <QtDBus/QDBusError>
10  #include <QtDBus/QDBusInterface>
11  #include <QtDBus/QDBusMetaType>
12  #include <QtDBus/QDBusReply>
13 @@ -58,23 +59,39 @@ PowermanagementEngine::~PowermanagementEngine()
14  
15  void PowermanagementEngine::init()
16  {
17 -    connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(QString)),
18 -            this,                              SLOT(deviceRemoved(QString)));
19      connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(QString)),
20              this,                              SLOT(deviceAdded(QString)));
21 +    connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(QString)),
22 +            this,                              SLOT(deviceRemoved(QString)));
23  
24 +    // FIXME This check doesn't work, connect seems to always return true, hence the hack below
25      if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.Solid.PowerManagement")) {
26          if (!QDBusConnection::sessionBus().connect("org.kde.Solid.PowerManagement",
27 -                                                   "/org/kde/Solid/PowerManagement",
28 -                                                   "org.kde.Solid.PowerManagement",
29 +                                                   "/org/kde/Solid/PowerManagement/Actions/BrightnessControl",
30 +                                                   "org.kde.Solid.PowerManagement.Actions.BrightnessControl",
31                                                     "brightnessChanged", this,
32                                                     SLOT(screenBrightnessChanged(int)))) {
33              kDebug() << "error connecting to Brightness changes via dbus";
34 -        }
35 -        else {
36 +            brightnessControlsAvailableChanged(false);
37 +        } else {
38              sourceRequestEvent("PowerDevil");
39              screenBrightnessChanged(0);
40 +            brightnessControlsAvailableChanged(true);
41          }
42 +
43 +        if (!QDBusConnection::sessionBus().connect("org.kde.Solid.PowerManagement",
44 +                                                   "/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl",
45 +                                                   "org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl",
46 +                                                   "keyboardBrightnessChanged", this,
47 +                                                   SLOT(keyboardBrightnessChanged(int)))) {
48 +            kDebug() << "error connecting to Keyboard Brightness changes via dbus";
49 +            keyboardBrightnessControlsAvailableChanged(false);
50 +        } else {
51 +            sourceRequestEvent("PowerDevil");
52 +            keyboardBrightnessChanged(0);
53 +            keyboardBrightnessControlsAvailableChanged(true);
54 +        }
55 +
56          if (!QDBusConnection::sessionBus().connect("org.kde.Solid.PowerManagement",
57                                                     "/org/kde/Solid/PowerManagement",
58                                                     "org.kde.Solid.PowerManagement",
59 @@ -114,27 +131,32 @@ bool PowermanagementEngine::sourceRequestEvent(const QString &name)
60          foreach (const Solid::Device &deviceBattery, listBattery) {
61              const Solid::Battery* battery = deviceBattery.as<Solid::Battery>();
62  
63 -            if (battery && (battery->type() == Solid::Battery::PrimaryBattery ||
64 -                            battery->type() == Solid::Battery::UpsBattery)) {
65 -                const QString source = QString("Battery%1").arg(index++);
66 +            const QString source = QString("Battery%1").arg(index++);
67  
68 -                batterySources << source;
69 -                m_batterySources[deviceBattery.udi()] = source;
70 +            batterySources << source;
71 +            m_batterySources[deviceBattery.udi()] = source;
72  
73 -                connect(battery, SIGNAL(chargeStateChanged(int,QString)), this,
74 -                        SLOT(updateBatteryChargeState(int,QString)));
75 -                connect(battery, SIGNAL(chargePercentChanged(int,QString)), this,
76 -                        SLOT(updateBatteryChargePercent(int,QString)));
77 -                connect(battery, SIGNAL(plugStateChanged(bool,QString)), this,
78 -                        SLOT(updateBatteryPlugState(bool,QString)));
79 +            connect(battery, SIGNAL(chargeStateChanged(int,QString)), this,
80 +                    SLOT(updateBatteryChargeState(int,QString)));
81 +            connect(battery, SIGNAL(chargePercentChanged(int,QString)), this,
82 +                    SLOT(updateBatteryChargePercent(int,QString)));
83 +            connect(battery, SIGNAL(plugStateChanged(bool,QString)), this,
84 +                    SLOT(updateBatteryPlugState(bool,QString)));
85  
86 -                // Set initial values
87 -                updateBatteryChargeState(battery->chargeState(), deviceBattery.udi());
88 -                updateBatteryChargePercent(battery->chargePercent(), deviceBattery.udi());
89 -                updateBatteryPlugState(battery->isPlugged(), deviceBattery.udi());
90 -            }
91 +            // Set initial values
92 +            updateBatteryChargeState(battery->chargeState(), deviceBattery.udi());
93 +            updateBatteryChargePercent(battery->chargePercent(), deviceBattery.udi());
94 +            updateBatteryPlugState(battery->isPlugged(), deviceBattery.udi());
95 +            updateBatteryPowerSupplyState(battery->isPowerSupply(), deviceBattery.udi());
96 +
97 +            setData(source, "Vendor", deviceBattery.vendor());
98 +            setData(source, "Product", deviceBattery.product());
99 +            setData(source, "Capacity", battery->capacity());
100 +            setData(source, "Type", batteryType(battery));
101          }
102  
103 +        updateBatteryNames();
104 +
105          setData("Battery", "Has Battery", !batterySources.isEmpty());
106          if (!batterySources.isEmpty()) {
107              setData("Battery", "Sources", batterySources);
108 @@ -180,14 +202,30 @@ bool PowermanagementEngine::sourceRequestEvent(const QString &name)
109              //kDebug() << "Sleepstate \"" << sleepstate << "\" supported.";
110          }
111      } else if (name == "PowerDevil") {
112 -        QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement",
113 -                                                          "/org/kde/Solid/PowerManagement",
114 -                                                          "org.kde.Solid.PowerManagement",
115 -                                                          "brightness");
116 -        QDBusPendingReply<int> reply = QDBusConnection::sessionBus().asyncCall(msg);
117 -        QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
118 -        QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
119 -                            this, SLOT(screenBrightnessReply(QDBusPendingCallWatcher*)));
120 +        QDBusMessage msg;
121 +        QDBusPendingReply<int> reply;
122 +
123 +        if (m_brightnessControlsAvailable) {
124 +          msg = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement",
125 +                                                            "/org/kde/Solid/PowerManagement/Actions/BrightnessControl",
126 +                                                            "org.kde.Solid.PowerManagement.Actions.BrightnessControl",
127 +                                                            "brightness");
128 +          reply = QDBusConnection::sessionBus().asyncCall(msg);
129 +          QDBusPendingCallWatcher *screenWatcher = new QDBusPendingCallWatcher(reply, this);
130 +          QObject::connect(screenWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
131 +                              this, SLOT(screenBrightnessReply(QDBusPendingCallWatcher*)));
132 +        }
133 +
134 +        if (m_keyboardBrightnessControlsAvailable) {
135 +          msg = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement",
136 +                                                            "/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl",
137 +                                                            "org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl",
138 +                                                            "keyboardBrightness");
139 +          reply = QDBusConnection::sessionBus().asyncCall(msg);
140 +          QDBusPendingCallWatcher *keyboardWatcher = new QDBusPendingCallWatcher(reply, this);
141 +          QObject::connect(keyboardWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
142 +                              this, SLOT(keyboardBrightnessReply(QDBusPendingCallWatcher*)));
143 +        }
144      //any info concerning lock screen/screensaver goes here
145      } else if (name == "UserActivity") {
146          setData("UserActivity", "IdleTime", KIdleTime::instance()->idleTime());
147 @@ -198,6 +236,37 @@ bool PowermanagementEngine::sourceRequestEvent(const QString &name)
148      return true;
149  }
150  
151 +QString PowermanagementEngine::batteryType(const Solid::Battery* battery)
152 +{
153 +  switch(battery->type()) {
154 +      case Solid::Battery::PrimaryBattery:
155 +          return QLatin1String("Battery");
156 +          break;
157 +      case Solid::Battery::UpsBattery:
158 +          return QLatin1String("Ups");
159 +          break;
160 +      case Solid::Battery::MonitorBattery:
161 +          return QLatin1String("Monitor");
162 +          break;
163 +      case Solid::Battery::MouseBattery:
164 +          return QLatin1String("Mouse");
165 +          break;
166 +      case Solid::Battery::KeyboardBattery:
167 +          return QLatin1String("Keyboad");
168 +          break;
169 +      case Solid::Battery::PdaBattery:
170 +          return QLatin1String("Pda");
171 +          break;
172 +      case Solid::Battery::PhoneBattery:
173 +          return QLatin1String("Phone");
174 +          break;
175 +      default:
176 +          return QLatin1String("Unknown");
177 +  }
178 +
179 +  return QLatin1String("Unknown");
180 +}
181 +
182  bool PowermanagementEngine::updateSourceEvent(const QString &source)
183  {
184      if (source == "UserActivity") {
185 @@ -243,6 +312,45 @@ void PowermanagementEngine::updateBatteryChargePercent(int newValue, const QStri
186      setData(source, "Percent", newValue);
187  }
188  
189 +void PowermanagementEngine::updateBatteryPowerSupplyState(bool newState, const QString& udi)
190 +{
191 +    const QString source = m_batterySources[udi];
192 +    setData(source, "Is Power Supply", newState);
193 +}
194 +
195 +void PowermanagementEngine::updateBatteryNames()
196 +{
197 +    uint unnamedBatteries = 0;
198 +    foreach (QString source, m_batterySources) {
199 +        DataContainer *batteryDataContainer = containerForSource(source);
200 +        if (batteryDataContainer) {
201 +            const QString batteryVendor = batteryDataContainer->data()["Vendor"].toString();
202 +            const QString batteryProduct = batteryDataContainer->data()["Product"].toString();
203 +
204 +            // Don't show battery name for primary power supply batteries. They usually have cryptic serial number names.
205 +            const QString batteryType = batteryDataContainer->data()["Type"].toString();
206 +            bool batteryIsPowerSupply = batteryDataContainer->data()["Is Power Supply"].toBool();
207 +            bool showBatteryName = batteryType != QLatin1String("Battery") ||
208 +                                   (batteryType != QLatin1String("Battery") && !batteryIsPowerSupply);
209 +
210 +            if (!batteryProduct.isEmpty() && batteryProduct != "Unknown Battery" && showBatteryName) {
211 +                if (!batteryVendor.isEmpty()) {
212 +                    setData(source, "Pretty Name", QString(batteryVendor + ' ' + batteryProduct));
213 +                } else {
214 +                    setData(source, "Pretty Name", batteryProduct);
215 +                }
216 +            } else {
217 +                ++unnamedBatteries;
218 +                if (unnamedBatteries > 1) {
219 +                    setData(source, "Pretty Name", i18nc("Placeholder is the battery number", "Battery %1", unnamedBatteries));
220 +                } else {
221 +                    setData(source, "Pretty Name", i18n("Battery"));
222 +                }
223 +            }
224 +        }
225 +    }
226 +}
227 +
228  void PowermanagementEngine::updateAcPlugState(bool newState)
229  {
230      setData("AC Adapter", "Plugged in", newState);
231 @@ -273,8 +381,7 @@ void PowermanagementEngine::deviceAdded(const QString& udi)
232      if (device.isValid()) {
233          const Solid::Battery* battery = device.as<Solid::Battery>();
234  
235 -        if (battery && (battery->type() == Solid::Battery::PrimaryBattery ||
236 -                        battery->type() == Solid::Battery::UpsBattery)) {
237 +        if (battery) {
238              int index = 0;
239              QStringList sourceNames(m_batterySources.values());
240              while (sourceNames.contains(QString("Battery%1").arg(index))) {
241 @@ -291,14 +398,24 @@ void PowermanagementEngine::deviceAdded(const QString& udi)
242                      SLOT(updateBatteryChargePercent(int,QString)));
243              connect(battery, SIGNAL(plugStateChanged(bool,QString)), this,
244                      SLOT(updateBatteryPlugState(bool,QString)));
245 +            connect(battery, SIGNAL(powerSupplyStateChanged(bool,QString)), this,
246 +                    SLOT(updateBatteryPowerSupplyState(bool,QString)));
247  
248              // Set initial values
249              updateBatteryChargeState(battery->chargeState(), device.udi());
250              updateBatteryChargePercent(battery->chargePercent(), device.udi());
251              updateBatteryPlugState(battery->isPlugged(), device.udi());
252 +            updateBatteryPowerSupplyState(battery->isPowerSupply(), device.udi());
253 +
254 +            setData(source, "Vendor", device.vendor());
255 +            setData(source, "Product", device.product());
256 +            setData(source, "Capacity", battery->capacity());
257 +            setData(source, "Type", batteryType(battery));
258  
259              setData("Battery", "Sources", sourceNames);
260              setData("Battery", "Has Battery", !sourceNames.isEmpty());
261 +
262 +            updateBatteryNames();
263          }
264      }
265  }
266 @@ -309,6 +426,18 @@ void PowermanagementEngine::batteryRemainingTimeChanged(qulonglong time)
267      setData("Battery", "Remaining msec", time);
268  }
269  
270 +void PowermanagementEngine::brightnessControlsAvailableChanged(bool available)
271 +{
272 +    setData("PowerDevil", "Screen Brightness Available", available);
273 +    m_brightnessControlsAvailable = available;
274 +}
275 +
276 +void PowermanagementEngine::keyboardBrightnessControlsAvailableChanged(bool available)
277 +{
278 +    setData("PowerDevil", "Keyboard Brightness Available", available);
279 +    m_keyboardBrightnessControlsAvailable = available;
280 +}
281 +
282  void PowermanagementEngine::batteryRemainingTimeReply(QDBusPendingCallWatcher *watcher)
283  {
284      QDBusPendingReply<qulonglong> reply = *watcher;
285 @@ -327,11 +456,18 @@ void PowermanagementEngine::screenBrightnessChanged(int brightness)
286      setData("PowerDevil", "Screen Brightness", brightness);
287  }
288  
289 +void PowermanagementEngine::keyboardBrightnessChanged(int brightness)
290 +{
291 +    setData("PowerDevil", "Keyboard Brightness", brightness);
292 +}
293 +
294  void PowermanagementEngine::screenBrightnessReply(QDBusPendingCallWatcher *watcher)
295  {
296      QDBusPendingReply<int> reply = *watcher;
297      if (reply.isError()) {
298          kDebug() << "Error getting screen brightness: " << reply.error().message();
299 +        // FIXME Because the above check doesn't work, we unclaim backlight support as soon as it fails
300 +        brightnessControlsAvailableChanged(false);
301      } else {
302          screenBrightnessChanged(reply.value());
303      }
304 @@ -339,6 +475,20 @@ void PowermanagementEngine::screenBrightnessReply(QDBusPendingCallWatcher *watch
305      watcher->deleteLater();
306  }
307  
308 +void PowermanagementEngine::keyboardBrightnessReply(QDBusPendingCallWatcher *watcher)
309 +{
310 +    QDBusPendingReply<int> reply = *watcher;
311 +    if (reply.isError()) {
312 +        kDebug() << "Error getting keyboard brightness: " << reply.error().message();
313 +        // FIXME Because the above check doesn't work, we unclaim backlight support as soon as it fails
314 +        keyboardBrightnessControlsAvailableChanged(false);
315 +    } else {
316 +        keyboardBrightnessChanged(reply.value());
317 +    }
318 +
319 +    watcher->deleteLater();
320 +}
321 +
322  K_EXPORT_PLASMA_DATAENGINE(powermanagement, PowermanagementEngine)
323  
324  #include "powermanagementengine.moc"
325 diff --git a/plasma/generic/dataengines/powermanagement/powermanagementengine.h b/plasma/generic/dataengines/powermanagement/powermanagementengine.h
326 index 512bf6e..dafb6c2 100644
327 --- a/plasma/generic/dataengines/powermanagement/powermanagementengine.h
328 +++ b/plasma/generic/dataengines/powermanagement/powermanagementengine.h
329 @@ -54,21 +54,32 @@ private slots:
330      void updateBatteryChargeState(int newState, const QString& udi);
331      void updateBatteryPlugState(bool newState, const QString& udi);
332      void updateBatteryChargePercent(int newValue, const QString& udi);
333 +    void updateBatteryPowerSupplyState(bool newState, const QString& udi);
334      void updateAcPlugState(bool newState);
335 +    void updateBatteryNames();
336 +
337      void deviceRemoved(const QString& udi);
338      void deviceAdded(const QString& udi);
339      void batteryRemainingTimeChanged(qulonglong time);
340      void batteryRemainingTimeReply(QDBusPendingCallWatcher*);
341      void screenBrightnessChanged(int brightness);
342 +    void keyboardBrightnessChanged(int brightness);
343      void screenBrightnessReply(QDBusPendingCallWatcher *watcher);
344 +    void keyboardBrightnessReply(QDBusPendingCallWatcher *watcher);
345 +    void brightnessControlsAvailableChanged(bool available);
346 +    void keyboardBrightnessControlsAvailableChanged(bool available);
347  
348  private:
349 +    QString batteryType(const Solid::Battery *battery);
350      QStringList basicSourceNames() const;
351  
352      QStringList m_sources;
353  
354      QHash<QString, QString> m_batterySources;  // <udi, Battery0>
355  
356 +    bool m_brightnessControlsAvailable;
357 +    bool m_keyboardBrightnessControlsAvailable;
358 +
359  };
360  
361  
362 diff --git a/plasma/generic/dataengines/powermanagement/powermanagementjob.cpp b/plasma/generic/dataengines/powermanagement/powermanagementjob.cpp
363 index 1b0b8a0..06156d9 100644
364 --- a/plasma/generic/dataengines/powermanagement/powermanagementjob.cpp
365 +++ b/plasma/generic/dataengines/powermanagement/powermanagementjob.cpp
366 @@ -94,6 +94,10 @@ void PowerManagementJob::start()
367          setScreenBrightness(parameters().value("brightness").toInt());
368          setResult(true);
369          return;
370 +    } else if (operation == "setKeyboardBrightness") {
371 +        setKeyboardBrightness(parameters().value("brightness").toInt());
372 +        setResult(true);
373 +        return;
374      }
375  
376      kDebug() << "don't know what to do with " << operation;
377 @@ -103,8 +107,8 @@ void PowerManagementJob::start()
378  bool PowerManagementJob::suspend(const SuspendType &type)
379  {
380      QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement",
381 -                                                      "/org/kde/Solid/PowerManagement",
382 -                                                      "org.kde.Solid.PowerManagement",
383 +                                                      "/org/kde/Solid/PowerManagement/Actions/SuspendSession",
384 +                                                      "org.kde.Solid.PowerManagement.Actions.SuspendSession",
385                                                        callForType(type));
386      QDBusConnection::sessionBus().asyncCall(msg);
387      return true;
388 @@ -130,13 +134,23 @@ QString PowerManagementJob::callForType(const SuspendType &type)
389  void PowerManagementJob::setScreenBrightness(int value)
390  {
391      QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement",
392 -                                                      "/org/kde/Solid/PowerManagement",
393 -                                                      "org.kde.Solid.PowerManagement",
394 +                                                      "/org/kde/Solid/PowerManagement/Actions/BrightnessControl",
395 +                                                      "org.kde.Solid.PowerManagement.Actions.BrightnessControl",
396                                                        "setBrightness");
397      msg << value;
398      QDBusConnection::sessionBus().asyncCall(msg);
399  }
400  
401 +void PowerManagementJob::setKeyboardBrightness(int value)
402 +{
403 +    QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement",
404 +                                                      "/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl",
405 +                                                      "org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl",
406 +                                                      "setKeyboardBrightness");
407 +    msg << value;
408 +    QDBusConnection::sessionBus().asyncCall(msg);
409 +}
410 +
411  void PowerManagementJob::requestShutDown()
412  {
413      KWorkSpace::requestShutDown();
414 diff --git a/plasma/generic/dataengines/powermanagement/powermanagementjob.h b/plasma/generic/dataengines/powermanagement/powermanagementjob.h
415 index 3b974ab..c1c7bf4 100644
416 --- a/plasma/generic/dataengines/powermanagement/powermanagementjob.h
417 +++ b/plasma/generic/dataengines/powermanagement/powermanagementjob.h
418 @@ -1,6 +1,6 @@
419  /*
420   * Copyright 2011 Sebastian Kügler <sebas@kde.org>
421 - * 
422 + *
423   * This program is free software; you can redistribute it and/or modify
424   * it under the terms of the GNU Library General Public License version 2 as
425   * published by the Free Software Foundation
426 @@ -41,6 +41,7 @@ class PowerManagementJob : public Plasma::ServiceJob
427          void requestShutDown();
428          QString callForType(const SuspendType &type);
429          void setScreenBrightness(int value);
430 +        void setKeyboardBrightness(int value);
431  };
432  
433  #endif // POWERMANAGEMENTJOB_H
434 diff --git a/plasma/generic/dataengines/powermanagement/powermanagementservice.operations b/plasma/generic/dataengines/powermanagement/powermanagementservice.operations
435 index 533c00a..c9abbf9 100644
436 --- a/plasma/generic/dataengines/powermanagement/powermanagementservice.operations
437 +++ b/plasma/generic/dataengines/powermanagement/powermanagementservice.operations
438 @@ -37,4 +37,9 @@
439            <label>The value of the screen brightness</label>
440          </entry>
441      </group>
442 +    <group name="setKeyboardBrightness">
443 +        <entry name="brightness" type="Int">
444 +            <label>The value of the keyboard brightness</label>
445 +        </entry>
446 +    </group>
447  </kcfg>
448 diff --git a/plasma/generic/applets/batterymonitor/contents/code/logic.js b/plasma/generic/applets/batterymonitor/contents/code/logic.js
449 index 974694a..d1c08c1 100644
450 --- a/plasma/generic/applets/batterymonitor/contents/code/logic.js
451 +++ b/plasma/generic/applets/batterymonitor/contents/code/logic.js
452 @@ -18,74 +18,178 @@
453   *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
454   */
455  
456 -var ram = 0
457 -var disk = 1
458 +var powermanagementDisabled = false;
459  
460  function updateCumulative() {
461      var sum = 0;
462 +    var count = 0;
463      var charged = true;
464 +    var plugged = false;
465      for (var i=0; i<batteries.count; i++) {
466          var b = batteries.get(i);
467 +        if (!b["Is Power Supply"]) {
468 +          continue;
469 +        }
470          if (b["Plugged in"]) {
471              sum += b["Percent"];
472 +            plugged = true;
473          }
474          if (b["State"] != "NoCharge") {
475              charged = false;
476          }
477 +        count++;
478      }
479  
480 -    if (batteries.count > 0) {
481 -        batteries.cumulativePercent = Math.round(sum/batteries.count);
482 +    if (count > 0) {
483 +      batteries.cumulativePercent = Math.round(sum/count);
484      } else {
485 -        batteries.cumulativePercent = 0;
486 +        // We don't have any power supply batteries
487 +        // Use the lowest value from any battery
488 +        if (batteries.count > 0) {
489 +            var b = lowestBattery();
490 +            batteries.cumulativePercent = b["Percent"];
491 +        } else {
492 +            batteries.cumulativePercent = 0;
493 +        }
494      }
495 +    batteries.cumulativePluggedin = plugged;
496      batteries.allCharged = charged;
497  }
498  
499 -function stringForState(batteryData) {
500 -    var pluggedIn = batteryData["Plugged in"];
501 -    var percent = batteryData["Percent"];
502 -    var state = batteryData["State"];
503 -
504 -    if (pluggedIn) {
505 -        if (state == "NoCharge") {
506 -            return i18n("<b>%1% (charged)</b>", percent);
507 -        } else if (state == "Discharging") {
508 -            return i18n("<b>%1% (discharging)</b>", percent);
509 -        } else {//charging
510 -            return i18n("<b>%1% (charging)</b>", percent);
511 +function plasmoidStatus() {
512 +    var status = "PassiveStatus";
513 +    if (powermanagementDisabled) {
514 +        status = "ActiveStatus";
515 +    }
516 +
517 +    if (batteries.cumulativePluggedin) {
518 +        if (batteries.cumulativePercent <= 10) {
519 +            status = "NeedsAttentionStatus";
520 +        } else if (!batteries.allCharged) {
521 +            status = "ActiveStatus";
522          }
523 +    } else if (batteries.count > 0) { // in case your mouse gets low
524 +        if (batteries.cumulativePercent && batteries.cumulativePercent <= 10) {
525 +            status = "NeedsAttentionStatus";
526 +        }
527 +    }
528 +    return status;
529 +}
530 +
531 +function lowestBattery() {
532 +    if (batteries.count == 0) {
533 +        return;
534      }
535  
536 -    return i18nc("Battery is not plugged in", "<b>Not present</b>");
537 +    var lowestPercent = 100;
538 +    var lowestBattery;
539 +    for(var i=0; i<batteries.count; i++) {
540 +        var b = batteries.get(i);
541 +        if (b["Percent"] && b["Percent"] < lowestPercent) {
542 +            lowestPercent = b["Percent"];
543 +            lowestBattery = b;
544 +        }
545 +    }
546 +    return b;
547  }
548  
549 -function updateTooltip() {
550 -    var text="";
551 -    for (var i=0; i<batteries.count; i++) {
552 -        if (batteries.count == 1) {
553 -            text += i18n("Battery:");
554 -        } else {
555 -            if (text != "") {
556 -                text += "<br/>";
557 +function stringForBatteryState(batteryData) {
558 +    if (batteryData["Plugged in"]) {
559 +        switch(batteryData["State"]) {
560 +            case "NoCharge": return i18n("Not Charging");
561 +            case "Discharging": return i18n("Discharging");
562 +            case "FullyCharged": return i18n("Fully Charged");
563 +            default: return i18n("Charging");
564 +        }
565 +    } else {
566 +        return i18nc("Battery is currently not present in the bay","Not present");
567 +    }
568 +}
569 +
570 +function iconForBattery(batteryData,pluggedIn) {
571 +    switch(batteryData["Type"]) {
572 +        case "Monitor":
573 +            return "video-display";
574 +        case "Mouse":
575 +            return "input-mouse";
576 +        case "Keyboard":
577 +            return "input-keyboard";
578 +        case "Pda":
579 +            return "pda";
580 +        case "Phone":
581 +            return "phone";
582 +        default: // Primary and UPS
583 +            p = batteryData["Percent"];
584 +            if (p >= 90) {
585 +                fill = "100";
586 +            } else if (p >= 70) {
587 +                fill = "080";
588 +            } else if (p >= 50) {
589 +                fill = "060";
590 +            } else if (p >= 30) {
591 +                fill = "040";
592 +            } else if (p >= 10) {
593 +                fill = "caution";
594 +            } else {
595 +                fill = "low";
596              }
597  
598 -            text += i18nc("tooltip: placeholder is the battery ID", "Battery %1:", i+1);
599 +            if (pluggedIn && batteryData["Is Power Supply"]) {
600 +                return "battery-charging-" + fill;
601 +            } else {
602 +                if (p < 5) {
603 +                    return "dialog-warning"
604 +                }
605 +                return "battery-" + fill;
606 +            }
607 +    }
608 +}
609 +
610 +function updateTooltip() {
611 +    var image = "";
612 +    var text = "";
613 +    if (batteries.count == 0) {
614 +        image = "battery-missing";
615 +        if (!powermanagementDisabled) {
616 +            text = i18n("No batteries available");
617          }
618 +    } else {
619 +        var hasPowerSupply = false;
620  
621 -        text += " ";
622 -        text += stringForState(pmSource.data["Battery"+i]);
623 -    }
624 +        text = "<table style='white-space: nowrap'>";
625 +        for(var i=0; i<batteries.count; i++) {
626 +            var b = batteries.get(i);
627 +            text += "<tr>";
628 +            text += "<td align='right'>" + i18nc("Placeholder is battery name", "%1:", b["Pretty Name"]) + " </td>";
629 +            text += "<td><b>";
630 +            if (b["Plugged in"]) {
631 +                text += i18nc("Placeholder is battery percentage", "%1%", b["Percent"]);
632 +            } else {
633 +                text += i18n("N/A")
634 +            }
635 +            text += "</b></td>";
636 +            text += "</tr>";
637 +
638 +            if (b["Is Power Supply"]) { hasPowerSupply = true; }
639 +        }
640 +        text += "</table>";
641  
642 -    if (text != "") {
643 -        text += "<br/>";
644 +        if (hasPowerSupply) {
645 +            var b = [];
646 +            b["Type"] = "Battery";
647 +            b["Percent"] = batteries.cumulativePercent;
648 +            image = iconForBattery(b, pmSource.data["AC Adapter"]["Plugged in"] ? true : false);
649 +        } else {
650 +            var b = lowestBattery();
651 +            image = iconForBattery(b, false);
652 +        }
653      }
654  
655 -    if (pmSource.data["AC Adapter"]) {
656 -        text += i18nc("tooltip", "AC Adapter:") + " ";
657 -        text += pmSource.data["AC Adapter"]["Plugged in"] ? i18nc("tooltip", "<b>Plugged in</b>") : i18nc("tooltip", "<b>Not plugged in</b>");
658 +    if (powermanagementDisabled) {
659 +        text += i18n("Power management is disabled");
660      }
661      batteries.tooltipText = text;
662 +    batteries.tooltipImage = image;
663  }
664  
665  function updateBrightness() {
666 @@ -94,16 +198,26 @@ function updateBrightness() {
667          return;
668      }
669      dialogItem.disableBrightnessUpdate = true;
670 -    dialogItem.screenBrightness = pmSource.data["PowerDevil"]["Screen Brightness"];
671 +    if (pmSource.data["PowerDevil"]["Screen Brightness"]) {
672 +        dialogItem.screenBrightness = pmSource.data["PowerDevil"]["Screen Brightness"];
673 +    }
674 +    if (pmSource.data["PowerDevil"]["Keyboard Brightness"]) {
675 +        dialogItem.keyboardBrightness = pmSource.data["PowerDevil"]["Keyboard Brightness"];
676 +    }
677      dialogItem.disableBrightnessUpdate = false;
678  }
679  
680 -function callForType(type) {
681 -    if (type == ram) {
682 -        return "suspendToRam";
683 -    } else if (type == disk) {
684 -        return "suspendToDisk";
685 -    }
686 +// TODO: give translated and formatted string with KGlobal::locale()->prettyFormatDuration(msec);
687 +function formatDuration(msec) {
688 +    if (msec == 0 || msec === undefined)
689 +        return "";
690 +
691 +    var time = new Date(msec);
692 +    var hours = time.getUTCHours();
693 +    var minutes = time.getUTCMinutes();
694  
695 -    return "suspendHybrid";
696 +    var str = "";
697 +    if (hours > 0) str += i18np("1 hour ", "%1 hours ", hours);
698 +    if (minutes > 0) str += i18np("1 minute", "%1 minutes", minutes);
699 +    return str;
700  }
701 diff --git a/plasma/generic/applets/batterymonitor/contents/code/platform.js b/plasma/generic/applets/batterymonitor/contents/code/platform.js
702 deleted file mode 100644
703 index 59af3af..0000000
704 --- a/plasma/generic/applets/batterymonitor/contents/code/platform.js
705 +++ /dev/null
706 @@ -1,9 +0,0 @@
707 -
708 -function shouldOfferSuspend(pmSource) {
709 -    return pmSource.data["Sleep States"]["Suspend"];
710 -}
711 -
712 -function shouldOfferHibernate(pmSource) {
713 -    return pmSource.data["Sleep States"]["Hibernate"];
714 -}
715 -
716 diff --git a/plasma/generic/applets/batterymonitor/contents/config/main.xml b/plasma/generic/applets/batterymonitor/contents/config/main.xml
717 index fc31b3e..5e9e31d 100644
718 --- a/plasma/generic/applets/batterymonitor/contents/config/main.xml
719 +++ b/plasma/generic/applets/batterymonitor/contents/config/main.xml
720 @@ -6,12 +6,6 @@
721    <kcfgfile name=""/>
722  
723    <group name="General">
724 -    <entry name="showBatteryString" type="Bool">
725 -      <default>false</default>
726 -    </entry>
727 -    <entry name="showMultipleBatteries" type="Bool">
728 -      <default>false</default>
729 -    </entry>
730      <entry name="showRemainingTime" type="Bool">
731        <default>false</default>
732      </entry>
733 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/AcAdapterItem.qml b/plasma/generic/applets/batterymonitor/contents/ui/AcAdapterItem.qml
734 new file mode 100644
735 index 0000000..c2216f8
736 --- /dev/null
737 +++ b/plasma/generic/applets/batterymonitor/contents/ui/AcAdapterItem.qml
738 @@ -0,0 +1,87 @@
739 +/*
740 + *   Copyright 2012-2013 Daniel Nicoletti <dantti12@gmail.com>
741 + *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
742 + *
743 + *   This program is free software; you can redistribute it and/or modify
744 + *   it under the terms of the GNU Library General Public License as
745 + *   published by the Free Software Foundation; either version 2 or
746 + *   (at your option) any later version.
747 + *
748 + *   This program is distributed in the hope that it will be useful,
749 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
750 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
751 + *   GNU General Public License for more details
752 + *
753 + *   You should have received a copy of the GNU Library General Public
754 + *   License along with this program; if not, write to the
755 + *   Free Software Foundation, Inc.,
756 + *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
757 + */
758 +
759 +import QtQuick 1.1
760 +import org.kde.plasma.core 0.1 as PlasmaCore
761 +import org.kde.plasma.components 0.1 as Components
762 +import org.kde.qtextracomponents 0.1
763 +
764 +Item {
765 +    id: brightnessItem
766 +    clip: true
767 +    width: parent.width
768 +    height: acIcon.height + padding.margins.top + padding.margins.bottom
769 +
770 +    property bool pluggedIn
771 +    property bool showTime
772 +    property string remainingString
773 +
774 +    QIconItem {
775 +        id: acIcon
776 +        width: theme.iconSizes.dialog
777 +        height: width
778 +        anchors {
779 +            top: parent.top
780 +            topMargin: padding.margins.top
781 +            left: parent.left
782 +            leftMargin: padding.margins.left
783 +        }
784 +
785 +        icon: pluggedIn ? QIcon("battery-charging-low") : QIcon("battery-low")
786 +    }
787 +
788 +    Components.Label {
789 +        id: acLabel
790 +        anchors {
791 +            top: acIcon.top
792 +            left: acIcon.right
793 +            leftMargin: 6
794 +        }
795 +        height: paintedHeight
796 +        text: i18n("AC Adapter")
797 +    }
798 +
799 +    Components.Label {
800 +        id: acStatus
801 +        anchors {
802 +            top: showTime ? acLabel.top : undefined
803 +            bottom: showTime ? undefined : acIcon.bottom
804 +            left: showTime ? acLabel.right : acIcon.right
805 +            leftMargin: showTime ? 3 : 6
806 +        }
807 +        height: paintedHeight
808 +        text: pluggedIn ? i18n("Plugged In") : i18n("Not Plugged In")
809 +        color: "#77"+(theme.textColor.toString().substr(1))
810 +    }
811 +
812 +    Components.Label {
813 +        id: acTime
814 +        anchors {
815 +            bottom: acIcon.bottom
816 +            left: acIcon.right
817 +            leftMargin: 6
818 +        }
819 +        height: paintedHeight
820 +        visible: showTime
821 +        text: pluggedIn ? i18n("Time remaining until full: %1", remainingString) : i18n("Time remaining until empty: %1", remainingString)
822 +        color: "#77"+(theme.textColor.toString().substr(1))
823 +    }
824 +}
825 +
826 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml b/plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml
827 index 080ab51..6a49d34 100644
828 --- a/plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml
829 +++ b/plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml
830 @@ -21,15 +21,13 @@ import QtQuick 1.1
831  import org.kde.plasma.core 0.1 as PlasmaCore
832  
833  Item {
834 -    
835 -    property bool monochrome
836      property bool hasBattery
837      property int percent
838      property bool pluggedIn
839 -    
840 +
841      PlasmaCore.Svg {
842          id: svg
843 -        imagePath: monochrome ? "icons/battery" : "widgets/battery-oxygen"
844 +        imagePath: "icons/battery"
845      }
846  
847      PlasmaCore.SvgItem {
848 @@ -39,25 +37,55 @@ Item {
849      }
850  
851      PlasmaCore.SvgItem {
852 +        id: fillSvg
853          anchors.fill: parent
854          svg: svg
855          elementId: hasBattery ? fillElement(percent) : "Unavailable"
856 -        visible: percent>10 || !hasBattery
857 +        visible: elementId != ""
858      }
859  
860      function fillElement(p) {
861 -        if (p >= 90) {
862 -            return "Fill100";
863 -        } else if (p >= 70) {
864 -            return "Fill80";
865 -        } else if (p >= 50) {
866 -            return "Fill60";
867 -        } else if (p > 20) {
868 -            return "Fill40";
869 -        } else if (p >= 10) {
870 -            return "Fill20";
871 +        // We switched from having steps of 20 for the battery percentage to a more accurate
872 +        // step of 10. This means we break other and older themes.
873 +        // If the Fill10 element is not found, it is likely that the theme doesn't support
874 +        // that and we use the older method of obtaining the fill element.
875 +        if (!svg.hasElement("Fill10")) {
876 +            if (p >= 90) {
877 +                return "Fill100";
878 +            } else if (p >= 70) {
879 +                return "Fill80";
880 +            } else if (p >= 50) {
881 +                return "Fill60";
882 +            } else if (p > 20) {
883 +                return "Fill40";
884 +            } else if (p >= 10) {
885 +                return "Fill20";
886 +            }
887 +            return "";
888 +        } else {
889 +            if (p >= 95) {
890 +                return "Fill100";
891 +            } else if (p >= 85) {
892 +                return "Fill90";
893 +            } else if (p >= 75) {
894 +                return "Fill90";
895 +            } else if (p >= 65) {
896 +                return "Fill80";
897 +            } else if (p >= 55) {
898 +                return "Fill60";
899 +            } else if (p >= 45) {
900 +                return "Fill50";
901 +            } else if (p >= 35) {
902 +                return "Fill40";
903 +            } else if (p >= 25) {
904 +                return "Fill30";
905 +            } else if (p >= 15) {
906 +                return "Fill20";
907 +            } else if (p >= 5) {
908 +                return "Fill10";
909 +            }
910 +            return "";
911          }
912 -        return "";
913      }
914  
915      PlasmaCore.SvgItem {
916 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/BatteryItem.qml b/plasma/generic/applets/batterymonitor/contents/ui/BatteryItem.qml
917 new file mode 100644
918 index 0000000..3317aea
919 --- /dev/null
920 +++ b/plasma/generic/applets/batterymonitor/contents/ui/BatteryItem.qml
921 @@ -0,0 +1,312 @@
922 +/*
923 + *   Copyright 2012-2013 Daniel Nicoletti <dantti12@gmail.com>
924 + *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
925 + *
926 + *   This program is free software; you can redistribute it and/or modify
927 + *   it under the terms of the GNU Library General Public License as
928 + *   published by the Free Software Foundation; either version 2 or
929 + *   (at your option) any later version.
930 + *
931 + *   This program is distributed in the hope that it will be useful,
932 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
933 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
934 + *   GNU General Public License for more details
935 + *
936 + *   You should have received a copy of the GNU Library General Public
937 + *   License along with this program; if not, write to the
938 + *   Free Software Foundation, Inc.,
939 + *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
940 + */
941 +
942 +import QtQuick 1.1
943 +import org.kde.plasma.core 0.1 as PlasmaCore
944 +import org.kde.plasma.components 0.1 as Components
945 +import org.kde.qtextracomponents 0.1
946 +import "plasmapackage:/code/logic.js" as Logic
947 +
948 +Item {
949 +    id: batteryItem
950 +    clip: true
951 +    width: batteryColumn.width
952 +    height: expanded ? batteryInfos.height + padding.margins.top + padding.margins.bottom * 2 + actionRow.height
953 +                     : batteryInfos.height + padding.margins.top + padding.margins.bottom
954 +
955 +    Behavior on height { PropertyAnimation {} }
956 +
957 +    property bool highlight
958 +    property bool expanded
959 +    property bool showChargeAnimation
960 +
961 +    // NOTE: According to the UPower spec this property is only valid for primary batteries, however
962 +    // UPower seems to set the Present property false when a device is added but not probed yet
963 +    property bool isPresent: model["Plugged in"]
964 +
965 +    function updateSelection() {
966 +        var containsMouse = mouseArea.containsMouse;
967 +
968 +        if (highlight || expanded && containsMouse) {
969 +            padding.opacity = 1;
970 +        } else if (expanded) {
971 +            padding.opacity = 0.8;
972 +        } else if (containsMouse) {
973 +            padding.opacity = 0.65;
974 +        } else {
975 +            padding.opacity = 0;
976 +        }
977 +    }
978 +
979 +    PlasmaCore.FrameSvgItem {
980 +        id: padding
981 +        imagePath: "widgets/viewitem"
982 +        prefix: "hover"
983 +        opacity: 0
984 +        Behavior on opacity { PropertyAnimation {} }
985 +        anchors.fill: parent
986 +    }
987 +
988 +    MouseArea {
989 +        id: mouseArea
990 +        anchors.fill: parent
991 +        hoverEnabled: true
992 +        onEntered: updateSelection()
993 +        onExited: updateSelection()
994 +        onClicked: {
995 +            if (expanded) {
996 +                expanded = false;
997 +            } else {
998 +                expanded = true;
999 +                batteryItem.forceActiveFocus();
1000 +            }
1001 +            updateSelection();
1002 +        }
1003 +    }
1004 +
1005 +    Item {
1006 +        id: batteryInfos
1007 +        height: Math.max(batteryIcon.height, batteryNameLabel.height + batteryPercentBar.height)
1008 +
1009 +        anchors {
1010 +            top: parent.top
1011 +            topMargin: padding.margins.top
1012 +            left: parent.left
1013 +            leftMargin: padding.margins.left
1014 +            right: parent.right
1015 +            rightMargin: padding.margins.right
1016 +        }
1017 +
1018 +        QIconItem {
1019 +            id: batteryIcon
1020 +            width: theme.iconSizes.dialog
1021 +            height: width
1022 +            anchors {
1023 +                verticalCenter: parent.verticalCenter
1024 +                left: parent.left
1025 +            }
1026 +            icon: QIcon(Logic.iconForBattery(model,pluggedIn))
1027 +        }
1028 +
1029 +        SequentialAnimation {
1030 +          id: chargeAnimation
1031 +          running: showChargeAnimation && model["State"] == "Charging"
1032 +          alwaysRunToEnd: true
1033 +          loops: Animation.Infinite
1034 +
1035 +          NumberAnimation {
1036 +              target: batteryIcon
1037 +              properties: "opacity"
1038 +              from: 1.0
1039 +              to: 0.5
1040 +              duration: 750
1041 +              easing.type: Easing.InCubic
1042 +          }
1043 +          NumberAnimation {
1044 +              target: batteryIcon
1045 +              properties: "opacity"
1046 +              from: 0.5
1047 +              to: 1.0
1048 +              duration: 750
1049 +              easing.type: Easing.OutCubic
1050 +          }
1051 +        }
1052 +
1053 +        Components.Label {
1054 +            id: batteryNameLabel
1055 +            anchors {
1056 +                verticalCenter: isPresent ? undefined : batteryIcon.verticalCenter
1057 +                top: isPresent ? parent.top : undefined
1058 +                left: batteryIcon.right
1059 +                leftMargin: 6
1060 +            }
1061 +            height: paintedHeight
1062 +            elide: Text.ElideRight
1063 +            text: model["Pretty Name"]
1064 +        }
1065 +
1066 +        Components.Label {
1067 +            id: batteryStatusLabel
1068 +            anchors {
1069 +                top: batteryNameLabel.top
1070 +                left: batteryNameLabel.right
1071 +                leftMargin: 3
1072 +            }
1073 +            text: Logic.stringForBatteryState(model)
1074 +            height: paintedHeight
1075 +            visible: model["Is Power Supply"]
1076 +            color: "#77"+(theme.textColor.toString().substr(1))
1077 +        }
1078 +
1079 +        Components.ProgressBar {
1080 +            id: batteryPercentBar
1081 +            anchors {
1082 +                bottom: parent.bottom
1083 +                left: batteryIcon.right
1084 +                leftMargin: 6
1085 +                right: batteryPercent.left
1086 +                rightMargin: 6
1087 +            }
1088 +            minimumValue: 0
1089 +            maximumValue: 100
1090 +            visible: isPresent
1091 +            value: parseInt(model["Percent"])
1092 +        }
1093 +
1094 +        Components.Label {
1095 +            id: batteryPercent
1096 +            anchors {
1097 +                verticalCenter: batteryPercentBar.verticalCenter
1098 +                right: parent.right
1099 +            }
1100 +            visible: isPresent
1101 +            text: i18nc("Placeholder is battery percentage", "%1%", model["Percent"])
1102 +        }
1103 +    }
1104 +
1105 +    Column {
1106 +        id: actionRow
1107 +        opacity: expanded ? 1 : 0
1108 +        width: parent.width
1109 +        anchors {
1110 +          top: batteryInfos.bottom
1111 +          topMargin: padding.margins.bottom
1112 +          left: parent.left
1113 +          leftMargin: padding.margins.left
1114 +          right: parent.right
1115 +          rightMargin: padding.margins.right
1116 +          bottomMargin: padding.margins.bottom
1117 +        }
1118 +        spacing: 4
1119 +        Behavior on opacity { PropertyAnimation {} }
1120 +
1121 +        PlasmaCore.SvgItem {
1122 +            svg: PlasmaCore.Svg {
1123 +                id: lineSvg
1124 +                imagePath: "widgets/line"
1125 +            }
1126 +            elementId: "horizontal-line"
1127 +            height: lineSvg.elementSize("horizontal-line").height
1128 +            width: parent.width
1129 +        }
1130 +
1131 +        Row {
1132 +            id: detailsRow
1133 +            width: parent.width
1134 +            spacing: 4
1135 +
1136 +            Column {
1137 +                id: labelsColumn
1138 +                Components.Label {
1139 +                    height: paintedHeight
1140 +                    width: parent.width
1141 +                    horizontalAlignment: Text.AlignRight
1142 +                    onPaintedWidthChanged: {
1143 +                        if (paintedWidth > parent.width) { parent.width = paintedWidth; }
1144 +                    }
1145 +                    text: model["State"] == "Charging" ? i18n("Time To Full:") : i18n("Time To Empty:")
1146 +                    visible: remainingTimeLabel.visible
1147 +                    font.pointSize: theme.smallestFont.pointSize
1148 +                    color: "#99"+(theme.textColor.toString().substr(1))
1149 +                }
1150 +                Components.Label {
1151 +                    height: paintedHeight
1152 +                    width: parent.width
1153 +                    horizontalAlignment: Text.AlignRight
1154 +                    onPaintedWidthChanged: {
1155 +                        if (paintedWidth > parent.width) { parent.width = paintedWidth; }
1156 +                    }
1157 +                    text: i18n("Capacity:")
1158 +                    visible: capacityLabel.visible
1159 +                    font.pointSize: theme.smallestFont.pointSize
1160 +                    color: "#99"+(theme.textColor.toString().substr(1))
1161 +                }
1162 +                Components.Label {
1163 +                    height: paintedHeight
1164 +                    width: parent.width
1165 +                    horizontalAlignment: Text.AlignRight
1166 +                    onPaintedWidthChanged: {
1167 +                        if (paintedWidth > parent.width) { parent.width = paintedWidth; }
1168 +                    }
1169 +                    text: i18n("Vendor:")
1170 +                    visible: vendorLabel.visible
1171 +                    font.pointSize: theme.smallestFont.pointSize
1172 +                    color: "#99"+(theme.textColor.toString().substr(1))
1173 +                }
1174 +                Components.Label {
1175 +                    height: paintedHeight
1176 +                    width: parent.width
1177 +                    horizontalAlignment: Text.AlignRight
1178 +                    onPaintedWidthChanged: {
1179 +                        if (paintedWidth > parent.width) { parent.width = paintedWidth; }
1180 +                    }
1181 +                    text: i18n("Model:")
1182 +                    visible: modelLabel.visible
1183 +                    font.pointSize: theme.smallestFont.pointSize
1184 +                    color: "#99"+(theme.textColor.toString().substr(1))
1185 +                }
1186 +            }
1187 +            Column {
1188 +                width: parent.width - labelsColumn.width - parent.spacing * 2
1189 +                Components.Label { // Remaining Time
1190 +                    id: remainingTimeLabel
1191 +                    height: paintedHeight
1192 +                    width: parent.width
1193 +                    elide: Text.ElideRight
1194 +                    text: Logic.formatDuration(model["Remaining Time"])
1195 +                    visible: showRemainingTime && model["Is Power Supply"] && model["State"] != "NoCharge" && text
1196 +                    font.pointSize: theme.smallestFont.pointSize
1197 +                    color: "#99"+(theme.textColor.toString().substr(1))
1198 +                }
1199 +                Components.Label { // Capacity
1200 +                    id: capacityLabel
1201 +                    height: paintedHeight
1202 +                    width: parent.width
1203 +                    elide: Text.ElideRight
1204 +                    text: i18nc("Placeholder is battery capacity", "%1%", model["Capacity"])
1205 +                    visible: model["Is Power Supply"] &&  model["Capacity"] != "" && model["Capacity"] !== undefined
1206 +                    font.pointSize: theme.smallestFont.pointSize
1207 +                    color: "#99"+(theme.textColor.toString().substr(1))
1208 +                }
1209 +                Components.Label { // Vendor
1210 +                    id: vendorLabel
1211 +                    height: paintedHeight
1212 +                    width: parent.width
1213 +                    elide: Text.ElideRight
1214 +                    text: model["Vendor"]
1215 +                    visible: model["Vendor"] != "" && model["Vendor"] !== undefined
1216 +                    font.pointSize: theme.smallestFont.pointSize
1217 +                    color: "#99"+(theme.textColor.toString().substr(1))
1218 +                }
1219 +                Components.Label { // Model
1220 +                    id: modelLabel
1221 +                    height: paintedHeight
1222 +                    width: parent.width
1223 +                    elide: Text.ElideRight
1224 +                    text: model["Product"]
1225 +                    visible: model["Product"] != "" && model["Product"] !== undefined
1226 +                    font.pointSize: theme.smallestFont.pointSize
1227 +                    color: "#99"+(theme.textColor.toString().substr(1))
1228 +                }
1229 +            }
1230 +        }
1231 +    }
1232 +}
1233 +
1234 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/BrightnessItem.qml b/plasma/generic/applets/batterymonitor/contents/ui/BrightnessItem.qml
1235 new file mode 100644
1236 index 0000000..34c596c
1237 --- /dev/null
1238 +++ b/plasma/generic/applets/batterymonitor/contents/ui/BrightnessItem.qml
1239 @@ -0,0 +1,89 @@
1240 +/*
1241 + *   Copyright 2012-2013 Daniel Nicoletti <dantti12@gmail.com>
1242 + *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
1243 + *
1244 + *   This program is free software; you can redistribute it and/or modify
1245 + *   it under the terms of the GNU Library General Public License as
1246 + *   published by the Free Software Foundation; either version 2 or
1247 + *   (at your option) any later version.
1248 + *
1249 + *   This program is distributed in the hope that it will be useful,
1250 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
1251 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1252 + *   GNU General Public License for more details
1253 + *
1254 + *   You should have received a copy of the GNU Library General Public
1255 + *   License along with this program; if not, write to the
1256 + *   Free Software Foundation, Inc.,
1257 + *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
1258 + */
1259 +
1260 +import QtQuick 1.1
1261 +import org.kde.plasma.core 0.1 as PlasmaCore
1262 +import org.kde.plasma.components 0.1 as Components
1263 +import org.kde.qtextracomponents 0.1
1264 +
1265 +Item {
1266 +    id: brightnessItem
1267 +    clip: true
1268 +    width: parent.width
1269 +    height: Math.max(brightnessIcon.height, brightnessLabel.height + brightnessSlider.height) + padding.margins.top + padding.margins.bottom
1270 +
1271 +    property alias icon: brightnessIcon.icon
1272 +    property alias label: brightnessLabel.text
1273 +    property alias value: brightnessSlider.value
1274 +
1275 +    signal changed(int screenBrightness)
1276 +
1277 +    QIconItem {
1278 +        id: brightnessIcon
1279 +        width: theme.iconSizes.dialog
1280 +        height: width
1281 +        anchors {
1282 +            verticalCenter: parent.verticalCenter
1283 +            topMargin: padding.margins.top
1284 +            bottomMargin: padding.margins.bottom
1285 +            left: parent.left
1286 +            leftMargin: padding.margins.left
1287 +        }
1288 +    }
1289 +
1290 +    Components.Label {
1291 +        id: brightnessLabel
1292 +        anchors {
1293 +            top: parent.top
1294 +            topMargin: padding.margins.top
1295 +            left: brightnessIcon.right
1296 +            leftMargin: 6
1297 +        }
1298 +        height: paintedHeight
1299 +    }
1300 +
1301 +    Components.Slider {
1302 +        id: brightnessSlider
1303 +        anchors {
1304 +            bottom: parent.bottom
1305 +            bottomMargin: padding.margins.bottom
1306 +            left: brightnessIcon.right
1307 +            right: brightnessPercent.left
1308 +            leftMargin: 6
1309 +            rightMargin: 6
1310 +        }
1311 +        minimumValue: 0
1312 +        maximumValue: 100
1313 +        stepSize: 10
1314 +        onValueChanged: changed(value)
1315 +    }
1316 +
1317 +    Components.Label {
1318 +        id: brightnessPercent
1319 +        anchors {
1320 +            right: parent.right
1321 +            rightMargin: padding.margins.right
1322 +            verticalCenter: brightnessSlider.verticalCenter
1323 +        }
1324 +        height: paintedHeight
1325 +        text: i18nc("Placeholder is brightness percentage", "%1%", brightnessSlider.value)
1326 +    }
1327 +}
1328 +
1329 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/CompactRepresentation.qml b/plasma/generic/applets/batterymonitor/contents/ui/CompactRepresentation.qml
1330 new file mode 100644
1331 index 0000000..ebab135
1332 --- /dev/null
1333 +++ b/plasma/generic/applets/batterymonitor/contents/ui/CompactRepresentation.qml
1334 @@ -0,0 +1,112 @@
1335 +/*
1336 +*   Copyright 2011 Sebastian Kügler <sebas@kde.org>
1337 +*   Copyright 2011 Viranch Mehta <viranch.mehta@gmail.com>
1338 +*   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
1339 +*
1340 +*   This program is free software; you can redistribute it and/or modify
1341 +*   it under the terms of the GNU Library General Public License as
1342 +*   published by the Free Software Foundation; either version 2 or
1343 +*   (at your option) any later version.
1344 +*
1345 +*   This program is distributed in the hope that it will be useful,
1346 +*   but WITHOUT ANY WARRANTY; without even the implied warranty of
1347 +*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1348 +*   GNU General Public License for more details
1349 +*
1350 +*   You should have received a copy of the GNU Library General Public
1351 +*   License along with this program; if not, write to the
1352 +*   Free Software Foundation, Inc.,
1353 +*   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
1354 +*/
1355 +
1356 +import QtQuick 1.1
1357 +import org.kde.plasma.core 0.1 as PlasmaCore
1358 +import org.kde.plasma.components 0.1 as Components
1359 +import "plasmapackage:/code/logic.js" as Logic
1360 +
1361 +ListView {
1362 +    id: view
1363 +
1364 +    property int minimumWidth
1365 +    property int minimumHeight
1366 +
1367 +    property bool hasBattery
1368 +
1369 +    property QtObject pmSource
1370 +    property QtObject batteries
1371 +
1372 +    property bool singleBattery
1373 +
1374 +    model: singleBattery ? 1 : batteries
1375 +
1376 +    anchors.fill: parent
1377 +    orientation: ListView.Horizontal
1378 +    interactive: false
1379 +
1380 +    function isConstrained() {
1381 +        return (plasmoid.formFactor == Vertical || plasmoid.formFactor == Horizontal);
1382 +    }
1383 +
1384 +    Component.onCompleted: {
1385 +        if (!isConstrained()) {
1386 +            minimumHeight = theme.iconSizes.dialog;
1387 +            minimumWidth = minimumHeight * view.count;
1388 +        } else {
1389 +            // NOTE: Keep in sync with systray
1390 +            minimumHeight = 24;
1391 +            minimumWidth = 24;
1392 +        }
1393 +    }
1394 +
1395 +    delegate: Item {
1396 +        id: batteryContainer
1397 +
1398 +        property bool hasBattery: view.singleBattery ? batteries.count : model["Plugged in"]
1399 +        property int percent: view.singleBattery ? batteries.cumulativePercent : model["Percent"]
1400 +        property bool pluggedIn: view.singleBattery ? pmSource.data["AC Adapter"]["Plugged in"] : pmSource.data["AC Adapter"]["Plugged in"] && model["Is Power Supply"]
1401 +
1402 +        width: view.width/view.count
1403 +        height: view.height
1404 +
1405 +        property real iconSize: Math.min(width, height)
1406 +
1407 +        Column {
1408 +            anchors.fill: parent
1409 +
1410 +            BatteryIcon {
1411 +                id: batteryIcon
1412 +                anchors.centerIn: isConstrained() ? parent : undefined
1413 +                anchors.horizontalCenter: isConstrained() ? undefined : parent.horizontalCenter
1414 +                hasBattery: batteryContainer.hasBattery
1415 +                percent: batteryContainer.percent
1416 +                pluggedIn: batteryContainer.pluggedIn
1417 +                height: isConstrained() ? batteryContainer.iconSize : batteryContainer.iconSize - batteryLabel.height
1418 +                width: height
1419 +            }
1420 +
1421 +            Components.Label {
1422 +                id: batteryLabel
1423 +                width: parent.width
1424 +                height: paintedHeight
1425 +                horizontalAlignment: Text.AlignHCenter
1426 +                text: i18nc("battery percentage below battery icon", "%1%", percent)
1427 +                font.pixelSize: Math.max(batteryContainer.iconSize/8, 10)
1428 +                visible: !isConstrained()
1429 +            }
1430 +        }
1431 +    }
1432 +
1433 +    MouseArea {
1434 +        id: mouseArea
1435 +        anchors.fill: parent
1436 +        hoverEnabled: true
1437 +        onClicked: plasmoid.togglePopup()
1438 +
1439 +        PlasmaCore.ToolTip {
1440 +            id: tooltip
1441 +            target: mouseArea
1442 +            image: batteries.tooltipImage
1443 +            subText: batteries.tooltipText
1444 +        }
1445 +    }
1446 +}
1447 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/PopupDialog.qml b/plasma/generic/applets/batterymonitor/contents/ui/PopupDialog.qml
1448 index 76fb1ce..4f46834 100644
1449 --- a/plasma/generic/applets/batterymonitor/contents/ui/PopupDialog.qml
1450 +++ b/plasma/generic/applets/batterymonitor/contents/ui/PopupDialog.qml
1451 @@ -1,5 +1,6 @@
1452  /*
1453   *   Copyright 2011 Viranch Mehta <viranch.mehta@gmail.com>
1454 + *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
1455   *
1456   *   This program is free software; you can redistribute it and/or modify
1457   *   it under the terms of the GNU Library General Public License as
1458 @@ -18,176 +19,106 @@
1459   */
1460  
1461  import QtQuick 1.1
1462 +import org.kde.plasma.core 0.1 as PlasmaCore
1463  import org.kde.plasma.components 0.1 as Components
1464 +import org.kde.qtextracomponents 0.1
1465  import "plasmapackage:/code/logic.js" as Logic
1466  
1467  Item {
1468      id: dialog
1469 -    width: childrenRect.width+24
1470 -    height: childrenRect.height+24
1471 +    property int actualHeight: batteryColumn.implicitHeight + settingsColumn.height + separator.height + 10 // 10 = separator margins
1472  
1473 -    property alias model: batteryLabels.model
1474 -    property alias hasBattery: batteryIcon.hasBattery
1475 -    property alias percent: batteryIcon.percent
1476 +    property alias model: batteryList.model
1477      property bool pluggedIn
1478 +    property bool showRemainingTime
1479 +
1480 +    property bool popupShown // somehow plasmoid.popupShowing isn't working
1481 +
1482 +    property bool isBrightnessAvailable
1483      property alias screenBrightness: brightnessSlider.value
1484 -    property int remainingMsec
1485 -    property alias showSuspendButton: suspendButton.visible
1486 -    property alias showHibernateButton: hibernateButton.visible
1487  
1488 +    property bool isKeyboardBrightnessAvailable
1489 +    property alias keyboardBrightness: keyboardBrightnessSlider.value
1490  
1491 -    signal suspendClicked(int type)
1492      signal brightnessChanged(int screenBrightness)
1493 +    signal keyboardBrightnessChanged(int keyboardBrightness)
1494      signal powermanagementChanged(bool checked)
1495  
1496 +    PlasmaCore.FrameSvgItem {
1497 +        id: padding
1498 +        imagePath: "widgets/viewitem"
1499 +        prefix: "hover"
1500 +        opacity: 0
1501 +    }
1502 +
1503      Column {
1504 -        id: labels
1505 -        spacing: 6
1506 +        id: batteryColumn
1507 +        spacing: 4
1508 +        width: parent.width
1509          anchors {
1510 -            top: parent.top
1511              left: parent.left
1512 -            margins: 12
1513 -        }
1514 -        Repeater {
1515 -            model: dialog.model
1516 -            Components.Label {
1517 -                text: model.count>1 ? i18nc("Placeholder is the battery ID", "Battery %1:", index+1) : i18n("Battery:")
1518 -                width: labels.width
1519 -                horizontalAlignment: Text.AlignRight
1520 -            }
1521 -        }
1522 -
1523 -        Components.Label {
1524 -            text: i18n("AC Adapter:")
1525 -            anchors.right: parent.right
1526 -            anchors.bottomMargin: 12
1527 -        }
1528 -
1529 -        Components.Label {
1530 -            text: i18nc("Label for remaining time", "Time Remaining:")
1531 -            visible: remainingTime.visible
1532 -            anchors.right: parent.right
1533 -        }
1534 -
1535 -        Components.Label {
1536 -            text: i18nc("Label for power management inhibition", "Power management enabled:")
1537 -            anchors.right: parent.right
1538 +            right: parent.right
1539 +            top: plasmoid.location == BottomEdge ? parent.top : undefined
1540 +            bottom: plasmoid.location == BottomEdge ? undefined : parent.bottom
1541          }
1542  
1543 -        Components.Label {
1544 -            text: i18n("Screen Brightness:")
1545 -            anchors.right: parent.right
1546 +        Repeater {
1547 +            id: batteryList
1548 +            delegate: BatteryItem { showChargeAnimation: popupShown }
1549          }
1550      }
1551  
1552      Column {
1553 -        id: values
1554 -        spacing: 6
1555 -        anchors {
1556 -            top: parent.top
1557 -            left: labels.right
1558 -            margins: 12
1559 -        }
1560 +        id: settingsColumn
1561 +        spacing: 0
1562 +        width: parent.width
1563  
1564 -        Column {
1565 -            id: upperValues
1566 -            spacing: 6
1567 -            anchors {
1568 -                left: values.left
1569 -            }
1570 -
1571 -            Repeater {
1572 -                id: batteryLabels
1573 -                Components.Label {
1574 -                    text: Logic.stringForState(model)
1575 -                    font.weight: Font.Bold
1576 -                }
1577 -            }
1578 -
1579 -            Components.Label {
1580 -                text: dialog.pluggedIn ? i18n("Plugged in") : i18n("Not plugged in")
1581 -                font.weight: Font.Bold
1582 -                anchors.bottomMargin: 12
1583 -            }
1584 -
1585 -            Components.Label {
1586 -                id: remainingTime
1587 -                text: formatDuration(remainingMsec);
1588 -                font.weight: Font.Bold
1589 -                visible: text!=""
1590 -            }
1591 -        }
1592 -
1593 -        Column {
1594 -            id: lowerValues
1595 -            spacing: 6
1596 -            width: upperValues.width + batteryIcon.width * 2
1597 -            anchors {
1598 -                left: values.left
1599 -            }
1600 -            Components.CheckBox {
1601 -                checked: true
1602 -                onClicked: powermanagementChanged(checked)
1603 -                x: 1
1604 -            }
1605 -
1606 -            Components.Slider {
1607 -                id: brightnessSlider
1608 -                width: lowerValues.width
1609 -                minimumValue: 0
1610 -                maximumValue: 100
1611 -                stepSize: 10
1612 -                onValueChanged: brightnessChanged(value)
1613 -            }
1614 +        anchors {
1615 +            left: parent.left
1616 +            right: parent.right
1617 +            top: plasmoid.location == BottomEdge ? undefined : parent.top
1618 +            bottom: plasmoid.location == BottomEdge ? parent.bottom : undefined
1619          }
1620 -    }
1621  
1622 -    // TODO: give translated and formatted string with KGlobal::locale()->prettyFormatDuration(msec);
1623 -    function formatDuration(msec) {
1624 -        if (msec==0)
1625 -            return "";
1626 -
1627 -        var time = new Date(msec);
1628 -        var hours = time.getUTCHours();
1629 -        var minutes = time.getUTCMinutes();
1630 -        var str = "";
1631 -        if (hours > 0) str += i18np("1 hour ", "%1 hours ", hours);
1632 -        if (minutes > 0) str += i18np("1 minute", "%1 minutes", minutes);
1633 -        return str;
1634 -    }
1635 +        BrightnessItem {
1636 +            id: brightnessSlider
1637 +            icon: QIcon("video-display")
1638 +            label: i18n("Display Brightness")
1639 +            visible: isBrightnessAvailable
1640 +            onChanged: brightnessChanged(value)
1641  
1642 -    Row {
1643 -        anchors {
1644 -            top: values.bottom
1645 -            margins: 12
1646 -            right: values.right
1647          }
1648  
1649 -        Components.ToolButton {
1650 -            id: suspendButton
1651 -            iconSource: "system-suspend"
1652 -            text: i18nc("Suspend the computer to RAM; translation should be short", "Sleep")
1653 -            onClicked: suspendClicked(Logic.ram)
1654 +        BrightnessItem {
1655 +            id: keyboardBrightnessSlider
1656 +            icon: QIcon("input-keyboard")
1657 +            label: i18n("Keyboard Brightness")
1658 +            visible: isKeyboardBrightnessAvailable
1659 +            onChanged: keyboardBrightnessChanged(value)
1660          }
1661  
1662 -        Components.ToolButton {
1663 -            id: hibernateButton
1664 -            iconSource: "system-suspend-hibernate"
1665 -            text: i18nc("Suspend the computer to disk; translation should be short", "Hibernate")
1666 -            onClicked: suspendClicked(Logic.disk)
1667 +        PowerManagementItem {
1668 +            id: pmSwitch
1669 +            onEnabledChanged: powermanagementChanged(enabled)
1670          }
1671      }
1672  
1673 -    BatteryIcon {
1674 -        id: batteryIcon
1675 -        monochrome: false
1676 -        pluggedIn: dialog.pluggedIn
1677 +    PlasmaCore.SvgItem {
1678 +        id: separator
1679 +        svg: PlasmaCore.Svg {
1680 +            id: lineSvg
1681 +            imagePath: "widgets/line"
1682 +        }
1683 +        elementId: "horizontal-line"
1684 +        height: lineSvg.elementSize("horizontal-line").height
1685 +        width: parent.width
1686          anchors {
1687 -            top: parent.top
1688 -            right: values.right
1689 -            topMargin: 12
1690 +            top: plasmoid.location == BottomEdge ? undefined : settingsColumn.bottom
1691 +            bottom: plasmoid.location == BottomEdge ? settingsColumn.top : undefined
1692 +            leftMargin: padding.margins.left
1693 +            rightMargin: padding.margins.right
1694 +            topMargin: 5
1695 +            bottomMargin: 5
1696          }
1697 -        width: height
1698 -        height: hibernateButton.height * 2
1699      }
1700  }
1701 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/PowerManagementItem.qml b/plasma/generic/applets/batterymonitor/contents/ui/PowerManagementItem.qml
1702 new file mode 100644
1703 index 0000000..85555ac
1704 --- /dev/null
1705 +++ b/plasma/generic/applets/batterymonitor/contents/ui/PowerManagementItem.qml
1706 @@ -0,0 +1,64 @@
1707 +/*
1708 + *   Copyright 2012-2013 Daniel Nicoletti <dantti12@gmail.com>
1709 + *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
1710 + *
1711 + *   This program is free software; you can redistribute it and/or modify
1712 + *   it under the terms of the GNU Library General Public License as
1713 + *   published by the Free Software Foundation; either version 2 or
1714 + *   (at your option) any later version.
1715 + *
1716 + *   This program is distributed in the hope that it will be useful,
1717 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
1718 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1719 + *   GNU General Public License for more details
1720 + *
1721 + *   You should have received a copy of the GNU Library General Public
1722 + *   License along with this program; if not, write to the
1723 + *   Free Software Foundation, Inc.,
1724 + *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
1725 + */
1726 +
1727 +import QtQuick 1.1
1728 +import org.kde.plasma.core 0.1 as PlasmaCore
1729 +import org.kde.plasma.components 0.1 as Components
1730 +import org.kde.qtextracomponents 0.1
1731 +
1732 +Item {
1733 +    id: brightnessItem
1734 +    clip: true
1735 +    width: parent.width
1736 +    height: Math.max(pmCheckBox.height, pmLabel.height) + padding.margins.top + padding.margins.bottom
1737 +
1738 +    property bool enabled: pmCheckBox.checked
1739 +
1740 +    Components.CheckBox {
1741 +        id: pmCheckBox
1742 +        anchors {
1743 +            verticalCenter: parent.verticalCenter
1744 +            left: parent.left
1745 +            leftMargin: padding.margins.left + (theme.iconSizes.dialog - width)
1746 +            topMargin: padding.margins.top
1747 +            bottomMargin: padding.margins.bottom
1748 +        }
1749 +        checked: true
1750 +    }
1751 +
1752 +    Components.Label {
1753 +        id: pmLabel
1754 +        anchors {
1755 +            verticalCenter: pmCheckBox.verticalCenter
1756 +            left: pmCheckBox.right
1757 +            leftMargin: 6
1758 +        }
1759 +        height: paintedHeight
1760 +        text: i18n("Enable Power Management")
1761 +    }
1762 +
1763 +    MouseArea {
1764 +        anchors.fill: parent
1765 +
1766 +        onReleased: pmCheckBox.released();
1767 +        onPressed: pmCheckBox.forceActiveFocus();
1768 +    }
1769 +}
1770 +
1771 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/ScrollableListView.qml b/plasma/generic/applets/batterymonitor/contents/ui/ScrollableListView.qml
1772 new file mode 100644
1773 index 0000000..c3cb818
1774 --- /dev/null
1775 +++ b/plasma/generic/applets/batterymonitor/contents/ui/ScrollableListView.qml
1776 @@ -0,0 +1,58 @@
1777 +/*
1778 + *   Copyright 2012 Daniel Nicoletti <dantti12@gmail.com>
1779 + *
1780 + *   This program is free software; you can redistribute it and/or modify
1781 + *   it under the terms of the GNU Library General Public License as
1782 + *   published by the Free Software Foundation; either version 2 or
1783 + *   (at your option) any later version.
1784 + *
1785 + *   This program is distributed in the hope that it will be useful,
1786 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
1787 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1788 + *   GNU General Public License for more details
1789 + *
1790 + *   You should have received a copy of the GNU Library General Public
1791 + *   License along with this program; if not, write to the
1792 + *   Free Software Foundation, Inc.,
1793 + *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
1794 + */
1795 +
1796 +import QtQuick 1.1
1797 +import org.kde.plasma.core 0.1 as PlasmaCore
1798 +import org.kde.plasma.components 0.1 as Components
1799 +import org.kde.qtextracomponents 0.1
1800 +
1801 +FocusScope {
1802 +    property alias delegate: list.delegate
1803 +    property alias model: list.model
1804 +    property alias view: list
1805 +    property alias interactive: list.interactive
1806 +    property alias currentIndex: list.currentIndex
1807 +    signal countChanged()
1808 +
1809 +    Component.onCompleted: {
1810 +        list.countChanged.connect(countChanged)
1811 +    }
1812 +
1813 +    ListView {
1814 +        id: list
1815 +        clip: true
1816 +        focus: true
1817 +        anchors {
1818 +            left:   parent.left
1819 +            right:  scrollBar.visible ? scrollBar.left : parent.right
1820 +            top :   parent.top
1821 +            bottom: parent.bottom
1822 +        }
1823 +        boundsBehavior: Flickable.StopAtBounds
1824 +    }
1825 +    Components.ScrollBar {
1826 +        id: scrollBar
1827 +        flickableItem: list
1828 +        anchors {
1829 +            right: parent.right
1830 +            top: list.top
1831 +            bottom: list.bottom
1832 +        }
1833 +    }
1834 +}
1835 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml b/plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml
1836 index a5e1c13..357c2dc 100644
1837 --- a/plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml
1838 +++ b/plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml
1839 @@ -1,6 +1,7 @@
1840  /*
1841   *   Copyright 2011 Sebastian Kügler <sebas@kde.org>
1842   *   Copyright 2011 Viranch Mehta <viranch.mehta@gmail.com>
1843 + *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
1844   *
1845   *   This program is free software; you can redistribute it and/or modify
1846   *   it under the terms of the GNU Library General Public License as
1847 @@ -21,128 +22,46 @@
1848  import QtQuick 1.1
1849  import org.kde.plasma.core 0.1 as PlasmaCore
1850  import "plasmapackage:/code/logic.js" as Logic
1851 -import "plasmapackage:/code/platform.js" as Platform
1852  
1853  Item {
1854      id: batterymonitor
1855 -    property int minimumWidth: dialogItem.width
1856 -    property int minimumHeight: dialogItem.height
1857 +    property int minimumWidth: theme.iconSizes.dialog * 9
1858 +    property int minimumHeight: dialogItem.actualHeight
1859 +    property int maximumHeight: dialogItem.actualHeight
1860  
1861      property bool show_remaining_time: false
1862  
1863 +    PlasmaCore.Theme { id: theme }
1864 +
1865      Component.onCompleted: {
1866 -        Logic.updateCumulative();
1867 -        Logic.updateTooltip();
1868 -        Logic.updateBrightness();
1869 +        plasmoid.aspectRatioMode = IgnoreAspectRatio
1870 +        updateLogic(true);
1871          plasmoid.addEventListener('ConfigChanged', configChanged);
1872 +        plasmoid.popupEvent.connect(popupEventSlot);
1873      }
1874  
1875      function configChanged() {
1876          show_remaining_time = plasmoid.readConfig("showRemainingTime");
1877      }
1878  
1879 -    property Component compactRepresentation: Component {
1880 -        ListView {
1881 -            id: view
1882 -
1883 -            property int minimumWidth
1884 -            property int minimumHeight
1885 -
1886 -            property bool showOverlay: false
1887 -            property bool showMultipleBatteries: false
1888 -            property bool hasBattery: pmSource.data["Battery"]["Has Battery"]
1889 -
1890 -            property QtObject pmSource: plasmoid.rootItem.pmSource
1891 -            property QtObject batteries: plasmoid.rootItem.batteries
1892 -
1893 -            property bool singleBattery: isConstrained() || !showMultipleBatteries || !hasBattery
1894 -
1895 -            model: singleBattery ? 1 : batteries
1896 -
1897 -            PlasmaCore.Theme { id: theme }
1898 -
1899 -            anchors.fill: parent
1900 -            orientation: ListView.Horizontal
1901 -
1902 -            function isConstrained() {
1903 -                return (plasmoid.formFactor == Vertical || plasmoid.formFactor == Horizontal);
1904 -            }
1905 -
1906 -            Component.onCompleted: {
1907 -                if (!isConstrained()) {
1908 -                    minimumWidth = 32;
1909 -                    minimumHeight = 32;
1910 -                }
1911 -                plasmoid.addEventListener('ConfigChanged', configChanged);
1912 -            }
1913 -
1914 -            function configChanged() {
1915 -                showOverlay = plasmoid.readConfig("showBatteryString");
1916 -                showMultipleBatteries = plasmoid.readConfig("showMultipleBatteries");
1917 -            }
1918 -
1919 -            delegate: Item {
1920 -                id: batteryContainer
1921 -
1922 -                property bool hasBattery: view.singleBattery ? batteries.cumulativePluggedin : model["Plugged in"]
1923 -                property int percent: view.singleBattery ? batteries.cumulativePercent : model["Percent"]
1924 -                property bool pluggedIn: pmSource.data["AC Adapter"]["Plugged in"]
1925 -
1926 -                width: view.width/view.count
1927 -                height: view.height
1928 -
1929 -                property real size: Math.min(width, height)
1930 -
1931 -                BatteryIcon {
1932 -                    id: batteryIcon
1933 -                    monochrome: true
1934 -                    hasBattery: parent.hasBattery
1935 -                    percent: parent.percent
1936 -                    pluggedIn: parent.pluggedIn
1937 -                    width: size; height: size
1938 -                    anchors.centerIn: parent
1939 -                }
1940 -
1941 -                Rectangle {
1942 -                    id: labelRect
1943 -                    // should be 40 when size is 90
1944 -                    width: Math.max(parent.size*4/9, 35)
1945 -                    height: width/2
1946 -                    anchors.centerIn: parent
1947 -                    color: theme.backgroundColor
1948 -                    border.color: "grey"
1949 -                    border.width: 2
1950 -                    radius: 4
1951 -                    opacity: hasBattery ? (showOverlay ? 0.7 : (isConstrained() ? 0 : mouseArea.containsMouse*0.7)) : 0
1952 -
1953 -                    Behavior on opacity { NumberAnimation { duration: 100 } }
1954 -                }
1955 -
1956 -                Text {
1957 -                    id: overlayText
1958 -                    text: i18nc("overlay on the battery, needs to be really tiny", "%1%", percent);
1959 -                    color: theme.textColor
1960 -                    font.pixelSize: Math.max(parent.size/8, 11)
1961 -                    anchors.centerIn: labelRect
1962 -                    // keep the opacity 1 when labelRect.opacity=0.7
1963 -                    opacity: labelRect.opacity/0.7
1964 -                }
1965 -            }
1966 +    function updateLogic(updateBrightness) {
1967 +        Logic.updateCumulative();
1968 +        plasmoid.status = Logic.plasmoidStatus();
1969 +        Logic.updateTooltip();
1970 +        if (updateBrightness) {
1971 +            Logic.updateBrightness();
1972 +        }
1973 +    }
1974  
1975 -            MouseArea {
1976 -                id: mouseArea
1977 -                anchors.fill: parent
1978 -                hoverEnabled: true
1979 -                onClicked: plasmoid.togglePopup()
1980 +    function popupEventSlot(popped) {
1981 +        dialogItem.popupShown = popped;
1982 +    }
1983  
1984 -                PlasmaCore.ToolTip {
1985 -                    id: tooltip
1986 -                    target: mouseArea
1987 -                    image: "battery"
1988 -                    subText: batteries.tooltipText
1989 -                }
1990 -            }
1991 -        }
1992 +    property Component compactRepresentation: CompactRepresentation {
1993 +        hasBattery: pmSource.data["Battery"]["Has Battery"]
1994 +        pmSource: plasmoid.rootItem.pmSource
1995 +        batteries: plasmoid.rootItem.batteries
1996 +        singleBattery: isConstrained() || !hasBattery
1997      }
1998  
1999      property QtObject pmSource: PlasmaCore.DataSource {
2000 @@ -150,12 +69,11 @@ Item {
2001          engine: "powermanagement"
2002          connectedSources: sources
2003          onDataChanged: {
2004 -            Logic.updateTooltip();
2005 -            Logic.updateBrightness();
2006 +            updateLogic(true);
2007          }
2008          onSourceAdded: {
2009              if (source == "Battery0") {
2010 -               disconnectSource(source);
2011 +                disconnectSource(source);
2012                  connectSource(source);
2013              }
2014          }
2015 @@ -172,45 +90,31 @@ Item {
2016          sourceFilter: "Battery[0-9]+"
2017  
2018          onDataChanged: {
2019 -            Logic.updateCumulative();
2020 -
2021 -            var status = "PassiveStatus";
2022 -            if (batteries.cumulativePluggedin) {
2023 -                if (batteries.cumulativePercent <= 10) {
2024 -                    status = "NeedsAttentionStatus";
2025 -                } else if (!batteries.allCharged) {
2026 -                    status = "ActiveStatus";
2027 -                }
2028 -            }
2029 -            plasmoid.status = status;
2030 +            updateLogic()
2031          }
2032  
2033          property int cumulativePercent
2034 -        property bool cumulativePluggedin: count > 0
2035 +        property bool cumulativePluggedin
2036          // true  --> all batteries charged
2037          // false --> one of the batteries charging/discharging
2038          property bool allCharged
2039          property string tooltipText
2040 +        property string tooltipImage
2041      }
2042  
2043      PopupDialog {
2044          id: dialogItem
2045          property bool disableBrightnessUpdate: false
2046          model: batteries
2047 -        hasBattery: batteries.cumulativePluggedin
2048 -        percent: batteries.cumulativePercent
2049 +        anchors.fill: parent
2050 +
2051 +        isBrightnessAvailable: pmSource.data["PowerDevil"]["Screen Brightness Available"] ? true : false
2052 +        isKeyboardBrightnessAvailable: pmSource.data["PowerDevil"]["Keyboard Brightness Available"] ? true : false
2053 +
2054 +        showRemainingTime: show_remaining_time
2055 +
2056          pluggedIn: pmSource.data["AC Adapter"]["Plugged in"]
2057 -        remainingMsec: parent.show_remaining_time ? Number(pmSource.data["Battery"]["Remaining msec"]) : 0
2058 -        showSuspendButton: Platform.shouldOfferSuspend(pmSource)
2059 -        showHibernateButton: Platform.shouldOfferHibernate(pmSource)
2060  
2061 -        onSuspendClicked: {
2062 -            plasmoid.togglePopup();
2063 -            service = pmSource.serviceForSource("PowerDevil");
2064 -            var operationName = Logic.callForType(type);
2065 -            operation = service.operationDescription(operationName);
2066 -            service.startOperationCall(operation);
2067 -        }
2068          onBrightnessChanged: {
2069              if (disableBrightnessUpdate) {
2070                  return;
2071 @@ -220,6 +124,15 @@ Item {
2072              operation.brightness = screenBrightness;
2073              service.startOperationCall(operation);
2074          }
2075 +        onKeyboardBrightnessChanged: {
2076 +            if (disableBrightnessUpdate) {
2077 +                return;
2078 +            }
2079 +            service = pmSource.serviceForSource("PowerDevil");
2080 +            operation = service.operationDescription("setKeyboardBrightness");
2081 +            operation.brightness = keyboardBrightness;
2082 +            service.startOperationCall(operation);
2083 +        }
2084          property int cookie1: -1
2085          property int cookie2: -1
2086          onPowermanagementChanged: {
2087 @@ -256,6 +169,8 @@ Item {
2088                      cookie2 = job.result;
2089                  });
2090              }
2091 +            Logic.powermanagementDisabled = !checked;
2092 +            updateLogic();
2093          }
2094      }
2095  }
2096 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/config.ui b/plasma/generic/applets/batterymonitor/contents/ui/config.ui
2097 deleted file mode 100644
2098 index 3df38e2..0000000
2099 --- a/plasma/generic/applets/batterymonitor/contents/ui/config.ui
2100 +++ /dev/null
2101 @@ -1,54 +0,0 @@
2102 -<?xml version="1.0" encoding="UTF-8"?>
2103 -<ui version="4.0">
2104 - <class>batteryConfig</class>
2105 - <widget class="QWidget" name="batteryConfig">
2106 -  <property name="geometry">
2107 -   <rect>
2108 -    <x>0</x>
2109 -    <y>0</y>
2110 -    <width>247</width>
2111 -    <height>73</height>
2112 -   </rect>
2113 -  </property>
2114 -  <property name="windowTitle">
2115 -   <string>Configure Battery Monitor</string>
2116 -  </property>
2117 -  <layout class="QVBoxLayout" name="verticalLayout">
2118 -   <item>
2119 -    <widget class="QCheckBox" name="kcfg_showBatteryString">
2120 -     <property name="toolTip">
2121 -      <string/>
2122 -     </property>
2123 -     <property name="text">
2124 -      <string>Show charge &amp;information</string>
2125 -     </property>
2126 -    </widget>
2127 -   </item>
2128 -   <item>
2129 -    <widget class="QCheckBox" name="kcfg_showMultipleBatteries">
2130 -     <property name="toolTip">
2131 -      <string/>
2132 -     </property>
2133 -     <property name="text">
2134 -      <string>Show the state for &amp;each battery present</string>
2135 -     </property>
2136 -    </widget>
2137 -   </item>
2138 -   <item>
2139 -    <spacer name="verticalSpacer">
2140 -     <property name="orientation">
2141 -      <enum>Qt::Vertical</enum>
2142 -     </property>
2143 -     <property name="sizeHint" stdset="0">
2144 -      <size>
2145 -       <width>20</width>
2146 -       <height>15</height>
2147 -      </size>
2148 -     </property>
2149 -    </spacer>
2150 -   </item>
2151 -  </layout>
2152 - </widget>
2153 - <resources/>
2154 - <connections/>
2155 -</ui>
2156 diff --git a/plasma/generic/applets/batterymonitor/metadata.desktop b/plasma/generic/applets/batterymonitor/metadata.desktop
2157 index cd8f1a2..2b70e2c 100644
2158 --- a/plasma/generic/applets/batterymonitor/metadata.desktop
2159 +++ b/plasma/generic/applets/batterymonitor/metadata.desktop
2160 @@ -159,7 +159,6 @@ Comment[zh_CN]=查看电池电源的状态
2161  Comment[zh_TW]=查看您的電池的電力狀態
2162  Encoding=UTF-8
2163  Keywords=Power Management;Battery;System;Energy;
2164 -Keywords[bs]=Upravljanje napajenjem, Baterija, Sistem, Energija
2165  Keywords[ca]=Sistema de gestió d'energia;Bateria;Sistema;Energia;
2166  Keywords[cs]=Správa napájení;Baterie;Systém;Energie;
2167  Keywords[da]=Strømstyring;battery;system;energi;
2168 @@ -167,17 +166,16 @@ Keywords[de]=Energieverwaltungssystem;Akku;System;Energie;
2169  Keywords[el]=Διαχείριση ισχύος·Μπαταρία·Σύστημα·Ενέργεια·
2170  Keywords[es]=Gestión de energía;Batería;Sistema;Energía;
2171  Keywords[fi]=Virranhallinta;Akku;Järjestelmä;Virransäästö;
2172 -Keywords[fr]=Gestion de l'énergie, Batterie, Système, Énergie, 
2173 -Keywords[gl]=Power Management;Battery;System;Energy;xestión da enerxía;batería;sistema;
2174 +Keywords[fr]=Gestion de l'énergie, Batterie, Système, Énergie,
2175  Keywords[hu]=Energiakezelés;Akkumulátor;Rendszer;Energia;
2176 -Keywords[ia]=Gestion de energia; Batteria;Systema; Energia;
2177 -Keywords[it]=Gestione energetica;Batteria;Sistema;Energia;
2178 +Keywords[ia]=Gestion de energia;Batteria;Systema; Energia;
2179  Keywords[kk]=Power Management;Battery;System;Energy;
2180  Keywords[lt]=Energijos valdymas,Baterija,Sistema,Energija,akumuliatorius;
2181  Keywords[mr]=वीज व्यवस्थापन; बॅटरी; प्रणाली; ऊर्जा;
2182  Keywords[nb]=Strømstyring; Batteri; System; Energi;
2183  Keywords[nl]=Energiebeheer;Batterij;Accu;Systeem;Energie;
2184 -Keywords[pl]=Zarządzanie energią;bateria;system;energia;
2185 +Keywords[pa]=ਪਾਵਰ ਪਰਬੰਧ;ਬੈਟਰੀ;ਸਿਸਟਮ;ਊਰਜਾ;
2186 +Keywords[pl]=Zarządzanie Energią;Bateria;System;Energia
2187  Keywords[pt]=Gestão de Energia;Bateria;Sistema;Energia;
2188  Keywords[pt_BR]=Gerenciamento de energia;Bateria;Sistema;Energia;
2189  Keywords[ru]=Power Management;Battery;System;Energy;управление питанием;батарея;система;энергия;энергопотребление
2190 @@ -198,17 +196,17 @@ Type=Service
2191  X-KDE-ServiceTypes=Plasma/Applet,Plasma/PopupApplet
2192  
2193  X-Plasma-API=declarativeappletscript
2194 -X-Plasma-DefaultSize=100,100
2195 +X-Plasma-DefaultSize=450,300
2196  X-Plasma-MainScript=ui/batterymonitor.qml
2197  X-Plasma-ConfigPlugins=powerdevilprofilesconfig,powerdevilactivitiesconfig,powerdevilglobalconfig
2198  X-Plasma-NotificationArea=true
2199  
2200 -X-KDE-PluginInfo-Author=Sebastian Kügler
2201 +X-KDE-PluginInfo-Author=Sebastian Kügler, Kai Uwe Broulik
2202  X-KDE-PluginInfo-Category=System Information
2203 -X-KDE-PluginInfo-Email=sebas@kde.org
2204 +X-KDE-PluginInfo-Email=sebas@kde.org, kde@privat.broulik.de
2205  X-KDE-PluginInfo-License=GPL
2206  X-KDE-PluginInfo-Name=battery
2207 -X-KDE-PluginInfo-Version=1.0
2208 +X-KDE-PluginInfo-Version=2.0
2209  X-KDE-PluginInfo-Website=http://vizZzion.org
2210  X-KDE-PluginInfo-Depends=
2211  X-KDE-PluginInfo-EnabledByDefault=true
2212 diff --git a/plasma/generic/applets/batterymonitor/platformcontents/touch/code/platform.js b/plasma/generic/applets/batterymonitor/platformcontents/touch/code/platform.js
2213 deleted file mode 100644
2214 index aa57ab8..0000000
2215 --- a/plasma/generic/applets/batterymonitor/platformcontents/touch/code/platform.js
2216 +++ /dev/null
2217 @@ -1,9 +0,0 @@
2218 -
2219 -function shouldOfferSuspend() {
2220 -    return false;
2221 -}
2222 -
2223 -function shouldOfferHibernate() {
2224 -    return false;
2225 -}
2226 -
2227 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml b/plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml
2228 index 357c2dc..feda7bc 100644
2229 --- a/plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml
2230 +++ b/plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml
2231 @@ -84,13 +84,19 @@ Item {
2232          }
2233      }
2234  
2235 -    property QtObject batteries: PlasmaCore.DataModel {
2236 +    property QtObject batteries: PlasmaCore.SortFilterModel {
2237          id: batteries
2238 -        dataSource: pmSource
2239 -        sourceFilter: "Battery[0-9]+"
2240 -
2241 -        onDataChanged: {
2242 -            updateLogic()
2243 +        filterRole: "Is Power Supply"
2244 +        sortOrder: Qt.DescendingOrder
2245 +        sourceModel: PlasmaCore.SortFilterModel {
2246 +            sortRole: "Pretty Name"
2247 +            sortOrder: Qt.AscendingOrder
2248 +            sourceModel: PlasmaCore.DataModel {
2249 +                dataSource: pmSource
2250 +                sourceFilter: "Battery[0-9]+"
2251 +
2252 +                onDataChanged: updateLogic()
2253 +            }
2254          }
2255  
2256          property int cumulativePercent
2257 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/AcAdapterItem.qml b/plasma/generic/applets/batterymonitor/contents/ui/AcAdapterItem.qml
2258 deleted file mode 100644
2259 index c2216f8..0000000
2260 --- a/plasma/generic/applets/batterymonitor/contents/ui/AcAdapterItem.qml
2261 +++ /dev/null
2262 @@ -1,87 +0,0 @@
2263 -/*
2264 - *   Copyright 2012-2013 Daniel Nicoletti <dantti12@gmail.com>
2265 - *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
2266 - *
2267 - *   This program is free software; you can redistribute it and/or modify
2268 - *   it under the terms of the GNU Library General Public License as
2269 - *   published by the Free Software Foundation; either version 2 or
2270 - *   (at your option) any later version.
2271 - *
2272 - *   This program is distributed in the hope that it will be useful,
2273 - *   but WITHOUT ANY WARRANTY; without even the implied warranty of
2274 - *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2275 - *   GNU General Public License for more details
2276 - *
2277 - *   You should have received a copy of the GNU Library General Public
2278 - *   License along with this program; if not, write to the
2279 - *   Free Software Foundation, Inc.,
2280 - *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
2281 - */
2282 -
2283 -import QtQuick 1.1
2284 -import org.kde.plasma.core 0.1 as PlasmaCore
2285 -import org.kde.plasma.components 0.1 as Components
2286 -import org.kde.qtextracomponents 0.1
2287 -
2288 -Item {
2289 -    id: brightnessItem
2290 -    clip: true
2291 -    width: parent.width
2292 -    height: acIcon.height + padding.margins.top + padding.margins.bottom
2293 -
2294 -    property bool pluggedIn
2295 -    property bool showTime
2296 -    property string remainingString
2297 -
2298 -    QIconItem {
2299 -        id: acIcon
2300 -        width: theme.iconSizes.dialog
2301 -        height: width
2302 -        anchors {
2303 -            top: parent.top
2304 -            topMargin: padding.margins.top
2305 -            left: parent.left
2306 -            leftMargin: padding.margins.left
2307 -        }
2308 -
2309 -        icon: pluggedIn ? QIcon("battery-charging-low") : QIcon("battery-low")
2310 -    }
2311 -
2312 -    Components.Label {
2313 -        id: acLabel
2314 -        anchors {
2315 -            top: acIcon.top
2316 -            left: acIcon.right
2317 -            leftMargin: 6
2318 -        }
2319 -        height: paintedHeight
2320 -        text: i18n("AC Adapter")
2321 -    }
2322 -
2323 -    Components.Label {
2324 -        id: acStatus
2325 -        anchors {
2326 -            top: showTime ? acLabel.top : undefined
2327 -            bottom: showTime ? undefined : acIcon.bottom
2328 -            left: showTime ? acLabel.right : acIcon.right
2329 -            leftMargin: showTime ? 3 : 6
2330 -        }
2331 -        height: paintedHeight
2332 -        text: pluggedIn ? i18n("Plugged In") : i18n("Not Plugged In")
2333 -        color: "#77"+(theme.textColor.toString().substr(1))
2334 -    }
2335 -
2336 -    Components.Label {
2337 -        id: acTime
2338 -        anchors {
2339 -            bottom: acIcon.bottom
2340 -            left: acIcon.right
2341 -            leftMargin: 6
2342 -        }
2343 -        height: paintedHeight
2344 -        visible: showTime
2345 -        text: pluggedIn ? i18n("Time remaining until full: %1", remainingString) : i18n("Time remaining until empty: %1", remainingString)
2346 -        color: "#77"+(theme.textColor.toString().substr(1))
2347 -    }
2348 -}
2349 -
2350 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml b/plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml
2351 index 106c8f9..cdb2a35 100644
2352 --- a/plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml
2353 +++ b/plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml
2354 @@ -32,11 +32,35 @@ Item {
2355      }
2356  
2357      PlasmaCore.SvgItem {
2358 +        id: batterySvg
2359          anchors.fill: parent
2360          svg: svg
2361          elementId: "Battery"
2362      }
2363  
2364 +    SequentialAnimation {
2365 +      running: percent < 5 && !pluggedIn
2366 +      alwaysRunToEnd: true
2367 +      loops: Animation.Infinite
2368 +
2369 +      NumberAnimation {
2370 +          target: batterySvg
2371 +          properties: "opacity"
2372 +          from: 1.0
2373 +          to: 0.2
2374 +          duration: 750
2375 +          easing.type: Easing.InCubic
2376 +      }
2377 +      NumberAnimation {
2378 +          target: batterySvg
2379 +          properties: "opacity"
2380 +          from: 0.2
2381 +          to: 1.0
2382 +          duration: 750
2383 +          easing.type: Easing.OutCubic
2384 +      }
2385 +    }
2386 +
2387      PlasmaCore.SvgItem {
2388          id: fillSvg
2389          anchors.fill: parent
This page took 0.204557 seconds and 2 git commands to generate.