added capacity loss information
[qbat.git] / batteryicon.cpp
blobaa786d261743880ecfe8d1b7bc25b64ba39a5ee5
1 //
2 // C++ Implementation: batteryicon
3 //
4 // Author: Oliver Groß <z.o.gross@gmx.de>, (C) 2008
5 //
6 // Copyright: See COPYING file that comes with this distribution
7 //
8 #include "batteryicon.h"
9 #include "common.h"
10 #include <QPainter>
11 #include <QMessageBox>
13 namespace qbat {
14 QDir CBatteryIcon::sysfsDir(UI_PATH_SYSFS_DIR);
16 CBatteryIcon::CBatteryIcon(Settings * settings, QString batteryName, QObject * parent) :
17 QSystemTrayIcon(parent),
18 m_Icon(28, 28),
19 m_Settings(settings)
21 m_Data.name = batteryName;
23 connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
24 this, SLOT(handleClicks(QSystemTrayIcon::ActivationReason)));
27 CBatteryIcon::~CBatteryIcon() {
30 void CBatteryIcon::updateIcon() {
31 m_Icon.fill(Qt::transparent);
32 QPainter painter(&m_Icon);
34 if (m_Data.currentCapacity != m_Data.fullCapacity || m_Data.status != UI_BATTERY_FULL) {
35 if (m_Data.status == UI_BATTERY_DISCHARGING)
36 painter.setPen(QColor(m_Settings->colors[UI_COLOR_PEN_DISCHARGE]));
37 else
38 painter.setPen(QColor(m_Settings->colors[UI_COLOR_PEN_CHARGE]));
40 painter.setBrush(QColor(m_Settings->colors[UI_COLOR_BRUSH_EMPTY]));
41 painter.drawRect(0, 4, 27, 23);
43 int chargedPixels = (int)(22 * m_Data.relativeCharge / 100.0);
45 painter.fillRect(1, 5 + 22 - chargedPixels, 26, chargedPixels, QColor(m_Settings->colors[UI_COLOR_BRUSH_CHARGED]));
47 if (m_Data.status == UI_BATTERY_DISCHARGING)
48 painter.setBrush(QColor(m_Settings->colors[UI_COLOR_BRUSH_POLE_DISCHARGE]));
49 else
50 painter.setBrush(QColor(m_Settings->colors[UI_COLOR_BRUSH_POLE_CHARGE]));
52 else {
53 painter.setPen(QColor(m_Settings->colors[UI_COLOR_PEN_FULL]));
54 painter.setBrush(QColor(m_Settings->colors[UI_COLOR_BRUSH_FULL]));
55 painter.drawRect(0, 4, 27, 23);
57 painter.setBrush(QColor(m_Settings->colors[UI_COLOR_BRUSH_POLE_FULL]));
59 painter.drawRect(7, 0, 13, 4);
61 painter.setBrush(Qt::NoBrush);
63 if (m_Data.relativeCharge < 100)
64 ((QFont&)painter.font()).setPixelSize(15);
65 else
66 ((QFont&)painter.font()).setPixelSize(12);
68 painter.setRenderHint(QPainter::TextAntialiasing);
69 ((QFont&)painter.font()).setBold(true);
70 if (m_Data.relativeCharge == -1)
71 painter.drawText(1, 9, 26, 16, Qt::AlignHCenter, QString('?'));
72 else
73 painter.drawText(1, 9, 26, 16, Qt::AlignHCenter, QString::number(m_Data.relativeCharge));
75 setIcon(m_Icon);
78 void CBatteryIcon::updateToolTip() {
79 QString newToolTip = tr("%1: %2%").arg(m_Data.name) +'\n';
81 if (m_Data.relativeCharge == -1)
82 newToolTip = newToolTip.arg('-');
83 else
84 newToolTip = newToolTip.arg(m_Data.relativeCharge);
86 switch (m_Data.status) {
87 case UI_BATTERY_DISCHARGING:
88 newToolTip += tr("status: %1").arg(tr("discharging"));
89 if (m_Data.rate) {
90 newToolTip += '\n';
91 qreal remainingTime = (qreal)(m_Data.currentCapacity) / m_Data.rate;
92 int remainingHours = (int)remainingTime;
93 int remainungMinutes = (int)(remainingTime * 60) % 60;
94 newToolTip += tr("remaining time: %1:%2").arg(remainingHours, 2, 10, QChar('0')).arg(remainungMinutes, 2, 10, QChar('0'));
96 break;
97 case UI_BATTERY_CHARGING:
98 newToolTip += tr("status: %1").arg(tr("charging"));
99 if (m_Data.rate && m_Data.fullCapacity) {
100 newToolTip += '\n';
101 qreal remainingTime = (qreal)(m_Data.fullCapacity - m_Data.currentCapacity) / m_Data.rate;
102 int remainingHours = (int)remainingTime;
103 int remainungMinutes = (int)(remainingTime * 60) % 60;
104 newToolTip += tr("remaining time: %1:%2").arg(remainingHours, 2, 10, QChar('0')).arg(remainungMinutes, 2, 10, QChar('0'));
106 break;
107 case UI_BATTERY_FULL:
108 newToolTip += tr("status: %1").arg(tr("full"));
109 break;
110 default:
111 newToolTip += tr("status: %1").arg(tr("unknown"));
112 break;
114 newToolTip += '\n';
116 if (m_Data.energyUnits) {
117 if ((m_Data.rate) && (m_Data.status != UI_BATTERY_FULL)) {
118 double rateW = qRound(m_Data.rate / 100000.0) / 10.0;
119 if (m_Data.voltage) {
120 double rateA = qRound((m_Data.rate / m_Data.voltage) / 1000.0) / 10.0;
121 newToolTip += tr("current rate: %1W / %2A").arg(rateW).arg(rateA) + '\n';
123 else
124 newToolTip += tr("current rate: %1W").arg(rateW) + '\n';
127 newToolTip += tr("current capacity: %1mWh").arg(m_Data.currentCapacity / 1000);
129 if (m_Data.fullCapacity)
130 newToolTip += '\n' + tr("last full capacity: %1mWh").arg(m_Data.fullCapacity / 1000);
132 if (m_Data.designCapacity) {
133 newToolTip += '\n' + tr("design capacity: %1mWh").arg(m_Data.designCapacity / 1000);
134 if (m_Data.fullCapacity < m_Data.designCapacity)
135 newToolTip += '\n' + tr("capacity loss: %1%").arg((int)((1 - (double)m_Data.fullCapacity / m_Data.designCapacity) * 100));
138 else
140 if ((m_Data.rate) && (m_Data.status != UI_BATTERY_FULL)) {
141 double rateA = m_Data.rate / 100000.0;
142 if (m_Data.voltage) {
143 double rateW = qRound(rateA * m_Data.voltage / 100.0) / 10.0;
144 newToolTip += tr("current rate: %1W / %2A").arg(rateW).arg(qRound(rateA) / 10.0) + '\n';
146 else
147 newToolTip += tr("current rate: %1A").arg(qRound(rateA) / 10.0) + '\n';
150 newToolTip += tr("current capacity: %1mAh").arg(m_Data.currentCapacity / 1000);
152 if (m_Data.fullCapacity)
153 newToolTip += '\n' + tr("last full capacity: %1mAh").arg(m_Data.fullCapacity / 1000);
155 if (m_Data.designCapacity)
156 newToolTip += '\n' + tr("design capacity: %1mAh").arg(m_Data.designCapacity / 1000);
159 setMessage(newToolTip);
162 void CBatteryIcon::updateData(int currentCapacity, int fullCapacity, int designCapacity, int rate, int voltage, int status, bool energyUnits) {
163 m_Data.energyUnits = energyUnits;
165 bool noupdate = true;
167 if (rate != m_Data.rate) {
168 noupdate = false;
169 m_Data.rate = rate;
172 if (voltage != m_Data.voltage) {
173 noupdate = false;
174 m_Data.voltage = voltage;
177 if (status != m_Data.status) {
178 noupdate = false;
179 m_Data.status = status;
182 if (fullCapacity != m_Data.fullCapacity) {
183 noupdate = false;
184 m_Data.fullCapacity = fullCapacity;
187 if (designCapacity != m_Data.designCapacity) {
188 noupdate = false;
189 m_Data.designCapacity = designCapacity;
192 if (currentCapacity != m_Data.currentCapacity) {
193 noupdate = false;
194 m_Data.currentCapacity = currentCapacity;
197 if (noupdate)
198 return;
200 qint8 newRelativeCharge = calcRelativeDef(currentCapacity, fullCapacity);
202 if (newRelativeCharge != m_Data.relativeCharge) {
203 m_Data.relativeCharge = newRelativeCharge;
205 if (isVisible())
206 updateIcon();
209 if (isVisible())
210 updateToolTip();
213 void CBatteryIcon::updateData() {
214 int currentCapacity = 0;
215 int fullCapacity = 0;
216 int designCapacity = 0;
217 int rate = 0;
218 int voltage = 0;
219 int status = 0;
220 bool energyUnits = sysfsDir.exists(m_Data.name + UI_CAPTION_NOW(UI_CAPTION_ENERGY));
222 rate = readIntSysFile(sysfsDir.filePath(m_Data.name + "/current_now").toAscii().constData());
223 voltage = readIntSysFile(sysfsDir.filePath(m_Data.name + UI_CAPTION_NOW(UI_CAPTION_VOLTAGE)).toAscii().constData()) / 10000;
225 char buffer[BUF_SIZE];
226 readStringFromFile(buffer, sysfsDir.filePath(m_Data.name + "/status").toAscii().constData());
227 status = toStatusInt(buffer);
229 if (energyUnits) {
230 fullCapacity = readIntSysFile(sysfsDir.filePath(m_Data.name + UI_CAPTION_FULL(UI_CAPTION_ENERGY)).toAscii().constData());
231 designCapacity = readIntSysFile(sysfsDir.filePath(m_Data.name + UI_CAPTION_DESIGN(UI_CAPTION_ENERGY)).toAscii().constData());
232 currentCapacity = readIntSysFile(sysfsDir.filePath(m_Data.name + UI_CAPTION_NOW(UI_CAPTION_ENERGY)).toAscii().constData());
234 else {
235 fullCapacity = readIntSysFile(sysfsDir.filePath(m_Data.name + UI_CAPTION_FULL(UI_CAPTION_CHARGE)).toAscii().constData());
236 designCapacity = readIntSysFile(sysfsDir.filePath(m_Data.name + UI_CAPTION_DESIGN(UI_CAPTION_CHARGE)).toAscii().constData());
237 currentCapacity = readIntSysFile(sysfsDir.filePath(m_Data.name + UI_CAPTION_NOW(UI_CAPTION_CHARGE)).toAscii().constData());
240 updateData(currentCapacity, fullCapacity, designCapacity, rate, voltage, status, energyUnits);
243 void CBatteryIcon::setMessage(QString value) {
244 m_Message = value;
245 setToolTip(tr("QBat - %1").arg(m_Message));
248 void CBatteryIcon::handleClicks(QSystemTrayIcon::ActivationReason reason) {
249 switch (reason) {
250 case Trigger:
251 if (supportsMessages())
252 showMessage(tr("QBat - Information"), m_Message);
253 else
254 QMessageBox::information(NULL, tr("QBat - Information"), m_Message);
255 break;
256 default:
257 break;