/* * battery.cpp * * Copyright (c) 1999 Paul Campbell <paul@taniwha.com> * Copyright (c) 2002 Marc Mutz <mutz@kde.org> * Copyright (c) 2006 Flavio Castelli <flavio.castelli@gmail.com> * * Requires the TQt widget libraries, available at no cost at * http://www.troll.no/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // my headers: #include "battery.h" #include "version.h" #include "portable.h" // other KDE headers: #include <tdelocale.h> #include <tdeconfig.h> #include <knuminput.h> #include <kiconloader.h> #include <kicondialog.h> #include <tdeapplication.h> #include <tdemessagebox.h> #include <krichtextlabel.h> // other TQt headers: #include <tqlayout.h> #include <tqlabel.h> #include <tqcheckbox.h> #include <tqhbox.h> #include <tqvgroupbox.h> #include <tqhgroupbox.h> #include <tqgrid.h> #include <tqpushbutton.h> #include <tqtooltip.h> extern void wake_laptop_daemon(); BatteryConfig::BatteryConfig (TQWidget * parent, const char *name) : TDECModule(parent, name), editPoll(0), iconloader(0), buttonNoBattery(0), buttonNoCharge(0), buttonCharge(0) { TDEGlobal::locale()->insertCatalogue("klaptopdaemon"); // For translation of klaptopdaemon messages apm = laptop_portable::has_power_management(); config = new TDEConfig("kcmlaptoprc"); instance = new TDEInstance("klaptopdaemon"); TQVBoxLayout *top_layout = new TQVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() ); // do we show the monitor runMonitor = new TQCheckBox( i18n("&Show battery monitor"), this ); top_layout->addWidget( runMonitor ); TQToolTip::add( runMonitor, i18n( "This box enables the battery state icon in the panel" ) ); connect( runMonitor, TQT_SIGNAL(clicked()), this, TQT_SLOT(configChanged()) ); connect( runMonitor, TQT_SIGNAL(clicked()), this, TQT_SLOT(runMonitorChanged()) ); // show also the battery level percentage showLevel = new TQCheckBox( i18n("Show battery level percentage"), this ); top_layout->addWidget( showLevel ); TQToolTip::add( showLevel, i18n( "This box enables a text message near the battery state icon containing battery level percentage" ) ); connect( showLevel, TQT_SIGNAL(clicked()), this, TQT_SLOT(configChanged()) ); notifyMe = new TQCheckBox( i18n("&Notify me whenever my battery becomes fully charged"), this ); top_layout->addWidget( notifyMe ); TQToolTip::add( notifyMe, i18n( "This box enables a dialog box that pops up when your battery becomes fully charged" ) ); connect( notifyMe, TQT_SIGNAL(clicked()), this, TQT_SLOT(configChanged()) ); blankSaver = new TQCheckBox( i18n("&Use a blank screen saver when running on battery"), this ); top_layout->addWidget( blankSaver ); connect( blankSaver, TQT_SIGNAL(clicked()), this, TQT_SLOT(configChanged()) ); if (!apm) { top_layout->addWidget( laptop_portable::no_power_management_explanation(this) ); } else { iconloader = new TDEIconLoader("klaptopdaemon"); // the poll time (in seconds) TQHBox *hb = new TQHBox( this ); hb->setSpacing( KDialog::spacingHint() ); top_layout->addWidget( hb ); TQLabel* poll_label = new TQLabel( i18n("&Check status every:"), hb ); editPoll = new TQSpinBox( 1, 3600, 1, hb ); // min,max,step TQToolTip::add( editPoll, i18n( "Choose how responsive the laptop software will be when it checks the battery status" ) ); editPoll->setSuffix( i18n("keep short, unit in spinbox", "sec") ); poll_label->setBuddy( editPoll ); connect( editPoll, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(configChanged()) ); TQWidget* spacer = new TQWidget( hb ); hb->setStretchFactor( spacer, 1 ); // group box to hold the icons together TQVGroupBox* icons_groupbox = new TQVGroupBox( i18n("Select Battery Icons"), this ); icons_groupbox->layout()->setSpacing( KDialog::spacingHint() ); top_layout->addWidget( icons_groupbox, 0, TQt::AlignLeft ); // layout to hold the icons inside the groupbox TQGrid *icon_grid = new TQGrid( 3 /*cols*/, icons_groupbox ); icon_grid->setSpacing( KDialog::spacingHint() ); buttonNoBattery = new TDEIconButton( iconloader, icon_grid ); buttonNoCharge = new TDEIconButton( iconloader, icon_grid ); buttonCharge = new TDEIconButton( iconloader, icon_grid ); (void)new TQLabel( buttonNoBattery, i18n("No &battery"), icon_grid); (void)new TQLabel( buttonNoCharge, i18n("&Not charging"), icon_grid); (void)new TQLabel( buttonCharge, i18n("Char&ging"), icon_grid); buttonNoBattery->setIconType( TDEIcon::NoGroup, TDEIcon::Any, 1); buttonNoCharge->setIconType( TDEIcon::NoGroup, TDEIcon::Any, 1); buttonCharge->setIconType( TDEIcon::NoGroup, TDEIcon::Any, 1); connect(buttonNoBattery, TQT_SIGNAL(iconChanged(TQString)), this, TQT_SLOT(iconChanged())); connect(buttonNoCharge, TQT_SIGNAL(iconChanged(TQString)), this, TQT_SLOT(iconChanged())); connect(buttonCharge, TQT_SIGNAL(iconChanged(TQString)), this, TQT_SLOT(configChanged())); int num_batteries; TQStringList battery_names, battery_states, battery_values; laptop_portable::get_battery_status(num_batteries, battery_names, battery_states, battery_values); if (num_batteries > 0) { TQHBoxLayout *hl = new TQHBoxLayout(); top_layout->addLayout(hl); TQHGroupBox *hb = new TQHGroupBox(i18n("Current Battery Status"), this); for (int i = 0; i < num_batteries; i++) { TQWidget *wp; if (num_batteries == 1) { wp = new TQWidget(hb); } else { wp = new TQVGroupBox(battery_names[i], hb); } TQVBoxLayout *vb = new TQVBoxLayout(wp); TQLabel *l; l = new TQLabel(wp); // icon indicating state vb->addWidget(l); batt_label_1.append(l); l = new TQLabel(TQString(""), wp); vb->addWidget(l); batt_label_2.append(l); l = new TQLabel(TQString(""), wp); vb->addWidget(l); batt_label_3.append(l); } hl->addWidget(hb); hl->addStretch(1); (void)startTimer(30*1000); // update 2x every minute } // TODO: remove linefeed from string, can't do it right now coz we have a string freeze TQLabel* explain = new KRichTextLabel( i18n("This panel controls whether the battery status monitor\nappears in the system tray and what it looks like.").replace("\n"," "), this); top_layout->addWidget(explain, 0); laptop_portable::extra_config(this, config, top_layout); } top_layout->addStretch(1); startMonitor = new TQPushButton( i18n("&Start Battery Monitor"), this); connect(startMonitor, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotStartMonitor())); top_layout->addWidget( startMonitor, 0, TQt::AlignRight ); load(); } BatteryConfig::~BatteryConfig() { delete instance; delete config; } void BatteryConfig::save() { enablemonitor = runMonitor->isChecked(); showlevel = showLevel->isChecked(); useblanksaver = blankSaver->isChecked(); notifyme = notifyMe->isChecked(); if (apm) { poll_time = editPoll->value(); nobattery = buttonNoBattery->icon(); chargebattery = buttonCharge->icon(); nochargebattery = buttonNoCharge->icon(); } config->setGroup("BatteryDefault"); config->writeEntry("Enable", enablemonitor); config->writeEntry("ShowLevel", showlevel); config->writeEntry("NotifyMe", notifyme); config->writeEntry("BlankSaver", useblanksaver); config->writeEntry("Poll", poll_time); config->writeEntry("NoBatteryPixmap", nobattery); config->writeEntry("ChargePixmap", chargebattery); config->writeEntry("NoChargePixmap", nochargebattery); config->sync(); changed(false); wake_laptop_daemon(); } void BatteryConfig::load() { load( false ); } void BatteryConfig::load(bool useDefaults) { config->setReadDefaults( useDefaults ); config->setGroup("BatteryDefault"); poll_time = config->readNumEntry("Poll", 20); enablemonitor = config->readBoolEntry("Enable", true); showlevel = config->readBoolEntry("ShowLevel", false); notifyme = config->readBoolEntry("NotifyMe", false); useblanksaver = config->readBoolEntry("BlankSaver", false); nobattery = config->readEntry("NoBatteryPixmap", "laptop_nobattery"); nochargebattery = config->readEntry("NoChargePixmap", "laptop_nocharge"); chargebattery = config->readEntry("ChargePixmap", "laptop_charge"); runMonitor->setChecked(enablemonitor); showLevel->setChecked(showlevel); blankSaver->setChecked(useblanksaver); notifyMe->setChecked(notifyme); if (apm) { editPoll->setValue(poll_time); buttonNoCharge->setIcon(nochargebattery); buttonCharge->setIcon(chargebattery); buttonNoBattery->setIcon(nobattery); } battery_pm = SmallIcon(nochargebattery, 20, TDEIcon::DefaultState, instance); battery_nopm = SmallIcon(nobattery, 20, TDEIcon::DefaultState, instance); emit changed(useDefaults); BatteryStateUpdate(); } void BatteryConfig::defaults() { load( true ); } void BatteryConfig::runMonitorChanged() { showLevel->setEnabled (runMonitor->isChecked()); } void BatteryConfig::configChanged() { emit changed(true); } TQString BatteryConfig::quickHelp() const { return i18n("<h1>Laptop Battery</h1>This module allows you to monitor " "your batteries. To make use of this module, you must have power management system software " "installed. (And, of course, you should have batteries in your machine.)"); } void BatteryConfig::slotStartMonitor() { wake_laptop_daemon(); if (!enablemonitor) { KMessageBox::information(0, i18n("<qt>The battery monitor has been started, but the tray icon is currently disabled. You can make it appear by selecting the <b>Show battery monitor</b> entry on this page and applying your changes.</qt>"), TQString(), "howToEnableMonitor"); } } void BatteryConfig::ConvertIcon(int percent, TQPixmap &pm, TQPixmap &result) { TQImage image = pm.convertToImage(); int w = image.width(); int h = image.height(); int count = 0; TQRgb rgb; int x, y; for (x = 0; x < w; x++) for (y = 0; y < h; y++) { rgb = image.pixel(x, y); if (tqRed(rgb) == 0xff && tqGreen(rgb) == 0xff && tqBlue(rgb) == 0xff) count++; } int c = (count*percent)/100; if (percent == 100) { c = count; } else if (percent != 100 && c == count) c = count-1; if (c) { uint ui; TQRgb blue = tqRgb(0x00,0x00,0xff); if (image.depth() <= 8) { ui = image.numColors(); // this fix thanks to Sven Krumpke image.setNumColors(ui+1); image.setColor(ui, blue); } else { ui = 0xff000000|blue; } for (y = h-1; y >= 0; y--) for (x = 0; x < w; x++) { rgb = image.pixel(x, y); if (tqRed(rgb) == 0xff && tqGreen(rgb) == 0xff && tqBlue(rgb) == 0xff) { image.setPixel(x, y, ui); c--; if (c <= 0) goto quit; } } } quit: result.convertFromImage(image); } void BatteryConfig::BatteryStateUpdate() { int num_batteries; TQStringList battery_names, battery_states, battery_values; laptop_portable::get_battery_status(num_batteries, battery_names, battery_states, battery_values); if (num_batteries > 0) { for (int i = 0; i < num_batteries; i++) { if (battery_states[i] == "yes") { TQPixmap result; ConvertIcon(battery_values[i].toInt(), battery_pm, result); batt_label_1.at(i)->setPixmap(result); batt_label_2.at(i)->setText(battery_values[i]+"%"); batt_label_3.at(i)->setText(i18n("Present")); } else { batt_label_1.at(i)->setPixmap(battery_nopm); batt_label_2.at(i)->setText(""); batt_label_3.at(i)->setText(i18n("Not present")); } } } } void BatteryConfig::iconChanged() { nobattery = buttonNoBattery->icon(); nochargebattery = buttonNoCharge->icon(); battery_pm = SmallIcon(nochargebattery, 20, TDEIcon::DefaultState, instance); battery_nopm = SmallIcon(nobattery, 20, TDEIcon::DefaultState, instance); emit changed(true); BatteryStateUpdate(); } void BatteryConfig::timerEvent(TQTimerEvent *) { BatteryStateUpdate(); } #include "battery.moc"