2 // C++ Implementation: powermanager
4 // Author: Oliver Groß <z.o.gross@gmx.de>, (C) 2008
6 // Copyright: See COPYING file that comes with this distribution
9 #include "powermanager.h"
12 #include "batteryicon.h"
13 #include "qtimermessagebox.h"
18 CPowerManager::CPowerManager(QObject
* parent
) :
22 // m_RelativeCapacity(100),
24 m_CriticalHandled(false),
25 m_SettingsFile(UI_FILE_CONFIG
, QSettings::IniFormat
, this)
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
);
43 CPowerManager::~CPowerManager() {
45 killTimer(m_DataTimer
);
49 inline void CPowerManager::readSettings() {
50 m_SettingsFile
.beginGroup("Main");
51 m_Settings
.pollingRate
= m_SettingsFile
.value("pollingRate", 3000).toUInt();
52 m_Settings
.showBalloon
= m_SettingsFile
.value("showBalloon", false).toBool();
53 m_SettingsFile
.endGroup();
55 m_SettingsFile
.beginGroup("TrayIcons");
56 m_Settings
.mergeBatteries
= m_SettingsFile
.value("mergeBatteries", false).toBool();
57 m_Settings
.colors
[UI_COLOR_PEN_CHARGE
] = m_SettingsFile
.value("textChargingColor", 0).toUInt();
58 m_Settings
.colors
[UI_COLOR_PEN_DISCHARGE
] = m_SettingsFile
.value("textDischargingColor", 0).toUInt();
59 m_Settings
.colors
[UI_COLOR_PEN_FULL
] = m_SettingsFile
.value("textFullColor", 0).toUInt();
60 m_Settings
.colors
[UI_COLOR_BRUSH_CHARGED
] = m_SettingsFile
.value("mainChargedColor", qRgb( 0, 255, 0)).toUInt();
61 m_Settings
.colors
[UI_COLOR_BRUSH_EMPTY
] = m_SettingsFile
.value("mainEmptyColor", qRgb(255, 255, 255)).toUInt();
62 m_Settings
.colors
[UI_COLOR_BRUSH_FULL
] = m_SettingsFile
.value("mainFullColor", m_Settings
.colors
[UI_COLOR_BRUSH_CHARGED
]).toUInt();
63 m_Settings
.colors
[UI_COLOR_BRUSH_POLE_CHARGE
] = m_SettingsFile
.value("poleChargingColor", qRgb(255, 255, 0)).toUInt();
64 m_Settings
.colors
[UI_COLOR_BRUSH_POLE_DISCHARGE
] = m_SettingsFile
.value("poleDischargingColor", qRgb(255, 255, 0)).toUInt();
65 m_Settings
.colors
[UI_COLOR_BRUSH_POLE_FULL
] = m_SettingsFile
.value("poleFullColor", m_Settings
.colors
[UI_COLOR_BRUSH_POLE_CHARGE
]).toUInt();
66 m_SettingsFile
.endGroup();
68 m_SettingsFile
.beginGroup("CriticalEvent");
69 m_Settings
.handleCritical
= m_SettingsFile
.value("handle", false).toBool();
70 m_Settings
.criticalCapacity
= m_SettingsFile
.value("criticalCapacity", 7).toUInt();
71 m_Settings
.executeCommand
= m_SettingsFile
.value("executeCommand", false).toBool();
72 m_Settings
.criticalCommand
= m_SettingsFile
.value("command", "").toString();
73 m_Settings
.confirmCommand
= m_SettingsFile
.value("confirmCommand", false).toBool();
74 m_Settings
.confirmWithTimeout
= m_SettingsFile
.value("confirmWithTimeout", false).toBool();
75 m_Settings
.timeoutValue
= m_SettingsFile
.value("timeoutValue", 5).toUInt();
76 m_SettingsFile
.endGroup();
79 inline void CPowerManager::writeSettings() {
80 m_SettingsFile
.beginGroup("Main");
81 m_SettingsFile
.setValue("pollingRate", m_Settings
.pollingRate
);
82 m_SettingsFile
.setValue("showBalloon", m_Settings
.showBalloon
);
83 m_SettingsFile
.endGroup();
85 m_SettingsFile
.beginGroup("TrayIcons");
86 m_SettingsFile
.setValue("mergeBatteries", m_Settings
.mergeBatteries
);
87 m_SettingsFile
.setValue("textChargingColor", m_Settings
.colors
[UI_COLOR_PEN_CHARGE
]);
88 m_SettingsFile
.setValue("textDischargingColor", m_Settings
.colors
[UI_COLOR_PEN_DISCHARGE
]);
89 m_SettingsFile
.setValue("textFullColor", m_Settings
.colors
[UI_COLOR_PEN_FULL
]);
90 m_SettingsFile
.setValue("mainChargedColor", m_Settings
.colors
[UI_COLOR_BRUSH_CHARGED
]);
91 m_SettingsFile
.setValue("mainEmptyColor", m_Settings
.colors
[UI_COLOR_BRUSH_EMPTY
]);
92 m_SettingsFile
.setValue("mainFullColor", m_Settings
.colors
[UI_COLOR_BRUSH_FULL
]);
93 m_SettingsFile
.setValue("poleChargingColor", m_Settings
.colors
[UI_COLOR_BRUSH_POLE_CHARGE
]);
94 m_SettingsFile
.setValue("poleDischargingColor", m_Settings
.colors
[UI_COLOR_BRUSH_POLE_DISCHARGE
]);
95 m_SettingsFile
.setValue("poleFullColor", m_Settings
.colors
[UI_COLOR_BRUSH_POLE_FULL
]);
96 m_SettingsFile
.endGroup();
98 m_SettingsFile
.beginGroup("CriticalEvent");
99 m_SettingsFile
.setValue("handle", m_Settings
.handleCritical
);
100 m_SettingsFile
.setValue("criticalCapacity", m_Settings
.criticalCapacity
);
101 m_SettingsFile
.setValue("executeCommand", m_Settings
.executeCommand
);
102 m_SettingsFile
.setValue("command", m_Settings
.criticalCommand
);
103 m_SettingsFile
.setValue("confirmCommand", m_Settings
.confirmCommand
);
104 m_SettingsFile
.setValue("confirmWithTimeout", m_Settings
.confirmWithTimeout
);
105 m_SettingsFile
.setValue("timeoutValue", m_Settings
.timeoutValue
);
106 m_SettingsFile
.endGroup();
109 void CPowerManager::timerEvent(QTimerEvent
* event
) {
110 if (event
->timerId() == m_Timer
)
112 else if (event
->timerId() == m_DataTimer
)
116 void CPowerManager::updateSupplies() {
117 if (CBatteryIcon::sysfsDir
.exists()) {
118 bool oldAC
= m_ACPlug
;
121 QStringList powerSupplies
= CBatteryIcon::sysfsDir
.entryList(QDir::Dirs
| QDir::NoDotAndDotDot
);
123 QList
<CBatteryIcon
*> newBatteryIcons
;
124 CBatteryIcon
* currentBatteryIcon
;
126 foreach(QString i
, powerSupplies
) {
127 // this is possibly not very reliable
128 if (CBatteryIcon::sysfsDir
.exists(i
+ "/online")) {
129 if (readIntSysFile(CBatteryIcon::sysfsDir
.filePath(i
+ "/online").toAscii().constData()) == 1) {
131 m_CriticalHandled
= false;
135 if (m_BatteryIcons
.contains(i
)) {
136 currentBatteryIcon
= m_BatteryIcons
.take(i
);
139 // qDebug("new battery: %s", i.toAscii().constData());
140 currentBatteryIcon
= new CBatteryIcon(&m_Settings
, i
, this);
141 currentBatteryIcon
->setContextMenu(&m_ContextMenu
);
142 currentBatteryIcon
->updateData();
143 currentBatteryIcon
->updateIcon();
144 currentBatteryIcon
->updateToolTip();
146 if (!m_Settings
.mergeBatteries
)
147 currentBatteryIcon
->show();
149 m_CriticalHandled
= false;
151 newBatteryIcons
<< currentBatteryIcon
;
155 foreach(CBatteryIcon
* i
, m_BatteryIcons
)
158 m_BatteryIcons
.clear();
160 foreach(CBatteryIcon
* i
, newBatteryIcons
)
161 m_BatteryIcons
.insert(i
->data().name
, i
);
163 if (oldAC
!= m_ACPlug
)
168 if (m_BatteryIcons
.isEmpty()) {
169 if (!m_DefaultIcon
->isVisible()) {
170 m_DefaultIcon
->setVisible(true);
171 m_DefaultIcon
->setIcon(QIcon(UI_ICON_QBAT_SMALL
));
174 m_DefaultIcon
->setMessage(tr("AC adapter plugged in"));
176 m_DefaultIcon
->setMessage(tr("AC adapter unplugged"));
180 if (!m_DefaultIcon
->isVisible()) {
181 m_DefaultIcon
->updateData();
182 m_DefaultIcon
->updateIcon();
184 m_DefaultIcon
->setVisible(m_Settings
.mergeBatteries
);
190 m_DefaultIcon
->setMessage(tr("no information available"));
191 m_DefaultIcon
->setVisible(true);
196 void CPowerManager::updateMergedData() {
197 if (!m_BatteryIcons
.isEmpty()) {
200 int voltageCount
= 0;
202 int fullCapacity
= 0;
203 int currentCapacity
= 0;
208 foreach (CBatteryIcon
* battery
, m_BatteryIcons
) {
209 if (battery
->data().voltage
) {
210 voltage
+= battery
->data().voltage
;
214 if (!battery
->data().energyUnits
) {
215 currentCapacity
+= battery
->data().currentCapacity
;
217 if (battery
->data().fullCapacity
) {
218 fullCapacity
+= battery
->data().fullCapacity
;
222 if (battery
->data().rate
) {
223 rate
+= battery
->data().rate
;
227 else if (battery
->data().voltage
) {
228 double voltageNorm
= battery
->data().voltage
/ 100.0;
229 currentCapacity
+= qRound(battery
->data().currentCapacity
/ voltageNorm
);
231 if (battery
->data().fullCapacity
) {
232 fullCapacity
+= qRound(battery
->data().fullCapacity
/ voltageNorm
);
236 if (battery
->data().rate
) {
237 rate
+= qRound(battery
->data().rate
/ voltageNorm
);
242 if ((!status
) || (battery
->data().status
!= UI_BATTERY_FULL
))
243 status
= battery
->data().status
;
247 fullCapacity
/= fullCount
;
253 voltage
/= voltageCount
;
255 currentCapacity
/= m_BatteryIcons
.count();
257 m_DefaultIcon
->updateData(currentCapacity
, fullCapacity
, 0, rate
, voltage
, status
, false);
261 void CPowerManager::checkCritical() {
262 if (m_ACPlug
|| m_CriticalHandled
||
263 m_DefaultIcon
->data().relativeCharge
== -1 || !m_Settings
.handleCritical
||
264 m_DefaultIcon
->data().relativeCharge
> m_Settings
.criticalCapacity
)
267 QString msgTitle
= (m_Settings
.executeCommand
&& m_Settings
.confirmWithTimeout
) ?
268 tr("QBat - critical battery capacity (will automatically choose ok on timeout)"):
269 tr("QBat - critical battery capacity");
270 QString msgText
= (m_Settings
.executeCommand
&& m_Settings
.confirmCommand
) ?
271 tr("WARNING: The attached battery(s) reached the critical mark.\n"
272 "Click cancel and please make sure to save and shut down soon or provide another source of power\n"
274 "Click ok to execute:\n%1").arg(m_Settings
.criticalCommand
) :
275 tr("WARNING: The attached battery(s) reached the critical mark.\n"
276 "Please make sure to save and shut down soon or provide another source of power.");
277 if (m_Settings
.executeCommand
&& (!m_Settings
.confirmCommand
|| (QTimerMessageBox::warning(NULL
, msgTitle
, msgText
,
278 (m_Settings
.confirmWithTimeout
) ? m_Settings
.timeoutValue
: -1, QMessageBox::Ok
| QMessageBox::Cancel
))))
279 QProcess::startDetached(m_Settings
.criticalCommand
);
281 if (m_Settings
.showBalloon
)
282 m_BatteryIcons
.begin().value()->showMessage(msgTitle
, msgText
, QSystemTrayIcon::Warning
, 7000);
284 QMessageBox::warning(NULL
, msgTitle
, msgText
);
286 m_CriticalHandled
= true;
289 void CPowerManager::updateBatteryData() {
290 foreach (CBatteryIcon
* battery
, m_BatteryIcons
)
291 battery
->updateData();
297 void CPowerManager::restartTimer() {
299 m_Timer
= startTimer(m_Settings
.pollingRate
);
300 killTimer(m_DataTimer
);
301 m_DataTimer
= startTimer(15000);
304 void CPowerManager::showSettings() {
307 if (dialog
.execute(&m_Settings
)) {
308 foreach (CBatteryIcon
* i
, m_BatteryIcons
) {
312 m_BatteryIcons
.clear();
313 m_DefaultIcon
->updateData(0, 0, 0, 0, 0, 0, false);
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);
326 m_BatteryIcons
.begin().value()->showMessage(tr("About QBat"), UI_NAME
+ "\nv" + QString(UI_VERSION
),
327 QSystemTrayIcon::Information
, 4000);
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
);