2 // C++ Implementation: batteryicon
4 // Author: Oliver Groß <z.o.gross@gmx.de>, (C) 2008
6 // Copyright: See COPYING file that comes with this distribution
8 #include "batteryicon.h"
11 #include <QMessageBox>
14 QDir
CBatteryIcon::sysfsDir(UI_PATH_SYSFS_DIR
);
16 CBatteryIcon::CBatteryIcon(Settings
* settings
, QString batteryName
, QObject
* parent
) :
17 QSystemTrayIcon(parent
),
21 m_Data
.name
= batteryName
;
25 connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason
)),
26 this, SLOT(handleClicks(QSystemTrayIcon::ActivationReason
)));
29 CBatteryIcon::~CBatteryIcon() {
32 void CBatteryIcon::updateIcon() {
33 m_Icon
.fill(Qt::transparent
);
34 QPainter
painter(&m_Icon
);
36 if (m_Data
.currentCapacity
!= m_Data
.fullCapacity
|| m_Data
.status
!= UI_BATTERY_FULL
) {
37 if (m_Data
.status
== UI_BATTERY_DISCHARGING
)
38 painter
.setPen(QColor(m_Settings
->colors
[UI_COLOR_PEN_DISCHARGE
]));
40 painter
.setPen(QColor(m_Settings
->colors
[UI_COLOR_PEN_CHARGE
]));
42 painter
.setBrush(QColor(m_Settings
->colors
[UI_COLOR_BRUSH_EMPTY
]));
43 painter
.drawRect(0, 4, 27, 23);
45 int chargedPixels
= (int)(22 * m_Data
.relativeCharge
/ 100.0);
47 painter
.fillRect(1, 5 + 22 - chargedPixels
, 26, chargedPixels
, QColor(m_Settings
->colors
[UI_COLOR_BRUSH_CHARGED
]));
49 if (m_Data
.status
== UI_BATTERY_DISCHARGING
)
50 painter
.setBrush(QColor(m_Settings
->colors
[UI_COLOR_BRUSH_POLE_DISCHARGE
]));
52 painter
.setBrush(QColor(m_Settings
->colors
[UI_COLOR_BRUSH_POLE_CHARGE
]));
55 painter
.setPen(QColor(m_Settings
->colors
[UI_COLOR_PEN_FULL
]));
56 painter
.setBrush(QColor(m_Settings
->colors
[UI_COLOR_BRUSH_FULL
]));
57 painter
.drawRect(0, 4, 27, 23);
59 painter
.setBrush(QColor(m_Settings
->colors
[UI_COLOR_BRUSH_POLE_FULL
]));
61 painter
.drawRect(7, 0, 13, 4);
63 painter
.setBrush(Qt::NoBrush
);
65 if (m_Data
.relativeCharge
< 100)
66 ((QFont
&)painter
.font()).setPixelSize(15);
68 ((QFont
&)painter
.font()).setPixelSize(12);
70 painter
.setRenderHint(QPainter::TextAntialiasing
);
71 ((QFont
&)painter
.font()).setBold(true);
72 if (m_Data
.relativeCharge
== -1)
73 painter
.drawText(1, 9, 26, 16, Qt::AlignHCenter
, QString('?'));
75 painter
.drawText(1, 9, 26, 16, Qt::AlignHCenter
, QString::number(m_Data
.relativeCharge
));
80 void CBatteryIcon::updateToolTip() {
81 QString newToolTip
= tr("%1: %2%").arg(m_Data
.name
) +'\n';
83 if (m_Data
.relativeCharge
== -1)
84 newToolTip
= newToolTip
.arg('-');
86 newToolTip
= newToolTip
.arg(m_Data
.relativeCharge
);
88 switch (m_Data
.status
) {
89 case UI_BATTERY_DISCHARGING
:
90 newToolTip
+= tr("status: %1").arg(tr("discharging"));
93 qreal remainingTime
= (qreal
)(m_Data
.currentCapacity
) / m_Data
.rate
;
94 int remainingHours
= (int)remainingTime
;
95 int remainungMinutes
= (int)(remainingTime
* 60) % 60;
96 newToolTip
+= tr("remaining time: %1:%2").arg(remainingHours
, 2, 10, QChar('0')).arg(remainungMinutes
, 2, 10, QChar('0'));
99 case UI_BATTERY_CHARGING
:
100 newToolTip
+= tr("status: %1").arg(tr("charging"));
101 if (m_Data
.rate
&& m_Data
.fullCapacity
) {
103 qreal remainingTime
= (qreal
)(m_Data
.fullCapacity
- m_Data
.currentCapacity
) / m_Data
.rate
;
104 int remainingHours
= (int)remainingTime
;
105 int remainungMinutes
= (int)(remainingTime
* 60) % 60;
106 newToolTip
+= tr("remaining time: %1:%2").arg(remainingHours
, 2, 10, QChar('0')).arg(remainungMinutes
, 2, 10, QChar('0'));
109 case UI_BATTERY_FULL
:
110 newToolTip
+= tr("status: %1").arg(tr("full"));
113 newToolTip
+= tr("status: %1").arg(tr("unknown"));
118 if (m_Data
.energyUnits
) {
119 if ((m_Data
.rate
) && (m_Data
.status
!= UI_BATTERY_FULL
)) {
120 double rateW
= qRound(m_Data
.rate
/ 100000.0) / 10.0;
121 if (m_Data
.voltage
) {
122 double rateA
= qRound((m_Data
.rate
/ m_Data
.voltage
) / 1000.0) / 10.0;
123 newToolTip
+= tr("current rate: %1W / %2A").arg(rateW
).arg(rateA
) + '\n';
126 newToolTip
+= tr("current rate: %1W").arg(rateW
) + '\n';
129 newToolTip
+= tr("current capacity: %1mWh").arg(m_Data
.currentCapacity
/ 1000);
131 if (m_Data
.fullCapacity
)
132 newToolTip
+= '\n' + tr("last full capacity: %1mWh").arg(m_Data
.fullCapacity
/ 1000);
134 if (m_Data
.designCapacity
)
135 newToolTip
+= '\n' + tr("design capacity: %1mWh").arg(m_Data
.designCapacity
/ 1000);
139 if ((m_Data
.rate
) && (m_Data
.status
!= UI_BATTERY_FULL
)) {
140 double rateA
= m_Data
.rate
/ 100000.0;
141 if (m_Data
.voltage
) {
142 double rateW
= qRound(rateA
* m_Data
.voltage
/ 100.0) / 10.0;
143 newToolTip
+= tr("current rate: %1W / %2A").arg(rateW
).arg(qRound(rateA
) / 10.0) + '\n';
146 newToolTip
+= tr("current rate: %1A").arg(qRound(rateA
) / 10.0) + '\n';
149 newToolTip
+= tr("current capacity: %1mAh").arg(m_Data
.currentCapacity
/ 1000);
151 if (m_Data
.fullCapacity
)
152 newToolTip
+= '\n' + tr("last full capacity: %1mAh").arg(m_Data
.fullCapacity
/ 1000);
154 if (m_Data
.designCapacity
)
155 newToolTip
+= '\n' + tr("design capacity: %1mAh").arg(m_Data
.designCapacity
/ 1000);
158 if (m_Data
.designCapacity
&& m_Data
.fullCapacity
< m_Data
.designCapacity
)
159 newToolTip
+= '\n' + tr("capacity loss: %1%").arg((int)((1 - (double)m_Data
.fullCapacity
/ m_Data
.designCapacity
) * 100));
161 setMessage(newToolTip
);
164 void CBatteryIcon::updateData(int currentCapacity
, int fullCapacity
, int designCapacity
, int rate
, int voltage
, int status
, bool energyUnits
) {
165 m_Data
.energyUnits
= energyUnits
;
167 bool noupdate
= true;
169 if (rate
!= m_Data
.rate
) {
174 if (voltage
!= m_Data
.voltage
) {
176 m_Data
.voltage
= voltage
;
179 if (status
!= m_Data
.status
) {
181 m_Data
.status
= status
;
184 if (fullCapacity
!= m_Data
.fullCapacity
) {
186 m_Data
.fullCapacity
= fullCapacity
;
189 if (designCapacity
!= m_Data
.designCapacity
) {
191 m_Data
.designCapacity
= designCapacity
;
194 if (currentCapacity
!= m_Data
.currentCapacity
) {
196 m_Data
.currentCapacity
= currentCapacity
;
202 qint8 newRelativeCharge
= calcRelativeDef(currentCapacity
, fullCapacity
);
204 if (newRelativeCharge
!= m_Data
.relativeCharge
) {
205 m_Data
.relativeCharge
= newRelativeCharge
;
215 void CBatteryIcon::updateData() {
216 int currentCapacity
= 0;
217 int fullCapacity
= 0;
218 int designCapacity
= 0;
222 bool energyUnits
= sysfsDir
.exists(m_Data
.name
+ UI_CAPTION_NOW(UI_CAPTION_ENERGY
));
224 rate
= readIntSysFile(sysfsDir
.filePath(m_Data
.name
+ "/current_now").toAscii().constData());
225 voltage
= readIntSysFile(sysfsDir
.filePath(m_Data
.name
+ UI_CAPTION_NOW(UI_CAPTION_VOLTAGE
)).toAscii().constData()) / 10000;
227 char buffer
[BUF_SIZE
];
228 readStringFromFile(buffer
, sysfsDir
.filePath(m_Data
.name
+ "/status").toAscii().constData());
229 status
= toStatusInt(buffer
);
232 fullCapacity
= readIntSysFile(sysfsDir
.filePath(m_Data
.name
+ UI_CAPTION_FULL(UI_CAPTION_ENERGY
)).toAscii().constData());
233 designCapacity
= readIntSysFile(sysfsDir
.filePath(m_Data
.name
+ UI_CAPTION_DESIGN(UI_CAPTION_ENERGY
)).toAscii().constData());
234 currentCapacity
= readIntSysFile(sysfsDir
.filePath(m_Data
.name
+ UI_CAPTION_NOW(UI_CAPTION_ENERGY
)).toAscii().constData());
237 fullCapacity
= readIntSysFile(sysfsDir
.filePath(m_Data
.name
+ UI_CAPTION_FULL(UI_CAPTION_CHARGE
)).toAscii().constData());
238 designCapacity
= readIntSysFile(sysfsDir
.filePath(m_Data
.name
+ UI_CAPTION_DESIGN(UI_CAPTION_CHARGE
)).toAscii().constData());
239 currentCapacity
= readIntSysFile(sysfsDir
.filePath(m_Data
.name
+ UI_CAPTION_NOW(UI_CAPTION_CHARGE
)).toAscii().constData());
242 updateData(currentCapacity
, fullCapacity
, designCapacity
, rate
, voltage
, status
, energyUnits
);
245 void CBatteryIcon::setMessage(QString value
) {
247 setToolTip(tr("QBat - %1").arg(m_Message
));
250 void CBatteryIcon::handleClicks(QSystemTrayIcon::ActivationReason reason
) {
253 if (supportsMessages())
254 showMessage(tr("QBat - Information"), m_Message
);
256 QMessageBox::information(NULL
, tr("QBat - Information"), m_Message
);