From 6c3af988afab7f46c91cad67c1c8ecac381bac53 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Oliver=20Gro=C3=9F?= Date: Tue, 8 Jan 2008 11:16:32 +0100 Subject: [PATCH] Initial commit --- .gitignore | 6 + batteryicon.cpp | 105 ++++++++++ batteryicon.h | 29 +++ common.cpp | 37 ++++ common.h | 19 ++ constants.h | 16 ++ main.cpp | 28 +++ powermanager.cpp | 81 ++++++++ powermanager.h | 32 +++ qbat.desktop | 11 ++ qbat.pro | 38 ++++ res/qbat.png | Bin 0 -> 2228 bytes res/qbat.svg | 590 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 992 insertions(+) create mode 100644 .gitignore create mode 100644 batteryicon.cpp create mode 100644 batteryicon.h create mode 100644 common.cpp create mode 100644 common.h create mode 100644 constants.h create mode 100644 main.cpp create mode 100644 powermanager.cpp create mode 100644 powermanager.h create mode 100644 qbat.desktop create mode 100644 qbat.pro create mode 100644 res/qbat.png create mode 100644 res/qbat.svg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..686e877 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +build + +qbat.kdevelop +qbat.kdevses +Doxyfile +qbat.kdevelop.pcs diff --git a/batteryicon.cpp b/batteryicon.cpp new file mode 100644 index 0000000..f6daa58 --- /dev/null +++ b/batteryicon.cpp @@ -0,0 +1,105 @@ +// +// C++ Implementation: batteryicon +// +// Author: Oliver Groß , (C) 2008 +// +// Copyright: See COPYING file that comes with this distribution +// +#include "batteryicon.h" +#include "common.h" +#include +#include +#include + +namespace qbat { + using namespace std; + + CBatteryIcon::CBatteryIcon(QString batteryName, QMenu * contextMenu, QObject * parent) : + QSystemTrayIcon(parent), + m_BatteryName(batteryName), + m_Icon(32, 32) + { + m_Icon.fill(Qt::transparent); + setContextMenu(contextMenu); + updateData(); + show(); + } + + CBatteryIcon::~CBatteryIcon() { + } + + void CBatteryIcon::updateData() { + QDir workDir(UI_PATH_SYSFS_DIR + ('/' + m_BatteryName)); + int chargeFull = readIntSysFile(workDir.filePath("charge_full").toAscii().constData()); + int chargeFullDesign = readIntSysFile(workDir.filePath("charge_full_design").toAscii().constData()); + int chargeNow = readIntSysFile(workDir.filePath("charge_now").toAscii().constData()); + int currentNow = readIntSysFile(workDir.filePath("current_now").toAscii().constData()); + string status = readStringSysFile(workDir.filePath("status").toAscii().constData()); + + QString newToolTip = tr("QBat - %1: %2%").arg(m_BatteryName) +'\n'; + if (chargeFull) + newToolTip = newToolTip.arg((int)(100.0 * chargeNow / chargeFull)); + else + newToolTip = newToolTip.arg('-'); + + if (status == "Discharging") { + newToolTip += tr("status: %1").arg(tr("dischaging")); + if (currentNow) { + newToolTip += '\n'; + qreal remainingTime = (qreal)chargeNow / (qreal)currentNow; + int remainingHours = (int)remainingTime; + int remainungMinutes = (int)(remainingTime * 60) % 60; + newToolTip += tr("remaining time: %1:%2").arg(remainingHours, 2, QChar('0')).arg(remainungMinutes, 2, QChar('0')); + } + } + else if (status == "Charging") + newToolTip += tr("status: %1").arg(tr("charging")); + else if (status == "Full") + newToolTip += tr("status: %1").arg(tr("full")); + else + newToolTip += tr("status: %1").arg(tr("unknown")); + + newToolTip += '\n'; + + if (status != "Full") + newToolTip += tr("current rate: %1A").arg(qRound(currentNow / 100000.0) / 10.0) + '\n'; + + newToolTip += tr("current capacity: %2mAh").arg(chargeNow / 1000) + '\n'; + + if (status != "Full") + newToolTip += tr("last full capacity: %3mAh").arg(chargeFull / 1000) + '\n'; + newToolTip += tr("design capacity: %4mAh").arg(chargeFullDesign / 1000); + + setToolTip(newToolTip); + QPainter painter(&m_Icon); + + + if (chargeNow != chargeFull) { + painter.setPen(Qt::black); + painter.setBrush(Qt::white); + painter.drawRect(0, 0, 31, 31); + + painter.setPen(Qt::NoPen); + painter.setBrush(Qt::green); + painter.drawRect(1, 1 + 30 - (int)(30.0 * chargeNow / chargeFull), 30, (int)(30.0 * chargeNow / chargeFull)); + + painter.setPen(Qt::black); + painter.setBrush(Qt::yellow); + painter.drawRect(23, 0, 8, 8); + } + else { + painter.setPen(Qt::black); + painter.setBrush(Qt::green); + painter.drawRect(0, 0, 31, 31); + + painter.setBrush(Qt::blue); + painter.drawRect(23, 0, 8, 8); + } + + painter.setBrush(Qt::NoBrush); + painter.font().setPixelSize(16); + painter.drawText(1, 12, 30, 16, Qt::AlignHCenter, QString::number((int)(100.0 * chargeNow / chargeFull))); + + setIcon(m_Icon); + } +} diff --git a/batteryicon.h b/batteryicon.h new file mode 100644 index 0000000..2953cc3 --- /dev/null +++ b/batteryicon.h @@ -0,0 +1,29 @@ +// +// C++ Interface: batteryicon +// +// Author: Oliver Groß , (C) 2008 +// +// Copyright: See COPYING file that comes with this distribution +// +#ifndef QBAT_BATTERYICON_H +#define QBAT_BATTERYICON_H + +#include + +namespace qbat { + class CBatteryIcon : public QSystemTrayIcon { + Q_OBJECT + private: + QString m_BatteryName; + QPixmap m_Icon; + public: + CBatteryIcon(QString batteryName, QMenu * contextMenu, QObject * parent = 0); + ~CBatteryIcon(); + + QString batteryName() const { return m_BatteryName; } + + void updateData(); + }; +} + +#endif diff --git a/common.cpp b/common.cpp new file mode 100644 index 0000000..291c6c2 --- /dev/null +++ b/common.cpp @@ -0,0 +1,37 @@ +// +// C++ Implementation: common +// +// Author: Oliver Groß , (C) 2008 +// +// Copyright: See COPYING file that comes with this distribution +// +#include +#include "common.h" + +namespace qbat { + using namespace std; + + string readStringSysFile(const char * fileName) { + ifstream inFile; + string buffer; + + inFile.open(fileName); + inFile >> buffer; + //getLine(inFile, buffer); + inFile.close(); + + return buffer; + } + + int readIntSysFile(const char * fileName) { + ifstream inFile; + int buffer; + + inFile.open(fileName); + inFile >> buffer; + //getLine(inFile, buffer); + inFile.close(); + + return buffer; + } +} diff --git a/common.h b/common.h new file mode 100644 index 0000000..6a39ed3 --- /dev/null +++ b/common.h @@ -0,0 +1,19 @@ +// +// C++ Interface: common +// +// Author: Oliver Groß , (C) 2008 +// +// Copyright: See COPYING file that comes with this distribution +// +#ifndef QBAT_COMMON_H +#define QBAT_COMMON_H + +#include +#include "constants.h" + +namespace qbat { + std::string readStringSysFile(const char * fileName); + int readIntSysFile(const char * fileName); +} + +#endif diff --git a/constants.h b/constants.h new file mode 100644 index 0000000..8d9e416 --- /dev/null +++ b/constants.h @@ -0,0 +1,16 @@ +#ifndef QBAT_CONSTANTS_H +#define QBAT_CONSTANTS_H + +#define UI_VERSION "0.0.1" +#define UI_NAME tr("QBat - Qt Battery Monitor") + +#define UI_DIR_WORK ".qbat/" + +#define UI_PATH_SYSFS_DIR "/sys/class/power_supply" +#define UI_PATH_TRANSLATIONS "/usr/share/qbat/lang/" +#define UI_PATH_ICONS "/usr/share/qbat/icons/" +#define UI_PATH_WORK (QDir::toNativeSeparators(QDir::homePath()) + "/" UI_DIR_WORK) + +#define UI_ICON_QBAT UI_PATH_ICONS "qbat.svg" + +#endif diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..e1e4bb6 --- /dev/null +++ b/main.cpp @@ -0,0 +1,28 @@ +#include +#include +#include "powermanager.h" +#include "constants.h" + +using namespace qbat; + +int main(int argc, char * argv[]) +{ + QApplication app(argc, argv); + + QString locale = QLocale::system().name(); + QTranslator translator; + translator.load(QString(UI_PATH_TRANSLATIONS "qbat_") + locale); + app.installTranslator(&translator); + app.setQuitOnLastWindowClosed(false); + +// { +// QDir workdir(UI_PATH_WORK); +// if (!workdir.exists()) { +// workdir.cdUp(); +// workdir.mkdir(UI_DIR_WORK); +// } +// } + + CPowerManager mainobject; + return app.exec(); +} diff --git a/powermanager.cpp b/powermanager.cpp new file mode 100644 index 0000000..c9a8b8f --- /dev/null +++ b/powermanager.cpp @@ -0,0 +1,81 @@ +// +// C++ Implementation: cpowermanager +// +// Author: Oliver Groß , (C) 2008 +// +// Copyright: See COPYING file that comes with this distribution +// +#include +#include "powermanager.h" +#include "common.h" + +namespace qbat { + using namespace std; + + CPowerManager::CPowerManager(QObject * parent) : + QObject(parent), + m_SysfsDir(UI_PATH_SYSFS_DIR), + m_DefaultTrayIcon(QIcon(UI_ICON_QBAT), this) + { + m_ContextMenu.addAction(tr("&Settings"))->setEnabled(false); + m_ContextMenu.addSeparator(); + m_ContextMenu.addAction(tr("&Quit"), qApp, SLOT(quit())); + + m_DefaultTrayIcon.setContextMenu(&m_ContextMenu); + + timerEvent(NULL); + if (m_SysfsDir.exists()) { + m_Timer = startTimer(3000); + } + } + + CPowerManager::~CPowerManager() { + killTimer(m_Timer); + } + + void CPowerManager::timerEvent(QTimerEvent *) { + if (m_SysfsDir.exists()) { + bool acPlug = false; + QStringList powerSupplies = m_SysfsDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + + QList newBatteryIcons; + CBatteryIcon * currentBatteryIcon; + + foreach(QString i, powerSupplies) { + string buffer = readStringSysFile(m_SysfsDir.filePath(i + "/type").toAscii().constData()); + + if (buffer == "Mains") { + if (1 == readIntSysFile(m_SysfsDir.filePath(i + "/online").toAscii().constData())) + acPlug = true; + } + else if (buffer == "Battery") { + if (!m_BatteryIcons.contains(i)) + currentBatteryIcon = new CBatteryIcon(i, &m_ContextMenu, this); + else { + currentBatteryIcon = m_BatteryIcons.take(i); + currentBatteryIcon->updateData(); + } + newBatteryIcons << currentBatteryIcon; + } + } + + foreach(CBatteryIcon * i, m_BatteryIcons) { + delete i; + } + + m_BatteryIcons.clear(); + + foreach(CBatteryIcon * i, newBatteryIcons) + m_BatteryIcons.insert(i->batteryName(), i); + + if (acPlug) + m_DefaultTrayIcon.setToolTip("QBat - " + tr("AC adapter plugged in")); + else + m_DefaultTrayIcon.setToolTip("QBat - " + tr("AC adapter unplugged")); + } + else + m_DefaultTrayIcon.setToolTip("QBat - " + tr("no information available")); + + m_DefaultTrayIcon.setVisible(m_BatteryIcons.isEmpty()); + } +} diff --git a/powermanager.h b/powermanager.h new file mode 100644 index 0000000..85d2bcf --- /dev/null +++ b/powermanager.h @@ -0,0 +1,32 @@ +// +// C++ Interface: cpowermanager +// +// Author: Oliver Groß , (C) 2008 +// +// Copyright: See COPYING file that comes with this distribution +// +#ifndef QBAT_POWERMANAGER_H +#define QBAT_POWERMANAGER_H + +#include +#include +#include +#include "batteryicon.h" + +namespace qbat { + class CPowerManager : public QObject { + Q_OBJECT + private: + void timerEvent(QTimerEvent * event); + int m_Timer; + QDir m_SysfsDir; + QMenu m_ContextMenu; + QHash m_BatteryIcons; + QSystemTrayIcon m_DefaultTrayIcon; + public: + CPowerManager(QObject * parent = 0); + ~CPowerManager(); + }; +} + +#endif diff --git a/qbat.desktop b/qbat.desktop new file mode 100644 index 0000000..e97f012 --- /dev/null +++ b/qbat.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Categories=System; +DocPath= +Encoding=UTF-8 +Exec=qbat +GenericName=Qt Battery Monitor +Icon=/usr/share/qbat/icons/qbat.png +MimeType=inode/directory +Name=QBat +Terminal=false +Type=Application diff --git a/qbat.pro b/qbat.pro new file mode 100644 index 0000000..dbad0a2 --- /dev/null +++ b/qbat.pro @@ -0,0 +1,38 @@ + +TEMPLATE = app +CONFIG += qt qdbus + +CODECFORSRC = UTF-8 +CODECFORTR = ISO-8859-1 + +OBJECTS_DIR = build/ +MOC_DIR = build/ +UI_DIR = ui/ + + +#FORMS = +#TRANSLATIONS = qbat_de.ts + +#HEADERS += +SOURCES += main.cpp \ + batteryicon.cpp \ + powermanager.cpp \ + common.cpp +DESTDIR = . + +target.path = /usr/bin +iconstarget.path = /usr/share/qbat/icons +iconstarget.files = res/*.png res/qbat.svg +langtarget.path = /usr/share/qbat/lang +langtarget.files = qbat_*.qm +shortcuttarget.path = /usr/share/applications +shortcuttarget.files = qbat.desktop + +INSTALLS += target iconstarget langtarget shortcuttarget + +HEADERS += constants.h \ +batteryicon.h \ +common.h \ +powermanager.h +TARGET = qbat + diff --git a/res/qbat.png b/res/qbat.png new file mode 100644 index 0000000000000000000000000000000000000000..609890c13e669a402e2a2fba3daea1894afe1eae GIT binary patch literal 2228 zcwPat2ut^gP)q`?~&UyH7?9}NsU7c)uq(`s)zQ@P^|NGqDi>NA}Wbv)$pFQ>kdBQaKn<~LO zJtOePqkrK!KvmVf*E?60fNAigD#6ci~>pSfpJv{+=nDu8ic!( z?z#)f4tX9Swb;=y>j@uYwgEre4=B{@P;Yo`qYkHL;YuACB8v|n5lli{k{#0NLa%a| z)7na(((N=VJLDAbP*-2tDcAWL$2bVg1C8znu>iw9_;wg-KwV)$p$^nK+FJX2$LCt- zGb|mex^UfrIW_@TfwRE$%48uEu*GZ57Ad3EwjD}4)NQHLR`q^obo{O@*Lea60B-<= zk82R$Ssc~^gFp}9`{WVuY|^&R$2N`LO{7!rD+WZw*s+5z8V272ULPOlRlPNh-LqJA zQNtGeFqm{*8o+<> zvi7RVq6NmrWO!^$ej>sQaBgf&o)Zy6MC8pk`Kt(1hYsOd7FZUHjv}T>B$MH@c$N1f zv4R1xbEmwBw|xEH&=9e37**wm+{m{^qruD5(-@PJ9)X7+2FpS-8Md?tr18?*>Jt#* z*;ovD;RV>e8`-`cLxfG44Br8^0+C{oS460dk9!1c8@6sm!eLVJI9q^qK;$DK;JUn0 zDuLrbAOPF9gJGb3ee43Z0jZNGnQJuo)3IY{rQ(rzh z_%M@>!y8ABqK@N%d-PENB%9?kcs}0y&O01)UEUiXM-Ah~b0T77v$4qFUa1b&XNT=Conmhz#0AHiQFRE4K{r90#@p0lr zf=idy0qI;I5ZDll#jtG~`Ve^^)umG|!LXV0D-2M+Y&_lH@tW(|XbgVNjEODq-xh1hEWIPSol%Sy$@B7t(5 zW~0Hrd>)yY@T{zzi9|5eAUYX>3ocYy5i2ZNN}M>s)yE&_wd2QS_rZf< z4jt;@gAam;2&q)k?CR6^vp#m{qH*DT(G*InU)Y3 z8XC&x^L0nW$4f66SXO|cp#d_P3_hQ45p;XTZwI_{EE0*}TyqGX_p>nLLQKKm-PMK< zV0d^qt*XBSzU;aIBbiLHZrwWi`ucEPcM0%LfHwobc`O_bbM4wSdh$^gE)*am(7OTz zfMzN*DoSOqfsxVUJS!@_k-C0ID7W&Dd6vulap?<*}N}+_Zsv2{fG#`ss%GH z6kKR_nE-(6y89f*G0vSk_rTygtyQg7QB}%;3KSJ)TL)cTvce*P$;rvrRdxFG>C?I# zmsyTGxvopGSfpmwDf_D)@KWpKtxM7wP7T*}e^seeB%jZJXqV~yUMLh$Rj$}`-alCa zVY+&xyrdGV>dPWhKXc~Heb4&MW3^h1QmI7Qs<2?zyu-k>z^4odN!JcvmL#;Psi{kj zNw8N0VXCUK6D(EN+ss! z=b5vMIHuzr^bVMiGa%f(*}sJV!1?p%{{j4SVq!u&tM78-0AOZjhKAYXTBz*#ds1M7 z0SW2)w*PkFq|Ih?FYxRA`}dPdrAVbxB$G*^(da!ZaXz1?*=%wpK8G3#5rOpv477Z| zi#6c31XNW;cX8?POWOtGy4Jd)h!9U{Og{# zlr17=i%bZwmPT5H`a1|k@NNz-08=gCO}aPxZE;)gybKiY>zY;CdGZD!n;V2|yaSX1 zP~-;imDtTI;Hs+oK=;Hq5i(mZZqizrJTS~<$o~On4RZ6y+XpxR0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 2.11.4.GIT