2 // C++ Implementation: cpowermanager
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"
17 CPowerManager::CPowerManager(QObject
* parent
) :
19 m_CriticalHandled(false),
20 m_SysfsDir(UI_PATH_SYSFS_DIR
),
21 m_SettingsFile(UI_FILE_CONFIG
, QSettings::IniFormat
, this),
22 m_DefaultTrayIcon(QIcon(UI_ICON_QBAT
), this)
25 m_ContextMenu
.addAction(tr("&Settings"), this, SLOT(showSettings()))->setEnabled(m_SysfsDir
.exists());
26 m_ContextMenu
.addAction(tr("&About"), this, SLOT(showAbout()));
27 m_ContextMenu
.addSeparator();
28 m_ContextMenu
.addAction(tr("&Quit"), qApp
, SLOT(quit()));
30 m_DefaultTrayIcon
.setContextMenu(&m_ContextMenu
);
33 if (m_SysfsDir
.exists()) {
34 m_Timer
= startTimer(m_Settings
.pollingRate
);
38 CPowerManager::~CPowerManager() {
43 inline void CPowerManager::readSettings() {
44 m_SettingsFile
.beginGroup("Main");
45 m_Settings
.pollingRate
= m_SettingsFile
.value("pollingRate", 3000).toUInt();
46 m_SettingsFile
.endGroup();
48 m_SettingsFile
.beginGroup("TrayIcons");
49 m_Settings
.mergeBatterys
= m_SettingsFile
.value("mergeBatterys", true).toBool();
50 m_Settings
.colors
[UI_COLOR_PEN
] = m_SettingsFile
.value("textColor", 0).toUInt();
51 m_Settings
.colors
[UI_COLOR_PEN_FULL
] = m_SettingsFile
.value("textFullColor", 0).toUInt();
52 m_Settings
.colors
[UI_COLOR_BRUSH_CHARGED
] = m_SettingsFile
.value("mainChargedColor", qRgb( 0, 255, 0)).toUInt();
53 m_Settings
.colors
[UI_COLOR_BRUSH_EMPTY
] = m_SettingsFile
.value("mainEmptyColor", qRgb(255, 255, 255)).toUInt();
54 m_Settings
.colors
[UI_COLOR_BRUSH_FULL
] = m_SettingsFile
.value("mainFullColor", m_Settings
.colors
[UI_COLOR_BRUSH_CHARGED
]).toUInt();
55 m_Settings
.colors
[UI_COLOR_BRUSH_POLE
] = m_SettingsFile
.value("poleColor", qRgb(255, 255, 0)).toUInt();
56 m_Settings
.colors
[UI_COLOR_BRUSH_POLE_FULL
] = m_SettingsFile
.value("poleFullColor", m_Settings
.colors
[UI_COLOR_BRUSH_POLE
]).toUInt();
57 m_SettingsFile
.endGroup();
59 m_SettingsFile
.beginGroup("CriticalEvent");
60 m_Settings
.handleCritical
= m_SettingsFile
.value("handle", false).toBool();
61 m_Settings
.criticalCapacity
= m_SettingsFile
.value("criticalCapacity", 7).toUInt();
62 m_Settings
.executeCommand
= m_SettingsFile
.value("executeCommand", false).toBool();
63 m_Settings
.criticalCommand
= m_SettingsFile
.value("command", "").toString();
64 m_SettingsFile
.endGroup();
67 inline void CPowerManager::writeSettings() {
68 m_SettingsFile
.beginGroup("Main");
69 m_SettingsFile
.setValue("pollingRate", m_Settings
.pollingRate
);
70 m_SettingsFile
.endGroup();
72 m_SettingsFile
.beginGroup("TrayIcons");
73 m_SettingsFile
.setValue("mergeBatterys", m_Settings
.mergeBatterys
);
74 m_SettingsFile
.setValue("textColor", m_Settings
.colors
[UI_COLOR_PEN
]);
75 m_SettingsFile
.setValue("textFullColor", m_Settings
.colors
[UI_COLOR_PEN_FULL
]);
76 m_SettingsFile
.setValue("mainChargedColor", m_Settings
.colors
[UI_COLOR_BRUSH_CHARGED
]);
77 m_SettingsFile
.setValue("mainEmptyColor", m_Settings
.colors
[UI_COLOR_BRUSH_EMPTY
]);
78 m_SettingsFile
.setValue("mainFullColor", m_Settings
.colors
[UI_COLOR_BRUSH_FULL
]);
79 m_SettingsFile
.setValue("poleColor", m_Settings
.colors
[UI_COLOR_BRUSH_POLE
]);
80 m_SettingsFile
.setValue("poleFullColor", m_Settings
.colors
[UI_COLOR_BRUSH_POLE_FULL
]);
81 m_SettingsFile
.endGroup();
83 m_SettingsFile
.beginGroup("CriticalEvent");
84 m_SettingsFile
.setValue("handle", m_Settings
.handleCritical
);
85 m_SettingsFile
.setValue("criticalCapacity", m_Settings
.criticalCapacity
);
86 m_SettingsFile
.setValue("executeCommand", m_Settings
.executeCommand
);
87 m_SettingsFile
.setValue("command", m_Settings
.criticalCommand
);
88 m_SettingsFile
.endGroup();
91 void CPowerManager::timerEvent(QTimerEvent
*) {
95 void CPowerManager::updateData() {
96 if (m_SysfsDir
.exists()) {
98 QStringList powerSupplies
= m_SysfsDir
.entryList(QDir::Dirs
| QDir::NoDotAndDotDot
);
101 int chargeFullDesign
= 0;
106 int relativeCapacity
= 100;
108 if (m_Settings
.mergeBatterys
) {
109 int batteryCount
= 0;
110 foreach(QString i
, powerSupplies
) {
111 string buffer
= readStringSysFile(m_SysfsDir
.filePath(i
+ "/type").toAscii().constData());
113 if ((!acPlug
) && (buffer
== "Mains")) {
114 if (1 == readIntSysFile(m_SysfsDir
.filePath(i
+ "/online").toAscii().constData()))
117 else if (buffer
== "Battery") {
118 chargeFull
+= readIntSysFile(m_SysfsDir
.filePath(i
+ "/charge_full").toAscii().constData());
119 chargeFullDesign
+= readIntSysFile(m_SysfsDir
.filePath(i
+ "/charge_full_design").toAscii().constData());
120 chargeNow
+= readIntSysFile(m_SysfsDir
.filePath(i
+ "/charge_now").toAscii().constData());
121 currentNow
+= readIntSysFile(m_SysfsDir
.filePath(i
+ "/current_now").toAscii().constData());
123 int statusBuffer
= toStatusInt(readStringSysFile(m_SysfsDir
.filePath(i
+ "/status").toAscii().constData()));
125 if ((!status
) || (statusBuffer
!= UI_BATTERY_FULL
))
126 status
= statusBuffer
;
133 if (m_Settings
.handleCritical
)
134 relativeCapacity
= (int)(100.0 * chargeNow
/ chargeFull
);
136 chargeFull
/= batteryCount
;
137 chargeFullDesign
/= batteryCount
;
138 chargeNow
/= batteryCount
;
139 currentNow
/= batteryCount
;
141 if (!m_BatteryIcons
.contains("merged")) {
142 if (!m_BatteryIcons
.isEmpty()) {
143 foreach(CBatteryIcon
* i
, m_BatteryIcons
) {
147 m_BatteryIcons
.clear();
150 CBatteryIcon
* currentBatteryIcon
= new CBatteryIcon("average", &m_Settings
, &m_ContextMenu
, this);
151 currentBatteryIcon
->updateData(chargeFull
, chargeFullDesign
, chargeNow
, currentNow
, status
);
152 m_BatteryIcons
.insert("merged", currentBatteryIcon
);
155 m_BatteryIcons
["merged"]->updateData(chargeFull
, chargeFullDesign
, chargeNow
, currentNow
, status
);
158 delete m_BatteryIcons
.take("merged");
162 QList
<CBatteryIcon
*> newBatteryIcons
;
163 CBatteryIcon
* currentBatteryIcon
;
165 int chargeNowMid
= 0;
166 int chargeFullMid
= 0;
168 foreach(QString i
, powerSupplies
) {
169 string buffer
= readStringSysFile(m_SysfsDir
.filePath(i
+ "/type").toAscii().constData());
171 if (buffer
== "Mains") {
172 if (1 == readIntSysFile(m_SysfsDir
.filePath(i
+ "/online").toAscii().constData()))
175 else if (buffer
== "Battery") {
176 chargeFull
= readIntSysFile(m_SysfsDir
.filePath(i
+ "/charge_full").toAscii().constData());
177 chargeFullDesign
= readIntSysFile(m_SysfsDir
.filePath(i
+ "/charge_full_design").toAscii().constData());
178 chargeNow
= readIntSysFile(m_SysfsDir
.filePath(i
+ "/charge_now").toAscii().constData());
179 currentNow
= readIntSysFile(m_SysfsDir
.filePath(i
+ "/current_now").toAscii().constData());
180 status
= toStatusInt(readStringSysFile(m_SysfsDir
.filePath(i
+ "/status").toAscii().constData()));
182 chargeFullMid
+= chargeFull
;
183 chargeNowMid
+= chargeNow
;
185 if (!m_BatteryIcons
.contains(i
)) {
186 currentBatteryIcon
= new CBatteryIcon(i
, &m_Settings
, &m_ContextMenu
, this);
187 currentBatteryIcon
->updateData(chargeFull
, chargeFullDesign
, chargeNow
, currentNow
, status
);
190 currentBatteryIcon
= m_BatteryIcons
.take(i
);
191 currentBatteryIcon
->updateData(chargeFull
, chargeFullDesign
, chargeNow
, currentNow
, status
);
193 newBatteryIcons
<< currentBatteryIcon
;
197 foreach(CBatteryIcon
* i
, m_BatteryIcons
) {
201 m_BatteryIcons
.clear();
203 foreach(CBatteryIcon
* i
, newBatteryIcons
)
204 m_BatteryIcons
.insert(i
->batteryName(), i
);
206 if (!m_BatteryIcons
.isEmpty())
207 relativeCapacity
= (int)(100.0 * chargeNowMid
/ chargeFullMid
);
212 m_DefaultTrayIcon
.setToolTip("QBat - " + tr("AC adapter plugged in"));
214 if ((m_Settings
.handleCritical
) && (relativeCapacity
<= m_Settings
.criticalCapacity
) && (!m_CriticalHandled
)) {
215 if (m_Settings
.executeCommand
)
216 QProcess::startDetached(m_Settings
.criticalCommand
);
218 QMessageBox::warning(NULL
, tr("QBat - critical battery capacity"),
219 tr("WARNING: The attached battery(s) reached the critical mark.\n\
220 Please make sure to save and shut down soon or provide another source of power."));
221 m_CriticalHandled
= true;
223 m_DefaultTrayIcon
.setToolTip("QBat - " + tr("AC adapter unplugged"));
227 m_DefaultTrayIcon
.setToolTip("QBat - " + tr("no information available"));
229 m_DefaultTrayIcon
.setVisible(m_BatteryIcons
.isEmpty());
232 void CPowerManager::restartTimer() {
234 m_Timer
= startTimer(m_Settings
.pollingRate
);
237 void CPowerManager::showSettings() {
239 connect(&dialog
, SIGNAL(settingsChanged()), this, SLOT(updateData()));
240 connect(&dialog
, SIGNAL(settingsChanged()), this, SLOT(restartTimer()));
242 dialog
.execute(&m_Settings
);
245 void CPowerManager::showAbout() {
246 QMessageBox aboutBox
;
248 aboutBox
.setWindowIcon(QIcon(UI_ICON_QBAT
));
249 aboutBox
.setIconPixmap(QPixmap(UI_ICON_QBAT
));
250 aboutBox
.setWindowTitle(tr("About QBat"));
251 aboutBox
.setText(UI_NAME
+ "\nv" + QString(UI_VERSION
));
252 aboutBox
.setStandardButtons(QMessageBox::Ok
);