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
);
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
)
111 else if (event
->timerId() == m_DataTimer
)
115 void CPowerManager::updateSupplies() {
116 if (CBatteryIcon::sysfsDir
.exists()) {
117 bool oldAC
= m_ACPlug
;
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) {
130 m_CriticalHandled
= false;
134 if (m_BatteryIcons
.contains(i
)) {
135 currentBatteryIcon
= m_BatteryIcons
.take(i
);
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
)
157 m_BatteryIcons
.clear();
159 foreach(CBatteryIcon
* i
, newBatteryIcons
)
160 m_BatteryIcons
.insert(i
->data().name
, i
);
162 if (oldAC
!= m_ACPlug
)
167 if (m_BatteryIcons
.isEmpty()) {
168 if (!m_DefaultIcon
->isVisible()) {
169 m_DefaultIcon
->setVisible(true);
170 m_DefaultIcon
->setIcon(QIcon(UI_ICON_QBAT_SMALL
));
173 m_DefaultIcon
->setMessage(tr("AC adapter plugged in"));
175 m_DefaultIcon
->setMessage(tr("AC adapter unplugged"));
179 if (!m_DefaultIcon
->isVisible()) {
180 m_DefaultIcon
->updateData();
181 m_DefaultIcon
->updateIcon();
183 m_DefaultIcon
->setVisible(m_Settings
.mergeBatteries
);
189 m_DefaultIcon
->setMessage(tr("no information available"));
190 m_DefaultIcon
->setVisible(true);
195 void CPowerManager::updateMergedData() {
196 if (!m_BatteryIcons
.isEmpty()) {
199 int voltageCount
= 0;
201 int fullCapacity
= 0;
202 int currentCapacity
= 0;
207 foreach (CBatteryIcon
* battery
, m_BatteryIcons
) {
208 if (battery
->data().voltage
) {
209 voltage
+= battery
->data().voltage
;
213 if (!battery
->data().energyUnits
) {
214 currentCapacity
+= battery
->data().currentCapacity
;
216 if (battery
->data().fullCapacity
) {
217 fullCapacity
+= battery
->data().fullCapacity
;
221 if (battery
->data().rate
) {
222 rate
+= battery
->data().rate
;
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
);
235 if (battery
->data().rate
) {
236 rate
+= qRound(battery
->data().rate
/ voltageNorm
);
241 if ((!status
) || (battery
->data().status
!= UI_BATTERY_FULL
))
242 status
= battery
->data().status
;
246 fullCapacity
/= fullCount
;
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
)
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"
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
);
280 if (m_Settings
.showBalloon
)
281 m_BatteryIcons
.begin().value()->showMessage(msgTitle
, msgText
, QSystemTrayIcon::Warning
, 7000);
283 QMessageBox::warning(NULL
, msgTitle
, msgText
);
285 m_CriticalHandled
= true;
288 void CPowerManager::updateBatteryData() {
289 foreach (CBatteryIcon
* battery
, m_BatteryIcons
)
290 battery
->updateData();
296 void CPowerManager::restartTimer() {
298 m_Timer
= startTimer(m_Settings
.pollingRate
);
299 killTimer(m_DataTimer
);
300 m_DataTimer
= startTimer(15000);
303 void CPowerManager::showSettings() {
306 if (dialog
.execute(&m_Settings
)) {
307 foreach (CBatteryIcon
* i
, m_BatteryIcons
) {
311 m_BatteryIcons
.clear();
312 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
);