gcc 4.4 build fix
[qbat.git] / powermanager.cpp
blob746dd96a7acfb894686bfb52b68731ba0262a438
1 //
2 // C++ Implementation: powermanager
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 <QtGui>
9 #include "powermanager.h"
10 #include "common.h"
11 #include "settings.h"
12 #include "batteryicon.h"
13 #include "qtimermessagebox.h"
15 namespace qbat {
16 using namespace std;
18 CPowerManager::CPowerManager(QObject * parent) :
19 QObject(parent),
20 m_Timer(-1),
21 m_DataTimer(-1),
22 // m_RelativeCapacity(100),
23 m_ACPlug(false),
24 m_CriticalHandled(false),
25 m_SettingsFile(UI_FILE_CONFIG, QSettings::IniFormat, this)
27 readSettings();
28 m_ContextMenu.addAction(tr("&Settings"), this, SLOT(showSettings()))->setEnabled(CBatteryIcon::sysfsDir.exists());
29 m_ContextMenu.addAction(tr("&About"), this, SLOT(showAbout()));
30 m_ContextMenu.addSeparator();
31 m_ContextMenu.addAction(tr("&Quit"), qApp, SLOT(quit()));
33 m_DefaultIcon = new CBatteryIcon(&m_Settings, tr("merged"), this);
34 m_DefaultIcon->setContextMenu(&m_ContextMenu);
36 if (CBatteryIcon::sysfsDir.exists()) {
37 m_DataTimer = startTimer(15000);
38 m_Timer = startTimer(m_Settings.pollingRate);
40 updateSupplies();
43 CPowerManager::~CPowerManager() {
44 killTimer(m_Timer);
45 killTimer(m_DataTimer);
48 inline void CPowerManager::readSettings() {
49 m_SettingsFile.beginGroup("Main");
50 m_Settings.pollingRate = m_SettingsFile.value("pollingRate", 3000).toUInt();
51 m_Settings.showBalloon = m_SettingsFile.value("showBalloon", false).toBool();
52 m_SettingsFile.endGroup();
54 m_SettingsFile.beginGroup("TrayIcons");
55 m_Settings.mergeBatteries = m_SettingsFile.value("mergeBatteries", false).toBool();
56 m_Settings.colors[UI_COLOR_PEN_CHARGE] = m_SettingsFile.value("textChargingColor", 0).toUInt();
57 m_Settings.colors[UI_COLOR_PEN_DISCHARGE] = m_SettingsFile.value("textDischargingColor", 0).toUInt();
58 m_Settings.colors[UI_COLOR_PEN_FULL] = m_SettingsFile.value("textFullColor", 0).toUInt();
59 m_Settings.colors[UI_COLOR_BRUSH_CHARGED] = m_SettingsFile.value("mainChargedColor", qRgb( 0, 255, 0)).toUInt();
60 m_Settings.colors[UI_COLOR_BRUSH_EMPTY] = m_SettingsFile.value("mainEmptyColor", qRgb(255, 255, 255)).toUInt();
61 m_Settings.colors[UI_COLOR_BRUSH_FULL] = m_SettingsFile.value("mainFullColor", m_Settings.colors[UI_COLOR_BRUSH_CHARGED]).toUInt();
62 m_Settings.colors[UI_COLOR_BRUSH_POLE_CHARGE] = m_SettingsFile.value("poleChargingColor", qRgb(255, 255, 0)).toUInt();
63 m_Settings.colors[UI_COLOR_BRUSH_POLE_DISCHARGE] = m_SettingsFile.value("poleDischargingColor", qRgb(255, 255, 0)).toUInt();
64 m_Settings.colors[UI_COLOR_BRUSH_POLE_FULL] = m_SettingsFile.value("poleFullColor", m_Settings.colors[UI_COLOR_BRUSH_POLE_CHARGE]).toUInt();
65 m_SettingsFile.endGroup();
67 m_SettingsFile.beginGroup("CriticalEvent");
68 m_Settings.handleCritical = m_SettingsFile.value("handle", false).toBool();
69 m_Settings.criticalCapacity = m_SettingsFile.value("criticalCapacity", 7).toUInt();
70 m_Settings.executeCommand = m_SettingsFile.value("executeCommand", false).toBool();
71 m_Settings.criticalCommand = m_SettingsFile.value("command", "").toString();
72 m_Settings.confirmCommand = m_SettingsFile.value("confirmCommand", false).toBool();
73 m_Settings.confirmWithTimeout = m_SettingsFile.value("confirmWithTimeout", false).toBool();
74 m_Settings.timeoutValue = m_SettingsFile.value("timeoutValue", 5).toUInt();
75 m_SettingsFile.endGroup();
78 inline void CPowerManager::writeSettings() {
79 m_SettingsFile.beginGroup("Main");
80 m_SettingsFile.setValue("pollingRate", m_Settings.pollingRate);
81 m_SettingsFile.setValue("showBalloon", m_Settings.showBalloon);
82 m_SettingsFile.endGroup();
84 m_SettingsFile.beginGroup("TrayIcons");
85 m_SettingsFile.setValue("mergeBatteries", m_Settings.mergeBatteries);
86 m_SettingsFile.setValue("textChargingColor", m_Settings.colors[UI_COLOR_PEN_CHARGE]);
87 m_SettingsFile.setValue("textDischargingColor", m_Settings.colors[UI_COLOR_PEN_DISCHARGE]);
88 m_SettingsFile.setValue("textFullColor", m_Settings.colors[UI_COLOR_PEN_FULL]);
89 m_SettingsFile.setValue("mainChargedColor", m_Settings.colors[UI_COLOR_BRUSH_CHARGED]);
90 m_SettingsFile.setValue("mainEmptyColor", m_Settings.colors[UI_COLOR_BRUSH_EMPTY]);
91 m_SettingsFile.setValue("mainFullColor", m_Settings.colors[UI_COLOR_BRUSH_FULL]);
92 m_SettingsFile.setValue("poleChargingColor", m_Settings.colors[UI_COLOR_BRUSH_POLE_CHARGE]);
93 m_SettingsFile.setValue("poleDischargingColor", m_Settings.colors[UI_COLOR_BRUSH_POLE_DISCHARGE]);
94 m_SettingsFile.setValue("poleFullColor", m_Settings.colors[UI_COLOR_BRUSH_POLE_FULL]);
95 m_SettingsFile.endGroup();
97 m_SettingsFile.beginGroup("CriticalEvent");
98 m_SettingsFile.setValue("handle", m_Settings.handleCritical);
99 m_SettingsFile.setValue("criticalCapacity", m_Settings.criticalCapacity);
100 m_SettingsFile.setValue("executeCommand", m_Settings.executeCommand);
101 m_SettingsFile.setValue("command", m_Settings.criticalCommand);
102 m_SettingsFile.setValue("confirmCommand", m_Settings.confirmCommand);
103 m_SettingsFile.setValue("confirmWithTimeout", m_Settings.confirmWithTimeout);
104 m_SettingsFile.setValue("timeoutValue", m_Settings.timeoutValue);
105 m_SettingsFile.endGroup();
108 void CPowerManager::timerEvent(QTimerEvent * event) {
109 if (event->timerId() == m_Timer)
110 updateSupplies();
111 else if (event->timerId() == m_DataTimer)
112 updateBatteryData();
115 void CPowerManager::updateSupplies() {
116 if (CBatteryIcon::sysfsDir.exists()) {
117 bool oldAC = m_ACPlug;
118 m_ACPlug = false;
120 QStringList powerSupplies = CBatteryIcon::sysfsDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
122 QList<CBatteryIcon *> newBatteryIcons;
123 CBatteryIcon * currentBatteryIcon;
125 foreach(QString i, powerSupplies) {
126 // this is possibly not very reliable
127 if (CBatteryIcon::sysfsDir.exists(i + "/online")) {
128 if (readIntSysFile(CBatteryIcon::sysfsDir.filePath(i + "/online").toAscii().constData()) == 1) {
129 m_ACPlug = true;
130 m_CriticalHandled = false;
133 else {
134 if (m_BatteryIcons.contains(i)) {
135 currentBatteryIcon = m_BatteryIcons.take(i);
137 else {
138 // qDebug("new battery: %s", i.toAscii().constData());
139 currentBatteryIcon = new CBatteryIcon(&m_Settings, i, this);
140 currentBatteryIcon->setContextMenu(&m_ContextMenu);
141 currentBatteryIcon->updateData();
142 currentBatteryIcon->updateIcon();
143 currentBatteryIcon->updateToolTip();
145 if (!m_Settings.mergeBatteries)
146 currentBatteryIcon->show();
148 m_CriticalHandled = false;
150 newBatteryIcons << currentBatteryIcon;
154 foreach(CBatteryIcon * i, m_BatteryIcons)
155 delete i;
157 m_BatteryIcons.clear();
159 foreach(CBatteryIcon * i, newBatteryIcons)
160 m_BatteryIcons.insert(i->data().name, i);
162 if (oldAC != m_ACPlug)
163 updateBatteryData();
164 else
165 updateMergedData();
167 if (m_BatteryIcons.isEmpty()) {
168 if (!m_DefaultIcon->isVisible()) {
169 m_DefaultIcon->setVisible(true);
170 m_DefaultIcon->setIcon(QIcon(UI_ICON_QBAT_SMALL));
172 if (m_ACPlug)
173 m_DefaultIcon->setMessage(tr("AC adapter plugged in"));
174 else
175 m_DefaultIcon->setMessage(tr("AC adapter unplugged"));
178 else {
179 if (!m_DefaultIcon->isVisible()) {
180 m_DefaultIcon->updateData();
181 m_DefaultIcon->updateIcon();
183 m_DefaultIcon->setVisible(m_Settings.mergeBatteries);
186 checkCritical();
188 else {
189 m_DefaultIcon->setMessage(tr("no information available"));
190 m_DefaultIcon->setVisible(true);
195 void CPowerManager::updateMergedData() {
196 if (!m_BatteryIcons.isEmpty()) {
197 int fullCount = 0;
198 int rateCount = 0;
199 int voltageCount = 0;
201 int fullCapacity = 0;
202 int currentCapacity = 0;
203 int rate = 0;
204 int voltage = 0;
205 int status = 0;
207 foreach (CBatteryIcon * battery, m_BatteryIcons) {
208 if (battery->data().voltage) {
209 voltage += battery->data().voltage;
210 voltageCount++;
213 if (!battery->data().energyUnits) {
214 currentCapacity += battery->data().currentCapacity;
216 if (battery->data().fullCapacity) {
217 fullCapacity += battery->data().fullCapacity;
218 fullCount++;
221 if (battery->data().rate) {
222 rate += battery->data().rate;
223 rateCount++;
226 else if (battery->data().voltage) {
227 double voltageNorm = battery->data().voltage / 100.0;
228 currentCapacity += qRound(battery->data().currentCapacity / voltageNorm);
230 if (battery->data().fullCapacity) {
231 fullCapacity += qRound(battery->data().fullCapacity / voltageNorm);
232 fullCount++;
235 if (battery->data().rate) {
236 rate += qRound(battery->data().rate / voltageNorm);
237 rateCount++;
241 if ((!status) || (battery->data().status != UI_BATTERY_FULL))
242 status = battery->data().status;
245 if (fullCount)
246 fullCapacity /= fullCount;
248 if (rateCount)
249 rate /= rateCount;
251 if (voltageCount)
252 voltage /= voltageCount;
254 currentCapacity /= m_BatteryIcons.count();
256 m_DefaultIcon->updateData(currentCapacity, fullCapacity, 0, rate, voltage, status, false);
260 void CPowerManager::checkCritical() {
261 if (m_ACPlug || m_CriticalHandled ||
262 m_DefaultIcon->data().relativeCharge == -1 || !m_Settings.handleCritical ||
263 m_DefaultIcon->data().relativeCharge > m_Settings.criticalCapacity)
264 return;
266 QString msgTitle = (m_Settings.executeCommand && m_Settings.confirmWithTimeout) ?
267 tr("QBat - critical battery capacity (will automatically choose ok on timeout)"):
268 tr("QBat - critical battery capacity");
269 QString msgText = (m_Settings.executeCommand && m_Settings.confirmCommand) ?
270 tr("WARNING: The attached battery(s) reached the critical mark.\n"
271 "Click cancel and please make sure to save and shut down soon or provide another source of power\n"
272 "or:\n"
273 "Click ok to execute:\n%1").arg(m_Settings.criticalCommand) :
274 tr("WARNING: The attached battery(s) reached the critical mark.\n"
275 "Please make sure to save and shut down soon or provide another source of power.");
276 if (m_Settings.executeCommand && (!m_Settings.confirmCommand || (QTimerMessageBox::warning(NULL, msgTitle, msgText,
277 (m_Settings.confirmWithTimeout) ? m_Settings.timeoutValue : -1, QMessageBox::Ok | QMessageBox::Cancel))))
278 QProcess::startDetached(m_Settings.criticalCommand);
279 else {
280 if (m_Settings.showBalloon)
281 m_BatteryIcons.begin().value()->showMessage(msgTitle, msgText, QSystemTrayIcon::Warning, 7000);
282 else
283 QMessageBox::warning(NULL, msgTitle, msgText);
285 m_CriticalHandled = true;
288 void CPowerManager::updateBatteryData() {
289 foreach (CBatteryIcon * battery, m_BatteryIcons)
290 battery->updateData();
292 updateMergedData();
293 checkCritical();
296 void CPowerManager::restartTimer() {
297 killTimer(m_Timer);
298 m_Timer = startTimer(m_Settings.pollingRate);
299 killTimer(m_DataTimer);
300 m_DataTimer = startTimer(15000);
303 void CPowerManager::showSettings() {
304 CSettings dialog;
306 if (dialog.execute(&m_Settings)) {
307 foreach (CBatteryIcon * i, m_BatteryIcons) {
308 delete i;
311 m_BatteryIcons.clear();
312 m_DefaultIcon->updateData(0, 0, 0, 0, 0, 0, false);
314 updateSupplies();
315 restartTimer();
316 writeSettings();
320 void CPowerManager::showAbout() {
321 if (m_Settings.showBalloon) {
322 if (m_DefaultIcon->isVisible())
323 m_DefaultIcon->showMessage(tr("About QBat"), UI_NAME + "\nv" + QString(UI_VERSION),
324 QSystemTrayIcon::Information, 4000);
325 else
326 m_BatteryIcons.begin().value()->showMessage(tr("About QBat"), UI_NAME + "\nv" + QString(UI_VERSION),
327 QSystemTrayIcon::Information, 4000);
329 else {
330 QMessageBox aboutBox;
332 aboutBox.setWindowIcon(QIcon(UI_ICON_QBAT_SMALL));
333 aboutBox.setIconPixmap(QPixmap(UI_ICON_QBAT_LARGE));
334 aboutBox.setWindowTitle(tr("About QBat"));
335 aboutBox.setText(UI_NAME + "\nv" + QString(UI_VERSION));
336 aboutBox.setStandardButtons(QMessageBox::Ok);
338 aboutBox.exec();