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_SysfsDir(UI_PATH_SYSFS_DIR
),
20 m_SettingsFile(UI_FILE_CONFIG
, QSettings::IniFormat
, this),
21 m_DefaultTrayIcon(QIcon(UI_ICON_QBAT
), this)
24 m_ContextMenu
.addAction(tr("&Settings"), this, SLOT(showSettings()))->setEnabled(m_SysfsDir
.exists());
25 m_ContextMenu
.addAction(tr("&About"), this, SLOT(showAbout()));
26 m_ContextMenu
.addSeparator();
27 m_ContextMenu
.addAction(tr("&Quit"), qApp
, SLOT(quit()));
29 m_DefaultTrayIcon
.setContextMenu(&m_ContextMenu
);
32 if (m_SysfsDir
.exists()) {
33 m_Timer
= startTimer(m_Settings
.pollingRate
);
37 CPowerManager::~CPowerManager() {
42 inline void CPowerManager::readSettings() {
43 m_SettingsFile
.beginGroup("Main");
44 m_Settings
.pollingRate
= m_SettingsFile
.value("pollingRate", 3000).toUInt();
45 m_SettingsFile
.endGroup();
47 m_SettingsFile
.beginGroup("TrayIcons");
48 m_Settings
.mergeBatterys
= m_SettingsFile
.value("mergeBatterys", true).toBool();
49 m_Settings
.colors
[UI_COLOR_PEN
] = m_SettingsFile
.value("textColor", 0).toUInt();
50 m_Settings
.colors
[UI_COLOR_PEN_FULL
] = m_SettingsFile
.value("textFullColor", 0).toUInt();
51 m_Settings
.colors
[UI_COLOR_BRUSH_CHARGED
] = m_SettingsFile
.value("mainChargedColor", qRgb( 0, 255, 0)).toUInt();
52 m_Settings
.colors
[UI_COLOR_BRUSH_EMPTY
] = m_SettingsFile
.value("mainEmptyColor", qRgb(255, 255, 255)).toUInt();
53 m_Settings
.colors
[UI_COLOR_BRUSH_FULL
] = m_SettingsFile
.value("mainFullColor", m_Settings
.colors
[UI_COLOR_BRUSH_CHARGED
]).toUInt();
54 m_Settings
.colors
[UI_COLOR_BRUSH_POLE
] = m_SettingsFile
.value("poleColor", qRgb(255, 255, 0)).toUInt();
55 m_Settings
.colors
[UI_COLOR_BRUSH_POLE_FULL
] = m_SettingsFile
.value("poleFullColor", m_Settings
.colors
[UI_COLOR_BRUSH_POLE
]).toUInt();
56 m_SettingsFile
.endGroup();
58 m_SettingsFile
.beginGroup("CriticalEvent");
59 m_Settings
.handleCritical
= m_SettingsFile
.value("handle", false).toBool();
60 m_Settings
.criticalCapacity
= m_SettingsFile
.value("criticalCapacity", 7).toUInt();
61 m_Settings
.executeCommand
= m_SettingsFile
.value("executeCommand", false).toBool();
62 m_Settings
.criticalCommand
= m_SettingsFile
.value("command", "").toString();
63 m_SettingsFile
.endGroup();
66 inline void CPowerManager::writeSettings() {
67 m_SettingsFile
.beginGroup("Main");
68 m_SettingsFile
.setValue("pollingRate", m_Settings
.pollingRate
);
69 m_SettingsFile
.endGroup();
71 m_SettingsFile
.beginGroup("TrayIcons");
72 m_SettingsFile
.setValue("mergeBatterys", m_Settings
.mergeBatterys
);
73 m_SettingsFile
.setValue("textColor", m_Settings
.colors
[UI_COLOR_PEN
]);
74 m_SettingsFile
.setValue("textFullColor", m_Settings
.colors
[UI_COLOR_PEN_FULL
]);
75 m_SettingsFile
.setValue("mainChargedColor", m_Settings
.colors
[UI_COLOR_BRUSH_CHARGED
]);
76 m_SettingsFile
.setValue("mainEmptyColor", m_Settings
.colors
[UI_COLOR_BRUSH_EMPTY
]);
77 m_SettingsFile
.setValue("mainFullColor", m_Settings
.colors
[UI_COLOR_BRUSH_FULL
]);
78 m_SettingsFile
.setValue("poleColor", m_Settings
.colors
[UI_COLOR_BRUSH_POLE
]);
79 m_SettingsFile
.setValue("poleFullColor", m_Settings
.colors
[UI_COLOR_BRUSH_POLE_FULL
]);
80 m_SettingsFile
.endGroup();
82 m_SettingsFile
.beginGroup("CriticalEvent");
83 m_SettingsFile
.setValue("handle", m_Settings
.handleCritical
);
84 m_SettingsFile
.setValue("criticalCapacity", m_Settings
.criticalCapacity
);
85 m_SettingsFile
.setValue("executeCommand", m_Settings
.executeCommand
);
86 m_SettingsFile
.setValue("command", m_Settings
.criticalCommand
);
87 m_SettingsFile
.endGroup();
90 void CPowerManager::timerEvent(QTimerEvent
*) {
94 void CPowerManager::updateData() {
95 if (m_SysfsDir
.exists()) {
97 QStringList powerSupplies
= m_SysfsDir
.entryList(QDir::Dirs
| QDir::NoDotAndDotDot
);
100 int chargeFullDesign
= 0;
105 int relativeCapacity
= 100;
107 if (m_Settings
.mergeBatterys
) {
108 int batteryCount
= 0;
109 foreach(QString i
, powerSupplies
) {
110 string buffer
= readStringSysFile(m_SysfsDir
.filePath(i
+ "/type").toAscii().constData());
112 if ((!acPlug
) && (buffer
== "Mains")) {
113 if (1 == readIntSysFile(m_SysfsDir
.filePath(i
+ "/online").toAscii().constData()))
116 else if (buffer
== "Battery") {
117 chargeFull
+= readIntSysFile(m_SysfsDir
.filePath(i
+ "/charge_full").toAscii().constData());
118 chargeFullDesign
+= readIntSysFile(m_SysfsDir
.filePath(i
+ "/charge_full_design").toAscii().constData());
119 chargeNow
+= readIntSysFile(m_SysfsDir
.filePath(i
+ "/charge_now").toAscii().constData());
120 currentNow
+= readIntSysFile(m_SysfsDir
.filePath(i
+ "/current_now").toAscii().constData());
122 int statusBuffer
= toStatusInt(readStringSysFile(m_SysfsDir
.filePath(i
+ "/status").toAscii().constData()));
124 if ((!status
) || (statusBuffer
!= UI_BATTERY_FULL
))
125 status
= statusBuffer
;
132 if (m_Settings
.handleCritical
)
133 relativeCapacity
= (int)(100.0 * chargeNow
/ chargeFull
);
135 chargeFull
/= batteryCount
;
136 chargeFullDesign
/= batteryCount
;
137 chargeNow
/= batteryCount
;
138 currentNow
/= batteryCount
;
140 if (!m_BatteryIcons
.contains("merged")) {
141 if (!m_BatteryIcons
.isEmpty()) {
142 foreach(CBatteryIcon
* i
, m_BatteryIcons
) {
146 m_BatteryIcons
.clear();
149 CBatteryIcon
* currentBatteryIcon
= new CBatteryIcon("average", &m_Settings
, &m_ContextMenu
, this);
150 currentBatteryIcon
->updateData(chargeFull
, chargeFullDesign
, chargeNow
, currentNow
, status
);
151 m_BatteryIcons
.insert("merged", currentBatteryIcon
);
154 m_BatteryIcons
["merged"]->updateData(chargeFull
, chargeFullDesign
, chargeNow
, currentNow
, status
);
157 delete m_BatteryIcons
.take("merged");
161 QList
<CBatteryIcon
*> newBatteryIcons
;
162 CBatteryIcon
* currentBatteryIcon
;
164 int chargeNowMid
= 0;
165 int chargeFullMid
= 0;
167 foreach(QString i
, powerSupplies
) {
168 string buffer
= readStringSysFile(m_SysfsDir
.filePath(i
+ "/type").toAscii().constData());
170 if (buffer
== "Mains") {
171 if (1 == readIntSysFile(m_SysfsDir
.filePath(i
+ "/online").toAscii().constData()))
174 else if (buffer
== "Battery") {
175 chargeFull
= readIntSysFile(m_SysfsDir
.filePath(i
+ "/charge_full").toAscii().constData());
176 chargeFullDesign
= readIntSysFile(m_SysfsDir
.filePath(i
+ "/charge_full_design").toAscii().constData());
177 chargeNow
= readIntSysFile(m_SysfsDir
.filePath(i
+ "/charge_now").toAscii().constData());
178 currentNow
= readIntSysFile(m_SysfsDir
.filePath(i
+ "/current_now").toAscii().constData());
179 status
= toStatusInt(readStringSysFile(m_SysfsDir
.filePath(i
+ "/status").toAscii().constData()));
181 chargeFullMid
+= chargeFull
;
182 chargeNowMid
+= chargeNow
;
184 if (!m_BatteryIcons
.contains(i
)) {
185 currentBatteryIcon
= new CBatteryIcon(i
, &m_Settings
, &m_ContextMenu
, this);
186 currentBatteryIcon
->updateData(chargeFull
, chargeFullDesign
, chargeNow
, currentNow
, status
);
189 currentBatteryIcon
= m_BatteryIcons
.take(i
);
190 currentBatteryIcon
->updateData(chargeFull
, chargeFullDesign
, chargeNow
, currentNow
, status
);
192 newBatteryIcons
<< currentBatteryIcon
;
196 foreach(CBatteryIcon
* i
, m_BatteryIcons
) {
200 m_BatteryIcons
.clear();
202 foreach(CBatteryIcon
* i
, newBatteryIcons
)
203 m_BatteryIcons
.insert(i
->batteryName(), i
);
205 if (!m_BatteryIcons
.isEmpty())
206 relativeCapacity
= (int)(100.0 * chargeNowMid
/ chargeFullMid
);
211 m_DefaultTrayIcon
.setToolTip("QBat - " + tr("AC adapter plugged in"));
213 if ((m_Settings
.handleCritical
) && (relativeCapacity
<= m_Settings
.criticalCapacity
)) {
214 if (m_Settings
.executeCommand
)
215 QProcess::startDetached(m_Settings
.criticalCommand
);
217 QMessageBox::warning(NULL
, tr("QBat - critical battery capacity"),
218 tr("WARNING: The attached battery(s) reached the critical mark.\n\
219 Please make sure to save and shut down soon or provide another source of power."));
221 m_DefaultTrayIcon
.setToolTip("QBat - " + tr("AC adapter unplugged"));
225 m_DefaultTrayIcon
.setToolTip("QBat - " + tr("no information available"));
227 m_DefaultTrayIcon
.setVisible(m_BatteryIcons
.isEmpty());
230 void CPowerManager::restartTimer() {
232 m_Timer
= startTimer(m_Settings
.pollingRate
);
235 void CPowerManager::showSettings() {
237 connect(&dialog
, SIGNAL(settingsChanged()), this, SLOT(updateData()));
238 connect(&dialog
, SIGNAL(settingsChanged()), this, SLOT(restartTimer()));
240 dialog
.execute(&m_Settings
);
243 void CPowerManager::showAbout() {
244 QMessageBox aboutBox
;
246 aboutBox
.setWindowIcon(QIcon(UI_ICON_QBAT
));
247 aboutBox
.setIconPixmap(QPixmap(UI_ICON_QBAT
));
248 aboutBox
.setWindowTitle(tr("About QBat"));
249 aboutBox
.setText(UI_NAME
+ "\nv" + QString(UI_VERSION
));
250 aboutBox
.setStandardButtons(QMessageBox::Ok
);