]> git.pld-linux.org Git - packages/kde4-kdebase-workspace.git/blob - kde4-kdebase-workspace-multibattery.patch
0f345b0398f39b8863578b07ab68fca636ba60a7
[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..9bd618d 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,159 @@
453   *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
454   */
455  
456 -var ram = 0
457 -var disk = 1
458 -
459  function updateCumulative() {
460      var sum = 0;
461 +    var count = 0;
462      var charged = true;
463 +    var plugged = false;
464      for (var i=0; i<batteries.count; i++) {
465          var b = batteries.get(i);
466 +        if (!b["Is Power Supply"]) {
467 +          continue;
468 +        }
469          if (b["Plugged in"]) {
470              sum += b["Percent"];
471 +            plugged = true;
472          }
473          if (b["State"] != "NoCharge") {
474              charged = false;
475          }
476 +        count++;
477      }
478  
479 -    if (batteries.count > 0) {
480 -        batteries.cumulativePercent = Math.round(sum/batteries.count);
481 +    if (count > 0) {
482 +      batteries.cumulativePercent = Math.round(sum/count);
483      } else {
484 -        batteries.cumulativePercent = 0;
485 +        // We don't have any power supply batteries
486 +        // Use the lowest value from any battery
487 +        if (batteries.count > 0) {
488 +            var b = lowestBattery();
489 +            batteries.cumulativePercent = b["Percent"];
490 +        } else {
491 +            batteries.cumulativePercent = 0;
492 +        }
493      }
494 +    batteries.cumulativePluggedin = plugged;
495      batteries.allCharged = charged;
496  }
497  
498 -function stringForState(batteryData) {
499 -    var pluggedIn = batteryData["Plugged in"];
500 -    var percent = batteryData["Percent"];
501 -    var state = batteryData["State"];
502 -
503 -    if (pluggedIn) {
504 -        if (state == "NoCharge") {
505 -            return i18n("<b>%1% (charged)</b>", percent);
506 -        } else if (state == "Discharging") {
507 -            return i18n("<b>%1% (discharging)</b>", percent);
508 -        } else {//charging
509 -            return i18n("<b>%1% (charging)</b>", percent);
510 +function plasmoidStatus() {
511 +    var status = "PassiveStatus";
512 +    if (batteries.cumulativePluggedin) {
513 +        if (batteries.cumulativePercent <= 10) {
514 +            status = "NeedsAttentionStatus";
515 +        } else if (!batteries.allCharged) {
516 +            status = "ActiveStatus";
517 +        }
518 +    } else if (batteries.count > 0) { // in case your mouse gets low
519 +        if (batteries.cumulativePercent && batteries.cumulativePercent <= 10) {
520 +            status = "NeedsAttentionStatus";
521          }
522      }
523 -
524 -    return i18nc("Battery is not plugged in", "<b>Not present</b>");
525 +    return status;
526  }
527  
528 -function updateTooltip() {
529 -    var text="";
530 -    for (var i=0; i<batteries.count; i++) {
531 -        if (batteries.count == 1) {
532 -            text += i18n("Battery:");
533 -        } else {
534 -            if (text != "") {
535 -                text += "<br/>";
536 -            }
537 +function lowestBattery() {
538 +    if (batteries.count == 0) {
539 +        return;
540 +    }
541  
542 -            text += i18nc("tooltip: placeholder is the battery ID", "Battery %1:", i+1);
543 +    var lowestPercent = 100;
544 +    var lowestBattery;
545 +    for(var i=0; i<batteries.count; i++) {
546 +        var b = batteries.get(i);
547 +        if (b["Percent"] && b["Percent"] < lowestPercent) {
548 +            lowestPercent = b["Percent"];
549 +            lowestBattery = b;
550          }
551 +    }
552 +    return b;
553 +}
554  
555 -        text += " ";
556 -        text += stringForState(pmSource.data["Battery"+i]);
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 -    if (text != "") {
599 -        text += "<br/>";
600 +            if (pluggedIn && batteryData["Is Power Supply"]) {
601 +                return "battery-charging-" + fill;
602 +            } else {
603 +                if (p < 5) {
604 +                    return "dialog-warning"
605 +                }
606 +                return "battery-" + fill;
607 +            }
608      }
609 +}
610 +
611 +function updateTooltip() {
612 +    var image = "";
613 +    var text = "";
614 +    if (batteries.count == 0) {
615 +        image = "battery-missing";
616 +        text = i18n("No Batteries Available");
617 +    } else {
618 +        var hasPowerSupply = false;
619 +
620 +        text = "<table style='white-space: nowrap'>";
621 +        for(var i=0; i<batteries.count; i++) {
622 +            var b = batteries.get(i);
623 +            text += "<tr>";
624 +            text += "<td align='right'>" + i18nc("Placeholder is battery name", "%1:", b["Pretty Name"]) + " </td>";
625 +            text += "<td>" + i18nc("Placeholder is battery percentage", "%1%", b["Percent"]) + "</td>";
626 +            text += "</tr>";
627  
628 -    if (pmSource.data["AC Adapter"]) {
629 -        text += i18nc("tooltip", "AC Adapter:") + " ";
630 -        text += pmSource.data["AC Adapter"]["Plugged in"] ? i18nc("tooltip", "<b>Plugged in</b>") : i18nc("tooltip", "<b>Not plugged in</b>");
631 +            if (b["Is Power Supply"]) { hasPowerSupply = true; }
632 +        }
633 +        text += "</table>";
634 +
635 +        if (hasPowerSupply) {
636 +            var b = [];
637 +            b["Percent"] = batteries.cumulativePercent;
638 +            image = iconForBattery(b, pmSource.data["AC Adapter"]["Plugged in"] ? true : false);
639 +        } else {
640 +            var b = lowestBattery();
641 +            image = iconForBattery(b, false);
642 +        }
643      }
644      batteries.tooltipText = text;
645 +    batteries.tooltipImage = image;
646  }
647  
648  function updateBrightness() {
649 @@ -94,16 +179,26 @@ function updateBrightness() {
650          return;
651      }
652      dialogItem.disableBrightnessUpdate = true;
653 -    dialogItem.screenBrightness = pmSource.data["PowerDevil"]["Screen Brightness"];
654 +    if (pmSource.data["PowerDevil"]["Screen Brightness"]) {
655 +        dialogItem.screenBrightness = pmSource.data["PowerDevil"]["Screen Brightness"];
656 +    }
657 +    if (pmSource.data["PowerDevil"]["Keyboard Brightness"]) {
658 +        dialogItem.keyboardBrightness = pmSource.data["PowerDevil"]["Keyboard Brightness"];
659 +    }
660      dialogItem.disableBrightnessUpdate = false;
661  }
662  
663 -function callForType(type) {
664 -    if (type == ram) {
665 -        return "suspendToRam";
666 -    } else if (type == disk) {
667 -        return "suspendToDisk";
668 -    }
669 +// TODO: give translated and formatted string with KGlobal::locale()->prettyFormatDuration(msec);
670 +function formatDuration(msec) {
671 +    if (msec == 0 || msec === undefined)
672 +        return "";
673 +
674 +    var time = new Date(msec);
675 +    var hours = time.getUTCHours();
676 +    var minutes = time.getUTCMinutes();
677  
678 -    return "suspendHybrid";
679 +    var str = "";
680 +    if (hours > 0) str += i18np("1 hour ", "%1 hours ", hours);
681 +    if (minutes > 0) str += i18np("1 minute", "%1 minutes", minutes);
682 +    return str;
683  }
684 diff --git a/plasma/generic/applets/batterymonitor/contents/code/platform.js b/plasma/generic/applets/batterymonitor/contents/code/platform.js
685 deleted file mode 100644
686 index 59af3af..0000000
687 --- a/plasma/generic/applets/batterymonitor/contents/code/platform.js
688 +++ /dev/null
689 @@ -1,9 +0,0 @@
690 -
691 -function shouldOfferSuspend(pmSource) {
692 -    return pmSource.data["Sleep States"]["Suspend"];
693 -}
694 -
695 -function shouldOfferHibernate(pmSource) {
696 -    return pmSource.data["Sleep States"]["Hibernate"];
697 -}
698 -
699 diff --git a/plasma/generic/applets/batterymonitor/contents/config/main.xml b/plasma/generic/applets/batterymonitor/contents/config/main.xml
700 index fc31b3e..5e9e31d 100644
701 --- a/plasma/generic/applets/batterymonitor/contents/config/main.xml
702 +++ b/plasma/generic/applets/batterymonitor/contents/config/main.xml
703 @@ -6,12 +6,6 @@
704    <kcfgfile name=""/>
705  
706    <group name="General">
707 -    <entry name="showBatteryString" type="Bool">
708 -      <default>false</default>
709 -    </entry>
710 -    <entry name="showMultipleBatteries" type="Bool">
711 -      <default>false</default>
712 -    </entry>
713      <entry name="showRemainingTime" type="Bool">
714        <default>false</default>
715      </entry>
716 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/AcAdapterItem.qml b/plasma/generic/applets/batterymonitor/contents/ui/AcAdapterItem.qml
717 new file mode 100644
718 index 0000000..c2216f8
719 --- /dev/null
720 +++ b/plasma/generic/applets/batterymonitor/contents/ui/AcAdapterItem.qml
721 @@ -0,0 +1,87 @@
722 +/*
723 + *   Copyright 2012-2013 Daniel Nicoletti <dantti12@gmail.com>
724 + *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
725 + *
726 + *   This program is free software; you can redistribute it and/or modify
727 + *   it under the terms of the GNU Library General Public License as
728 + *   published by the Free Software Foundation; either version 2 or
729 + *   (at your option) any later version.
730 + *
731 + *   This program is distributed in the hope that it will be useful,
732 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
733 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
734 + *   GNU General Public License for more details
735 + *
736 + *   You should have received a copy of the GNU Library General Public
737 + *   License along with this program; if not, write to the
738 + *   Free Software Foundation, Inc.,
739 + *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
740 + */
741 +
742 +import QtQuick 1.1
743 +import org.kde.plasma.core 0.1 as PlasmaCore
744 +import org.kde.plasma.components 0.1 as Components
745 +import org.kde.qtextracomponents 0.1
746 +
747 +Item {
748 +    id: brightnessItem
749 +    clip: true
750 +    width: parent.width
751 +    height: acIcon.height + padding.margins.top + padding.margins.bottom
752 +
753 +    property bool pluggedIn
754 +    property bool showTime
755 +    property string remainingString
756 +
757 +    QIconItem {
758 +        id: acIcon
759 +        width: theme.iconSizes.dialog
760 +        height: width
761 +        anchors {
762 +            top: parent.top
763 +            topMargin: padding.margins.top
764 +            left: parent.left
765 +            leftMargin: padding.margins.left
766 +        }
767 +
768 +        icon: pluggedIn ? QIcon("battery-charging-low") : QIcon("battery-low")
769 +    }
770 +
771 +    Components.Label {
772 +        id: acLabel
773 +        anchors {
774 +            top: acIcon.top
775 +            left: acIcon.right
776 +            leftMargin: 6
777 +        }
778 +        height: paintedHeight
779 +        text: i18n("AC Adapter")
780 +    }
781 +
782 +    Components.Label {
783 +        id: acStatus
784 +        anchors {
785 +            top: showTime ? acLabel.top : undefined
786 +            bottom: showTime ? undefined : acIcon.bottom
787 +            left: showTime ? acLabel.right : acIcon.right
788 +            leftMargin: showTime ? 3 : 6
789 +        }
790 +        height: paintedHeight
791 +        text: pluggedIn ? i18n("Plugged In") : i18n("Not Plugged In")
792 +        color: "#77"+(theme.textColor.toString().substr(1))
793 +    }
794 +
795 +    Components.Label {
796 +        id: acTime
797 +        anchors {
798 +            bottom: acIcon.bottom
799 +            left: acIcon.right
800 +            leftMargin: 6
801 +        }
802 +        height: paintedHeight
803 +        visible: showTime
804 +        text: pluggedIn ? i18n("Time remaining until full: %1", remainingString) : i18n("Time remaining until empty: %1", remainingString)
805 +        color: "#77"+(theme.textColor.toString().substr(1))
806 +    }
807 +}
808 +
809 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml b/plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml
810 index 080ab51..6a49d34 100644
811 --- a/plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml
812 +++ b/plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml
813 @@ -21,15 +21,13 @@ import QtQuick 1.1
814  import org.kde.plasma.core 0.1 as PlasmaCore
815  
816  Item {
817 -    
818 -    property bool monochrome
819      property bool hasBattery
820      property int percent
821      property bool pluggedIn
822 -    
823 +
824      PlasmaCore.Svg {
825          id: svg
826 -        imagePath: monochrome ? "icons/battery" : "widgets/battery-oxygen"
827 +        imagePath: "icons/battery"
828      }
829  
830      PlasmaCore.SvgItem {
831 @@ -39,25 +37,55 @@ Item {
832      }
833  
834      PlasmaCore.SvgItem {
835 +        id: fillSvg
836          anchors.fill: parent
837          svg: svg
838          elementId: hasBattery ? fillElement(percent) : "Unavailable"
839 -        visible: percent>10 || !hasBattery
840 +        visible: elementId != ""
841      }
842  
843      function fillElement(p) {
844 -        if (p >= 90) {
845 -            return "Fill100";
846 -        } else if (p >= 70) {
847 -            return "Fill80";
848 -        } else if (p >= 50) {
849 -            return "Fill60";
850 -        } else if (p > 20) {
851 -            return "Fill40";
852 -        } else if (p >= 10) {
853 -            return "Fill20";
854 +        // We switched from having steps of 20 for the battery percentage to a more accurate
855 +        // step of 10. This means we break other and older themes.
856 +        // If the Fill10 element is not found, it is likely that the theme doesn't support
857 +        // that and we use the older method of obtaining the fill element.
858 +        if (!svg.hasElement("Fill10")) {
859 +            if (p >= 90) {
860 +                return "Fill100";
861 +            } else if (p >= 70) {
862 +                return "Fill80";
863 +            } else if (p >= 50) {
864 +                return "Fill60";
865 +            } else if (p > 20) {
866 +                return "Fill40";
867 +            } else if (p >= 10) {
868 +                return "Fill20";
869 +            }
870 +            return "";
871 +        } else {
872 +            if (p >= 95) {
873 +                return "Fill100";
874 +            } else if (p >= 85) {
875 +                return "Fill90";
876 +            } else if (p >= 75) {
877 +                return "Fill90";
878 +            } else if (p >= 65) {
879 +                return "Fill80";
880 +            } else if (p >= 55) {
881 +                return "Fill60";
882 +            } else if (p >= 45) {
883 +                return "Fill50";
884 +            } else if (p >= 35) {
885 +                return "Fill40";
886 +            } else if (p >= 25) {
887 +                return "Fill30";
888 +            } else if (p >= 15) {
889 +                return "Fill20";
890 +            } else if (p >= 5) {
891 +                return "Fill10";
892 +            }
893 +            return "";
894          }
895 -        return "";
896      }
897  
898      PlasmaCore.SvgItem {
899 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/BatteryItem.qml b/plasma/generic/applets/batterymonitor/contents/ui/BatteryItem.qml
900 new file mode 100644
901 index 0000000..81779ff
902 --- /dev/null
903 +++ b/plasma/generic/applets/batterymonitor/contents/ui/BatteryItem.qml
904 @@ -0,0 +1,310 @@
905 +/*
906 + *   Copyright 2012-2013 Daniel Nicoletti <dantti12@gmail.com>
907 + *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
908 + *
909 + *   This program is free software; you can redistribute it and/or modify
910 + *   it under the terms of the GNU Library General Public License as
911 + *   published by the Free Software Foundation; either version 2 or
912 + *   (at your option) any later version.
913 + *
914 + *   This program is distributed in the hope that it will be useful,
915 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
916 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
917 + *   GNU General Public License for more details
918 + *
919 + *   You should have received a copy of the GNU Library General Public
920 + *   License along with this program; if not, write to the
921 + *   Free Software Foundation, Inc.,
922 + *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
923 + */
924 +
925 +import QtQuick 1.1
926 +import org.kde.plasma.core 0.1 as PlasmaCore
927 +import org.kde.plasma.components 0.1 as Components
928 +import org.kde.qtextracomponents 0.1
929 +import "plasmapackage:/code/logic.js" as Logic
930 +
931 +Item {
932 +    id: batteryItem
933 +    clip: true
934 +    width: batteryColumn.width
935 +    height: expanded ? batteryInfos.height + padding.margins.top + padding.margins.bottom * 2 + actionRow.height
936 +                     : batteryInfos.height + padding.margins.top + padding.margins.bottom
937 +
938 +    Behavior on height { PropertyAnimation {} }
939 +
940 +    property bool highlight
941 +    property bool expanded
942 +    property bool showChargeAnimation
943 +
944 +    property bool isPresent: !model["Is Power Supply"] || model["Plugged in"]
945 +
946 +    function updateSelection() {
947 +        var containsMouse = mouseArea.containsMouse;
948 +
949 +        if (highlight || expanded && containsMouse) {
950 +            padding.opacity = 1;
951 +        } else if (expanded) {
952 +            padding.opacity = 0.8;
953 +        } else if (containsMouse) {
954 +            padding.opacity = 0.65;
955 +        } else {
956 +            padding.opacity = 0;
957 +        }
958 +    }
959 +
960 +    PlasmaCore.FrameSvgItem {
961 +        id: padding
962 +        imagePath: "widgets/viewitem"
963 +        prefix: "hover"
964 +        opacity: 0
965 +        Behavior on opacity { PropertyAnimation {} }
966 +        anchors.fill: parent
967 +    }
968 +
969 +    MouseArea {
970 +        id: mouseArea
971 +        anchors.fill: parent
972 +        hoverEnabled: true
973 +        onEntered: updateSelection()
974 +        onExited: updateSelection()
975 +        onClicked: {
976 +            if (expanded) {
977 +                expanded = false;
978 +            } else {
979 +                expanded = true;
980 +                batteryItem.forceActiveFocus();
981 +            }
982 +            updateSelection();
983 +        }
984 +    }
985 +
986 +    Item {
987 +        id: batteryInfos
988 +        height: Math.max(batteryIcon.height, batteryNameLabel.height + batteryPercentBar.height)
989 +
990 +        anchors {
991 +            top: parent.top
992 +            topMargin: padding.margins.top
993 +            left: parent.left
994 +            leftMargin: padding.margins.left
995 +            right: parent.right
996 +            rightMargin: padding.margins.right
997 +        }
998 +
999 +        QIconItem {
1000 +            id: batteryIcon
1001 +            width: theme.iconSizes.dialog
1002 +            height: width
1003 +            anchors {
1004 +                verticalCenter: parent.verticalCenter
1005 +                left: parent.left
1006 +            }
1007 +            icon: QIcon(Logic.iconForBattery(model,pluggedIn))
1008 +        }
1009 +
1010 +        SequentialAnimation {
1011 +          id: chargeAnimation
1012 +          running: showChargeAnimation && model["State"] == "Charging"
1013 +          alwaysRunToEnd: true
1014 +          loops: Animation.Infinite
1015 +
1016 +          NumberAnimation {
1017 +              target: batteryIcon
1018 +              properties: "opacity"
1019 +              from: 1.0
1020 +              to: 0.5
1021 +              duration: 750
1022 +              easing.type: Easing.InCubic
1023 +          }
1024 +          NumberAnimation {
1025 +              target: batteryIcon
1026 +              properties: "opacity"
1027 +              from: 0.5
1028 +              to: 1.0
1029 +              duration: 750
1030 +              easing.type: Easing.OutCubic
1031 +          }
1032 +        }
1033 +
1034 +        Components.Label {
1035 +            id: batteryNameLabel
1036 +            anchors {
1037 +                verticalCenter: isPresent ? undefined : batteryIcon.verticalCenter
1038 +                top: isPresent ? parent.top : undefined
1039 +                left: batteryIcon.right
1040 +                leftMargin: 6
1041 +            }
1042 +            height: paintedHeight
1043 +            elide: Text.ElideRight
1044 +            text: model["Pretty Name"]
1045 +        }
1046 +
1047 +        Components.Label {
1048 +            id: batteryStatusLabel
1049 +            anchors {
1050 +                top: batteryNameLabel.top
1051 +                left: batteryNameLabel.right
1052 +                leftMargin: 3
1053 +            }
1054 +            text: Logic.stringForBatteryState(model)
1055 +            height: paintedHeight
1056 +            visible: model["Is Power Supply"]
1057 +            color: "#77"+(theme.textColor.toString().substr(1))
1058 +        }
1059 +
1060 +        Components.ProgressBar {
1061 +            id: batteryPercentBar
1062 +            anchors {
1063 +                bottom: parent.bottom
1064 +                left: batteryIcon.right
1065 +                leftMargin: 6
1066 +                right: batteryPercent.left
1067 +                rightMargin: 6
1068 +            }
1069 +            minimumValue: 0
1070 +            maximumValue: 100
1071 +            visible: isPresent
1072 +            value: parseInt(model["Percent"])
1073 +        }
1074 +
1075 +        Components.Label {
1076 +            id: batteryPercent
1077 +            anchors {
1078 +                verticalCenter: batteryPercentBar.verticalCenter
1079 +                right: parent.right
1080 +            }
1081 +            visible: isPresent
1082 +            text: i18nc("Placeholder is battery percentage", "%1%", model["Percent"])
1083 +        }
1084 +    }
1085 +
1086 +    Column {
1087 +        id: actionRow
1088 +        opacity: expanded ? 1 : 0
1089 +        width: parent.width
1090 +        anchors {
1091 +          top: batteryInfos.bottom
1092 +          topMargin: padding.margins.bottom
1093 +          left: parent.left
1094 +          leftMargin: padding.margins.left
1095 +          right: parent.right
1096 +          rightMargin: padding.margins.right
1097 +          bottomMargin: padding.margins.bottom
1098 +        }
1099 +        spacing: 4
1100 +        Behavior on opacity { PropertyAnimation {} }
1101 +
1102 +        PlasmaCore.SvgItem {
1103 +            svg: PlasmaCore.Svg {
1104 +                id: lineSvg
1105 +                imagePath: "widgets/line"
1106 +            }
1107 +            elementId: "horizontal-line"
1108 +            height: lineSvg.elementSize("horizontal-line").height
1109 +            width: parent.width
1110 +        }
1111 +
1112 +        Row {
1113 +            id: detailsRow
1114 +            width: parent.width
1115 +            spacing: 4
1116 +
1117 +            Column {
1118 +                id: labelsColumn
1119 +                Components.Label {
1120 +                    height: paintedHeight
1121 +                    width: parent.width
1122 +                    horizontalAlignment: Text.AlignRight
1123 +                    onPaintedWidthChanged: {
1124 +                        if (paintedWidth > parent.width) { parent.width = paintedWidth; }
1125 +                    }
1126 +                    text: model["State"] == "Charging" ? i18n("Time To Full:") : i18n("Time To Empty:")
1127 +                    visible: remainingTimeLabel.visible
1128 +                    font.pointSize: theme.smallestFont.pointSize
1129 +                    color: "#99"+(theme.textColor.toString().substr(1))
1130 +                }
1131 +                Components.Label {
1132 +                    height: paintedHeight
1133 +                    width: parent.width
1134 +                    horizontalAlignment: Text.AlignRight
1135 +                    onPaintedWidthChanged: {
1136 +                        if (paintedWidth > parent.width) { parent.width = paintedWidth; }
1137 +                    }
1138 +                    text: i18n("Capacity:")
1139 +                    visible: capacityLabel.visible
1140 +                    font.pointSize: theme.smallestFont.pointSize
1141 +                    color: "#99"+(theme.textColor.toString().substr(1))
1142 +                }
1143 +                Components.Label {
1144 +                    height: paintedHeight
1145 +                    width: parent.width
1146 +                    horizontalAlignment: Text.AlignRight
1147 +                    onPaintedWidthChanged: {
1148 +                        if (paintedWidth > parent.width) { parent.width = paintedWidth; }
1149 +                    }
1150 +                    text: i18n("Vendor:")
1151 +                    visible: vendorLabel.visible
1152 +                    font.pointSize: theme.smallestFont.pointSize
1153 +                    color: "#99"+(theme.textColor.toString().substr(1))
1154 +                }
1155 +                Components.Label {
1156 +                    height: paintedHeight
1157 +                    width: parent.width
1158 +                    horizontalAlignment: Text.AlignRight
1159 +                    onPaintedWidthChanged: {
1160 +                        if (paintedWidth > parent.width) { parent.width = paintedWidth; }
1161 +                    }
1162 +                    text: i18n("Model:")
1163 +                    visible: modelLabel.visible
1164 +                    font.pointSize: theme.smallestFont.pointSize
1165 +                    color: "#99"+(theme.textColor.toString().substr(1))
1166 +                }
1167 +            }
1168 +            Column {
1169 +                width: parent.width - labelsColumn.width - parent.spacing * 2
1170 +                Components.Label { // Remaining Time
1171 +                    id: remainingTimeLabel
1172 +                    height: paintedHeight
1173 +                    width: parent.width
1174 +                    elide: Text.ElideRight
1175 +                    text: Logic.formatDuration(model["Remaining Time"])
1176 +                    visible: showRemainingTime && model["Is Power Supply"] && model["State"] != "NoCharge" && text
1177 +                    font.pointSize: theme.smallestFont.pointSize
1178 +                    color: "#99"+(theme.textColor.toString().substr(1))
1179 +                }
1180 +                Components.Label { // Capacity
1181 +                    id: capacityLabel
1182 +                    height: paintedHeight
1183 +                    width: parent.width
1184 +                    elide: Text.ElideRight
1185 +                    text: i18nc("Placeholder is battery capacity", "%1%", model["Capacity"])
1186 +                    visible: model["Capacity"] != "" && model["Capacity"] !== undefined
1187 +                    font.pointSize: theme.smallestFont.pointSize
1188 +                    color: "#99"+(theme.textColor.toString().substr(1))
1189 +                }
1190 +                Components.Label { // Vendor
1191 +                    id: vendorLabel
1192 +                    height: paintedHeight
1193 +                    width: parent.width
1194 +                    elide: Text.ElideRight
1195 +                    text: model["Vendor"]
1196 +                    visible: model["Vendor"] != "" && model["Vendor"] !== undefined
1197 +                    font.pointSize: theme.smallestFont.pointSize
1198 +                    color: "#99"+(theme.textColor.toString().substr(1))
1199 +                }
1200 +                Components.Label { // Model
1201 +                    id: modelLabel
1202 +                    height: paintedHeight
1203 +                    width: parent.width
1204 +                    elide: Text.ElideRight
1205 +                    text: model["Product"]
1206 +                    visible: model["Product"] != "" && model["Product"] !== undefined
1207 +                    font.pointSize: theme.smallestFont.pointSize
1208 +                    color: "#99"+(theme.textColor.toString().substr(1))
1209 +                }
1210 +            }
1211 +        }
1212 +    }
1213 +}
1214 +
1215 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/BrightnessItem.qml b/plasma/generic/applets/batterymonitor/contents/ui/BrightnessItem.qml
1216 new file mode 100644
1217 index 0000000..34c596c
1218 --- /dev/null
1219 +++ b/plasma/generic/applets/batterymonitor/contents/ui/BrightnessItem.qml
1220 @@ -0,0 +1,89 @@
1221 +/*
1222 + *   Copyright 2012-2013 Daniel Nicoletti <dantti12@gmail.com>
1223 + *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
1224 + *
1225 + *   This program is free software; you can redistribute it and/or modify
1226 + *   it under the terms of the GNU Library General Public License as
1227 + *   published by the Free Software Foundation; either version 2 or
1228 + *   (at your option) any later version.
1229 + *
1230 + *   This program is distributed in the hope that it will be useful,
1231 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
1232 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1233 + *   GNU General Public License for more details
1234 + *
1235 + *   You should have received a copy of the GNU Library General Public
1236 + *   License along with this program; if not, write to the
1237 + *   Free Software Foundation, Inc.,
1238 + *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
1239 + */
1240 +
1241 +import QtQuick 1.1
1242 +import org.kde.plasma.core 0.1 as PlasmaCore
1243 +import org.kde.plasma.components 0.1 as Components
1244 +import org.kde.qtextracomponents 0.1
1245 +
1246 +Item {
1247 +    id: brightnessItem
1248 +    clip: true
1249 +    width: parent.width
1250 +    height: Math.max(brightnessIcon.height, brightnessLabel.height + brightnessSlider.height) + padding.margins.top + padding.margins.bottom
1251 +
1252 +    property alias icon: brightnessIcon.icon
1253 +    property alias label: brightnessLabel.text
1254 +    property alias value: brightnessSlider.value
1255 +
1256 +    signal changed(int screenBrightness)
1257 +
1258 +    QIconItem {
1259 +        id: brightnessIcon
1260 +        width: theme.iconSizes.dialog
1261 +        height: width
1262 +        anchors {
1263 +            verticalCenter: parent.verticalCenter
1264 +            topMargin: padding.margins.top
1265 +            bottomMargin: padding.margins.bottom
1266 +            left: parent.left
1267 +            leftMargin: padding.margins.left
1268 +        }
1269 +    }
1270 +
1271 +    Components.Label {
1272 +        id: brightnessLabel
1273 +        anchors {
1274 +            top: parent.top
1275 +            topMargin: padding.margins.top
1276 +            left: brightnessIcon.right
1277 +            leftMargin: 6
1278 +        }
1279 +        height: paintedHeight
1280 +    }
1281 +
1282 +    Components.Slider {
1283 +        id: brightnessSlider
1284 +        anchors {
1285 +            bottom: parent.bottom
1286 +            bottomMargin: padding.margins.bottom
1287 +            left: brightnessIcon.right
1288 +            right: brightnessPercent.left
1289 +            leftMargin: 6
1290 +            rightMargin: 6
1291 +        }
1292 +        minimumValue: 0
1293 +        maximumValue: 100
1294 +        stepSize: 10
1295 +        onValueChanged: changed(value)
1296 +    }
1297 +
1298 +    Components.Label {
1299 +        id: brightnessPercent
1300 +        anchors {
1301 +            right: parent.right
1302 +            rightMargin: padding.margins.right
1303 +            verticalCenter: brightnessSlider.verticalCenter
1304 +        }
1305 +        height: paintedHeight
1306 +        text: i18nc("Placeholder is brightness percentage", "%1%", brightnessSlider.value)
1307 +    }
1308 +}
1309 +
1310 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/CompactRepresentation.qml b/plasma/generic/applets/batterymonitor/contents/ui/CompactRepresentation.qml
1311 new file mode 100644
1312 index 0000000..e9dc772
1313 --- /dev/null
1314 +++ b/plasma/generic/applets/batterymonitor/contents/ui/CompactRepresentation.qml
1315 @@ -0,0 +1,112 @@
1316 +/*
1317 +*   Copyright 2011 Sebastian Kügler <sebas@kde.org>
1318 +*   Copyright 2011 Viranch Mehta <viranch.mehta@gmail.com>
1319 +*   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
1320 +*
1321 +*   This program is free software; you can redistribute it and/or modify
1322 +*   it under the terms of the GNU Library General Public License as
1323 +*   published by the Free Software Foundation; either version 2 or
1324 +*   (at your option) any later version.
1325 +*
1326 +*   This program is distributed in the hope that it will be useful,
1327 +*   but WITHOUT ANY WARRANTY; without even the implied warranty of
1328 +*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1329 +*   GNU General Public License for more details
1330 +*
1331 +*   You should have received a copy of the GNU Library General Public
1332 +*   License along with this program; if not, write to the
1333 +*   Free Software Foundation, Inc.,
1334 +*   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
1335 +*/
1336 +
1337 +import QtQuick 1.1
1338 +import org.kde.plasma.core 0.1 as PlasmaCore
1339 +import org.kde.plasma.components 0.1 as Components
1340 +import "plasmapackage:/code/logic.js" as Logic
1341 +
1342 +ListView {
1343 +    id: view
1344 +
1345 +    property int minimumWidth
1346 +    property int minimumHeight
1347 +
1348 +    property bool hasBattery
1349 +
1350 +    property QtObject pmSource
1351 +    property QtObject batteries
1352 +
1353 +    property bool singleBattery
1354 +
1355 +    model: singleBattery ? 1 : batteries
1356 +
1357 +    anchors.fill: parent
1358 +    orientation: ListView.Horizontal
1359 +    interactive: false
1360 +
1361 +    function isConstrained() {
1362 +        return (plasmoid.formFactor == Vertical || plasmoid.formFactor == Horizontal);
1363 +    }
1364 +
1365 +    Component.onCompleted: {
1366 +        if (!isConstrained()) {
1367 +            minimumHeight = theme.iconSizes.dialog;
1368 +            minimumWidth = minimumHeight * view.count;
1369 +        } else {
1370 +            // NOTE: Keep in sync with systray
1371 +            minimumHeight = 24;
1372 +            minimumWidth = 24;
1373 +        }
1374 +    }
1375 +
1376 +    delegate: Item {
1377 +        id: batteryContainer
1378 +
1379 +        property bool hasBattery: view.singleBattery ? batteries.count : model["Plugged in"]
1380 +        property int percent: view.singleBattery ? batteries.cumulativePercent : model["Percent"]
1381 +        property bool pluggedIn: pmSource.data["AC Adapter"]["Plugged in"]
1382 +
1383 +        width: view.width/view.count
1384 +        height: view.height
1385 +
1386 +        property real iconSize: Math.min(width, height)
1387 +
1388 +        Column {
1389 +            anchors.fill: parent
1390 +
1391 +            BatteryIcon {
1392 +                id: batteryIcon
1393 +                anchors.centerIn: isConstrained() ? parent : undefined
1394 +                anchors.horizontalCenter: isConstrained() ? undefined : parent.horizontalCenter
1395 +                hasBattery: batteryContainer.hasBattery
1396 +                percent: batteryContainer.percent
1397 +                pluggedIn: batteryContainer.pluggedIn
1398 +                height: isConstrained() ? batteryContainer.iconSize : batteryContainer.iconSize - batteryLabel.height
1399 +                width: height
1400 +            }
1401 +
1402 +            Components.Label {
1403 +                id: batteryLabel
1404 +                width: parent.width
1405 +                height: paintedHeight
1406 +                horizontalAlignment: Text.AlignHCenter
1407 +                text: i18nc("battery percentage below battery icon", "%1%", percent)
1408 +                font.pixelSize: Math.max(batteryContainer.iconSize/8, 10)
1409 +                visible: !isConstrained()
1410 +            }
1411 +        }
1412 +    }
1413 +
1414 +    MouseArea {
1415 +        id: mouseArea
1416 +        anchors.fill: parent
1417 +        hoverEnabled: true
1418 +        onClicked: plasmoid.togglePopup()
1419 +
1420 +        PlasmaCore.ToolTip {
1421 +            id: tooltip
1422 +            target: mouseArea
1423 +            image: batteries.tooltipImage
1424 +            subText: batteries.tooltipText
1425 +        }
1426 +    }
1427 +}
1428 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/PopupDialog.qml b/plasma/generic/applets/batterymonitor/contents/ui/PopupDialog.qml
1429 index 76fb1ce..4f46834 100644
1430 --- a/plasma/generic/applets/batterymonitor/contents/ui/PopupDialog.qml
1431 +++ b/plasma/generic/applets/batterymonitor/contents/ui/PopupDialog.qml
1432 @@ -1,5 +1,6 @@
1433  /*
1434   *   Copyright 2011 Viranch Mehta <viranch.mehta@gmail.com>
1435 + *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
1436   *
1437   *   This program is free software; you can redistribute it and/or modify
1438   *   it under the terms of the GNU Library General Public License as
1439 @@ -18,176 +19,106 @@
1440   */
1441  
1442  import QtQuick 1.1
1443 +import org.kde.plasma.core 0.1 as PlasmaCore
1444  import org.kde.plasma.components 0.1 as Components
1445 +import org.kde.qtextracomponents 0.1
1446  import "plasmapackage:/code/logic.js" as Logic
1447  
1448  Item {
1449      id: dialog
1450 -    width: childrenRect.width+24
1451 -    height: childrenRect.height+24
1452 +    property int actualHeight: batteryColumn.implicitHeight + settingsColumn.height + separator.height + 10 // 10 = separator margins
1453  
1454 -    property alias model: batteryLabels.model
1455 -    property alias hasBattery: batteryIcon.hasBattery
1456 -    property alias percent: batteryIcon.percent
1457 +    property alias model: batteryList.model
1458      property bool pluggedIn
1459 +    property bool showRemainingTime
1460 +
1461 +    property bool popupShown // somehow plasmoid.popupShowing isn't working
1462 +
1463 +    property bool isBrightnessAvailable
1464      property alias screenBrightness: brightnessSlider.value
1465 -    property int remainingMsec
1466 -    property alias showSuspendButton: suspendButton.visible
1467 -    property alias showHibernateButton: hibernateButton.visible
1468  
1469 +    property bool isKeyboardBrightnessAvailable
1470 +    property alias keyboardBrightness: keyboardBrightnessSlider.value
1471  
1472 -    signal suspendClicked(int type)
1473      signal brightnessChanged(int screenBrightness)
1474 +    signal keyboardBrightnessChanged(int keyboardBrightness)
1475      signal powermanagementChanged(bool checked)
1476  
1477 +    PlasmaCore.FrameSvgItem {
1478 +        id: padding
1479 +        imagePath: "widgets/viewitem"
1480 +        prefix: "hover"
1481 +        opacity: 0
1482 +    }
1483 +
1484      Column {
1485 -        id: labels
1486 -        spacing: 6
1487 +        id: batteryColumn
1488 +        spacing: 4
1489 +        width: parent.width
1490          anchors {
1491 -            top: parent.top
1492              left: parent.left
1493 -            margins: 12
1494 -        }
1495 -        Repeater {
1496 -            model: dialog.model
1497 -            Components.Label {
1498 -                text: model.count>1 ? i18nc("Placeholder is the battery ID", "Battery %1:", index+1) : i18n("Battery:")
1499 -                width: labels.width
1500 -                horizontalAlignment: Text.AlignRight
1501 -            }
1502 -        }
1503 -
1504 -        Components.Label {
1505 -            text: i18n("AC Adapter:")
1506 -            anchors.right: parent.right
1507 -            anchors.bottomMargin: 12
1508 -        }
1509 -
1510 -        Components.Label {
1511 -            text: i18nc("Label for remaining time", "Time Remaining:")
1512 -            visible: remainingTime.visible
1513 -            anchors.right: parent.right
1514 -        }
1515 -
1516 -        Components.Label {
1517 -            text: i18nc("Label for power management inhibition", "Power management enabled:")
1518 -            anchors.right: parent.right
1519 +            right: parent.right
1520 +            top: plasmoid.location == BottomEdge ? parent.top : undefined
1521 +            bottom: plasmoid.location == BottomEdge ? undefined : parent.bottom
1522          }
1523  
1524 -        Components.Label {
1525 -            text: i18n("Screen Brightness:")
1526 -            anchors.right: parent.right
1527 +        Repeater {
1528 +            id: batteryList
1529 +            delegate: BatteryItem { showChargeAnimation: popupShown }
1530          }
1531      }
1532  
1533      Column {
1534 -        id: values
1535 -        spacing: 6
1536 -        anchors {
1537 -            top: parent.top
1538 -            left: labels.right
1539 -            margins: 12
1540 -        }
1541 +        id: settingsColumn
1542 +        spacing: 0
1543 +        width: parent.width
1544  
1545 -        Column {
1546 -            id: upperValues
1547 -            spacing: 6
1548 -            anchors {
1549 -                left: values.left
1550 -            }
1551 -
1552 -            Repeater {
1553 -                id: batteryLabels
1554 -                Components.Label {
1555 -                    text: Logic.stringForState(model)
1556 -                    font.weight: Font.Bold
1557 -                }
1558 -            }
1559 -
1560 -            Components.Label {
1561 -                text: dialog.pluggedIn ? i18n("Plugged in") : i18n("Not plugged in")
1562 -                font.weight: Font.Bold
1563 -                anchors.bottomMargin: 12
1564 -            }
1565 -
1566 -            Components.Label {
1567 -                id: remainingTime
1568 -                text: formatDuration(remainingMsec);
1569 -                font.weight: Font.Bold
1570 -                visible: text!=""
1571 -            }
1572 -        }
1573 -
1574 -        Column {
1575 -            id: lowerValues
1576 -            spacing: 6
1577 -            width: upperValues.width + batteryIcon.width * 2
1578 -            anchors {
1579 -                left: values.left
1580 -            }
1581 -            Components.CheckBox {
1582 -                checked: true
1583 -                onClicked: powermanagementChanged(checked)
1584 -                x: 1
1585 -            }
1586 -
1587 -            Components.Slider {
1588 -                id: brightnessSlider
1589 -                width: lowerValues.width
1590 -                minimumValue: 0
1591 -                maximumValue: 100
1592 -                stepSize: 10
1593 -                onValueChanged: brightnessChanged(value)
1594 -            }
1595 +        anchors {
1596 +            left: parent.left
1597 +            right: parent.right
1598 +            top: plasmoid.location == BottomEdge ? undefined : parent.top
1599 +            bottom: plasmoid.location == BottomEdge ? parent.bottom : undefined
1600          }
1601 -    }
1602  
1603 -    // TODO: give translated and formatted string with KGlobal::locale()->prettyFormatDuration(msec);
1604 -    function formatDuration(msec) {
1605 -        if (msec==0)
1606 -            return "";
1607 -
1608 -        var time = new Date(msec);
1609 -        var hours = time.getUTCHours();
1610 -        var minutes = time.getUTCMinutes();
1611 -        var str = "";
1612 -        if (hours > 0) str += i18np("1 hour ", "%1 hours ", hours);
1613 -        if (minutes > 0) str += i18np("1 minute", "%1 minutes", minutes);
1614 -        return str;
1615 -    }
1616 +        BrightnessItem {
1617 +            id: brightnessSlider
1618 +            icon: QIcon("video-display")
1619 +            label: i18n("Display Brightness")
1620 +            visible: isBrightnessAvailable
1621 +            onChanged: brightnessChanged(value)
1622  
1623 -    Row {
1624 -        anchors {
1625 -            top: values.bottom
1626 -            margins: 12
1627 -            right: values.right
1628          }
1629  
1630 -        Components.ToolButton {
1631 -            id: suspendButton
1632 -            iconSource: "system-suspend"
1633 -            text: i18nc("Suspend the computer to RAM; translation should be short", "Sleep")
1634 -            onClicked: suspendClicked(Logic.ram)
1635 +        BrightnessItem {
1636 +            id: keyboardBrightnessSlider
1637 +            icon: QIcon("input-keyboard")
1638 +            label: i18n("Keyboard Brightness")
1639 +            visible: isKeyboardBrightnessAvailable
1640 +            onChanged: keyboardBrightnessChanged(value)
1641          }
1642  
1643 -        Components.ToolButton {
1644 -            id: hibernateButton
1645 -            iconSource: "system-suspend-hibernate"
1646 -            text: i18nc("Suspend the computer to disk; translation should be short", "Hibernate")
1647 -            onClicked: suspendClicked(Logic.disk)
1648 +        PowerManagementItem {
1649 +            id: pmSwitch
1650 +            onEnabledChanged: powermanagementChanged(enabled)
1651          }
1652      }
1653  
1654 -    BatteryIcon {
1655 -        id: batteryIcon
1656 -        monochrome: false
1657 -        pluggedIn: dialog.pluggedIn
1658 +    PlasmaCore.SvgItem {
1659 +        id: separator
1660 +        svg: PlasmaCore.Svg {
1661 +            id: lineSvg
1662 +            imagePath: "widgets/line"
1663 +        }
1664 +        elementId: "horizontal-line"
1665 +        height: lineSvg.elementSize("horizontal-line").height
1666 +        width: parent.width
1667          anchors {
1668 -            top: parent.top
1669 -            right: values.right
1670 -            topMargin: 12
1671 +            top: plasmoid.location == BottomEdge ? undefined : settingsColumn.bottom
1672 +            bottom: plasmoid.location == BottomEdge ? settingsColumn.top : undefined
1673 +            leftMargin: padding.margins.left
1674 +            rightMargin: padding.margins.right
1675 +            topMargin: 5
1676 +            bottomMargin: 5
1677          }
1678 -        width: height
1679 -        height: hibernateButton.height * 2
1680      }
1681  }
1682 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/PowerManagementItem.qml b/plasma/generic/applets/batterymonitor/contents/ui/PowerManagementItem.qml
1683 new file mode 100644
1684 index 0000000..c82a86d
1685 --- /dev/null
1686 +++ b/plasma/generic/applets/batterymonitor/contents/ui/PowerManagementItem.qml
1687 @@ -0,0 +1,67 @@
1688 +/*
1689 + *   Copyright 2012-2013 Daniel Nicoletti <dantti12@gmail.com>
1690 + *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
1691 + *
1692 + *   This program is free software; you can redistribute it and/or modify
1693 + *   it under the terms of the GNU Library General Public License as
1694 + *   published by the Free Software Foundation; either version 2 or
1695 + *   (at your option) any later version.
1696 + *
1697 + *   This program is distributed in the hope that it will be useful,
1698 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
1699 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1700 + *   GNU General Public License for more details
1701 + *
1702 + *   You should have received a copy of the GNU Library General Public
1703 + *   License along with this program; if not, write to the
1704 + *   Free Software Foundation, Inc.,
1705 + *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
1706 + */
1707 +
1708 +import QtQuick 1.1
1709 +import org.kde.plasma.core 0.1 as PlasmaCore
1710 +import org.kde.plasma.components 0.1 as Components
1711 +import org.kde.qtextracomponents 0.1
1712 +
1713 +Item {
1714 +    id: brightnessItem
1715 +    clip: true
1716 +    width: parent.width
1717 +    height: Math.max(pmCheckBox.height, pmLabel.height) + padding.margins.top + padding.margins.bottom
1718 +
1719 +    property alias enabled: pmCheckBox.checked
1720 +
1721 +    signal enabledChanged(bool checked)
1722 +
1723 +    Components.CheckBox {
1724 +        id: pmCheckBox
1725 +        anchors {
1726 +            verticalCenter: parent.verticalCenter
1727 +            left: parent.left
1728 +            leftMargin: padding.margins.left + (theme.iconSizes.dialog - width)
1729 +            topMargin: padding.margins.top
1730 +            bottomMargin: padding.margins.bottom
1731 +        }
1732 +        checked: true
1733 +        onCheckedChanged: enabledChanged(checked)
1734 +    }
1735 +
1736 +    Components.Label {
1737 +        id: pmLabel
1738 +        anchors {
1739 +            verticalCenter: pmCheckBox.verticalCenter
1740 +            left: pmCheckBox.right
1741 +            leftMargin: 6
1742 +        }
1743 +        height: paintedHeight
1744 +        text: i18n("Enable Power Management")
1745 +    }
1746 +
1747 +    MouseArea {
1748 +        anchors.fill: parent
1749 +
1750 +        onReleased: pmCheckBox.released();
1751 +        onPressed: pmCheckBox.forceActiveFocus();
1752 +    }
1753 +}
1754 +
1755 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/ScrollableListView.qml b/plasma/generic/applets/batterymonitor/contents/ui/ScrollableListView.qml
1756 new file mode 100644
1757 index 0000000..c3cb818
1758 --- /dev/null
1759 +++ b/plasma/generic/applets/batterymonitor/contents/ui/ScrollableListView.qml
1760 @@ -0,0 +1,58 @@
1761 +/*
1762 + *   Copyright 2012 Daniel Nicoletti <dantti12@gmail.com>
1763 + *
1764 + *   This program is free software; you can redistribute it and/or modify
1765 + *   it under the terms of the GNU Library General Public License as
1766 + *   published by the Free Software Foundation; either version 2 or
1767 + *   (at your option) any later version.
1768 + *
1769 + *   This program is distributed in the hope that it will be useful,
1770 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
1771 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1772 + *   GNU General Public License for more details
1773 + *
1774 + *   You should have received a copy of the GNU Library General Public
1775 + *   License along with this program; if not, write to the
1776 + *   Free Software Foundation, Inc.,
1777 + *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
1778 + */
1779 +
1780 +import QtQuick 1.1
1781 +import org.kde.plasma.core 0.1 as PlasmaCore
1782 +import org.kde.plasma.components 0.1 as Components
1783 +import org.kde.qtextracomponents 0.1
1784 +
1785 +FocusScope {
1786 +    property alias delegate: list.delegate
1787 +    property alias model: list.model
1788 +    property alias view: list
1789 +    property alias interactive: list.interactive
1790 +    property alias currentIndex: list.currentIndex
1791 +    signal countChanged()
1792 +
1793 +    Component.onCompleted: {
1794 +        list.countChanged.connect(countChanged)
1795 +    }
1796 +
1797 +    ListView {
1798 +        id: list
1799 +        clip: true
1800 +        focus: true
1801 +        anchors {
1802 +            left:   parent.left
1803 +            right:  scrollBar.visible ? scrollBar.left : parent.right
1804 +            top :   parent.top
1805 +            bottom: parent.bottom
1806 +        }
1807 +        boundsBehavior: Flickable.StopAtBounds
1808 +    }
1809 +    Components.ScrollBar {
1810 +        id: scrollBar
1811 +        flickableItem: list
1812 +        anchors {
1813 +            right: parent.right
1814 +            top: list.top
1815 +            bottom: list.bottom
1816 +        }
1817 +    }
1818 +}
1819 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml b/plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml
1820 index a5e1c13..f082c38 100644
1821 --- a/plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml
1822 +++ b/plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml
1823 @@ -1,6 +1,7 @@
1824  /*
1825   *   Copyright 2011 Sebastian Kügler <sebas@kde.org>
1826   *   Copyright 2011 Viranch Mehta <viranch.mehta@gmail.com>
1827 + *   Copyright 2013 Kai Uwe Broulik <kde@privat.broulik.de>
1828   *
1829   *   This program is free software; you can redistribute it and/or modify
1830   *   it under the terms of the GNU Library General Public License as
1831 @@ -21,128 +22,40 @@
1832  import QtQuick 1.1
1833  import org.kde.plasma.core 0.1 as PlasmaCore
1834  import "plasmapackage:/code/logic.js" as Logic
1835 -import "plasmapackage:/code/platform.js" as Platform
1836  
1837  Item {
1838      id: batterymonitor
1839 -    property int minimumWidth: dialogItem.width
1840 -    property int minimumHeight: dialogItem.height
1841 +    property int minimumWidth: theme.iconSizes.dialog * 9
1842 +    property int minimumHeight: dialogItem.actualHeight
1843 +    property int maximumHeight: dialogItem.actualHeight
1844  
1845      property bool show_remaining_time: false
1846  
1847 +    PlasmaCore.Theme { id: theme }
1848 +
1849      Component.onCompleted: {
1850 +        plasmoid.aspectRatioMode = IgnoreAspectRatio
1851          Logic.updateCumulative();
1852 +        plasmoid.status = Logic.plasmoidStatus();
1853          Logic.updateTooltip();
1854          Logic.updateBrightness();
1855          plasmoid.addEventListener('ConfigChanged', configChanged);
1856 +        plasmoid.popupEvent.connect(popupEventSlot);
1857      }
1858  
1859      function configChanged() {
1860          show_remaining_time = plasmoid.readConfig("showRemainingTime");
1861      }
1862  
1863 -    property Component compactRepresentation: Component {
1864 -        ListView {
1865 -            id: view
1866 -
1867 -            property int minimumWidth
1868 -            property int minimumHeight
1869 -
1870 -            property bool showOverlay: false
1871 -            property bool showMultipleBatteries: false
1872 -            property bool hasBattery: pmSource.data["Battery"]["Has Battery"]
1873 -
1874 -            property QtObject pmSource: plasmoid.rootItem.pmSource
1875 -            property QtObject batteries: plasmoid.rootItem.batteries
1876 -
1877 -            property bool singleBattery: isConstrained() || !showMultipleBatteries || !hasBattery
1878 -
1879 -            model: singleBattery ? 1 : batteries
1880 -
1881 -            PlasmaCore.Theme { id: theme }
1882 -
1883 -            anchors.fill: parent
1884 -            orientation: ListView.Horizontal
1885 -
1886 -            function isConstrained() {
1887 -                return (plasmoid.formFactor == Vertical || plasmoid.formFactor == Horizontal);
1888 -            }
1889 -
1890 -            Component.onCompleted: {
1891 -                if (!isConstrained()) {
1892 -                    minimumWidth = 32;
1893 -                    minimumHeight = 32;
1894 -                }
1895 -                plasmoid.addEventListener('ConfigChanged', configChanged);
1896 -            }
1897 -
1898 -            function configChanged() {
1899 -                showOverlay = plasmoid.readConfig("showBatteryString");
1900 -                showMultipleBatteries = plasmoid.readConfig("showMultipleBatteries");
1901 -            }
1902 -
1903 -            delegate: Item {
1904 -                id: batteryContainer
1905 -
1906 -                property bool hasBattery: view.singleBattery ? batteries.cumulativePluggedin : model["Plugged in"]
1907 -                property int percent: view.singleBattery ? batteries.cumulativePercent : model["Percent"]
1908 -                property bool pluggedIn: pmSource.data["AC Adapter"]["Plugged in"]
1909 -
1910 -                width: view.width/view.count
1911 -                height: view.height
1912 -
1913 -                property real size: Math.min(width, height)
1914 -
1915 -                BatteryIcon {
1916 -                    id: batteryIcon
1917 -                    monochrome: true
1918 -                    hasBattery: parent.hasBattery
1919 -                    percent: parent.percent
1920 -                    pluggedIn: parent.pluggedIn
1921 -                    width: size; height: size
1922 -                    anchors.centerIn: parent
1923 -                }
1924 -
1925 -                Rectangle {
1926 -                    id: labelRect
1927 -                    // should be 40 when size is 90
1928 -                    width: Math.max(parent.size*4/9, 35)
1929 -                    height: width/2
1930 -                    anchors.centerIn: parent
1931 -                    color: theme.backgroundColor
1932 -                    border.color: "grey"
1933 -                    border.width: 2
1934 -                    radius: 4
1935 -                    opacity: hasBattery ? (showOverlay ? 0.7 : (isConstrained() ? 0 : mouseArea.containsMouse*0.7)) : 0
1936 -
1937 -                    Behavior on opacity { NumberAnimation { duration: 100 } }
1938 -                }
1939 -
1940 -                Text {
1941 -                    id: overlayText
1942 -                    text: i18nc("overlay on the battery, needs to be really tiny", "%1%", percent);
1943 -                    color: theme.textColor
1944 -                    font.pixelSize: Math.max(parent.size/8, 11)
1945 -                    anchors.centerIn: labelRect
1946 -                    // keep the opacity 1 when labelRect.opacity=0.7
1947 -                    opacity: labelRect.opacity/0.7
1948 -                }
1949 -            }
1950 -
1951 -            MouseArea {
1952 -                id: mouseArea
1953 -                anchors.fill: parent
1954 -                hoverEnabled: true
1955 -                onClicked: plasmoid.togglePopup()
1956 +    function popupEventSlot(popped) {
1957 +        dialogItem.popupShown = popped;
1958 +    }
1959  
1960 -                PlasmaCore.ToolTip {
1961 -                    id: tooltip
1962 -                    target: mouseArea
1963 -                    image: "battery"
1964 -                    subText: batteries.tooltipText
1965 -                }
1966 -            }
1967 -        }
1968 +    property Component compactRepresentation: CompactRepresentation {
1969 +        hasBattery: pmSource.data["Battery"]["Has Battery"]
1970 +        pmSource: plasmoid.rootItem.pmSource
1971 +        batteries: plasmoid.rootItem.batteries
1972 +        singleBattery: isConstrained() || !hasBattery
1973      }
1974  
1975      property QtObject pmSource: PlasmaCore.DataSource {
1976 @@ -150,12 +63,14 @@ Item {
1977          engine: "powermanagement"
1978          connectedSources: sources
1979          onDataChanged: {
1980 +            Logic.updateCumulative();
1981 +            plasmoid.status = Logic.plasmoidStatus();
1982              Logic.updateTooltip();
1983              Logic.updateBrightness();
1984          }
1985          onSourceAdded: {
1986              if (source == "Battery0") {
1987 -               disconnectSource(source);
1988 +                disconnectSource(source);
1989                  connectSource(source);
1990              }
1991          }
1992 @@ -173,44 +88,31 @@ Item {
1993  
1994          onDataChanged: {
1995              Logic.updateCumulative();
1996 -
1997 -            var status = "PassiveStatus";
1998 -            if (batteries.cumulativePluggedin) {
1999 -                if (batteries.cumulativePercent <= 10) {
2000 -                    status = "NeedsAttentionStatus";
2001 -                } else if (!batteries.allCharged) {
2002 -                    status = "ActiveStatus";
2003 -                }
2004 -            }
2005 -            plasmoid.status = status;
2006 +            plasmoid.status = Logic.plasmoidStatus();
2007          }
2008  
2009          property int cumulativePercent
2010 -        property bool cumulativePluggedin: count > 0
2011 +        property bool cumulativePluggedin
2012          // true  --> all batteries charged
2013          // false --> one of the batteries charging/discharging
2014          property bool allCharged
2015          property string tooltipText
2016 +        property string tooltipImage
2017      }
2018  
2019      PopupDialog {
2020          id: dialogItem
2021          property bool disableBrightnessUpdate: false
2022          model: batteries
2023 -        hasBattery: batteries.cumulativePluggedin
2024 -        percent: batteries.cumulativePercent
2025 +        anchors.fill: parent
2026 +
2027 +        isBrightnessAvailable: pmSource.data["PowerDevil"]["Screen Brightness Available"] ? true : false
2028 +        isKeyboardBrightnessAvailable: pmSource.data["PowerDevil"]["Keyboard Brightness Available"] ? true : false
2029 +
2030 +        showRemainingTime: show_remaining_time
2031 +
2032          pluggedIn: pmSource.data["AC Adapter"]["Plugged in"]
2033 -        remainingMsec: parent.show_remaining_time ? Number(pmSource.data["Battery"]["Remaining msec"]) : 0
2034 -        showSuspendButton: Platform.shouldOfferSuspend(pmSource)
2035 -        showHibernateButton: Platform.shouldOfferHibernate(pmSource)
2036  
2037 -        onSuspendClicked: {
2038 -            plasmoid.togglePopup();
2039 -            service = pmSource.serviceForSource("PowerDevil");
2040 -            var operationName = Logic.callForType(type);
2041 -            operation = service.operationDescription(operationName);
2042 -            service.startOperationCall(operation);
2043 -        }
2044          onBrightnessChanged: {
2045              if (disableBrightnessUpdate) {
2046                  return;
2047 @@ -220,6 +122,15 @@ Item {
2048              operation.brightness = screenBrightness;
2049              service.startOperationCall(operation);
2050          }
2051 +        onKeyboardBrightnessChanged: {
2052 +            if (disableBrightnessUpdate) {
2053 +                return;
2054 +            }
2055 +            service = pmSource.serviceForSource("PowerDevil");
2056 +            operation = service.operationDescription("setKeyboardBrightness");
2057 +            operation.brightness = keyboardBrightness;
2058 +            service.startOperationCall(operation);
2059 +        }
2060          property int cookie1: -1
2061          property int cookie2: -1
2062          onPowermanagementChanged: {
2063 diff --git a/plasma/generic/applets/batterymonitor/contents/ui/config.ui b/plasma/generic/applets/batterymonitor/contents/ui/config.ui
2064 deleted file mode 100644
2065 index 3df38e2..0000000
2066 --- a/plasma/generic/applets/batterymonitor/contents/ui/config.ui
2067 +++ /dev/null
2068 @@ -1,54 +0,0 @@
2069 -<?xml version="1.0" encoding="UTF-8"?>
2070 -<ui version="4.0">
2071 - <class>batteryConfig</class>
2072 - <widget class="QWidget" name="batteryConfig">
2073 -  <property name="geometry">
2074 -   <rect>
2075 -    <x>0</x>
2076 -    <y>0</y>
2077 -    <width>247</width>
2078 -    <height>73</height>
2079 -   </rect>
2080 -  </property>
2081 -  <property name="windowTitle">
2082 -   <string>Configure Battery Monitor</string>
2083 -  </property>
2084 -  <layout class="QVBoxLayout" name="verticalLayout">
2085 -   <item>
2086 -    <widget class="QCheckBox" name="kcfg_showBatteryString">
2087 -     <property name="toolTip">
2088 -      <string/>
2089 -     </property>
2090 -     <property name="text">
2091 -      <string>Show charge &amp;information</string>
2092 -     </property>
2093 -    </widget>
2094 -   </item>
2095 -   <item>
2096 -    <widget class="QCheckBox" name="kcfg_showMultipleBatteries">
2097 -     <property name="toolTip">
2098 -      <string/>
2099 -     </property>
2100 -     <property name="text">
2101 -      <string>Show the state for &amp;each battery present</string>
2102 -     </property>
2103 -    </widget>
2104 -   </item>
2105 -   <item>
2106 -    <spacer name="verticalSpacer">
2107 -     <property name="orientation">
2108 -      <enum>Qt::Vertical</enum>
2109 -     </property>
2110 -     <property name="sizeHint" stdset="0">
2111 -      <size>
2112 -       <width>20</width>
2113 -       <height>15</height>
2114 -      </size>
2115 -     </property>
2116 -    </spacer>
2117 -   </item>
2118 -  </layout>
2119 - </widget>
2120 - <resources/>
2121 - <connections/>
2122 -</ui>
2123 diff --git a/plasma/generic/applets/batterymonitor/metadata.desktop b/plasma/generic/applets/batterymonitor/metadata.desktop
2124 index cd8f1a2..2b70e2c 100644
2125 --- a/plasma/generic/applets/batterymonitor/metadata.desktop
2126 +++ b/plasma/generic/applets/batterymonitor/metadata.desktop
2127 @@ -159,7 +159,6 @@ Comment[zh_CN]=查看电池电源的状态
2128  Comment[zh_TW]=查看您的電池的電力狀態
2129  Encoding=UTF-8
2130  Keywords=Power Management;Battery;System;Energy;
2131 -Keywords[bs]=Upravljanje napajenjem, Baterija, Sistem, Energija
2132  Keywords[ca]=Sistema de gestió d'energia;Bateria;Sistema;Energia;
2133  Keywords[cs]=Správa napájení;Baterie;Systém;Energie;
2134  Keywords[da]=Strømstyring;battery;system;energi;
2135 @@ -167,17 +166,16 @@ Keywords[de]=Energieverwaltungssystem;Akku;System;Energie;
2136  Keywords[el]=Διαχείριση ισχύος·Μπαταρία·Σύστημα·Ενέργεια·
2137  Keywords[es]=Gestión de energía;Batería;Sistema;Energía;
2138  Keywords[fi]=Virranhallinta;Akku;Järjestelmä;Virransäästö;
2139 -Keywords[fr]=Gestion de l'énergie, Batterie, Système, Énergie, 
2140 -Keywords[gl]=Power Management;Battery;System;Energy;xestión da enerxía;batería;sistema;
2141 +Keywords[fr]=Gestion de l'énergie, Batterie, Système, Énergie,
2142  Keywords[hu]=Energiakezelés;Akkumulátor;Rendszer;Energia;
2143 -Keywords[ia]=Gestion de energia; Batteria;Systema; Energia;
2144 -Keywords[it]=Gestione energetica;Batteria;Sistema;Energia;
2145 +Keywords[ia]=Gestion de energia;Batteria;Systema; Energia;
2146  Keywords[kk]=Power Management;Battery;System;Energy;
2147  Keywords[lt]=Energijos valdymas,Baterija,Sistema,Energija,akumuliatorius;
2148  Keywords[mr]=वीज व्यवस्थापन; बॅटरी; प्रणाली; ऊर्जा;
2149  Keywords[nb]=Strømstyring; Batteri; System; Energi;
2150  Keywords[nl]=Energiebeheer;Batterij;Accu;Systeem;Energie;
2151 -Keywords[pl]=Zarządzanie energią;bateria;system;energia;
2152 +Keywords[pa]=ਪਾਵਰ ਪਰਬੰਧ;ਬੈਟਰੀ;ਸਿਸਟਮ;ਊਰਜਾ;
2153 +Keywords[pl]=Zarządzanie Energią;Bateria;System;Energia
2154  Keywords[pt]=Gestão de Energia;Bateria;Sistema;Energia;
2155  Keywords[pt_BR]=Gerenciamento de energia;Bateria;Sistema;Energia;
2156  Keywords[ru]=Power Management;Battery;System;Energy;управление питанием;батарея;система;энергия;энергопотребление
2157 @@ -198,17 +196,17 @@ Type=Service
2158  X-KDE-ServiceTypes=Plasma/Applet,Plasma/PopupApplet
2159  
2160  X-Plasma-API=declarativeappletscript
2161 -X-Plasma-DefaultSize=100,100
2162 +X-Plasma-DefaultSize=450,300
2163  X-Plasma-MainScript=ui/batterymonitor.qml
2164  X-Plasma-ConfigPlugins=powerdevilprofilesconfig,powerdevilactivitiesconfig,powerdevilglobalconfig
2165  X-Plasma-NotificationArea=true
2166  
2167 -X-KDE-PluginInfo-Author=Sebastian Kügler
2168 +X-KDE-PluginInfo-Author=Sebastian Kügler, Kai Uwe Broulik
2169  X-KDE-PluginInfo-Category=System Information
2170 -X-KDE-PluginInfo-Email=sebas@kde.org
2171 +X-KDE-PluginInfo-Email=sebas@kde.org, kde@privat.broulik.de
2172  X-KDE-PluginInfo-License=GPL
2173  X-KDE-PluginInfo-Name=battery
2174 -X-KDE-PluginInfo-Version=1.0
2175 +X-KDE-PluginInfo-Version=2.0
2176  X-KDE-PluginInfo-Website=http://vizZzion.org
2177  X-KDE-PluginInfo-Depends=
2178  X-KDE-PluginInfo-EnabledByDefault=true
2179 diff --git a/plasma/generic/applets/batterymonitor/platformcontents/touch/code/platform.js b/plasma/generic/applets/batterymonitor/platformcontents/touch/code/platform.js
2180 deleted file mode 100644
2181 index aa57ab8..0000000
2182 --- a/plasma/generic/applets/batterymonitor/platformcontents/touch/code/platform.js
2183 +++ /dev/null
2184 @@ -1,9 +0,0 @@
2185 -
2186 -function shouldOfferSuspend() {
2187 -    return false;
2188 -}
2189 -
2190 -function shouldOfferHibernate() {
2191 -    return false;
2192 -}
2193 -
This page took 0.289333 seconds and 2 git commands to generate.