diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-19 20:40:48 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-19 20:40:48 +0000 |
commit | be4fc77c294a41a0db46ba692fbe45b2045b66c3 (patch) | |
tree | 4e930029faf4f131514b080217ad080fd3a5acb8 /src | |
download | tdepowersave-be4fc77c294a41a0db46ba692fbe45b2045b66c3.tar.gz tdepowersave-be4fc77c294a41a0db46ba692fbe45b2045b66c3.zip |
Added KDE3 version of kpowersave
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kpowersave@1092957 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src')
97 files changed, 20941 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..9e85c65 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,103 @@ +# set the include path for X, qt and KDE +INCLUDES = \ + -DPACKAGE_KDE_SOUND_DIR=\""$(prefix)/share/sounds/"\" \ + $(all_includes) \ + @PACKAGE_CFLAGS@ + +# these are the headers for your project +noinst_HEADERS = \ + autodimm.h \ + autosuspend.h \ + blacklisteditdialog.h \ + configuredialog.h \ + countdowndialog.h \ + dbusHAL.h \ + detaileddialog.h \ + hardware.h \ + hardware_battery.h \ + hardware_batteryCollection.h \ + hardware_cpu.h \ + inactivity.h \ + infodialog.h \ + kpowersave.h \ + logviewer.h \ + privileges.h \ + screen.h \ + settings.h \ + suspenddialog.h + + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +KDE_ICON = kpowersave + +######################################################################### +# APPLICATION SECTION +######################################################################### +# this is the program that gets installed. it's name is used for all +# of the other Makefile.am variables + +bin_PROGRAMS = +lib_LTLIBRARIES = +kdeinit_LTLIBRARIES = kpowersave.la + +# the application source, library search path, and link libraries +kpowersave_la_SOURCES = \ + dummy.cpp \ + autodimm.cpp \ + autosuspend.cpp \ + blacklistedit_Dialog.ui \ + blacklisteditdialog.cpp \ + configure_Dialog.ui \ + configuredialog.cpp \ + countdown_Dialog.ui \ + countdowndialog.cpp \ + dbusHAL.cpp \ + detailed_Dialog.ui \ + detaileddialog.cpp \ + hardware.cpp \ + hardware_battery.cpp \ + hardware_batteryCollection.cpp \ + hardware_cpu.cpp \ + inactivity.cpp \ + info_Dialog.ui \ + infodialog.cpp \ + kpowersave.cpp \ + kpowersave.skel \ + log_viewer.ui \ + logviewer.cpp \ + main.cpp \ + screen.cpp \ + settings.cpp \ + suspenddialog.cpp \ + suspend_Dialog.ui + + +kpowersave_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -module -avoid-version +kpowersave_la_LIBADD = $(LIB_KIO) @PACKAGE_LIBS@ -ldbus-qt-1 -lXss -lXext -lXtst + +# this is where the desktop file will go +xdg_apps_DATA = kpowersave.desktop + +# and for autostart +autostartdir = $(prefix)/share/autostart +autostart_DATA = kpowersave-autostart.desktop + +# this is where the shell's XML-GUI resource file goes +shellrcdir = $(kde_datadir)/kpowersave +shellrc_DATA = eventsrc +# shellrc_DATA = kpowersaveui.rc + +# pics subdir +SUBDIRS = pics +messages: + $(EXTRACTRC) *ui eventsrc >> rc.cpp + $(XGETTEXT) `find . -name \*.h -o -name \*.H -o -name \*.cpp -o -name \*.C` -o $(podir)/kpowersave.pot + rm -f rc.cpp + +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(kde_confdir) + $(INSTALL_DATA) $(top_srcdir)/src/config/kpowersaverc_default $(DESTDIR)$(kde_confdir)/kpowersaverc + + diff --git a/src/autodimm.cpp b/src/autodimm.cpp new file mode 100644 index 0000000..03dc0bc --- /dev/null +++ b/src/autodimm.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (C) 2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! \file autodimm.cpp + * \brief In this file can be found the autodimm class related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \version 0.0.1 + * \date 2007 + */ + +#include "autodimm.h" + +/*! The default constructor of the class autodimm */ +autodimm::autodimm() : inactivity() { + kdDebugFuncIn(trace); + + lastIdleTime = 0; + + checkActivity = new QTimer( this ); + connect( checkActivity, SIGNAL(timeout()), this, SLOT(pollActivity())); + + kdDebugFuncOut(trace); +} + +/*! The default destructor of the class autodimm */ +autodimm::~autodimm() { + kdDebugFuncIn(trace); +} + +/*! + * Public function to start to check (poll) if the user get active again. + */ +void autodimm::startCheckForActivity() { + kdDebugFuncIn(trace); + + lastIdleTime = 0; + + // stop the timer if running + if (checkActivity->isActive()) + checkActivity->stop(); + + checkActivity->start(RECHECK_INTERVALL, false); + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to call check if the user is active again. + */ +void autodimm::pollActivity() { + kdDebugFuncIn(trace); + + unsigned long idletime = 0; + + idletime = getXInactivity(); + if (idletime < lastIdleTime) { + kdDebug() << "Looks as if the user is active again (lastIdleTime:" << lastIdleTime + << " , current idletime: " << idletime << ")" << endl; + + // The user is/was active ... + if (idletime <= 1000) + kdDebug() << "Looks as if the user was active within the last second" << endl; + + // stop the timer ... no need to let run ... start again if needed + if (checkActivity->isActive()) checkActivity->stop(); + // emit the signal that the user is active again. + emit UserIsActiveAgain(); + } else { + lastIdleTime = idletime; + } + + kdDebugFuncOut(trace); +} + +#include "autodimm.moc" diff --git a/src/autodimm.h b/src/autodimm.h new file mode 100644 index 0000000..ace1e08 --- /dev/null +++ b/src/autodimm.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2007 by Danny Kukawka * + * <dkukawka@suse.de>, >danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! +* \file autodimm.h +* \brief Headerfile for autodimm.cpp and the class \ref autodimm. +*/ +/*! +* \class autodimm +* \brief class for 'dimm the display on user inactivity' related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \version 0.0.1 +* \date 2007 +*/ + +#ifndef AUTODIMM_H +#define AUTODIMM_H + +// from project +#include "inactivity.h" + +class autodimm : public inactivity +{ + Q_OBJECT + +public: + //! default constructor + autodimm(); + //! default destructor + ~autodimm(); + + //! to start check if the user is active again + void startCheckForActivity(); + +signals: + //! signal emited if the user is active again + void UserIsActiveAgain(); + +private: + //! idle time from the last check + unsigned long lastIdleTime; + + //! QTimer intervall for the Timer to recheck for user activity + /*! + * The time intervall to recheck for the activity of the user. + * The timeslice is currently 1 sec. + */ + static const int RECHECK_INTERVALL = 1000; + + //! QTimer for check activity + /*! + * This timer is used to check if the user get active again. + * The timerinterval is defined trough \ref RECHECK_INTERVALL . + */ + QTimer *checkActivity; + +private slots: + //! to poll X to get info if the user is active again + void pollActivity(); + +}; + +#endif diff --git a/src/autosuspend.cpp b/src/autosuspend.cpp new file mode 100644 index 0000000..a46a93c --- /dev/null +++ b/src/autosuspend.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2004 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! \file autosuspend.cpp + * \brief In this file can be found the autosuspend related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2005 + */ + +#include "autosuspend.h" + +/*! The default constructor of the class autosuspend */ +autosuspend::autosuspend() : inactivity () { + kdDebugFuncIn(trace); + +} + +/*! The default destructor of the class autosuspend */ +autosuspend::~autosuspend() { + kdDebugFuncIn(trace); +} + +#include "autosuspend.moc" diff --git a/src/autosuspend.h b/src/autosuspend.h new file mode 100644 index 0000000..e537f34 --- /dev/null +++ b/src/autosuspend.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2004 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +#ifndef AUTOSUSPEND_H +#define AUTOSUSPEND_H + +// from project +#include "inactivity.h" + +/*! +* \file autosuspend.h +* \brief Headerfile for autosuspend.cpp and the class \ref autosuspend. +*/ +/*! +* \class autosuspend +* \brief class for autosuspend related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2005 +*/ + +class autosuspend : public inactivity +{ + Q_OBJECT + +public: + //! default constructor + autosuspend(); + //! default destructor + ~autosuspend(); +}; + +#endif diff --git a/src/blacklistedit_Dialog.ui b/src/blacklistedit_Dialog.ui new file mode 100644 index 0000000..5a91bfc --- /dev/null +++ b/src/blacklistedit_Dialog.ui @@ -0,0 +1,275 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>blacklistedit_Dialog</class> +<widget class="QDialog"> + <property name="name"> + <cstring>blacklistedit_Dialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>490</width> + <height>246</height> + </rect> + </property> + <property name="caption"> + <string>Autosuspend Blacklist Edit</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>OK</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton" row="0" column="3"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Cancel</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer row="0" column="0"> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>305</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QButtonGroup" row="0" column="0"> + <property name="name"> + <cstring>bG_scheme</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string></string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLineEdit" row="0" column="0"> + <property name="name"> + <cstring>lE_blacklist</cstring> + </property> + </widget> + <widget class="QPushButton" row="0" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>pB_add</cstring> + </property> + <property name="text"> + <string>Add</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>pB_remove</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + <widget class="QListBox" row="0" column="3" rowspan="3" colspan="1"> + <property name="name"> + <cstring>lB_blacklist</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>150</height> + </size> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer22</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>31</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="2" column="2"> + <property name="name"> + <cstring>spacer23</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>21</width> + <height>140</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>tLabel_info</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>220</width> + <height>110</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignBottom</set> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>released()</signal> + <receiver>blacklistedit_Dialog</receiver> + <slot>buttonOk_released()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>released()</signal> + <receiver>blacklistedit_Dialog</receiver> + <slot>buttonCancel_released()</slot> + </connection> + <connection> + <sender>pB_remove</sender> + <signal>released()</signal> + <receiver>blacklistedit_Dialog</receiver> + <slot>pB_remove_released()</slot> + </connection> + <connection> + <sender>pB_add</sender> + <signal>released()</signal> + <receiver>blacklistedit_Dialog</receiver> + <slot>pB_add_released()</slot> + </connection> + <connection> + <sender>lE_blacklist</sender> + <signal>textChanged(const QString&)</signal> + <receiver>blacklistedit_Dialog</receiver> + <slot>lE_blacklist_textChanged()</slot> + </connection> + <connection> + <sender>lB_blacklist</sender> + <signal>currentChanged(QListBoxItem*)</signal> + <receiver>blacklistedit_Dialog</receiver> + <slot>lB_blacklist_currentChanged()</slot> + </connection> +</connections> +<tabstops> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>lE_blacklist</tabstop> + <tabstop>pB_add</tabstop> + <tabstop>pB_remove</tabstop> + <tabstop>lB_blacklist</tabstop> +</tabstops> +<slots> + <slot>buttonOk_released()</slot> + <slot>buttonCancel_released()</slot> + <slot>buttonApply_released()</slot> + <slot>pB_remove_released()</slot> + <slot>pB_add_released()</slot> + <slot>lB_blacklist_selected( QListBoxItem * )</slot> + <slot>lE_blacklist_textChanged()</slot> + <slot>lB_blacklist_selected()</slot> + <slot>lB_blacklist_currentChanged(QListBoxItem*)</slot> + <slot>lB_blacklist_currentChanged()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/blacklisteditdialog.cpp b/src/blacklisteditdialog.cpp new file mode 100644 index 0000000..fb2ce80 --- /dev/null +++ b/src/blacklisteditdialog.cpp @@ -0,0 +1,172 @@ +/*************************************************************************** + * Copyright (C) 2005 by Danny Kukawka * + * danny.kukawka@web.de, dkukawka@suse.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! + * \file blacklisteditdialog.cpp + * \brief In this file can be found the "blacklist edit dialog" related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2005 + */ + +// own header +#include "blacklisteditdialog.h" + +// KDE headers: +#include <klocale.h> +#include <kiconloader.h> + +// QT headers: +#include <qbuttongroup.h> +#include <qdialog.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qlistbox.h> +#include <qpushbutton.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qtooltip.h> + +/*! This is the default constructor of class blacklistEditDialog . */ +blacklistEditDialog::blacklistEditDialog( QStringList blacklisted, QString captionName, + bool initImport, QWidget *parent, const char *name) + :blacklistedit_Dialog(parent, name, false, WDestructiveClose ) +{ + blacklist = blacklisted; + + changed = initImport; + + pB_add->setEnabled(false); + pB_remove->setEnabled(false); + + lB_blacklist->insertStringList(blacklist); + lB_blacklist->sort(); + + if (captionName.startsWith(i18n("General Blacklist"))) + this->bG_scheme->setTitle(captionName); + else + this->bG_scheme->setTitle( i18n("Scheme: ") + captionName); + this->setIcon(SmallIcon("configure", QIconSet::Automatic)); + buttonCancel->setIconSet(SmallIconSet("cancel", QIconSet::Automatic)); + buttonOk->setIconSet(SmallIconSet("ok", QIconSet::Automatic)); + pB_add->setIconSet(SmallIconSet("forward", QIconSet::Automatic)); + pB_remove->setIconSet(SmallIconSet("back", QIconSet::Automatic)); + +} + +/*! This is the default destructor of class blacklistEditDialog . */ +blacklistEditDialog::~blacklistEditDialog() +{ + // no need to delete child widgets, Qt does it all for us +} + +/*! + * SLOT: called if the 'ok' button clicked. This SLOT emit + * \ref config_finished() and close the dialog. + */ +void blacklistEditDialog::buttonOk_released() { + + if(changed == true) { + changed = false; + emit config_finished( blacklist ); + } + close(); +} + + +/*! + * SLOT: called if the 'cancel' button clicked. This SLOT close + * the dialog. + */ +void blacklistEditDialog::buttonCancel_released(){ + changed = false; + close(); +} + + +/*! + * SLOT: called if the 'remove' button clicked. The SLOT try to remove + * the selected item from the QListBox and the QStringList \ref blacklist . + */ +void blacklistEditDialog::pB_remove_released(){ + + if(blacklist.remove(lB_blacklist->selectedItem()->text()) > 0) { + lB_blacklist->removeItem(lB_blacklist->currentItem()); + lB_blacklist->sort(); + changed = true; + + pB_remove->setEnabled(false); + tLabel_info->setText(i18n("Selected entry removed.")); + } + else { + tLabel_info->setText(i18n("Could not remove the selected entry.")); + } +} + + +/*! + * SLOT: called if the 'add' button clicked. The SLOT try to add the string from + * the QLineEdit lE_blacklist to the QListBox and the QStringList \ref blacklist . + */ +void blacklistEditDialog::pB_add_released(){ + + QString text = lE_blacklist->text(); + // remove the whitespaces and check if text is empty + if(text.stripWhiteSpace() != "") { + // check if the entry is already present + if(!lB_blacklist->findItem(text, Qt::ExactMatch)) { + lB_blacklist->insertItem(text); + lB_blacklist->sort(); + blacklist.append(text); + blacklist.sort(); + tLabel_info->setText(i18n("Inserted new entry.")); + changed = true; + } + else { + tLabel_info->setText(i18n("Entry exists already. Did not insert new entry.")); + } + } + else tLabel_info->setText(i18n("Empty entry was not inserted.")); + + // set the widgets back to default + lE_blacklist->setText(""); + pB_remove->setEnabled(false); + pB_add->setEnabled(false); +} + + +/*! + * SLOT: called if a item in the QListBox lB_blacklist is selected. + * Here we enable the remove button pB_remove . + */ +void blacklistEditDialog::lB_blacklist_currentChanged(){ + // enable the remove button + pB_remove->setEnabled(true); +} + + +/*! + * SLOT: called if the input-line in the dialog is modified. Here we enable + * the add button pB_add . + */ +void blacklistEditDialog::lE_blacklist_textChanged(){ + // enable the add button + pB_add->setEnabled(true); +} + +#include "blacklisteditdialog.moc" diff --git a/src/blacklisteditdialog.h b/src/blacklisteditdialog.h new file mode 100644 index 0000000..adbf559 --- /dev/null +++ b/src/blacklisteditdialog.h @@ -0,0 +1,94 @@ +/*************************************************************************** + * Copyright (C) 2005 by Danny Kukawka * + * danny.kukawka@web.de, dkukawka@suse.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! +* \file blacklisteditdialog.h +* \brief Headerfile for blacklisteditdialog.cpp and the class \ref +* blacklistEditDialog . +*/ +/*! +* \class blacklistEditDialog +* \brief class for dialog to edit the blacklist related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2005 +*/ + +#ifndef BLACKLISTEDITDIALOG_H +#define BLACKLISTEDITDIALOG_H + +#include "blacklistedit_Dialog.h" + +class blacklistEditDialog: public blacklistedit_Dialog { + + Q_OBJECT + +public: + + //! default constructor + blacklistEditDialog(QStringList blacklisted, QString captionName, bool initImport = false, + QWidget *parent = 0, const char *name = 0); + //! default destructor + ~blacklistEditDialog(); + +private: + + //! QStringList with the blacklisted processes + /*! + * This QStringList contains the given blacklisted processes + * for edit. If the dialog changed, we change also this list. + */ + QStringList blacklist; + + //! to tell if the blacklist was changed + /*! + * This boolean value tells if the current blacklist was changed. + * \li true: if the blacklist changed + * \li false: if the blacklist isn't changed + */ + bool changed; + + +private slots: + + //! called if the 'ok' button clicked + void buttonOk_released(); + //! called if the 'cancel' button clicked + void buttonCancel_released(); + //! called if the 'remove' button clicked + void pB_remove_released(); + //! called if the 'add' button clicked + void pB_add_released(); + //! called if a item of the listbox selected + void lB_blacklist_currentChanged(); + //! called if something input in the QLineEdit + void lE_blacklist_textChanged(); + +signals: + + //! signal emited if the configuration finished + /*! + * This signal is emited if the configuration is finished + * and the blacklist was modified- + * \return QStringList (the modified blacklist) + */ + void config_finished( QStringList ); + +}; + +#endif diff --git a/src/config/kpowersaverc_default b/src/config/kpowersaverc_default new file mode 100644 index 0000000..61e6e05 --- /dev/null +++ b/src/config/kpowersaverc_default @@ -0,0 +1,151 @@ +[General] +lockOnSuspend=true +lockOnLidClose=true +ActionOnLidClose= +ActionOnLidCloseValue= +ActionOnPowerButton=SHUTDOWN +ActionOnPowerButtonValue= +ActionOnSleepButton=SUSPEND2RAM +ActionOnS2DiskButton=SUSPEND2DISK +buttonsAllowedActions=SHUTDOWN,LOGOUT_DIALOG,SUSPEND2DISK,SUSPEND2RAM +AutoSuspendCountdown=true +AutoSuspendCountdownTimeOut=30 +Autostart=true +AutostartNeverAsk=false +unmountExternalOnSuspend=false +callSetPowerSaveOnAC=true +lockMethod=automatic +timeToFakeKeyAfterLock=2500 +forceDpmsOffOnLidClose=true +psMsgAsPassivePopup=false +autoInactiveBlacklist=mplayer,gmplayer,kaffeine,xine,mencoder,cdrecord,cdrecord-dvd,cdrdao,growisofs,kdetv,xawtv,realplay.bin,wodim +autoDimmBlacklist=mplayer,gmplayer,kaffeine,xine,kdetv,xawtv,realplay.bin +schemes=Performance,Powersave,Presentation,Acoustic +ac_scheme=Performance +battery_scheme=Powersave +batteryWarning=12 +batteryWarningAction= +batteryWarningActionValue= +batteryLow=7 +batteryLowAction=BRIGHTNESS +batteryLowActionValue=1 +batteryCritical=2 +batteryCriticalAction=SHUTDOWN +batteryCriticalActionValue= +batteryAllowedActions=SHUTDOWN,SUSPEND2DISK,SUSPEND2RAM,CPUFREQ_POWERSAVE,CPUFREQ_PERFORMANCE,CPUFREQ_DYNAMIC,BRIGHTNESS + +[default-scheme] +specSsSettings=false +disableSs=false +blankSs=false +specPMSettings=false +standbyAfter=5 +suspendAfter=10 +powerOffAfter=15 +disableDPMS=false +autoSuspend=false +autoInactiveAction=_NONE_ +autoInactiveActionAfter=0 +autoInactiveSchemeBlacklistEnabled=false +autoInactiveSchemeBlacklist= +autoDimm=false +autoDimmAfter=0 +autoDimmTo=50 +autoDimmSchemeBlacklistEnabled=false +autoDimmSchemeBlacklist= +enableBrightness=true +brightnessPercent=100 +cpuFreqPolicy=DYNAMIC +cpuFreqPolicyPerformance=51 + +[Performance] +specSsSettings=false +specPMSettings=true +standbyAfter=10 +suspendAfter=20 +powerOffAfter=30 +disableDPMS=false +autoSuspend=false +autoInactiveAction=_NONE_ +autoInactiveActionAfter=0 +autoInactiveSchemeBlacklistEnabled=false +autoInactiveSchemeBlacklist= +autoDimm=false +autoDimmAfter=0 +autoDimmTo=50 +autoDimmSchemeBlacklistEnabled=false +autoDimmSchemeBlacklist= +enableBrightness=true +brightnessPercent=100 +cpuFreqPolicy=DYNAMIC +cpuFreqDynamicPerformance=75 + +[Powersave] +specSsSettings=true +disableSs=false +blankSs=true +specPMSettings=true +standbyAfter=2 +suspendAfter=3 +powerOffAfter=5 +disableDPMS=false +autoSuspend=false +autoInactiveAction=_NONE_ +autoInactiveActionAfter=0 +autoInactiveSchemeBlacklistEnabled=false +autoInactiveSchemeBlacklist= +autoDimm=true +autoDimmAfter=5 +autoDimmTo=15 +autoDimmSchemeBlacklistEnabled=No +autoDimmSchemeBlacklist= +enableBrightness=true +brightnessPercent=50 +cpuFreqPolicy=DYNAMIC +cpuFreqDynamicPerformance=25 + +[Presentation] +specSsSettings=true +disableSs=true +specPMSettings=true +standbyAfter=10 +suspendAfter=20 +powerOffAfter=30 +disableDPMS=true +autoSuspend=false +autoInactiveAction=_NONE_ +autoInactiveActionAfter=0 +autoInactiveSchemeBlacklistEnabled=false +autoInactiveSchemeBlacklist= +autoDimm=false +autoDimmAfter=0 +autoDimmTo=100 +autoDimmSchemeBlacklistEnabled=false +autoDimmSchemeBlacklist= +enableBrightness=true +brightnessPercent=100 +cpuFreqPolicy=DYNAMIC +cpuFreqDynamicPerformance=60 + +[Acoustic] +specSsSettings=true +disableSs=false +specPMSettings=true +standbyAfter=5 +suspendAfter=7 +powerOffAfter=10 +disableDPMS=false +autoSuspend=false +autoInactiveAction=_NONE_ +autoInactiveActionAfter=0 +autoInactiveSchemeBlacklistEnabled=false +autoInactiveSchemeBlacklist= +autoDimm=false +autoDimmAfter=0 +autoDimmTo=50 +autoDimmSchemeBlacklistEnabled=false +autoDimmSchemeBlacklist= +enableBrightness=true +brightnessPercent=100 +cpuFreqPolicy=DYNAMIC +cpuFreqDynamicPerformance=50 diff --git a/src/configure.in.in b/src/configure.in.in new file mode 100644 index 0000000..796c968 --- /dev/null +++ b/src/configure.in.in @@ -0,0 +1,9 @@ +#MIN_CONFIG(3.0.0) + +AM_INIT_AUTOMAKE(kpowersave, 0.1) +AC_C_BIGENDIAN +AC_CHECK_KDEMAXPATHLEN + +AC_PATH_QT +AC_PATH_QT_MOC_UIC + diff --git a/src/configure_Dialog.ui b/src/configure_Dialog.ui new file mode 100644 index 0000000..0578501 --- /dev/null +++ b/src/configure_Dialog.ui @@ -0,0 +1,2602 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>configure_Dialog</class> +<widget class="QDialog"> + <property name="name"> + <cstring>configure_Dialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>534</width> + <height>476</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>KPowersave Settings</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="0" column="3"> + <property name="name"> + <cstring>buttonApply</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Apply</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + <widget class="QPushButton" row="0" column="0"> + <property name="name"> + <cstring>buttonHelp</cstring> + </property> + <property name="text"> + <string>Help</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton" row="0" column="4"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Cancel</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer row="0" column="1"> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>250</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="0" column="2"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>OK</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <widget class="QTabWidget" row="0" column="0"> + <property name="name"> + <cstring>tabWidget</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>screen_settings</cstring> + </property> + <attribute name="title"> + <string>Scheme Settings</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QToolBox" row="0" column="1"> + <property name="name"> + <cstring>tB_scheme</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="midLineWidth"> + <number>0</number> + </property> + <property name="currentIndex"> + <number>3</number> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>screensaver</cstring> + </property> + <property name="backgroundMode"> + <enum>PaletteBackground</enum> + </property> + <attribute name="label"> + <string>Screen Saver and DPMS</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="3" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>cB_SpecificPM</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Enable specific display power management</string> + </property> + </widget> + <widget class="QLabel" row="4" column="1"> + <property name="name"> + <cstring>tL_standbyAfter</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Standby after:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>sB_standby</cstring> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QCheckBox" row="2" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>cB_blankScreen</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Only blank the screen</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>cB_disable_Ss</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Disable screen saver</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>cB_specificSettings</cstring> + </property> + <property name="text"> + <string>Enable specific screensaver settings</string> + </property> + </widget> + <widget class="QLabel" row="5" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>tL_suspendAfter</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Suspend after:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>sB_suspend</cstring> + </property> + </widget> + <spacer row="4" column="2"> + <property name="name"> + <cstring>spacer7_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>MinimumExpanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>160</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="6" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>tL_powerOffAfter</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Power off after:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>sB_powerOff</cstring> + </property> + </widget> + <widget class="QCheckBox" row="7" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>cB_disablePM</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Disable display power management</string> + </property> + </widget> + <widget class="QSpinBox" row="6" column="3"> + <property name="name"> + <cstring>sB_powerOff</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="suffix"> + <string> min</string> + </property> + <property name="maxValue"> + <number>120</number> + </property> + </widget> + <widget class="QSpinBox" row="5" column="3"> + <property name="name"> + <cstring>sB_suspend</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="suffix"> + <string> min</string> + </property> + <property name="maxValue"> + <number>120</number> + </property> + </widget> + <widget class="QSpinBox" row="4" column="3"> + <property name="name"> + <cstring>sB_standby</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="suffix"> + <string> min</string> + </property> + <property name="maxValue"> + <number>120</number> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>brightness</cstring> + </property> + <property name="backgroundMode"> + <enum>PaletteBackground</enum> + </property> + <attribute name="label"> + <string>Brightness</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox" row="2" column="0"> + <property name="name"> + <cstring>gB_Brightness</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Settings</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="0" column="1"> + <property name="name"> + <cstring>spacer47_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="1" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>pB_resetBrightness</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Reset</string> + </property> + </widget> + <widget class="QLabel" row="0" column="2"> + <property name="name"> + <cstring>tL_valueBrightness</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>40</width> + <height>30</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer51</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>231</width> + <height>31</height> + </size> + </property> + </spacer> + <spacer row="2" column="2"> + <property name="name"> + <cstring>spacer44</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>MinimumExpanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>21</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QSlider" row="0" column="0"> + <property name="name"> + <cstring>brightnessSlider</cstring> + </property> + <property name="mouseTracking"> + <bool>false</bool> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="maxValue"> + <number>100</number> + </property> + <property name="lineStep"> + <number>3</number> + </property> + <property name="pageStep"> + <number>10</number> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="tickmarks"> + <enum>Below</enum> + </property> + <property name="tickInterval"> + <number>0</number> + </property> + </widget> + </grid> + </widget> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>cB_Brightness</cstring> + </property> + <property name="text"> + <string>Enable scheme specific Brightness settings</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>tL_brightness</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>50</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>autosuspend</cstring> + </property> + <property name="backgroundMode"> + <enum>PaletteBackground</enum> + </property> + <attribute name="label"> + <string>Autosuspend</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>cB_autoSuspend</cstring> + </property> + <property name="text"> + <string>Enable autosuspend</string> + </property> + </widget> + <widget class="QComboBox" row="2" column="1"> + <property name="name"> + <cstring>cB_autoInactivity</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>20</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>20</height> + </size> + </property> + </widget> + <widget class="Line" row="3" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>line2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QCheckBox" row="4" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>cB_Blacklist</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Enable scheme-specific blacklist</string> + </property> + </widget> + <widget class="QLabel" row="2" column="2"> + <property name="name"> + <cstring>tL_autoInactivity_After</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>after:</string> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + <property name="buddy" stdset="0"> + <cstring>sB_autoInactivity</cstring> + </property> + </widget> + <widget class="QSpinBox" row="2" column="3"> + <property name="name"> + <cstring>sB_autoInactivity</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string> min</string> + </property> + </widget> + <widget class="QPushButton" row="5" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>pB_editBlacklist</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Edit Blacklist...</string> + </property> + </widget> + <spacer row="6" column="2"> + <property name="name"> + <cstring>spacer17_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>21</width> + <height>50</height> + </size> + </property> + </spacer> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer16</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>30</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="1" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>tL_autoInactivity_explain</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>If the current desktop user is inactive the computer will:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cB_autoInactivity</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>page</cstring> + </property> + <property name="backgroundMode"> + <enum>PaletteBackground</enum> + </property> + <attribute name="label"> + <string>Autodimm</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>cB_autoDimm</cstring> + </property> + <property name="text"> + <string>Enable autodimm the display</string> + </property> + </widget> + <widget class="Line" row="3" column="1" rowspan="1" colspan="5"> + <property name="name"> + <cstring>line2_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QCheckBox" row="4" column="1" rowspan="1" colspan="5"> + <property name="name"> + <cstring>cB_BlacklistDimm</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Enable scheme-specific blacklist</string> + </property> + </widget> + <widget class="QPushButton" row="5" column="3" rowspan="1" colspan="3"> + <property name="name"> + <cstring>pB_editBlacklistDimm</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Edit Blacklist...</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0" rowspan="1" colspan="6"> + <property name="name"> + <cstring>tL_autoDimmExplain</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>If the current desktop user is inactive the computer will:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cB_autoInactivity</cstring> + </property> + </widget> + <spacer row="6" column="4"> + <property name="name"> + <cstring>spacer83</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="2" column="1"> + <property name="name"> + <cstring>tL_autoDimmAfter</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>after:</string> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + <property name="buddy" stdset="0"> + <cstring>sB_autoInactivity</cstring> + </property> + </widget> + <widget class="QSpinBox" row="2" column="5"> + <property name="name"> + <cstring>sB_autoDimmTo</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string> %</string> + </property> + <property name="maxValue"> + <number>100</number> + </property> + </widget> + <widget class="QLabel" row="2" column="3" rowspan="1" colspan="2"> + <property name="name"> + <cstring>tL_autoDimmTo</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>dimm to:</string> + </property> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer16_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QSpinBox" row="2" column="2"> + <property name="name"> + <cstring>sB_autoDimmTime</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>20</height> + </size> + </property> + <property name="suffix"> + <string> min</string> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>cpufreq</cstring> + </property> + <property name="backgroundMode"> + <enum>PaletteBackground</enum> + </property> + <attribute name="label"> + <string>CPU Frequency Policy</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QComboBox" row="0" column="2"> + <item> + <property name="text"> + <string>Performance</string> + </property> + </item> + <item> + <property name="text"> + <string>Dynamic</string> + </property> + </item> + <item> + <property name="text"> + <string>Powersave</string> + </property> + </item> + <property name="name"> + <cstring>comboB_cpuFreq</cstring> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer19</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>170</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Set CPU Frequency Policy:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>comboB_cpuFreq</cstring> + </property> + </widget> + <spacer row="0" column="1"> + <property name="name"> + <cstring>spacer18</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>MinimumExpanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>misc</cstring> + </property> + <property name="backgroundMode"> + <enum>PaletteBackground</enum> + </property> + <attribute name="label"> + <string>Miscellaneous</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>cB_disableNotifications</cstring> + </property> + <property name="text"> + <string>Disable Notifications</string> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer34</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>170</height> + </size> + </property> + </spacer> + </grid> + </widget> + </widget> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>pB_deleteScheme</cstring> + </property> + <property name="text"> + <string>Delete</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="0"> + <property name="name"> + <cstring>pB_newScheme</cstring> + </property> + <property name="text"> + <string>New</string> + </property> + </widget> + <widget class="QListBox" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>listBox_schemes</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>110</width> + <height>0</height> + </size> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>TabPage</cstring> + </property> + <attribute name="title"> + <string>General Settings</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QToolBox" row="0" column="0"> + <property name="name"> + <cstring>tB_general</cstring> + </property> + <property name="currentIndex"> + <number>4</number> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>g_bat</cstring> + </property> + <property name="backgroundMode"> + <enum>PaletteBackground</enum> + </property> + <attribute name="label"> + <string>Battery</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0" rowspan="1" colspan="7"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>75</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Define the battery warning levels (in percentage) and the releated action if the level get reached:</string> + </property> + <property name="textFormat"> + <enum>RichText</enum> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="minimumSize"> + <size> + <width>90</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Warning level:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>sB_batWarning</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel1_2_2</cstring> + </property> + <property name="minimumSize"> + <size> + <width>90</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Low level:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>sB_batLow</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel1_2_3</cstring> + </property> + <property name="minimumSize"> + <size> + <width>90</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Critical level:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>sB_batCritical</cstring> + </property> + </widget> + <spacer row="4" column="2"> + <property name="name"> + <cstring>spacer78</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>50</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="1" column="4"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>if reached call:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cB_batWarning</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="4"> + <property name="name"> + <cstring>textLabel3_2</cstring> + </property> + <property name="text"> + <string>if reached call:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cB_batLow</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="4"> + <property name="name"> + <cstring>textLabel3_3</cstring> + </property> + <property name="text"> + <string>if reached call:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cB_batCritical</cstring> + </property> + </widget> + <widget class="QComboBox" row="1" column="5"> + <property name="name"> + <cstring>cB_batWarning</cstring> + </property> + <property name="minimumSize"> + <size> + <width>150</width> + <height>0</height> + </size> + </property> + </widget> + <widget class="QComboBox" row="2" column="5"> + <property name="name"> + <cstring>cB_batLow</cstring> + </property> + <property name="minimumSize"> + <size> + <width>150</width> + <height>0</height> + </size> + </property> + </widget> + <widget class="QComboBox" row="3" column="5"> + <property name="name"> + <cstring>cB_batCritical</cstring> + </property> + <property name="minimumSize"> + <size> + <width>150</width> + <height>0</height> + </size> + </property> + </widget> + <widget class="QSpinBox" row="2" column="6"> + <property name="name"> + <cstring>sB_batLowAction_value</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string> %</string> + </property> + <property name="maxValue"> + <number>100</number> + </property> + </widget> + <widget class="QSpinBox" row="3" column="6"> + <property name="name"> + <cstring>sB_batCritAction_value</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string> %</string> + </property> + <property name="maxValue"> + <number>100</number> + </property> + </widget> + <widget class="QSpinBox" row="1" column="2"> + <property name="name"> + <cstring>sB_batWarning</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string> %</string> + </property> + <property name="maxValue"> + <number>100</number> + </property> + </widget> + <widget class="QSpinBox" row="2" column="2"> + <property name="name"> + <cstring>sB_batLow</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string> %</string> + </property> + <property name="maxValue"> + <number>100</number> + </property> + </widget> + <widget class="QSpinBox" row="3" column="2"> + <property name="name"> + <cstring>sB_batCritical</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string> %</string> + </property> + <property name="maxValue"> + <number>100</number> + </property> + </widget> + <widget class="QSpinBox" row="1" column="6"> + <property name="name"> + <cstring>sB_batWarnAction_value</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string> %</string> + </property> + <property name="maxValue"> + <number>100</number> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>g_button</cstring> + </property> + <property name="backgroundMode"> + <enum>PaletteBackground</enum> + </property> + <attribute name="label"> + <string>Button Events</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>textLabel1_3_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>30</height> + </size> + </property> + <property name="text"> + <string>Define the action which should be executed if the related button get pressed:</string> + </property> + <property name="textFormat"> + <enum>RichText</enum> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>textLabel3_4_4</cstring> + </property> + <property name="text"> + <string>Suspend-to-disk Button:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cB_S2DiskButton</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel3_4_3</cstring> + </property> + <property name="text"> + <string>Sleep button:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cB_SleepButton</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel3_4_2</cstring> + </property> + <property name="text"> + <string>Lid close Button:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cB_LidcloseButton</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel3_4</cstring> + </property> + <property name="text"> + <string>Power Button:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cB_PowerButton</cstring> + </property> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer85</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>130</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="2" column="1"> + <property name="name"> + <cstring>spacer85_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>130</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="3" column="1"> + <property name="name"> + <cstring>spacer85_3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>130</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="4" column="1"> + <property name="name"> + <cstring>spacer85_4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>130</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QComboBox" row="3" column="2"> + <property name="name"> + <cstring>cB_SleepButton</cstring> + </property> + <property name="minimumSize"> + <size> + <width>160</width> + <height>0</height> + </size> + </property> + </widget> + <widget class="QComboBox" row="2" column="2"> + <property name="name"> + <cstring>cB_LidcloseButton</cstring> + </property> + <property name="minimumSize"> + <size> + <width>160</width> + <height>0</height> + </size> + </property> + </widget> + <widget class="QComboBox" row="1" column="2"> + <property name="name"> + <cstring>cB_PowerButton</cstring> + </property> + <property name="minimumSize"> + <size> + <width>160</width> + <height>0</height> + </size> + </property> + </widget> + <widget class="QComboBox" row="4" column="2"> + <property name="name"> + <cstring>cB_S2DiskButton</cstring> + </property> + <property name="minimumSize"> + <size> + <width>160</width> + <height>0</height> + </size> + </property> + </widget> + <spacer row="5" column="2"> + <property name="name"> + <cstring>spacer89</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>g_schemes</cstring> + </property> + <property name="backgroundMode"> + <enum>PaletteBackground</enum> + </property> + <attribute name="label"> + <string>Default Schemes</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>textLabel1_3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Select the following schemes as default if the system is running on AC or on batteries.</string> + </property> + <property name="textFormat"> + <enum>RichText</enum> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel2_2_2</cstring> + </property> + <property name="text"> + <string>Battery scheme:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cB_batteryScheme</cstring> + </property> + </widget> + <widget class="QComboBox" row="1" column="2"> + <property name="name"> + <cstring>cB_acScheme</cstring> + </property> + <property name="minimumSize"> + <size> + <width>175</width> + <height>0</height> + </size> + </property> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer80</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>110</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="2" column="1"> + <property name="name"> + <cstring>spacer80_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>110</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QComboBox" row="2" column="2"> + <property name="name"> + <cstring>cB_batteryScheme</cstring> + </property> + <property name="minimumSize"> + <size> + <width>175</width> + <height>0</height> + </size> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string>AC scheme:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cB_acScheme</cstring> + </property> + </widget> + <spacer row="3" column="2"> + <property name="name"> + <cstring>spacer82</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>75</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>g_lock</cstring> + </property> + <property name="backgroundMode"> + <enum>PaletteBackground</enum> + </property> + <attribute name="label"> + <string>Lock Screen</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>cB_lockSuspend</cstring> + </property> + <property name="text"> + <string>Lock screen before suspend or standby</string> + </property> + </widget> + <widget class="QComboBox" row="2" column="1"> + <property name="name"> + <cstring>comboB_lock</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <spacer row="2" column="2"> + <property name="name"> + <cstring>spacer5_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>163</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>tL_lockWith</cstring> + </property> + <property name="text"> + <string>Lock screen with:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>comboB_lock</cstring> + </property> + </widget> + <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>cB_lockLid</cstring> + </property> + <property name="text"> + <string>Lock screen on lid close</string> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>spacer79</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>110</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>g_misc</cstring> + </property> + <property name="backgroundMode"> + <enum>PaletteBackground</enum> + </property> + <attribute name="label"> + <string>Miscellaneous</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox" row="1" column="0"> + <property name="name"> + <cstring>groupBox_notify</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Notifications</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>pB_configNotify</cstring> + </property> + <property name="text"> + <string>Configure Notifications...</string> + </property> + </widget> + <spacer row="0" column="0"> + <property name="name"> + <cstring>spacer47_3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>100</width> + <height>21</height> + </size> + </property> + </spacer> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer48_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>100</width> + <height>21</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QGroupBox" row="2" column="0"> + <property name="name"> + <cstring>groupBox7</cstring> + </property> + <property name="title"> + <string>Autostart</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="1" column="1"> + <property name="name"> + <cstring>cB_autostart_neverAsk</cstring> + </property> + <property name="text"> + <string>Never ask me again on exit</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>cB_autostart</cstring> + </property> + <property name="text"> + <string>KPowersave starts automatically on login</string> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer11</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>groupBox7_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>General Blacklists</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>pB_editAutosuspendGBlacklist</cstring> + </property> + <property name="text"> + <string>Edit Autosuspend Blacklist...</string> + </property> + </widget> + <spacer row="0" column="0"> + <property name="name"> + <cstring>spacer47</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>100</width> + <height>21</height> + </size> + </property> + </spacer> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer48</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>100</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>pB_editAutodimmGBlacklist</cstring> + </property> + <property name="text"> + <string>Edit Autodimm Blacklist...</string> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + </widget> + </grid> + </widget> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonApply</sender> + <signal>clicked()</signal> + <receiver>configure_Dialog</receiver> + <slot>buttonApply_clicked()</slot> + </connection> + <connection> + <sender>cB_specificSettings</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_specificSettings_toggled(bool)</slot> + </connection> + <connection> + <sender>cB_SpecificPM</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_SpecificPM_toggled(bool)</slot> + </connection> + <connection> + <sender>cB_disablePM</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_disablePM_toggled(bool)</slot> + </connection> + <connection> + <sender>cB_disable_Ss</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_disable_Ss_toggled(bool)</slot> + </connection> + <connection> + <sender>cB_specificSettings</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>cB_disable_Ss</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>cB_blankScreen</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>cB_SpecificPM</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>sB_standby</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>sB_suspend</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>sB_powerOff</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>cB_disablePM</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>configure_Dialog</receiver> + <slot>buttonOk_clicked()</slot> + </connection> + <connection> + <sender>listBox_schemes</sender> + <signal>currentChanged(QListBoxItem*)</signal> + <receiver>configure_Dialog</receiver> + <slot>listBox_schemes_currentChanged()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>configure_Dialog</receiver> + <slot>buttonCancel_clicked()</slot> + </connection> + <connection> + <sender>cB_Blacklist</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_Blacklist_toggled(bool)</slot> + </connection> + <connection> + <sender>cB_autoInactivity</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_autoInactivity_activated(int)</slot> + </connection> + <connection> + <sender>cB_autoSuspend</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_autoSuspend_toggled(bool)</slot> + </connection> + <connection> + <sender>sB_autoInactivity</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>cB_Brightness</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>cB_Brightness</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_Brightness_toggled(bool)</slot> + </connection> + <connection> + <sender>pB_resetBrightness</sender> + <signal>clicked()</signal> + <receiver>configure_Dialog</receiver> + <slot>pB_resetBrightness_clicked()</slot> + </connection> + <connection> + <sender>brightnessSlider</sender> + <signal>sliderMoved(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>brightnessSlider_sliderMoved(int)</slot> + </connection> + <connection> + <sender>cB_disableNotifications</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>sB_standby</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>sB_standby_valueChanged()</slot> + </connection> + <connection> + <sender>sB_suspend</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>sB_suspend_valueChanged()</slot> + </connection> + <connection> + <sender>sB_powerOff</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>sB_powerOff_valueChanged()</slot> + </connection> + <connection> + <sender>pB_newScheme</sender> + <signal>clicked()</signal> + <receiver>configure_Dialog</receiver> + <slot>pB_newScheme_clicked()</slot> + </connection> + <connection> + <sender>pB_deleteScheme</sender> + <signal>clicked()</signal> + <receiver>configure_Dialog</receiver> + <slot>pB_deleteScheme_clicked()</slot> + </connection> + <connection> + <sender>comboB_cpuFreq</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>cB_PowerButton</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>cB_LidcloseButton</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>cB_SleepButton</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>cB_S2DiskButton</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>cB_batWarning</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>cB_batLow</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>cB_batCritical</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>sB_batWarning</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>sB_batLow</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>sB_batCritical</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>cB_acScheme</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>cB_batteryScheme</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>comboB_lock</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>cB_lockSuspend</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>cB_lockLid</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>pB_configNotify</sender> + <signal>released()</signal> + <receiver>configure_Dialog</receiver> + <slot>pB_configNotify_released()</slot> + </connection> + <connection> + <sender>cB_autostart</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>cB_autostart_neverAsk</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>sB_batWarning</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>sB_batWarning_valueChanged()</slot> + </connection> + <connection> + <sender>sB_batLow</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>sB_batLow_valueChanged()</slot> + </connection> + <connection> + <sender>sB_batCritical</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>sB_batCritical_valueChanged()</slot> + </connection> + <connection> + <sender>sB_batWarnAction_value</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>sB_batLowAction_value</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>sB_batCritAction_value</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>general_valueChanged()</slot> + </connection> + <connection> + <sender>cB_batWarning</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_batWarning_activated()</slot> + </connection> + <connection> + <sender>cB_batLow</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_batLow_activated()</slot> + </connection> + <connection> + <sender>cB_batCritical</sender> + <signal>activated(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_batCritical_activated()</slot> + </connection> + <connection> + <sender>cB_autoDimm</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_autoDimm_toggled(bool)</slot> + </connection> + <connection> + <sender>sB_autoDimmTime</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>sB_autoDimmTo</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>scheme_valueChanged()</slot> + </connection> + <connection> + <sender>cB_BlacklistDimm</sender> + <signal>toggled(bool)</signal> + <receiver>configure_Dialog</receiver> + <slot>cB_BlacklistDimm_toggled(bool)</slot> + </connection> + <connection> + <sender>pB_editBlacklistDimm</sender> + <signal>clicked()</signal> + <receiver>configure_Dialog</receiver> + <slot>pB_editBlacklistDimm_clicked()</slot> + </connection> + <connection> + <sender>pB_editBlacklist</sender> + <signal>clicked()</signal> + <receiver>configure_Dialog</receiver> + <slot>pB_editBlacklistSuspend_clicked()</slot> + </connection> + <connection> + <sender>pB_editAutosuspendGBlacklist</sender> + <signal>clicked()</signal> + <receiver>configure_Dialog</receiver> + <slot>pB_editBlacklistSuspend_clicked()</slot> + </connection> + <connection> + <sender>pB_editAutodimmGBlacklist</sender> + <signal>clicked()</signal> + <receiver>configure_Dialog</receiver> + <slot>pB_editBlacklistDimm_clicked()</slot> + </connection> + <connection> + <sender>sB_autoDimmTime</sender> + <signal>valueChanged(int)</signal> + <receiver>configure_Dialog</receiver> + <slot>sB_autoDimmTime_valueChanged(int)</slot> + </connection> +</connections> +<tabstops> + <tabstop>tabWidget</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonApply</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>listBox_schemes</tabstop> + <tabstop>pB_newScheme</tabstop> + <tabstop>pB_deleteScheme</tabstop> + <tabstop>cB_specificSettings</tabstop> + <tabstop>cB_disable_Ss</tabstop> + <tabstop>cB_blankScreen</tabstop> + <tabstop>cB_SpecificPM</tabstop> + <tabstop>sB_standby</tabstop> + <tabstop>sB_suspend</tabstop> + <tabstop>sB_powerOff</tabstop> + <tabstop>cB_disablePM</tabstop> + <tabstop>cB_Brightness</tabstop> + <tabstop>brightnessSlider</tabstop> + <tabstop>pB_resetBrightness</tabstop> + <tabstop>cB_autoSuspend</tabstop> + <tabstop>cB_autoInactivity</tabstop> + <tabstop>sB_autoInactivity</tabstop> + <tabstop>cB_Blacklist</tabstop> + <tabstop>pB_editBlacklist</tabstop> + <tabstop>comboB_cpuFreq</tabstop> + <tabstop>cB_disableNotifications</tabstop> + <tabstop>sB_batWarning</tabstop> + <tabstop>sB_batLow</tabstop> + <tabstop>sB_batCritical</tabstop> + <tabstop>cB_batWarning</tabstop> + <tabstop>cB_batLow</tabstop> + <tabstop>cB_batCritical</tabstop> + <tabstop>sB_batWarnAction_value</tabstop> + <tabstop>sB_batLowAction_value</tabstop> + <tabstop>sB_batCritAction_value</tabstop> + <tabstop>cB_PowerButton</tabstop> + <tabstop>cB_LidcloseButton</tabstop> + <tabstop>cB_SleepButton</tabstop> + <tabstop>cB_S2DiskButton</tabstop> + <tabstop>cB_acScheme</tabstop> + <tabstop>cB_batteryScheme</tabstop> + <tabstop>cB_lockSuspend</tabstop> + <tabstop>cB_lockLid</tabstop> + <tabstop>comboB_lock</tabstop> + <tabstop>pB_editAutosuspendGBlacklist</tabstop> + <tabstop>pB_configNotify</tabstop> + <tabstop>cB_autostart</tabstop> + <tabstop>cB_autostart_neverAsk</tabstop> + <tabstop>buttonHelp</tabstop> +</tabstops> +<slots> + <slot>buttonApply_clicked()</slot> + <slot>cB_specificSettings_toggled( bool )</slot> + <slot>cB_SpecificPM_toggled( bool )</slot> + <slot>cB_disablePM_toggled( bool )</slot> + <slot>cB_disable_Ss_toggled( bool )</slot> + <slot>buttonOk_clicked()</slot> + <slot>listBox_schemes_currentChanged()</slot> + <slot>buttonCancel_clicked()</slot> + <slot>comboB_autoInactivity_activated( int )</slot> + <slot>cB_Blacklist_toggled( bool )</slot> + <slot>cB_autoInactivity_activated( int )</slot> + <slot>pB_editBlacklist_clicked()</slot> + <slot>cB_disableAutosuspendSound_toggled( bool )</slot> + <slot>cB_disableBatSound_toggled( bool )</slot> + <slot>cB_batWarning_toggled( bool )</slot> + <slot>cB_batLow_toggled( bool )</slot> + <slot>cB_batCritical_toggled( bool )</slot> + <slot>cB_autosuspendSound_toggled( bool )</slot> + <slot>pB_playWarning_released()</slot> + <slot>pB_playLow_released()</slot> + <slot>pB_playCritical_released()</slot> + <slot>pB_playAutosuspend_released()</slot> + <slot>pB_fileDialogWarning_released()</slot> + <slot>pB_fileDialogLow_released()</slot> + <slot>pB_fileDialogCritical_released()</slot> + <slot>pB_fileDialogAutosuspend_released()</slot> + <slot>cB_ACOutSound_toggled( bool )</slot> + <slot>cB_ACInSound_toggled( bool )</slot> + <slot>pB_playACOut_released()</slot> + <slot>pB_playACIn_released()</slot> + <slot>pB_fileDialogACOut_released()</slot> + <slot>pB_fileDialogACIn_released()</slot> + <slot>lE_path_textChanged()</slot> + <slot>cB_autoSuspend_toggled( bool )</slot> + <slot>buttonHelp_clicked()</slot> + <slot>cB_Brightness_toggled( bool )</slot> + <slot>brighnessSlider_valueChanged( int )</slot> + <slot>pB_testBrightness_clicked()</slot> + <slot>pB_resetBrightness_clicked()</slot> + <slot>brightnessSlider_valueChanged( int )</slot> + <slot>brightnessSlider_sliderMoved( int )</slot> + <slot>cB_disableNotifications_toggled( bool )</slot> + <slot>sB_standby_valueChanged()</slot> + <slot>sB_suspend_valueChanged()</slot> + <slot>sB_powerOff_valueChanged()</slot> + <slot>pB_newScheme_clicked()</slot> + <slot>pB_deleteScheme_clicked()</slot> + <slot>comboB_cpuFreq_activated( int )</slot> + <slot>scheme_valueChanged()</slot> + <slot>pB_configNotify_released()</slot> + <slot>sB_batWarning_valueChanged()</slot> + <slot>sB_batLow_valueChanged()</slot> + <slot>sB_batCritical_valueChanged()</slot> + <slot>general_valueChanged()</slot> + <slot>cB_batWarning_activated()</slot> + <slot>cB_batLow_activated()</slot> + <slot>cB_batCritical_activated()</slot> + <slot>cB_autoDimm_toggled( bool )</slot> + <slot>cB_BlacklistDimm_toggled( bool )</slot> + <slot>pB_editBlacklistDimm_clicked()</slot> + <slot>pB_editAutosuspendBlacklist_clicked()</slot> + <slot>pB_editBlacklistSuspend_clicked()</slot> + <slot>pB_editAutosuspendGBlacklist_released()</slot> + <slot>pB_editAutosuspendGBlacklist_clicked()</slot> + <slot>pB_editAutodimmGBlacklist_clicked()</slot> + <slot>sB_autoDimmTime_valueChanged( int )</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/configuredialog.cpp b/src/configuredialog.cpp new file mode 100644 index 0000000..196b26b --- /dev/null +++ b/src/configuredialog.cpp @@ -0,0 +1,1874 @@ +/*************************************************************************** + * Copyright (C) 2005 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! \file configuredialog.cpp + * All here displayed file members of configureDialog.cpp are related to operations with the + * configure dialog for kpowersave + * \brief In this file can be found all configure dialog related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2005 + */ + + // KDE - Headers + #include <kaudioplayer.h> + #include <kconfig.h> + #include <kiconloader.h> + #include <klocale.h> + #include <kmessagebox.h> + #include <kinputdialog.h> + #include <kaccelmanager.h> + + // QT - Headers + #include <qcheckbox.h> + #include <qcombobox.h> + #include <qdialog.h> + #include <qgroupbox.h> + #include <qlabel.h> + #include <qlineedit.h> + #include <qlistbox.h> + #include <qpushbutton.h> + #include <qslider.h> + #include <qspinbox.h> + #include <qstringlist.h> + #include <qtabwidget.h> + #include <qtoolbox.h> + #include <qtooltip.h> + #include <qstring.h> + + #include "configuredialog.h" + +/*! This is the default constructor of the class ConfigureDialog. */ +ConfigureDialog::ConfigureDialog( KConfig *_config, HardwareInfo *_hwinfo, Settings *_settings, + QWidget *parent, const char *name) + :configure_Dialog(parent, name, false, WDestructiveClose ) +{ + kdDebugFuncIn(trace); + + kconfig = _config; + settings = _settings; + hwinfo = _hwinfo; + suspend = hwinfo->getSuspendSupport(); + + QString session = getenv("DESKTOP_SESSION"); + if(session.startsWith("gnome")) gnome_session = true; + else gnome_session = false; + + initalised = false; + general_changed = false; + scheme_changed = false; + displayed_WARN_autosuspend = false; + + // check if brightness is supporte + if(hwinfo->supportBrightness()) { + brightnessLevels = hwinfo->getMaxBrightnessLevel() -1; + brightness_last = hwinfo->getCurrentBrightnessLevel(); + } else { + brightnessLevels = -1; + brightness_last = -1; + } + brightness_changed = false; + + currentScheme = -1; + + // get the correct available suspend types + SuspendStates suspend = hwinfo->getSuspendSupport(); + if( suspend.suspend2ram && (suspend.suspend2ram_allowed || suspend.suspend2ram_allowed == -1)) + actions.append("Suspend to RAM"); + if ( suspend.suspend2disk && (suspend.suspend2disk_allowed || suspend.suspend2disk_allowed == -1)) + actions.append("Suspend to Disk"); + if ( suspend.standby && (suspend.standby_allowed || suspend.standby_allowed == -1)) + actions.append("Standby"); + + setIcons(); + setTooltips(); + getSchemeList(); + setSchemeList(); + setGeneralSettings(); + setInactivityBox(); + selectScheme(settings->currentScheme); + + tL_valueBrightness->setFrameStyle(QFrame::Panel | QFrame::Sunken); + tL_valueBrightness->setBackgroundMode(Qt::PaletteBase); + tL_valueBrightness->setAlignment(Qt::AlignCenter); + tL_valueBrightness->setFocusPolicy(NoFocus); + + // hide Lid item if this is not a laptop + if (!hwinfo->isLaptop()) + cB_lockLid->hide(); + // hide CPU Freq page if not supported + if (!hwinfo->supportCPUFreq()) { + tB_scheme->setItemLabel( 4, tB_scheme->itemLabel(4) + i18n(" - not supported")); + tB_scheme->setItemEnabled( 4, false); + } + + if (!hwinfo->supportBrightness()) { + tB_scheme->setItemLabel( 3, tB_scheme->itemLabel(3) + i18n(" - not supported")); + tB_scheme->setItemEnabled( 3, false); + } + + initalised = true; + kdDebugFuncOut(trace); +} + +/*! This is the default destructor of the class ConfigureDialog. */ +ConfigureDialog::~ConfigureDialog(){ + kdDebugFuncIn(trace); + // no need to delete child widgets, Qt does it all for us +} + +/* ---- START General setup SECTION ---- */ + +/*! + * This used to fill the QListBox listBox_schemes and the scheme related QComboBoxes + * with the existing schemes. + */ +void ConfigureDialog::setSchemeList(){ + kdDebugFuncIn(trace); + + listBox_schemes->clear(); + cB_acScheme->clear(); + cB_batteryScheme->clear(); + + for ( QStringList::Iterator it = schemes.begin(); it != schemes.end(); ++it ) { + QString _tmp = *it; + if(_tmp == "Performance" || _tmp == i18n("Performance")) { + listBox_schemes->insertItem(SmallIcon("scheme_power", QIconSet::Automatic), i18n(_tmp)); + cB_acScheme->insertItem(i18n(_tmp)); + cB_batteryScheme->insertItem(i18n(_tmp)); + } else if(_tmp == "Powersave" || _tmp == i18n("Powersave")) { + listBox_schemes->insertItem(SmallIcon("scheme_powersave", QIconSet::Automatic), + i18n(_tmp)); + cB_acScheme->insertItem(i18n(_tmp)); + cB_batteryScheme->insertItem(i18n(_tmp)); + } else if(_tmp == "Presentation" || _tmp == i18n("Presentation")){ + listBox_schemes->insertItem(SmallIcon("scheme_presentation", QIconSet::Automatic), + i18n(_tmp)); + cB_acScheme->insertItem(i18n(_tmp)); + cB_batteryScheme->insertItem(i18n(_tmp)); + } else if(_tmp == "Acoustic" || _tmp == i18n("Acoustic")) { + listBox_schemes->insertItem(SmallIcon("scheme_acoustic", QIconSet::Automatic), + i18n(_tmp)); + cB_acScheme->insertItem(i18n(_tmp)); + cB_batteryScheme->insertItem(i18n(_tmp)); + } else if(_tmp == "AdvancedPowersave" || _tmp == i18n("Advanced Powersave")) { + listBox_schemes->insertItem(SmallIcon("scheme_advanced_powersave", + QIconSet::Automatic), i18n("Advanced Powersave")); + cB_acScheme->insertItem(i18n("Advanced Powersave")); + cB_batteryScheme->insertItem(i18n("Advanced Powersave")); + } else { + listBox_schemes->insertItem(i18n(_tmp)); + cB_acScheme->insertItem(i18n(_tmp)); + cB_batteryScheme->insertItem(i18n(_tmp)); + } + } + + KAcceleratorManager::manage(pB_newScheme); + kdDebugFuncOut(trace); +} + +/*! + * This used to get the list of schemes in from the config + */ +void ConfigureDialog::getSchemeList(){ + kdDebugFuncIn(trace); + + if (kconfig->hasGroup("General")) { + kconfig->setGroup("General"); + schemes = kconfig->readListEntry("schemes", ','); + } + + kdDebugFuncOut(trace); +} + +/*! + * This used to set the current scheme based on the name of the scheme + * \param _scheme QString with the name of the scheme + */ +void ConfigureDialog::selectScheme (QString _scheme){ + kdDebugFuncIn(trace); + + // select the current scheme in the listbox + if(!_scheme.isEmpty()) { + int pos = schemes.findIndex(_scheme); + if(pos > -1) { + listBox_schemes->setCurrentItem(pos); + currentScheme = pos; + } else { + listBox_schemes->setCurrentItem(0); + } + } else { + listBox_schemes->setCurrentItem(0); + } + + kdDebugFuncOut(trace); +} + +/*! + * This used to set all needed Icons for the dialog. + */ +void ConfigureDialog::setIcons(){ + kdDebugFuncIn(trace); + + /* set all Icons */ + this->setIcon(SmallIcon("kpowersave", QIconSet::Automatic)); + buttonApply->setIconSet(SmallIconSet("apply", QIconSet::Automatic)); + buttonCancel->setIconSet(SmallIconSet("cancel", QIconSet::Automatic)); + buttonOk->setIconSet(SmallIconSet("ok", QIconSet::Automatic)); + buttonHelp->setIconSet(SmallIconSet("help", QIconSet::Automatic)); + + pB_editBlacklist->setIconSet(SmallIconSet("configure", QIconSet::Automatic)); + pB_editBlacklistDimm->setIconSet(SmallIconSet("configure", QIconSet::Automatic)); + pB_editAutosuspendGBlacklist->setIconSet(SmallIconSet("configure", QIconSet::Automatic)); + pB_editAutodimmGBlacklist->setIconSet(SmallIconSet("configure", QIconSet::Automatic)); + + tB_scheme->setItemIconSet( 0 ,SmallIcon("kscreensaver", QIconSet::Automatic)); + tB_scheme->setItemIconSet( 1 ,SmallIcon("display", QIconSet::Automatic)); + + if(actions[0] == "Suspend to Disk") + tB_scheme->setItemIconSet( 2 ,SmallIcon("suspend_to_disk", QIconSet::Automatic)); + else if(actions[0] == "Suspend to RAM") + tB_scheme->setItemIconSet( 2 ,SmallIcon("suspend_to_ram", QIconSet::Automatic)); + else if(actions[0] == "Standby") + tB_scheme->setItemIconSet( 2 ,SmallIcon("stand_by", QIconSet::Automatic)); + + tB_scheme->setItemIconSet( 3 ,SmallIcon("autodimm", QIconSet::Automatic)); + tB_scheme->setItemIconSet( 4 ,SmallIcon("processor", QIconSet::Automatic)); + tB_scheme->setItemIconSet( 5 ,SmallIcon("misc", QIconSet::Automatic)); + + tB_general->setItemIconSet( 0, SmallIcon( "scheme_powersave", QIconSet::Automatic)); + tB_general->setItemIconSet( 1, SmallIcon( "button", QIconSet::Automatic)); + tB_general->setItemIconSet( 2, SmallIcon( "scheme_power", QIconSet::Automatic)); + tB_general->setItemIconSet( 3, SmallIcon( "lock", QIconSet::Automatic)); + tB_general->setItemIconSet( 4, SmallIcon( "misc", QIconSet::Automatic)); + pB_configNotify->setIconSet(SmallIconSet("knotify", QIconSet::Automatic)); + + kdDebugFuncOut(trace); +} + +/*! + * This used to set all needed Tooltips for the dialog. + */ +void ConfigureDialog::setTooltips(){ + kdDebugFuncIn(trace); + + // QToolTip::setWakeUpDelay ( 1000 ); + QToolTip::add(cB_specificSettings, i18n("This enables specific screen saver settings. \n" + "Note: If selected, the global screen saver settings are \n" + "overwritten while kpowersave runs.")); + QToolTip::add(cB_disable_Ss, i18n("This disables the screen saver. \n" + "Note: If selected, the global screen saver settings are \n" + "overwritten while kpowersave runs.")); + QToolTip::add(cB_blankScreen, i18n("This blanks the screen instead of using a specific screen saver. \n" + "Note: This may work only with KScreensaver.")); + QToolTip::add(cB_SpecificPM, i18n("This enables specific DPMS settings. \n" + "Note: If selected, the global DPMS settings are \n" + "overwritten while kpowersave runs.")); + QToolTip::add(cB_disablePM, i18n("This disables DPMS support.")); + QToolTip::add(cB_lockSuspend, i18n("If selected, the screen is locked on suspend or standby.")); + QToolTip::add(cB_lockLid, i18n("If selected, the screen is locked if the lid close event is triggered.")); + + QToolTip::add(cB_autoSuspend, i18n("Check this box to enable or disable automatic suspension of " + "the computer.")); + QToolTip::add(cB_autoInactivity, i18n("Activate this action if the user was inactive for the defined " + "time \n(greater than 0 minutes). If empty, nothing happens.")); + + tB_scheme->setItemToolTip ( 0, i18n("All scheme-related screen saver and DPMS settings.")); + tB_scheme->setItemToolTip ( 1, i18n("All scheme-related display brightness settings.")); + tB_scheme->setItemToolTip ( 2, i18n("All scheme-related automatic suspend settings.")); + + QToolTip::add(brightnessSlider, i18n("Here you can change the brightness of your display. \n" + "Use the slider to change the brightness directly for \n" + "testing. To reset back to previous level, please press \n" + "the 'Reset' button. ")); + QToolTip::add(pB_resetBrightness, i18n("Use this button to set back the slider and the " + "display brightness.")); + + kdDebugFuncOut(trace); +} + +/*! + * This function is used to get the real name of the predefined schemes. + * This is a workaround for the case if Yast translated the name of the + * scheme In this case is a new config section created and the old settings + * would be lost. + * \param s_scheme QString with the 'current' name of the scheme + * \return QString with the english name of the scheme + */ +QString ConfigureDialog::getSchemeRealName(QString s_scheme) { + kdDebugFuncIn(trace); + QString ret = s_scheme; + + if( s_scheme == "Performance" || s_scheme == i18n("Performance")) + ret = "Performance"; + else if( s_scheme == "Powersave" || s_scheme == i18n("Powersave")) + ret = "Powersave"; + else if( s_scheme == "Presentation" || s_scheme == i18n("Presentation")) + ret = "Presentation"; + else if( s_scheme == "Acoustic" || s_scheme == i18n("Acoustic")) + ret = "Acoustic"; + + kdDebugFuncOut(trace); + return ret; +} + +/*! + * This function is used to read the settings from configfile and + * set the values to the related dialog elements. + * \param schemeID Integer value, represent the position of the + * scheme in the QListBox and within the pdaemon-list. + */ +void ConfigureDialog::setConfigToDialog( int schemeID ){ + if (trace) kdDebug() << funcinfo << "IN , scheme: " << schemeID << endl; + + initalised = false; + + QString s_scheme = getSchemeRealName(schemes[schemeID]); + if (kconfig->hasGroup(s_scheme)){ + settings->load_general_settings(); + + // set the delete scheme button enabled if needed + if (!s_scheme.startsWith("Performance") && !s_scheme.startsWith("Powersave") && + !s_scheme.startsWith("Presentation") && !s_scheme.startsWith("Acoustic")) { + if (!s_scheme.startsWith(settings->ac_scheme) || + !s_scheme.startsWith(settings->battery_scheme)) { + // enable delete button + pB_deleteScheme->setEnabled( true ); + QToolTip::add(pB_deleteScheme, i18n("Press this button to delete the " + "selected scheme.")); + } else { + // disable button + pB_deleteScheme->setEnabled( false ); + QToolTip::add(pB_deleteScheme, i18n("You can't delete the current AC " + "or battery scheme.")); + } + } else { + // disable button, can't delete these scheme, they are default + pB_deleteScheme->setEnabled( false ); + QToolTip::add(pB_deleteScheme, i18n("You can't delete this default scheme.")); + } + + kconfig->setGroup(s_scheme); + } + // no configuration found, set to default values ?! + else { + if(kconfig->hasGroup("default-scheme")) + kconfig->setGroup("default-scheme"); + else { + kdDebugFuncOut(trace); + return; + } + } + + cB_disable_Ss_toggled(kconfig->readBoolEntry("disableSs",false)); + cB_blankScreen->setChecked(kconfig->readBoolEntry("blankSs",false)); + cB_specificSettings_toggled(kconfig->readBoolEntry("specSsSettings",false)); + + int i_standby = kconfig->readNumEntry("standbyAfter", -1); + if(i_standby >= 0) { + sB_standby->setValue(i_standby); + } + else { + // load value from default-scheme + if(kconfig->hasGroup("default-scheme")){ + kconfig->setGroup("default-scheme"); + i_standby = kconfig->readNumEntry("standbyAfter", -1); + if(i_standby >= 0) { + sB_standby->setValue(i_standby); + } + else sB_standby->setValue(0); + } + else{ + sB_standby->setValue(0); + } + // reset group to selected scheme + if (kconfig->hasGroup(s_scheme)) kconfig->setGroup(s_scheme); + else kconfig->setGroup("default-scheme"); + } + + int i_suspend = kconfig->readNumEntry("suspendAfter", -1); + if(i_suspend >= 0) { + sB_suspend->setValue(i_suspend); + } + else { + // load value from default-scheme + if(kconfig->hasGroup("default-scheme")){ + kconfig->setGroup("default-scheme"); + i_standby = kconfig->readNumEntry("suspendAfter", -1); + if(i_standby >= 0) { + sB_standby->setValue(i_standby); + } + else sB_standby->setValue(0); + } + else{ + sB_standby->setValue(0); + } + // reset group to selected scheme + if (kconfig->hasGroup(s_scheme)) kconfig->setGroup(s_scheme); + else kconfig->setGroup("default-scheme"); + } + + int i_poweroff = kconfig->readNumEntry("powerOffAfter", -1); + if(i_poweroff >= 0) { + sB_powerOff->setValue(i_poweroff); + } + else { + // load value from default-scheme + if(kconfig->hasGroup("default-scheme")){ + kconfig->setGroup("default-scheme"); + i_standby = kconfig->readNumEntry("powerOffAfter", -1); + if(i_poweroff >= 0) { + sB_powerOff->setValue(i_poweroff); + } + else sB_powerOff->setValue(0); + } + else{ + sB_powerOff->setValue(0); + } + // reset group to selected scheme + if (kconfig->hasGroup(s_scheme)) kconfig->setGroup(s_scheme); + else kconfig->setGroup("default-scheme"); + } + + cB_SpecificPM_toggled(kconfig->readBoolEntry("specPMSettings",false)); + cB_disablePM_toggled(kconfig->readBoolEntry("disableDPMS",false)); + + // set autosuspend related settings + QString _action = kconfig->readEntry("autoInactiveAction", "NULL"); + if( _action != "NULL") { + int _index = actions.findIndex(_action); + if( _index != -1) { + cB_autoInactivity->setCurrentItem( _index ); + cB_autoInactivity_activated( _index ); + cB_Blacklist->setEnabled(true); + } + else { + // set to empty element if not supported by current machine or + // if the value is "_NONE_" + cB_autoInactivity->setCurrentItem( 0 ); + cB_autoInactivity_activated( 0 ); + cB_Blacklist->setEnabled(false); + } + } + else { + // set to disabled (to reduce code), if a entry found set to enabled ! + cB_Blacklist->setEnabled(false); + + if(kconfig->hasGroup("default-scheme")){ + kconfig->setGroup("default-scheme"); + _action = kconfig->readEntry("autoInactiveAction", "NULL"); + if(_action != "NULL") { + int _index = actions.findIndex(_action); + if( _index != -1) { + cB_autoInactivity->setCurrentItem( _index ); + tL_autoInactivity_After->setEnabled(true); + cB_Blacklist->setEnabled(true); + } + else { + cB_autoInactivity->setCurrentItem( 0 ); + } + } + else { + cB_autoInactivity->setCurrentItem( 0 ); + } + // reset group to selected scheme + if (kconfig->hasGroup(s_scheme)) kconfig->setGroup(s_scheme); + else kconfig->setGroup("default-scheme"); + } + else{ + cB_autoInactivity->setCurrentItem( 0 ); + } + } + if( cB_autoInactivity->currentItem() == 0 ) { + sB_autoInactivity->setEnabled(false); + tL_autoInactivity_After->setEnabled(false); + } + + int i_autoInactivityAfter = kconfig->readNumEntry("autoInactiveActionAfter", -1); + if(i_autoInactivityAfter >= 0) { + sB_autoInactivity->setValue(i_autoInactivityAfter); + } + else { + // load value from default-scheme + if(kconfig->hasGroup("default-scheme")){ + kconfig->setGroup("default-scheme"); + i_autoInactivityAfter = kconfig->readNumEntry("autoInactiveActionAfter", -1); + if(i_autoInactivityAfter >= 0) { + sB_autoInactivity->setValue(i_autoInactivityAfter); + } + else sB_autoInactivity->setValue(0); + } + else{ + sB_autoInactivity->setValue(0); + } + // reset group to selected scheme + if (kconfig->hasGroup(s_scheme)) kconfig->setGroup(s_scheme); + else kconfig->setGroup("default-scheme"); + } + + if (hwinfo->supportBrightness()) { + // enable the widgets + cB_Brightness->setEnabled(true); + cB_Brightness_toggled(kconfig->readBoolEntry("enableBrightness",false)); + + if (brightnessLevels > 33) + brightnessSlider->setLineStep(3); + else + brightnessSlider->setLineStep(100/brightnessLevels); + + brightnessSlider->setPageStep(10); + + int i_brightnessPercent = kconfig->readNumEntry("brightnessPercent", -1); + if(i_brightnessPercent >= 0) { + brightnessSlider->setValue(i_brightnessPercent); + tL_valueBrightness->setText(QString::number(i_brightnessPercent) + " %"); + } + else { + brightnessSlider->setValue(100); + tL_valueBrightness->setText(QString::number(100)+ " %"); + } + + tL_brightness->setText(i18n("Your hardware supports to change the brightness. The " + "values of the slider are in percent and mapped " + "to the available brightness levels of your hardware.")); + } + else { + cB_Brightness->setEnabled(false); + gB_Brightness->setEnabled(false); + tL_brightness->setText(i18n("Your Hardware currently not support changing the brightness " + "of your display.")); + } + + // no need to enable autodimm if not support change brightness + if (hwinfo->supportBrightness()) { + int i_autoDimmAfter = kconfig->readNumEntry("autoDimmAfter", -1); + if(i_autoDimmAfter >= 0) { + sB_autoDimmTime->setValue(i_autoDimmAfter); + } + else { + // load value from default-scheme + if(kconfig->hasGroup("default-scheme")){ + kconfig->setGroup("default-scheme"); + i_autoDimmAfter = kconfig->readNumEntry("autoDimmAfter", -1); + if(i_autoDimmAfter >= 0) { + sB_autoDimmTime->setValue(i_autoDimmAfter); + } + else sB_autoDimmTime->setValue(0); + } + else{ + sB_autoDimmTime->setValue(0); + } + // reset group to selected scheme + if (kconfig->hasGroup(s_scheme)) kconfig->setGroup(s_scheme); + else kconfig->setGroup("default-scheme"); + } + + int i_autoDimmTo = kconfig->readNumEntry("autoDimmTo", -1); + if(i_autoDimmTo >= 0) { + sB_autoDimmTo->setValue(i_autoDimmTo); + } + else { + // load value from default-scheme + if(kconfig->hasGroup("default-scheme")){ + kconfig->setGroup("default-scheme"); + i_autoDimmTo = kconfig->readNumEntry("autoDimmTo", -1); + if(i_autoDimmAfter >= 0) { + sB_autoDimmTo->setValue(i_autoDimmTo); + } + else sB_autoDimmTo->setValue(0); + } + else{ + sB_autoDimmTo->setValue(0); + } + // reset group to selected scheme + if (kconfig->hasGroup(s_scheme)) kconfig->setGroup(s_scheme); + else kconfig->setGroup("default-scheme"); + } + } + + if (hwinfo->supportCPUFreq()) { + QString cpuFreqPolicy = kconfig->readEntry("cpuFreqPolicy"); + + if (cpuFreqPolicy.isEmpty()) { + // load value from default-scheme + if(kconfig->hasGroup("default-scheme")){ + kconfig->setGroup("default-scheme"); + cpuFreqPolicy = kconfig->readEntry("cpuFreqPolicy"); + } + if (cpuFreqPolicy.isEmpty()) { + cpuFreqPolicy = "DYNAMIC"; + } + // reset group to selected scheme + if (kconfig->hasGroup(s_scheme)) kconfig->setGroup(s_scheme); + else kconfig->setGroup("default-scheme"); + } + + if (cpuFreqPolicy.startsWith("PERFORMANCE")) { + comboB_cpuFreq->setCurrentItem(0); + } else if (cpuFreqPolicy.startsWith("DYNAMIC")) { + comboB_cpuFreq->setCurrentItem(1); + } else if (cpuFreqPolicy.startsWith("POWERSAVE")) { + comboB_cpuFreq->setCurrentItem(2); + } else { + kdWarning() << "Could not read/map CPU Freq Policy, set to dynamic" << endl; + comboB_cpuFreq->setCurrentItem(1); + } + } + + cB_disableNotifications->setChecked(kconfig->readBoolEntry("disableNotifications",false)); + + cB_Blacklist_toggled(kconfig->readBoolEntry("autoInactiveSchemeBlacklistEnabled",false)); + cB_autoSuspend_toggled(kconfig->readBoolEntry("autoSuspend",false)); + cB_BlacklistDimm_toggled(kconfig->readBoolEntry("autoDimmSchemeBlacklistEnabled",false)); + cB_autoDimm_toggled(kconfig->readBoolEntry("autoDimm",false)); + + initalised = true; + scheme_changed = false; + if(!general_changed) buttonApply->setEnabled(false); + currentScheme = schemeID; + + kdDebugFuncOut(trace); +} + +/*! + * This is used to set the values from the section general in configfile to the + * related items in the dialog. + */ +void ConfigureDialog::setGeneralSettings() { + kdDebugFuncIn(trace); + + kconfig->setGroup("General"); + + cB_lockSuspend->setChecked(kconfig->readBoolEntry("lockOnSuspend",false)); + cB_lockLid->setChecked(kconfig->readBoolEntry("lockOnLidClose",false)); + cB_autostart->setChecked(kconfig->readBoolEntry("Autostart",false)); + cB_autostart_neverAsk->setChecked(kconfig->readBoolEntry("AutostartNeverAsk",false)); + + QString lockmethod = kconfig->readEntry("lockMethod", "NULL"); + if(comboB_lock->count() == 0 ){ + comboB_lock->insertItem(i18n("Select Automatically"),0); + comboB_lock->insertItem(i18n("KScreensaver"),1); + comboB_lock->insertItem(i18n("XScreensaver"),2); + comboB_lock->insertItem(i18n("xlock"),3); + if (gnome_session) comboB_lock->insertItem(i18n("GNOME Screensaver"),4); + } + + if (lockmethod == "automatic") comboB_lock->setCurrentItem(0); + else if (lockmethod == "kscreensaver") comboB_lock->setCurrentItem(1); + else if (lockmethod == "xscreensaver") comboB_lock->setCurrentItem(2); + else if (lockmethod == "xlock") comboB_lock->setCurrentItem(3); + else if (gnome_session && (lockmethod == "gnomescreensaver")) comboB_lock->setCurrentItem(4); + else comboB_lock->setCurrentItem(0); + + if(cB_lockSuspend->isOn() || cB_lockLid->isOn() ) { + tL_lockWith->setEnabled(true); + comboB_lock->setEnabled(true); + } + else { + tL_lockWith->setEnabled(false); + comboB_lock->setEnabled(false); + } + + // battery tab + BatteryCollection* _primBats = hwinfo->getPrimaryBatteries(); + if (_primBats->getNumBatteries() > 0) { + // set widgets in the tab + sB_batWarning->setValue(kconfig->readNumEntry("batteryWarning",0)); + sB_batLow->setValue(kconfig->readNumEntry("batteryLow",0)); + sB_batCritical->setValue(kconfig->readNumEntry("batteryCritical",0)); + // hide them and enable only if needed + sB_batWarnAction_value->hide(); + sB_batLowAction_value->hide(); + sB_batCritAction_value->hide(); + + QString _select; + QStringList _actions = kconfig->readListEntry("batteryAllowedActions", QString()); + _select = kconfig->readEntry("batteryWarningAction", QString()); + fillActionComboBox(cB_batWarning, _actions, _select); + if (_select == "BRIGHTNESS" && hwinfo->supportBrightness()) { + sB_batWarnAction_value->show(); + sB_batWarnAction_value->setValue(kconfig->readNumEntry( "batteryWarningActionValue",0)); + } + _select = kconfig->readEntry("batteryLowAction", QString()); + fillActionComboBox(cB_batLow, _actions, _select); + if (_select == "BRIGHTNESS" && hwinfo->supportBrightness()) { + sB_batLowAction_value->show(); + sB_batLowAction_value->setValue( kconfig->readNumEntry( "batteryLowActionValue",0)); + } + _select = kconfig->readEntry("batteryCriticalAction", QString()); + fillActionComboBox(cB_batCritical, _actions, _select); + if (_select == "BRIGHTNESS" && hwinfo->supportBrightness()) { + sB_batCritAction_value->show(); + sB_batCritAction_value->setValue(kconfig->readNumEntry("batteryCriticalActionValue",0)); + } + } else { + // disable tab + tB_general->setItemLabel( 0, tB_scheme->itemLabel(0) + i18n(" - not supported")); + tB_general->setItemEnabled( 0, false); + } + + // buttons tab: + QStringList _actions = kconfig->readListEntry("buttonsAllowedActions", QString()); + fillActionComboBox(cB_PowerButton, _actions, kconfig->readEntry("ActionOnPowerButton", QString())); + fillActionComboBox(cB_SleepButton, _actions, kconfig->readEntry("ActionOnSleepButton", QString())); + fillActionComboBox(cB_S2DiskButton, _actions, kconfig->readEntry("ActionOnS2DiskButton", QString())); + // avoid logout dialog for lidclose - this make no sense + _actions.remove("LOGOUT_DIALOG"); + fillActionComboBox(cB_LidcloseButton, _actions, kconfig->readEntry("ActionOnLidClose", QString())); + + // default scheme tab: + QString _ac_scheme = kconfig->readEntry( "ac_scheme", "Performance"); + QString _bat_scheme = kconfig->readEntry( "battery_scheme", "Powersave"); + cB_acScheme->setCurrentItem(schemes.findIndex(_ac_scheme)); + cB_batteryScheme->setCurrentItem(schemes.findIndex(_bat_scheme)); + + kdDebugFuncOut(trace); +} + +/* ---- END General setup SECTION ---- */ + +/* ---- START store settings SECTION ---- */ + +/*! + * This used to save changes in settings of the current scheme. + */ +void ConfigureDialog::saveSchemeSettings() { + kdDebugFuncIn(trace); + + QString s_scheme = getSchemeRealName(schemes[currentScheme]); + kconfig->setGroup(s_scheme); + + kconfig->writeEntry("specSsSettings",cB_specificSettings->isOn()); + kconfig->writeEntry("disableSs",cB_disable_Ss->isOn()); + kconfig->writeEntry("blankSs",cB_blankScreen->isOn()); + kconfig->writeEntry("specPMSettings",cB_SpecificPM->isOn()); + kconfig->writeEntry("disableDPMS",cB_disablePM->isOn()); + + kconfig->writeEntry("standbyAfter",sB_standby->value()); + kconfig->writeEntry("suspendAfter",sB_suspend->value()); + kconfig->writeEntry("powerOffAfter",sB_powerOff->value()); + + kconfig->writeEntry("disableNotifications",cB_disableNotifications->isOn()); + + if(cB_autoInactivity->currentText() == " "){ + kconfig->writeEntry("autoInactiveAction", "_NONE_"); + } + else{ + int _index = cB_autoInactivity->currentItem(); + if(_index > 0) { + /*if(_index == (cB_autoInactivity->count()-1)) { + kconfig->writeEntry("autoInactiveAction","shutdown"); + } + else { + kconfig->writeEntry("autoInactiveAction",actions[(_index)]); + }*/ + kconfig->writeEntry("autoInactiveAction",actions[(_index)]); + } + kconfig->writeEntry("autoInactiveActionAfter",sB_autoInactivity->value()); + } + kconfig->writeEntry("autoSuspend",cB_autoSuspend->isOn()); + kconfig->writeEntry("autoInactiveSchemeBlacklistEnabled",cB_Blacklist->isOn()); + + kconfig->writeEntry("autoDimm",cB_autoDimm->isOn()); + kconfig->writeEntry("autoDimmAfter", sB_autoDimmTime->value()); + kconfig->writeEntry("autoDimmTo", sB_autoDimmTo->value()); + kconfig->writeEntry("autoDimmSchemeBlacklistEnabled",cB_BlacklistDimm->isOn()); + + kconfig->writeEntry("enableBrightness",cB_Brightness->isOn()); + if(brightness_changed) + kconfig->writeEntry("brightnessPercent",brightnessSlider->value()); + + + if(hwinfo->supportCPUFreq()) { + switch( comboB_cpuFreq->currentItem()) { + case 0: + kconfig->writeEntry("cpuFreqPolicy", "PERFORMANCE"); + break; + case 2: + kconfig->writeEntry("cpuFreqPolicy", "POWERSAVE"); + break; + case 1: + default: + kconfig->writeEntry("cpuFreqPolicy", "DYNAMIC"); + break; + } + } + + kconfig->sync(); + scheme_changed = false; + if(!general_changed) buttonApply->setEnabled(false); + + kdDebugFuncOut(trace); +} + +/*! + * This used to save changes in settings of the current scheme. + */ +void ConfigureDialog::saveGeneralSettings() { + kdDebugFuncIn(trace); + + kconfig->setGroup("General"); + + kconfig->writeEntry("lockOnSuspend",cB_lockSuspend->isOn()); + kconfig->writeEntry("lockOnLidClose",cB_lockLid->isOn()); + kconfig->writeEntry("Autostart",cB_autostart->isOn()); + kconfig->writeEntry("AutostartNeverAsk",cB_autostart_neverAsk->isOn()); + + QString selected_method = ""; + int _selected = comboB_lock->currentItem(); + if(_selected == 0) selected_method = "automatic"; + else if(_selected == 1) selected_method = "kscreensaver"; + else if(_selected == 2) selected_method = "xscreensaver"; + else if(_selected == 3) selected_method = "xlock"; + else if(gnome_session && (_selected == 4)) selected_method = "gnomescreensaver"; + kconfig->writeEntry( "lockMethod", selected_method ); + + kconfig->writeEntry("batteryWarning", sB_batWarning->value()); + kconfig->writeEntry("batteryLow", sB_batLow->value()); + kconfig->writeEntry("batteryCritical", sB_batCritical->value()); + + // battery level tab + QString _action = mapDescriptionToAction(cB_batWarning->currentText()); + kconfig->writeEntry("batteryWarningAction", _action); + if (_action == "BRIGHTNESS") { + kconfig->writeEntry("batteryWarningActionValue", sB_batWarnAction_value->value()); + } + _action = mapDescriptionToAction(cB_batLow->currentText()); + kconfig->writeEntry("batteryLowAction", _action); + if (_action == "BRIGHTNESS") { + kconfig->writeEntry("batteryLowActionValue", sB_batLowAction_value->value()); + } + _action = mapDescriptionToAction(cB_batCritical->currentText()); + kconfig->writeEntry("batteryCriticalAction", _action); + if (_action == "BRIGHTNESS") { + kconfig->writeEntry("batteryCriticalActionValue", sB_batCritAction_value->value()); + } + + // button tab + kconfig->writeEntry("ActionOnPowerButton", mapDescriptionToAction(cB_PowerButton->currentText())); + kconfig->writeEntry("ActionOnLidClose", mapDescriptionToAction(cB_LidcloseButton->currentText())); + kconfig->writeEntry("ActionOnSleepButton", mapDescriptionToAction(cB_SleepButton->currentText())); + kconfig->writeEntry("ActionOnS2DiskButton", mapDescriptionToAction(cB_S2DiskButton->currentText())); + + // schemes tab + kconfig->writeEntry("ac_scheme", getSchemeRealName(schemes[cB_acScheme->currentItem()])); + kconfig->writeEntry("battery_scheme", getSchemeRealName(schemes[cB_batteryScheme->currentItem()])); + + kconfig->sync(); + general_changed = false; + if(!scheme_changed) buttonApply->setEnabled(false); + + kdDebugFuncOut(trace); +} + +/* ---- END store settings SECTION ---- */ + +/* ---- START monitor changes SECTION ---- */ + +/*! + * SLOT: Called if a value within the Tab 'General Settings' is changed. + */ +void ConfigureDialog::general_valueChanged(){ + kdDebugFuncIn(trace); + + if(initalised) { + general_changed = true; + buttonApply->setEnabled(true); + // enable/disable the comboB_lock and tL_lockWith + if(cB_lockSuspend->isOn() || cB_lockLid->isOn() ) { + tL_lockWith->setEnabled(true); + comboB_lock->setEnabled(true); + } + else { + tL_lockWith->setEnabled(false); + comboB_lock->setEnabled(false); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: Called if a value within the Tab 'Scheme Settings' is changed. + */ +void ConfigureDialog::scheme_valueChanged(){ + kdDebugFuncIn(trace); + + if(initalised) { + scheme_changed = true; + buttonApply->setEnabled(true); + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if the current scheme in the QListBox listBox_schemes is + * changed/ a other scheme was selected. + */ +void ConfigureDialog::listBox_schemes_currentChanged(){ + kdDebugFuncIn(trace); + + // store current settings if something changed + if(initalised && scheme_changed ) { + int res = KMessageBox::warningYesNo(this, + i18n("There are unsaved changes in the active scheme.\n" + "Apply the changes before jumping to the next scheme " + "or discard the changes?"), + i18n("Unsaved Changes"), KStdGuiItem::apply(), + KStdGuiItem::discard()); + + if (res == KMessageBox::Yes) { + // Save changes + saveSchemeSettings(); + } + if (res == KMessageBox::No) { + // discard changes and reset trigger + scheme_changed = false; + } + } + // set to new Item + setConfigToDialog(listBox_schemes->currentItem()); + + kdDebugFuncOut(trace); +} + +/* ---- END monitor changes SECTION ---- */ + +/* ---- START BUTTON SECTION ---- */ + +/*! + * SLOT: called if the 'Apply' button is clicked. + */ +void ConfigureDialog::buttonApply_clicked(){ + kdDebugFuncIn(trace); + + if(initalised && scheme_changed ) { + saveSchemeSettings(); + scheme_changed = false; + } + if(initalised && general_changed ) { + saveGeneralSettings(); + general_changed = false; + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if the 'Chancel' button is clicked. + */ +void ConfigureDialog::buttonCancel_clicked(){ + kdDebugFuncOut(trace); + + if (scheme_changed || general_changed) { + int res = KMessageBox::warningYesNoCancel(this, + i18n("There are unsaved changes.\nApply the changes " + "before cancel or discard the changes?"), + i18n("Unsaved Changes"), KStdGuiItem::apply(), + KStdGuiItem::discard()); + if (res == KMessageBox::Yes) { + buttonApply_clicked(); + } + else if (res == KMessageBox::Cancel) return; + } + + kdDebugFuncOut(trace); + close(); +} + +/*! + * SLOT: called if the 'OK' button is clicked. + */ +void ConfigureDialog::buttonOk_clicked(){ + kdDebugFuncIn(trace); + + buttonApply_clicked(); + buttonApply->setEnabled(false); + + kdDebugFuncOut(trace); + close(); +} + +/*! + * SLOT: called if the 'Help' button is clicked. + */ +void ConfigureDialog::buttonHelp_clicked(){ + kdDebugFuncIn(trace); + + emit openHelp(); + + kdDebugFuncOut(trace); +} + +/* ---- END BUTTON SECTION ---- */ + +/* ---- START SCHEME ADD/DELETE SECTION ---- */ + +/*! + * SLOT: called if the 'New' scheme button is clicked. + */ +void ConfigureDialog::pB_newScheme_clicked(){ + kdDebugFuncIn(trace); + + bool _ok = false; + bool _end = false; + QString _new; + QString _text = i18n("Please insert a name for the new scheme:"); + QString _error; + + getSchemeList(); + + while (!_end) { + _new = KInputDialog::getText( i18n("KPowersave Configuration"), + _error + _text, QString::null, &_ok, this); + if (!_ok ) { + _end = true; + } else { + _error = QString(); + if (!_new.isEmpty()) { + if ( schemes.contains(_new)) + _error = i18n("Error: A scheme with this name already exist.\n"); + else + _end = true; + } + } + } + + if (!_new.isEmpty()) { + // write append new scheme to list + schemes.append(_new); + kconfig->setGroup("General"); + kconfig->writeEntry("schemes", schemes, ","); + kconfig->sync(); + + // update GUI + setSchemeList(); + selectScheme(_new); + saveSchemeSettings(); + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if the 'Delete' scheme button is clicked. + */ +void ConfigureDialog::pB_deleteScheme_clicked(){ + kdDebugFuncIn(trace); + + if (pB_deleteScheme->isEnabled()) { + int answer = KMessageBox::questionYesNo( this, i18n("Do you really want to delete the " + "%1 scheme?").arg(schemes[currentScheme]), + i18n("Confirm delete scheme"), + i18n("Delete"), i18n("Cancel")); + if (answer == KMessageBox::Yes) { + // delete the scheme, we can be sure this is a userscheme + QString _s_tmp = getSchemeRealName(schemes[currentScheme]); + if (kconfig->hasGroup(_s_tmp) && kconfig->deleteGroup(_s_tmp)) { + schemes.remove(_s_tmp); + kconfig->setGroup("General"); + kconfig->writeEntry("schemes", schemes, ","); + kconfig->sync(); + + // update GUI + setSchemeList(); + selectScheme(settings->currentScheme); + } else { + // could not delete the scheme ... error case + KMessageBox::queuedMessageBox(this, KMessageBox::Error, + i18n("Could not delete the selected scheme.")); + } + } + } + + kdDebugFuncOut(trace); +} + +/* ---- END SCHEME ADD/DELETE SECTION ---- */ + +/* ---- START SCREENSAVER SECTION ---- */ + +/*! + * SLOT: called if QCheckBox cB_specificSettings is toggled. + * \param state boolean, true if toggled on + * false if toggled off + */ +void ConfigureDialog::cB_specificSettings_toggled(bool state){ + kdDebugFuncIn(trace); + + if(!initalised) cB_specificSettings->setChecked(state); + + /* set widgets visible/disabled */ + if(state){ + cB_disable_Ss->setEnabled(true); + if(cB_disable_Ss->isOn()){ + cB_blankScreen->setEnabled(false); + } + else { + cB_blankScreen->setEnabled(true); + } + } + else { + cB_disable_Ss->setEnabled(false); + cB_blankScreen->setEnabled(false); + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if QCheckBox cB_disable_Ss is toggled. + * \param state boolean, true if toggled on + * false if toggled off + */ +void ConfigureDialog::cB_disable_Ss_toggled(bool state){ + kdDebugFuncIn(trace); + + /* set widgets visible/disabled */ + if(!initalised) cB_disable_Ss->setChecked(state); + cB_blankScreen->setEnabled(!state); + + kdDebugFuncOut(trace); +} + + +/* ---- END SCREENSAVER SECTION ---- */ + +/* ---- START DPMS SECTION ---- */ + +/*! + * SLOT: called if QCheckBox cB_SpecificPM is toggled. + * \param state boolean, true if toggled on + * false if toggled offtrue + */ +void ConfigureDialog::cB_SpecificPM_toggled(bool state){ + kdDebugFuncIn(trace); + + if(!initalised) cB_SpecificPM->setChecked(state); + + /* set widgets visible/disabled */ + cB_disablePM->setEnabled(state); + if(cB_disablePM->isOn()) { + state = false; + } + tL_standbyAfter->setEnabled(state); + sB_standby->setEnabled(state); + tL_suspendAfter->setEnabled(state); + sB_suspend->setEnabled(state); + tL_powerOffAfter->setEnabled(state); + sB_powerOff->setEnabled(state); + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if QCheckBox cB_disablePM is toggled. + * \param state boolean, true if toggled on + * false if toggled off + */ +void ConfigureDialog::cB_disablePM_toggled(bool state){ + kdDebugFuncIn(trace); + + if(!initalised) cB_disablePM->setChecked(state); + + /* set widgets visible/disabled */ + tL_standbyAfter->setEnabled(!state); + sB_standby->setEnabled(!state); + tL_suspendAfter->setEnabled(!state); + sB_suspend->setEnabled(!state); + tL_powerOffAfter->setEnabled(!state); + sB_powerOff->setEnabled(!state); + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if the standby QSpinBoxes for DPMS timout is changed. + */ +void ConfigureDialog::sB_standby_valueChanged() { + kdDebugFuncIn(trace); + + if (initalised) { + if (sB_standby->value() == 0 ) + return; + if ( sB_standby->value() > sB_suspend->value()) { + sB_suspend->setValue(sB_standby->value()); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if the suspend QSpinBoxes for DPMS timout is changed. + */ +void ConfigureDialog::sB_suspend_valueChanged() { + kdDebugFuncIn(trace); + + if (initalised) { + if (sB_suspend->value() == 0 ) + return; + + if ( sB_suspend->value() < sB_standby->value()) { + sB_standby->setValue(sB_suspend->value()); + } + if ( sB_suspend->value() > sB_powerOff->value()) { + sB_powerOff->setValue(sB_suspend->value()); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if the powerOff QSpinBoxes for DPMS timout is changed. + */ +void ConfigureDialog::sB_powerOff_valueChanged() { + kdDebugFuncIn(trace); + + if (initalised) { + if (sB_powerOff->value() == 0 ) + return; + if ( sB_powerOff->value() < sB_suspend->value()) { + sB_suspend->setValue(sB_powerOff->value()); + } + } + + kdDebugFuncOut(trace); +} + +/* ---- END DPMS SECTION ---- */ + +/* ---- START Inactivity SECTION ---- */ + +/*! + * This used to set the inactivity related combobox cB_autoInactivity . + */ +void ConfigureDialog::setInactivityBox(){ + kdDebugFuncIn(trace); + + cB_autoInactivity->clear(); + // add "nothing" at start of the list + actions.push_front(" "); + // add "Turn Off Computer" at end of the list + // QString _to_i18n = i18n("Turn Off Computer"); + // actions.append("Turn Off Computer"); + + for ( QStringList::Iterator it = actions.begin(); it != actions.end(); ++it ) { + cB_autoInactivity->insertItem( i18n( *it ) ); + } + + kdDebugFuncOut(trace); +} + +/*! + * This used to set the autosuspend related widgets. + */ +void ConfigureDialog::cB_autoSuspend_toggled( bool toggled ) { + kdDebugFuncIn(trace); + + if(cB_autoSuspend->isOn() != toggled) + cB_autoSuspend->setChecked(toggled); + + tL_autoInactivity_explain->setEnabled(toggled); + cB_autoInactivity->setEnabled(toggled); + if(cB_autoInactivity->currentItem() > 0) { + cB_autoInactivity->setEnabled(true); + tL_autoInactivity_After->setEnabled(true); + sB_autoInactivity->setEnabled(true); + cB_Blacklist->setEnabled(true); + cB_Blacklist_toggled(cB_Blacklist->isOn()); + } + + if(!toggled) { + cB_autoSuspend->setChecked(false); + tL_autoInactivity_After->setEnabled(false); + cB_autoInactivity->setEnabled(false); + sB_autoInactivity->setEnabled(false); + cB_Blacklist->setEnabled(false); + pB_editBlacklist->setEnabled(false); + } + + scheme_changed = true; + buttonApply->setEnabled(true); + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if a new item in cB_autoInactivity is selected. + * \param selectedItem Integer, contains the ID of the new item in the + * comboBox. + */ +void ConfigureDialog::cB_autoInactivity_activated( int selectedItem ) { + kdDebugFuncIn(trace); + + if( actions[selectedItem] != " " ) { + if(!displayed_WARN_autosuspend && initalised) { + QString _msg = "<qt>" + i18n("<b>Note:</b> If you select this option, the computer " + "will suspend or standby if the current user is " + "inactive for the defined time even if somebody is " + "logged in remotely to the X server.<br><br> This " + "feature can also produce problems with some programs, " + "such as video players or cd burner. These programs can " + "be blacklisted by checking <b>Enable scheme-specific " + "blacklist</b> and click <b>Edit Blacklist...</b>. If " + "this does not help, report the problem or deactivate " + "autosuspend.<br><br> Really use this option?") + + "</qt>"; + + int tmp = KMessageBox::warningContinueCancel(this, _msg); + if (tmp == KMessageBox::Cancel) { + selectedItem = 0; + } + displayed_WARN_autosuspend = true; + } + sB_autoInactivity->setEnabled(true); + tL_autoInactivity_After->setEnabled(true); + cB_Blacklist->setEnabled(true); + if(cB_Blacklist->isChecked()) pB_editBlacklist->setEnabled(true); + + } + else { + sB_autoInactivity->setEnabled(false); + tL_autoInactivity_After->setEnabled(false); + cB_Blacklist->setEnabled(false); + pB_editBlacklist->setEnabled(false); + } + + cB_autoInactivity->setCurrentItem( selectedItem ); + + if(initalised) { + scheme_changed = true; + buttonApply->setEnabled(true); + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: Called if the 'Enable scheme specific blacklist' is toggled. + * \param toggled boolean, true if toggled on + * false if toggled off + */ +void ConfigureDialog::cB_Blacklist_toggled( bool toggled ){ + kdDebugFuncIn(trace); + + pB_editBlacklist->setEnabled(toggled); + + if(initalised) { + buttonApply->setEnabled(true); + scheme_changed = true; + } else { + cB_Blacklist->setChecked(toggled); + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: Called if the 'edit blacklist' button is toggled. + */ +void ConfigureDialog::pB_editBlacklistSuspend_clicked(){ + kdDebugFuncIn(trace); + + QString _top_text = ""; + bool initialiseImport = false; + + if(tabWidget->currentPageIndex() == 0 ) { + QString s_scheme = getSchemeRealName(schemes[listBox_schemes->currentItem()]); + _top_text = listBox_schemes->currentText(); + if (kconfig->hasGroup(s_scheme)){ + kconfig->setGroup(s_scheme); + } + blacklist = kconfig->readListEntry("autoInactiveSchemeBlacklist", ','); + if( blacklist.empty()) { + QString _msg = i18n("The blacklist of the selected scheme is empty. " + "Import the general blacklist?"); + int tmp = KMessageBox::questionYesNo(this, _msg, QString(), i18n("Import"), i18n("Do Not Import")); + if (tmp == KMessageBox::Yes) { + initialiseImport = true; + if(kconfig->hasGroup("General")){ + kconfig->setGroup("General"); + blacklist = kconfig->readListEntry("autoInactiveBlacklist", ','); + } + } + } + } + else { + if(kconfig->hasGroup("General")){ + _top_text = i18n("General Autosuspend Blacklist"); + kconfig->setGroup("General"); + blacklist = kconfig->readListEntry("autoInactiveBlacklist", ','); + } + } + blacklistEDlgAS = new blacklistEditDialog(blacklist, _top_text, initialiseImport, this); + + connect( blacklistEDlgAS, SIGNAL(config_finished(QStringList)), this, + SLOT(saveSchemeSuspendBlacklist(QStringList))); + blacklistEDlgAS->exec(); + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: Called if the signal config_finished(QStringList) recieved + * and the autosuspend blacklist is edited. + * \param new_blacklist QStringlist with the edited blacklisted processes + */ + +void ConfigureDialog::saveSchemeSuspendBlacklist( QStringList new_blacklist){ + kdDebugFuncIn(trace); + + if(tabWidget->currentPageIndex() == 0 ) { + QString s_scheme = getSchemeRealName(schemes[currentScheme]); + kconfig->setGroup(s_scheme); + kconfig->writeEntry("autoInactiveSchemeBlacklist", new_blacklist, ','); + } + else { + kconfig->setGroup("General"); + kconfig->writeEntry("autoInactiveBlacklist", new_blacklist, ','); + } + + kconfig->sync(); + kdDebugFuncOut(trace); +} + +/* ---- END Inactivity SECTION ---- */ + +/* ---- START Autodimm SECTION ---- */ + +/*! + * This used to set the autodimm related widgets. + */ +void ConfigureDialog::cB_autoDimm_toggled( bool toggled ) { + kdDebugFuncIn(trace); + + if(cB_autoDimm->isOn() != toggled) + cB_autoDimm->setChecked(toggled); + + if (toggled) + tL_autoDimmExplain->setEnabled(toggled); + tL_autoDimmAfter->setEnabled(toggled); + sB_autoDimmTime->setEnabled(toggled); + tL_autoDimmTo->setEnabled(toggled); + sB_autoDimmTo->setEnabled(toggled); + + if (sB_autoDimmTime->value() > 0) + cB_BlacklistDimm->setEnabled(toggled); + + if (cB_BlacklistDimm->isOn()) + pB_editBlacklistDimm->setEnabled(toggled); + + if (toggled) { + if (sB_autoDimmTime->value() > 0) { + tL_autoDimmTo->setEnabled(true); + sB_autoDimmTo->setEnabled(true); + } else { + tL_autoDimmTo->setEnabled(false); + sB_autoDimmTo->setEnabled(false); + } + } + + scheme_changed = true; + buttonApply->setEnabled(true); + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: Called if the 'Enable scheme specific blacklist' is toggled. + * \param toggled boolean, true if toggled on + * false if toggled off + */ +void ConfigureDialog::cB_BlacklistDimm_toggled( bool toggled ){ + kdDebugFuncIn(trace); + + pB_editBlacklistDimm->setEnabled(toggled); + + if(initalised) { + buttonApply->setEnabled(true); + scheme_changed = true; + } else { + cB_BlacklistDimm->setChecked(toggled); + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: Called if the 'edit blacklist' button for autodimm is toggled. + */ +void ConfigureDialog::pB_editBlacklistDimm_clicked(){ + kdDebugFuncIn(trace); + + QString _top_text = ""; + bool initialiseImport = false; + + if(tabWidget->currentPageIndex() == 0 ) { + QString s_scheme = getSchemeRealName(schemes[listBox_schemes->currentItem()]); + _top_text = listBox_schemes->currentText(); + if (kconfig->hasGroup(s_scheme)){ + kconfig->setGroup(s_scheme); + } + blacklist = kconfig->readListEntry("autoDimmSchemeBlacklist", ','); + if( blacklist.empty()) { + QString _msg = i18n("The blacklist of the selected scheme is empty. " + "Import the general blacklist?"); + int tmp = KMessageBox::questionYesNo(this, _msg, QString(), i18n("Import"), i18n("Do Not Import")); + if (tmp == KMessageBox::Yes) { + initialiseImport = true; + if(kconfig->hasGroup("General")){ + kconfig->setGroup("General"); + blacklist = kconfig->readListEntry("autoDimmBlacklist", ','); + } + } + } + } + else { + if(kconfig->hasGroup("General")){ + _top_text = i18n("General Autodimm Blacklist"); + kconfig->setGroup("General"); + blacklist = kconfig->readListEntry("autoDimmBlacklist", ','); + } + } + blacklistEDlgAD = new blacklistEditDialog(blacklist, _top_text, initialiseImport, this); + + connect( blacklistEDlgAD, SIGNAL(config_finished(QStringList)), this, + SLOT(saveSchemeDimmBlacklist(QStringList))); + blacklistEDlgAD->exec(); + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: Called if the signal config_finished(QStringList) recieved + * and the autdimm blacklist is edited. + * \param new_blacklist QStringlist with the edited blacklisted processes + */ +void ConfigureDialog::saveSchemeDimmBlacklist( QStringList new_blacklist){ + kdDebugFuncIn(trace); + + if(tabWidget->currentPageIndex() == 0 ) { + QString s_scheme = getSchemeRealName(schemes[currentScheme]); + kconfig->setGroup(s_scheme); + kconfig->writeEntry("autoDimmSchemeBlacklist", new_blacklist, ','); + } + else { + kconfig->setGroup("General"); + kconfig->writeEntry("autoDimmBlacklist", new_blacklist, ','); + } + + kconfig->sync(); + kdDebugFuncOut(trace); +} + +/*! + * SLOT: Called if there \ref sB_autoDimmTime get changed + * \param value Integer with the new value + */ +void ConfigureDialog::sB_autoDimmTime_valueChanged( int value ) { + kdDebugFuncIn(trace); + + if (value > 0) { + if (!tL_autoDimmTo->isEnabled()) { + tL_autoDimmTo->setEnabled(true); + sB_autoDimmTo->setEnabled(true); + cB_BlacklistDimm->setEnabled(true); + if (cB_BlacklistDimm->isOn()) + pB_editBlacklistDimm->setEnabled(true); + } + } else { + if (tL_autoDimmTo->isEnabled()) { + tL_autoDimmTo->setEnabled(false); + sB_autoDimmTo->setEnabled(false); + cB_BlacklistDimm->setEnabled(false); + pB_editBlacklistDimm->setEnabled(false); + } + } + kdDebugFuncOut(trace); +} + + +/* ---- END Autodimm SECTION ---- */ + +/* ---- START Brightness SECTION ---- */ +/*! \b SLOT: to enable the brigthness related widgets */ +void ConfigureDialog::cB_Brightness_toggled( bool toggled ) { + kdDebugFuncIn(trace); + + gB_Brightness->setEnabled(toggled); + cB_Brightness->setChecked(toggled); + connect(brightnessSlider, SIGNAL(valueChanged (int)), this, SLOT(brightnessSlider_sliderMoved(int))); + + kdDebugFuncOut(trace); +} + +/*! \b SLOT: to change the brightness if the slider is changed */ +void ConfigureDialog::brightnessSlider_sliderMoved( int new_value ) { + kdDebugFuncIn(trace); + + if (cB_Brightness->isEnabled() && cB_Brightness->isChecked()) { + scheme_valueChanged(); + tL_valueBrightness->setText(QString::number(new_value) + " %"); + hwinfo->setBrightness(-1, new_value); + pB_resetBrightness->setEnabled(true); + brightness_changed = true; + } + + kdDebugFuncOut(trace); +} + +/*! \b SLOT: to reset the brightness if the reset button clicked */ +void ConfigureDialog::pB_resetBrightness_clicked( ) { + kdDebugFuncIn(trace); + + hwinfo->setBrightness(brightness_last, -1); + brightnessSlider->setValue(brightness_last); + pB_resetBrightness->setEnabled(false); + brightness_changed = false; + + kdDebugFuncOut(trace); +} + +/* ---- END Brightness SECTION ---- */ + +/* ---- START battery level SECTION ---- */ +/*! + * SLOT: called if the warning QSpinBoxes for battery level is changed. + */ +void ConfigureDialog::sB_batWarning_valueChanged() { + kdDebugFuncIn(trace); + + if (initalised) { + if (sB_batWarning->value() == 0 ) + sB_batWarning->setValue(1); + if ( sB_batWarning->value() <= sB_batLow->value()) { + sB_batLow->setValue(sB_batWarning->value()-1); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if the low QSpinBoxes for battery level is changed. + */ +void ConfigureDialog::sB_batLow_valueChanged() { + kdDebugFuncIn(trace); + + if (initalised) { + if (sB_batLow->value() == 0 ) + sB_batLow->setValue(1); + + if ( sB_batLow->value() >= sB_batWarning->value()) { + sB_batWarning->setValue(sB_batLow->value()+1); + } + if ( sB_batLow->value() <= sB_batCritical->value()) { + sB_batCritical->setValue(sB_batLow->value()-1); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if the critical QSpinBoxes for battery level is changed. + */ +void ConfigureDialog::sB_batCritical_valueChanged() { + kdDebugFuncIn(trace); + + if (initalised) { + if (sB_batCritical->value() == 0 ) + sB_batCritical->setValue(1); + if ( sB_batCritical->value() >= sB_batLow->value()) { + sB_batLow->setValue(sB_batCritical->value()+1); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if the QComboBox for the battery warning level action changed, + * used to hide/show the related QSpinboxes if needed. + */ +void ConfigureDialog::cB_batWarning_activated() { + kdDebugFuncIn(trace); + + if ( mapDescriptionToAction(cB_batWarning->currentText()) == "BRIGHTNESS") { + sB_batWarnAction_value->show(); + } else { + sB_batWarnAction_value->hide(); + } + + kdDebugFuncOut(trace); +} + +//! called if the QComboBox for the battery low level action changed +/*! + * used to hide/show the related QSpinboxes if needed. + */ +void ConfigureDialog::cB_batLow_activated() { + kdDebugFuncIn(trace); + + if ( mapDescriptionToAction(cB_batLow->currentText()) == "BRIGHTNESS") { + sB_batLowAction_value->show(); + } else { + sB_batLowAction_value->hide(); + } + + kdDebugFuncOut(trace); +} + +/*! + * SLOT: called if the QComboBox for the battery critical level action changed, + * used to hide/show the related QSpinboxes if needed. + */ +void ConfigureDialog::cB_batCritical_activated() { + kdDebugFuncIn(trace); + + if ( mapDescriptionToAction(cB_batCritical->currentText()) == "BRIGHTNESS") { + sB_batCritAction_value->show(); + } else { + sB_batCritAction_value->hide(); + } + + kdDebugFuncOut(trace); +} + +/* ---- END battery level SECTION ---- */ + +/*! \b SLOT: to open the KNotify config dialog */ +void ConfigureDialog::pB_configNotify_released( ) { + kdDebugFuncIn(trace); + + emit openKNotify(); + + kdDebugFuncOut(trace); +} + +/* ---- START helper functions SECTION ---- */ +/*! + * Map the key from config for a action to a descriptive name. + * \param action QString with the config key value + * \return QString with the description + */ +QString ConfigureDialog::mapActionToDescription( QString action ) { + kdDebugFuncIn(trace); + + QString ret; + + if (action.startsWith("SHUTDOWN")) { + ret = i18n("Shutdown"); + } else if (action.startsWith("LOGOUT_DIALOG")) { + ret = i18n("Logout Dialog"); + } else if (action.startsWith("SUSPEND2DISK")) { + if (actions.contains("Suspend to Disk")) + ret = i18n("Suspend to Disk"); + } else if (action.startsWith("SUSPEND2RAM")) { + if (actions.contains("Suspend to RAM")) + ret = i18n("Suspend to RAM"); + } else if (action.startsWith("CPUFREQ_POWERSAVE")) { + if (hwinfo->supportCPUFreq()) + ret = i18n("CPU Powersave policy"); + } else if (action.startsWith("CPUFREQ_DYNAMIC")) { + if (hwinfo->supportCPUFreq()) + ret = i18n("CPU Dynamic policy"); + } else if (action.startsWith("CPUFREQ_PERFORMANCE")) { + if (hwinfo->supportCPUFreq()) + ret = i18n("CPU Performance policy"); + } else if (action.startsWith("BRIGHTNESS")) { + if (hwinfo->supportBrightness()) + ret = i18n("Set Brightness to"); + } + + kdDebugFuncOut(trace); + return ret; +} + +/*! + * Map the action description (maybe translated) back to a QString key for the config. + * \param description QString with the description + * \return QString with the config key value + */ +QString ConfigureDialog::mapDescriptionToAction( QString description ) { + kdDebugFuncIn(trace); + + QString ret; + + if (description.startsWith("Shutdown") || description.startsWith(i18n("Shutdown"))) { + ret = "SHUTDOWN"; + } else if (description.startsWith("Logout Dialog") || + description.startsWith(i18n("Logout Dialog"))) { + ret = "LOGOUT_DIALOG"; + } else if (description.startsWith("Suspend to Disk") || + description.startsWith(i18n("Suspend to Disk"))) { + ret = "SUSPEND2DISK"; + } else if (description.startsWith("Suspend to RAM") || + description.startsWith(i18n("Suspend to RAM"))) { + ret = "SUSPEND2RAM"; + } else if (description.startsWith("CPU Powersave policy") || + description.startsWith(i18n("CPU Powersave policy"))) { + ret = "CPUFREQ_POWERSAVE"; + } else if (description.startsWith("CPU Dynamic policy") || + description.startsWith(i18n("CPU Dynamic policy"))) { + ret = "CPUFREQ_DYNAMIC"; + } else if (description.startsWith("CPU Performance policy") || + description.startsWith(i18n("CPU Performance policy"))) { + ret = "CPUFREQ_PERFORMANCE"; + } else if (description.startsWith("Set Brightness to") || + description.startsWith(i18n("Set Brightness to"))) { + ret = "BRIGHTNESS"; + } + + kdDebugFuncOut(trace); + return ret; +} + +/*! + * Helper to fill a QComboBox with their text and select the correct item + * \param _cb Pointer to the QComboBox + * \param _actions QStringList with the allowed actions + * \param _select QString with the action to select + */ +void ConfigureDialog::fillActionComboBox(QComboBox *_cb, QStringList _actions, QString _select) { + kdDebugFuncIn(trace); + + _cb->clear(); + _cb->insertItem(""); + + for ( QStringList::Iterator it = _actions.begin(); it != _actions.end(); ++it ) { + QString _tmp = *it; + + QString _desc = mapActionToDescription( _tmp ); + if (!_desc.isEmpty()) { + _cb->insertItem( _desc ); + if (_tmp == _select) { + _cb->setCurrentItem(_cb->count()-1); + } + } + } + + kdDebugFuncOut(trace); +} + +/* ---- END helper functions SECTION ---- */ + +#include "configuredialog.moc" diff --git a/src/configuredialog.h b/src/configuredialog.h new file mode 100644 index 0000000..19cbdeb --- /dev/null +++ b/src/configuredialog.h @@ -0,0 +1,225 @@ +/*************************************************************************** + * Copyright (C) 2005 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +#ifndef CONFIGUREDIALOG_H +#define CONFIGUREDIALOG_H + +/*! +* \file configuredialog.h +* \brief Headerfile for configureDialog.cpp and the class \ref ConfigureDialog. +*/ +/*! +* \class ConfigureDialog +* \brief class for all config dialog related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2005 +*/ + +// own header +#include "blacklisteditdialog.h" +#include "settings.h" +#include "hardware.h" + +// header of the UI +#include "configure_Dialog.h" + +class ConfigureDialog: public configure_Dialog { + + Q_OBJECT + +public: + //! default constructor + ConfigureDialog( KConfig *_config, HardwareInfo *_hwinfo, Settings *_settings, + QWidget *parent = 0, const char *name = 0); + //! default destructor + ~ConfigureDialog(); + +private: + + //! pointer to instance of the blacklist edit dialog for Autosuspend + blacklistEditDialog* blacklistEDlgAS; + //! pointer to instance of the blacklist edit dialog for Autodimm + blacklistEditDialog* blacklistEDlgAD; + + //! the pointer to the config of kpowersave, get from constructor + KConfig *kconfig; + //! pointer to the KPowersave settings, get from constructor + Settings *settings; + //! pointer to hardware information and actions + HardwareInfo *hwinfo; + //! struct with allowed suspend states + SuspendStates suspend; + + //! QStringList with the blacklisted processes + QStringList blacklist; + //! QStringList with all available supported actions + QStringList actions; + //! QStringList with the name of the schemes in the config + QStringList schemes; + + //! true if the current desktop session is a GNOME session, else if not + bool gnome_session; + + //! true if a value within the Tab 'General Settings' is changed, else if not + bool general_changed; + //! true if all is initialised, false if not + bool initalised; + //! true if a value within the Tab 'Scheme Settings' is changed, else if not + bool scheme_changed; + //! true if the warning message was displayed , else if not! + bool displayed_WARN_autosuspend; + //! true if the brightness was changed + bool brightness_changed; + + //! represent the ID of the current selected scheme related to the schemeList + int currentScheme; + + //! the max numbers of levels supported by the machine + int brightnessLevels; + //! the brightness as the configdialog was started + int brightness_last; + + //! to store the changed 'General' setttings + void saveGeneralSettings(); + //! to store the (changed) settings of the current scheme + void saveSchemeSettings(); + //! set all needed widgets in the dialog for a given ID of a scheme + + void setConfigToDialog( int ); + //! set the values from the section general in configfile to dialog + void setGeneralSettings(); + //! set all needed icons + void setIcons(); + //! set all needed tooltips + void setTooltips(); + //! set the gB_inactivity visible/invisible + void setInactivityBox(); + + //! set the schemelist to the listbox + void setSchemeList(); + //! get the list of schemes and fill \ref schemes + void getSchemeList(); + //! set the current scheme + void selectScheme (QString _scheme); + //! to get the real Name of the Scheme + QString getSchemeRealName( QString ); + + //! map a action string from options to a description + QString mapActionToDescription( QString action ); + //! map a (translated) description of a action back to the name config key + QString mapDescriptionToAction( QString description ); + //! fill a QComboBox with actions (translated text) and select a value + void fillActionComboBox(QComboBox *_cb, QStringList _actions, QString _select); + +signals: + + //! signal to open the Help + void openHelp(); + //! signal to open the KNotify dialog + void openKNotify(); + +private slots: + + //! alled if the user click on 'Apply' Button + void buttonApply_clicked(); + //! called if the user click on 'Chancel' Button + void buttonCancel_clicked(); + //! called if the user click on 'OK' Button + void buttonOk_clicked(); + //! called if the user click on 'Help' Button + void buttonHelp_clicked(); + + //! called if the 'Enable scheme specific blacklist' checkbox toggled + void cB_Blacklist_toggled( bool ); + //! called if the 'Disable screensaver' checkbox toggled + void cB_disable_Ss_toggled( bool ); + //! called if the 'disablePM' checkbox toggled + void cB_disablePM_toggled( bool ); + //! called if the 'SpecificPM' checkbox toggled + void cB_SpecificPM_toggled( bool ); + //! called if the 'specificSettings' checkbox toggled + void cB_specificSettings_toggled( bool ); + + //! called if the checkbox cB_autoSuspend toggled + void cB_autoSuspend_toggled( bool ); + //! called if the current comboB_autoInactivity item is changed + void cB_autoInactivity_activated( int ); + + //! called if the checkbox cB_autoDimm toggled + void cB_autoDimm_toggled( bool ); + //! called if the 'Enable scheme specific blacklist' checkbox toggled + void cB_BlacklistDimm_toggled( bool ); + //! called if the value of sB_autoDimmTime get changed + void sB_autoDimmTime_valueChanged( int ); + + //! called if a value in section 'general' changed + void general_valueChanged(); + //! called if the current 'schemes' ListBoxItem changed + void listBox_schemes_currentChanged(); + //! called if a checkbox in section 'scheme' changed + void scheme_valueChanged(); + + //! called if the pB_editBlacklist clicked + void pB_editBlacklistSuspend_clicked(); + //! to store the changed and from BlacklistEditDlg recieved suspend blacklist to scheme + void saveSchemeSuspendBlacklist( QStringList ); + //! called if the pB_editBlacklistDimm clicked + void pB_editBlacklistDimm_clicked(); + //! to store the changed and from BlacklistEditDlg recieved dimm blacklist to scheme + void saveSchemeDimmBlacklist( QStringList ); + + //! called if the checkbox cB_Brightness toggled + void cB_Brightness_toggled ( bool ); + //! called if the slider for brightness changed + void brightnessSlider_sliderMoved( int ); + //! called if pB_resetBrightness clicked + void pB_resetBrightness_clicked(); + //! called if pB_configNotify released + void pB_configNotify_released(); + + //! called if the button for a new scheme get clicked + void pB_newScheme_clicked(); + //! called if the button for delete a scheme get clicked + void pB_deleteScheme_clicked(); + + //! called if the value of the standby DPMS spinBox changed + void sB_standby_valueChanged(); + //! called if the value of the suspend DPMS spinBox changed + void sB_suspend_valueChanged(); + //! called if the value of the powerOff DPMS spinBox changed + void sB_powerOff_valueChanged(); + + //! called if the warning QSpinBoxes for battery level is changed + void sB_batWarning_valueChanged(); + //! called if the low QSpinBoxes for battery level is changed + void sB_batLow_valueChanged(); + //! called if the critical QSpinBoxes for battery level is changed + void sB_batCritical_valueChanged(); + + //! called if the QComboBox for the battery warning level action changed + void cB_batWarning_activated(); + //! called if the QComboBox for the battery low level action changed + void cB_batLow_activated(); + //! called if the QComboBox for the battery critical level action changed + void cB_batCritical_activated(); + +}; + +#endif + diff --git a/src/countdown_Dialog.ui b/src/countdown_Dialog.ui new file mode 100644 index 0000000..eda8d01 --- /dev/null +++ b/src/countdown_Dialog.ui @@ -0,0 +1,204 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>countdown_Dialog</class> +<widget class="QDialog"> + <property name="name"> + <cstring>countdown_Dialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>344</width> + <height>127</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string></string> + </property> + <property name="sizeGripEnabled"> + <bool>false</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="2" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>142</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="2" column="4"> + <property name="name"> + <cstring>pB_cancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="accel"> + <string>Alt+C</string> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Maximum</enum> + </property> + <property name="sizeHint"> + <size> + <width>30</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="2" column="5" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>144</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>iconPixmap</cstring> + </property> + <property name="minimumSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + </widget> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="3" rowspan="1" colspan="4"> + <property name="name"> + <cstring>textLabel</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="textFormat"> + <enum>AutoText</enum> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + <spacer row="1" column="6"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Maximum</enum> + </property> + <property name="sizeHint"> + <size> + <width>30</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KProgress" row="1" column="1" rowspan="1" colspan="5"> + <property name="name"> + <cstring>progressBar</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>200</width> + <height>20</height> + </size> + </property> + </widget> + </grid> +</widget> +<images> + <image name="image0"> + <data format="XPM.GZ" length="2304">789c8593c9721a311086ef3cc5947573a5dacc303043a57230b6f1beef4ee530128bc1069bcd5b2aef9e5f52b702d855410cf0a9b7bf5b626d35ba39398c56d74a936931ed99c8dc17e368b5351b0cde7ffefaf1bbb4922411de59354a56be9556681c994895ddcbf12c70eeb8c19cb27d12d8d955c7711efc47cc6ca7a970ece2559739e77c3781bdff85b0f7a71d66c3fecf81bdff8be7b8ccfe75cb71b96c98ef3cc7a27f37b08fbf1266ff3eb3e879779c076e0ab3ff03b3e88985d95eb69cd42b329f4761b6f798a57ed572250efcc12cf56acc92ffd2732af932c775b03f9f4238f1f637cb699c72bc3281bdbe7bcbd5a456653e715c04ce99eb5c6f10d8db9f84b9de3a738bede7c2deae7cbd228bd99e58ae2562a7d47316b37f8bb9caac1c17b9c46f0973fc2db3e8df6716fd1b96b34a883f6516ff0ab3f4776839d745c1f98f2cd7d3c07b81eb8ebbcc6dd64b9e75c2fe078e8d663b5d5b2e52dde67a9bc21cdff36c12d63f0cecfd5bc29c6f9bb9c6f74f0973bc0eecedafc21c7fc65c707c4798ef4fdbb191fa4a0b73fc31b3d433817d3e89977a0533e73f9d06ce3d93a282d4fcb73ccbfbbedf85a5977861f9fa4bb93496a116b53fd798cbdfe1dc5dbaa71ef5e9811e69005aa839af1f11437aa2671ad1982678a634a317c4bc7ea95fc3fbcd79cee81d153e5063e2f80d96aff4af5303b9fbb4419bd0afd1c11635113d428d3658f46fb3ee1df8efd21ee77aa57d3aa043c48fa1f1888e17f41b3a419e199d22dad019f6cee9822e5169cbf5f3f4497f0fbb57748daeb79d36eb7543b788b8c3aff2d27c0ce637418c71bfd7e16975af439546e7638ad14d27e4b7937cc0ee87d36dbdc7e8654c899b5b0f99faf6f4e6f2b7713a53ecb6a802dd13e4f64f0a3d764655d273fa35340fb03b41779b5443fe017237dcca506744f9bff9b8b32d30cf3a229a98e0266ad83b94baf3b027b6a3e8d3fd39c644ed79f695822a5bf34015dc47e6e2b717ee8f565a19d7a93de30f74d9740a6d8d866a7dca8fa5dad0fd8c8899bf71aa8333cfe0ddc5ccf457f71f73eae22c7b98f73b6632806ef4a1eedd348ba5fbc97da81e3e87f018867d7916ef7f31f75feab86f1df6cd57faffbf56fe7c2ffd0519fbee77</data> + </image> +</images> +<connections> + <connection> + <sender>pB_cancel</sender> + <signal>pressed()</signal> + <receiver>countdown_Dialog</receiver> + <slot>pB_cancel_pressed()</slot> + </connection> +</connections> +<slots> + <slot>pB_cancel_pressed()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/countdowndialog.cpp b/src/countdowndialog.cpp new file mode 100644 index 0000000..3deac27 --- /dev/null +++ b/src/countdowndialog.cpp @@ -0,0 +1,177 @@ +/*************************************************************************** + * Copyright (C) 2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! \file countdowndialog.cpp + * \brief In this file can be found the countdown dialog related code. + * \author Danny Kukawka, <dkukawka@suse.de, danny.kukawka@web.de> + * \date 2007 + */ + +// own header +#include "countdowndialog.h" +#include "kpowersave_debug.h" + +// KDE headers: +#include <klocale.h> +#include <kiconloader.h> +#include <kprogress.h> + +// QT headers: +#include <qdialog.h> +#include <qlabel.h> +#include <qprogressbar.h> +#include <qpushbutton.h> +#include <qstring.h> +#include <qtimer.h> + +/*! This is the default constructor of class countDownDialog . */ +countDownDialog::countDownDialog( int timeout, QWidget *parent, const char *name) + :countdown_Dialog(parent, name, false, Qt::WStyle_StaysOnTop | Qt::WDestructiveClose ) +{ + kdDebugFuncIn(trace); + chancel = false; + remaining = timeout; + timeOut = timeout; + + PROGRESS = new QTimer(this); + connect(PROGRESS, SIGNAL(timeout()), this, SLOT(updateProgress())); + + this->setCaption(i18n("KPowersave")); + + kdDebugFuncOut(trace); +} + +/*! This is the default destructor of class countDownDialog . */ +countDownDialog::~countDownDialog() { + kdDebugFuncIn(trace); + // no need to delete child widgets, Qt does it all for us + emit dialogClosed(chancel); + + kdDebugFuncOut(trace); +} + +/*! + * This used to set Icon/pixmap for the dialog. + * \param type QString with the type of the current suspend + * to set the pixmap in the dialog + */ +void countDownDialog::setPixmap( QString type ) +{ + QPixmap pixmap = 0; + + if(type.startsWith("suspend2disk")){ + pixmap = KGlobal::iconLoader()->loadIcon("suspend_to_disk", KIcon::NoGroup, KIcon::SizeLarge); + } else if (type.startsWith("suspend2ram")) { + pixmap = KGlobal::iconLoader()->loadIcon("suspend_to_ram", KIcon::NoGroup, KIcon::SizeLarge); + } else if (type.startsWith("standby")) { + pixmap = KGlobal::iconLoader()->loadIcon("stand_by", KIcon::NoGroup, KIcon::SizeLarge); + } else { + pixmap = KGlobal::iconLoader()->loadIcon("kpowersave", KIcon::NoGroup, KIcon::SizeLarge); + } + iconPixmap->setPixmap( pixmap ); +} + +/*! + * To set the message to the dialog, which should be shown to the user. + * \param text QString with the message. + */ +void countDownDialog::setMessageText(QString text) { + kdDebugFuncIn(trace); + + if (!text.isEmpty()) { + textLabel->setText(text); + } + + kdDebugFuncOut(trace); +} + +/*! + * To show the dialog and start the countdown. + * \return boolean with the result of the operation + * \retval true if the dialog could get displayed + * \retval false if there is any problem + */ +bool countDownDialog::showDialog() { + kdDebugFuncIn(trace); + + bool _retval = false; + + if (!textLabel->text().isEmpty() && timeOut > 0) { + // init the progressbar + progressBar->setFormat(i18n("%1 seconds").arg(remaining)); + progressBar->setPercentageVisible(true); + progressBar->setProgress(100); + progressBar->setEnabled(true); + + this->adjustSize(); + this->show(); + + PROGRESS->start(1000, true); + } + + kdDebugFuncOut(trace); + return _retval; +} + +/*! + * \b SLOT to get the event if the 'Cancel' button was pressed. + */ +void countDownDialog::pB_cancel_pressed() { + kdDebugFuncIn(trace); + + if (PROGRESS->isActive()) + PROGRESS->stop(); + + chancel = true; + close(); + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to handle the change of the progressbar. + */ +void countDownDialog::updateProgress() { + kdDebugFuncIn(trace); + + if (remaining == 0 ) { + if (PROGRESS->isActive()) + PROGRESS->stop(); + + chancel = false; + close(); + } else if ( remaining > 0) { + int setTo = (int)((100.0/(float)timeOut)*(float)remaining); + + // set the progressBar + progressBar->setFormat(i18n("%1 seconds").arg(remaining)); + progressBar->setPercentageVisible(true); + progressBar->setProgress(setTo); + progressBar->setEnabled(true); + + // increase counter + remaining--; + // start needed timer + PROGRESS->start(1000, true); + } + + kdDebugFuncOut(trace); +} + +#include "countdowndialog.moc" diff --git a/src/countdowndialog.h b/src/countdowndialog.h new file mode 100644 index 0000000..86662f6 --- /dev/null +++ b/src/countdowndialog.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! +* \file countdowndialog.h +* \brief Headerfile for countdowndialog.cpp and the class \ref countDownDialog. +*/ +/*! +* \class countDownDialog +* \brief class for countdown dialog related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2007 +*/ + +#ifndef COUNTDOWNDIALOG_H +#define COUNTDOWNDIALOG_H + +#include "countdown_Dialog.h" + +class countDownDialog: public countdown_Dialog { + + Q_OBJECT + +public: + + //! default constructor + countDownDialog(int timeout, QWidget *parent = 0, const char *name = 0); + //! default destructor + ~countDownDialog(); + + //! set needed icons + void setPixmap( QString ); + //! to set the message text for the user + void setMessageText(QString text); + //! to show up the dialog + bool showDialog(); + +private: + //! Timer for the timeout + /*! + * This timer is used to change the progressbar and to close the dialog if + * the \ref timeOut is over. + */ + QTimer *PROGRESS; + + //! time the dialog should be displayed + int timeOut; + //! remaining time to show the dialog + int remaining; + + //! to store the info if the countdown was chanceled + bool chancel; + +private slots: + + //! to update the progressbar + void updateProgress(); + //! to catch the event if the 'Chancel' button get pressed + void pB_cancel_pressed(); + +signals: + //! emited if the dialog get closed + void dialogClosed( bool result); + +}; + +#endif diff --git a/src/dbusHAL.cpp b/src/dbusHAL.cpp new file mode 100644 index 0000000..3c9a293 --- /dev/null +++ b/src/dbusHAL.cpp @@ -0,0 +1,1314 @@ + /************************************************************************** + * Copyright (C) 2006-2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! + * \file dbusHAL.cpp + * \brief In this file can be found the functionality to connect to + * the HAL daemon via D-Bus, to handle D-Bus calls/events and to + * provide wrapper to HAL lib and functions + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2006-2007 + */ + + // KDE Header +#include <klocale.h> + +// DBUS - Header +#include "dbusHAL.h" + +// system headers +#include <iostream> + +static void* myInstance = 0; + +/*! The default constructor of the class dbusHAL. */ +dbusHAL::dbusHAL(){ + kdDebugFuncIn(trace); + + dbus_is_connected = false; + hal_is_connected = false; + aquiredPolicyPower = false; + hal_ctx = NULL; + + // add pointer to this for filter_function() + myInstance=this; + // init connection to dbus + if(!initDBUS()) { + kdError() << "Can't connect to D-Bus" << endl; + m_dBusQtConnection = NULL; + } + if(!initHAL()) + kdError() << "Can't connect to HAL" << endl; + + kdDebugFuncOut(trace); +} + +/*! This is the default destructor of class dbusPowersaveConnection. */ +dbusHAL::~dbusHAL(){ + kdDebugFuncIn(trace); + + close(); + myInstance = NULL; + + kdDebugFuncOut(trace); +} + +/*! + * This function return information about connection status to the DBUS daemon. + * \return boolean with the state of the connection to D-Bus + * \retval true if connected + * \retval false if disconnected + */ +bool dbusHAL::isConnectedToDBUS() { + return dbus_is_connected; +} + +/*! + * This function return information about connection status to the HAL daemon. + * \return boolean with the state of the connection to HAL + * \retval true if connected + * \retval false if disconnected + */ +bool dbusHAL::isConnectedToHAL() { + return hal_is_connected; +} + +/*! + * This function return information if the org.freedesktop.Policy.Power + * interface was claimed. + * \return boolean with the status of claim the interface + * \retval true if aquired + * \retval false if not + */ +bool dbusHAL::aquiredPolicyPowerInterface() { + return aquiredPolicyPower; +} + +/*! + * This function try a reconnect to D-Bus and HAL daemon. + * \return boolean with the result of the operation + * \retval true if successful reconnected to D-Bus and HAL + * \retval false if unsuccessful + */ +bool dbusHAL::reconnect() { + // free HAL context + freeHAL(); + // close D-Bus connection + close(); + // init D-Bus conntection and HAL context + return (initDBUS() && initHAL()); +} + +/*! + * This function close the connection to powersave over the D-Bus daemon. + * \return boolean with the result of the operation + * \retval true if successful closed the connection + * \retval false if any problems + */ +bool dbusHAL::close() { + if ( m_dBusQtConnection != NULL ) { + releasePolicyPowerIface(); + m_dBusQtConnection->close(); + m_dBusQtConnection = NULL; + } + dbus_is_connected = false; + + return true; +} + +/* ----> D-Bus section :: START <---- */ + +/*! + * This function initialise the connection to the D-Bus daemon. + * \return boolean with the result of the operation + * \retval true if successful initialised D-Bus connection + * \retval false if unsuccessful + */ +bool dbusHAL::initDBUS(){ + kdDebugFuncIn(trace); + + dbus_is_connected = false; + + DBusError error; + dbus_error_init(&error); + + dbus_connection = dbus_bus_get( DBUS_BUS_SYSTEM, &error ); + + if (dbus_connection == NULL){ + kdError() << "Failed to open connection to system message bus: " << error.message << endl; + dbus_error_free (&error); + return false; + } + + if ( dbus_error_is_set( &error ) ) { + kdError() << "Failed to register connection with system message bus: " << error.message << endl; + return false; + } + + aquirePolicyPowerIface(); + + dbus_connection_set_exit_on_disconnect( dbus_connection, false ); + + /* add the filter function which should be executed on events on the bus */ + if ( ! dbus_connection_add_filter( dbus_connection, filterFunction, this, NULL) ) { + kdFatal() << "Error: Not enough memory to add filter to dbus connection" << endl; + exit(EXIT_FAILURE); + } + + /* add a match rule to catch all signals going through the bus with D-Bus interface */ + dbus_bus_add_match( dbus_connection, "type='signal'," + "interface='org.freedesktop.DBus'," + "member='NameOwnerChanged'", NULL); + + /* add a match rule to catch all signals going through the bus with HAL interface */ + dbus_bus_add_match( dbus_connection, "type='signal'," + "interface='org.freedesktop.Hal.Manager'," + "member='DeviceAdded'", NULL); + dbus_bus_add_match( dbus_connection, "type='signal'," + "interface='org.freedesktop.Hal.Manager'," + "member='DeviceRemoved'", NULL); + dbus_bus_add_match( dbus_connection, "type='signal'," + "interface='org.freedesktop.Hal.Device'," + "member='PropertyModified'", NULL); + dbus_bus_add_match( dbus_connection, "type='signal'," + "interface='org.freedesktop.Hal.Device'," + "member='Condition'", NULL); + + /* add a match rule to catch all signals going through the bus with ConsoleKit Interface */ + dbus_bus_add_match( dbus_connection, "type='signal'," + "interface='org.freedesktop.ConsoleKit.Session'," + "member='ActiveChanged'", NULL); + + m_dBusQtConnection = new DBusQt::Connection(this); + m_dBusQtConnection->dbus_connection_setup_with_qt_main(dbus_connection); + + dbus_is_connected = true; + + kdDebugFuncOut(trace); + return true; +} + +/*! + * This function aquire the org.freedesktop.Policy.Power interface + * \return boolean with the result of the operation + * \retval true if successful aquired the interface + * \retval false if unsuccessful + */ +bool dbusHAL::aquirePolicyPowerIface(){ + kdDebugFuncIn(trace); + + if (dbus_connection == NULL) { + kdDebugFuncOut(trace); + return false; + } + + switch (dbus_bus_request_name(dbus_connection, "org.freedesktop.Policy.Power", + DBUS_NAME_FLAG_REPLACE_EXISTING, NULL)) { + case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: + kdDebug() << "Acquired org.freedesktop.Policy.Power interface" << endl; + aquiredPolicyPower = true; + break; + case DBUS_REQUEST_NAME_REPLY_IN_QUEUE: + kdWarning() << "Queued to aquire org.freedesktop.Policy.Power interface" << endl; + aquiredPolicyPower = false; + break; + default: + kdWarning() << "Unknown error while aquire org.freedesktop.Policy.Power interface" << endl; + aquiredPolicyPower = false; + break; + } + + kdDebugFuncOut(trace); + return aquiredPolicyPower; +} + +/*! + * This function release the org.freedesktop.Policy.Power interface + * \return boolean with the result of the operation + * \retval true if successful aquired the interface + * \retval false if unsuccessful + */ +bool dbusHAL::releasePolicyPowerIface(){ + kdDebugFuncIn(trace); + + int result; + bool retval = false; + DBusError error; + + if (dbus_connection == NULL) { + kdDebugFuncOut(trace); + return false; + } + + dbus_error_init(&error); + + result = dbus_bus_release_name(dbus_connection, "org.freedesktop.Policy.Power", &error); + + if ( dbus_error_is_set( &error ) ) { + kdError() << "Failed to release org.freedesktop.Policy.Power: " << error.message << endl; + dbus_error_free(&error); + } else { + switch (result) { + case DBUS_RELEASE_NAME_REPLY_RELEASED: + kdDebug() << "Released org.freedesktop.Policy.Power interface" << endl; + retval = true; + aquiredPolicyPower = false; + break; + case DBUS_RELEASE_NAME_REPLY_NOT_OWNER: + kdWarning() << "Couldn't release org.freedesktop.Policy.Power, not the owner" << endl; + break; + case DBUS_RELEASE_NAME_REPLY_NON_EXISTENT: + kdWarning() << "Couldn't release org.freedesktop.Policy.Power, Iface not existing" << endl; + break; + default: + kdWarning() << "Couldn't release org.freedesktop.Policy.Power, unknown error" << endl; + break; + } + } + + return retval; + kdDebugFuncOut(trace); +} + +/*! + * This function check if the org.freedesktop.Policy.Power + * interface is owned by someone + * \return boolean with the result of the operation + * \retval true if the interface is owned by someone + * \retval false if else + */ +bool dbusHAL::isPolicyPowerIfaceOwned(){ + kdDebugFuncIn(trace); + + bool retval = false; + DBusError error; + + if (dbus_connection == NULL) { + kdDebugFuncOut(trace); + return false; + } + + dbus_error_init(&error); + + retval = dbus_bus_name_has_owner(dbus_connection, "org.freedesktop.Policy.Power", &error); + + if ( dbus_error_is_set( &error ) ) { + kdError() << "Failed to check if org.freedesktop.Policy.Power has an owner: " << error.message << endl; + dbus_error_free(&error); + } + + kdDebugFuncOut(trace); + return retval; +} + +/* ----> DBUS section :: END <---- */ +/* ----> HAL section :: START <---- */ + +/*! + * This function initialise the connection to HAL over the D-Bus daemon. + * \return boolean with the result of the operation + * \retval true if successful initialised HAL connection and context + * \retval false if unsuccessful + */ +bool dbusHAL::initHAL(){ + kdDebugFuncIn(trace); + + if ( !dbus_is_connected ) { + freeHAL(); + return false; + } else if ( hal_is_connected && (hal_ctx != NULL)) { + return true; + } + + // could not connect to HAL, reset all and try again + freeHAL(); + + DBusError error; + dbus_error_init(&error); + + dbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (dbus_connection == NULL || dbus_error_is_set(&error)) { + kdError() << "could not open connection to system bus: " << error.message << endl; + dbus_error_free(&error); + return false; + } + + bool hal_is_ready = dbus_bus_name_has_owner(dbus_connection, "org.freedesktop.Hal", &error); + + if (!hal_is_ready) { + kdWarning() << "HAL is not ready. We will try later... " << endl; + + if ( dbus_error_is_set( &error ) ) { + kdError() << "Error checking if hal service exists: " << error.message << endl; + dbus_error_free( &error ); + } + + freeHAL(); + return false; + } + + if((hal_ctx = libhal_ctx_new()) == NULL) { + kdError() << "Could not init HAL context" << endl; + return false; + } + + /* setup dbus connection for hal */ + if (!libhal_ctx_set_dbus_connection(hal_ctx, dbus_connection)) { + kdError() << "Could not set up connection to dbus for hal" << endl; + freeHAL(); + return false; + } + + /* init the hal library */ + if (!libhal_ctx_init(hal_ctx, &error)) { + kdError() << "Could not init hal library: " << error.message << endl; + freeHAL(); + return false; + } + + hal_is_connected = true; + + kdDebugFuncOut(trace); + return hal_is_connected; +} + +/*! + * This function free the hal connection/context. + */ +void dbusHAL::freeHAL(){ + + if ( hal_ctx != NULL ) { + libhal_ctx_free( hal_ctx ); + hal_ctx = NULL; + } + hal_is_connected = false; +} + +/*! + * This function try a reconnect to the HAL daemon only. + * \return boolean with the result of the operation + * \retval true if successful reconnected to HAL + * \retval false if unsuccessful + */ +bool dbusHAL::reconnectHAL() { + // free HAL context + freeHAL(); + // init HAL context + return (initHAL()); +} + +/*! + * This function query a integer property from HAL for a given device + * \param udi QString with the UDI of the device + * \param property QString with the property + * \param returnval pointer to the return value + * \return If the query was successful or not + */ +bool dbusHAL::halGetPropertyInt(QString udi, QString property, int *returnval){ + kdDebugFuncIn(trace); + + bool ret = false; + + if (!initHAL() || udi.isEmpty() || property.isEmpty()) + goto out; + + DBusError error; + dbus_error_init(&error); + + if (!libhal_device_property_exists(hal_ctx, udi, property, &error)) { + kdWarning() << "Property: " << property << " for: " << udi << " doesn't exist." << endl; + goto out; + } + + *returnval = libhal_device_get_property_int(hal_ctx, udi, property, &error); + + if (dbus_error_is_set(&error)) { + kdError() << "Fetching property: " << property << " for: " << udi + << " failed with: " << error.message << endl; + dbus_error_free(&error); + goto out; + } else { + ret = true; + } + +out: + kdDebugFuncOut(trace); + return true; +} + +/*! + * This function query a boolean property from HAL for a given device + * \param udi QString with the UDI of the device + * \param property QString with the property + * \param returnval pointer to the return value + * \return If the query was successful or not + */ +bool dbusHAL::halGetPropertyBool(QString udi, QString property, bool *returnval){ + kdDebugFuncIn(trace); + + bool ret = false; + + if (!initHAL() || udi.isEmpty() || property.isEmpty()) + goto out; + + DBusError error; + dbus_error_init(&error); + + if (!libhal_device_property_exists(hal_ctx, udi, property, &error)) { + kdWarning() << "Property: " << property << " for: " << udi << " doesn't exist." << endl; + goto out; + } + + *returnval = libhal_device_get_property_bool(hal_ctx, udi, property, &error); + + if (dbus_error_is_set(&error)) { + kdError() << "Fetching property: " << property << " for: " << udi + << " failed with: " << error.message << endl; + dbus_error_free(&error); + goto out; + } else { + ret = true; + } + +out: + kdDebugFuncOut(trace); + return ret; +} + + +/*! + * This function query a Sting property from HAL for a given device + * \param udi QString with the UDI of the device + * \param property QString with the property + * \param returnval pointer to the return value + * \return If the query was successful or not + */ +bool dbusHAL::halGetPropertyString(QString udi, QString property, QString *returnval){ + kdDebugFuncIn(trace); + + bool ret = false; + + if (!initHAL() || udi.isEmpty() || property.isEmpty()) + goto out; + + DBusError error; + dbus_error_init(&error); + + if (!libhal_device_property_exists(hal_ctx, udi, property, &error)) { + kdWarning() << "Property: " << property << " for: " << udi << " doesn't exist." << endl; + goto out; + } + + *returnval = libhal_device_get_property_string(hal_ctx, udi, property, &error); + + if (dbus_error_is_set(&error)) { + kdError() << "Fetching property: " << property << " for: " << udi + << " failed with: " << error.message << endl; + dbus_error_free(&error); + goto out; + } else { + ret = true; + } + +out: + kdDebugFuncOut(trace); + return ret; +} + +/*! + * This function query a String List property from HAL for a given device + * \param udi QString with the udi of the device + * \param property QString with the property to query + * \param devices QStringList to return the values + * \return If the query was successful or not + */ +bool dbusHAL::halGetPropertyStringList (QString udi, QString property, QStringList *devices) { + kdDebugFuncIn(trace); + + bool ret = false; + + if (!initHAL() || udi.isEmpty() || property.isEmpty()) + goto out; + + DBusError error; + char ** found; + + dbus_error_init(&error); + + if (!libhal_device_property_exists(hal_ctx, udi, property, &error)) { + kdWarning() << "Property: " << property << " for: " << udi << " doesn't exist." << endl; + goto out; + } + + found = libhal_device_get_property_strlist (hal_ctx, udi, property, &error); + + if (dbus_error_is_set(&error)) { + kdWarning() << "Error while query existing strlist Property: " << property + << " for: " << udi << " error: " << error.message << endl; + dbus_error_free(&error); + libhal_free_string_array(found); + goto out; + } else { + for (int i = 0; found[i] != NULL ; ++i) { + QString _to_add = found[i]; + if (!_to_add.isEmpty()) *devices += _to_add; + } + libhal_free_string_array(found); + ret = true; + } + +out: + kdDebugFuncOut(trace); + return ret; +} + + +/*! + * This function query a capability from HAL for a given device + * \param udi QString with the UDI of the device + * \param capability QString with the capability to query + * \param returnval pointer to the return value as boolean + * \return If the query was successful or not + */ +bool dbusHAL::halQueryCapability(QString udi, QString capability, bool *returnval) { + kdDebugFuncIn(trace); + + bool ret = false; + + if (!initHAL() || udi.isEmpty() || capability.isEmpty()) + goto out; + + DBusError error; + dbus_error_init(&error); + + *returnval = libhal_device_query_capability(hal_ctx, udi, capability, &error); + + if (dbus_error_is_set(&error)) { + kdError() << "Fetching capability: " << capability << " for: " << udi + << " failed with: " << error.message << endl; + dbus_error_free(&error); + goto out; + } else { + ret = true; + } + +out: + kdDebugFuncOut(trace); + return ret; +} + +/*! + * Use this function to check if a device has a specia property/key. + * \param udi QString with the UDI of the device + * \param property QString with the property + * \return If the query was successful or not + */ +bool dbusHAL::halDevicePropertyExist(QString udi, QString property ) { + kdDebugFuncIn(trace); + + bool ret = false; + + if (!initHAL() || udi.isEmpty() || property.isEmpty()) + goto out; + + DBusError error; + dbus_error_init(&error); + + if (! libhal_device_property_exists (hal_ctx, udi, property, &error)) { + if (dbus_error_is_set(&error)) { + kdError() << "Fetching existing property: " << property << " for: " << udi + << " failed with: " << error.message << endl; + dbus_error_free(&error); + } + goto out; + } else { + ret = true; + } + +out: + kdDebugFuncOut(trace); + return ret; +} + +/*! + * Use this function to search find devices with a give capability + * \param capability QString with the capability to query + * \param devices QStringList to return the found devices + * \return If the query was successful or not + */ +bool dbusHAL::halFindDeviceByCapability (QString capability, QStringList *devices) { + kdDebugFuncIn(trace); + + DBusError error; + char ** found; + int num = 0; + bool ret = false; + + if (!initHAL() || capability.isEmpty()) + goto out; + + dbus_error_init(&error); + + found = libhal_find_device_by_capability (hal_ctx, capability, &num, &error); + + if (dbus_error_is_set(&error)) { + kdError() << "Could not get list of devices with capability: " << capability + << " error: " << error.message << endl; + dbus_error_free(&error); + libhal_free_string_array(found); + goto out; + } else { + for (int i = 0; i < num; ++i) { + QString _to_add = found[i]; + if (!_to_add.isEmpty()) *devices += _to_add; + } + libhal_free_string_array(found); + ret = true; + } + +out: + kdDebugFuncOut(trace); + return ret; +} + +/*! + * Use this function to search find devices with a special string property + * \param property QString with the name of the property + * \param keyval QString with value of the string property + * \param devices QStringList to return the found devices + * \return If the query was successful or not + */ +bool dbusHAL::halFindDeviceByString (QString property, QString keyval, QStringList *devices) { + kdDebugFuncIn(trace); + + DBusError error; + char ** found; + int num = 0; + bool ret = false; + + if (!initHAL() || property.isEmpty() || keyval.isEmpty()) + goto out; + + dbus_error_init(&error); + + found = libhal_manager_find_device_string_match (hal_ctx, property, keyval, &num, &error); + + if (dbus_error_is_set(&error)) { + kdError() << "Could not get list of devices with key: " << property + << "and string value: " << keyval << " error: " << error.message << endl; + dbus_error_free(&error); + libhal_free_string_array(found); + goto out; + } else { + for (int i = 0; i < num; ++i) { + QString _to_add = found[i]; + if (!_to_add.isEmpty()) *devices += _to_add; + } + libhal_free_string_array(found); + ret = true; + } + +out: + kdDebugFuncOut(trace); + return ret; +} + +/* ----> HAL section :: END <---- */ +/* ----> D-Bus methode calls functions :: START <---- */ +/*! + * This function call a D-Bus method + * \param interface QString with te dbus interface + * \param path QString with the object path + * \param object QString with the object name + * \param method QString with the name of the methode + * \param first_arg_type integer with the dbus type of the first argument + * \param ... more arguments + * \return If the query was successful or not + */ +bool dbusHAL::dbusSystemMethodCall( QString interface, QString path, QString object, QString method, + int first_arg_type, ... ) { + kdDebugFuncIn(trace); + + bool _ret = false; + va_list var_args; + + va_start(var_args, first_arg_type); + _ret = dbusMethodCall( interface, path, object, method, DBUS_BUS_SYSTEM, + NULL, -1, first_arg_type, var_args); + va_end(var_args); + + kdDebugFuncOut(trace); + return _ret; +} + + +/*! + * This overloaded function call a D-Bus method on the D-Bus system bus with a return value + * \param interface QString with the dbus interface + * \param path QString with the object path + * \param object QString with the object name + * \param method QString with the name of the method + * \param retvalue void pointer to arguments, if NULL we make a simple call + * \param retval_type Integer with the dbus type of the return value, set to -1 if retvalue is NULL + * \param first_arg_type Integer with the dbus type of the first argument followed by the value + * \return If the query was successful or not + */ +bool dbusHAL::dbusSystemMethodCall( QString interface, QString path, QString object, QString method, + void *retvalue, int retval_type, int first_arg_type, ... ) { + kdDebugFuncIn(trace); + + bool _ret = false; + va_list var_args; + + va_start(var_args, first_arg_type); + _ret = dbusMethodCall( interface, path, object, method, DBUS_BUS_SYSTEM, + retvalue, retval_type, first_arg_type, var_args); + va_end(var_args); + + kdDebugFuncOut(trace); + return _ret; +} + + +/*! + * This function call a D-Bus method with a return value + * \param interface QString with the dbus interface + * \param path QString with the object path + * \param object QString with the object name + * \param method QString with the name of the method + * \param dbus_type DBusBusType with the D-Bus BUS Type + * \param retvalue void pointer to arguments, if NULL we make a simple call + * \param retval_type Integer with the dbus type of the return value, set to -1 if retvalue is NULL + * \param first_arg_type Integer with the dbus type of the first argument followed by the value + * \param var_args va_list with more arguments + * \return If the query was successful or not + */ +bool dbusHAL::dbusMethodCall( QString interface, QString path, QString object, QString method, + DBusBusType dbus_type, void *retvalue, int retval_type, int first_arg_type, + va_list var_args ) { + kdDebugFuncIn(trace); + + DBusMessage *message; + DBusMessage *reply; + DBusError error; + bool ret = false; + + dbus_error_init(&error); + + dbus_connection = dbus_bus_get(dbus_type, &error); + + if (dbus_error_is_set(&error)) { + kdError() << "Could not get dbus connection: " << error.message << endl; + dbus_error_free(&error); + goto out; + } + + message = dbus_message_new_method_call( interface, path, object, method ); + dbus_message_append_args_valist(message, first_arg_type, var_args); + + if (retvalue == NULL) { + if (!dbus_connection_send(dbus_connection, message, NULL)) { + kdError() << "Could not send method call." << endl; + dbus_message_unref( message ); + goto out; + } + } else { + reply = dbus_connection_send_with_reply_and_block(dbus_connection, message, -1, &error); + + if (dbus_error_is_set(&error)) { + kdError() << "Could not send dbus message: " << error.message << endl; + dbus_message_unref(message); + dbus_error_free(&error); + goto out; + } + + int type = dbus_message_get_type(reply); + if (type == DBUS_MESSAGE_TYPE_METHOD_RETURN) { + if (!dbus_message_get_args(reply, &error, retval_type, retvalue, DBUS_TYPE_INVALID)){ + if (dbus_error_is_set(&error)) { + kdError() << "Could not get argument from reply: " + << error.message << endl; + dbus_error_free(&error); + } + dbus_message_unref(reply); + dbus_message_unref(message); + goto out; + } + } else { + kdError() << "Revieved invalid DBUS_MESSAGE_TYPE: " << type + << "expected: " << DBUS_MESSAGE_TYPE_METHOD_RETURN << endl; + dbus_message_unref(reply); + dbus_message_unref(message); + goto out; + } + } + + ret = true; // if we are here, everything should be okay + dbus_message_unref(message); + dbus_connection_flush(dbus_connection); + +out: + kdDebugFuncOut(trace); + return ret; +} + +/*! + * Function to call a suspend and call if resumed \ref callBackSuspend() + * to emit a resume signal. + * \param suspend a char pointer with the name of the suspend interface + * \return If the query was successful or not + */ +bool dbusHAL::dbusMethodCallSuspend ( const char *suspend ) { + kdDebugFuncIn(trace); + + DBusMessage *message; + DBusError error; + DBusPendingCall* pcall = NULL; + bool ret = false; + + dbus_error_init(&error); + dbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + + if (dbus_error_is_set(&error)) { + kdError() << "Could not get dbus connection: " << error.message << endl; + dbus_error_free(&error); + goto out; + } + + message = dbus_message_new_method_call( HAL_SERVICE, HAL_COMPUTER_UDI, HAL_PM_IFACE, suspend); + if (strcmp( suspend, "Suspend") == 0) { + int wake_up = 0; + dbus_message_append_args (message, DBUS_TYPE_INT32, &wake_up, DBUS_TYPE_INVALID); + } + + if (message) { + // need to set INT_MAX as default and not -1 + dbus_connection_send_with_reply (dbus_connection, message, &pcall, INT_MAX); + if (pcall) { + dbus_pending_call_ref (pcall); // really needed? + dbus_pending_call_set_notify (pcall, dbusHAL::callBackSuspend, NULL, NULL); + } + dbus_message_unref (message); + ret = true; + } + +out: + kdDebugFuncOut(trace); + return ret; +} + +/*! + * Slot called by D-Bus as set in \ref dbusMethodCallSuspend() + * Here we emit the resume signal. + */ +void dbusHAL::callBackSuspend (DBusPendingCall* pcall, void* /*data*/) { + kdDebugFuncIn(trace); + + DBusMessage* reply = NULL; + DBusError error; + int result; + bool failed = false; + + if (!pcall) { + kdError() << "dbusHAL::callBackSuspend - DBusPendingCall not set, return" << endl; + kdDebugFuncOut(trace); + return; + } + + reply = dbus_pending_call_steal_reply (pcall); + if (reply == NULL) { + kdError() << "dbusHAL::callBackSuspend - Got no reply, return" << endl; + goto out; + } + + dbus_error_init(&error); + + if (!dbus_message_get_args (reply, &error, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID)) { + if (dbus_error_is_set(&error)) { + kdError() << "Could not get argument from reply: " << error.message << endl; + dbus_error_free(&error); + } + + kdWarning() << "dbusHAL::callBackSuspend dbus_message_get_args failed, maybe timouted" << endl; + failed = true; + } + + dbus_message_unref (reply); + +out: + dbus_pending_call_unref (pcall); + + if (failed) + emit ((dbusHAL*) myInstance)->backFromSuspend( -1 ); + else + emit ((dbusHAL*) myInstance)->backFromSuspend( result ); + + kdDebugFuncOut(trace); + return; +} + + +/* ----> D-Bus methode calls functions :: END <---- */ +/* ---> PolicyKit method call section :: START <--- */ + +/*! + * Check if the user is privileged to a special privilege + * \param privilege QString with the name of the requested privilege + * \param udi QString with the UDI. + * \param ressource QString with the name of the ressource + * \param user QString with the name of the user. If empty the current user is used. + * \return int with info if the user is allowed or not. + * \retval 0 if not allowed + * \retval 1 if allowed + * \retval -1 if a error occurs or we could not query the interface + */ +int dbusHAL::isUserPrivileged(QString privilege, QString udi, QString ressource, QString user) { + kdDebugFuncIn(trace); + + const char *_unique_name; + const char *_user; + const char *_privilege; + + int retval = -1; + + if (user.isEmpty() || user.isNull()) + _user = getenv("USER"); + else + _user = user.latin1(); + + if (_user == NULL || privilege.isEmpty()) + goto out; + + _unique_name = dbus_bus_get_unique_name(dbus_connection); + _privilege = privilege.latin1(); + +#ifdef USE_LIBHAL_POLICYCHECK + DBusError error; + char *result; + + if (udi.isEmpty()) { + kdError() << "No UDI given ... could not lookup privileges" << endl; + goto out; + } + if (!hal_is_connected) { + kdError() << "HAL not running, could not call libhal for lookup privileges" << endl; + goto out; + } + + dbus_error_init(&error); + result = libhal_device_is_caller_privileged ( hal_ctx, udi.latin1(), _privilege, _unique_name, &error); + + if ( dbus_error_is_set( &error ) ) { + kdWarning() << "Error while lookup privileges: " << error.message << endl; + dbus_error_free( &error ); + retval = -1; + } else { + if (!strcmp(result, "yes")) { + retval = 1; + } else if (!strcmp(result, "no")) { + retval = 0; + } else { + retval = -1; + } + } + + libhal_free_string(result); +#else + // not sure if we need this, but to avoid problems + dbus_bool_t _retval; + const char *_ressource; + _ressource = ressource.latin1(); + + if (!dbusSystemMethodCall( "org.freedesktop.PolicyKit", + "/org/freedesktop/PolicyKit/Manager", + "org.freedesktop.PolicyKit.Manager", + "IsUserPrivileged", + &_retval, DBUS_TYPE_BOOLEAN, + DBUS_TYPE_STRING, &_unique_name, + DBUS_TYPE_STRING, &_user, + DBUS_TYPE_STRING, &_privilege, + DBUS_TYPE_STRING, &_ressource, + DBUS_TYPE_INVALID)) { + retval = -1; // only to be sure we have no changes trough the call + } else { + retval = (int) _retval; + } +#endif + +out: + kdDebugFuncOut(trace); + return retval; +} +/* ---> PolicyKit method call section :: END <--- */ + +/*! + * Use this SLOT to emit a reviced messages to the kpowersave. + * NOTE: Because of the filter function this need to be a public function. + * Don't use this function in any other place than this class. + * \param type enum with the type of the message + * \param message String with the message + * \param string String with additional info + */ +void dbusHAL::emitMsgReceived( msg_type type, QString message, QString string ) { + + if (message.startsWith("dbus.terminate")) + dbus_is_connected = false; + + if (type == POLICY_POWER_OWNER_CHANGED) { + if (message.startsWith("NOW_OWNER")) + aquiredPolicyPower = true; + else + aquiredPolicyPower = false; + } + + emit msgReceived_withStringString( type, message, string ); +} + +#include "dbusHAL.moc" +// --> functions which are not member of the class ... + +/*! + * This function is needed filter function for the D-Bus connection to filter + * all needed messages from the bus which are needful for KPowersave. + * \param connection existing connection to the D-Bus daemon + * \param message the recieved message from the D-Bus daemon + * \param data void pointer (see dbus bindings for more information) + * \return DBusHandlerResult + */ +DBusHandlerResult +filterFunction (DBusConnection *connection, DBusMessage *message, void */*data*/) { + kdDebugFuncIn(trace); + + bool reply_wanted; + char *value; + QString ifaceType; + + DBusError error; + dbus_error_init( &error ); + + if (dbus_message_is_signal (message, + DBUS_INTERFACE_LOCAL, + "Disconnected")){ + ((dbusHAL*) myInstance)->emitMsgReceived( DBUS_EVENT, "dbus.terminate", 0 ); + dbus_connection_unref(connection); + kdDebugFuncOut(trace); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if ( dbus_message_get_type( message ) != DBUS_MESSAGE_TYPE_SIGNAL ) { + if (trace) kdDebug() << "recieved message, but wasn't from type DBUS_MESSAGE_TYPE_SIGNAL" << endl; + kdDebugFuncOut(trace); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + ifaceType = dbus_message_get_interface( message ); + if (ifaceType == NULL) { + kdDebug() << "Received message from invalid interface" << endl; + kdDebugFuncOut(trace); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + reply_wanted = !dbus_message_get_no_reply( message ); + + if (ifaceType.startsWith(DBUS_INTERFACE_DBUS)) { + if(trace) kdDebug() << "Received from DBUS_INTERFACE_DBUS" << endl; + /* get the name of the signal */ + const char *signal = dbus_message_get_member( message ); + + /* get the first argument. This must be a string at the moment */ + dbus_message_get_args( message, &error, DBUS_TYPE_STRING, &value, DBUS_TYPE_INVALID ); + + if ( dbus_error_is_set( &error ) ) { + kdWarning() << "Received signal " << error.message << " but no string argument" << endl; + dbus_error_free( &error ); + kdDebugFuncOut(trace); + return DBUS_HANDLER_RESULT_HANDLED; + } + + if (trace) kdDebug() << "filter_function::SIGNAL=" << signal << " VALUE=" << value << endl; + + /* our name is... */ + if ( ! strcmp( signal, "NameAcquired" ) ) { + kdDebugFuncOut(trace); + return DBUS_HANDLER_RESULT_HANDLED; + } + + else if ( ! strcmp( signal, "NameOwnerChanged" )) { + char *service; + char *old_owner; + char *new_owner; + + if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &service, + DBUS_TYPE_STRING, &old_owner, + DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID)) { + if (!strcmp(service, "org.freedesktop.Hal")) { + if (!strcmp(new_owner, "") && strcmp(old_owner, "")) { + // Hal service stopped. + kdDebug() << "=== org.freedesktop.Hal terminated ===" << endl; + ((dbusHAL*) myInstance)->emitMsgReceived( DBUS_EVENT, + "hal.terminate", + NULL ); + } + else if (!strcmp(old_owner, "") && strcmp(new_owner, "")) { + // Hal service started. + kdDebug() << "=== org.freedesktop.Hal started ===" << endl; + ((dbusHAL*) myInstance)->emitMsgReceived( DBUS_EVENT, + "hal.started", + NULL ); + } + } else if (!strcmp(service, "org.freedesktop.Policy.Power")) { + const char *own_name; + + own_name = dbus_bus_get_unique_name(((dbusHAL*) myInstance)->get_DBUS_connection()); + + if (!strcmp(new_owner, own_name)) { + kdDebug() << "=== now owner of org.freedesktop.Policy.Power ===" << endl; + // we have now again the ower of the name! + ((dbusHAL*) myInstance)->emitMsgReceived( POLICY_POWER_OWNER_CHANGED, + "NOW_OWNER", + NULL ); + } else { + // some other has now the interface + kdDebug() << "=== someone owner of org.freedesktop.Policy.Power ===" << endl; + ((dbusHAL*) myInstance)->emitMsgReceived( POLICY_POWER_OWNER_CHANGED, + "OTHER_OWNER", + NULL ); + } + } + } + } + kdDebugFuncOut(trace); + return DBUS_HANDLER_RESULT_HANDLED; + } else if (ifaceType.startsWith("org.freedesktop.Hal.Manager")) { + kdDebug() << "Received from org.freedesktop.Hal.Manager" << endl; + char *udi; + + const char *signal = dbus_message_get_member( message ); + /* get the first argument. This must be a string at the moment */ + dbus_message_get_args( message, &error, DBUS_TYPE_STRING, &value, DBUS_TYPE_INVALID ); + + if ( dbus_error_is_set( &error ) ) { + kdWarning() << "Received signal, but no string argument: " << error.message << endl; + dbus_error_free( &error ); + kdDebugFuncOut(trace); + return DBUS_HANDLER_RESULT_HANDLED; + } + + if (dbus_message_get_args( message, &error, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID )) { + if (! strcmp(signal, "DeviceRemoved") || ! strcmp(signal, "DeviceAdded")) { + ((dbusHAL*) myInstance)->emitMsgReceived( HAL_DEVICE, signal, udi ); + kdDebug() << "org.freedesktop.Hal.Manager: uid: " << udi + << " signal: " << signal << endl; + } else { + kdWarning() << "Received unknown signal from org.freedesktop.Hal.Manager: " + << signal << endl; + } + } + kdDebugFuncOut(trace); + return DBUS_HANDLER_RESULT_HANDLED; + + } else if (ifaceType.startsWith("org.freedesktop.Hal.Device")) { + const char *udi = dbus_message_get_path (message); + const char *signal = dbus_message_get_member( message ); + + /* Code taken from libhal */ + if (! strcmp(signal, "PropertyModified")) { + if (trace) kdDebug() << "-------- PropertyModified ------" << endl; + int i, num_modifications; + DBusMessageIter iter; + DBusMessageIter iter_array; + + dbus_message_iter_init (message, &iter); + dbus_message_iter_get_basic (&iter, &num_modifications); + dbus_message_iter_next (&iter); + + dbus_message_iter_recurse (&iter, &iter_array); + + for (i = 0; i < num_modifications; i++) { + dbus_bool_t removed, added; + char *key; + DBusMessageIter iter_struct; + + dbus_message_iter_recurse (&iter_array, &iter_struct); + + dbus_message_iter_get_basic (&iter_struct, &key); + dbus_message_iter_next (&iter_struct); + dbus_message_iter_get_basic (&iter_struct, &removed); + dbus_message_iter_next (&iter_struct); + dbus_message_iter_get_basic (&iter_struct, &added); + + /* don't check if we really need this device, check this in an other class */ + ((dbusHAL*) myInstance)->emitMsgReceived( HAL_PROPERTY_CHANGED, udi, key); + kdDebug() << "PropertyModified: uid: " << udi << " key: " << key << endl; + + dbus_message_iter_next (&iter_array); + } + } else if (! strcmp(signal, "Condition")) { + if (trace) kdDebug() << "-------- Condition ------" << endl; + char *name, *detail; + + dbus_message_get_args( message, &error, DBUS_TYPE_STRING, &value, DBUS_TYPE_INVALID ); + + if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &detail, DBUS_TYPE_INVALID)) { + ((dbusHAL*) myInstance)->emitMsgReceived( HAL_CONDITION, name, detail ); + } else { + if (dbus_error_is_set( &error )) dbus_error_free( &error ); + } + } else { + kdDebug() << "Received unknown signal from org.freedesktop.Hal.Device: " + << signal << endl; + } + kdDebugFuncOut(trace); + return DBUS_HANDLER_RESULT_HANDLED; + } else if (ifaceType.startsWith("org.freedesktop.ConsoleKit.Session")) { + kdDebug() << "Received from org.freedesktop.ConsoleKit.Session" << endl; + + const char *session = dbus_message_get_path (message); + const char *signal = dbus_message_get_member( message ); + + if (! strcmp(signal, "ActiveChanged")) { + dbus_bool_t active; + + if (dbus_message_get_args( message, &error, DBUS_TYPE_BOOLEAN, &active, DBUS_TYPE_INVALID )) { + ((dbusHAL*) myInstance)->emitMsgReceived( CONSOLEKIT_SESSION_ACTIVE, + session, QString("%1").arg((int)active)); + } else { + if (dbus_error_is_set( &error )) dbus_error_free( &error ); + } + } else { + kdDebug() << "Received unknown signal from org.freedesktop.ConsoleKit.Session: " + << signal << endl; + kdDebugFuncOut(trace); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + kdDebugFuncOut(trace); + return DBUS_HANDLER_RESULT_HANDLED; + } else { + kdDebugFuncOut(trace); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } +} + +// --> some functions to get private members + +//! to get the current connection to D-Bus +DBusConnection * dbusHAL::get_DBUS_connection() { + return dbus_connection; +} diff --git a/src/dbusHAL.h b/src/dbusHAL.h new file mode 100644 index 0000000..9346f0a --- /dev/null +++ b/src/dbusHAL.h @@ -0,0 +1,214 @@ + /************************************************************************** + * Copyright (C) 2006-2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! +* \file dbusHAL.h +* \brief Headerfile for dbusHAL.cpp and the class \ref dbusHAL. +*/ +/*! +* \class dbusHAL +* \brief class for connection to HAL via D-Bus +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2006-2007 +*/ + +#ifndef _DBUSHAL_H_ +#define _DBUSHAL_H_ + +#ifndef DBUS_API_SUBJECT_TO_CHANGE +#define DBUS_API_SUBJECT_TO_CHANGE +#endif + +// Global Header +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +// QT - Header +#include <qstring.h> + +// D-Bus Header +#include <dbus/dbus.h> // needed for dbus_bool_t +#include <dbus/message.h> +#include <dbus/connection.h> + +// HAL Library +#include <hal/libhal.h> + +// kpowersave - Header +#include "kpowersave_debug.h" + +#define HAL_SERVICE "org.freedesktop.Hal" +#define HAL_PM_IFACE "org.freedesktop.Hal.Device.SystemPowerManagement" +#define HAL_LPANEL_IFACE "org.freedesktop.Hal.Device.LaptopPanel" +#define HAL_CPUFREQ_IFACE "org.freedesktop.Hal.Device.CPUFreq" +#define HAL_COMPUTER_UDI "/org/freedesktop/Hal/devices/computer" +#define CK_SERVICE "org.freedesktop.ConsoleKit" +#define CK_MANAGER_IFACE "org.freedesktop.ConsoleKit.Manager" +#define CK_MANAGER_OBJECT "/org/freedesktop/ConsoleKit/Manager" +#define CK_SESSION_IFACE "org.freedesktop.ConsoleKit.Session" + +enum msg_type { + ACPI_EVENT, + DBUS_EVENT, + HAL_DEVICE, + HAL_PROPERTY_CHANGED, + HAL_CONDITION, + CONSOLEKIT_SESSION_ACTIVE, + POLICY_POWER_OWNER_CHANGED +}; + +class dbusHAL : public QObject{ + Q_OBJECT + +private: + + //! QT connection to D-Bus + DBusQt::Connection* m_dBusQtConnection; + //! real connection to D-Bus + DBusConnection *dbus_connection; + //! HAL context + LibHalContext *hal_ctx; + + //! to store information if KPowersave is connected to D-Bus + /*! + * This boolean represent information about the state of the connection to D-Bus + * \li true: if connected + * \li false: if disconnected + */ + bool dbus_is_connected; + //! to store information if KPowersave is connected to HAL + /*! + * This boolean represent information about the state of the connection to HAL + * \li true: if connected + * \li false: if disconnected + */ + bool hal_is_connected; + + //! if we could claim the org.freedesktop.Policy.Power interface + /*! + * This boolean represent information if KPowersave could claim the + * org.freedesktop.Policy.Power interface from the D-Bus + * \li true: if aquired + * \li false: if not + */ + bool aquiredPolicyPower; + + /* D-Bus helper functions */ + //! to initialise the connection to D-Bus + bool initDBUS(); + //! to call a methode on a dbus interface with reply + bool dbusMethodCall( QString interface, QString path, QString object, QString method, + DBusBusType dbus_type, void *retvalue, int retval_type, + int first_arg_type, va_list var_args); + + //! function to be called back by DBusPendingCall::dbus_pending_call_set_notify() + static void callBackSuspend (DBusPendingCall* pcall, void* /*data*/); + + /* HAL helper functions */ + //! to initialise the connection to HAL + bool initHAL(); + //! to free the HAL context + void freeHAL(); + +public: + + //! default constructor + dbusHAL(); + //! default destructor + ~dbusHAL(); + + //! to reconnect to D-Bus and HAL + bool reconnect(); + //! to reconnect only HAL + bool reconnectHAL(); + //! to close the connection to D-Bus and HAL + bool close(); + + //! to aquire the org.freedesktop.Policy.Power interface + bool aquirePolicyPowerIface(); + //! to release the org.freedesktop.Policy.Power interface + bool releasePolicyPowerIface(); + //! to check if the org.freedesktop.Policy.Power interface has an owner + bool isPolicyPowerIfaceOwned(); + + // --- helper to get private members of the class --- // + //! to get information if KPowersave is connected to D-Bus + bool isConnectedToDBUS(); + //! to get information if KPowersave is connected to HAL + bool isConnectedToHAL(); + //! to get info about claim org.freedesktop.Policy.Power interface + bool aquiredPolicyPowerInterface(); + + //! return the current HAL context + LibHalContext *get_HAL_context(); + //! return the current DBus connection + DBusConnection *get_DBUS_connection(); + + /* HAL device information stuff */ + //! Query a integer device property from HAL + bool halGetPropertyInt(QString udi, QString property, int *returnval); + //! Query a bolean device property from HAL + bool halGetPropertyBool(QString udi, QString property, bool *returnval); + //! Query a string device property from HAL + bool halGetPropertyString(QString udi, QString property, QString *returnval); + //! Query a string list device property from HAL + bool halGetPropertyStringList (QString udi, QString property, QStringList *devices); + //! Query a capability for a HAL device + bool halQueryCapability(QString udi, QString capability, bool *returnval); + + /* functions to find devices and check stuff */ + //! check if a property exist on a device + bool halDevicePropertyExist(QString udi, QString property); + //! to find a device by capability + bool halFindDeviceByCapability (QString capability, QStringList *devices); + //! to find a device by a string property + bool halFindDeviceByString (QString property, QString keyval, QStringList *devices); + + /* D-Bus helper functions */ + + /* functions to call methodes */ + //! to call a methode on a dbus system bus method without reply + bool dbusSystemMethodCall( QString interface, QString path, QString object, QString method, + int first_arg_type, ... ); + //! to call a methode on a dbus system bus method with reply + bool dbusSystemMethodCall( QString interface, QString path, QString object, QString method, + void *retvalue, int retval_type, int first_arg_type, ... ); + + //! to call a suspend method on HAL + bool dbusMethodCallSuspend ( const char *suspend ); + + /* PolicyKit call helper */ + //! check if the user has a requested privilege + int isUserPrivileged( QString privilege, QString udi, QString ressource = "", QString user = QString()); + + //! wrapper to emit a signal with a event from HAL + void emitMsgReceived( msg_type type, QString message, QString string ); + +signals: + //! signal with message to forward from D-Bus to HAL + void msgReceived_withStringString( msg_type, QString, QString ); + //! signal if we resumed! + void backFromSuspend( int result ); +}; + +//! filter function to filter out needed information from D-Bus messages +DBusHandlerResult filterFunction (DBusConnection *connection, DBusMessage *message, void *data); + +#endif diff --git a/src/detailed_Dialog.ui b/src/detailed_Dialog.ui new file mode 100644 index 0000000..79a9335 --- /dev/null +++ b/src/detailed_Dialog.ui @@ -0,0 +1,642 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>detailed_Dialog</class> +<widget class="QDialog"> + <property name="name"> + <cstring>detailed_Dialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>287</width> + <height>381</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>kpowersave</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>GeneralGroup</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>General Information</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSplitter" row="0" column="1"> + <property name="name"> + <cstring>splitter7</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout17</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="1"> + <property name="name"> + <cstring>InfoLabelValue</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <bold>1</bold> + </font> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>InfoLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignTop</set> + </property> + </widget> + </grid> + </widget> + <spacer> + <property name="name"> + <cstring>spacer13</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>10</width> + <height>50</height> + </size> + </property> + </spacer> + </widget> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout18</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>InfoPictogram</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer14</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>MinimumExpanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </grid> + </widget> + <widget class="QGroupBox" row="1" column="0"> + <property name="name"> + <cstring>BatteryGroup</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Battery Status</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>118</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget" row="0" column="1"> + <property name="name"> + <cstring>layout15</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="3" column="0"> + <property name="name"> + <cstring>layout14</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>LabelAC</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>AC Adapter</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer9_3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KLed"> + <property name="name"> + <cstring>LedAC</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer9</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>LabelACStatus</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>plugged in</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="2" column="0"> + <property name="name"> + <cstring>powerConsLayout</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>tl_powerConsDesc</cstring> + </property> + <property name="text"> + <string>Power Consumtion: </string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>tl_powerConsValue</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </hbox> + </widget> + <widget class="QFrame" row="0" column="0"> + <property name="name"> + <cstring>BatteryFrame</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Raised</enum> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout12</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>90</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>BatteryPictogram</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + <widget class="QGroupBox" row="2" column="0"> + <property name="name"> + <cstring>ProcessorGroup</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Processor Status</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout12_2</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer5_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>90</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>ProcessorPictogram</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <widget class="QSplitter" row="0" column="1"> + <property name="name"> + <cstring>splitter6</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout16</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QFrame" row="0" column="0"> + <property name="name"> + <cstring>ProcessorFrame</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Raised</enum> + </property> + </widget> + </grid> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2_2_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget" row="3" column="0"> + <property name="name"> + <cstring>layout19</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="0" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>230</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>OkButton</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>OK</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/detaileddialog.cpp b/src/detaileddialog.cpp new file mode 100644 index 0000000..c48df79 --- /dev/null +++ b/src/detaileddialog.cpp @@ -0,0 +1,497 @@ +/*************************************************************************** + * Copyright (C) 2006 by Daniel Gollub * + * <dgollub@suse.de> * + * 2006-2007 Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! + * \file detaileddialog.cpp + * \brief In this file can be found the detailed dialog related code. + * \author Daniel Gollub <dgollub@suse.de> + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2006-2007 + */ + +// KDE headers: +#include <kled.h> +#include <kiconloader.h> +#include <klocale.h> + +// QT headers: +#include <qpushbutton.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qtimer.h> +#include <qgroupbox.h> + +// own headers +#include "detaileddialog.h" + +/*! + * This is the default constructor of the class detaileddialog. + */ +detaileddialog::detaileddialog( HardwareInfo *_hwinfo, QPixmap *_pixmap, Settings *_set, + QWidget* parent, const char* name ) + : detailed_Dialog( parent, name, false, WDestructiveClose ) { + kdDebugFuncIn(trace); + hwinfo = _hwinfo; + config = _set; + pixmap = _pixmap; + primaryBatteries = hwinfo->getPrimaryBatteries(); + cpuInfo = new CPUInfo(); + + int batteries = primaryBatteries->getNumBatteries(); + numOfCPUs = cpuInfo->getCPUNum(); + + this->setCaption(i18n("KPowersave Information Dialog")); + + // use this as compromise with current translation process + // TODO: remove them in the next translation round + GeneralGroup->setTitle(i18n("Miscellaneous")); + ProcessorGroup->setTitle(i18n("CPUs")); + + ProcessorGridLayout = new QGridLayout(ProcessorFrame, numOfCPUs, 2, 0, 5, "ProcessorGridLayout"); + + if (batteries > 0) { + if (batteries > 1) batteries++; + + BatteryGroup->setTitle(i18n("Battery state:").remove(":")); + BatteryGridLayout = new QGridLayout(BatteryFrame, batteries, 2, 0, 5, "BatteryGridLayout"); + + for (int i = 0; i < batteries; i++) { + QLabel *Label = new QLabel(BatteryFrame, "BatteryLabel"); + if ((primaryBatteries->getNumBatteries() > 1) && (i == 0)) + Label->setText( i18n( "Total:" )); + else if ((primaryBatteries->getNumBatteries() > 1) && (i > 0)) + Label->setText( i18n( "Battery %1" ).arg(i)); + else + Label->setText( i18n( "Battery %1" ).arg(i + 1)); + + BatteryGridLayout->addWidget( Label, i , 0); + + KProgress *PBar = new KProgress(BatteryFrame, "BatteryPBar"); + PBar->setTextEnabled(true); + + BatteryPBar.append( PBar ); + BatteryGridLayout->addWidget( PBar, i , 1); + } + BatteryFrame->adjustSize(); + tl_powerConsDesc->hide(); + tl_powerConsValue->hide(); + connect(hwinfo, SIGNAL(generalDataChanged()), this, SLOT(setBattery())); + connect(primaryBatteries, SIGNAL(batteryChanged()), this, SLOT(setBattery())); + connect(primaryBatteries, SIGNAL(batteryChargingStateChanged(int)), this, + SLOT(setPowerConsumption())); + connect(primaryBatteries, SIGNAL(batteryRateChanged()), this, + SLOT(setPowerConsumption())); + setBattery(); + setPowerConsumption(); + } else { + BatteryGroup->hide(); + } + + cpuInfo->checkCPUSpeed(); + + ProcessorPictogram->setPixmap(SmallIcon("processor", 22)); + + for (int i = 0; i < numOfCPUs; i++) { + QLabel *Label = new QLabel(ProcessorFrame, "ProcessorLabel"); + Label->setText( i18n( "Processor %1" ).arg(i + 1)); + ProcessorGridLayout->addWidget( Label, i , 0); + + KProgress *CPUPBar = new KProgress(ProcessorFrame, "ProcessorPBar"); + CPUPBar->setTextEnabled(true); + + ProcessorPBar.append( CPUPBar ); + ProcessorGridLayout->addWidget( CPUPBar, i , 1); + } + ProcessorFrame->adjustSize(); + + connect(OkButton, SIGNAL(clicked()), this, SLOT(closeDetailedDlg())); + connect(hwinfo, SIGNAL(ACStatus(bool)), this, SLOT(setAC())); + // TODO: replace event + //connect(pd, SIGNAL(schemeDataChanged()), this, SLOT(setInfos())); + connect(hwinfo, SIGNAL(generalDataChanged()), this, SLOT(setInfos())); + + if (hwinfo->supportCPUFreq() || cpuInfo->cpuFreqHW) { + // Check if cpufreq is available + cpuInfo->getCPUMaxSpeed(); + setProcessor(); + connect(hwinfo, SIGNAL(currentCPUFreqPolicyChanged()), this, SLOT(setInfos())); + } else { + // .. if not, use cpu throttling + if (!cpuInfo->getCPUThrottlingState() || numOfCPUs <= 1) { + connect(hwinfo, SIGNAL(generalDataChanged()), this, SLOT(setProcessorThrottling())); + } + setProcessorThrottling(); + } + + setAC(); + setInfos(); + + kdDebugFuncOut(trace); +} + +/*! This is the default destructor of class detaileddialog. */ +detaileddialog::~detaileddialog() { + kdDebugFuncIn(trace); + // no need to delete child widgets, Qt does it all for us +} + +/*! + * \b SLOT called if the dialog is closed by the user. + * We do some cleanups here. + */ +void detaileddialog::closeDetailedDlg() { + kdDebugFuncIn(trace); + + this->close(); + delete(this); +} + +/*! + * \b SLOT to set up the battery progress widgets. + */ +void detaileddialog::setBattery() { + kdDebugFuncIn(trace); + + QString minutes; + int batteries = 0; + + + // refresh battery collection + primaryBatteries = hwinfo->getPrimaryBatteries(); + QPtrList<Battery> allBatteries = hwinfo->getAllBatteries(); + + batteries = primaryBatteries->getNumBatteries(); + + if (batteries > 1) batteries++; + + for (int i=0; i < batteries ; i++) { + int _r_min = 0; + int _r_per = 0; + int _c_state = UNKNOWN_STATE; + bool _present = false; + + BatteryPBar[i]->setTextEnabled(true); + BatteryPBar[i]->reset(); + + if ( (primaryBatteries->getNumBatteries() > 1) && (i == 0) ) { + // first progressbar with overall infos + + _r_min = primaryBatteries->getRemainingMinutes(); + _r_per = primaryBatteries->getRemainingPercent(); + _c_state = primaryBatteries->getChargingState(); + if (primaryBatteries->getNumPresentBatteries() > 0) + _present = true; + } + else { + // find the related primary battery + int _current = 0; + Battery *bat; + for (bat = allBatteries.first(); bat; bat = allBatteries.next() ) { + if (bat->getType() == primaryBatteries->getBatteryType()) { + _current++; + + if (!bat->isPresent()) { + _present = false; + } + else { + _r_min = bat->getRemainingMinutes(); + _r_per = bat->getPercentage(); + _c_state = bat->getChargingState(); + _present = true; + } + + if (_current == i) { + break; + } + + } + } + } + + if (!_present) { + BatteryPBar[i]->setFormat(i18n("not present")); + BatteryPBar[i]->setProgress(0); + BatteryPBar[i]->setEnabled(false); + } else { + int hours = _r_min / 60; + minutes.setNum(_r_min % 60); + minutes = minutes.rightJustify(2, '0'); + + // CHARG_STATE_CHARG_DISCHARG --> display only the percentage + if (_c_state == UNKNOWN_STATE || _r_min < 0 ) { + BatteryPBar[i]->setFormat("%p%"); + } else if (_c_state == CHARGING && hwinfo->hasAPM() ) { + // this should fix apm, where we have no time info if charging + BatteryPBar[i]->setFormat("%p% " + i18n("charged")); + } else if (_c_state == CHARGING) { + QString temp = i18n("%1:%2 h until charged").arg(hours).arg(minutes); + BatteryPBar[i]->setFormat(temp); + } else if (_c_state == DISCHARGING) { + QString temp = i18n("%1:%2 h remaining").arg(hours).arg(minutes); + BatteryPBar[i]->setFormat(temp); + + } else { + //fallback + BatteryPBar[i]->setFormat(i18n("unknown")); + } + + if (_r_per < 0) + BatteryPBar[i]->setProgress(0); + else + BatteryPBar[i]->setProgress(_r_per); + BatteryPBar[i]->setEnabled(true); + } + } + + BatteryPictogram->setPixmap(*pixmap); + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to set up the Processor/CPU progress bar widgets. + */ +void detaileddialog::setPowerConsumption() { + kdDebugFuncIn(trace); + + // refresh battery collection + primaryBatteries = hwinfo->getPrimaryBatteries(); + int rate = primaryBatteries->getCurrentRate(); + + if (rate > 0 && !primaryBatteries->getChargeLevelUnit().isEmpty()) { + + QString _val; + _val.setNum(rate); + _val += " " + primaryBatteries->getChargeLevelUnit().remove('h'); + + tl_powerConsValue->setText(_val); + + if (!tl_powerConsDesc->isShown()) { + tl_powerConsDesc->show(); + tl_powerConsValue->show(); + } + } else { + if (tl_powerConsDesc->isShown()) { + tl_powerConsDesc->hide(); + tl_powerConsValue->hide(); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to set up the Processor/CPU progress bar widgets. + */ +void detaileddialog::setProcessor() { + kdDebugFuncIn(trace); + + cpuInfo->checkCPUSpeed(); + + for (int i=0; i < numOfCPUs; i++) { + kdDebug() << "ID: " << i << "(" << cpuInfo->cpufreq_speed.count() + << ") cur_freq: " << cpuInfo->cpufreq_speed[i] << " max_freq: " + << cpuInfo->cpufreq_max_speed[i] << endl; + + //ProcessorPBar[i]->setTextEnabled(true); + if (cpuInfo->cpufreq_speed[i] > 0) { + // CPU/Core is back from offline + if(ProcessorPBar[i]->progress() == 0) + cpuInfo->getCPUMaxSpeed(); + + if(ProcessorPBar[i]->progress() != cpuInfo->cpufreq_speed[i]) { + // get max cpu freq and set it to the max of the progressbar + int maxfreq = cpuInfo->cpufreq_max_speed[i]; + ProcessorPBar[i]->setTotalSteps(maxfreq); + + // display 1400 MHz instead of 1400% + ProcessorPBar[i]->setFormat(i18n("%v MHz")); + ProcessorPBar[i]->setProgress(cpuInfo->cpufreq_speed[i]); + ProcessorPBar[i]->setEnabled(true); + } + } else { + ProcessorPBar[i]->setFormat(i18n("deactivated")); + ProcessorPBar[i]->setProgress(0); + ProcessorPBar[i]->setEnabled(false); + } + } + QTimer::singleShot(333, this, SLOT(setProcessor())); + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to set up the Processor/CPU bar widgets for cpu throttling machines. + */ +void detaileddialog::setProcessorThrottling() { + kdDebugFuncOut(trace); + + bool throttling = cpuInfo->getCPUThrottlingState(); + cpuInfo->checkCPUSpeedThrottling(); + + for (int i=0; i < numOfCPUs; i++) { + if (throttling) + kdDebug() << "Throttling CPU : " << i << " - freq: " << cpuInfo->cpufreq_speed[i] + << " - throttling state: " << cpuInfo->cpu_throttling[i] << "%" << endl; + else + kdDebug() << "CPU - freq: " << cpuInfo->cpufreq_speed[i] << endl; + + if (throttling && cpuInfo->cpufreq_speed[i] > 0 && cpuInfo->cpu_throttling[i] >= 0) { + // get max cpu freq and set it to the max of the progressbar + ProcessorPBar[i]->setTotalSteps(100); + QString ProgressString = QString("%1% (%2 MHz)").arg(100 - cpuInfo->cpu_throttling[i]).arg(cpuInfo->cpufreq_speed[i]); + ProcessorPBar[i]->setFormat(i18n(ProgressString)); + ProcessorPBar[i]->setProgress(100 - cpuInfo->cpu_throttling[i]); + ProcessorPBar[i]->setEnabled(true); + } else if (cpuInfo->cpufreq_speed[i] < 0) { + ProcessorPBar[i]->setFormat(i18n("deactivated")); + ProcessorPBar[i]->setProgress(0); + ProcessorPBar[i]->setEnabled(false); + } else { + ProcessorPBar[i]->setTotalSteps(cpuInfo->cpufreq_speed[i]); + ProcessorPBar[i]->setFormat(i18n("%v MHz")); + ProcessorPBar[i]->setProgress(cpuInfo->cpufreq_speed[i]); + ProcessorPBar[i]->setEnabled(true); + } + } + + if (throttling || numOfCPUs > 1) { + // currently there are no events we can use to get actual data + // so we recheck data ever 2 secs to register changes in the + // throttling state and if a CPU/core online state change + QTimer::singleShot(2000, this, SLOT(setProcessorThrottling())); + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to set up the AC status within the Led widget. + */ +void detaileddialog::setAC() { + kdDebugFuncIn(trace); + + if (hwinfo->getAcAdapter()) { + LabelACStatus->setText( i18n("plugged in") ); + LedAC->on(); + } else { + LedAC->off(); + LabelACStatus->setText( i18n("unplugged") ); + } + + setInfos(); + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to set all additional informtation as e.g. CPUFrequency policy + * or current scheme + */ +void detaileddialog::setInfos() { + kdDebugFuncOut(trace); + + QString display; + QString displayValue; + + if(!config->currentScheme.isEmpty()) + display += i18n("Current Scheme: ") + "\n"; + displayValue += i18n(config->currentScheme) + "\n"; + if(config->currentScheme == config->ac_scheme) + InfoPictogram->setPixmap(SmallIcon("scheme_power", 22)); + else if(config->currentScheme == config->battery_scheme) + InfoPictogram->setPixmap(SmallIcon("scheme_powersave", 22)); + else if(config->currentScheme == "Acoustic") + InfoPictogram->setPixmap(SmallIcon("scheme_acoustic", 22)); + else if(config->currentScheme == "Presentation") + InfoPictogram->setPixmap(SmallIcon("scheme_presentation", 22)); + else if(config->currentScheme == "AdvancedPowersave") + InfoPictogram->setPixmap(SmallIcon("scheme_advanced_powersave", 22)); + else + InfoPictogram->setPixmap(SmallIcon("kpowersave", 22)); + + if(hwinfo->isOnline()) { + if (hwinfo->supportCPUFreq()) { + display += i18n("Current CPU Frequency Policy:") + "\n"; + switch (hwinfo->getCurrentCPUFreqPolicy()){ + case PERFORMANCE: + displayValue += i18n("Performance") + "\n"; + break; + case DYNAMIC: + displayValue += i18n("Dynamic") + "\n"; + break; + case POWERSAVE: + displayValue += i18n("Powersave") + "\n"; + break; + default: + displayValue += i18n("unknown") + "\n"; + break; + } + } + + // refresh battery collection + primaryBatteries = hwinfo->getPrimaryBatteries(); + int batteries = primaryBatteries->getNumBatteries(); + QPtrList<Battery> allBatteries = hwinfo->getAllBatteries(); + + if (batteries > 0 && primaryBatteries->getNumPresentBatteries() > 0) { + + display += i18n("Battery state:") + "\n"; + switch (primaryBatteries->getBatteryState()){ + case BAT_CRIT: + displayValue += i18n("Critical") + "\n"; + break; + case BAT_LOW: + displayValue += i18n("Low") + "\n"; + break; + case BAT_WARN: + displayValue += i18n("Warning") + "\n"; + break; + case BAT_NORM: + displayValue += i18n("ok") + "\n"; + break; + default: + displayValue += i18n("unknown") + "\n"; + break; + } + } + + if(hwinfo->supportBrightness()) { + display += i18n("Set brightness supported:") + "\n"; + displayValue += i18n("yes") + "\n"; + } else { + display += i18n("Set brightness supported:") + "\n"; + displayValue += i18n("no") + "\n"; + } + + display += i18n("HAL Daemon:"); + displayValue += i18n("running"); + } + else { + display += i18n("HAL Daemon:"); + displayValue += i18n("not running"); + } + + if(!display.isEmpty()) + InfoLabel->setText(display); + + InfoLabelValue->setText(displayValue); + kdDebugFuncOut(trace); +} + +#include "detaileddialog.moc" diff --git a/src/detaileddialog.h b/src/detaileddialog.h new file mode 100644 index 0000000..3873030 --- /dev/null +++ b/src/detaileddialog.h @@ -0,0 +1,113 @@ +/*************************************************************************** + * Copyright (C) 2006 by Daniel Gollub * + * <dgollub@suse.de> * + * Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +#ifndef DETAILEDDIALOG_H +#define DETAILEDDIALOG_H + +// own headers: +#include "detailed_Dialog.h" + +// KDE headers: +#include <kprogress.h> + +// other QT headers: +#include <qpixmap.h> + +// own headers: +#include "hardware.h" +#include "hardware_cpu.h" +#include "settings.h" +#include "hardware_batteryCollection.h" + +/*! +* \file detaileddialog.h +* \brief Headerfile for detaileddialog.cpp and the class \ref detaileddialog. +*/ + /*! + * \class detaileddialog + * \brief The class for the detailed information dialog + * \author Daniel Gollub, <dgollub@suse.de> + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2006 + */ +class detaileddialog: public detailed_Dialog { + + Q_OBJECT + +public: + //! default constructor + detaileddialog(HardwareInfo *_hwinfo, QPixmap *_pixmap, Settings *_set, QWidget *parent = 0, const char *name = 0); + //! default destructor + ~detaileddialog(); + +private slots: + //! to close the dialog + void closeDetailedDlg(); + //! to setup the battery progress widgets + void setBattery(); + //! to setup the current power consumtion widgets + void setPowerConsumption(); + //! to setup the CPU progress widgets + void setProcessor(); + //! to setup the Throttling CPU progress widgets + void setProcessorThrottling(); + //! to set the state AC KLed + void setAC(); + //! to set all other information + void setInfos(); + +private: + //! pointer to class HardwareInfo to get cpu/battey/AC information + HardwareInfo *hwinfo; + //! pointer to class CPUInfo to get CPU information + CPUInfo *cpuInfo; + //! pointer to hardware information about the primary batteries. + BatteryCollection *primaryBatteries; + //! pointer to class settinfs to get the current settings + Settings *config; + + //! pointer to the kpowersave class + QPixmap *pixmap; + + //! the numbers of CPUs in the system + int numOfCPUs; + + //! list of progressbars for battery information + /*! + * This QValueList with type KProgress contains the list + * of battery progress widgets. Each element represent + * one battery or batteryslot + */ + QValueList<KProgress *> BatteryPBar; + //! list of progressbars for CPU information + /*! + * This QValueList with type KProgress contains the list + * of CPU progress widgets. Each element represent one CPU. + */ + QValueList<KProgress *> ProcessorPBar; + + //! QGridLayout for Battery progress widgets + QGridLayout* BatteryGridLayout; + //! QGridLayout for Processor progress widgets + QGridLayout* ProcessorGridLayout; +}; + +#endif diff --git a/src/dummy.cpp b/src/dummy.cpp new file mode 100644 index 0000000..4db9268 --- /dev/null +++ b/src/dummy.cpp @@ -0,0 +1,127 @@ +/*************************************************************************** + * Copyright (C) 2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! \file dummy.cpp + * \brief This file contains unused strings for translation + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \version 0.0.1 + * \date 2007 + */ + +#include <qstring.h> +#include <klocale.h> + +class dummy { + + dummy() { + QString dummy; + + // from configuredialog.cpp: + dummy = i18n("If the current desktop user is inactive, dim the display to:"); + dummy = i18n("Enable dim display on inactivity"); + dummy = i18n("Blacklist"); + dummy = i18n("Here you can add programs which should, if running, prevent the dimming " + "of the display."); + dummy = i18n("Would you like to import a predefined blacklist?"); + dummy = i18n("Disable CPUs/Cores"); + dummy = i18n("Max. running CPUs:"); + dummy = i18n("Max. running CPUs/Cores:"); + dummy = i18n("Min. running CPUs:"); + dummy = i18n("Min. running CPUs/Cores:"); + dummy = i18n("Enable to switch off CPUs/cores"); + dummy = i18n("You have a multiprocessor/multicore machine."); + dummy = i18n("You can disable CPUs/cores to reduce power consumption and save battery power."); + dummy = i18n("Device"); + dummy = i18n("Devices"); + dummy = i18n("Device class"); + dummy = i18n("activate"); + dummy = i18n("Activate"); + dummy = i18n("deactivate"); + dummy = i18n("Deactivate"); + dummy = i18n("activated"); + dummy = i18n("deactivated"); + dummy = i18n("do nothing"); + dummy = i18n("Deactivate following devices:"); + dummy = i18n("Activate following devices"); + dummy = i18n("Reactivate following devices"); + dummy = i18n("Deactivate following device classes:"); + dummy = i18n("Activate following devices classes"); + dummy = i18n("Reactivate following device classes"); + dummy = i18n("If the scheme switched all devices are again activated."); + dummy = i18n("This is a experimental feature."); + dummy = i18n("If you have problems with this feature, please report them."); + dummy = i18n("Select one of the available devices and click on "); + dummy = i18n("Select one of the available device classes and click on "); + dummy = i18n("Select one or more of the available devices and click on "); + dummy = i18n("Select one or more of the available device classes and click on "); + dummy = i18n("Please note: If you e.g. deactivate a network device you may lose your " + "internet connection."); + dummy = i18n("<b>Note:</b> If you select this option, the computer will suspend or standby " + "if the current user is inactive for the defined time. <br><br> This feature " + "can also produce problems with some programs, such as video players or " + "cd burner. These programs can be blacklisted by checking <b>Enable " + "scheme-specific blacklist</b> and click <b>Edit Blacklist...</b>. If this " + "does not help, report the problem or deactivate autosuspend.<br><br> " + "Really use this option?"); + dummy = i18n("Try to use only one CPU/Core."); + dummy = i18n("Reduce power consumption by try to use only one CPU/Core instead of spreading " + "the work over all/multiple CPUs."); + + // for settings.cpp: + dummy = i18n("Could not load the global configuration."); + dummy = i18n("Could not load the requested scheme configuration."); + dummy = i18n("Configure the current scheme."); + dummy = i18n("Try loading the default configuration."); + dummy = i18n("Maybe the global configuration file is empty or missing."); + + // for kpowersave.cpp: + dummy = i18n("Cannot connect to D-Bus. The D-Bus daemon may not be running."); + dummy = i18n("Scheme switched to %1. \n Deactivate following devices: %2").arg("").arg(""); + dummy = i18n("Scheme switched to %1. \n Activate following devices: %2").arg("").arg(""); + dummy = i18n("Report ..."); + dummy = i18n("Suspend to RAM is not supported on your machine."); + dummy = i18n("Additionally, please mail the output of %1 to %2 . Thanks!").arg("").arg(""); + dummy = i18n("Power consumption"); + + // for screen.cpp + dummy = i18n("KScreensaver not found."); + dummy = i18n("Try locking with XScreensaver or xlock."); + dummy = i18n("XScreensaver not found."); + dummy = i18n("Try locking the screen with xlock."); + dummy = i18n("XScreensaver and xlock not found. It is not possible to lock the screen. " + "Check your installation."); + + // for detaileddialog.cpp: + dummy = i18n("D-Bus daemon:"); + dummy = i18n("ConsoleKit daemon:"); + dummy = i18n("Autosuspend activated:"); + dummy = i18n("Autodimm activated:"); + dummy = i18n("enabled"); + dummy = i18n("Session active:"); + + // for countdowndialog.cpp + dummy = i18n("The display get dimmed down to %1% in: ").arg(30); + + // other ConsoleKit related stuff + dummy = i18n("Could not call %1. The current desktop session is not active.").arg(""); + dummy = i18n("Could not set %1. The current desktop session is not active.").arg(""); + dummy = i18n("Stopped %1. The current desktop session is now inactive.").arg(""); + dummy = i18n("Restarted %1. The current desktop session is now active again.").arg(""); + } +}; diff --git a/src/eventsrc b/src/eventsrc new file mode 100644 index 0000000..88ccc0b --- /dev/null +++ b/src/eventsrc @@ -0,0 +1,364 @@ +[!Global!] +IconName=kpowersave +Comment=KPowersave +Comment[cs]=KPowersave +Comment[de]=KPowersave +Comment[es]=KPowersave +Comment[fr]=KPowersave +Comment[it]=KPowersave +Comment[ja]=KPowersave +Comment[pl]=KPowersave +Comment[pt]=KPowersave +Comment[pt_BR]=KPowersave +Comment[ru]=KPowersave +Comment[zh_CN]=KPowersave +Comment[zh_TW]=KPowersave + +[plug_event] +Name=PlugEvent +Comment=AC adapter plugged in +Comment[cs]=Připojen do sítě +Comment[de]=Netzstecker angeschlossen +Comment[es]=Adaptador de CA conectado +Comment[fr]=Adaptateur CA branché +Comment[it]=Adattatore CA collegato +Comment[ja]=ACアダプタプラグ接続 +Comment[pl]=Zasilacz sieciowy podłączony +Comment[pt]=Foi ligado o Adaptador CA +Comment[pt_BR]=Adaptador de CA conectado +Comment[ru]=Питание подключено +Comment[zh_CN]=AC 适配器已插入 +Comment[zh_TW]=已插入 AC 介面卡 +default_sound=KDE_Dialog_Appear.ogg +default_presentation=17 + +[unplug_event] +Name=UnplugEvent +Comment=AC adpater unplugged +Comment[cs]=Odpojen ze sítě +Comment[de]=Netzstecker entfernt +Comment[es]=Adaptador de CA desconectado +Comment[fr]=Adaptateur CA non branché +Comment[it]=Adattatore CA scollegato +Comment[ja]=ACアダプタプラグ非接続 +Comment[pl]=Zasilacz sieciowy odłączony +Comment[pt]=O Adaptador CA foi desligado +Comment[pt_BR]=Adaptador de CA desconectado +Comment[ru]=Питание отключено +Comment[zh_CN]=AC 适配器已拔出 +Comment[zh_TW]=未插入 AC 介面卡 +default_sound=KDE_Dialog_Disappear.ogg +default_presentation=17 + +[battery_warning_event] +Name=BatteryWarningEvent +Comment=Battery charge dropped to level WARNING +Comment[cs]=Stav baterie dosáhl úrovně POPLACH +Comment[de]=Batteriestand erreicht Level WARNUNG +Comment[es]=El nivel de carga de la batería es ADVERTENCIA +Comment[fr]=Le niveau de charge de la batterie est tombé au niveau AVERTISSEMENT +Comment[it]=La carica della batteria è sul livello AVVERTENZA +Comment[ja]=充電量が警告レベルまで下がりました +Comment[pl]=Naładowanie baterii spadło do poziomu OSTRZEŻENIE +Comment[pt]=Estado da bateria baixou para o nível de AVISO +Comment[pt_BR]=A carga da bateria caiu para o nível AVISO +Comment[ru]=Уровень заряда батареи сменился на ПРЕДУПРЕЖДЕНИ +Comment[zh_CN]=电池电量降至"警告"级别 +Comment[zh_TW]=電池充電量已降至「警告」層級 +default_sound=KDE_Event_1.ogg +default_presentation=17 + +[battery_low_event] +Name=BatteryLowEvent +Comment=Battery charge dropped to level LOW +Comment[cs]=Stav baterie dosáhl NÍZKĚ úrovně +Comment[de]=Batteriestand erreicht Level NIEDRIG +Comment[es]=El nivel de carga de la batería es BAJO +Comment[fr]=Le niveau de charge de la batterie est tombé au niveau FAIBLE +Comment[it]=La carica della batteria è sul livello BASSA +Comment[ja]=充電量が低レベルまで下がりました +Comment[pl]=Naładowanie baterii spadło do poziomu NISKI +Comment[pt]=Estado da bateria baixou para o nível de BAIXO +Comment[pt_BR]=A carga da bateria caiu para o nível BAIXO +Comment[ru]=Состояние батареи изменилось к НИЗКОМУ +Comment[zh_CN]=电池电量降至"低电量"级别 +Comment[zh_TW]=電池充電量已降至「低」層級 +default_sound=KDE_Event_1.ogg +default_presentation=17 + +[battery_critical_event] +Name=BatteryCriticalEvent +Comment=Battery charge dropped to level CRITICAL +Comment[cs]=Stav baterie dosáhl KRITICKÉ úrovně +Comment[de]=Batteriestand erreicht Level KRITISCH +Comment[es]=El nivel de carga de la batería es CRÍTICO +Comment[fr]=Le niveau de charge de la batterie est tombé au niveau CRITIQUE +Comment[it]=La carica della batteria è sul livello CRITICA +Comment[ja]=充電量が致命的レベルまで下がりました +Comment[pl]=Naładowanie baterii spadło do poziomu OSTRZEŻENIE +Comment[pt]=Estado da bateria baixou para o nível CRÍTICO +Comment[pt_BR]=A carga da bateria caiu para o nível CRÍTICO +Comment[ru]=Состояние батареи изменилось к КРИТИЧЕСКОМУ +Comment[zh_CN]=电池电量降至"电量严重不足"级别 +Comment[zh_TW]=電池充電量已降至「危急」層級 +default_sound=KDE_Event_1.ogg +default_presentation=17 + +[autosuspend_event] +Name=AutosupendEvent +Comment=Autosuspend is going to be executed +Comment[cs]=Vykonává se automatické uspání +Comment[de]=Autosuspend wird ausgeführt +Comment[es]=Se ejecutará la suspensión automática +Comment[fr]=La mise en veille automatique va être exécutée +Comment[it]=Attivazione in corso della sospensione automatica +Comment[ja]=自動サスペンドが実行されます。 +Comment[pl]=Zostanie wykonane automatyczne uśpienie +Comment[pt]=Será executada a sustensão automática +Comment[pt_BR]=A suspensão automática será executada +Comment[ru]=Запускается автозасыпание +Comment[zh_CN]=将执行自动暂停 +Comment[zh_TW]=即將執行自動暫停 +default_sound=KDE_Event_2.ogg +default_presentation=17 + +[autodimm_down_event] +Name=AutodimmDownEvent +Comment=Autodimm dimm the display down +default_presentation=0 + +[autodimm_up_event] +Name=AutodimmUpEvent +Comment=Autodimm dimm the display up +default_presentation=0 + +[scheme_Performance] +Name=SchemeSwitchToPerformanceEvent +Comment=Switched to scheme Performance +Comment[cs]=Powersave přepnut do schématu Výkon +Comment[de]=Zu Schema Leistung gewechselt. +Comment[es]=Powersave ha pasado al esquema de rendimiento +Comment[fr]=La fonction d'économie d'énergie a été basculée sur le profil Performance +Comment[it]=Powersave attivato nello schema Prestazioni +Comment[ja]=省電力がスキーム「パフォーマンス」に切り替わりました +Comment[pl]=Schemat oszczędzania przełączono na Wydajność +Comment[pt]=Powersave alterou para o esquema de Desempenho +Comment[pt_BR]=O Powersave mudou para o esquema Desempenhodefault_presentation=0 +Comment[ru]=Управление питанием переключено на схему Производительность +Comment[zh_CN]=Powersave 切换为"执行"方案 +Comment[zh_TW]=Powersave 已切換至「效能」規劃 +default_presentation=0 + +[scheme_Powersave] +Name=SchemeSwitchToPowersaveEvent +Comment=Switched to scheme Powersave +Comment[cs]=Powersave přepnut do schématu Úspora energie +Comment[de]=Zu Schema Energiesparen gewechselt +Comment[es]=Powersave ha pasado al esquema de ahorro de energía +Comment[fr]=La fonction d'économie d'énergie a été basculée sur le profil Économie d'énergie +Comment[it]=Powersave attivato nello schema Risparmio energetico +Comment[ja]=省電力がスキーム「省電力」に切り替わりました +Comment[pl]=Schemat oszczędzania przełączono na Oszczędzanie +Comment[pt]=Powersave alterou para o esquema de Economia +Comment[pt_BR]=O Powersave mudou para o esquema Powersave +Comment[ru]=Управление питанием переключено на схему Энергосбережение +Comment[zh_CN]=Powersave 切换为"省电"方案 +Comment[zh_TW]=Powersave 已切換至 Powersave 規劃 +default_presentation=0 + +[scheme_Acoustic] +Name=SchemeSwitchToAcousticEvent +Comment=Switched to scheme Acoustic +Comment[cs]=Powersave přepnut do schématu Tichý +Comment[de]=Zu Schema Akustik gewechselt +Comment[es]=Powersave ha pasado al esquema acústico +Comment[fr]=La fonction d'économie d'énergie a été basculée sur le profil Acoustique +Comment[it]=Powersave attivato nello schema Acustica +Comment[ja]=省電力がスキーム「アコースティック」に切り替わりました +Comment[pl]=Schemat oszczędzania przełączono na Hałas +Comment[pt]=Powersave alterou para o esquema Silencioso +Comment[pt_BR]=O Powersave mudou para o esquema Acústica +Comment[ru]=Управление питанием переключилено на схему Шумоподавление +Comment[zh_CN]=Powersave 切换为"声音"方案 +Comment[zh_TW]=Powersave 已切換至「音效」規劃 +default_presentation=0 + +[scheme_Presentation] +Name=SchemeSwitchToPresentationEvent +Comment=Switched to scheme Presentation +Comment[cs]=Powersave přepnut do schématu Prezentace +Comment[de]=Zu Schema Präsentation gewechselt +Comment[es]=Powersave ha pasado al esquema de presentación +Comment[fr]=La fonction d'économie d'énergie a été basculée sur le profil Présentation +Comment[it]=Powersave attivato nello schema Presentazione +Comment[ja]=省電力がスキーム「プレゼンテーション」に切り替わりました: +Comment[pl]=Schemat oszczędzania przełączono na Prezentacja +Comment[pt]=Powersave alterou para o esquema de Apresentação +Comment[pt_BR]=O Powersave mudou para o esquema Apresentação +Comment[ru]=Управление питанием переключено на схему Презентация +Comment[zh_CN]=Powersave 切换为"演示"方案 +Comment[zh_TW]=Powersave 已切換至「簡報」規劃 +default_presentation=0 + +[scheme_Unknown] +Name=SchemeSwitchToUnknownEvent +Comment=Switched to unknown/user defined scheme +Comment[cs]=Powersave přepnut do neznámého/uživatelem definovaného schématu +Comment[de]=Zu unbekanntem/benutzerdefiniertem Schema gewechselt +Comment[es]=Powersave ha pasado a un esquema desconocido o definido por el usuario +Comment[fr]=La fonction d'économie d'énergie a été basculée sur un profil inconnu/défini par un utilisateur +Comment[it]=Powersave attivato nello schema sconosciuto/definito dall'utente +Comment[ja]=省電力が不明/ユーザ定義スキームに切り替わりました: +Comment[pl]=Schemat oszczędzania przełączono na schemat nieznany lub użytkownika +Comment[pt]=Powersave alterou para um esquema desconhecido ou definido pelo utilizador +Comment[pt_BR]=O Powersave mudou para um esquema desconhecido/definido pelo usuário +Comment[ru]=Управление питанием переключилось на определяемую пользователем схему +Comment[zh_CN]=Powersave 切换为未知/用户定义的方案。 +Comment[zh_TW]=Powersave 已切換至未知的/使用者定義的規劃 +default_presentation=0 + +[suspend2disk_event] +Name=SuspendToDiskEvent +Comment=Suspend to Disk is started +Comment[cs]=Uspávání na disk +Comment[de]='Suspend to Disk' wurde gestartet +Comment[es]=Se ha iniciado la suspensión en disco +Comment[fr]=La mise en veille sur disque a été lancée +Comment[it]=Sospendi su disco avviata +Comment[ja]=サスペンド(ディスク)を開始しました +Comment[pl]=Rozpoczęto Usypianie na Dysk +Comment[pt]=Iniciou-se a Suspensão para o Disco +Comment[pt_BR]=Suspender para Disco foi iniciado +Comment[ru]=Запуск Уснуть на диск +Comment[zh_CN]=启动暂挂到磁盘 +Comment[zh_TW]=已啟動「暫停寫入到磁碟」 +default_presentation=0 + +[suspend2ram_event] +Name=SuspendToRamEvent +Comment=Suspend to RAM is started +Comment[cs]=Uspávání do RAM +Comment[de]='Suspend to RAM' wurde gestartet +Comment[es]=Se ha iniciado la suspensión en RAM +Comment[fr]=La mise en veille sur RAM a été lancée +Comment[it]=Sospensione su RAM avviata +Comment[ja]=サスペンド(RAM)を開始しました +Comment[pl]=Rozpoczęto Usypianie do pamięci RAM +Comment[pt]=Iniciou-se a Suspensão para a Memória +Comment[pt_BR]=Suspender para RAM foi iniciado +Comment[ru]=Запуск Уснуть в память +Comment[zh_CN]=启动暂挂到 RAM +Comment[zh_TW]=已啟動「暫停寫入到 RAM」 +default_presentation=0 + +[standby_event] +Name=StandbyEvent +Comment=Standby is started +Comment[cs]=Přepínání do pohotovosti +Comment[de]=Stand-by wurde gestartet +Comment[es]=Se ha iniciado el modo de stand-by +Comment[fr]=La mise en attente a été lancée +Comment[it]=Standby avviato +Comment[ja]=スタンバイを開始しました +Comment[pl]=Przechodzenie w Stan Uśpienia +Comment[pt]=Iniciou-se o StandBy +Comment[pt_BR]=O Standby foi iniciado +Comment[ru]=Запуск ждущего режима +Comment[zh_CN]=启动待机 +Comment[zh_TW]=已啟動「待機」 +default_presentation=0 + +[resume_from_suspend2disk_event] +Name=ResumeFromSuspendToDiskEvent +Comment=Resumed from Suspend to Disk +Comment[cs]=Probouzení z uspání na disk +Comment[de]=Wiederaufnahme nach 'Suspend to Disk' +Comment[es]=Reanudación desde suspensión en disco +Comment[fr]=Reprise après la mise en veille sur disque +Comment[it]=Ripristinato da Sospendi su disco +Comment[ja]=サスペンド(ディスク)から再開しました +Comment[pl]=Wznowiono po Uśpieniu na Dysk +Comment[pt]=O Sistema acordou da Suspensão para Disco +Comment[pt_BR]=Continuação a partir da Suspensão para Disco +Comment[ru]=Возврат из режима 'Уснуть на диск' +Comment[zh_CN]=已从暂挂到磁盘恢复 +Comment[zh_TW]=從「暫停寫入到磁碟」繼續 +default_presentation=0 + +[resume_from_suspend2ram_event] +Name=ResumeFromSuspendToRamEvent +Comment=Resumed from Suspend to RAM +Comment[cs]=Probouzení z uspání do RAM +Comment[de]=Wiederaufnahme nach 'Suspend to RAM' +Comment[es]=Reanudación desde suspensión en RAM +Comment[fr]=Reprise après la mise en veille sur RAM +Comment[it]=Ripristinato da Sospendi su RAM +Comment[ja]=サスペンド(RAM)から再開しました +Comment[pl]=Wznowiono po Uśpieniu do pamięci RAM +Comment[pt]=O Sistema acordou da Suspensão para Memória +Comment[pt_BR]=Continuação a partir da Suspensão para a Memória +Comment[ru]=Возврат из режима 'уснуть в память' +Comment[zh_CN]=从“暂挂到 RAM”继续执行 +Comment[zh_TW]=從「暫停寫入到 RAM」繼續執行 +default_presentation=0 + +[resume_from_standby_event] +Name=ResumeFromStandbyEvent +Comment=Resumed from Standby +Comment[cs]=Probouzení z pohotovosti +Comment[de]=Wiederaufnahme nach Stand-by +Comment[es]=Reanudación desde stand-by +Comment[fr]=Reprise après la mise en attente +Comment[it]=Ripristinato da Standby +Comment[ja]=スタンバイから再開しました +Comment[pl]=Wznowiono ze Stanu Uśpienia +Comment[pt]=O Sistema acordou do StandBy +Comment[pt_BR]=Continuação a partir do Standby +Comment[ru]=Возврат из ждущего режима +Comment[zh_CN]=已从待机恢复 +Comment[zh_TW]=從「待機」繼續 +default_presentation=0 + +[lid_closed_event] +Name=LidCloseEvent +Comment=The lid was closed +Comment[cs]=Víko zavřeno +Comment[de]=Der Laptop wurde geschlossen +Comment[es]=Tapa cerrada +Comment[fr]=L'écran était fermé +Comment[it]=Lo schermo è stato chiuso +Comment[ja]=Lidがクローズしました +Comment[pl]=Pokrywa została zamknięta +Comment[pt]=A tampa foi fechada +Comment[pt_BR]=A tampa foi fechada +Comment[ru]=Дисплей ноутбука закрыт +Comment[zh_CN]=此盖已关闭 +Comment[zh_TW]=蓋子已關閉 +default_presentation=0 + +[lid_opened_event] +Name=LidOpenedEvent +Comment=The lid was opened +Comment[cs]=Víko otevřeno +Comment[de]=Der Laptop wurde geöffnet +Comment[es]=Tapa abierta +Comment[fr]=L'écran était ouvert +Comment[it]=Lo schermo è stato aperto +Comment[ja]=Lidがオープンしました +Comment[pl]=Pokrywa została otwarta +Comment[pt]=A tampa foi aberta +Comment[pt_BR]=A tampa foi aberta +Comment[ru]=Дисплей ноутбука открыт +Comment[zh_CN]=此盖已打开 +Comment[zh_TW]=蓋子已開啟 +default_presentation=0 + +[brightness_up_event] +Name=BrightnessUpEvent +Comment=The brightness up key was pressed +default_presentation=0 + +[brightness_down_event] +Name=BrightnessDownEvent +Comment=The brightness down key was pressed +default_presentation=0 diff --git a/src/hardware.cpp b/src/hardware.cpp new file mode 100644 index 0000000..6be19a1 --- /dev/null +++ b/src/hardware.cpp @@ -0,0 +1,1720 @@ + /************************************************************************** + * Copyright (C) 2006-2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! + * \file hardware.cpp + * \brief In this file can be found the hardware information related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2006-2007 + */ + +// include global header +#include <fcntl.h> + +// include QT header +#include <qtimer.h> +#include <qdir.h> + +// include own header +#include "hardware.h" +#include "kpowersave_debug.h" +#include "privileges.h" + +/*! The default constructor of the class HardwareInfo */ +HardwareInfo::HardwareInfo() { + kdDebugFuncIn(trace); + + // init members + acadapter = true; + lidclose = false; + dbus_terminated = true; + hal_terminated = true; + laptop = false; + brightness = false; + brightness_in_hardware = false; + schedPowerSavings = false; + sessionIsActive = true; // assume as first we are active + + // update everything the first time + update_info_ac_changed = true; + update_info_cpufreq_policy_changed = true; + update_info_primBattery_changed = true; + + currentCPUFreqPolicy = UNKNOWN_CPUFREQ; + primaryBatteriesWarnLevel = 12; + primaryBatteriesLowLevel = 7; + primaryBatteriesCriticalLevel = 2; + + allUDIs = QStringList(); + consoleKitSession = QString(); + BatteryList.setAutoDelete( true ); // the list owns the objects + + primaryBatteries = new BatteryCollection(BAT_PRIMARY); + setPrimaryBatteriesWarningLevel(); // force default settings + + // connect to D-Bus and HAL + dbus_HAL = new dbusHAL(); + if (dbus_HAL->isConnectedToDBUS()) { + dbus_terminated = false; + if (dbus_HAL->isConnectedToHAL()) { + hal_terminated = false; + } else { + kdError() << "Could not connect to HAL" << endl; + } + } else { + kdError() << "Could not connect to D-Bus & HAL" << endl; + } + + checkConsoleKitSession(); + checkPowermanagement(); + checkIsLaptop(); + checkBrightness(); + checkCPUFreq(); + // getSchedPowerSavings(); + checkSuspend(); + intialiseHWInfo(); + + updatePrimaryBatteries(); + + // connect to signals + connect(dbus_HAL, SIGNAL(msgReceived_withStringString( msg_type, QString, QString )), + this, SLOT(processMessage( msg_type, QString, QString ))); + connect(dbus_HAL, SIGNAL(backFromSuspend(int)), this, SLOT(handleResumeSignal(int))); + + kdDebugFuncOut(trace); +} + +/*! The default desctuctor of the class HardwareInfo */ +HardwareInfo::~HardwareInfo() { + kdDebugFuncIn(trace); + + delete dbus_HAL; + dbus_HAL = NULL; + + kdDebugFuncOut(trace); +} + +/*! + * This funtion is used to handle the reconnect to the D-Bus daemon + */ +void HardwareInfo::reconnectDBUS() { + kdDebugFuncIn(trace); + + if (!dbus_HAL->isConnectedToDBUS()) { + bool _reconnect = dbus_HAL->reconnect(); + + if (!_reconnect && !dbus_HAL->isConnectedToDBUS()) { + //reconnect failed + emit dbusRunning(DBUS_NOT_RUNNING); + QTimer::singleShot(4000, this, SLOT(reconnectDBUS())); + } else if (!_reconnect && dbus_HAL->isConnectedToDBUS()) { + // reset everything, we are reconnected + dbus_terminated = false; + hal_terminated = true; + emit dbusRunning(DBUS_RUNNING); + } else if (_reconnect) { + // reset everything, we are reconnected + dbus_terminated = false; + hal_terminated = false; + reinitHardwareInfos(); + emit dbusRunning(hal_terminated); + emit halRunning(DBUS_RUNNING); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * This funtion is used to reinit all hardware information. + * \return Boolean with result of the call + * \retval true if reinit HW infos correct + * \retval false if not + */ +bool HardwareInfo::reinitHardwareInfos () { + kdDebugFuncIn(trace); + + if (dbus_HAL->isConnectedToDBUS() && dbus_HAL->isConnectedToHAL()) { + /* first cleanup */ + acadapter = true; + lidclose = false; + laptop = false; + brightness = false; + has_APM = false; + has_ACPI = false; + + update_info_ac_changed = true; + update_info_cpufreq_policy_changed = true; + update_info_primBattery_changed = true; + + allUDIs = QStringList(); + + BatteryList.clear(); + primaryBatteries = new BatteryCollection(BAT_PRIMARY); + + // check the current desktop session again + checkConsoleKitSession(); + + /* reinit hardware data */ + checkPowermanagement(); + checkIsLaptop(); + checkBrightness(); + checkCPUFreq(); + checkSuspend(); + intialiseHWInfo(); + // getSchedPowerSavings(); + updatePrimaryBatteries(); + + kdDebugFuncOut(trace); + return true; + } else { + kdDebugFuncOut(trace); + return false; + } +} + +/*! + * This funtion is used to parse a message from D-Bus for the different + * messagetypes and events. + * \param type a \ref msg_type which should be parse/processed + * \param message the message + * \param value an optional message value as e.g. message string + */ +void HardwareInfo::processMessage (msg_type type, QString message, QString value) { + kdDebugFuncIn(trace); + + switch(type) { + case ACPI_EVENT: + // we don't handle acpi events here atm + break; + case DBUS_EVENT: + kdDebug() << "D-Bus Event: " << value << endl; + if ( message.startsWith("dbus.terminate")){ + // TODO: addapt from pdaemon + dbus_terminated = true; + QTimer::singleShot(4000, this, SLOT(reconnectDBUS())); + } + else if ( message.startsWith("hal.")) { + if ( message.startsWith("hal.terminate")) { + hal_terminated = true; + emit halRunning(false); + // TODO: update data + emit generalDataChanged(); + } else if ( message.startsWith("hal.started")) { + hal_terminated = false; + reinitHardwareInfos(); + emit halRunning( true ); + // TODO: update data + emit generalDataChanged(); + } + // TODO: addapt from pdaemon + } + break; + case HAL_DEVICE: + // --> we can maybe ignore these events except for batteries, not shure atm + int _type; + + if (message.startsWith("DeviceAdded")) { + if (checkIfHandleDevice(value, &_type)) { + switch (_type) { + case BATTERY: + case AC_ADAPTER: + case BUTTON_SLEEP: + case BUTTON_POWER: + case LID: + // TODO: handle code if needed actually not + break; + case LAPTOP_PANEL: + checkBrightness(); + break; + default: + kdDebug() << "New device added Device udi: " + << value << "type: " << _type << endl; + break; + } + } + } else if (message.startsWith("DeviceRemoved")) { + if (allUDIs.contains(value)) { + if (checkIfHandleDevice(value, &_type)) { + switch (_type) { + case BATTERY: + case AC_ADAPTER: + case BUTTON_SLEEP: + case BUTTON_POWER: + case LID: + // TODO: handle code if needed + break; + case LAPTOP_PANEL: + checkBrightness(); + break; + default: + kdDebug() << "Couldn't handle unknown device" << endl; + break; + } + } + } else { + kdDebug() << "Not monitored device removed: " << value << endl; + } + } else { + kdDebug() << "Unknown HAL_DEVICE message: " << message << endl; + } + break; + case HAL_PROPERTY_CHANGED: + if (!message.isEmpty() && allUDIs.contains( message )) { + if (value.startsWith( "ac_adapter.present" )) { + QTimer::singleShot(50, this, SLOT(checkACAdapterState())); + } else if (value.startsWith( "battery." )) { + // this is a battery event + updateBatteryValues(message, value); + } else if (value.startsWith( "button.state.value" )) { + if (message.startsWith( *udis["lidclose"] )) { + QTimer::singleShot(50, this, SLOT(checkLidcloseState())); + } + } else if (value.startsWith( "laptop_panel")) { + if (message.startsWith( *udis["laptop_panel"] )) { + QTimer::singleShot(50, this, SLOT(checkBrightness())); + } + } + // TODO: add needed code + } else { + kdDebug() << "HAL_PROPERTY_CHANGED for unmonitored device: " << value << endl; + } + break; + case HAL_CONDITION: + // TODO: Check if we really need to monitor this events. We get maybe also + // HAL_PROPERTY_CHANGED event for the key + if (message.startsWith("ButtonPressed")) { + kdDebug() << "ButtonPressed event from HAL: " << value << endl; + if (value.startsWith("lid")) { + QTimer::singleShot(50, this, SLOT(checkLidcloseState())); + } else if (value.startsWith("power")) { + QTimer::singleShot(50, this, SLOT(emitPowerButtonPressed())); + } else if (value.startsWith("sleep") || value.startsWith("suspend")) { + QTimer::singleShot(50, this, SLOT(emitSleepButtonPressed())); + } else if (value.startsWith("hibernate")) { + QTimer::singleShot(50, this, SLOT(emitS2diskButtonPressed())); + } else if (value.startsWith("brightness-")) { + if (!brightness_in_hardware && value.endsWith("-up")) + QTimer::singleShot(50, this, SLOT(brightnessUpPressed())); + else if (!brightness_in_hardware && value.endsWith("-down")) + QTimer::singleShot(50, this, SLOT(brightnessDownPressed())); + } + } else { + kdDebug() << "Unmonitored HAL_CONDITION: " << message << " : " << value << endl; + } + break; + case CONSOLEKIT_SESSION_ACTIVE: + if (!message.isEmpty() && !value.isEmpty()) { + if (message == consoleKitSession) { + if (value == "1") { + sessionIsActive = true; + } else { + sessionIsActive = false; + } + QTimer::singleShot(50, this, SLOT(emitSessionActiveState())); + } else { + if (trace) + kdDebug() << "CONSOLEKIT_SESSION_ACTIVE: not our session" << endl; + } + } + break; + case POLICY_POWER_OWNER_CHANGED: + if (message.startsWith("NOW_OWNER")) { + // TODO: add code + } else if (message.startsWith("OTHER_OWNER")){ + // TODO: add code + } + break; + default: + kdDebug() << "Recieved unknown package type: " << type << endl; + break; + } + + kdDebugFuncOut(trace); +} + +/*! + * This SLOT is used to fetch the resume signal and multiplex. If needed some + * actions after resume, do this here. + * \param result integer with the result of the resume/suspend + */ +void HardwareInfo::handleResumeSignal (int result) { + if (trace) kdDebug() << funcinfo << "IN: " << "(int result: " << result << ")"<< endl; + + if (result == -1) { + // check if time since suspend is higher than 6 hours, + // the magic D-Bus timeout for pending calls + if (calledSuspend.elapsed() > 21600000) { + emit resumed(INT_MAX); + } + } else { + emit resumed(result); + } + + calledSuspend = QTime(); + kdDebugFuncOut(trace); +} + +/*! + * This function checks the session for the running KPowersave instance + * \return Boolean with result of operation + * \retval true if the query/check could get finished + * \retval false on every error + */ +bool HardwareInfo::checkConsoleKitSession () { + kdDebugFuncIn(trace); + + bool retval = false; + + if (dbus_HAL->isConnectedToDBUS()) { + char *reply; + char *cookie = getenv("XDG_SESSION_COOKIE"); + + if (cookie == NULL) { + kdDebug() << "Could not get XDG_SESSION_COOKIE from environment" << endl; + sessionIsActive = true; + } else { + if (dbus_HAL->dbusSystemMethodCall( CK_SERVICE, CK_MANAGER_OBJECT, + CK_MANAGER_IFACE, "GetSessionForCookie", + &reply, DBUS_TYPE_OBJECT_PATH, + DBUS_TYPE_STRING, &cookie, + DBUS_TYPE_INVALID)) { + if (trace) + kdDebug() << "GetSessionForCookie returned: " << reply << endl; + + if (reply != NULL) { + dbus_bool_t i_reply; + consoleKitSession = reply; + + if (dbus_HAL->dbusSystemMethodCall( CK_SERVICE, consoleKitSession, + CK_SESSION_IFACE, "IsActive", + &i_reply, DBUS_TYPE_BOOLEAN, + DBUS_TYPE_INVALID)) { + sessionIsActive = ((i_reply != 0) ? true: false); + if (trace) + kdDebug() << "IsActive returned: " << sessionIsActive << endl; + + retval = true; + } else { + kdError() << "Could get session cookie and session name, but not " + << "but not the status of the session. Assume for now " + << "the Session is inactive!" << endl; + sessionIsActive = false; + } + } + } + } + } + + kdDebugFuncOut(trace); + return retval; +} + + +/*! + * This function check for a given UDI, if we should handle a device + * \param _udi QString with the UDI of the device + * \param *type pointer to a integer to return the type of the device, see \ref device_type + * \return Boolean with info if we should handle the device. + * \retval true if we should handle + * \retval false if not + */ +bool HardwareInfo::checkIfHandleDevice ( QString _udi, int *type) { + kdDebugFuncIn(trace); + + QStringList _cap; + bool ret = true; + + if (dbus_HAL->halGetPropertyStringList( _udi, "info.capabilities", &_cap) && !_cap.isEmpty()) { + if (_cap.contains("ac_adapter")) { + *type = BATTERY; + } else if (_cap.contains("button")) { + QString _val; + if (dbus_HAL->halGetPropertyString( _udi, "button.type", &_val)) { + if (_val.startsWith("lid")) { + *type = LID; + } else if ( _val.startsWith("power")) { + *type = BUTTON_POWER; + } else if ( _val.startsWith("sleep")) { + *type = BUTTON_SLEEP; + } else { + ret = false; + } + } else { + ret = false; + } + } else if (_cap.contains("battery")) { + *type = BATTERY; + } else if (_cap.contains("laptop_panel")) { + *type = LAPTOP_PANEL; + } else { + ret = false; + kdDebug() << "Device with capability " << _cap.join(", ") << " unhandled" << endl; + } + } else { + ret = false; + } + + if (!ret) *type = UNKNOWN_DEVICE; + + kdDebugFuncOut(trace); + return ret; +} + +// --> set some values for devices +/*! + * This function set the warning level for the primary battery collection + * If all give param are -1 or not set this function force the current + * settings to the primary battery collection. + * \param _warn value for the state BAT_WARN or -1 + * \param _low value for the state BAT_LOW or -1 + * \param _crit value for the state BAT_CRIT or -1 + */ +void HardwareInfo::setPrimaryBatteriesWarningLevel (int _warn, int _low, int _crit ) { + if (trace) kdDebug() << funcinfo << "IN: " << "warn: " << _warn << " low: " << _low << " crit: " << _crit << endl; + + if (_warn > -1 && _low > -1 && _crit > -1 ){ + primaryBatteriesWarnLevel = _warn; + primaryBatteriesLowLevel = _low; + primaryBatteriesCriticalLevel = _crit; + } + + if (primaryBatteries) { + primaryBatteries->setWarnLevel( primaryBatteriesWarnLevel ); + primaryBatteries->setLowLevel( primaryBatteriesLowLevel ); + primaryBatteries->setCritLevel( primaryBatteriesCriticalLevel ); + if (!BatteryList.isEmpty()) { + primaryBatteries->refreshInfo( BatteryList, true ); + } + } + + kdDebugFuncOut(trace); +} + +// --> init HW information section -- START <--- + +/*! + * The function checks if the machine is a laptop. + */ +void HardwareInfo::checkIsLaptop () { + kdDebugFuncIn(trace); + + QString ret; + + if (dbus_HAL->halGetPropertyString(HAL_COMPUTER_UDI, "system.formfactor", &ret)) { + + if (!ret.isEmpty() && ret.startsWith("laptop")) + laptop = true; + else + laptop = false; + } else { + // error case + laptop = false; + } + + kdDebugFuncOut(trace); +} + +/*! + * The function checks wether the machine support ACPI/APM/PMU or not. + */ +void HardwareInfo::checkPowermanagement() { + kdDebugFuncIn(trace); + + QString ret; + + has_APM = false; + has_ACPI = false; + has_PMU = false; + + if (dbus_HAL->halGetPropertyString( HAL_COMPUTER_UDI, "power_management.type", &ret)) { + + if (ret.isEmpty()) { + return; + } else if (ret.startsWith("acpi")) { + has_ACPI = true; + } else if (ret.startsWith("apm")) { + has_APM = true; + } else if (ret.startsWith("pmu")) { + has_PMU = true; + } + } + + kdDebugFuncOut(trace); +} + + +/*! + * The function checks wether the machine can suspend/standby. + */ +void HardwareInfo::checkSuspend() { + kdDebugFuncIn(trace); + + QStringList ret; + bool _ret_b = false; + + suspend_states = SuspendStates(); + + if (dbus_HAL->halGetPropertyStringList( HAL_COMPUTER_UDI, HAL_PM_IFACE ".method_names", + &ret )) { + // check for suspend2ram + if (dbus_HAL->halGetPropertyBool( HAL_COMPUTER_UDI, "power_management.can_suspend", &_ret_b ) || + dbus_HAL->halGetPropertyBool( HAL_COMPUTER_UDI, "power_management.can_suspend_to_ram", + &_ret_b )) { + suspend_states.suspend2ram_can = _ret_b; + if (_ret_b) { + if (ret.contains( "Suspend" )) { + suspend_states.suspend2ram = true; + suspend_states.suspend2ram_allowed = dbus_HAL->isUserPrivileged(PRIV_SUSPEND, + HAL_COMPUTER_UDI); + } + } else { + suspend_states.suspend2ram = false; + suspend_states.suspend2ram_allowed = -1; + } + } else { + suspend_states.suspend2ram_can = false; + suspend_states.suspend2ram = false; + suspend_states.suspend2ram_allowed = -1; + } + + // check for suspend2disk + if (dbus_HAL->halGetPropertyBool( HAL_COMPUTER_UDI, "power_management.can_hibernate", &_ret_b ) || + dbus_HAL->halGetPropertyBool( HAL_COMPUTER_UDI, "power_management.can_suspend_to_disk", + &_ret_b )) { + suspend_states.suspend2disk_can = _ret_b; + if (_ret_b) { + if (ret.contains( "Hibernate" )) { + suspend_states.suspend2disk = true; + suspend_states.suspend2disk_allowed = + dbus_HAL->isUserPrivileged(PRIV_HIBERNATE, + HAL_COMPUTER_UDI); + } + } else { + suspend_states.suspend2disk = false; + suspend_states.suspend2disk_allowed = -1; + } + } else { + suspend_states.suspend2disk_can = false; + suspend_states.suspend2disk = false; + suspend_states.suspend2disk_allowed = -1; + } + + // check for StandBy + if (dbus_HAL->halGetPropertyBool( HAL_COMPUTER_UDI, "power_management.can_standby", &_ret_b )) { + suspend_states.standby_can = _ret_b; + if (_ret_b) { + if (ret.contains( "Standby" )) { + suspend_states.standby = true; + suspend_states.standby_allowed = dbus_HAL->isUserPrivileged(PRIV_STANDBY, + HAL_COMPUTER_UDI); + } + } else { + suspend_states.standby = false; + suspend_states.standby_allowed = -1; + } + } else { + suspend_states.standby_can = false; + suspend_states.standby = false; + suspend_states.standby_allowed = -1; + } + } + + kdDebugFuncOut(trace); +} + +/*! + * The function checks wether the machine support CPU frequency changes + * via HAL. + */ +void HardwareInfo::checkCPUFreq() { + kdDebugFuncIn(trace); + + bool ret = false; + + if (dbus_HAL->halQueryCapability( HAL_COMPUTER_UDI, "cpufreq_control", &ret )) { + cpuFreq = ret; + cpuFreqAllowed = dbus_HAL->isUserPrivileged( PRIV_CPUFREQ, HAL_COMPUTER_UDI); + + checkCurrentCPUFreqPolicy(); + } else { + cpuFreq = false; + } + + kdDebugFuncOut(trace); +} + +/*! + * The function check the currently selected CPU Frequency policy + * \return the current policy + */ +cpufreq_type HardwareInfo::checkCurrentCPUFreqPolicy() { + kdDebugFuncIn(trace); + + char *gov; + + cpufreq_type _current = UNKNOWN_CPUFREQ; + + if (cpuFreq) { + + if (dbus_HAL->dbusSystemMethodCall( HAL_SERVICE, HAL_COMPUTER_UDI, + HAL_CPUFREQ_IFACE, "GetCPUFreqGovernor", + &gov, DBUS_TYPE_STRING, DBUS_TYPE_INVALID)) { + if (gov != NULL) { + kdDebug() << "got CPU Freq gov: " << gov << endl; + if (!strcmp(gov, "ondemand") || !strcmp(gov, "userspace") || + !strcmp(gov, "conservative")) { + _current = DYNAMIC; + } else if (!strcmp(gov, "powersave")) { + _current = POWERSAVE; + } else if (!strcmp(gov, "performance")) { + _current = PERFORMANCE; + } else { + kdError() << "Got unknown CPUFreq Policy back: " << gov << endl; + } + cpuFreqGovernor = gov; + } + else { + kdWarning() << "Could not get information about current governor" << endl; + } + } else { + kdWarning() << "Could not get information about current governor" << endl; + } + } else { + kdWarning() << "CPU Frequency interface not supported by machine or HAL" << endl; + } + + if (_current != currentCPUFreqPolicy) { + currentCPUFreqPolicy = _current; + update_info_cpufreq_policy_changed = true; + emit currentCPUFreqPolicyChanged(); + } else { + update_info_cpufreq_policy_changed = false; + } + + kdDebugFuncOut(trace); + return currentCPUFreqPolicy; +} + + +/*! + * The function checks wether the machine provide a brightness interface and init + * (if needed) brightness information. + */ +void HardwareInfo::checkBrightness() { + kdDebugFuncIn(trace); + + QStringList devices; + + brightness = false; + currentBrightnessLevel = -1; + availableBrightnessLevels = -1; + + if( dbus_HAL->halFindDeviceByCapability("laptop_panel", &devices)) { + if (devices.isEmpty()) { + udis.remove("laptop_panel"); + kdDebug() << "no device with category laptop_panel found" << endl; + kdDebugFuncOut(trace); + return; + } else { + int retval; + + + kdDebug() << "laptop_panel device found: " << devices.first() << endl; + // we should asume there is only one laptop panel device in the system + if (dbus_HAL->halGetPropertyInt(devices.first(), "laptop_panel.num_levels", &retval )) { + udis.insert("laptop_panel", new QString( devices.first() )); + if (!allUDIs.contains( devices.first() )) + allUDIs.append( devices.first() ); + + if (retval > 1) { + dbus_HAL->halGetPropertyBool(devices.first(), "laptop_panel.brightness_in_hardware", + &brightness_in_hardware); + + availableBrightnessLevels = retval; +#ifdef USE_LIBHAL_POLICYCHECK + brightnessAllowed = dbus_HAL->isUserPrivileged( PRIV_LAPTOP_PANEL, + devices.first()); + // TODO: check brightnessAllowed +#endif + brightness = true; + // get the current level via GetBrightness + checkCurrentBrightness(); + } else { + kdError() << "Found a Panel, but laptop_panel.num_levels < 2, which means " + << "KPowersave can't set usefull values" << endl; + } + } + } + } + + kdDebugFuncOut(trace); +} + + +/*! + * The function check the current brigthness + */ +void HardwareInfo::checkCurrentBrightness() { + kdDebugFuncIn(trace); + + if (brightness) { + int retval; + // get the current level via GetBrightness + if (dbus_HAL->dbusSystemMethodCall( HAL_SERVICE, *udis["laptop_panel"], HAL_LPANEL_IFACE, + "GetBrightness", &retval, DBUS_TYPE_INT32, + DBUS_TYPE_INVALID ) ) { + currentBrightnessLevel = (int) retval; + } + } + + kdDebugFuncOut(trace); +} + + +/*! + * The function initialise the hardware information and collect all + * initial information from HAL. + * \return boolean with result of the operation + * \retval true if successful + * \retval false else, if a error occurs + */ +bool HardwareInfo::intialiseHWInfo() { + kdDebugFuncIn(trace); + + QStringList ret; + + if (!dbus_HAL->isConnectedToDBUS() || !dbus_HAL->isConnectedToHAL()) + return false; + + if( dbus_HAL->halFindDeviceByCapability("ac_adapter", &ret)) { + // there should be normaly only one device, but let be sure + for ( QStringList::iterator it = ret.begin(); it != ret.end(); ++it ) { + // we need a deep copy + udis.insert("acadapter", new QString( *it )); + if (!allUDIs.contains( *it )) + allUDIs.append( *it ); + checkACAdapterState(); + } + } + + ret.clear(); + + if( dbus_HAL->halFindDeviceByString("button.type", "lid", &ret)) { + // there should be normaly only one device, but let be sure + for ( QStringList::iterator it = ret.begin(); it != ret.end(); ++it ) { + // we need a deep copy + udis.insert("lidclose", new QString( *it )); + if (!allUDIs.contains( *it )) + allUDIs.append( *it ); + checkLidcloseState(); + } + } + + ret.clear(); + + // find batteries and fill battery information + if( dbus_HAL->halFindDeviceByCapability("battery", &ret)) { + if (!ret.isEmpty()) { + // there should be normaly only one device, but let be sure + for ( QStringList::iterator it = ret.begin(); it != ret.end(); ++it ) { + if (!allUDIs.contains( *it )) + allUDIs.append( *it ); + BatteryList.append( new Battery(dbus_HAL, *it) ); + } + + // connect to signals for primary batteries: + Battery *bat; + for (bat = BatteryList.first(); bat; bat = BatteryList.next() ) { + if (bat->getType() == BAT_PRIMARY) { + connect(bat, SIGNAL(changedBattery()),this, SLOT(updatePrimaryBatteries())); + } + } + } + } + + kdDebugFuncOut(trace); + return true; +} + +/*! + * The function/SLOT checks the state of the AC adapter. + */ +void HardwareInfo::checkACAdapterState() { + kdDebugFuncIn(trace); + + if ( udis["acadapter"] ) { + bool _state; + + if (dbus_HAL->halGetPropertyBool(*udis["acadapter"] , "ac_adapter.present", &_state )) { + if (_state != acadapter) { + acadapter = _state; + update_info_ac_changed = true; + emit ACStatus( acadapter ); + } else { + update_info_ac_changed = false; + } + } else { + // we use true as default e.g. for workstations + acadapter = true; + } + } + + kdDebugFuncOut(trace); +} + +/*! + * The function checks the state of the Lidclose button. + */ +void HardwareInfo::checkLidcloseState() { + kdDebugFuncIn(trace); + + if ( udis["lidclose"] ) { + bool _state; + + if (dbus_HAL->halGetPropertyBool(*udis["lidclose"] , "button.state.value", &_state )) { + if (_state != lidclose) { + lidclose = _state; + emit lidcloseStatus( lidclose ); + } + } else { + lidclose = false; + } + } + + kdDebugFuncOut(trace); +} + +/*! + * This funtion is used to call a update of a battery value for a given + * UDI and the given changed property + * \param udi QString with the UDI of the battery + * \param property QString with the changed property + */ +void HardwareInfo::updateBatteryValues (QString udi, QString property) { + kdDebugFuncIn(trace); + + if (!udi.isEmpty() && allUDIs.contains( udi )) { + // find effected battery object + Battery *bat; + for (bat = BatteryList.first(); bat; bat = BatteryList.next() ) { + if (udi.startsWith( bat->getUdi())) { + // found a battery with udi + bat->updateProperty(udi, property); + } + } + } else { + kdDebug() << "UDI is empty or not in the list of monitored devices: " << udi << endl; + } + + kdDebugFuncOut(trace); + return; +} + +/*! + * This function refresh the information for the primary battery collection. + */ +void HardwareInfo::updatePrimaryBatteries () { + kdDebugFuncIn(trace); + + if (!BatteryList.isEmpty()) { + if (primaryBatteries->getNumBatteries() < 1) { + setPrimaryBatteriesWarningLevel(); + primaryBatteries->refreshInfo( BatteryList ); + connect(primaryBatteries, SIGNAL(batteryChanged()), this, + SLOT(setPrimaryBatteriesChanges())); + connect(primaryBatteries, SIGNAL(batteryWarnState(int,int)), this, + SLOT(emitBatteryWARNState(int,int))); + } else { + setPrimaryBatteriesWarningLevel(); + primaryBatteries->refreshInfo( BatteryList ); + } + } else { + primaryBatteries = new BatteryCollection(BAT_PRIMARY); + } + + kdDebugFuncOut(trace); +} + +/*! + * This function set the change status for the primary battery collection + */ +void HardwareInfo::setPrimaryBatteriesChanges () { + kdDebugFuncIn(trace); + + update_info_primBattery_changed = true; + emit primaryBatteryChanged(); + + kdDebugFuncOut(trace); +} + +/*! + * This slot emit a signal if a warning state of a battery reached + */ +void HardwareInfo::emitBatteryWARNState (int type, int state) { + kdDebugFuncIn(trace); + + if (type == BAT_PRIMARY) + emit primaryBatteryChanged(); + else + emit generalDataChanged(); + + emit batteryWARNState(type, state); + + kdDebugFuncOut(trace); +} + +// --> init HW information section -- END <--- +// --> HAL method call (trigger actions) section -- START <--- + +/*! + * Function to trigger a suspend via HAL + * \param suspend enum of suspend_type with the requested suspend + * \return boolean with result of the operation + * \retval true if successful + * \retval false else, if a error occurs + */ +bool HardwareInfo::suspend( suspend_type suspend ) { + kdDebugFuncIn(trace); + + calledSuspend = QTime(); + + if (dbus_HAL->isConnectedToDBUS() && dbus_HAL->isConnectedToHAL()) { + switch (suspend) { + case SUSPEND2DISK: + if (suspend_states.suspend2disk && (suspend_states.suspend2disk_allowed != 0)) { + if (dbus_HAL->dbusMethodCallSuspend("Hibernate")) { + calledSuspend.start(); + return true; + } else { + return false; + } + } else { + if ( !suspend_states.suspend2disk ) + kdDebug() << "The machine does not support suspend to disk." << endl; + else + kdWarning() << "Policy forbid user to trigger suspend to disk" << endl; + + return false; + } + break; + case SUSPEND2RAM: + if (suspend_states.suspend2ram && (suspend_states.suspend2ram_allowed != 0)) { + if (dbus_HAL->dbusMethodCallSuspend("Suspend")) { + calledSuspend.start(); + return true; + } else { + return false; + } + } else { + if ( !suspend_states.suspend2ram ) + kdDebug() << "The machine does not support suspend to ram." << endl; + else + kdWarning() << "Policy forbid user to trigger suspend to ram" << endl; + + return false; + } + break; + case STANDBY: + if (suspend_states.standby && (suspend_states.standby_allowed != 0)) { + if (dbus_HAL->dbusMethodCallSuspend("Standby")) { + calledSuspend.start(); + return true; + } else { + return false; + } + } else { + if ( !suspend_states.standby ) + kdDebug() << "The machine does not support standby." << endl; + else + kdWarning() << "Policy forbid user to trigger standby" << endl; + + return false; + } + break; + default: + return false; + } + } + + kdDebugFuncOut(trace); + return false; +} + +/*! + * Function to set brightness via HAL (if supported by hardware) + * \param level Integer with the level to set, (range: 0 - \ref availableBrightnessLevels ) + * \param percent Integer with the brightness percentage to set + * \return boolean with result of the operation + * \retval true if successful + * \retval false else, if a error occurs + */ +bool HardwareInfo::setBrightness ( int level, int percent ){ + if (trace) kdDebug() << funcinfo << "IN: " << "level: " << level << " percent: " << percent << endl; + + bool retval = false; + + if ((level == -1) && (percent >= 0)) { + if (percent == 0) { + level = 0; + } else if (percent >= 98) { + level = (availableBrightnessLevels - 1); + } else { + level = (int)((float)availableBrightnessLevels * ((float)percent/100.0)); + if (level > (availableBrightnessLevels -1)) + level = availableBrightnessLevels -1; + kdDebug() << "percentage mapped to new level: " << level << endl; + } + } + + if (dbus_HAL->isConnectedToDBUS() && dbus_HAL->isConnectedToHAL()) { + if (!brightness) + checkBrightness(); + + if (!brightness || (level < 0 ) || (level >= availableBrightnessLevels)) { + kdError() << "Change brightness or requested level not supported " << endl; + } else { + if (currentBrightnessLevel == level) { + kdDebug() << "Brightness level not changed, requested level == current level" << endl; + retval = true; + } else { + if (dbus_HAL->dbusSystemMethodCall( HAL_SERVICE, *udis["laptop_panel"], + HAL_LPANEL_IFACE, "SetBrightness", + DBUS_TYPE_INT32, &level, + DBUS_TYPE_INVALID )) { + retval = true; + } + } + } + } + + // check for actual brightness level to be sure everything was set correct + checkCurrentBrightness(); + kdDebugFuncOut(trace); + return retval; +} + +/*! + * Function to set the CPU frequency policy via HAL. + * \param cpufreq enum of cpufreq_type with the policy to set + * \param limit integer with range 0 - 100 (only if cpufreq == DYNAMIC) + * \return boolean with result of the operation + * \retval true if successful + * \retval false else, if a error occurs + */ +bool HardwareInfo::setCPUFreq ( cpufreq_type cpufreq, int limit ) { + if (trace) kdDebug() << funcinfo << "IN: " << "cpufreq_type: " << cpufreq << " limit: " << limit << endl; + + if (!cpuFreq) { + kdError() << "This machine does not support change the CPU Freq via HAL" << endl; + return false; + } + + if (cpuFreqAllowed == 0) { + kdError() << "Could not set CPU Freq, this not the needed privileges." << endl; + return false; + } + + if (dbus_HAL->isConnectedToDBUS() && dbus_HAL->isConnectedToHAL()) { + dbus_bool_t consider = (dbus_bool_t) getAcAdapter(); + QStringList dynamic; + + if (checkCurrentCPUFreqPolicy() == cpufreq) { + if (cpufreq == DYNAMIC && !cpuFreqGovernor.startsWith("ondemand")) { + kdDebug() << "CPU Freq Policy is already DYNAMIC, but not governor is currently " + << "not 'ondemand'. Try to set ondemand governor." << endl; + } else { + kdDebug() << "Didn't change Policy, was already set." << endl; + return true; + } + } + + switch (cpufreq) { + case PERFORMANCE: + if (!setCPUFreqGovernor("performance")) { + kdError() << "Could not set CPU Freq to performance policy" << endl; + return false; + } + break; + case DYNAMIC: + dynamic << "ondemand" << "userspace" << "conservative"; + + for (QStringList::Iterator it = dynamic.begin(); it != dynamic.end(); it++){ + kdDebug() << "Try to set dynamic CPUFreq to: " << *it << endl; + + if (setCPUFreqGovernor((*it).latin1())) { + kdDebug() << "Set dynamic successful to: " << *it << endl; + break; + } + } + + // set dynamic performance limit + if (!dbus_HAL->dbusSystemMethodCall( HAL_SERVICE, HAL_COMPUTER_UDI, + HAL_CPUFREQ_IFACE, + "SetCPUFreqPerformance", + DBUS_TYPE_INT32, &limit, + DBUS_TYPE_INVALID)) { + kdError() << "Could not call/set SetCPUFreqPerformance with value: " + << limit << endl; + } + + // correct set ondemand + if (!dbus_HAL->dbusSystemMethodCall( HAL_SERVICE, HAL_COMPUTER_UDI, + HAL_CPUFREQ_IFACE, + "SetCPUFreqConsiderNice", + DBUS_TYPE_BOOLEAN, &consider, + DBUS_TYPE_INVALID)) { + kdError() << "Couldn't set SetCPUFreqConsiderNice for DYNAMIC" << endl; + } + + break; + case POWERSAVE: + if (!setCPUFreqGovernor("powersave")) { + kdError() << "Could not set CPU Freq to powersave policy" << endl; + return false; + } + break; + default: + kdWarning() << "Unknown cpufreq_type: " << cpufreq << endl; + return false; + } + + // check if the policy was really set (and emit signal) + if (checkCurrentCPUFreqPolicy() == cpufreq) { +// update_info_cpufreq_policy_changed = true; +// emit currentCPUFreqPolicyChanged(); + return true; + } else { + return false; + } + } else { + return false; + } +} + +/*! + * Function to set the CPU governor via HAL. + * \param governor char * with the name of the governor + * \return boolean with result of the operation + * \retval true if successful + * \retval false else, if a error occurs + */ +bool HardwareInfo::setCPUFreqGovernor( const char *governor ) { + kdDebugFuncIn(trace); + + int reply; + bool ret = true; + + kdDebug() << "Try to set CPUFreq to governor: " << governor << endl; + if (!dbus_HAL->dbusSystemMethodCall( HAL_SERVICE, HAL_COMPUTER_UDI, + HAL_CPUFREQ_IFACE, "SetCPUFreqGovernor", + &reply, DBUS_TYPE_INVALID, + DBUS_TYPE_STRING, &governor, + DBUS_TYPE_INVALID)) { + kdError() << "Could not set CPU Freq to governor: " << governor << endl; + ret = false; + } + + kdDebugFuncOut(trace); + return ret; +} + + +/*! + * Function to set the powersave mode (incl. e.g. disk settings) via HAL. + * \param on boolean which tell if enable/disable powersave mode + * \return boolean with result of the operation + * \retval true if successful + * \retval false else, if a error occurs + */ +bool HardwareInfo::setPowerSave( bool on ) { + kdDebugFuncIn(trace); + + bool retval = false; + + if (dbus_HAL->isConnectedToDBUS() && dbus_HAL->isConnectedToHAL()) { + dbus_bool_t _tmp = (dbus_bool_t) on; + int reply; + +#ifdef USE_LIBHAL_POLICYCHECK + if (dbus_HAL->isUserPrivileged(PRIV_SETPOWERSAVE, HAL_COMPUTER_UDI) != 0) { +#else + if (true) { +#endif + if (!dbus_HAL->dbusSystemMethodCall( HAL_SERVICE, HAL_COMPUTER_UDI, + HAL_PM_IFACE, "SetPowerSave", + &reply, DBUS_TYPE_INT32, + DBUS_TYPE_BOOLEAN, &_tmp, + DBUS_TYPE_INVALID)) { + kdError() << "Could not call/set SetPowerSave on HAL, " + << "could be a bug in HAL spec" << endl; + } else { + retval = true; + } + } else { + kdError() << "The user isn't allowed to call SetPowerSave() on HAL. " + << "Maybe KPowersave run not in a active session." << endl; + } + } + + kdDebugFuncOut(trace); + return retval; +} + +/*! + * Function to call GetSchedPowerSavings() via HAL. + * \return boolean with result of the operation + * \retval true if successful + * \retval false else, if a error occurs + */ +bool HardwareInfo::getSchedPowerSavings() { + kdDebugFuncIn(trace); + + bool returnval = false; + + if (dbus_HAL->isConnectedToDBUS() && dbus_HAL->isConnectedToHAL()) { + dbus_bool_t ret; + + //NOTE: the kernel only allow 1/0 for the related sysfs entry + if (dbus_HAL->dbusSystemMethodCall( HAL_SERVICE, HAL_COMPUTER_UDI, + HAL_CPUFREQ_IFACE, "GetSchedPowerSavings", + &ret, DBUS_TYPE_BOOLEAN, DBUS_TYPE_INVALID)) { + schedPowerSavings = ((ret != 0) ? true: false); + returnval = true; + } else { + schedPowerSavings = false; + kdWarning() << "Could not call GetSchedPowerSavings() " << endl; + } + } + + kdDebugFuncOut(trace); + return returnval; +} + +/*! + * Function to call SetSchedPowerSavings() via HAL. Note: this would only work on + * Multiprocessor/-core machines. + * \return boolean with result of the operation + * \retval true if successful + * \retval false else, if a error occurs + */ +bool HardwareInfo::setSchedPowerSavings( bool enable ) { + kdDebugFuncIn(trace); + + bool retval = false; + + if (dbus_HAL->isConnectedToDBUS() && dbus_HAL->isConnectedToHAL()) { + dbus_bool_t _tmp = (dbus_bool_t) enable; + + //NOTE: the kernel only allow 1/0 for the related sysfs entry + if (dbus_HAL->dbusSystemMethodCall( HAL_SERVICE, HAL_COMPUTER_UDI, + HAL_CPUFREQ_IFACE, + "SetCPUFreqPerformance", + DBUS_TYPE_BOOLEAN, &_tmp, + DBUS_TYPE_INVALID)) { + retval = true; + } else { + kdWarning() << "Could not call SetSchedPowerSavings() " << endl; + } + } + + kdDebugFuncOut(trace); + return retval; +} + + +// --> HAL method call (trigger actions) section -- END <--- + +// --> private helper functions/slots to forward/handle events -- START <-- +// need this functions to make events from HAL/D-Bus independent +// from QT event loop and to allow QT3 D-Bus bindings to get not +// blocked by normal KDE/QT (GUI) calls +/*! + * Function to emit the signal for the Power button. + */ +void HardwareInfo::emitPowerButtonPressed() { + if (sessionIsActive) { + emit powerButtonPressed(); + } else { + kdWarning() << "Session is not active, don't react on power button event!" << endl; + } +} + +/*! + * Function to emit the signal for the Sleep button. + */ +void HardwareInfo::emitSleepButtonPressed() { + if (sessionIsActive) { + emit sleepButtonPressed(); + } else { + kdWarning() << "Session is not active, don't react on sleep button event!" << endl; + } +} + +/*! + * Function to emit the signal for the s2disk button. + */ +void HardwareInfo::emitS2diskButtonPressed() { + if (sessionIsActive) { + emit s2diskButtonPressed(); + } else { + kdWarning() << "Session is not active, don't react on suspend2disk button event!" << endl; + } +} + +/*! + * Function to emit the signal about changes in the session state + */ +void HardwareInfo::emitSessionActiveState() { + if (sessionIsActive) { + if (!dbus_HAL->aquiredPolicyPowerInterface()) { + dbus_HAL->aquirePolicyPowerIface(); + } + } else { + if (dbus_HAL->aquiredPolicyPowerInterface()) { + dbus_HAL->releasePolicyPowerIface(); + } + } + + emit desktopSessionIsActive(sessionIsActive); +} + +/*! + * Function to set the brightess a step up. + * \param percentageStep Integer of next step should get set + * \return result of the operation + * \retval true if could get set + * \retval false else + */ +bool HardwareInfo::setBrightnessUp(int percentageStep) { + kdDebugFuncIn(trace); + + bool retval = false; + + checkCurrentBrightness(); + + if (supportBrightness() && (getCurrentBrightnessLevel() >= 0) && + (getCurrentBrightnessLevel() != (getMaxBrightnessLevel()-1))) { + int setTo = 0; + int minPercStep = 10; + int currentPerc = (int)(((float)getCurrentBrightnessLevel()/(float)(getMaxBrightnessLevel()-1))*100.0); + + if (percentageStep > 0 && (percentageStep <= (100-currentPerc))) { + minPercStep = percentageStep; + } + + if ((currentPerc + minPercStep) > 100) { + // set to 100 % + setTo = getMaxBrightnessLevel() -1; + } else { + setTo = (int)(((float)(getMaxBrightnessLevel()-1))*(((float)(currentPerc + minPercStep))/100.0)); + if ((setTo == getCurrentBrightnessLevel()) && (setTo < (getMaxBrightnessLevel() -1))) { + setTo++; + } + } + + if (trace) { + kdDebug() << "Max: " << getMaxBrightnessLevel() + << " Current: " << getCurrentBrightnessLevel() + << " minPercStep: " << minPercStep + << " currentPerc: " << currentPerc + << " setTo: " << setTo << endl; + } + + retval = setBrightness(setTo, -1); + } + + kdDebugFuncOut(trace); + return retval; +} + +/*! + * Function to set the brightess a step up. + * \param percentageStep Integer of next step should get set + * \return result of the operation + * \retval true if could get set + * \retval false else + */ +bool HardwareInfo::setBrightnessDown(int percentageStep) { + kdDebugFuncIn(trace); + + bool retval = false; + + checkCurrentBrightness(); + + if (supportBrightness() && (getCurrentBrightnessLevel() > 0)) { + int setTo = 0; + int minPercStep = 10; + int currentPerc = (int)(((float)getCurrentBrightnessLevel()/(float)(getMaxBrightnessLevel()-1))*100.0); + + if (percentageStep > 0 && (percentageStep < currentPerc)) { + minPercStep = percentageStep; + } + + if ((currentPerc - minPercStep) < 0) { + setTo = 0; + } else { + setTo = (int)(((float)(getMaxBrightnessLevel()-1))*(((float)(currentPerc - minPercStep))/100.0)); + if ((setTo == getCurrentBrightnessLevel()) && (setTo > 0)) { + setTo--; + } + } + + if (trace) { + kdDebug() << "Max: " << getMaxBrightnessLevel() + << " Current: " << getCurrentBrightnessLevel() + << " minPercStep: " << minPercStep + << " currentPerc: " << currentPerc + << " setTo: " << setTo << endl; + } + + retval = setBrightness(setTo, -1); + } + + kdDebugFuncOut(trace); + return retval; +} + +/*! + * Function to handle the signal for the brightness up button/key + */ +void HardwareInfo::brightnessUpPressed() { + kdDebugFuncIn(trace); + + if (brightness) { + if (!sessionIsActive) { + kdWarning() << "Session is not active, don't react on brightness up key event!" << endl; + } else { + if (currentBrightnessLevel < availableBrightnessLevels) { + setBrightnessUp(); + } else { + kdWarning() << "Could not set brightness to higher level, it's already set to max." << endl; + } + } + } + kdDebugFuncOut(trace); +} + +/*! + * Function to handle the signal for the brightness down button/key + */ +void HardwareInfo::brightnessDownPressed() { + kdDebugFuncIn(trace); + + if (brightness) { + if (!sessionIsActive) { + kdWarning() << "Session is not active, don't react on brightness down key event!" << endl; + } else { + if (currentBrightnessLevel > 0) { + setBrightnessDown(); + } else { + kdWarning() << "Could not set brightness to lower level, it's already set to min." << endl; + } + } + } +} + +// --> private helper slots to forward/handle events -- END <-- + +// --> get private members section -- START <--- + +/*! + * The function return the current state of the ac adapter. + * \return boolean with the current state + * \retval true if adapter is present/connected or unknown + * \retval false if not + */ +bool HardwareInfo::getAcAdapter() const { + return acadapter; +} + +/*! + * The function return the current state of the lidclose button. + * \return boolean with the current state + * \retval true if the lid is closed + * \retval false if the lid is opend + */ +bool HardwareInfo::getLidclose() const { + return lidclose; +} + +/*! + * The function return the maximal available brightness level + * \return Integer with max level or -1 if not supported + */ +int HardwareInfo::getMaxBrightnessLevel() const { + if (brightness) + return availableBrightnessLevels; + else + return -1; +} + +/*! + * The function return the current brightness level + * \return Integer with max level or -1 if not supported or unkown + */ +int HardwareInfo::getCurrentBrightnessLevel() const { + if (brightness) + return currentBrightnessLevel; + else + return -1; +} + +/*! + * The function return the current set CPU Frequency Policy + * \return Integer with currently set Policy or -1 if not supported or unkown + */ +int HardwareInfo::getCurrentCPUFreqPolicy() const { + return currentCPUFreqPolicy; +} + +/*! + * The function return information if the system support the different + * suspend/standby methodes and if the user can call them. + * \return struct with information from \ref suspend_states + * TODO: check if we maybe should replace this by more different functions + */ +SuspendStates HardwareInfo::getSuspendSupport() const { + return suspend_states; +} + +/*! + * The function return a pointer to the battery collection of primary batteries. + * \return BatteryCollection with type == PRIMARY + */ +BatteryCollection* HardwareInfo::getPrimaryBatteries() const { + return primaryBatteries; +} + +/*! + * The function return all batteries + * \return QPtrList<Battery> + */ +QPtrList<Battery> HardwareInfo::getAllBatteries() const { + return BatteryList; +} + + +/*! + * The function return the status of \ref laptop. + * \return boolean with info if machine is a laptop + * \retval true if a laptop + * \retval false else/if not a laptop + */ +bool HardwareInfo::isLaptop() const { + return laptop; +} + +/*! + * The function return info if there is a working connection to D-Bus and HAL. + * This mean if we get hardwareinformation + * \return boolean with info if D-Bus and HAL work + * \retval true if connected + * \retval false if not connected + */ +bool HardwareInfo::isOnline() const { + return (!dbus_terminated && !hal_terminated); +} + +/*! + * The function return the status of \ref has_ACPI. + * \return boolean with info if machine support ACPI + * \retval true if support ACPI + * \retval false else + */ +bool HardwareInfo::hasACPI() const { + return has_ACPI; +} + +/*! + * The function return the status of \ref has_APM. + * \return boolean with info if machine support APM + * \retval true if support APM + * \retval false else + */ +bool HardwareInfo::hasAPM() const { + return has_APM; +} + +/*! + * The function return the status of \ref has_PMU. + * \return boolean with info if machine support PMU + * \retval true if support PMU + * \retval false else + */ +bool HardwareInfo::hasPMU() const { + return has_PMU; +} + +/*! + * The function return the status of \ref brightness. + * \return boolean with info if machine support brightness changes via HAL + * \retval true if support brightness changes + * \retval false else + */ +bool HardwareInfo::supportBrightness() const { + return brightness; +} + +/*! + * The function return the status of \ref cpuFreq. + * \return boolean with info if machine support change the CPU frequency via HAL + * \retval true if support brightness changes + * \retval false else + */ +bool HardwareInfo::supportCPUFreq() const { + return cpuFreq; +} + +/*! + * The function return the status of \ref sessionIsActive. + * \return boolean with info if current desktop session is marked in ConsoleKit as activ + * \retval true if the current session is active + * \retval false else + */ +bool HardwareInfo::currentSessionIsActive() const { + return sessionIsActive; +} + +/*! + * The function return \ref cpuFreqAllowed and tell by this if the user is allowed + * to change the CPU Freq. + * \return \ref cpuFreqAllowed + * \retval 0 allowed + * \retval 1 not allowed + * \retval -1 unknown + */ +int HardwareInfo::isCpuFreqAllowed () { + cpuFreqAllowed = dbus_HAL->isUserPrivileged( PRIV_CPUFREQ, HAL_COMPUTER_UDI); + return cpuFreqAllowed; +} + +/*! check if the org.freedesktop.Policy.Power interface has an owner + * \return boolean with info if org.freedesktop.Policy.Power interface has an owner or not + * \retval true if there is a owner + * \retval false else + */ +bool HardwareInfo::isPolicyPowerIfaceOwned () { + return dbus_HAL->isPolicyPowerIfaceOwned(); +} + + +// --> get private members section -- END <--- + +#include "hardware.moc" diff --git a/src/hardware.h b/src/hardware.h new file mode 100644 index 0000000..826deb6 --- /dev/null +++ b/src/hardware.h @@ -0,0 +1,502 @@ + /************************************************************************** + * Copyright (C) 2006-2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! +* \file hardware.h +* \brief Headerfile for hardwareinfo.cpp. This file collect/hold all +* Hardware information as e.g. battery and ac state. +*/ + +/*! +* \class HardwareInfo +* \brief class for hardware information related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2006-2007 +*/ + +#ifndef _HARDWARE_H_ +#define _HARDWARE_H_ + +// Global Header +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +// QT - Header +#include <qstring.h> +#include <qobject.h> +#include <qvaluelist.h> +#include <qptrlist.h> +#include <qdict.h> + +// HAL Library +#include <hal/libhal.h> + +#include "dbusHAL.h" +#include "hardware_battery.h" +#include "hardware_batteryCollection.h" + +enum suspend_type { + SUSPEND2DISK, + SUSPEND2RAM, + STANDBY +}; + +enum cpufreq_type { + UNKNOWN_CPUFREQ = -1, + PERFORMANCE, + DYNAMIC, + POWERSAVE +}; + +enum device_type { + BATTERY, + AC_ADAPTER, + BUTTON_SLEEP, + BUTTON_POWER, + LID, + LAPTOP_PANEL, + UNKNOWN_DEVICE +}; + +enum ERROR_MSG { + DBUS_NO_RIGHTS, + DBUS_NOT_RUNNING, + DBUS_RUNNING +}; + +//! hold information if suspend/standby/pm actions are supported and allowed +/*! +* This dictionary contains information about the available pm capabilities and +* the related interfaces in HAL. +*/ +typedef struct SuspendStates { + //! true if the machine support suspend2ram and the interface is available + bool suspend2ram; + //! true if the machine support suspend2ram, but no interface available + bool suspend2ram_can; + //! true if the machine support suspend2ram and PolicyKit allow to call the interface + int suspend2ram_allowed; + //! true if the machine support suspend2disk and the interface is available + bool suspend2disk; + //! true if the machine support suspend2disk, but no interface available + bool suspend2disk_can; + //! true if the machine support suspend2disk and PolicyKit allow to call the interface + int suspend2disk_allowed; + //! true if the machine support standby and the interface is available + bool standby; + //! true if the machine support standby, but no interface available + bool standby_can; + //! true if the machine support standby and PolicyKit allow to call the interface + int standby_allowed; + + SuspendStates () { + suspend2ram = false; + suspend2ram_can = false; + suspend2ram_allowed = -1; + suspend2disk = false; + suspend2disk_can = false; + suspend2disk_allowed = -1; + standby = false; + standby_can = false; + standby_allowed = -1; + } +} SuspendStates; + +class HardwareInfo : public QObject{ + + Q_OBJECT + +private: + //! pointer to the dbusHAL connection class + dbusHAL *dbus_HAL; + + //! hold udis of special hardware execpt batteries represented by a QString pairs (name,udi) + /*! + * This directory handle udis for known fixed devices as e.g ac adapter. This devices are + * currently available: + * \li acadapter + * \li lidclose + * \li laptop_panel + */ + QDict<QString> udis; + + //! hold the UDIs of all hardware we handle atm + /*! + * This QStringList contains the list of UDIs we handle at the moment in this + * class. This should be used to handle device events from HAL for devices we + * want to monitor + */ + QStringList allUDIs; + + //! hold information if suspend/standby/pm actions are supported and allowed + /*! + * This dictionary contains information about the available pm capabilities and + * the related interfaces in HAL. + */ + SuspendStates suspend_states; + + QTime calledSuspend; + + //! hold the list of pointers to all relevant batteries + QPtrList<Battery> BatteryList; + //! hold the information about all primary batteries + BatteryCollection *primaryBatteries; + + //! hold the name of the CPU Freq governor from the last check + QString cpuFreqGovernor; + + //! hold the ConsoleKit name/path of the actual session + QString consoleKitSession; + + //! enum with the currently active CPU Freq policy + /*! This enum contains the enum with the currently set CPU Freq Policy. */ + cpufreq_type currentCPUFreqPolicy; + + //! the state of the ac adapter + /*! + * This boolean represent information about the AC adapter state. + * \li true: if AC adapter is present + * \li false: it AC adapter is not present + */ + bool acadapter; + //! the state of the lidclose button + /*! + * This boolean represent information about the Lid button state. + * \li true: if lid is closed + * \li false: else + */ + bool lidclose; + //! if the machine support APM + /*! + * This boolean represent information if the machine support APM or not. + * \li true: if APM supported + * \li false: else + */ + bool has_APM; + //! if the machine support ACPI + /*! + * This boolean represent information if the machine support ACPI or not. + * \li true: if ACPI supported + * \li false: else + */ + bool has_ACPI; + //! if the machine support PMU (ppc power management) + /*! + * This boolean represent information if the machine support PMU or not. + * \li true: if PMU supported + * \li false: else + */ + bool has_PMU; + //! if the machine support change CPU Freq via HAL interface + /*! + * This boolean represent information if the machine support change the + * CPU freqency via HAL. + * \li true: if supported + * \li false: else + */ + bool cpuFreq; + //! if the machine support change *SchedPowerSavings methodes via HAL interface + /*! + * This boolean represent information if the machine support change the + * SchedPowerSavings methodes via HAL. + * \li true: if supported + * \li false: else + */ + bool schedPowerSavings; + //! if the machine support change brightness + /*! + * This boolean represent information if the machine support brightness changes. + * \li true: if supported + * \li false: else + */ + bool brightness; + //! if brightness get controled via keyevents in hardware + /*! + * This boolean represent information if the machine handle brightness button + * and keyevents in hardware. If so KPowersave should ignore key events. + * \li true: if handled in hardware + * \li false: else + */ + bool brightness_in_hardware; + //! if the machine is a laptop + /*! + * This boolean represent information if the machine is a laptop. + * \li true: if the machine is a laptop + * \li false: else + */ + bool laptop; + + //! if the current desktop session is active + /*! + * This boolean represent information if the current desktop session in + * Which KPowersave runs is marked in ConsoleKit as active or not. + * \li true: if active + * \li false: else + */ + bool sessionIsActive; + + //! if the current user can use the CPU Freq interface + /*! + * This integer tell if the current user is allowed to change the + * CPU Frequency policy via the HAL interface + * \li 1: if allowed + * \li 0: if not allowed + * \li -1: if unknown (e.g. there is no policy/PolicyKit) + */ + int cpuFreqAllowed; + //! if the current user can use the brightness interface + /*! + * This integer tell if the current user is allowed to change the + * brightness via the HAL interface + * \li 1: if allowed + * \li 0: if not allowed + * \li -1: if unknown (e.g. there is no policy/PolicyKit) + */ + int brightnessAllowed; + + + //! Integer with the number of current brightness + /*! This contains the current brighness level. */ + int currentBrightnessLevel; + //! Integer with the number of availabl brightness level + /*! This contains the number of available brightness levels for internal usage. */ + int availableBrightnessLevels; + + //! interger with the current warning level + int primaryBatteriesWarnLevel; + //! interger with the current low level + int primaryBatteriesLowLevel; + //! interger with the current critical level + int primaryBatteriesCriticalLevel; + + // --> functions + //! check if the machine support ACPI/APM/PMU or not + void checkPowermanagement(); + //! check the possible suspend/standby states + void checkSuspend(); + //! check if the machine support change CPU Freq via HAL + void checkCPUFreq(); + //! check the current brightness level + void checkCurrentBrightness(); + //! check if the machine is a laptop + void checkIsLaptop(); + + //! initalise all hardware information + bool intialiseHWInfo(); + //! reinit all hardware information + bool reinitHardwareInfos(); + //! to check the current ConsoleKit session + bool checkConsoleKitSession(); + //! to check if we should handle a device + bool checkIfHandleDevice ( QString _udi, int *type ); + //! to set the CPUFreq governor + bool setCPUFreqGovernor( const char *governor ); + //! to get the state of SchedPowerSave setting of kernel/HAL + bool getSchedPowerSavings(); + //! to set the state of SchedPowerSave setting of kernel/HAL + bool setSchedPowerSavings( bool enable ); + + //! find and update a battery information + void updateBatteryValues (QString udi, QString property); + +private slots: + + //! to fetch events from D-Bus and handle them + void processMessage (msg_type type, QString message, QString value); + //! to update \ref primaryBatteries + void updatePrimaryBatteries (); + //! to set \ref update_info_primBattery_changed + void setPrimaryBatteriesChanges (); + //! check the state of the lidclose button + void checkLidcloseState(); + //! check the state of the AC adapter + void checkACAdapterState(); + //! check if brightness change is possible + void checkBrightness(); + + //! SLOT to handle the reconnect to D-Bus + void reconnectDBUS(); + + //! SLOT to forward signal about changed battery warning state + void emitBatteryWARNState (int type, int state); + + //! SLOT to handle resume and forward a signal for resume + void handleResumeSignal (int result); + + //! to emit signal for power button + void emitPowerButtonPressed(); + //! to emit signal for sleep button + void emitSleepButtonPressed(); + //! to emit signal for s2disk button + void emitS2diskButtonPressed(); + //! to emit signal for session state + void emitSessionActiveState(); + + //! to handle signal for brightness Up buttons/keys + void brightnessUpPressed(); + //! to handle signal for brightness Down buttons/keys + void brightnessDownPressed(); + +signals: + //! signal for larger data changes + void generalDataChanged(); + //! emited if the CPU Freq Policy changed + void currentCPUFreqPolicyChanged(); + + //! signal the AC adapter + void ACStatus( bool ); + //! signal for the lidclose button + void lidcloseStatus ( bool ); + //! signal for pressed the power button + void powerButtonPressed (); + //! signal for pressed sleep (suspend2ram) button + void sleepButtonPressed (); + //! signal for pressed the suspend2disk (hibernate) button + void s2diskButtonPressed (); + + // battery related signals + //! signal if the primary battery collection changed + void primaryBatteryChanged(); + //! signal to inform about reaching a warning state + void batteryWARNState(int type, int state); + + // Error signals + //! signal if the HAL daemon terminate and restart + void halRunning( bool ); + //! signal if the D-Bus daemon terminate and restart + void dbusRunning( int ); + + //! signal if the IsActive state of + void desktopSessionIsActive (bool); + + //! signal if we are back from resume + void resumed ( int success ); + +public: + + // update related info --> need to be reset if the data was read + //! tells if the CPUFreq Policy changed + /*! + * This boolean represent information about CPUFreq Policy changes. + * \li true: if something changed + * \li false: if nothing changed (or this is reset to false if the message was consumed) + */ + bool update_info_cpufreq_policy_changed; + //! tells if the AC status changed + /*! + * This boolean represent information about AC status changes. + * \li true: if something changed + * \li false: if nothing changed (or this is reset to false if the message was consumed) + */ + bool update_info_ac_changed; + //! tells if the primary battery collection changed some values + /*! + * This boolean represent information about primary battery changes. + * \li true: if something changed + * \li false: if nothing changed (or this is reset to false if the message was consumed) + */ + bool update_info_primBattery_changed; + + //! boolean which tell us if the D-Bus daemon was terminated + /*! + * This boolean contains information if the D-Bus daemon terminated and + * we recieved "dbus.terminate" + * \li true: If D-Bus terminated + * \li false: If D-Bus not terminated + */ + bool dbus_terminated; + //! boolean which tell us if the HAL daemon was terminated + /*! + * This boolean contains information if the HAL daemon terminated and + * we recieved "hal.terminate" + * \li true: If HAL terminated + * \li false: If HAL not terminated + */ + bool hal_terminated; + + // --> functions + //! default constructor + HardwareInfo(); + //! default destructor + ~HardwareInfo(); + + // to get private members + //! get info about support of suspend/standby + SuspendStates getSuspendSupport() const; + //! get a pointer to the primary batteries + BatteryCollection* getPrimaryBatteries() const; + //! get all batteries + QPtrList<Battery> getAllBatteries() const; + + //! check the currently set CPU Frequency Policy + cpufreq_type checkCurrentCPUFreqPolicy(); + + //! get max brightness level + int getMaxBrightnessLevel() const; + //! get current brightness level + int getCurrentBrightnessLevel() const; + //! get currently CPU Frequency Policy + int getCurrentCPUFreqPolicy() const; + //! if the user is allowed to change CPU Freq PolicyKit + int isCpuFreqAllowed (); + + //! if org.freedesktop.Policy.Power has a owner + bool isPolicyPowerIfaceOwned(); + + //! get state of the AC adapter + bool getAcAdapter() const; + //! get the state of the lid button + bool getLidclose() const; + //! check if the machine is a latop + bool isLaptop() const; + //! check if there is a connection to D-Bus _and_ HAL + bool isOnline() const; + //! check if the machine support ACPI + bool hasACPI() const; + //! check if the machine support APM + bool hasAPM() const; + //! check if the machine support PMU + bool hasPMU() const; + //! check if the machine support change the CPU frequency + bool supportCPUFreq() const; + //! check if the machine support brightness changes + bool supportBrightness() const; + //! check if the current session is active + bool currentSessionIsActive() const; + + // --> functions to call a HAL interface and trigger an action + //! execute/trigger a suspend via the HAL interface + bool suspend ( suspend_type suspend ); + //! set the brightness via HAL interface + bool setBrightness ( int level, int percent = -1); + //! to set the brightness down + bool setBrightnessDown(int percentageStep = -1); + //! to set the brightness up + bool setBrightnessUp(int percentageStep = -1); + //! set the CPU frequency policy/speed + bool setCPUFreq ( cpufreq_type cpufreq, int limit = 51 ); + //! call SetPowerSave method on HAL. + bool setPowerSave( bool on ); + + //! function to set warning states for the primary battery collection + void setPrimaryBatteriesWarningLevel (int _warn = -1, int _low = -1, int _crit = -1 ); +}; + +#endif diff --git a/src/hardware_battery.cpp b/src/hardware_battery.cpp new file mode 100644 index 0000000..131854f --- /dev/null +++ b/src/hardware_battery.cpp @@ -0,0 +1,1035 @@ + /************************************************************************** + * Copyright (C) 2006-2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! + * \file hardware_battery.cpp + * \brief In this file can be found the Battery related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2006-2007 + */ + +#include "hardware_battery.h" + +/*! The default constructor of the class Battery. */ +Battery::Battery(dbusHAL* _dbus_HAL) : dbus_HAL(_dbus_HAL) { + kdDebugFuncIn(trace); + + udi = QString(); + initialized = false; + + initDefault(); + init(NULL); + + kdDebugFuncOut(trace); +} + +/*! The default constructor of the class Battery. */ +Battery::Battery( dbusHAL* _dbus_HAL, QString _udi ) : dbus_HAL(_dbus_HAL), udi(_udi) { + if (trace) kdDebug() << funcinfo << "IN , udi: " << udi << endl; + + initialized = false; + + initDefault(); + init(NULL); + + kdDebugFuncOut(trace); +} + +/*! The default constructor of the class Battery. */ +Battery::Battery() { + kdDebugFuncIn(trace); + initialized = false; + + initDefault(); + udi = QString(); + + kdDebugFuncOut(trace); +} + +/*! The default destructor of the class Battery. */ +Battery::~Battery() { + kdDebugFuncIn(trace); + +} + +//! init a battery with default values +void Battery::initDefault() { + kdDebugFuncIn(trace); + + present = false; + type = BAT_UNKNOWN; + state = BAT_NORM; + capacity_state = "ok"; + charging_state = UNKNOWN_STATE; + charge_level_unit = "mWh"; + charge_level_current = 0; + charge_level_lastfull = 0; + charge_level_percentage = 0; + design_capacity = 0; + present_rate = 0; + remaining_minutes = 0; + serial = ""; + + warn_level = 12; + low_level = 7; + crit_level = 2; + + kdDebugFuncOut(trace); +} + +//! initialize this battery object with values from HAL +void Battery::init(dbusHAL* _dbus_HAL) { + kdDebugFuncIn(trace); + + if (_dbus_HAL != NULL) + dbus_HAL = _dbus_HAL; + + // read battery information from HAL + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + //couldnt connect to HAL + state=BAT_HAL_ERROR; + } else { + if (resetUdi(udi)) { + //udi is valid + recheck(); //fills all values + //ready here for now + } else { + //udi is invalid or is no battery + state=BAT_HAL_ERROR; + kdWarning() << "Warning: Battery::init cannot make use of udi " << udi << endl; + } + } + + initialized = true; + kdDebugFuncOut(trace); +} + +//! rechecks only minimalistic set properties +/*! +* Will only recheck properties regarding current battery states/levels. +*/ +void Battery::minRecheck() { + kdDebugFuncIn(trace); + + //first check whether HAL is available + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + //grr... no luck + kdError() << "Battery::recheck couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return; + } + + checkBatteryPresent(); + if (!present) { + kdDebug() << "No need to update other properties, battery not present." << endl; + kdDebugFuncOut(trace); + return; + } else { + checkCapacityState(); + checkChargeLevelCurrent(); + checkRemainingPercentage(); + checkChargingState(); + checkChargeLevelRate(); + checkRemainingTime(); + } + + kdDebugFuncOut(trace); +} + +//! recheck all properties of the battery +/*! + * Check and set the properties of a battery or collect the information for all + * primary batteries in one object. + */ +void Battery::recheck() { + kdDebugFuncIn(trace); + + //first check whether HAL is available + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + //grr... no luck + kdError() << "Battery::recheck couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return; + } + + checkBatteryPresent(); + checkBatteryType(); + if (!present) { + kdDebug() << "Warning: No need to update properties, battery not present." << endl; + kdDebugFuncOut(trace); + return; + } else { + checkBatteryTechnology(); + checkCapacityState(); + checkChargeLevelCurrent(); + checkChargeLevelLastfull(); + checkRemainingPercentage(); + checkChargingState(); + checkChargeLevelUnit(); + checkChargeLevelDesign(); + checkChargeLevelRate(); + checkRemainingTime(); + } + + kdDebugFuncOut(trace); +} + +// ---> query HAL for properties SECTION : START <---- + +//! to check battery.present +/*! + * function to update \ref present from property battery.present + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::checkBatteryPresent () { + kdDebugFuncIn(trace); + + bool _present = false; + + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + kdError() << "Couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + if (dbus_HAL->halGetPropertyBool(udi,"battery.present", &_present)) { + if (_present != present) { + present = _present; + + // force depending changes + if (_present) { + // should be now present + recheck(); + } + if (!_present) { + //Uhhh, battery is not present, so we need to reset battery to default. + initDefault(); + checkBatteryType(); + state = BAT_NONE; + } + + if (initialized) { + emit changedBatteryPresent(); + emit changedBattery(); + } + } + + // also query the serial ... no need to do this in a extra place + dbus_HAL->halGetPropertyString(udi, "battery.serial", &serial); + + } else { + //query was not successfull + kdDebug() << "Query of battery.present of " << udi << " wasn't successfull." << endl; + //..but we assume its there try on + present = true; + } + + kdDebugFuncOut(trace); + return true; +} + +//! to check battery.type +/*! + * function to update \ref type from property battery.type + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::checkBatteryType () { + kdDebugFuncIn(trace); + + QString tmp_qstring; + + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + kdError() << "Couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + if (dbus_HAL->halGetPropertyString(udi,"battery.type", &tmp_qstring)) { + if (tmp_qstring.compare("primary") == 0) { + type = BAT_PRIMARY; + } else if (tmp_qstring.compare("mouse") == 0) { + type = BAT_MOUSE; + } else if (tmp_qstring.compare("keyboard") == 0) { + type = BAT_KEYBOARD; + } else if (tmp_qstring.compare("keyboard_mouse") == 0) { + type = BAT_KEY_MOUSE; + } else if (tmp_qstring.compare("camera") == 0) { + type = BAT_CAMERA; + } else if (tmp_qstring.compare("ups") == 0) { + type = BAT_UPS; + } else { + //anything else will currently be "UNKNOWN" + type = BAT_UNKNOWN; + } + kdDebugFuncOut(trace); + return true; + } else { + //query was not successfull + kdWarning() << "Query of battery.type of " << udi << " was not successfull." << endl; + type = BAT_UNKNOWN; + kdDebugFuncOut(trace); + return false; + } +} + +//! to check battery.technology +/*! + * function to update \ref technology from property battery.technology + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::checkBatteryTechnology () { + kdDebugFuncIn(trace); + + QString tmp_qstring; + + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + kdError() << "Couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + if (!present) { + kdWarning() << "No need to update property, battery not present." << endl; + kdDebugFuncOut(trace); + return false; + } + + if (dbus_HAL->halGetPropertyString(udi,"battery.technology", &tmp_qstring)) { + if (!tmp_qstring.isEmpty()) { + technology = QString(tmp_qstring); + } else { + technology = QString("UNKNOWN"); + } + kdDebugFuncOut(trace); + return true; + } else { + //query was not successfull, but this property is optional + technology = QString("UNKNOWN"); + kdDebugFuncOut(trace); + return false; + } +} + + +//! to check battery.charge_level.capacity_state +/*! + * function to update \ref capacity_state from battery.charge_level.capacity_state + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::checkCapacityState () { + kdDebugFuncIn(trace); + + QString tmp_qstring; + + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + kdError() << "Couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + if (!present) { + kdWarning() << "No need to update property, battery not present." << endl; + kdDebugFuncOut(trace); + return false; + } + + if (dbus_HAL->halGetPropertyString(udi, "battery.charge_level.capacity_state", &tmp_qstring)) { + capacity_state = QString(tmp_qstring); + kdDebugFuncOut(trace); + return true; + } else { + //query was not successfull, but this property is optional + capacity_state = QString(); + kdDebugFuncOut(trace); + return false; + } +} + + +//! to check battery.charge_level.current +/*! + * function to update \ref charge_level_current from property battery.charge_level.current + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::checkChargeLevelCurrent () { + kdDebugFuncIn(trace); + + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + kdError() << "Couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + if (!present) { + kdWarning() << "No need to update property, battery not present." << endl; + kdDebugFuncOut(trace); + return false; + } + + if (dbus_HAL->halGetPropertyInt(udi, "battery.charge_level.current", &charge_level_current)) { + if (charge_level_current < 0) { + //overflow? + charge_level_current = 0; + } + kdDebugFuncOut(trace); + return true; + } else { + //query was not successfull (is mandatory) + kdError() << "Couldn't request charge_level.current for udi: " << udi << endl; + state = BAT_NONE; + kdDebugFuncOut(trace); + return false; + } +} + + +//! to check battery.charge_level.last_full +/*! + * function to update \ref charge_level_lastfull from property battery.charge_level.last_full + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::checkChargeLevelLastfull () { + kdDebugFuncIn(trace); + + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + kdError() << "Couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + if (!present) { + kdWarning() << "No need to update property, battery not present." << endl; + kdDebugFuncOut(trace); + return false; + } + + if (dbus_HAL->halGetPropertyInt(udi, "battery.charge_level.last_full", &charge_level_lastfull)) { + if (charge_level_lastfull < charge_level_current ) { + //possible overflow? + charge_level_lastfull = charge_level_current; + } + kdDebugFuncOut(trace); + return true; + } else { + //query was not successfull (is mandatory) + kdError() << "couldn't query last_full of udi: " << udi << endl; + charge_level_lastfull = 0; // set back to 0 + kdDebugFuncOut(trace); + return false; + } +} + +//! to check battery.charge_level.rate +/*! + * function to update \ref present_rate from property battery.charge_level.rate + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::checkChargeLevelRate () { + kdDebugFuncIn(trace); + + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + kdError() << "Couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + if (!present) { + kdWarning() << "No need to update property, battery not present." << endl; + kdDebugFuncOut(trace); + return false; + } + + int _rate = present_rate; + + if (dbus_HAL->halGetPropertyInt(udi, "battery.charge_level.rate", &present_rate)) { + if (present_rate < 0 ) + present_rate = 0; + + if (present_rate != _rate) + emit changedBattery(); + + kdDebugFuncOut(trace); + return true; + } else { + //query was not successfull but this is optional + kdError() << "Couldn't request charge_level.rate for udi: " << udi << endl; + present_rate = 0; + kdDebugFuncOut(trace); + return false; + } +} + + +//! to check battery.charge_level.unit +/*! + * function to update \ref charge_level_unit from property battery.charge_level.unit + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::checkChargeLevelUnit () { + kdDebugFuncOut(trace); + + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + kdError() << "Couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + if (!present) { + kdWarning() << "No need to update property, battery not present." << endl; + kdDebugFuncOut(trace); + return false; + } + + if (!dbus_HAL->halGetPropertyString(udi, "battery.charge_level.unit", &charge_level_unit)) { + //query was not successfull but this is optional + kdWarning() << "Couldn't request charge_level.unit for udi: " << udi << endl; + kdDebugFuncOut(trace); + return false; + } else { + kdDebugFuncOut(trace); + return true; + } +} + +//! to check battery.charge_level.design +/*! + * function to update \ref design_capacity from property battery.charge_level.design + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::checkChargeLevelDesign () { + kdDebugFuncIn(trace); + + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + kdError() << "Couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + if (!present) { + kdWarning() << "No need to update property, battery not present." << endl; + kdDebugFuncOut(trace); + return false; + } + + if (dbus_HAL->halGetPropertyInt(udi, "battery.charge_level.design", &design_capacity)) { + if (design_capacity < 0) + design_capacity = 0; + + kdDebugFuncOut(trace); + return true; + } else { + //query was not successfull (is mandatory but not critical) + kdWarning() << "Couldn't request charge_level.design for udi: " << udi << endl; + kdDebugFuncOut(trace); + return false; + } +} + + +//! to check battery.charge_level.percentage +/*! + * function to update \ref charge_level_percentage from property battery.charge_level.percentage + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::checkRemainingPercentage () { + kdDebugFuncIn(trace); + + bool ret = false; + int _val = 0; + int _state = -1; + + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + kdError() << "Couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + if (!present) { + kdWarning() << "No need to update property, battery not present." << endl; + kdDebugFuncOut(trace); + return false; + } + + if (dbus_HAL->halGetPropertyInt(udi, "battery.charge_level.percentage", &_val)) { + if (_val > 100) { + _val = 100; + } else if (_val < 0) { + _val = 0; + } + ret = true; + } else { + //query was not successfull, but this property is optional + //so we calculate it from charge_level + if (charge_level_current > 0) { + _val = (int)((float)(charge_level_current * 100) / (float)charge_level_lastfull); + ret = true; + } else { + kdError() << "Couldn't query percentage of udi: " << udi + << ". and charge_level_current >= 0" << endl; + } + } + + if (charge_level_percentage != _val) { + if (initialized) { + emit changedBatteryPercentage(); + emit changedBattery(); + } + charge_level_percentage = _val; + } + + //battery state + if (charge_level_percentage <= crit_level) { + //we are now in critical level + _state = BAT_CRIT; + } else if (charge_level_percentage <= low_level) { + //we are now in a low level + _state = BAT_LOW; + } else if (charge_level_percentage <= warn_level) { + //we are now in warning state + _state = BAT_WARN; + } else if (state != BAT_NONE) { + _state = BAT_NORM; + } else { + _state = BAT_NONE; + } + + if (state != _state) { + if (initialized) { + if (_state == (BAT_CRIT || BAT_LOW || BAT_WARN)) + emit changedBatteryWarnState(_state); + else if (state == (BAT_CRIT || BAT_LOW || BAT_WARN)) + emit changedBatteryWarnState(_state); + else + emit changedBatteryState(); + + emit changedBattery(); + } + state = _state; + } + + kdDebugFuncOut(trace); + return ret; +} + +//! to check battery.remaining_time +/*! + * function to update \ref remaining_minutes from property battery.remaining_time + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::checkRemainingTime () { + kdDebugFuncIn(trace); + + int _min = 0; + bool _ret = false; + + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + kdError() << "Couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + if (!present) { + kdWarning() << "No need to update property, battery not present." << endl; + kdDebugFuncOut(trace); + return false; + } + + if (dbus_HAL->halGetPropertyInt(udi, "battery.remaining_time", &_min)) { + _min /= 60; + _ret = true; + } else { + //query was not successfull, but this is optional + //and even very unlikely to be present + + //try to get it via charge_level_current and present_rate + if (charge_level_current > 0 && present_rate > 0) { + _min = ((charge_level_current * 60 )/ present_rate) ; + _ret = true; + } else { + //we don't know it better + _min = 0; + _ret = false; + } + } + + if (remaining_minutes != _min) { + if (initialized) { + emit changedBatteryTime(); + emit changedBattery(); + } + + remaining_minutes = _min; + } + + kdDebugFuncOut(trace); + return _ret; +} + +//! to check battery.rechargeable.is_* +/*! + * function to update \ref charging_state from property battery.rechargeable.is_* + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::checkChargingState () { + kdDebugFuncIn(trace); + + bool tmp_bool = false; + bool tmp_bool2 = false; + bool _ret = false; + int _c_state = -1; + + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + kdError() << "Couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + if (!present) { + kdWarning() << "No need to update property, battery not present." << endl; + kdDebugFuncOut(trace); + return false; + } + + if (dbus_HAL->halGetPropertyBool(udi, "battery.rechargeable.is_charging", &tmp_bool) && + dbus_HAL->halGetPropertyBool(udi, "battery.rechargeable.is_discharging", &tmp_bool2)) { + if (tmp_bool && !tmp_bool2) { + _c_state = CHARGING; + } else if (tmp_bool2 && !tmp_bool) { + _c_state = DISCHARGING; + } else { + _c_state = UNKNOWN_STATE; + } + + _ret = true; + } else { + kdError() << "Couldn't get current charging state for udi: " << udi << endl; + _c_state = UNKNOWN_STATE; + _ret = false; + } + + if (charging_state != _c_state) { + if (initialized) { + emit changedBatteryChargingState(); + emit changedBattery(); + } + + charging_state = _c_state; + } + + kdDebugFuncOut(trace); + return _ret; +} + +// ---> query HAL for properties SECTION : END <---- + +//! to recheck a special value for a HAL event +/*! + * Check for the given property new values from HAL and set them to + * the battery variables. + * \param _udi QString with the UDI of the device to recheck + * \param _property QString with the property which was changed + * \return boolean with the result of the operation + * \retval true if the update was successfull + * \retval false if the update couldn't be applied + */ +bool Battery::updateProperty(QString _udi, QString _property) { + kdDebugFuncIn(trace); + + //first check whether HAL is available + if (!dbus_HAL->isConnectedToHAL() && !dbus_HAL->reconnect()) { + //grr... no luck + kdError() << "Battery::updateProperty couldn't connect to HAL" << endl; + kdDebugFuncOut(trace); + return false; + } + + bool ret = true; + + if (udi.startsWith(_udi)) { + // handle different keys and update only the needed + if (_property.startsWith("battery.present")) { + if (!checkBatteryPresent()) ret = false; + } else if (_property.startsWith("battery.type")) { + if (!checkBatteryType()) ret = false; + } else if (_property.startsWith("battery.charge_level.capacity_state")) { + if (!checkCapacityState()) ret= false; + } else if (_property.startsWith("battery.charge_level.current")) { + if (!checkChargeLevelCurrent()) ret = false; + } else if (_property.startsWith("battery.charge_level.rate")) { + if (!checkChargeLevelRate()) ret = false; + } else if (_property.startsWith("battery.charge_level.percentage")) { + if (!checkRemainingPercentage()) ret = false; + } else if (_property.startsWith("battery.remaining_time")) { + if (!checkRemainingTime()) ret = false; + } else if (_property.startsWith("battery.rechargeable.is_")) { + if (!checkChargingState()) ret = false; + } else if (_property.startsWith("battery.charge_level.last_full")) { + if (!checkChargeLevelLastfull()) ret = false; + // --> changes on this keys should normally not happen except if battery was added /removed + } else if (_property.startsWith("battery.technology")) { + if (!checkBatteryTechnology()) ret = false; + } else if (_property.startsWith("battery.charge_level.unit")) { + if (!checkChargeLevelUnit()) ret = false; + } else if (_property.startsWith("battery.charge_level.design")) { + if (!checkChargeLevelDesign()) ret = false; + } else { + kdDebug() << "Unknown or unhandled device property: " << _property + << " for device with udi: " << _udi << endl; + ret = false; + } + } else { + kdError() << "Given UDI doesn't match the UDI of this battery object." << endl; + ret = false; + } + + kdDebugFuncOut(trace); + return ret; +} + +//! Resets the current HAL udi used by the one given +/*! +* The given QString will be (checked and) used as new HAL udi for the battery. +* But don't forget to do a recheck of the battery afterwards. +* \param _udi QString with the UDI to reset +* \return boolean with the result of the operation +* \retval true if reset was successfull +* \retval false if reset couldn't be applied +*/ +bool Battery::resetUdi(QString _udi) { + kdDebugFuncIn(trace); + + bool tmp_result=false; + + //trivial pre-check to eliminate totally dumb _udi strings + if (!_udi.isNull() && !_udi.isEmpty() && _udi.startsWith("/org/freedesktop/Hal/devices/")) { + + //ok, now lets ask HAL if its really a battery + if (dbus_HAL->isConnectedToHAL() || dbus_HAL->reconnect()) { + + dbus_HAL->halQueryCapability(_udi,"battery",&tmp_result); + + } else { + kdError() << "Battery::resetUdi couldn't connect to HAL" << endl; + } + + } else { + kdError() << "Battery::resetUdi received empty or invalid udi" << endl; + } + + kdDebugFuncOut(trace); + return tmp_result; +} + +// ---> write private members SECTION : START <---- + +//! sets the chargelevel in percent when battery should go into state warning +void Battery::setWarnLevel(int _warn_level) { + kdDebugFuncIn(trace); + + if (_warn_level < low_level) { + kdError() << "Refuse requested level: " << _warn_level + << " as it is smaller than the LowLevel: " << low_level << endl; + } else { + warn_level = _warn_level; + } + + kdDebugFuncOut(trace); +} + +//! sets the chargelevel in percent when battery should go into state low +void Battery::setLowLevel(int _low_level) { + kdDebugFuncIn(trace); + + if (_low_level < crit_level || _low_level > warn_level) { + kdError() << "Refuse requested level: " << _low_level + << " as it is not between WarnLevel: " << warn_level + << " and CritLevel: " << crit_level << endl; + } else { + low_level = _low_level; + } + + kdDebugFuncOut(trace); +} + +//! sets the chargelevel in percent when battery should go into state critical +void Battery::setCritLevel(int _crit_level) { + kdDebugFuncIn(trace); + + if (_crit_level > low_level) { + kdError() << "Refuse requested level: " << _crit_level + << " as it is bigger than LowLevel: " << low_level << endl; + } else { + crit_level = _crit_level; + } + + kdDebugFuncOut(trace); +} + +// ---> write private members SECTION : END <---- +// ---> get private members SECTION : START <---- + +//! reports the HAL udi of this battery +QString Battery::getUdi() const { + return QString(udi); +} + +//! reports the battery type +int Battery::getType() const { + return type; +} + +//! gives the name of this battery technology +QString Battery::getTechnology() const { + return QString(technology); +} + +//! tells the current batterystate as enum BAT_STATE_ +int Battery::getState() const { + return state; +} + +//! estimates the remaining minutes until fully charged/discharged +int Battery::getRemainingMinutes() const { + return remaining_minutes; +} + +//! current charging/discharging rate +int Battery::getPresentRate() const { + return present_rate; +} + +//! get availability of this battery +bool Battery::isPresent() { + return present; +} + +//! maximum capacity of this battery by design +int Battery::getDesignCapacity() const { + return design_capacity; +} + +//! current charging state as enum BAT_CHARG_STATE +int Battery::getChargingState() const { + return charging_state; +} + +//! reports the physical unit of values like DesignCapacity, PresentRate and Lastfull +QString Battery::getChargelevelUnit() const { + return QString(charge_level_unit); +} + +//! reports current chargelevel in percentage +int Battery::getPercentage() const { + return charge_level_percentage; +} + +//! reports last full capacity of this battery when fully charged +int Battery::getLastfull() const { + return charge_level_lastfull; +} + +//! reports current chargelevel in units reported by getChargelevelUnit() +int Battery::getCurrentLevel() const { + return charge_level_current; +} + +//! reports HAL capacity_state value +QString Battery::getCapacityState() const { + return QString(capacity_state); +} + +//! reports the chargelevel in percent when battery goes to state warning +int Battery::getWarnLevel() const { + return warn_level; +} + +//! reports the chargelevel in percent when battery goes to state low +int Battery::getLowLevel() const { + return low_level; +} + +//! reports the chargelevel in percent when battery goes to state critical +int Battery::getCritLevel() const { + return crit_level; +} + +//some convenience methods + +//! check if the battery is currently charged +bool Battery::isCharging() { + return (charging_state == CHARGING); +} + +//! check if the battery gets currently discharged +bool Battery::isDischarging() { + return (charging_state == DISCHARGING); +} + +//! check it this is a primary battery +bool Battery::isPrimary() const { + return (type == BAT_PRIMARY); +} + +//! check if the battery state is ok/normal +bool Battery::isOk() { + return (state == BAT_NORM); +} + +//! check if the battery is in warning level/state +bool Battery::isWarning() { + return (state == BAT_WARN); +} + +//! check if the battery is in a low chargingstate +bool Battery::isLow() { + return (state == BAT_LOW); +} + +//! check if the battery level is critical +bool Battery::isCritical() { + return (state == BAT_CRIT); +} + +// ---> get private members SECTION : START <---- + +#include "hardware_battery.moc" diff --git a/src/hardware_battery.h b/src/hardware_battery.h new file mode 100644 index 0000000..99a0bc0 --- /dev/null +++ b/src/hardware_battery.h @@ -0,0 +1,341 @@ + /************************************************************************** + * Copyright (C) 2006-2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + + +/*! +* \file hardware_battery.h +* \brief Headerfile for hardware_battery.cpp and the class \ref Battery. +*/ +/*! +* \class Battery +* \brief class for Battery related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2006-2007 +*/ + +#ifndef _BATTERY_H_ +#define _BATTERY_H_ + +// Global Header +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +// QT - Header +#include <qstring.h> +#include <qstringlist.h> +#include <qobject.h> + +#include "dbusHAL.h" + +class Battery : public QObject { + + Q_OBJECT + +private: + //! Internal reference to dbusHAL for communication with HAL daemon + dbusHAL* dbus_HAL; + + //! HAL udi of the battery to represent + /*! + * This QString holds the HAL udi adress of the battery. + * \li empty: all primary batteries are represented + * \li e.g. "/org/freedesktop/Hal/devices/acpi_BAT0": first acpi battery + */ + QString udi; + + //! Technologyname of the battery + /*! + * Tells the type of technologyname the battery is working with. + * \li e.g. "LION" + */ + QString technology; + //! Current charging state of this battery as reported by HAL + /*! + * This QString tells the current capacity_state HAL is reporting. + * \li as of current HAL spec: "ok", "critical" + */ + QString capacity_state; + //! Unit of charge_level_unit and charge_level_lastfull. + /*! This QString tells the physical unit the values of charge_level_unit. */ + QString charge_level_unit; + //! Serialnumber of the the battery + /*! Identifies the currently installed battery uniquely. */ + QString serial; + + //! Boolean which tells if the battery is initalized first time + /*! + * When the battery (represented by the object) is intialised the first time + * (via recheck() or init()) this value is true. + * \li true: if battery object is now intialised + * \li false: if not + */ + bool initialized; + //! Boolean which tells if the battery is present/connected + /*! + * When the battery (represented by the object) is available this is true. + * \li true: battery is available + * \li false: battery is disconnected/not available + */ + bool present; + + //! Roletype of battery + /*! + * This int/enum tells what role this battery is used as. + * \li BAT_PRIMARY: Std. battery for normal system operation + * \li BAT_MOUSE: powersupply for wireless mouse + * \li BAT_KEYBOARD: powersupply in wireless keyboards + * \li BAT_KEY_MOUSE: powersupply in combined keyboard+mouse gadgets + * \li BAT_UPS: Battery in UPS systems (step in on outage of mains) + * \li BAT_CAMERA: battery is contained in a connected digital camera + * \li UNKNOWN: Batterytype/role isn't known + */ + int type; + //! Current general state this battery is in + /*! + * This int/enum tells what rough state the battery is currently in. + * \li BAT_NORM: batterylevel is ok + * \li BAT_WARN: battery is soon getting low + * \li BAT_LOW: batterylevel is already low + * \li BAT_CRIT: batterylevel has become really critical + * \li BAT_NONE: battery state not available + * \li BAT_HAL_ERROR: battery state couldn't be retrieved because of a HAL error + */ + int state; + //! Current charging state of this battery + /*! + * This int/enum tells if the battery is charged or discharged. + * \li CHARGING: battery gets charged + * \li DISCHARGING: battery get discharged + * \li UNKNOWN_STATE: battery is neither charged nor discharged + */ + int charging_state; + //! Current level the battery is charged to + /*! + * This int tells (in physical units of Battery::charge_level_unit) + * at what charging level the battery is currently at + * \li a value >= 0 + */ + int charge_level_current; + //! Charging level of battery it could hold when fully charged + /*! + * This int tells (in physical units of Battery::charge_level_unit) the + * maximum charginglevel of the battery on its last fullcharge. + * \li a value >=0 + */ + int charge_level_lastfull; + //! Current charge level of battery in percentage + /*! + * This int tells the current charge level of the battery in percent. + * \li a value between 0 and 100 + */ + int charge_level_percentage; + //! The maximum capacity by design of the battery. + /*! + * This int tells (in physical units of Battery::charge_level_unit) + * the maximum capacity this battery was designed for by its vendor. + * \li a value > 0 + */ + int design_capacity; + //! Current charging/discharging rate + /*! + * This int tells (in physical units of Battery::charge_level_unit per + * second) the currently reported charging/discharging rate. + * \li a value >= 0 + */ + int present_rate; + //! Expected minutes unitl fully discharged/charged + /*! + * This int tells the current estimate until the battery is fully + * discharged/charged (with current discharging/charging-rate and last + * full capacity). + * \li a value >= 0 + */ + int remaining_minutes; + + //! charge_level in percent that will put battery into warning state + int warn_level; + //! charge_level in percent that will put battery into low state + int low_level; + //! charge_level in percent that will put battery into critical state + int crit_level; + + // private functions + //! function to set initial values for a battery + void initDefault(); + + //! to check battery.present + bool checkBatteryPresent(); + //! to check battery.type + bool checkBatteryType(); + //! to check battery.technology + bool checkBatteryTechnology(); + //! to check battery.charge_level.capacity_state + bool checkCapacityState(); + //! to check battery.charge_level.current + bool checkChargeLevelCurrent(); + //! to check battery.charge_level.last_full + bool checkChargeLevelLastfull(); + //! to check battery.charge_level.rate + bool checkChargeLevelRate(); + //! to check battery.charge_level.unit + bool checkChargeLevelUnit(); + //! to check battery.charge_level.design + bool checkChargeLevelDesign(); + //! to check battery.charge_level.percentage + bool checkRemainingPercentage(); + //! to check battery.remaining_time + bool checkRemainingTime(); + //! to check battery.rechargeable.is_* + bool checkChargingState(); + +signals: + //! emitted if the remaining percentage changed + void changedBatteryPercentage(); + //! emitted if the remaining time changed + void changedBatteryTime(); + //! emitted if the the present state changed + void changedBatteryPresent(); + //! emitted if the charging state changed + void changedBatteryChargingState(); + //! emitted if the battery state changed + void changedBatteryState(); + //! emitted if the Battery warning state changed + void changedBatteryWarnState (int state); + //! emitted if any Battery state changed + void changedBattery(); + +public: + + //! default constructor + Battery( dbusHAL* _dbus_HAL, QString _udi ); + //! default constructor + Battery( dbusHAL* _dbus_HAL ); + //! this constructor forces the use of init with dbuHAL pointer set! + Battery(); + //! default destructor + ~Battery(); + + //! initialize this battery object with values from HAL + void init( dbusHAL* _dbus_HAL = NULL ); + //! recheck all properties of the battery + void recheck(); + //! rechecks only minimalistic set properties + void minRecheck(); + //! update a property on HAL event + bool updateProperty(QString _udi, QString _property); + + //ro-Interface to internal data + //! reports the HAL udi of this battery + QString getUdi() const; + //! reports HAL capacity_state value + QString getCapacityState() const; + //! reports the physical unit of values like DesignCapacity, PresentRate and Lastfull + QString getChargelevelUnit() const; + //! gives the name of this battery technology + QString getTechnology() const; + + //! get availability of this battery + bool isPresent(); + + //! reports the battery type + int getType() const; + //! tells the current batterystate as enum BAT_STATE_ + int getState() const; + //! estimates the remaining minutes until fully charged/discharged + int getRemainingMinutes() const; + //! current charging/discharging rate + int getPresentRate() const; + //! maximum capacity of this battery by design + int getDesignCapacity() const; + //! current charging state as enum BAT_CHARG_STATE + int getChargingState() const; + //! reports current chargelevel in percentage + int getPercentage() const; + //! reports last full capacity of this battery when fully charged + int getLastfull() const; + //! reports current chargelevel in units reported by getChargelevelUnit() + int getCurrentLevel() const; + + //! reports the chargelevel in percent when battery goes to state warning + int getWarnLevel() const; + //! reports the chargelevel in percent when battery goes to state low + int getLowLevel() const; + //! reports the chargelevel in percent when battery goes to state critical + int getCritLevel() const; + + //writeable access to internals + //! Resets the current HAL udi used by the one given + /*! + * The given QString will be (checked and) used as new HAL udi for the battery. + * But don't forget to do a recheck of the battery afterwards. + * \li returns TRUE: if reset was successfull + * \li returns FALSE: if reset couldn't be applied + */ + bool resetUdi(QString); + + //! sets the chargelevel in percent when battery should go into state warning + void setWarnLevel(int _warn_level); + //! sets the chargelevel in percent when battery should go into state low + void setLowLevel(int _low_level); + //! sets the chargelevel in percent when battery should go into state critical + void setCritLevel(int _crit_level); + + //some convenience methods + //! check if the battery is currently charged + bool isCharging(); + //! check if the battery gets currently discharged + bool isDischarging(); + //! check it this is a primary battery + bool isPrimary() const; + //! check if the battery state is ok/normal + bool isOk(); + //! check if the battery is in warning level/state + bool isWarning(); + //! check if the battery is in a low chargingstate + bool isLow(); + //! check if the battery level is critical + bool isCritical(); +}; + + +enum BAT_TYPE { + BAT_PRIMARY, + BAT_MOUSE, + BAT_KEYBOARD, + BAT_KEY_MOUSE, + BAT_UPS, + BAT_CAMERA, + BAT_UNKNOWN +}; +enum BAT_CHARG_STATE { + CHARGING, + DISCHARGING, + UNKNOWN_STATE +}; +enum BAT_STATE { + BAT_NONE, + BAT_WARN, + BAT_LOW, + BAT_CRIT, + BAT_NORM, + BAT_HAL_ERROR +}; + +#endif diff --git a/src/hardware_batteryCollection.cpp b/src/hardware_batteryCollection.cpp new file mode 100644 index 0000000..a9b00e4 --- /dev/null +++ b/src/hardware_batteryCollection.cpp @@ -0,0 +1,340 @@ + /************************************************************************** + * Copyright (C) 2006-2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! + * \file hardware_batteryCollection.cpp + * \brief In this file can be found the Battery Collection related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2006-2007 + */ + +// own headers +#include "hardware_batteryCollection.h" + +/*! The default constructor of the class BatteryCollection. */ +BatteryCollection::BatteryCollection( int _type ) { + kdDebugFuncIn(trace); + + initDefault(); + type = _type; + + kdDebugFuncOut(trace); +} + + +/*! The default destructor of the class BatteryCollection. */ +BatteryCollection::~BatteryCollection( ) { + kdDebugFuncIn(trace); + +} + +//! init a battery with default values +void BatteryCollection::initDefault() { + kdDebugFuncIn(trace); + + udis.clear(); + + present_rate_unit = "mWh"; + + charging_state = UNKNOWN_STATE; + state = BAT_NORM; + remaining_percent = -1; + remaining_minutes = -1; + present_rate = 0; + + warn_level = 12; + low_level = 7; + crit_level = 2; + + kdDebugFuncOut(trace); +} + +/*! + * This function refresh the information of the collection from the given + * batterylist. + * \param BatteryList QPtrList with battery objects + * \param force_level_recheck boolean with info if the the check for the current + * battery warning level should get forced + */ +bool BatteryCollection::refreshInfo(QPtrList<Battery> BatteryList, bool force_level_recheck) { + kdDebugFuncIn(trace); + + int _charging_state = UNKNOWN_STATE; + int _percent = 0; + int _minutes = 0; + int _present_batteries = 0; + int _present_rate = 0; + + // for now: clean list before run update process! + udis.clear(); + + if (!BatteryList.isEmpty()) { + Battery *bat; + for (bat = BatteryList.first(); bat; bat = BatteryList.next() ) { + if (type == bat->getType()) { + udis.append(bat->getUdi()); + + if (bat->isPresent()) { + // count present batteries + _present_batteries++; + + // handle charging state + if (bat->getChargingState() != _charging_state) { + if (_charging_state == UNKNOWN_STATE) { + _charging_state = bat->getChargingState(); + } else if ( bat->getChargingState() == UNKNOWN_STATE) { + kdWarning() << "found battery with unknown state," + << " do nothing" << endl; + } else { + + if (_charging_state != bat->getChargingState()) { + // This should only happen if one is in + // state CHARGING and the other in DISCHARGING + kdWarning() << "Unexpected chargingstates" << endl; + _charging_state = UNKNOWN_STATE; + } + } + } + + // handle remaining percentage + if (bat->getPercentage() >= 0) { + _percent = (_percent + bat->getPercentage()) / _present_batteries; + } + + if (bat->getRemainingMinutes() >= 0) { + _minutes += bat->getRemainingMinutes(); + } + + if (bat->getPresentRate() >= 0) { + _present_rate += bat->getPresentRate(); + } + + if (!bat->getChargelevelUnit().isEmpty()) { + present_rate_unit = bat->getChargelevelUnit(); + } + } + } + } + + bool _changed = false; + + if (_charging_state != charging_state) { + charging_state = _charging_state; + _changed = true; + emit batteryChargingStateChanged (charging_state); + } + if (_percent != remaining_percent || force_level_recheck) { + remaining_percent = _percent; + + if (_present_batteries < 1) { + /* there are no batteries present, we don't need to emit + a event, there is nothing ... */ + state = BAT_NONE; + }else if (remaining_percent <= crit_level) { + if (state != BAT_CRIT) { + state = BAT_CRIT; + emit batteryWarnState( type, BAT_CRIT ); + } + } else if (remaining_percent <= low_level) { + if (state != BAT_LOW) { + state = BAT_LOW; + emit batteryWarnState( type, BAT_LOW ); + } + } else if (remaining_percent <= warn_level) { + if (state != BAT_WARN) { + state = BAT_WARN; + emit batteryWarnState( type, BAT_WARN ); + } + } else if (state != BAT_NONE) { + if (state != BAT_NORM) { + state = BAT_NORM; + emit batteryWarnState( type, BAT_NORM ); + } + } else { + state = BAT_NONE; + } + + _changed = true; + emit batteryPercentageChanged (remaining_percent ); + } + if (_minutes != remaining_minutes) { + remaining_minutes = _minutes; + _changed = true; + emit batteryMinutesChanged( remaining_minutes ); + } + if (_present_batteries != present_batteries) { + present_batteries = _present_batteries; + _changed = true; + emit batteryPresentChanged ( present_batteries ); + } + if (_present_rate != present_rate ) { + present_rate = _present_rate; + // don't set to changed, this avoid useless calls + emit batteryRateChanged (); + } + + if (_changed) + emit batteryChanged(); + + kdDebugFuncOut(trace); + return true; + } else { + kdError() << "Could not refresh battery information, BatteryList was empty" << endl; + initDefault(); + kdDebugFuncOut(trace); + return false; + } +} + +//! check if the given udi is already handled by this collection +bool BatteryCollection::isBatteryHandled( QString udi ) { + return udis.contains( udi ); +} + +// ---> write private members SECTION : START <---- +//! get the unit for charge level stuff +QString BatteryCollection::getChargeLevelUnit() const { + return present_rate_unit; +} + +//! get the current reported battery rate +int BatteryCollection::getCurrentRate() const { + return present_rate; +} + +//! get the cumulative remaining time +int BatteryCollection::getRemainingMinutes() const { + return remaining_minutes; +} + +//! get the cumulative remaining percentage of the battery capacity +int BatteryCollection::getRemainingPercent() const { + return remaining_percent; +} + +//! get the current Charging state of the machine +int BatteryCollection::getChargingState() const { + return charging_state; +} + +//! get the current battery state for this collection +int BatteryCollection::getBatteryState() const { + return state; +} + +//! get the number of available batteries +int BatteryCollection::getNumBatteries() const { + return udis.count(); +} + +//! get the number of present batteries, represent \ref present_batteries +int BatteryCollection::getNumPresentBatteries() const { + return present_batteries; +} + +//! get the battery Type from enum \ref BAT_TYPE +int BatteryCollection::getBatteryType() const { + return type; +} + +//! sets the chargelevel in percent when battery should go into state warning +/*! + * \return boolean with result of the operation + * \retval true if successful + * \retval false else, if a error occurs + */ +bool BatteryCollection::setWarnLevel(int _warn_level) { + kdDebugFuncIn(trace); + + if (_warn_level < low_level) { + kdError() << "Refuse: " << _warn_level + << " as it is smaller than the LowLevel: " << low_level << endl; + kdDebugFuncOut(trace); + return false; + } else { + warn_level = _warn_level; + kdDebugFuncOut(trace); + return true; + } +} + +//! sets the chargelevel in percent when battery should go into state low +/*! + * \return boolean with result of the operation + * \retval true if successful + * \retval false else, if a error occurs + */ +bool BatteryCollection::setLowLevel(int _low_level) { + kdDebugFuncIn(trace); + + if (_low_level < crit_level || _low_level > warn_level) { + kdError() << "Refuses: " << _low_level + << " as it is not between WarnLevel: " << warn_level + << " and CritLevel: " << crit_level << endl; + kdDebugFuncOut(trace); + return false; + } else { + low_level = _low_level; + kdDebugFuncOut(trace); + return true; + } +} + +//! sets the chargelevel in percent when battery should go into state critical +/*! + * \return boolean with result of the operation + * \retval true if successful + * \retval false else, if a error occurs + */ +bool BatteryCollection::setCritLevel(int _crit_level) { + kdDebugFuncIn(trace); + + if (_crit_level > low_level) { + kdError() << "Refuses " << _crit_level + << " as it is bigger than LowLevel: " << low_level << endl; + kdDebugFuncOut(trace); + return false; + } else { + crit_level = _crit_level; + kdDebugFuncOut(trace); + return true; + } +} + +// ---> write private members SECTION : END <---- +// ---> get private members SECTION : START <---- + +//! reports the chargelevel in percent when battery goes to state warning +int BatteryCollection::getWarnLevel() const { + return warn_level; +} + +//! reports the chargelevel in percent when battery goes to state low +int BatteryCollection::getLowLevel() const { + return low_level; +} + +//! reports the chargelevel in percent when battery goes to state critical +int BatteryCollection::getCritLevel() const { + return crit_level; +} + +// ---> get private members SECTION : END <---- + +#include "hardware_batteryCollection.moc" diff --git a/src/hardware_batteryCollection.h b/src/hardware_batteryCollection.h new file mode 100644 index 0000000..9b98952 --- /dev/null +++ b/src/hardware_batteryCollection.h @@ -0,0 +1,204 @@ + /************************************************************************** + * Copyright (C) 2006-2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! +* \file hardware_batteryCollection.h +* \brief Headerfile for hardware_batteryCollection.cpp and the class \ref BatteryCollection. +*/ +/*! +* \class BatteryCollection +* \brief class to collect batteryinformation for a special type of battries +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2006-2007 +*/ + +#ifndef _BATTERYCOLLECTION_H_ +#define _BATTERYCOLLECTION_H_ + +// Global Header +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +// QT - Header +#include <qstring.h> +#include <qstringlist.h> +#include <qobject.h> + +// own Header +#include "hardware_battery.h" + +class BatteryCollection : public QObject { + + Q_OBJECT + +private: + + //! contains the udis of the batteries of this collection + QStringList udis; + + //! contains the rate unit + QString present_rate_unit; + + //! Roletype of battery + /*! + * This int/enum tells what role this battery is used as. + * \li BAT_PRIMARY: Std. battery for normal system operation + * \li BAT_MOUSE: powersupply for wireless mouse + * \li BAT_KEYBOARD: powersupply in wireless keyboards + * \li BAT_KEY_MOUSE: powersupply in combined keyboard+mouse gadgets + * \li BAT_UPS: Battery in UPS systems (step in on outage of mains) + * \li BAT_CAMERA: battery is contained in a connected digital camera + * \li UNKNOWN: Batterytype/role isn't known + */ + int type; + //! Current charging state of the active battery of this collection + /*! + * This int/enum tells if the battery is charged or discharged. + * \li CHARGING: battery gets charged + * \li DISCHARGING: battery get discharged + * \li UNKNOWN_STATE: battery is neither charged nor discharged + */ + int charging_state; + //! Current general state this battery is in + /*! + * This int/enum tells what rough state the battery is currently in. + * \li BAT_NORM: batterylevel is ok + * \li BAT_WARN: battery is soon getting low + * \li BAT_LOW: batterylevel is already low + * \li BAT_CRIT: batterylevel has become really critical + * \li BAT_NONE: battery state not available + * \li BAT_HAL_ERROR: battery state couldn't be retrieved because of a HAL error + */ + int state; + + //! Current charge level of battery in percentage + /*! + * This int tells the current charge level of the battery in percent. + * \li a value between 0 and 100 + */ + int remaining_percent; + //! Expected minutes unitl fully discharged/charged + /*! + * This int tells the current estimate until the battery is fully + * discharged/charged (with current discharging/charging-rate and last + * full capacity). + * \li a value >= 0 + */ + int remaining_minutes; + + //! number of present batteries + /*! + * This int tells how many batteries of this type are really present. + * This mean only batteries and not battery slots/bays. + * \li a value >= 0 + */ + int present_batteries; + + //! number of present batteries + /*! + * This int tells the current rate of the batteries + * \li a value >= 0 + */ + int present_rate; + + //! charge_level in percent that will put battery into warning state + int warn_level; + //! charge_level in percent that will put battery into low state + int low_level; + //! charge_level in percent that will put battery into critical state + int crit_level; + + //! init the battery collection with a default value + void initDefault(); + +signals: + + //! emitted if we switch to a warning state + /*! + * The first int tell the battery type and the second which warning state we reached: + * \li BAT_NORM: batterylevel is ok ... only emitted if we return form BAT_WARN + * \li BAT_WARN: battery is soon getting low + * \li BAT_LOW: batterylevel is already low + * \li BAT_CRIT: batterylevel has become really critical + */ + void batteryWarnState (int type, int state); + //! emitted if the charging state changed + void batteryChargingStateChanged (int changing_state); + //! emitted if the remainig percentage changed + void batteryPercentageChanged (int percent); + //! emitted if the remainig minutes changed + void batteryMinutesChanged (int minutes ); + //! emitted if the number of present batteries changed + void batteryPresentChanged (int num ); + //! emitted if the present rate changed + void batteryRateChanged (); + //! emitted if any Battery state changed + void batteryChanged(); + +public: + //! default constructor + BatteryCollection( int type ); + //! default destructor + ~BatteryCollection(); + + // functions + //! refresh the information of the collection from the given batterylist + bool refreshInfo(QPtrList<Battery> BatteryList, bool force_level_recheck = false); + //! check if this collection already handle a special battery/udi + bool isBatteryHandled(QString udi); + + // get internals + //! get the unit for charge level stuff + QString getChargeLevelUnit() const; + + //! get the cumulative remaining time + int getRemainingMinutes() const; + //! get the cumulative remaining percentage of the battery capacity + int getRemainingPercent() const; + //! get the current Charging state of the machine + int getChargingState() const; + //! get the current battery state + int getBatteryState() const; + //! get the number of available batteries + int getNumBatteries() const; + //! get the number of present batteries + int getNumPresentBatteries() const; + //! get the battery Type from enum \ref BAT_TYPE + int getBatteryType() const; + //! get the current battery rate + int getCurrentRate() const; + + //! reports the chargelevel in percent when battery goes to state warning + int getWarnLevel() const; + //! reports the chargelevel in percent when battery goes to state low + int getLowLevel() const; + //! reports the chargelevel in percent when battery goes to state critical + int getCritLevel() const; + + //! sets the chargelevel in percent when battery should go into state warning + bool setWarnLevel(int _warn_level); + //! sets the chargelevel in percent when battery should go into state low + bool setLowLevel(int _low_level); + //! sets the chargelevel in percent when battery should go into state critical + bool setCritLevel(int _crit_level); + +}; + +#endif diff --git a/src/hardware_cpu.cpp b/src/hardware_cpu.cpp new file mode 100644 index 0000000..c05e3ec --- /dev/null +++ b/src/hardware_cpu.cpp @@ -0,0 +1,312 @@ + /************************************************************************** + * Copyright (C) 2006 by Daniel Gollub * + * <dgollub@suse.de> * + * Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! + * \file hardware_cpu.cpp + * \brief In this file can be found the CPU information related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \author Daniel Gollub, <dgollub@suse.de> + * \author + * \date 2006 + */ + +// include own header +#include "hardware_cpu.h" +#include "hardware_cpu.moc" + +// QT Header +#include <qdir.h> +#include <qtimer.h> + +// system header +#include <fcntl.h> + +/*! The default constructor of the class CPUInfo */ +CPUInfo::CPUInfo() { + kdDebugFuncIn(trace); + + update_info_cpufreq_speed_changed = true; + numOfCPUs = -1; + + kdDebugFuncOut(trace); +} + +/*! The default desctuctor of the class CPUInfo */ +CPUInfo::~CPUInfo() { + kdDebugFuncIn(trace); +} + +/*! + * This function counts all online/offline CPUS. + * Returns the total count of CPUs - _not_ the last CPU ID! + */ +int CPUInfo::getCPUNum() { + kdDebugFuncIn(trace); + + int cpu_id=0; + QDir tmp_dir; + QString cpu_path = "/sys/devices/system/cpu/cpu0/"; +#ifdef FAKE_CPU + cpu_path.prepend("/tmp/foo"); +#endif + + // let check if we support cpufreq in general + if (tmp_dir.exists(tmp_dir.absFilePath(cpu_path + "cpufreq/scaling_cur_freq", true))) { + cpuFreqHW = true; + } else { + cpuFreqHW = false; + } + + QString tmp_path = tmp_dir.absFilePath(cpu_path, true); + + while (tmp_dir.exists(tmp_path)) { + int tmp = cpu_id; + + cpu_id++; + cpu_path.replace(QString::number(tmp), QString::number(cpu_id)); + tmp_path = tmp_dir.absFilePath(cpu_path, true); + } + + kdDebug() << "getCPUNum() return: '" << cpu_id << "'" << endl; + kdDebugFuncOut(trace); + return cpu_id; +} + +/*! + * The function checks the current CPU Speed. The current cpu speed needs to be read out from + * sysfs and currently not be obtained through the daemon. If the CPUFreg changed the new value + * is set to \ref cpufreq_speed . + * \return Information if something changed or if there are errors as an interger value + * \retval -1 if there are error by reading from /sys/.. + * \retval 0 if nothing changed + * \retval 1 if something changed + */ +int CPUInfo::checkCPUSpeed(){ + kdDebugFuncOut(trace); + + bool speed_changed = false; + int new_value = -1; + int fd; + char buf[15]; + QString cpu_device = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"; +#ifdef FAKE_CPU + cpu_device.prepend("/tmp/foo"); +#endif + + // first check path for the kernel on-demand-govenour then + // for the use userspace case + update_info_cpufreq_speed_changed = false; + cpufreq_speed.clear(); + + if (numOfCPUs == -1) + numOfCPUs = getCPUNum(); + + for (int cpu_id=0; cpu_id < numOfCPUs; cpu_id++) { + + new_value = -1; + + fd = open(cpu_device, O_RDONLY); + if (read(fd, buf, 14) > 0){ + new_value = strtol(buf, NULL, 10)/1000; + close(fd); + } + else{ + close(fd); + speed_changed = true; + // CPU disabeld -> set Freq to -1 + cpufreq_speed.append(-1); + } + + if (new_value != cpufreq_speed[cpu_id]) { + speed_changed = true; + cpufreq_speed.append(new_value); + } + + cpu_device.replace(QString::number(cpu_id), QString::number(cpu_id+1)); + } + + if (speed_changed) { + update_info_cpufreq_speed_changed = true; + kdDebugFuncOut(trace); + return 1; + } + + kdDebugFuncOut(trace); + return 0; +} + +/*! + * The function checks the Speed of throttling CPU(s). The cpu speed needs to be read out from + * /proc/cpuinfo. + * \return Success or error while reading /proc/cpuinfo + * \retval 0 successful + * \retval -1 reading problem + */ +int CPUInfo::checkCPUSpeedThrottling() { + kdDebugFuncOut(trace); + + QString cpu_file = "/proc/cpuinfo"; +#ifdef FAKE_CPU + cpu_file.prepend("/tmp/foo"); +#endif + QFile cpu_info(cpu_file); + + // clear cpufreq list + cpufreq_speed.clear(); + + if ( !cpu_info.open(IO_ReadOnly) ) { + cpu_info.close(); + kdDebugFuncOut(trace); + return -1; + } + + QTextStream stream( &cpu_info ); + QString line; + + while ( !stream.atEnd() ) { + line = stream.readLine(); + + if (line.startsWith("cpu MHz : ")) { + line.remove("cpu MHz : "); + line = line.remove(line.length() - 4, 4); + cpufreq_speed.append(line.toInt()); + } + } + + while ((int) cpufreq_speed.count() < numOfCPUs) { + cpufreq_speed.append(-1); + } + + cpu_info.close(); + kdDebugFuncOut(trace); + return 0; +} + +/*! + * The function gets the current throttling state of the CPU(s). The throttling state needs to be + * read out from /proc/acpi/processor/CPUX/throttling. + * \return boolean with info if throttling is supported + * \retval true if throttling is supported + * \retval false if not supported or on any other error + */ +bool CPUInfo::getCPUThrottlingState() { + kdDebugFuncIn(trace); + + int id = 0; + QFileInfo *fi; + QString cpu_dirname; + QString dir_acpi_processor = "/proc/acpi/processor/"; +#ifdef FAKE_CPU + dir_acpi_processor.prepend("/tmp/foo"); +#endif + + QDir d_throttling(dir_acpi_processor); + if (!d_throttling.exists()) { + kdDebugFuncOut(trace); + return false; + } + + d_throttling.setFilter( QDir::Dirs ); + d_throttling.setNameFilter("CPU*"); + + const QFileInfoList *list = d_throttling.entryInfoList(); + QFileInfoListIterator it( *list ); + + // clear throttling value list + cpu_throttling.clear(); + + while ((fi = it.current()) != 0 ) { + cpu_dirname = fi->fileName(); + + QString throttling_device = d_throttling.absPath(); + throttling_device.append("/").append(cpu_dirname).append("/throttling"); + + kdDebug() << "Throttling state file for CPU" << id << " will be: " << throttling_device << endl; + + QFile throttling(throttling_device); + + // open throttling state file + if ( throttling.open(IO_ReadOnly) ) { + QTextStream stream( &throttling ); + QString line; + + do { + line = stream.readLine(); + } while (!line.startsWith(" *T") && !stream.atEnd() ); + + if (line.startsWith(" *T")) { + line = line.right(3); + line.remove("%"); + cpu_throttling.append(line.toInt()); + kdDebug () << "CPU " << id + << ": cpu_throttling is set to: " << cpu_throttling[id] << endl; + } else { + cpu_throttling.append(0); + } + } + + throttling.close(); + ++it; // next entry + id++; // count cpu id + } + + kdDebugFuncOut(trace); + return true; +} + +/*! + * The function gets the Max CPU Speed. The max cpu speed needs to be read out from + * sysfs and currently not be obtained through the daemon. + */ +void CPUInfo::getCPUMaxSpeed() { + kdDebugFuncIn(trace); + + int fd; + int maxfreq; + char buf[15]; + QString cpu_device_max = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"; +#ifdef FAKE_CPU + cpu_device_max.prepend("/tmp/foo"); +#endif + + cpufreq_max_speed.clear(); + + if (numOfCPUs == -1) + numOfCPUs = getCPUNum(); + +// while (!access(cpu_device_max, R_OK)) { + for (int cpu_id=0; cpu_id < numOfCPUs; cpu_id++) { + + fd = open(cpu_device_max, O_RDONLY); + if (read(fd, buf, 14) > 0){ + maxfreq = strtol(buf, NULL, 10)/1000; + cpufreq_max_speed.append(maxfreq); + close(fd); + } else { + cpufreq_max_speed.append(-1); + close(fd); + } + + cpu_device_max.replace(QString::number(cpu_id), QString::number(cpu_id+1)); + } + + kdDebugFuncOut(trace); +} diff --git a/src/hardware_cpu.h b/src/hardware_cpu.h new file mode 100644 index 0000000..0c41237 --- /dev/null +++ b/src/hardware_cpu.h @@ -0,0 +1,115 @@ + /************************************************************************** + * Copyright (C) 2006 by Daniel Gollub * + * <dgollub@suse.de> * + * Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! +* \file hardware_cpu.h +* \brief Headerfile for hardware_cpu.cpp and the class \ref CPUInfo. +*/ +/*! +* \class CPUInfo +* \brief class for CPU information related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2006 +*/ + +#ifndef _HARDWARE_CPU_H_ +#define _HARDWARE_CPU_H_ + +// Global Header +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +// QT Headers +#include <qstring.h> +#include <qobject.h> +#include <qvaluelist.h> + +// own headers +#include "kpowersave_debug.h" + +class CPUInfo : public QObject{ + + Q_OBJECT + +private: + + //! Integer with the numbers of CPUs in the system + /*! This contains the number of CPUs in the current system */ + int numOfCPUs; + +public: + + //! represent the current Throttling of the CPU + /*! + * This interge value represent the current throttling step of the CPU in percent + * \li a value >= 0 in % + */ + QValueList <int> cpu_throttling; + + //! represent the current CPU speeds + /*! + * This integer value represent the current speed/frequency of the CPUs in Mhz + * \li a value > 0 in Mhz + */ + QValueList <int> cpufreq_speed; + + //! represent the max. CPU speeds + /*! + * This integer value represent the max speed/frequency of the CPUs in Mhz + * \li a value > 0 in Mhz + */ + QValueList <int> cpufreq_max_speed; + + //! if the machine support change CPU Freq in general + /*! + * This boolean represent information if the machine support change the + * CPU freqency in general vi sysfs + * \li true: if supported + * \li false: else + */ + bool cpuFreqHW; + //! tells if the CPUFreq Speed changed + /*! + * This boolean represent information about CPUFreq Speed changes. + * \li true: if something changed + * \li false: if nothing changed (or this is reset to false if the message was consumed) + */ + bool update_info_cpufreq_speed_changed; + + // --> functions + //! default constructor + CPUInfo(); + //! default destructor + ~CPUInfo(); + + //! checks the current CPU Speed from sysfs + int checkCPUSpeed(); + //! checks the Speed of throttling CPUs from /proc/cpuinfo + int checkCPUSpeedThrottling(); + //! read the current throttling state of the CPUs from /proc/acpi/processor/CPUX/throttling + bool getCPUThrottlingState(); + //! read the max speed of the CPUs + void getCPUMaxSpeed(); + //! counts the total number of CPUs + int getCPUNum(); +}; +#endif diff --git a/src/hi16-app-kpowersave.png b/src/hi16-app-kpowersave.png Binary files differnew file mode 100644 index 0000000..19ec2a7 --- /dev/null +++ b/src/hi16-app-kpowersave.png diff --git a/src/hi32-app-kpowersave.png b/src/hi32-app-kpowersave.png Binary files differnew file mode 100644 index 0000000..b7c15a6 --- /dev/null +++ b/src/hi32-app-kpowersave.png diff --git a/src/hi48-app-kpowersave.png b/src/hi48-app-kpowersave.png Binary files differnew file mode 100644 index 0000000..9cc3006 --- /dev/null +++ b/src/hi48-app-kpowersave.png diff --git a/src/inactivity.cpp b/src/inactivity.cpp new file mode 100644 index 0000000..e432fb7 --- /dev/null +++ b/src/inactivity.cpp @@ -0,0 +1,368 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! \file inactivity.cpp + * \brief In this file can be found the inactivity related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2006-2007 + */ + +// own header +#include "inactivity.h" + +/* needed for lXext C library linkage */ +extern "C" { + #include <X11/Xproto.h> + #include <X11/extensions/dpms.h> + #include <X11/extensions/scrnsaver.h> +} + +// KDE Headers +#include <klocale.h> + +/*! The default constructor of the class autosuspend */ +inactivity::inactivity() { + kdDebugFuncIn(trace); + + proc = NULL; + + timeToInactivity = 0; + blacklisted_running_last = 0; + + pidof_call_failed = false; + pidof_call_started = false; + pidof_call_returned = false; + blacklisted_running = false; + + int dummy = 0; + has_XSC_Extension = XScreenSaverQueryExtension( qt_xdisplay(), &dummy, &dummy ); + + checkInactivity = new QTimer( this ); + connect( checkInactivity, SIGNAL(timeout()), this, SLOT(check())); + + kdDebugFuncOut(trace); +} + +/*! The default destructor of the class autosuspend */ +inactivity::~inactivity() { + kdDebugFuncIn(trace); + + delete proc; + proc = NULL; + + kdDebugFuncOut(trace); +} + +/*! + * This function start the monitoring of inactivity of user on the X-Server. + * Here wee set the time for the signal \ref inactivityTimeExpired() and start + * the needed QTimer. + * \param timeToExpire Integer value representing the time of inactivity which need + * to elapse befor send signal. The time is in seconds. + * \param blacked QStringList with blacklisted programs which if detected with + * pidof() as running prevent the autosuspend. + */ +void inactivity::start( int timeToExpire, QStringList blacked ) { + kdDebugFuncIn(trace); + + blacklist = blacked; + + if(timeToExpire > 0 && has_XSC_Extension){ + stop(); + timeToInactivity = (unsigned long) (timeToExpire * 1000); + checkInactivity->start(CHECK_for_INACTIVITY, true); + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to call check as recheck inactivity if befor a running PID + * request was detected. + */ +void inactivity::recheck() { + kdDebugFuncIn(trace); + + check(true); + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to call check without a recheck. + */ +void inactivity::check() { + check(false); +} + +/*! + * \b SLOT to check the current idle-time of the X-Server and if there + * are blacklisted programs are running. If the through \ref timeToInactivity + * defined time is expired, this function emit signal \ref inactivityTimeExpired() . + * \param recheck boolean which define if this is a recheck or not. + * \li true, if this is a recheck. In this case we didn't call + * \ref checkBlacklisted() again + * \li false, if this is normal check + */ +void inactivity::check( bool recheck ) { + kdDebugFuncIn(trace); + + if (timeToInactivity > 0) { + checkXInactivity(); + if (!pidof_call_started && !recheck) checkBlacklisted(); + + if( idleTime < blacklisted_running_last ) { + blacklisted_running_last = idleTime; + } + + if((idleTime - blacklisted_running_last ) >= timeToInactivity) { + if (!pidof_call_started) { + if (( pidof_call_returned && !blacklisted_running ) || + ( pidof_call_returned && pidof_call_failed )) { + emit inactivityTimeExpired(); + } + else { + checkInactivity->start(CHECK_for_INACTIVITY, true); + } + } + else { + //called if there is a getPIDs() is running + QTimer::singleShot(500, this, SLOT(recheck())); + } + } + else checkInactivity->start(CHECK_for_INACTIVITY, true); + } else { + kdWarning() << "timeToInactivity <= 0, stoped autosuspend checks!" << endl; + } + + kdDebugFuncOut(trace); +} + +/*! + * This function stop the monitoring and reset all variables and Timer. + */ +void inactivity::stop() { + kdDebugFuncIn(trace); + + if (checkInactivity->isActive()) checkInactivity->stop(); + timeToInactivity = 0; + idleTime = 0; + blacklisted_running_last = 0; + + pidof_call_failed = false; + pidof_call_started = false; + pidof_call_returned = false; + blacklisted_running = false; + + kdDebugFuncOut(trace); +} + +/*! + * This function query the idle-time of user-imput from the X-Server and set + * the return value to \ref idleTime. + */ +void inactivity::checkXInactivity(){ + kdDebugFuncIn(trace); + + idleTime = getXInactivity(); + kdDebug() << "autosuspend::checkXInactivity - idleTime: " << idleTime << endl; + + kdDebugFuncOut(trace); +} + +/*! + * This function query the idle-time of user-imput from the X-Server and + * return the current idle-time. + */ +unsigned long inactivity::getXInactivity(){ + kdDebugFuncIn(trace); + + if(has_XSC_Extension) { + static XScreenSaverInfo* mitInfo = 0; + if (!mitInfo) mitInfo = XScreenSaverAllocInfo (); + XScreenSaverQueryInfo (qt_xdisplay(), DefaultRootWindow (qt_xdisplay()), mitInfo); + kdDebugFuncOut(trace); + return workaroundCreepyXServer(mitInfo->idle); + } + else { + kdDebugFuncOut(trace); + return 0; + } + +} + +/*! + * This function workaround a fucking XServer idleTime bug in the + * XScreenSaverExtension, if dpms is running. In this case always the + * current dpms-state time is extracted from the current idletime. + * This mean: XScreenSaverInfo->idle is not the time since the last + * user activity, as descriped in the header file of the extension. + * This result in SUSE bug # and sf.net bug # + * + * Workaround: check if if XServer is in a dpms state, check the + * current timeout for this state and add this value to + * the current idle time and return. + * + * \param _idleTime a unsigned long value with the current ideletime fromm + * XScreenSaverInfo->idle + * \return a unsigned long with the corrected idletime + */ +unsigned long inactivity::workaroundCreepyXServer( unsigned long _idleTime ){ + kdDebugFuncOut(trace); + + int dummy; + CARD16 standby, suspend, off; + CARD16 state; + BOOL onoff; + + Display *dpy = qt_xdisplay(); + + kdDebug() << "Current idleTime: " << _idleTime << endl; + + if (DPMSQueryExtension(dpy, &dummy, &dummy)) { + if (DPMSCapable(dpy)) { + DPMSGetTimeouts(dpy, &standby, &suspend, &off); + DPMSInfo(dpy, &state, &onoff); + + if (onoff) { + switch (state) { + case DPMSModeStandby: + kdDebug() << "DPMS enabled. Monitor in Standby. Standby: " + << standby << " sec" << endl; + // this check is a littlebit paranoid, but be sure + if (_idleTime < (unsigned) (standby * 1000)) + _idleTime += (standby * 1000); + break; + case DPMSModeSuspend: + kdDebug() << "DPMS enabled. Monitor in Suspend. Suspend: " + << suspend << " sec" << endl; + if (_idleTime < (unsigned) ((suspend + standby) * 1000)) + _idleTime += ((suspend + standby) * 1000); + break; + case DPMSModeOff: + kdDebug() << "DPMS enabled. Monitor is Off. Off: " + << off << " sec" << endl; + if (_idleTime < (unsigned) ((off + suspend + standby) * 1000)) + _idleTime += ((off + suspend + standby) * 1000); + break; + case DPMSModeOn: + default: + break; + } + } + } + } + + kdDebug() << "Corrected idleTime: " << _idleTime << endl; + kdDebugFuncOut(trace); + return _idleTime; +} + +/*! + * This funtion starts the monitoring of blacklisted processes. + */ +void inactivity::checkBlacklisted(){ + kdDebugFuncIn(trace); + + if (proc != NULL) { + delete proc; + proc = NULL; + } + + proc = new KProcess; + *proc << "pidof" << blacklist; + + connect( proc, SIGNAL(receivedStdout(KProcess *, char *, int)),this, + SLOT(getPIDs(KProcess *, char *, int))); + connect( proc, SIGNAL(processExited(KProcess *)), + SLOT(getPIDsExited(KProcess *))); + + if (!proc->start(KProcess::NotifyOnExit, KProcess::AllOutput)) + { + emit displayErrorMsg(i18n("Could not start 'pidof'. " + "Could not autosuspend the machine.\n" + "Please check your installation.")); + } + + pidof_call_started = true; + pidof_call_returned = false; + pidof_call_failed = false; + + kdDebugFuncOut(trace); +} + + +/*! + * \b SLOT to get the return of the command pidof and parse this to set + * \ref blacklisted_running . + * \param *proc pointer to the sending KProcess + * \param *buffer the char pointer to the output of the process to stdout + * \param *lenght the length of the buffer + */ +void inactivity::getPIDs(KProcess */*proc*/, char *buffer, int /*lenght*/) { + kdDebugFuncIn(trace); + + QString pids(buffer); + pids.remove(" "); + if(pids.isEmpty() || pids == "\n" ) { + kdDebug() << "NO! BLACKLISTED IS RUNNING" << endl; + blacklisted_running = false; + } + else { + if (pids.contains(QRegExp::QRegExp("[0-9]"))) { + kdDebug() << "BLACKLISTED IS RUNNING" << endl; + blacklisted_running = true; + blacklisted_running_last = idleTime; + } + else { + kdError() << "GET BLACKLISTED FAILED - WRONG RETURN" << endl; + blacklisted_running = false; + pidof_call_failed = true; + } + } + + kdDebugFuncOut(trace); +} + + +/*! + * \b SLOT which called if the call of pidof is exited + * \param proc the KPocess which called this SLOT + */ +void inactivity::getPIDsExited(KProcess *proc){ + kdDebugFuncIn(trace); + + pidof_call_returned = true; + pidof_call_started = false; + + + if (proc->normalExit()){ + // if returned some pids or if pid returned nothing + if (proc->exitStatus() == 1 || proc->exitStatus() == 0){ + pidof_call_failed = false; + kdDebugFuncOut(trace); + return; + } + } + // if something crashed/failed + pidof_call_failed = true; + kdDebugFuncOut(trace); +} + +#include "inactivity.moc" diff --git a/src/inactivity.h b/src/inactivity.h new file mode 100644 index 0000000..d3fb979 --- /dev/null +++ b/src/inactivity.h @@ -0,0 +1,170 @@ + /************************************************************************** + * Copyright (C) 2006 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +#ifndef _INACTIVITY_H_ +#define _INACTIVITY_H_ + +/* this is needed to avoid typedef clash with X11 + */ +#ifndef QT_CLEAN_NAMESPACE +#define QT_CLEAN_NAMESPACE +#endif + +// KDE Header +#include <kprocess.h> + +// QT Header +#include <qregexp.h> +#include <qstring.h> +#include <qwidget.h> +#include <qtimer.h> +#include <qevent.h> + +// X11 Header +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#include <X11/Xutil.h> + +// from project +#include "kpowersave_debug.h" + +/*! +* \file inactivity.h +* \brief Headerfile for inactivity.cpp and the class \ref inactivity. +*/ +/*! +* \class inactivity +* \brief class for detect inactivity related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2006 +*/ + +class inactivity : public QWidget +{ + Q_OBJECT + +public: + //! default constructor + inactivity(); + //! default destructor + ~inactivity(); + + //! to start the monitoring of the X-Server + void start(int, QStringList); + //! to stop the monitoring of the X-Server + void stop(); + + //! to get the current user inactivity + unsigned long getXInactivity(); + +signals: + + //! signal emited if the with \ref start() set time of inactivity is expired + void inactivityTimeExpired(); + //! signal to emit error msg + void displayErrorMsg( QString ); + +private: + + //! pointer to the process to call pidof + KProcess *proc; + + //! about the call result of pidof + /*! + * This boolean tells if call of the command pidof failed. + * \li true: if failed + * \li false: if not + */ + bool pidof_call_failed; + //! about the call of command pidof + /*! + * This boolean tells if the call of the command pidof was started or if + * the command is running + * \li true: if is started/running + * \li false: if not + */ + bool pidof_call_started; + //! if pidof return value is recieved + /*! + * This boolean tells if the call of the command pidof returned and the + * returnvalue was parsed to set \ref blacklisted_running + * \li true: if returned and parsed + * \li false: if not + */ + bool pidof_call_returned; + //! if a blacklisted program/process is running + /*! + * This boolean tells if a blacklisted program/process is currently running. + * \li true: if a blacklisted program/process is running + * \li false: if not + */ + bool blacklisted_running; + + //! QStringList with blacklisted programs for autosuspend + QStringList blacklist; + + //! time which must expire befor emit signal for autosuspend + unsigned long timeToInactivity; + //! time of inactivity from the last check + unsigned long idleTime; + //! time of inactivity from the last check + unsigned long blacklisted_running_last; + //! if the XServer-has XScreenSaverExtension + int has_XSC_Extension; + + //! QTimer intervall for the \ref checkInactivity Timer + /*! + * The time intervall to check for the current status and time of + * userinactivity. The timeslice is currently 30 sec. + */ + static const int CHECK_for_INACTIVITY = 30000; + + //! QTimer for check inactivity + /*! + * This timer is used to check the currently status and time of + * userinactivity on the X-Server. The timerinterval is defined trough + * \ref CHECK_for_INACTIVITY . + */ + QTimer *checkInactivity; + + // -------- FUNCTIONS ------------ + + //! to check the user-inactivity on the XServer + void checkXInactivity(); + //! to check for running blacklisted programs + void checkBlacklisted(); + //! to monitor the values + void check( bool recheck ); + //! to workaround a strange behavior of the XScreenSaver extension + unsigned long workaroundCreepyXServer( unsigned long ); + +private slots: + + //! to monitor the values + void check(); + //! to monitor the values + void recheck(); + //! to get the PIDs of blacklisted programs/processes + void getPIDs(KProcess *, char *, int); + //! to get the signal if the command call is exited + void getPIDsExited(KProcess *); +}; + +#endif diff --git a/src/info_Dialog.ui b/src/info_Dialog.ui new file mode 100644 index 0000000..43e1479 --- /dev/null +++ b/src/info_Dialog.ui @@ -0,0 +1,217 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>info_Dialog</class> +<widget class="QDialog"> + <property name="name"> + <cstring>info_Dialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>459</width> + <height>131</height> + </rect> + </property> + <property name="caption"> + <string>Information</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="3" column="4"> + <property name="name"> + <cstring>buttonOK</cstring> + </property> + <property name="minimumSize"> + <size> + <width>90</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>OK</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + <spacer row="3" column="5" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>171</width> + <height>21</height> + </size> + </property> + </spacer> + <spacer row="3" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>151</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="1" rowspan="2" colspan="2"> + <property name="name"> + <cstring>iconPixmap</cstring> + </property> + <property name="minimumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + </widget> + <widget class="QLabel" row="0" column="3" rowspan="2" colspan="4"> + <property name="name"> + <cstring>msgText</cstring> + </property> + <property name="minimumSize"> + <size> + <width>370</width> + <height>50</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer6</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="1" column="2"> + <property name="name"> + <cstring>spacer6_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="2" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>61</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QCheckBox" row="2" column="3" rowspan="1" colspan="3"> + <property name="name"> + <cstring>dontShowAgain</cstring> + </property> + <property name="minimumSize"> + <size> + <width>330</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + <spacer row="2" column="6"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>31</width> + <height>21</height> + </size> + </property> + </spacer> + </grid> +</widget> +<images> + <image name="image0"> + <data format="XPM.GZ" length="2304">789c8593c9721a311086ef3cc5947573a5dacc303043a57230b6f1beef4ee530128bc1069bcd5b2aef9e5f52b702d855410cf0a9b7bf5b626d35ba39398c56d74a936931ed99c8dc17e368b5351b0cde7ffefaf1bbb4922411de59354a56be9556681c994895ddcbf12c70eeb8c19cb27d12d8d955c7711efc47cc6ca7a970ece2559739e77c3781bdff85b0f7a71d66c3fecf81bdff8be7b8ccfe75cb71b96c98ef3cc7a27f37b08fbf1266ff3eb3e879779c076e0ab3ff03b3e88985d95eb69cd42b329f4761b6f798a57ed572250efcc12cf56acc92ffd2732af932c775b03f9f4238f1f637cb699c72bc3281bdbe7bcbd5a456653e715c04ce99eb5c6f10d8db9f84b9de3a738bede7c2deae7cbd228bd99e58ae2562a7d47316b37f8bb9caac1c17b9c46f0973fc2db3e8df6716fd1b96b34a883f6516ff0ab3f4776839d745c1f98f2cd7d3c07b81eb8ebbcc6dd64b9e75c2fe078e8d663b5d5b2e52dde67a9bc21cdff36c12d63f0cecfd5bc29c6f9bb9c6f74f0973bc0eecedafc21c7fc65c707c4798ef4fdbb191fa4a0b73fc31b3d433817d3e89977a0533e73f9d06ce3d93a282d4fcb73ccbfbbedf85a5977861f9fa4bb93496a116b53fd798cbdfe1dc5dbaa71ef5e9811e69005aa839af1f11437aa2671ad1982678a634a317c4bc7ea95fc3fbcd79cee81d153e5063e2f80d96aff4af5303b9fbb4419bd0afd1c11635113d428d3658f46fb3ee1df8efd21ee77aa57d3aa043c48fa1f1888e17f41b3a419e199d22dad019f6cee9822e5169cbf5f3f4497f0fbb57748daeb79d36eb7543b788b8c3aff2d27c0ce637418c71bfd7e16975af439546e7638ad14d27e4b7937cc0ee87d36dbdc7e8654c899b5b0f99faf6f4e6f2b7713a53ecb6a802dd13e4f64f0a3d764655d273fa35340fb03b41779b5443fe017237dcca506744f9bff9b8b32d30cf3a229a98e0266ad83b94baf3b027b6a3e8d3fd39c644ed79f695822a5bf34015dc47e6e2b717ee8f565a19d7a93de30f74d9740a6d8d866a7dca8fa5dad0fd8c8899bf71aa8333cfe0ddc5ccf457f71f73eae22c7b98f73b6632806ef4a1eedd348ba5fbc97da81e3e87f018867d7916ef7f31f75feab86f1df6cd57faffbf56fe7c2ffd0519fbee77</data> + </image> +</images> +<connections> + <connection> + <sender>buttonOK</sender> + <signal>clicked()</signal> + <receiver>info_Dialog</receiver> + <slot>ButtonOK_clicked()</slot> + </connection> +</connections> +<slots> + <slot>ButtonOK_clicked()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/infodialog.cpp b/src/infodialog.cpp new file mode 100644 index 0000000..74b3891 --- /dev/null +++ b/src/infodialog.cpp @@ -0,0 +1,120 @@ +/*************************************************************************** + * Copyright (C) 2005 by Danny Kukawka * + * danny.kukawka@web.de, dkukawka@suse.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! + * \file infodialog.cpp + * \brief In this file can be found the "information dialog with checkbox" + * related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2005 + */ + +// own headers +#include "infodialog.h" + +// KDE headers: +#include <kiconloader.h> +#include <klocale.h> + +// QT headers: +#include <qcheckbox.h> +#include <qdialog.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qstring.h> +#include <qtooltip.h> + +/*! This is the default constructor of class infoDialog . */ +infoDialog::infoDialog( KConfig *config, QString captionName, QString message, + QString dontShowAgainMsg, QString settingsEntryName, + QWidget *parent, const char *name) + :info_Dialog( parent, name, false, Qt::WStyle_StaysOnTop | WDestructiveClose ) +{ + if ( message.isEmpty() || (!dontShowAgainMsg.isEmpty() && settingsEntryName.isEmpty()) || + (!dontShowAgainMsg.isEmpty() && (config == 0))) + close(); + + if (config != 0) { + settings = config; + settings->reparseConfiguration(); + if (settings->hasGroup("infoDialog")){ + settings->setGroup("infoDialog"); + if (settings->readBoolEntry(settingsEntryName, false)) { + dialogDisabled = true; + //close(); + } + else + dialogDisabled = false; + } + } + + buttonOK->setIconSet(SmallIconSet("ok", QIconSet::Automatic)); + + QPixmap pixmap = 0; + pixmap = KGlobal::iconLoader()->loadIcon("messagebox_warning", KIcon::NoGroup, KIcon::SizeMedium); + iconPixmap->setPixmap( pixmap ); + + msgText->setText(message); + + if (!captionName.isEmpty()) + this->setCaption(i18n("KPowersave") + " - " + captionName); + else + this->setCaption(i18n("KPowersave")); + + if (dontShowAgainMsg.isEmpty()) { + dontShowAgain->setHidden(true); + } else { + entryName = settingsEntryName; + dontShowAgain->setText(dontShowAgainMsg); + dontShowAgain->setHidden(false); + } + this->adjustSize(); +} + +/*! This is the default destructor of class infoDialog . */ +infoDialog::~infoDialog() +{ + // no need to delete child widgets, Qt does it all for us +} + +/*! + * Use this function to get the value of \ref dialogDisabled. + * \return boolean with value of \ref dialogDisabled + * \retval true if disabled by user before + * \retval false if not + */ +bool infoDialog::dialogIsDisabled() { + return dialogDisabled; +} + +/*! + * SLOT: called if the 'ok' button clicked. This SLOT sync the settings + * and close the dialog. + */ +void infoDialog::ButtonOK_clicked() { + + if (!entryName.isEmpty() && dontShowAgain->isVisible()) { + settings->setGroup( "infoDialog" ); + settings->writeEntry( entryName, dontShowAgain->isChecked()); + settings->sync(); + } + close(); +} + +#include "infodialog.moc" diff --git a/src/infodialog.h b/src/infodialog.h new file mode 100644 index 0000000..7d419dd --- /dev/null +++ b/src/infodialog.h @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2005 by Danny Kukawka * + * danny.kukawka@web.de, dkukawka@suse.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! +* \file infodialog.h +* \brief Headerfile for infoDialog.cpp and the class \ref infoDialog . +*/ +/*! +* \class infoDialog +* \brief class for information dialog with checkbox (e.g. for DontShowAgain) +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2005 +*/ + +#ifndef INFODIALOG_H +#define INFODIALOG_H + +#include <kconfig.h> + +#include "info_Dialog.h" + +class infoDialog: public info_Dialog { + + Q_OBJECT + +public: + + //! default constructor + infoDialog( KConfig *config = 0, QString captionName = QString(), QString message = QString(), + QString dontShowAgainMsg = QString(), QString settingsEntryName = QString(), + QWidget *parent = 0, const char *name = 0); + //! default destructor + ~infoDialog(); + + //! return the value of dialogDisabled + bool dialogIsDisabled(); + +private: + + //! the pointer to the settings of kpowersave, get from constructor + KConfig *settings; + + //! name of the entry in the settings + /*! QString store the name of the settings entry to + * store settings of 'DontShowAgain' checkbox + */ + QString entryName; + + //! represent if the dialog is disabled by user + /*! + * This boolean tell if the dialog is already disabled by user settings + * \li true: if dialog is disabled + * \li false: if not + */ + bool dialogDisabled; + +private slots: + + //! called if the 'ok' button clicked + void ButtonOK_clicked(); + +}; + +#endif diff --git a/src/kpowersave-autostart.desktop b/src/kpowersave-autostart.desktop new file mode 100644 index 0000000..3409cbc --- /dev/null +++ b/src/kpowersave-autostart.desktop @@ -0,0 +1,68 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=kpowersave +Name[xx]=xxkpowersavexx +Name[de]=KPowersave +Name[es]=KPowersave +Name[fr]=KPowersave +Name[it]=KPowersave +Name[ja]=KPowersave +Name[pt_BR]=KPowersave +Name[ru]=KPowersave +Name[sv]=KPowersave +Name[zh_CN]=KPowersave +Name[zh_TW]=KPowersave +GenericName=Battery Monitor +Exec=kpowersave +Icon=kpowersave +Type=Application +Comment=Battery monitor and general power management +Comment[bg]=Монитор за батерията и основно управление на енергията +GenericName[bg]=Монитор за батерията +Comment[cs]=Sledování stavu baterií a správa napájení +GenericName[cs]=Monitor baterie +GenericName[de]=Akkuüberwachung +Comment[de]=Akkuüberwachung und allgemeine Energieverwaltung +GenericName[el]=Παρακολούθηση Μπαταρίας +GenericName[es]=Monitor de carga de la batería +Comment[es]=Monitor de batería y gestión general de la energía +Comment[fi]=Akkumonitori ja yleinen virranhallinta +GenericName[fi]=Akkumonitori +Comment[fr]=Moniteur de batterie et gestion de l'alimentation +GenericName[fr]=Moniteur de batterie +GenericName[hu]=Akkumulátorfigyelő +Comment[it]=Monitor della batteria e gestione generale dell'alimentazione +GenericName[it]=Monitor della batteria +Comment[km]=កមមវធ<200b>តរតពនតយ<200b>ថម នង គរបគរង<200b>ថាមពល<200b>ទទៅ +GenericName[km]=កមមវធ<200b>តរតពនតយ<200b>ថម +Comment[nb]=Batteriovervåking og generell strømstyring +GenericName[nb]=Batteriovervåker +GenericName[nl]=Batterijmonitor +GenericName[ja]=バッテリモニタ +Comment[ja]=バッテリモニタと一般電源管理 +Name[pa]=ਕ-ਊਰਜਾ ਸਭਾਲ +GenericName[pa]=ਬਟਰੀ ਦਰਸ਼ਕ +Comment[pl]=Monitor stanu baterii i ogólne zarządzanie energią +GenericName[pl]=Monitor baterii +Comment[pt]=Monitor de bateria e gestor global de energia +GenericName[pt]=Monitor de Bateria +Comment[pt_BR]=Monitor de Bateria e Gerenciamento de Energia Geral +GenericName[pt_BR]=Monitor de Bateria +GenericName[ru]=Монитор Батареи +Comment[ru]=Монитор батареи и управление энергосбережением +GenericName[sv]=Batteriövervakare +GenericName[tr]=Pil durumu izleme ve güç yönetimi arayüzü +Comment[tr]=Pil durumu izleme ve güç yönetimi arayüzü +Comment[uk]=Монітор стану батареї і загальне керування живленням +GenericName[uk]=Монітор батарей +Comment[xx]=xxBattery monitor and general power managementxx +GenericName[zh_CN]=电池监视器 +Comment[zh_CN]=电池监视器和常规电源管理 +GenericName[zh_TW]=電池監視器 +Comment[zh_TW]=電池監視器和一般電源管理 +X-KDE-autostart-after=panel +X-KDE-StartupNotify=false +X-KDE-UniqueApplet=true +X-KDE-autostart-condition=kpowersaverc:General:Autostart:true +Categories=System;Applet; + diff --git a/src/kpowersave.cpp b/src/kpowersave.cpp new file mode 100644 index 0000000..ab6c088 --- /dev/null +++ b/src/kpowersave.cpp @@ -0,0 +1,2753 @@ + /************************************************************************** + * Copyright (C) 2004 by Thomas Renninger * + * <trenn@suse.de> and * + * 2004-2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +// KDE headers: +#include <kaboutapplication.h> +#include <kapplication.h> +#include <kaudioplayer.h> +#include <kconfig.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <knotifyclient.h> +#include <knotifydialog.h> +#include <kpassivepopup.h> +#include <kpopupmenu.h> + +// other Qt headers: +#include <qcursor.h> +#include <qevent.h> +#include <qfile.h> +#include <qimage.h> +#include <qpixmap.h> +#include <qtimer.h> +#include <qtooltip.h> + +// own headers: +#include "kpowersave.h" +#include "infodialog.h" + +/*! +* \file kpowersave.cpp +* \brief This file contains the main functionality of the kpowersave-applet.*/ + +/*! + * This is the default constructor of the class kpowersave. + */ +kpowersave::kpowersave( bool force_acpi_check, bool trace_func ) : KSystemTray(0, "kpowersave"), + DCOPObject("KPowersaveIface") { + trace = trace_func; + kdDebugFuncIn(trace); + + display = new screen(); + settings = new Settings(); + autoSuspend = new autosuspend(); + autoDimm = new autodimm(); + hwinfo = new HardwareInfo(); + suspend = hwinfo->getSuspendSupport(); + + yast2 = NULL; + + resume_result = 0; + + config = KGlobal::config(); + config->setGroup("General"); + if(!config->readBoolEntry("AlreadyStarted", false) || force_acpi_check){ + config->writeEntry("AlreadyStarted", true); + // check whether APM, ACPI, PMU, CPUFreq or Suspend2Disk/ram supported, otherwise end up + // and don't start kpowersave ever again until force_acpi_check == true. + if (!hwinfo->hasACPI() && !hwinfo->hasAPM() && !hwinfo->hasPMU() && + !hwinfo->supportCPUFreq() && !suspend.suspend2disk && !suspend.suspend2ram){ + config->writeEntry("Autostart", false); + config->sync(); + kdError() << "This machine does not support ACPI, APM, PMU, CPUFreq, Suspend2Disk nor " + << "Suspend2RAM. Close KPowersave now." << endl; + exit(-1); + } + } + + // default init + if (hwinfo->getAcAdapter()) { + settings->load_scheme_settings( settings->ac_scheme); + } else { + settings->load_scheme_settings( settings->battery_scheme); + } + // set the battery warning levels + hwinfo->setPrimaryBatteriesWarningLevel(settings->batteryWarningLevel, + settings->batteryLowLevel, + settings->batteryCriticalLevel); + + // connect to signals for changes + connect(hwinfo, SIGNAL(generalDataChanged()), this, SLOT(update())); + connect(hwinfo, SIGNAL(primaryBatteryChanged()), this, SLOT(update())); + connect(hwinfo, SIGNAL(ACStatus(bool)), this, SLOT(handleACStatusChange (bool))); + connect(hwinfo, SIGNAL(resumed(int)), this, SLOT(forwardResumeSignal(int))); + + // connect to error mesages + connect(autoSuspend, SIGNAL(displayErrorMsg(QString)), this, SLOT(showErrorMessage(QString))); + connect(hwinfo, SIGNAL(halRunning(bool)), this, SLOT(showHalErrorMsg())); + connect(hwinfo, SIGNAL(dbusRunning(int)), this, SLOT(showDBusErrorMsg(int))); + + // connect to events + connect(hwinfo, SIGNAL(lidcloseStatus(bool)), this, SLOT(handleLidEvent(bool))); + connect(hwinfo, SIGNAL(powerButtonPressed()), this, SLOT (handlePowerButtonEvent())); + connect(hwinfo, SIGNAL(sleepButtonPressed()), this, SLOT (handleSleepButtonEvent())); + connect(hwinfo, SIGNAL(s2diskButtonPressed()), this, SLOT (handleS2DiskButtonEvent())); + connect(hwinfo, SIGNAL(batteryWARNState(int,int)), this, SLOT(notifyBatteryStatusChange (int,int))); + connect(hwinfo, SIGNAL(desktopSessionIsActive(bool)), this, SLOT (handleSessionState(bool))); + connect(autoSuspend, SIGNAL(inactivityTimeExpired()), this, SLOT(do_autosuspendWarn())); + connect(autoDimm, SIGNAL(inactivityTimeExpired()), this, SLOT(do_downDimm())); + connect(autoDimm, SIGNAL(UserIsActiveAgain()), this, SLOT(do_upDimm())); + + config->sync(); + + config_dialog_shown = false; + suspend_dialog_shown = false; + detailedIsShown = false; + hal_error_shown = false; + icon_set_colored = false; + icon_BG_is_colored = false; + + calledSuspend = -1; + countWhiteIconPixel = 0; + + pixmap_name = "NONE"; + suspendType = "NULL"; + + BAT_WARN_ICON_Timer = new QTimer(this); + connect(BAT_WARN_ICON_Timer, SIGNAL(timeout()), this, SLOT(do_setIconBG())); + + DISPLAY_HAL_ERROR_Timer = new QTimer(this); + connect(DISPLAY_HAL_ERROR_Timer, SIGNAL(timeout()), this, SLOT(showHalErrorMsg())); + + AUTODIMM_Timer = new QTimer(this); + + initMenu(); + update(); + updateCPUFreqMenu(); + setSchemeSettings(); + + kdDebugFuncOut(trace); +} + + +/*! This is the default destructor of class kpowersave. */ +kpowersave::~kpowersave(){ + kdDebugFuncIn(trace); + + delete hwinfo; + delete display; + delete settings; + delete autoSuspend; +#ifdef ENABLE_YAST_ENTRY + delete yast2; +#endif +} + +/*! + * use this function to initalise the main kicker menu + */ +void kpowersave::initMenu() { + kdDebugFuncIn(trace); + + CONFIGURE_ID = this->contextMenu()->insertItem(SmallIcon("configure", QIconSet::Automatic), + i18n("Configure KPowersave..."), + this, SLOT(showConfigureDialog())); + CONFIGURE_EVENTS_ID = this->contextMenu()->insertItem(SmallIcon("knotify", QIconSet::Automatic), + i18n("Configure Notifications..."), + this, SLOT(showConfigureNotificationsDialog())); +#ifdef ENABLE_YAST_ENTRY + YAST_MODULE_MENU_ID = this->contextMenu()->insertItem(SmallIcon("yast", QIconSet::Automatic), + i18n("Start YaST2 Power Management Module..."), + this, SLOT(do_config())); +#endif + + SLEEP_SEPARATOR_MENU_ID = this->contextMenu()->insertSeparator(); + SUSPEND2DISK_MENU_ID = this->contextMenu()->insertItem( SmallIconSet("suspend_to_disk", + QIconSet::Automatic), + i18n("Suspend to Disk"), this, + SLOT(do_suspend2disk())); + SUSPEND2RAM_MENU_ID = this->contextMenu()->insertItem( SmallIconSet("suspend_to_ram", + QIconSet::Automatic), + i18n("Suspend to RAM"), this, + SLOT(do_suspend2ram())); + STANDBY_MENU_ID = this->contextMenu()->insertItem( SmallIconSet("stand_by", QIconSet::Automatic), + i18n("Standby"), this, SLOT(do_standby())); + + speed_menu = new QPopupMenu(this, i18n("Set CPU Frequency Policy")); + speed_menu->insertItem(i18n("Performance"), PERFORMANCE); + speed_menu->insertItem(i18n("Dynamic"), DYNAMIC); + speed_menu->insertItem(i18n("Powersave"), POWERSAVE); + + CPUFREQ_SEPARATOR_MENU_ID = contextMenu()->insertSeparator(); + + CPUFREQ_MENU_ID = contextMenu()->insertItem(i18n("Set CPU Frequency Policy"), speed_menu); + connect(speed_menu, SIGNAL(activated(int)), this, SLOT(do_setSpeedPolicy(int))); + connect(hwinfo, SIGNAL(currentCPUFreqPolicyChanged()), this, SLOT(updateCPUFreqMenu())); + + + SCHEME_SEPARATOR_MENU_ID = contextMenu()->insertSeparator(); + + scheme_menu = new QPopupMenu(this, i18n("Set Active Scheme")); + SCHEME_MENU_ID = contextMenu()->insertItem(i18n("Set Active Scheme"), scheme_menu); + connect(scheme_menu, SIGNAL(activated(int)), this, SLOT(do_setActiveScheme(int))); + + // menu entry for the autosuspend disable checkbox, disabled by default, only + // displayed if autosuspend for the current scheme is activated + AUTOSUSPEND_SEPARATOR_MENU_ID = contextMenu()->insertSeparator(); + AUTOSUSPEND_MENU_ID = this->contextMenu()->insertItem( i18n("Disable Actions on Inactivity"), + this,SLOT(do_setAutosuspend())); + this->contextMenu()->setItemVisible(AUTOSUSPEND_SEPARATOR_MENU_ID, false); + this->contextMenu()->setItemVisible(AUTOSUSPEND_MENU_ID, false); + + HELP_SEPARATOR_MENU_ID = contextMenu()->insertSeparator(); + + help_menu = new QPopupMenu(this, i18n("&Help")); + + help_menu->insertItem( SmallIcon("help", QIconSet::Automatic), i18n("&KPowersave Handbook"), + this, SLOT(slotHelp())); + help_menu->insertSeparator(); + help_menu->insertItem( i18n("&Report a bug ..."), this, SLOT(slotReportBug())); + help_menu->insertItem( SmallIcon("kpowersave", QIconSet::Automatic), + i18n("&About KPowersave"), this, SLOT(slotAbout())); + + HELP_MENU = contextMenu()->insertItem(SmallIcon("help", QIconSet::Automatic), + i18n("&Help"), help_menu); + + connect(this, SIGNAL(quitSelected()), this, SLOT(_quit())); + + kdDebugFuncOut(trace); +} + +/*! + * This funtion load and manipulate the icons for the kickerapplet-section. + * The redraw interval depends on \ref icon_set_colored and \ref BAT_icon_BG_intervall. + */ +void kpowersave::redrawPixmap(){ + kdDebugFuncIn(trace); + + // if colored icon_background: normal redraw intervall is set off. + // Icon (only) redrawed every BAT_icon_BG_intervall + if (icon_set_colored) { + if (icon_state_changed) { + loadIcon(); + drawIcon(); + } + } + else { + loadIcon(); + drawIcon(); + } + + kdDebugFuncOut(trace); +} + +/*! + * Starts the configure dialog of kpowersave. + */ +void kpowersave::showConfigureDialog() { + kdDebugFuncIn(trace); + + if(!config_dialog_shown) { + if (settings->schemes.count() > 0){ + configDlg = new ConfigureDialog(config, hwinfo, settings); + configDlg->show(); + config_dialog_shown = true; + connect(configDlg, SIGNAL(destroyed()), this, SLOT(observeConfigDlg())); + connect(configDlg, SIGNAL(openHelp()), this, SLOT(slotHelp())); + connect(configDlg, SIGNAL(openKNotify()), this, SLOT(showConfigureNotificationsDialog())); + } + else { + KPassivePopup::message(i18n("WARNING"), i18n("Cannot find any schemes."), + SmallIcon("messagebox_warning", 20), this, + i18n("Warning"), 15000); + } + } else { + configDlg->setWindowState(configDlg->windowState() & ~WindowMinimized | WindowActive); + configDlg->setActiveWindow(); + } + + kdDebugFuncOut(trace); +} + +/*! + * Starts the notification configure dialog of kpowersave. + */ +void kpowersave::showConfigureNotificationsDialog() { + kdDebugFuncIn(trace); + + KNotifyDialog::configure(this); + + kdDebugFuncOut(trace); +} + +/*! + * Load the icons (from filesystem) for the kicker applet to \ref pixmap . + * To reduce the systemload the icons are only reloaded if \ref pixmap_name + * is changed. + */ +void kpowersave::loadIcon(){ + kdDebugFuncIn(trace); + + QString pixmap_name_tmp = "NONE"; + + BatteryCollection *primary = hwinfo->getPrimaryBatteries(); + + if (hwinfo->hal_terminated || !hwinfo->isOnline() ) { + pixmap_name_tmp = QString("ERROR"); + } + else if (hwinfo->getAcAdapter() || primary->getBatteryState() == BAT_NONE) { + icon_set_colored = false; + + if (primary->getBatteryState() == BAT_NONE || (primary->getRemainingPercent() < 0 || + primary->getRemainingPercent() >= 99)) + pixmap_name_tmp = QString("laptoppower"); + else + pixmap_name_tmp = QString("laptopcharge"); + } + else { + switch(primary->getBatteryState()) { + case BAT_CRIT: + case BAT_LOW: + if (icon_BG_is_colored) pixmap_name_tmp = QString("laptopbattery"); + else pixmap_name_tmp = QString("laptopbatteryRED"); + icon_BG_is_colored = !icon_BG_is_colored; + icon_set_colored = true; + break; + case BAT_WARN: + if (icon_BG_is_colored) pixmap_name_tmp = QString("laptopbattery"); + else pixmap_name_tmp = QString("laptopbatteryORANGE"); + icon_BG_is_colored = !icon_BG_is_colored; + icon_set_colored = true; + break; + default: + // if battery is discharging and not in warning, low or critical state + pixmap_name_tmp = QString("laptopbattery"); + icon_set_colored = false; + icon_BG_is_colored = false; + } + + if (icon_set_colored){ + icon_state_changed = false; + BAT_WARN_ICON_Timer->start(BAT_icon_BG_intervall, true); + } + } + + // reload icon only if new icon selected + if(pixmap_name_tmp != pixmap_name) { + pixmap_name = pixmap_name_tmp; + if (pixmap_name.startsWith("ERROR")) { + pixmap = SmallIcon("laptoppower", 22, KIcon::DisabledState); + } + else + pixmap = SmallIcon(pixmap_name, 22); + } + + kdDebugFuncOut(trace); +} + + +/*! + * This function draw the battery-capacity (colored field) to the icon. + * Here also counted the white pixel in the icon-files. Since the icons are + * the same and white pixel only in the retangel of the icon, the white pixel + * stored in \ref countWhiteIconPixel only one time. + */ +void kpowersave::drawIcon(){ + kdDebugFuncIn(trace); + + BatteryCollection *primary = hwinfo->getPrimaryBatteries(); + + QImage image = pixmap.convertToImage(); + int w = image.width(); + int h = image.height(); + int x, y; + + if((pixmap_name.contains("laptopbattery") || pixmap_name.contains("charge")) && + countWhiteIconPixel == 0) { + for (x = 0; x < w; x++) + for (y = 0; y < h; y++) + if(QColor(image.pixel(x, y)) == Qt::white) countWhiteIconPixel++; + } + + int c = (countWhiteIconPixel * primary->getRemainingPercent()) / 100; + + if (c > 0) { + uint ui; + QRgb Rgb_set; + + if (hwinfo->getAcAdapter()) { + Rgb_set = qRgb(0x00, 0xff, 0x00); //green + } + else { + switch(primary->getBatteryState()) { + case BAT_CRIT: + case BAT_LOW: + Rgb_set = qRgb(0xff, 0x00, 0x00);//red + break; + case BAT_WARN: + Rgb_set = qRgb(0xff, 0x55, 0x00); //orange + break; + default: + Rgb_set = qRgb(0x00, 0xff, 0x00); //green + } + } + if (image.depth() <= 8) { + ui = image.numColors(); + image.setNumColors(ui + 1); + image.setColor(ui, Rgb_set); + } + ui = 0xff000000 | Rgb_set; + + for (y = h - 1; y >= 0; y--) { + for (x = 0; x < w ; x++) { + if(QColor(image.pixel(x, y)) == Qt::white) { + image.setPixel(x, y, ui); + c--; + if (c <= 0) goto quit; + } + } + } + } +quit: + fullIcon.convertFromImage(image); + setPixmap(fullIcon); + + kdDebugFuncOut(trace); +} + +/*! +* By this function we fill and update the Tooltip for the icon in the kicker applet. +* The content of the tooltip alway updated, if something change. +* \todo Check if the tooltip also updated if mouse \b is over the icon, if not we maybe +* should implement this.\n If it is possible we should update the tooltip permanently +* while the mouse cursor is over the widget +*/ +void kpowersave::updateTooltip(){ + kdDebugFuncIn(trace); + + BatteryCollection *primary = hwinfo->getPrimaryBatteries(); + int percent = primary->getRemainingPercent(); + int minutes = primary->getRemainingMinutes(); + int charging_state = primary->getChargingState(); + + QString tmp, num3; + num3.setNum(minutes % 60); + num3 = num3.rightJustify(2, '0'); + + if (hwinfo->hal_terminated){ + tmp = i18n("No information about battery and AC status available"); + } + else if (hwinfo->getAcAdapter()) { + if (percent == 100) tmp = i18n("Plugged in -- fully charged"); + // assume that no battery is there + else { + if ((percent < 0 && minutes < 0) || primary->getBatteryState() == BAT_NONE) { + tmp = i18n("Plugged in"); + } + else if (minutes > 0){ + if (charging_state == CHARGING) + tmp = i18n("Plugged in -- %1% charged (%2:%3 h until full " + "charged)").arg(percent).arg(minutes / 60).arg(num3); + else + tmp = i18n("Plugged in -- %1% charged (%2:%3 remaining hours)") + .arg(percent).arg(minutes / 60).arg(num3); + } + else if (charging_state == CHARGING && hwinfo->hasAPM()) { + tmp = i18n("Plugged in -- %1% charged").arg(percent); + } + else{ + if (percent == -1) tmp = i18n("Plugged in -- no battery"); + else tmp = i18n("Plugged in -- %1% charged").arg(percent); + } + } + } else{ + if (minutes >= 0){ + tmp = i18n("Running on batteries -- %1% charged (%2:%3 hours remaining)") + .arg(percent).arg(minutes / 60).arg(num3); + } + else { + tmp = i18n("Running on batteries -- %1% charged").arg(percent); + } + } + // add string whether battery is charging, but only if < 100% to avoid + // stupid tooltip message on machines which always with 100% and on AC + // are charging, as e.g. Sony Vaio FS vgn-fs115b + if (charging_state == CHARGING && percent < 100) + tmp += i18n(" -- battery is charging"); + + QToolTip::add(this, tmp); + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to starts the Yast2-power-management module. This called by the menuentry + * with ID \ref YAST_MODULE_MENU_ID, named "Start YaST2 Power Management Module". + * It create a new KProcess and execute "/sbin/yast2 power-management" with kdesu. + */ +void kpowersave::do_config(){ + kdDebugFuncIn(trace); + + #ifdef ENABLE_YAST_ENTRY + delete yast2; + + yast2 = new KProcess; + *yast2 << "kdesu" << "--nonewdcop" << "/sbin/yast2" << "power-management"; + + connect(yast2, SIGNAL(processExited(KProcess *)), + SLOT(slotConfigProcessExited(KProcess *))); + if(!yast2->start(KProcess::NotifyOnExit)) + { + delete yast2; + yast2 = NULL; + } + + kdDebugFuncOut(trace); + #else + kdDebugFuncOut(trace); + return; + #endif +} + +/*! + * \b SLOT to open the KPowersave help + */ +void kpowersave::slotHelp() +{ + kapp->invokeHelp( "", "kpowersave" ); +} + +/*! + * \b SLOT to open the KPowersave About dialog + */ +void kpowersave::slotAbout() +{ + KAboutApplication a( this ); + a.exec(); +} + +/*! + * \b SLOT to open the website to report bugs + */ +void kpowersave::slotReportBug() +{ +#ifdef DISTRO_IS_SUSE + #ifdef DISTRO_IS_SLES_SLED + kapp->invokeBrowser("https://bugzilla.novell.com/"); + #else + kapp->invokeBrowser("http://en.opensuse.org/Submitting_Bug_Reports"); + #endif +#else + #ifdef DISTRO_IS_ALTLINUX + kapp->invokeBrowser("http://bugzilla.altlinux.org/"); + #else + #ifdef DISTRO_IS_UBUNTU + kapp->invokeBrowser("https://launchpad.net/distros/ubuntu/+bugs"); + #else + #ifdef DISTRO_IS_PARDUS + kapp->invokeBrowser("http://bugs.pardus.org.tr/"); + #else + kapp->invokeBrowser("http://sourceforge.net/tracker/?group_id=124576&atid=700009"); + #endif + #endif + #endif +#endif +} + +/*! + * \b SLOT to set the icon background on/off if battery is in critical, low or warning-state. Within + * this function we set \ref icon_state_changed to true and call \ref redrawPixmap() to redraw the + * kickerapplet icon and create a icon with blinking background. \n \n + * The slot called by the QTimer \ref BAT_WARN_ICON_Timer . The interval of the timer is defined + * trough \ref BAT_icon_BG_intervall and starts here: \ref loadIcon() . + */ +void kpowersave::do_setIconBG(){ + kdDebugFuncIn(trace); + + if (icon_set_colored) icon_state_changed = true; + redrawPixmap(); + + kdDebugFuncOut(trace); +} +/*! + * \b SLOT to enable/disable the autosuspend. + */ +void kpowersave::do_setAutosuspend(){ + kdDebugFuncIn(trace); + + if(!contextMenu()->isItemChecked(AUTOSUSPEND_MENU_ID)) { + autoSuspend->stop(); + contextMenu()->setItemChecked(AUTOSUSPEND_MENU_ID, true); + } + else { + if(settings->autoSuspend) { + contextMenu()->setItemChecked(AUTOSUSPEND_MENU_ID, false); + setAutoSuspend(false); + } + else { + contextMenu()->setItemVisible(AUTOSUSPEND_MENU_ID, false); + contextMenu()->setItemChecked(AUTOSUSPEND_MENU_ID, false); + contextMenu()->setItemVisible(AUTOSUSPEND_SEPARATOR_MENU_ID, false); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT which called if the \ref configDlg is destroyed. We set within this SLOT + * \ref config_dialog_shown to false. + * TODO: check if we maybe should force here the current default scheme depending on the AC/battery state + */ +void kpowersave::observeConfigDlg(){ + kdDebugFuncIn(trace); + + // reload general settings + settings->load_general_settings(); + // set the battery warning levels - all other general settings don't need to + // get set, since we check the settings only on events. + hwinfo->setPrimaryBatteriesWarningLevel(settings->batteryWarningLevel, + settings->batteryLowLevel, + settings->batteryCriticalLevel); + + // reload the maybe changed scheme settings + settings->load_scheme_settings( settings->currentScheme ); + // set the scheme + setSchemeSettings(); + + config_dialog_shown=false; + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT which called from \ref do_config() if the 'kdesu yast2' KProcess exited. + * This function control the return value and display if needed a errormessage on failure. + */ +void kpowersave::slotConfigProcessExited(KProcess *proc){ + kdDebugFuncIn(trace); + + #ifdef ENABLE_YAST_ENTRY + if (proc->normalExit()){ + if (proc->exitStatus() != 0 && proc->exitStatus() != 16){ + KPassivePopup::message( i18n("WARNING"), + i18n("Could not start YaST Power Management Module. " + "Check if it is installed."), + SmallIcon("messagebox_warning", 20), this, + i18n("Warning"), 15000); + } + } + else{ + KPassivePopup::message( i18n("WARNING"), + i18n("Could not start YaST Power Management Module. " + "Check if it is installed."), + SmallIcon("messagebox_warning", 20), this, i18n("Warning"), 15000); + } + + kdDebugFuncOut(trace); + #else + kdDebugFuncOut(trace); + return; + #endif +} + +/*! + * \b SLOT to send the command for "suspend to disk" to HAL daemon. + * If there is a error while "suspend to disk" the user get e messagebox. + * This function need a running HAL daemon for "suspend to disk". + * \return boolean with the result of the operation + * \retval true if successful + * \retval false if command not supported or if powersaved not running + */ +bool kpowersave::do_suspend2disk(){ + kdDebugFuncIn(trace); + + if (suspend.suspend2disk) { + if (suspend.suspend2disk_allowed || suspend.suspend2disk_allowed == -1) { + calledSuspend = SUSPEND2DISK; + if (!handleMounts(true)) { + kdWarning() << "Could not umount ..." << endl; + calledSuspend = -1; + kdDebugFuncOut(trace); + return false; + } + + if(settings->lockOnSuspend) { + display->lockScreen( settings->lockmethod ); + } + + autoSuspend->stop(); + autoDimm->stop(); + notifySuspend(calledSuspend); + bool ret = hwinfo->suspend(SUSPEND2DISK); + + if (ret) { + kdDebugFuncOut(trace); + return true; + } else { + KPassivePopup::message( i18n("WARNING"),i18n("Suspend to disk failed"), + SmallIcon("messagebox_warning", 20), this, + i18n("Warning"), 15000); + kdDebugFuncOut(trace); + return false; + } + } else { + KPassivePopup::message( i18n("WARNING"), + i18n("Suspend to disk disabled by administrator."), + SmallIcon("messagebox_warning", 20), + this, i18n("Warning"), 15000); + this->contextMenu()->setItemEnabled(SUSPEND2DISK_MENU_ID, false); + kdDebugFuncOut(trace); + return false; + } + } else { + kdWarning() << "This machine does not provide suspend2disk via HAL" << endl; + kdDebugFuncOut(trace); + return false; + } +} + +/*! + * \b SLOT to send the command for "suspend to RAM" to the HAL daemon. + * If there is a error while "suspend to RAM" the user get e messagebox. + * This function need a running HAL daemon for "suspend to RAM". + * \return boolean with the result of the operation + * \retval true if successful + * \retval false if command not supported or if powersaved not running + */ +bool kpowersave::do_suspend2ram(){ + kdDebugFuncIn(trace); + + if (suspend.suspend2ram) { + if (suspend.suspend2ram_allowed || suspend.suspend2ram_allowed == -1) { + calledSuspend = SUSPEND2RAM; + if (!handleMounts(true)) { + kdWarning() << "Could not umount ..." << endl; + calledSuspend = -1; + kdDebugFuncOut(trace); + return false; + } + + if(settings->lockOnSuspend) { + display->lockScreen( settings->lockmethod ); + } + + autoSuspend->stop(); + autoDimm->stop(); + notifySuspend(calledSuspend); + bool ret = hwinfo->suspend(SUSPEND2RAM); + + if (ret) { + kdDebugFuncOut(trace); + return true; + } else { + KPassivePopup::message( i18n("WARNING"),i18n("Suspend to RAM failed"), + SmallIcon("messagebox_warning", 20), this, + i18n("Warning"), 15000); + kdDebugFuncOut(trace); + return false; + } + } else { + KPassivePopup::message( i18n("WARNING"), + i18n("Suspend to RAM disabled by administrator."), + SmallIcon("messagebox_warning", 20), this, + i18n("Warning"), 15000); + this->contextMenu()->setItemEnabled(SUSPEND2RAM_MENU_ID, false); + kdDebugFuncOut(trace); + return false; + } + } else { + kdWarning() << "This machine does not provide suspend2ram via HAL" << endl; + kdDebugFuncOut(trace); + return false; + } +} + +/*! + * \b SLOT to send the command for "stand-by" to the HAL daemon. + * If there is a error while "stand-by" the user get e messagebox. + * This function need a running HAL daemon for "stand-by". + * \return boolean with the result of the operation + * \retval true if successful + * \retval false if command not supported or if powersaved not running + */ +bool kpowersave::do_standby(){ + kdDebugFuncIn(trace); + + if (suspend.standby) { + if (suspend.standby_allowed || suspend.standby_allowed == -1) { + calledSuspend = STANDBY; + if (!handleMounts(true)) { + kdWarning() << "Could not umount ..." << endl; + calledSuspend = -1; + kdDebugFuncOut(trace); + return false; + } + + if(settings->lockOnSuspend) { + display->lockScreen( settings->lockmethod ); + } + + autoSuspend->stop(); + autoDimm->stop(); + notifySuspend(calledSuspend); + bool ret = hwinfo->suspend(STANDBY); + + if (ret) { + kdDebugFuncOut(trace); + return true; + } else { + KPassivePopup::message( i18n("WARNING"),i18n("Standby failed"), + SmallIcon("messagebox_warning", 20), this, + i18n("Warning"), 15000); + kdDebugFuncOut(trace); + return false; + } + } else { + KPassivePopup::message( i18n("WARNING"),i18n("Standby disabled by administrator."), + SmallIcon("messagebox_warning", 20), this, + i18n("Warning"), 15000); + this->contextMenu()->setItemEnabled(STANDBY_MENU_ID, false); + kdDebugFuncOut(trace); + return false; + } + } else { + kdWarning() << "This machine does not provide suspend2ram via HAL" << endl; + kdDebugFuncOut(trace); + return false; + } +} + +/*! + * \b SLOT to send check if we should display the warning dialog and display + * the dialog if needed or call directly autosuspend after the signal + * \ref autosuspend::inactivityTimeExpired was recieved. + */ +void kpowersave::do_autosuspendWarn() { + kdDebugFuncIn(trace); + + if (settings->autoSuspendCountdown && (settings->autoSuspendCountdownTimeout > 0)) { + // we have to display the warn dialog + if(!contextMenu()->isItemChecked(AUTOSUSPEND_MENU_ID)) { + QString message; + + countdown = new countDownDialog(settings->autoSuspendCountdownTimeout); + + if(settings->autoInactiveAction == "Suspend to Disk") { + countdown->setPixmap("suspend2disk"); + } else if (settings->autoInactiveAction == "Suspend to RAM") { + countdown->setPixmap("suspend2ram"); + } else if (settings->autoInactiveAction == "Standby") { + countdown->setPixmap("standby"); + } else { + countdown->setPixmap("kpowersave"); + } + + // TODO: rework this after translation round for openSUSE 10.3 ! + message = i18n("Inactivity detected.") + " " + + i18n("To stop the %1 press the 'Cancel' button before the countdown " + "expire.").arg(i18n("Autosuspend")) + "\n\n" + + i18n("The computer autosuspend in: "); + + countdown->setMessageText(message); + + connect(countdown, SIGNAL(dialogClosed(bool)), this, SLOT(do_autosuspend(bool))); + countdown->showDialog(); + } + } else { + // call directly autosuspend + do_autosuspend(false); + } + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to send the related suspend command for autosuspend + * \param chancel boolean with info if the autosuspend should get chanceld + * \return boolean with the result of the operation + * \retval true if successful + * \retval false if command not supported or on any other error + * \todo add check if the requested command is supported befor send and + * add message for this case to tell that maybe changed config! + */ +bool kpowersave::do_autosuspend(bool chancel) { + kdDebugFuncIn(trace); + + // TODO: check if this is really needed, it get called also on the suspend methodes + autoSuspend->stop(); + + if (!chancel) { + if(!settings->disableNotifications) { + KNotifyClient::event( this->winId(), "autosuspend_event", + i18n("System is going into suspend mode now")); + } + + if(settings->autoSuspend && !contextMenu()->isItemChecked(AUTOSUSPEND_MENU_ID)) { + if(settings->autoInactiveAction == "Suspend to Disk") { + return do_suspend2disk(); + } else if (settings->autoInactiveAction == "Suspend to RAM") { + return do_suspend2ram(); + } else if (settings->autoInactiveAction == "Standby") { + return do_standby(); + } else { + return false; + } + } else { + return false; + } + } else { + kdDebug() << "The autosuspend was chanceled (via the chancel dialog), start again." << endl; + setAutoSuspend(false); + return false; + } +} + +/*! + * \b SLOT to dimm the display down to the configured level if the signal + * \ref autodimm::inactivityTimeExpired was recieved. + * \param + * \return boolean with the result of the operation + * \retval true if successful + * \retval false else + */ +void kpowersave::do_downDimm() { + kdDebugFuncIn(trace); + + if (hwinfo->supportBrightness()) { + if (!AUTODIMM_Timer->isActive()) { + int dimmToLevel = (int)((float)hwinfo->getMaxBrightnessLevel()*((float)settings->autoDimmTo/100.0)); + + // check if we really need to dimm down + if (dimmToLevel < hwinfo->getCurrentBrightnessLevel()) { + int steps = hwinfo->getCurrentBrightnessLevel() - dimmToLevel; + int timePerStep = (1500 / steps); + + autoDimmDown = true; + + AUTODIMM_Timer = new QTimer(this); + connect(AUTODIMM_Timer, SIGNAL(timeout()), this, SLOT(do_dimm())); + AUTODIMM_Timer->start(timePerStep, false); + } else { + kdWarning() << "Don't dimm down, current level is already lower than requested Level" << endl; + } + } else { + // wait until the timer is stopped, try later! + QTimer::singleShot(1500, this, SLOT(do_downDimm())); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to dimm the display up to the configured level if the signal + * \ref autodimm::UserIsActiveAgain was recieved. + * \param + * \return boolean with the result of the operation + * \retval true if successful + * \retval false else + */ +void kpowersave::do_upDimm() { + kdDebugFuncIn(trace); + + //NOTE we go back to the value of the scheme and not the last on, to reduce trouble with the scheme + + if (hwinfo->supportBrightness()) { + if (!AUTODIMM_Timer->isActive()) { + int dimmToLevel = (int)((float)hwinfo->getMaxBrightnessLevel()*((float)settings->brightnessValue/100.0)); + + // check if we really need to dimm up + if (dimmToLevel > hwinfo->getCurrentBrightnessLevel()) { + int steps = dimmToLevel - hwinfo->getCurrentBrightnessLevel(); + int timePerStep = (750 / steps); + + autoDimmDown = false; + + AUTODIMM_Timer = new QTimer(this); + connect(AUTODIMM_Timer, SIGNAL(timeout()), this, SLOT(do_dimm())); + AUTODIMM_Timer->start(timePerStep, false); + + // start autodimm again + setAutoDimm(false); + } else { + kdWarning() << "Don't dimm up, current level is already above requested Level" << endl; + } + } else { + // wait until the timer is stopped, try later! + QTimer::singleShot(750, this, SLOT(do_downDimm())); + } + } + + kdDebugFuncOut(trace); +} + + +/*! + * \b SLOT to dimm the display down + * \return boolean with the result of the operation + * \retval true if successful + * \retval false else + */ +void kpowersave::do_dimm() { + kdDebugFuncIn(trace); + + int current = hwinfo->getCurrentBrightnessLevel(); + + if (autoDimmDown) { + // dimm the display down + if (current > 0 && + current > ((int)((float)hwinfo->getMaxBrightnessLevel()*((float)settings->autoDimmTo/100.0))-1)) { + hwinfo->setBrightness((current -1) , -1); + } else { + AUTODIMM_Timer->stop(); + + // start checking if the user get active again + // NOTE: we start this here because the X-Server detect brightness changes as + // User activity --> FUCKING STUPID PIECE OF SHIT + autoDimm->startCheckForActivity(); + } + } else { + // dimm the display up + if (current < ((int)((float)hwinfo->getMaxBrightnessLevel()*((float)settings->brightnessValue/100.0))-1)) { + hwinfo->setBrightness((current +1) , -1); + } else { + AUTODIMM_Timer->stop(); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * Function handle umount/remount external storage media before/after + * suspend. + * \param suspend boolean with info if the machine go into suspend or not + * \return result of the operation + * \retval true if all was successful + * \retval false if not + */ +bool kpowersave::handleMounts( bool suspend ) { + if (trace) kdDebug() << funcinfo << "IN: " << "called suspend: " << suspend << endl; + + bool _ret = false; + QString _errormsg; + + if (settings->unmountExternalOnSuspend) { + QString _method; + DCOPRef dcop_ref = DCOPRef( "kded", "mediamanager" ); + + if (suspend) { + _method = "unmountAllSuspend()"; + } else { + _method = "remountAllResume()"; + } + DCOPReply reply = dcop_ref.call(_method.latin1()); + if ( reply.isValid() ) { + reply.get(_errormsg); + if (_errormsg.isEmpty()) { + kdDebugFuncOut(trace); + return true; + } else { + kdError() << "ERROR while umount/remount partitions: " << _errormsg << endl; + } + } else { + kdWarning() << "Could not umount external storage partitions." << endl; + } + + } else { + kdDebugFuncOut(trace); + return true; + } + + // this is only needed for suspend case and an error ... + // on resume a simple error msg should be enough + if (!_ret && suspend) { + // handle error case + QString _msg; + QString _e_msg; + QString _suspend; + + if (!_errormsg.isEmpty()) { + _e_msg = _errormsg; + } else { + _e_msg = i18n("Could not call DCOP interface to umount external media."); + } + + // ugly: need qt-tags because mediamanager can return html formated strings !!! + _msg = "<qt>" + + i18n("Could not umount external media before suspend/standby. \n " + "(Reason: %1)\n \n Would you like to continue suspend/standby " + "anyway? \n(Warning: Continue suspend can cause data loss!)").arg(_e_msg) + + "</qt>"; + + _suspend = getSuspendString(calledSuspend); + + int answer = KMessageBox::questionYesNo( 0, _msg, + i18n("Error while prepare %1").arg(_suspend), + i18n("Suspend anyway"), i18n("Cancel suspend"), + "ignoreMountOnSuspend"); + + if (answer == KMessageBox::Yes) { + _ret = true; + } + } + + kdDebugFuncOut(trace); + return _ret; +} + +/*! + * Handle the event for the power button and call the related action. + */ +void kpowersave::handlePowerButtonEvent( ) { + kdDebugFuncIn(trace); + + /* Only go to suspend on button event if we already resumed successful. + This should solve problems if we get may a event for the powerbutton + if there machine was waked up via power button. */ + if (calledSuspend == -1) { + handleActionCall(settings->powerButtonAction, settings->powerButtonActionValue); + } + + kdDebugFuncOut(trace); +} + +/*! + * Handle the event for the suspend2ram/sleep button and call the related action. + */ +void kpowersave::handleSleepButtonEvent() { + kdDebugFuncIn(trace); + + // Only go to suspend on button event if we already resumed successful. + if (calledSuspend == -1) { + handleActionCall(settings->sleepButtonAction, -1); + } + + kdDebugFuncOut(trace); +} + +/*! + * Handle the event for the suspend2disk (hibernater) button and call the related action. + */ +void kpowersave::handleS2DiskButtonEvent(){ + kdDebugFuncIn(trace); + + // Only go to suspend on button event if we already resumed successful. + if (calledSuspend == -1) { + handleActionCall(settings->s2diskButtonAction, -1); + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to handle the lidclose event. If the screen get locked + * depends on the user specific settings. + * \param closed boolean with info if the lid is closed or not + */ +void kpowersave::handleLidEvent( bool closed ){ + if (trace) kdDebug() << funcinfo << "IN: " << "Lid closed? " << closed << endl; + + if (closed) { + // get new general settings! This could maybe removed if we + // could be shure, that the settings are actuall + settings->load_general_settings(); + + // handle screen lock + if (settings->lidcloseAction < 0) { + if(settings->lockOnLidClose) { + if(!display->lockScreen( settings->lockmethod )) { + KPassivePopup::message( i18n("WARNING"), + i18n("Could not lock the screen. There may " + "be a problem with the selected \nlock " + "method or something else."), + SmallIcon("messagebox_warning", 20), this, + i18n("Warning"), 10000); + + } + } + if(settings->forceDpmsOffOnLidClose) { + display->forceDPMSOff(); + } + } else { + // handle lock action + if (hwinfo->currentSessionIsActive()) { + handleActionCall(settings->lidcloseAction, settings->lidcloseActionValue); + } else { + kdWarning() << "Session is not active, don't react on lidclose " + << "event with a action call (like e.g. Suspend)!" << endl; + } + } + + if(!settings->disableNotifications) + KNotifyClient::event( this->winId(), "lid_closed_event", i18n("The Lid was closed.")); + } else { + if(settings->forceDpmsOffOnLidClose) { + // reset the scheme settings to avoid problems related to call xset on lidclose + setSchemeSettings(); + } + + if (settings->lockOnLidClose) { + activateLoginScreen(); + } + + if(!settings->disableNotifications) + KNotifyClient::event( this->winId(), "lid_opened_event", i18n("The Lid was opened.")); + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to show the login dialog if the desktop was locked before the suspend. + */ +void kpowersave::activateLoginScreen(){ + kdDebugFuncIn(trace); + + // get new general settings! This could maybe removed if we + // could be shure, that the settings are actuall + settings->load_general_settings(); + + if(settings->timeToFakeKeyAfterLock >= 0) { + QTimer::singleShot(settings->timeToFakeKeyAfterLock, display, SLOT(fakeShiftKeyEvent())); + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to set the current suspend type for later use. + */ +void kpowersave::setSuspendType( QString suspendtype){ + kdDebugFuncIn(trace); + + suspendType = suspendtype; + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT which called if kpowersave is exited by the user. In this case the user + * is asked through a yes/no box if "KPowersave start automatically on log in" and the + * result is written to the KDE configfile. + */ +void kpowersave::_quit (){ + kdDebugFuncIn(trace); + + // set the KDE-Settings back to user default + if(getenv("KDE_FULL_SESSION")) { + // first try to call the KDE method via DCOP to reset, if not fall back + if (!display->resetKDEScreensaver()) { + settings->load_kde(); + // reset to KDE screensaver settings + display->blankOnlyScreen(false); + if(!settings->kde->enabled) display->setScreenSaver(false); + else display->setScreenSaver(true); + + if(!settings->kde->displayEnergySaving) display->setDPMS(false); + else display->setDPMS(true); + + display->has_DPMS = display->setDPMSTimeouts( settings->kde->displayStandby, + settings->kde->displaySuspend, + settings->kde->displayPowerOff); + } + } + + // set, if this is a GNOME session, XScreensaver settings back to user default + QString session = getenv("DESKTOP_SESSION"); + if(session.startsWith("gnome")) { + display->resetXScreensaver(); + } + + if(!settings->autostartNeverAsk) { + QString tmp1 = i18n ("Start KPowersave automatically when you log in?"); + int tmp2 = KMessageBox::questionYesNo ( 0, tmp1, i18n("Question"), + i18n("Start Automatically"), i18n("Do Not Start")); + config->setGroup("General"); + config->writeEntry ("Autostart", tmp2 == KMessageBox::Yes); + config->sync (); + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT called if the user select a 'CPU Frequency Policy' from the menu ( \ref CPUFREQ_MENU_ID ). + */ +void kpowersave::do_setSpeedPolicy(int menu_id){ + if (trace) kdDebug() << funcinfo << "IN: " << "menu_id/set policy to: " << menu_id << endl; + + if(!hwinfo->setCPUFreq((cpufreq_type)menu_id, settings->cpuFreqDynamicPerformance)) { + KPassivePopup::message(i18n("WARNING"), + i18n("CPU Freq Policy %1 could not be set.").arg(speed_menu->text(menu_id)), + SmallIcon("messagebox_warning", 20), this, i18n("Warning"), 10000); + } else { + hwinfo->checkCurrentCPUFreqPolicy(); + update(); + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT called if the user select a scheme from the menu. If there is any errormessage + * while try to set the selected scheme, the user get a messagebox with info. + */ +void kpowersave::do_setActiveScheme( int i ){ + if (trace) kdDebug() << funcinfo << "IN: " << "set scheme to: " << i << endl; + + if(settings->schemes[i] && (settings->schemes[i] != settings->currentScheme)) { + for (int x = 0; x < (int) scheme_menu->count(); x++){ + if (x == i) + scheme_menu->setItemChecked(x, true); + else + scheme_menu->setItemChecked(x, false); + } + settings->load_scheme_settings( settings->schemes[i]); + setSchemeSettings(); + notifySchemeSwitch(); + } else if (!settings->schemes[i]){ + KPassivePopup::message( i18n("WARNING"), + i18n("Scheme %1 could not be activated.").arg(scheme_menu->text(i)), + SmallIcon("messagebox_warning", 20), this, i18n("Warning"), 5000); + } + + kdDebugFuncOut(trace); +} + +/*! + * This function is invoked if something has to be updated. This including also menu entries. + * If the battery is in warning state (and powersave set pdaemon->send_battery_state_change_message) + * the function pop-up a messagebox. + */ +void kpowersave::update(){ + kdDebugFuncIn(trace); + + int redraw_pixmap = 0; + QString justMins; + + /* need to redraw pixmap in toolbar */ + if (hwinfo->update_info_ac_changed){ + redraw_pixmap = 1; + } + if (!hwinfo->isOnline()){ + this->contextMenu()->setItemVisible(SUSPEND2DISK_MENU_ID, false); + this->contextMenu()->setItemVisible(SUSPEND2RAM_MENU_ID, false); + this->contextMenu()->setItemVisible(STANDBY_MENU_ID, false); + this->contextMenu()->setItemVisible(SLEEP_SEPARATOR_MENU_ID, false); + this->contextMenu()->setItemVisible(SCHEME_SEPARATOR_MENU_ID, false); + this->contextMenu()->setItemVisible(SCHEME_MENU_ID, false); + this->contextMenu()->setItemVisible(HELP_SEPARATOR_MENU_ID, false); + this->contextMenu()->setItemVisible(CONFIGURE_ID, false); + this->contextMenu()->setItemVisible(CONFIGURE_EVENTS_ID, false); + if (!pixmap_name.startsWith("ERROR")) { + // dirty !!! but this work for the moment + hwinfo->update_info_cpufreq_policy_changed = true; + suspend = hwinfo->getSuspendSupport(); + redraw_pixmap = 1; + } + } + else{ + if (pixmap_name.startsWith("ERROR")) { + redraw_pixmap = 1; + hwinfo->update_info_cpufreq_policy_changed = true; + suspend = hwinfo->getSuspendSupport(); + } + this->contextMenu()->setItemVisible(SUSPEND2DISK_MENU_ID, true); + this->contextMenu()->setItemVisible(SUSPEND2RAM_MENU_ID, true); + this->contextMenu()->setItemVisible(STANDBY_MENU_ID, true); + this->contextMenu()->setItemVisible(SLEEP_SEPARATOR_MENU_ID, true); + this->contextMenu()->setItemVisible(SCHEME_SEPARATOR_MENU_ID, true); + this->contextMenu()->setItemVisible(SCHEME_MENU_ID, true); + this->contextMenu()->setItemVisible(HELP_SEPARATOR_MENU_ID, true); + this->contextMenu()->setItemVisible(CONFIGURE_ID, true); + this->contextMenu()->setItemVisible(CONFIGURE_EVENTS_ID, true); + + if (suspend.suspend2disk && (suspend.suspend2disk_allowed || + suspend.suspend2disk_allowed == -1)) { + this->contextMenu()->setItemEnabled(SUSPEND2DISK_MENU_ID, true); + } else { + if (!suspend.suspend2disk) + this->contextMenu()->setItemVisible(SUSPEND2DISK_MENU_ID, false); + else + this->contextMenu()->setItemEnabled(SUSPEND2DISK_MENU_ID, false); + } + + if (suspend.suspend2ram && (suspend.suspend2ram_allowed || + suspend.suspend2ram_allowed == -1)) { + this->contextMenu()->setItemEnabled(SUSPEND2RAM_MENU_ID, true); + } else { + if (!suspend.suspend2ram) + this->contextMenu()->setItemVisible(SUSPEND2RAM_MENU_ID, false); + else + this->contextMenu()->setItemEnabled(SUSPEND2RAM_MENU_ID, false); + } + + if (suspend.standby && (suspend.standby_allowed || suspend.standby_allowed == -1)) { + this->contextMenu()->setItemEnabled(STANDBY_MENU_ID, true); + } else { + if (!suspend.standby) + this->contextMenu()->setItemVisible(STANDBY_MENU_ID, false); + else + this->contextMenu()->setItemEnabled(STANDBY_MENU_ID, false); + } + } + + if (hwinfo->update_info_cpufreq_policy_changed == true){ + updateCPUFreqMenu(); + } + + BatteryCollection *primary = hwinfo->getPrimaryBatteries(); + + if (hwinfo->update_info_primBattery_changed == true){ + justMins.setNum(primary->getRemainingMinutes() % 60); + justMins = justMins.rightJustify(2, '0'); + + redraw_pixmap = 1; + hwinfo->update_info_primBattery_changed = false; + } + + updateSchemeMenu(); + + if (redraw_pixmap){ + redrawPixmap(); + } + + kdDebugFuncOut(trace); +} + +/*! + * This function is involved if the CPUFreqMenu must be updated. + */ +void kpowersave::updateCPUFreqMenu(){ + kdDebugFuncIn(trace); + + if (hwinfo->supportCPUFreq() && hwinfo->isOnline() && hwinfo->isCpuFreqAllowed()) { + /* set CPU frequency menu entries *********/ + /* speed menu has id 3 in context menu */ + contextMenu()->setItemVisible(CPUFREQ_MENU_ID, true); + contextMenu()->setItemEnabled(CPUFREQ_MENU_ID, true); + contextMenu()->setItemVisible(CPUFREQ_SEPARATOR_MENU_ID, true); + + switch (hwinfo->getCurrentCPUFreqPolicy()){ + case PERFORMANCE: + speed_menu->setItemChecked(PERFORMANCE, true); + speed_menu->setItemChecked(DYNAMIC, false); + speed_menu->setItemChecked(POWERSAVE, false); + break; + case DYNAMIC: + speed_menu->setItemChecked(PERFORMANCE, false); + speed_menu->setItemChecked(DYNAMIC, true); + speed_menu->setItemChecked(POWERSAVE, false); + break; + case POWERSAVE: + speed_menu->setItemChecked(PERFORMANCE, false); + speed_menu->setItemChecked(DYNAMIC, false); + speed_menu->setItemChecked(POWERSAVE, true); + break; + } + } else { + /* there never were policies */ + if (!speed_menu) { + return ; + } else if (hwinfo->supportCPUFreq() && (hwinfo->isCpuFreqAllowed() != 1)) { + contextMenu()->setItemEnabled(CPUFREQ_MENU_ID, false); + contextMenu()->setItemVisible(CPUFREQ_SEPARATOR_MENU_ID, true); + } else{ + /* there were CPU freq policies, but they are not accessible any more */ + /* delete speed_menu */ + contextMenu()->setItemVisible(CPUFREQ_MENU_ID, false); + contextMenu()->setItemVisible(CPUFREQ_SEPARATOR_MENU_ID, false); + } + } + + hwinfo->update_info_cpufreq_policy_changed = false; + + kdDebugFuncOut(trace); +} + +/*! + * The function used to update the scheme menu. A update is needed if + * if there is maybe new schemes or if the current scheme changed or switched + * By this way also set the settings for screensaver and other parameter + * related to the selected scheme. + */ +void kpowersave::updateSchemeMenu(){ + kdDebugFuncIn(trace); + + if (settings->schemes.count() == 0 || !hwinfo->isOnline()){ + /* there never were schemes */ + if (!scheme_menu) + return ; + else{ + /* there were schemes, but they are not accessible any more */ + /* delete scheme_menu */ + scheme_menu->clear(); + contextMenu()->setItemVisible(SCHEME_MENU_ID, false); + contextMenu()->setItemVisible(SCHEME_SEPARATOR_MENU_ID, false); + return ; + } + } + + /* redraw all scheme entries ... */ + scheme_menu->clear(); + // clear the list of real scheme names + org_schemenames.clear(); + + org_schemenames = settings->schemes; + + int x = 0; + for ( QStringList::iterator it = org_schemenames.begin(); it != org_schemenames.end(); ++it ) { + + QString _t = *it; + + if ( *it == settings->ac_scheme ){ + scheme_menu->insertItem( SmallIcon("scheme_power", QIconSet::Automatic), + i18n( (QString)*it ), x, x); + } + else{ + if ( *it == settings->battery_scheme ){ + scheme_menu->insertItem(SmallIcon("scheme_powersave", QIconSet::Automatic), + i18n( *it ), x, x); + } + else{ + if ((QString)*it == "Acoustic"){ + scheme_menu->insertItem(SmallIcon("scheme_acoustic", + QIconSet::Automatic), + i18n("Acoustic"), x, x); + } + else if ((QString)*it == "Presentation"){ + scheme_menu->insertItem(SmallIcon("scheme_presentation", + QIconSet::Automatic), + i18n("Presentation"), x, x); + + } + else if((QString)*it == "AdvancedPowersave") { + scheme_menu->insertItem(SmallIcon("scheme_advanced_powersave", + QIconSet::Automatic), + i18n( "Advanced Powersave" ), x, x); + } + else { + scheme_menu->insertItem(i18n( *it ), x, x); + } + } + } + + if ( *it == settings->currentScheme ) { + scheme_menu->setItemChecked(x, true); + } + ++x; + } + + if (x == 0 && scheme_menu){ + // this should not happen, scheme_list should have been NULL before + // now we'd have an empty menu ... + } + else{ + contextMenu()->setItemVisible(SCHEME_MENU_ID, true); + contextMenu()->setItemVisible(SCHEME_SEPARATOR_MENU_ID, true); + } + + kdDebugFuncOut(trace); +} + + +/*! + * Reimplemented eventhandler for mouse enterEvent. This is called if the mouse cursor + * enters the widget. In this case if the user move the mouse cursor over the kpowersave + * trayicon. \n \n + * We use this event to update the Tooltip with all needed information. The time beetween + * the event and the automatically popup of the QToolTip should be long enought to collect + * the needed values and add a updated Tooltip. + */ +void kpowersave::enterEvent( QEvent */*qee*/ ){ + + updateTooltip(); + +} + +/*! + * Event handler for mouse wheel events. If the system supports changing display + * brightness and changing brightness is enabled in the current scheme settings, + * this will raise the brightness by one level for wheel up events and lower the + * brightness by one level for wheel down events. + */ +void kpowersave::wheelEvent (QWheelEvent *qwe) +{ + kdDebugFuncIn(trace); + + if (!hwinfo->supportBrightness() && settings->brightness) + return; + + if (qwe->orientation () == Vertical) { + if (qwe->delta() > 0) { + do_brightnessUp(5); + } else { + do_brightnessDown(5); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * Reimplemented eventhandler for mousePressEvents which is involved if the user click + * on the icon on the kickerapplet. This was written to guarantee that a click with the + * right and the left mousebutton activate the menu. In the future this can also used + * to popup maybe a other menu. + */ +void kpowersave::mousePressEvent(QMouseEvent *qme){ + kdDebugFuncIn(trace); + + KSystemTray::mousePressEvent(qme); + if (hwinfo->isOnline()) { + if (qme->button() == RightButton){ + // TODO check if maybe some rechecks needed + this->contextMenu()->exec(QCursor::pos()); + } else if (qme->button() == LeftButton) { + showDetailedDialog(); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT called if the detaileddialog is closed. With this we prevent open + * the dialog twice, use this function to reset the used variables. + */ +void kpowersave::closedetaileddialog() { + detailedIsShown = false; +} + +/*! + * \b SLOT used to display error messages related to D-Bus in kpowersave. This function + * block all messeges which we have in kpowersave! + * TODO: do something usefull + */ +void kpowersave::showDBusErrorMsg( int type ){ + kdDebugFuncIn(trace); + + static bool displayed = false; + + QString msg; + QString dlg_name; + + switch (type) { + case DBUS_RUNNING: + update(); + return; + case DBUS_NOT_RUNNING: + msg = i18n("The D-Bus daemon is not running.\nStarting it will " + "provide full functionality: /etc/init.d/dbus start"); + dlg_name = "dbusNotRunning"; + break; + default: + kdDebugFuncOut(trace); + return; + } + + if (!displayed && !dlg_name.isEmpty()) { + infoDialog *dlg = new infoDialog( config, i18n("Warning"), msg, + i18n("Don't show this message again."), dlg_name); + + if (!dlg->dialogIsDisabled()) { + dlg->show(); + } + // set this always to true ... this should reduce the calls + displayed = true; + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT to display the HAL error message. We use this + * function to delay the message, and prevent display them is HAL or + * powersaved restarted. + */ +void kpowersave::showHalErrorMsg() { + kdDebugFuncIn(trace); + + if (hwinfo->isOnline()) { + // HAL is back! + update(); + } + if (!hwinfo->dbus_terminated) { + if(hal_error_shown && !DISPLAY_HAL_ERROR_Timer->isActive() && hwinfo->hal_terminated){ + KPassivePopup::message( i18n("ERROR"), + i18n("Could not get information from HAL. The haldaemon is " + "maybe not running."), + SmallIcon("messagebox_warning", 20), this, + i18n("Error"), 5000); + } + else if (hwinfo->hal_terminated && !hal_error_shown && !DISPLAY_HAL_ERROR_Timer->isActive()) { + hal_error_shown = true; + DISPLAY_HAL_ERROR_Timer->start(HAL_ERROR_MSG_intervall, true); + } + else if (!hwinfo->hal_terminated) { + hal_error_shown = false; + DISPLAY_HAL_ERROR_Timer->stop(); + } + } else { + // only for the case that HAL is also down with dbus and not back after restart + if (hwinfo->hal_terminated && !hal_error_shown && !DISPLAY_HAL_ERROR_Timer->isActive()) + DISPLAY_HAL_ERROR_Timer->start(HAL_ERROR_MSG_intervall, true); + } + + kdDebugFuncOut(trace); + return; +} + +/*! + * \b SLOT used to display messeges in kpowersave. This function + * block all messeges which we have in kpowersave! + */ +void kpowersave::showErrorMessage( QString msg ){ + kdDebugFuncIn(trace); + + if(settings->psMsgAsPassivePopup) { + KPassivePopup::message("KPowersave", msg, SmallIcon("messagebox_warning", 20), + this, i18n("Warning"), 10000); + } else { + kapp->updateUserTimestamp(); + // KMessageBox::error( 0, msg); + KMessageBox::queuedMessageBox(0, KMessageBox::Error, msg); + } + + kdDebugFuncOut(trace); +} + + +/*! + * Use this function to set the SchemeSettings. This function currently set the + * e.g. the screensaver and dpms settings. Don't forget to call this function if + * a scheme is changed or if the settings changed. + */ +void kpowersave::setSchemeSettings(){ + kdDebugFuncIn(trace); + + // --> check if there is a scheme set, if not, use defaults + if ( settings->currentScheme.isEmpty()) { + if (hwinfo->getAcAdapter()) { + settings->load_scheme_settings( settings->ac_scheme); + } else { + settings->load_scheme_settings( settings->battery_scheme); + } + } + + // call setPowerSave() depending on AC state + if (settings->callSetPowerSaveOnAC) { + if (hwinfo->getAcAdapter()) + hwinfo->setPowerSave(false); + else + hwinfo->setPowerSave(true); + } + + // --> set autosuspend settings + if(settings->autoSuspend) { + setAutoSuspend(false); + } else { + this->contextMenu()->setItemVisible(AUTOSUSPEND_MENU_ID, false); + this->contextMenu()->setItemChecked(AUTOSUSPEND_MENU_ID, false); + this->contextMenu()->setItemVisible(AUTOSUSPEND_SEPARATOR_MENU_ID, false); + autoSuspend->stop(); + } + + // --> set autodimm settings + if (settings->autoDimm) { + setAutoDimm(true); + } else { + autoDimm->stop(); + } + + // --> set screensaver + if(settings->specSsSettings){ + if(settings->disableSs) display->setScreenSaver(false); + else { + display->setScreenSaver(true); + if(settings->blankSs) display->blankOnlyScreen(true); + else { + display->blankOnlyScreen(false); + } + } + + } // TODO: check if this really work !!! + else if(getenv("KDE_FULL_SESSION")) { + // try to reset the complete screensaver settings. Ff this fail, use own methodes + if (!display->resetKDEScreensaver()) { + settings->load_kde(); + // Always disable blankOnly screensaver setting (default). KDE does + // not provide a GUI to configure it and most likely we are the + // only ones messing with it + display->blankOnlyScreen(false); + + // reset to global screensaver settings + if(!settings->kde->enabled) display->setScreenSaver(false); + else { + display->setScreenSaver(true); + // What should we do with settings->kde->lock ? + // Maybe nothing ?! + } + } + } else if ((getenv("DESKTOP_SESSION") != NULL) && !strcmp(getenv("DESKTOP_SESSION"), "gnome")) { + // use this to set XScreensaver back to default settings this should + // also cover the DPMS settings for GNOME/XScreensaver + display->resetXScreensaver(); + } + + // --> set DPMS settings + if(settings->specPMSettings){ + // set the new DPMS settings + if(settings->disableDPMS) { + display->setDPMS(false); + } + else { + display->setDPMS(true); + display->has_DPMS = display->setDPMSTimeouts( settings->standbyAfter, + settings->suspendAfter, + settings->powerOffAfter); + } + } + else if(getenv("KDE_FULL_SESSION")){ + // try to reset the KDE screensaver/DPMS settings (if there are also + // no special screensaver settings) otherwise fall back and set values from files + if (!settings->specSsSettings && !display->resetKDEScreensaver()) { + settings->load_kde(); + // reset to global screensaver settings + if(!settings->kde->displayEnergySaving) { + display->setDPMS(false); + } + else { + display->setDPMS(true); + display->has_DPMS = display->setDPMSTimeouts( settings->kde->displayStandby, + settings->kde->displaySuspend, + settings->kde->displayPowerOff); + } + } + } + + // --> set brightness settings + if(settings->brightness && hwinfo->supportBrightness()) { + // set to given values + hwinfo->setBrightness (-1, settings->brightnessValue); + } + + // --> set CPU Freq settings + if(hwinfo->supportCPUFreq()) { + hwinfo->setCPUFreq( settings->cpuFreqPolicy, settings->cpuFreqDynamicPerformance); + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT which called to set and start the autosuspend monitoring. + * \param resumed boolean value which represent information if machine + * currently back from suspend/standby + */ +void kpowersave::setAutoSuspend( bool resumed ){ + if (trace) kdDebug() << funcinfo << "IN: " << "resumed? " << resumed << endl; + + if(settings->autoInactiveActionAfter > 0 && settings->autoSuspend) { + int autoInactiveActionAfter = 0; + + if( settings->autoInactiveAction.startsWith("_NONE_")) { + autoSuspend->stop(); + return; + } + if (resumed) { + autoSuspend->stop(); + delete autoSuspend; + autoSuspend = new autosuspend(); + connect(autoSuspend, SIGNAL(inactivityTimeExpired()), this, + SLOT(do_autosuspendWarn())); + } + + if (settings->autoSuspendCountdown && (settings->autoSuspendCountdownTimeout > 0)) { + autoInactiveActionAfter = ((settings->autoInactiveActionAfter * 60) - + settings->autoSuspendCountdownTimeout); + } else { + autoInactiveActionAfter = settings->autoInactiveActionAfter * 60; + } + + if(settings->autoInactiveSBlistEnabled) { + autoSuspend->start( autoInactiveActionAfter, settings->autoInactiveSBlist ); + } + else { + autoSuspend->start( autoInactiveActionAfter, settings->autoInactiveGBlist ); + } + this->contextMenu()->setItemVisible(AUTOSUSPEND_SEPARATOR_MENU_ID, true); + this->contextMenu()->setItemVisible(AUTOSUSPEND_MENU_ID, true); + } + else { + // if autosuspend is not NULL: stop autosuspend + if (autoSuspend) { + autoSuspend->stop(); + } + + this->contextMenu()->setItemVisible(AUTOSUSPEND_MENU_ID, false); + this->contextMenu()->setItemVisible(AUTOSUSPEND_SEPARATOR_MENU_ID, false); + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT which called to set and start the autodimm monitoring. + * \param resumed boolean value which represent information if machine + * currently back from suspend/standby + */ +void kpowersave::setAutoDimm( bool resumed ){ + if (trace) kdDebug() << funcinfo << "IN: " << "resumed? " << resumed << endl; + + if(settings->autoDimmAfter > 0 && settings->autoDimm) { + if(settings->autoDimmTo < 0) { + autoDimm->stop(); + kdWarning() << "Not allowed or set level for dimm" << endl; + } else { + if (resumed) { + // setup again + autoDimm->stop(); + delete autoDimm; + autoDimm = new autodimm(); + connect(autoDimm, SIGNAL(inactivityTimeExpired()), this, SLOT(do_downDimm())); + connect(autoDimm, SIGNAL(UserIsActiveAgain()), this, SLOT(do_upDimm())); + } + + if (settings->autoDimmSBlistEnabled) { + autoDimm->start(settings->autoDimmAfter * 60, settings->autoDimmSBlist); + } else { + autoDimm->start(settings->autoDimmAfter * 60, settings->autoDimmGBlist); + } + } + } else { + if (autoDimm) + autoDimm->stop(); + } + + kdDebugFuncOut(trace); +} + +// -------- start KNotify functions ------------- // + +/*! + * \b SLOT called if a battery warning state reached and related signal recieved. + * Here we emit the related KNotify event, if not disabled. + * \param type integer with the type of the battery + * \param state integer represent the reached battery state + */ +void kpowersave::notifyBatteryStatusChange ( int type, int state ) { + if (trace) kdDebug() << funcinfo << "IN: " << "type: " << type << "state: " << state << endl; + + + if (type == BAT_PRIMARY) { + BatteryCollection *primary = hwinfo->getPrimaryBatteries(); + int min = primary->getRemainingMinutes(); + + if (primary->getChargingState() == CHARGING) { + kdDebug() << "kpowersave::notifyBatteryStatusChange: Battery is charging, ignore event" << endl; + return; + } + if (hwinfo->getAcAdapter()) { + // the machine is on AC, no need to inform about battery state, + // this is maybe only a race condition with not directly actuall + // charge state + kdDebug() << "kpowersave::notifyBatteryStatusChange: Machine is on AC, ignore event" << endl; + kdDebugFuncOut(trace); + return; + } + + switch (state) { + case BAT_WARN: + if (!settings->disableNotifications) + KNotifyClient::event(this->winId(), "battery_warning_event", + i18n("Battery state changed to WARNING -- remaining time: " + "%1 hours and %2 minutes.").arg(min/60).arg(min%60)); + // set/call related actions + handleActionCall(settings->batteryWarningLevelAction, + settings->batteryWarningLevelActionValue); + break; + case BAT_LOW: + if (!settings->disableNotifications) + KNotifyClient::event(this->winId(), "battery_low_event", + i18n("Battery state changed to LOW -- remaining time: " + "%1 hours and %2 minutes.").arg(min/60).arg(min%60)); + // set/call related actions + handleActionCall(settings->batteryLowLevelAction, + settings->batteryLowLevelActionValue); + break; + case BAT_CRIT: + // handle carefully: + if (settings->batteryCriticalLevelAction == GO_SHUTDOWN) { + if (!settings->disableNotifications) + KNotifyClient::event(this->winId(), "battery_critical_event", + i18n("Battery state changed to CRITICAL -- " + "remaining time: %1 hours and %2 minutes.\n" + "Shut down your system or plug in the power " + "cable immediately. Otherwise the machine\n" + "will go shutdown in 30 seconds") + .arg(min/ 60).arg(min%60)); + + QTimer::singleShot(30000, this, SLOT(handleCriticalBatteryActionCall())); + } else { + if (!settings->disableNotifications) + KNotifyClient::event(this->winId(), "battery_critical_event", + i18n("Battery state changed to CRITICAL -- " + "remaining time: %1 hours and %2 minutes.\n" + "Shut down your system or plug in the power " + "cable immediately.") + .arg(min/ 60).arg(min%60)); + + handleActionCall(settings->batteryCriticalLevelAction, + settings->batteryCriticalLevelActionValue); + } + break; + default: + break; + } + } else { + // TODO: add some code later for the other batteries + } + + kdDebugFuncOut(trace); +} + + +/*! + * Function to call the action for battery critical event. This is ugly, but + * because of QTimer::singleShot() can't take param ... + * NOTE: Use this only for SHUTDOWN atm + */ +void kpowersave::handleCriticalBatteryActionCall () { + kdDebugFuncIn(trace); + + handleActionCall(GO_SHUTDOWN, settings->batteryCriticalLevelActionValue, true, true); + + kdDebugFuncOut(trace); +} + +/*! + * Function to set a special action for a battery warning level. + * \param action integer with the type of the action from \ref action + * \param value integer value of the action as e.g. a brightness level + * \param checkAC bool if there should be a check for AC state befor call the action + */ +void kpowersave::handleActionCall ( action action, int value , bool checkAC, bool batWarnCall ) { + if (trace) kdDebug() << funcinfo << "IN: " << "action: " << action << "value: " << value + << "checkAC: " << checkAC << endl; + + if (hwinfo->currentSessionIsActive()) { + switch (action) { + case GO_SHUTDOWN: + // to be shure if we really need the shutdown + if ((checkAC && !hwinfo->getAcAdapter()) || !checkAC ) { + DCOPRef shutdown = DCOPRef( "ksmserver", "ksmserver" ); + shutdown.send("logout", 0, 2, 2); + } + break; + case LOGOUT_DIALOG: + { + DCOPRef shutdown = DCOPRef( "ksmserver", "ksmserver" ); + shutdown.send("logout", 1, 2, 2); + } + break; + case GO_SUSPEND2RAM: + QTimer::singleShot(100, this, SLOT(do_suspend2ram())); + break; + case GO_SUSPEND2DISK: + QTimer::singleShot(100, this, SLOT(do_suspend2disk())); + break; + case BRIGHTNESS: + hwinfo->setBrightness( -1, value ); + break; + case CPUFREQ_POWERSAVE: + hwinfo->setCPUFreq( POWERSAVE ); + break; + case CPUFREQ_DYNAMIC: + hwinfo->setCPUFreq( DYNAMIC, settings->cpuFreqDynamicPerformance ); + break; + case CPUFREQ_PERFORMANCE: + hwinfo->setCPUFreq( PERFORMANCE ); + break; + case SWITCH_SCHEME: // not supported atm + case UNKNOWN_ACTION: + case NONE: + default: + kdError() << "Could not set the requested Action: " << action << endl; + break; + } + } else if (batWarnCall) { + if (!hwinfo->isPolicyPowerIfaceOwned()) { + switch (action) { + case GO_SHUTDOWN: + // to be shure if we really need the shutdown + if ((checkAC && !hwinfo->getAcAdapter()) || !checkAC ) { + DCOPRef shutdown = DCOPRef( "ksmserver", "ksmserver" ); + shutdown.send("logout", 0, 2, 2); + } + break; + default: + kdError() << "Could not call requested action, inactive session: " << action << endl; + break; + } + } + } else { + kdError() << "Could not set the requested action, session is inactiv: " << action << endl; + } + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT called if ac stated changed. Here we emit the related KNotify event. + * and switch to the AC/battery scheme depending on the state of AC + * \param acstate boolean represent the state of AC (true == AC plugged in ...) + */ +void kpowersave::handleACStatusChange ( bool acstate , bool notifyEvent ) { + if (trace) kdDebug() << funcinfo << "IN: " << "acstate: " << acstate << "notifyEvent: " << notifyEvent << endl; + + int index; + + if (hwinfo->currentSessionIsActive()) { + + // emit notify event + if(notifyEvent && !settings->disableNotifications) { + if (acstate) { + KNotifyClient::event(this->winId(), "plug_event", i18n("AC adapter plugged in")); + } else { + KNotifyClient::event(this->winId(), "unplug_event", i18n("AC adapter unplugged")); + } + } + + // handle switch to AC/battery default scheme + if (acstate) { + index = settings->schemes.findIndex(settings->ac_scheme); + } else { + index = settings->schemes.findIndex(settings->battery_scheme); + } + + if (index != -1) + do_setActiveScheme(index); + + // update applet + update(); + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT called if scheme switched. Here we emit the related KNotify events + * if they are not disabled. + */ +void kpowersave::notifySchemeSwitch() { + kdDebugFuncIn(trace); + + if(!settings->disableNotifications) { + QString _scheme = settings->currentScheme; + QString eventType; + + if( _scheme != "Performance" && _scheme != "Powersave" && _scheme != "Acoustic" && + _scheme != "Presentation" && _scheme != "AdvancedPowersave" ) + eventType = "scheme_Unknown"; + else + eventType = "scheme_" + _scheme; + + KNotifyClient::event( this->winId(), eventType, + i18n("Switched to scheme: %1").arg(i18n(_scheme))); + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT called if the machine suspend. Here we emit the related KNotify events + * if they are not disabled. + */ +void kpowersave::notifySuspend( int suspendType ) { + kdDebugFuncIn(trace); + + if(!settings->disableNotifications) { + switch (suspendType) { + case SUSPEND2DISK: + KNotifyClient::event( this->winId(), "suspend2disk_event", + i18n("System is going into %1 now."). + arg(i18n("Suspend to Disk"))); + break; + case SUSPEND2RAM: + KNotifyClient::event( this->winId(), "suspend2ram_event", + i18n("System is going into %1 now."). + arg(i18n("Suspend to RAM"))); + break; + case STANDBY: + KNotifyClient::event( this->winId(), "standby_event", + i18n("System is going into %1 now."). + arg(i18n("Standby"))); + break; + default: + break; + } + } + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT called to independent handleResumeSignal() from event loop and + * to avoid problems with the QT3 D-Bus bindings + */ +void kpowersave::forwardResumeSignal( int result ) { + if (trace) kdDebug() << funcinfo << "IN: " << "result: " << result << endl; + + resume_result = result; + + QTimer::singleShot(100, this, SLOT(handleResumeSignal())); + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT called if the machine suspend. Here we emit the related KNotify events + * if they are not disabled. + */ +void kpowersave::handleResumeSignal() { + kdDebugFuncIn(trace); + + // fake key to show the login dialog if we locked the screen + if(settings->lockOnSuspend) { + activateLoginScreen(); + } + + // reset autosuspend and autodimm + setAutoSuspend(true); + setAutoDimm(true); + + // reset the CPU Freq Policy ... for more see https://bugzilla.novell.com/show_bug.cgi?id=223164 + if(hwinfo->supportCPUFreq()) { + hwinfo->setCPUFreq( settings->cpuFreqPolicy, settings->cpuFreqDynamicPerformance ); + } + + if(!settings->disableNotifications) { + switch (calledSuspend) { + case SUSPEND2DISK: + KNotifyClient::event( this->winId(), "resume_from_suspend2disk_event", + i18n("System is resumed from %1.").arg( + i18n("Suspend to Disk"))); + break; + case SUSPEND2RAM: + KNotifyClient::event( this->winId(), "resume_from_suspend2ram_event", + i18n("System is resumed from %1.").arg( + i18n("Suspend to RAM"))); + break; + case STANDBY: + KNotifyClient::event( this->winId(), "resume_from_standby_event", + i18n("System is resumed from %1.").arg( + i18n("Standby"))); + break; + default: + kdError() << "called suspend type unknown" << endl; + break; + + } + } + + // handle result of the resume/suspend + if (resume_result == 0 || resume_result == INT_MAX) { + if ( resume_result == INT_MAX ) + kdWarning() << "Unknown if we successful resumed, look like a D-Bus timeout since " + << "elapsed time between suspend and resume is higher than 6 hours" << endl; + + // successful resumed ... remount only in this case + if (!handleMounts(false)) { + KPassivePopup::message( i18n("WARNING"), + i18n("Could not remount (all) external storage" + " media."), SmallIcon("messagebox_warning", 20), + this, i18n("Warning"), 15000); + } + } else { + kdError() << "Unknown error while suspend. Errorcode: " << resume_result << endl; + QString msg; + + msg = i18n("An unknown error occurred while %1. The errorcode is: '%2'"). + arg(getSuspendString(calledSuspend)).arg(resume_result); + +#if defined(DISTRO_IS_SUSE) || defined(DISTRO_IS_SLES_SLED) || defined(DISTRO_IS_PARDUS) + // okay we know this system use pm-utils and log is under /var/log/pm-suspend.log + msg += "\n" + i18n("Do you want to have a look at the log file?"); + int answer = KMessageBox::questionYesNo(0, msg, i18n("Error while %1"). + arg(getSuspendString(calledSuspend))); + if (answer == KMessageBox::Yes) { + #if defined(DISTRO_IS_SLES_SLED) + switch (calledSuspend) { + case SUSPEND2DISK: + logview = new LogViewer ("/var/log/suspend2disk.log"); + logview->show(); + break; + case SUSPEND2RAM: + logview = new LogViewer ("/var/log/suspend2ram.log"); + logview->show(); + break; + case STANDBY: + logview = new LogViewer ("/var/log/standby.log"); + logview->show(); + break; + default: + break; + } + #else + logview = new LogViewer ("/var/log/pm-suspend.log"); + logview->show(); + #endif + } +#else + KMessageBox::error(0, msg, i18n("Error while %1").arg(getSuspendString(calledSuspend))); +#endif + } + // set back ... suspend is handled + calledSuspend = -1; + resume_result = 0; + + kdDebugFuncOut(trace); +} + +/*! + * \b SLOT called if the state of the current session change + * \param state boolean represent the state of the session + * TODO: fix scheme handling + * TODO: fix critical battery situations (see the todo file in the source) + */ +void kpowersave::handleSessionState (bool state) { + kdDebugFuncIn(trace); + + if (state) { + // session is active again + if (settings->autoSuspend) disableAutosuspend(false); + if (settings->autoDimm) setAutoDimm(false); + /* handle may missed/not set AC status changes while the + session was inactive and set them to the default schemes ?! */ + handleACStatusChange(hwinfo->getAcAdapter(), false); + + } else { + // session is now inactive + if (settings->autoSuspend) disableAutosuspend(true); + if (settings->autoDimm) autoDimm->stop(); + } + + kdDebugFuncOut(trace); +} + +// -------- end KNotify functions ------------- // +// ------------ helper functions -------------- // + +/*! + * Helper function to get a i18n name for a suspend type. + * \param type Integer value with the suspend type + * \return QString with the translated name or NULL if it fail + */ +QString kpowersave::getSuspendString (int type) { + kdDebugFuncIn(trace); + + switch (type) { + case SUSPEND2DISK: + return i18n("Suspend to Disk"); + break; + case SUSPEND2RAM: + return i18n("Suspend to RAM"); + break; + case STANDBY: + return i18n("Standby"); + break; + default: + return QString(); + } + + kdDebugFuncOut(trace); +} + +// --------- end helper functions ------------- // +// ------------ DCOP functions ---------------- // + +/*! + * DCOP Interface funtion to lock the screen with the userdefined methode. + * \return boolean with the result of locking the screen + * \retval true if locking the screen was successful + * \retval false if locking the screen failed or the user don't wan't to lock + */ +bool kpowersave::lockScreen(){ + kdDebugFuncIn(trace); + + settings->load_general_settings(); + + return display->lockScreen( settings->lockmethod ); + + kdDebugFuncOut(trace); +} + +/*! + * DCOP Interface funtion to return the name of the current powersave scheme. + * \return QString with the name of the current scheme + */ +QString kpowersave::currentScheme (){ + kdDebugFuncIn(trace); + + if(hwinfo->isOnline()) { + return settings->currentScheme; + } else { + return "ERROR: D-Bus and/or HAL not running"; + } + + kdDebugFuncOut(trace); +} + +/*! + * DCOP Interface funtion to return the name of the current cpuFreqPolicy. + * \return QString with the name of the current cpuFreqPolicy + */ +QString kpowersave::currentCPUFreqPolicy() { + kdDebugFuncIn(trace); + + if(hwinfo->isOnline()) { + QString _cpuFreq = ""; + switch (hwinfo->getCurrentCPUFreqPolicy()){ + case PERFORMANCE: + _cpuFreq = "PERFORMANCE"; + break; + case DYNAMIC: + _cpuFreq = "DYNAMIC"; + break; + case POWERSAVE: + _cpuFreq = "POWERSAVE"; + break; + default: + _cpuFreq = "UNKNOWN"; + break; + } + return _cpuFreq; + } else { + return "ERROR: HAL or/and DBus not running"; + } + + kdDebugFuncOut(trace); +} + +/*! + * DCOP Interface funtion to send a list with the allowed + * CPU Frequency states. + * \return QStringList with the supported CPUFreq states + */ +QStringList kpowersave::listCPUFreqPolicies() { + kdDebugFuncIn(trace); + + QStringList ret_list; + if (hwinfo->isCpuFreqAllowed()) { + ret_list.append("PERFORMANCE"); + ret_list.append("DYNAMIC"); + ret_list.append("POWERSAVE"); + } + else { + ret_list.append("NOT SUPPORTED"); + } + + kdDebugFuncOut(trace); + return ret_list; +} + +/*! + * DCOP Interface funtion to set the current CPUFreq policy + * \param policy QString with the policy to set, only values from + * list_CPUFreqPolicies are allowed (except "NOT SUPPORTED") + * \return boolean with the result of set the requested CPUFreq policy + * \retval true if successful set + * \retval false if not supported or any other failure + */ +bool kpowersave::do_setCPUFreqPolicy( QString policy ) { + if (trace) kdDebug() << funcinfo << "IN: " << "policy: " << policy << endl; + + + bool ret = true; + /* + if (hwinfo->isCpuFreqAllowed() && hwinfo->isOnline()) { + if (policy == "PERFORMANCE") { + hwinfo->setCPUFreq(PERFORMANCE); + } else if (policy == "DYNAMIC") { + hwinfo->setCPUFreq(DYNAMIC, settings->cpuFreqDynamicPerformance); + } else if (policy == "POWERSAVE") { + hwinfo->setCPUFreq(POWERSAVE); + } else { + kdDebugFuncOut(trace); + ret = false; + } + } else { + ret = false; + } + */ + kdDebugFuncOut(trace); + return ret; +} + +/*! + * DCOP Interface funtion to send a list with the supported and enabled + * sleeping states. + * \return QStringList with the supported spleeping states + */ +QStringList kpowersave::allowed_sleepingStates(){ + kdDebugFuncIn(trace); + + QStringList sleepList; + if(hwinfo->isOnline()) { + if (suspend.suspend2disk && (suspend.suspend2disk_allowed || + suspend.suspend2disk_allowed == -1)){ + sleepList.append("suspendToDisk"); + } + if (suspend.suspend2ram && (suspend.suspend2ram_allowed || + suspend.suspend2ram_allowed == -1)){ + sleepList.append("suspendToRAM"); + } + if (suspend.standby && (suspend.standby_allowed || suspend.standby_allowed == -1)){ + sleepList.append("standBy"); + } + if(sleepList.isEmpty()){ + sleepList.append("NO_SLEEPING_STATES_SUPPORTED"); + } + } + else { + sleepList.append("ERROR: D-Bus and/or HAL not running"); + } + + kdDebugFuncOut(trace); + return sleepList; +} + +/*! + * DCOP Interface funtion to send a list with the all schemes. + * \return QStringList with all schemes + */ +QStringList kpowersave::listSchemes(){ + kdDebugFuncIn(trace); + + QStringList _schemeList; + if(hwinfo->isOnline()) { + if (settings->schemes.count() > 0){ + _schemeList = settings->schemes; + } + } + else { + _schemeList.append("ERROR: D-Bus and/or HAL not running"); + } + + kdDebugFuncOut(trace); + return _schemeList; +} + + +/*! + * DCOP Interface funtion to set the current scheme. + * \return boolean with the result of set the requested scheme + * \retval false if failed (e.g. scheme is not in the list) + * \retval true if scheme found and set + * \param _scheme QString with the scheme to set, scheme should be + * named as list from list_schemes() + */ +bool kpowersave::do_setScheme( QString /*_scheme*/ ) { + kdDebugFuncIn(trace); + +/* int index; + index = settings->schemes.findIndex(_scheme); + + if (index != -1) { + do_setActiveScheme(index); + kdDebugFuncOut(trace); + return true; + } + else { + kdDebugFuncOut(trace); + return false; + } +*/ + kdDebugFuncOut(trace); + return false; +} + +/*! + * DCOP Interface funtion to send the suspend to disk command to powersave. + * \return boolean with the result of calling do_suspend2disk() + * \retval true if successful + * \retval false if not supported or powersaved not running + */ +bool kpowersave::do_suspendToDisk(){ + kdDebugFuncIn(trace); + kdDebugFuncOut(trace); + return do_suspend2disk(); +} + +/*! + * DCOP Interface funtion to send the suspend to disk command to powersave. + * \return boolean with the result of calling do_suspend2ram() + * \retval true if successful + * \retval false if not supported or powersaved not running + */ +bool kpowersave::do_suspendToRAM(){ + kdDebugFuncIn(trace); + kdDebugFuncOut(trace); + return do_suspend2ram(); +} + +/*! + * DCOP Interface funtion to send the suspend to disk command to powersave. + * \return boolean with the result of calling do_standby() + * \retval true if successful + * \retval false if not supported or powersaved not running + */ +bool kpowersave::do_standBy(){ + kdDebugFuncIn(trace); + kdDebugFuncOut(trace); + return do_standby(); +} + +//! dcop function to set the brightness up +bool kpowersave::do_brightnessUp(int percentageStep) { + kdDebugFuncIn(trace); + + bool retval = false; + + if(hwinfo->isOnline()) { + retval = hwinfo->setBrightnessUp(percentageStep); + } + + kdDebugFuncOut(trace); + return retval; +} + +//! dcop function to set the brightness down +bool kpowersave::do_brightnessDown(int percentageStep) { + kdDebugFuncIn(trace); + + bool retval = false; + + if(hwinfo->isOnline()) { + retval = hwinfo->setBrightnessDown(percentageStep); + } + + kdDebugFuncOut(trace); + return retval; +} + + +/*! + * DCOP Interface funtion to stop/start the Autosuspend + * \param disable boolean which tell if the autosuspend should be stopped (true) + * or started (false). + */ +void kpowersave::disableAutosuspend( bool disable ){ + kdDebugFuncIn(trace); + + if(settings->autoSuspend && settings->autoInactiveActionAfter > 0) { + if (disable) { + if ( !contextMenu()->isItemChecked(AUTOSUSPEND_MENU_ID)) { + autoSuspend->stop(); + contextMenu()->setItemChecked(AUTOSUSPEND_MENU_ID, true); + } + } + else { + contextMenu()->setItemChecked(AUTOSUSPEND_MENU_ID, false); + setAutoSuspend(true); + } + } + + kdDebugFuncOut(trace); +} + +/*! + * DCOP Interface funtion to open/close the detailed dialog. + */ +void kpowersave::showDetailedDialog( ){ + kdDebugFuncIn(trace); + + if (detailedIsShown) { + detailedDlg->close(); + delete(detailedDlg); + closedetaileddialog(); + return; + } + + detailedDlg = new detaileddialog(hwinfo, &fullIcon, settings); + + if (detailedDlg) { + detailedDlg->show(); + detailedIsShown = true; + } + + connect(detailedDlg, SIGNAL(destroyed()), this, SLOT(closedetaileddialog())); + + kdDebugFuncOut(trace); +} + +/*! + * DCOP Interface funtion to open the configure dialog. + * \return boolean with the result of open the dialog + * \retval false if failed (e.g. D-Bus or HAL is not running) + * \retval true if correct opend + */ +bool kpowersave::openConfigureDialog (){ + kdDebugFuncIn(trace); + + if(hwinfo->isOnline()) { + showConfigureDialog(); + kdDebugFuncOut(trace); + return config_dialog_shown; + } else { + kdDebugFuncOut(trace); + return false; + } +} + +/*! + * DCOP Interface funtion to find out if the current + * scheme manages DPMS + * \return boolean + * \retval false if current scheme does not overwrite DPMS + * \retval true if current scheme does + */ +bool kpowersave::currentSchemeManagesDPMS () { + kdDebugFuncIn(trace); + + return settings->specPMSettings; + + kdDebugFuncOut(trace); +} + + +//! dcop funtion to get the current brightness level +int kpowersave::brightnessGet() { + kdDebugFuncIn(trace); + + int retval = -1; + + if (hwinfo->supportBrightness()) { + retval = (int)(((float)hwinfo->getCurrentBrightnessLevel() / (float)hwinfo->getMaxBrightnessLevel()-1) * 100.0); + } + + kdDebugFuncOut(trace); + + return retval; +} + +#include "kpowersave.moc" diff --git a/src/kpowersave.desktop b/src/kpowersave.desktop new file mode 100644 index 0000000..914b172 --- /dev/null +++ b/src/kpowersave.desktop @@ -0,0 +1,68 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=kpowersave +Name[xx]=xxkpowersavexx +Name[de]=KPowersave +Name[es]=KPowersave +Name[fr]=KPowersave +Name[it]=KPowersave +Name[ja]=KPowersave +Name[pt_BR]=KPowersave +Name[ru]=KPowersave +Name[sv]=KPowersave +Name[zh_CN]=KPowersave +Name[zh_TW]=KPowersave +GenericName=Battery Monitor +Exec=kpowersave --force-acpi-check +Icon=kpowersave +Type=Application +Comment=Battery monitor and general power management +Comment[bg]=Монитор за батерията и основно управление на енергията +GenericName[bg]=Монитор за батерията +Comment[cs]=Sledování stavu baterií a správa napájení +GenericName[cs]=Monitor baterie +GenericName[de]=Akkuüberwachung +Comment[de]=Akkuüberwachung und allgemeine Energieverwaltung +GenericName[el]=Παρακολούθηση Μπαταρίας +GenericName[es]=Monitor de carga de la batería +Comment[es]=Monitor de batería y gestión general de la energía +Comment[fi]=Akkumonitori ja yleinen virranhallinta +GenericName[fi]=Akkumonitori +Comment[fr]=Moniteur de batterie et gestion de l'alimentation +GenericName[fr]=Moniteur de batterie +GenericName[hu]=Akkumulátorfigyelő +Comment[it]=Monitor della batteria e gestione generale dell'alimentazione +GenericName[it]=Monitor della batteria +Comment[km]=កមមវធ<200b>តរតពនតយ<200b>ថម នង គរបគរង<200b>ថាមពល<200b>ទទៅ +GenericName[km]=កមមវធ<200b>តរតពនតយ<200b>ថម +Comment[nb]=Batteriovervåking og generell strømstyring +GenericName[nb]=Batteriovervåker +GenericName[nl]=Batterijmonitor +GenericName[ja]=バッテリモニタ +Comment[ja]=バッテリモニタと一般電源管理 +Name[pa]=ਕ-ਊਰਜਾ ਸਭਾਲ +GenericName[pa]=ਬਟਰੀ ਦਰਸ਼ਕ +Comment[pl]=Monitor stanu baterii i ogólne zarządzanie energią +GenericName[pl]=Monitor baterii +Comment[pt]=Monitor de bateria e gestor global de energia +GenericName[pt]=Monitor de Bateria +Comment[pt_BR]=Monitor de Bateria e Gerenciamento de Energia Geral +GenericName[pt_BR]=Monitor de Bateria +GenericName[ru]=Монитор Батареи +Comment[ru]=Монитор батареи и управление энергосбережением +GenericName[sv]=Batteriövervakare +GenericName[tr]=Pil durumu izleme ve güç yönetimi arayüzü +Comment[tr]=Pil durumu izleme ve güç yönetimi arayüzü +Comment[uk]=Монітор стану батареї і загальне керування живленням +GenericName[uk]=Монітор батарей +Comment[xx]=xxBattery monitor and general power managementxx +GenericName[zh_CN]=电池监视器 +Comment[zh_CN]=电池监视器和常规电源管理 +GenericName[zh_TW]=電池監視器 +Comment[zh_TW]=電池監視器和一般電源管理 +X-KDE-autostart-after=panel +X-KDE-StartupNotify=false +X-KDE-UniqueApplet=true +X-KDE-autostart-condition=kpowersaverc:General:Autostart:true +Categories=System;Applet; + diff --git a/src/kpowersave.h b/src/kpowersave.h new file mode 100644 index 0000000..cfd7e01 --- /dev/null +++ b/src/kpowersave.h @@ -0,0 +1,486 @@ +/************************************************************************** +* Copyright (C) 2004 by Thomas Renninger * +* <trenn@suse.de> and * +* 2004-2007 by Danny Kukawka * +* <dkukawka@suse.de>, <danny.kukawka@web.de> * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of version 2 of the GNU General Public License * +* as published by the Free Software Foundation. * +* * +* 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. * +***************************************************************************/ + +#ifndef _KPOWERSAVE_H_ +#define _KPOWERSAVE_H_ + +// this is needed to avoid typedef clash with X11/Xmd.h (X11/Xproto.h) +#ifndef QT_CLEAN_NAMESPACE +#define QT_CLEAN_NAMESPACE +#endif + +// Global Header +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +// KDE - Header +#include <kprocess.h> +#include <ksystemtray.h> +#include <dcopobject.h> + +// QT - Header +#include <qpopupmenu.h> + +// kpowersave - Header +#include "autosuspend.h" +#include "autodimm.h" +#include "configuredialog.h" +#include "countdowndialog.h" +#include "detaileddialog.h" +#include "hardware.h" +#include "kpowersave_debug.h" +#include "logviewer.h" +#include "screen.h" +#include "settings.h" + + +/*! +* \file kpowersave.h +* \brief Headerfile for kpowersave.cpp and the class \ref kpowersave. +*/ + /*! + * \class kpowersave + * \brief The central class for the kpowersave-applet + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \author Thomas Renninger, <trenn@suse.de> + * \date 2004 - 2007 + */ + +class kpowersave : public KSystemTray, public DCOPObject +{ + Q_OBJECT + K_DCOP + +private: + + // permanent pointers + //! to configure kpowersave + KConfig *config; + //! instance of \ref screen + screen *display; + //! instance of \ref settings + Settings *settings; + //! pointer to class HardwareInfo object + HardwareInfo *hwinfo; + //! instance of \ref autosuspend + autosuspend *autoSuspend; + //! instance of \ref autodimm + autodimm * autoDimm; + + // temporary pointer, use them if needed + //! KProcess to start YaST-module for configuration + KProcess *yast2; + //! instance of \ref ConfigureDialog + /*! the implemtation and all related functions for the configure dialog*/ + ConfigureDialog *configDlg; + //! instance of \ref LogViewer + LogViewer *logview; + //! instance of \ref countDownDialog + countDownDialog *countdown; + + + //! struct wth information about suspend states and permissions + SuspendStates suspend; + //! enum with the last called suspend, this need to be reset if needed + int calledSuspend; + + //! instance of \ref detaileddialog + detaileddialog *detailedDlg; + + //! represent the state of opened \ref detailedDlg + /*! + * This boolean represent information about the detailedDlg. Use this to inform + * if the dialog is displayed. + * \li true: if dialog is displayed + * \li false: if not + */ + bool detailedIsShown; + //! represent the state of the configure dialog + /*! + * This boolean represent information about the configure dialog. Use this to inform + * if the dialog is displayed. + * \li true: if dialog is displayed + * \li false: if not + */ + bool config_dialog_shown; + + //! represent background status of the kickerapplet icon + /*! + * This boolean represent information about the background of the kickerapplet icon. + * \li true: if iconbackground is colored + * \li false: if iconbackground is not colored + */ + bool icon_BG_is_colored; + //! represent color status of the kickerapplet icon + /*! + * This boolean represent the state of the kickerapplet icon. It don't display + * information about the icon backgrund like \ref icon_BG_is_colored . It say + * only that the icon is in state to have a blinking background . + * \li true: if icon set to be colored + * \li false: if icon isn't set to be colored + */ + bool icon_set_colored; + //! represent the state of icon changing + /*! + * This boolean represent information about changing the icon background. It's used to + * change the intervall of redraw the kickerapplet icon. + * \li true: if the state of icon is changed + * \li false: if the state of icon isn't change + */ + bool icon_state_changed; + //! represent the state of the suspend/progress dialog + /*! + * This boolean represent information about the current state of + * visible of the suspend/progress dialog. + * \li true: if the dialog is shown + * \li false: if not + */ + bool suspend_dialog_shown; + //! represent display state of HAL error message + /*! + * This boolean represent information about the current state of + * the HAL error message + * \li true: if the errormessage was already displayed in this context + * \li false: if not + */ + bool hal_error_shown; + + //! tell if the display should get dimmed down + /*! + * This boolean represent information if the display should get dimmed down + * within the \ref do_dimm() function or not. + * \li true: if the display should get dimmed down + * \li false: if the display should get dimmed up + */ + bool autoDimmDown; + + //! to temporary hold the resume result + int resume_result; + + //! a menu entry ID + /*! contains the ID of the menuentry for kpowersave configure Dialog */ + int CONFIGURE_ID; + + int CONFIGURE_EVENTS_ID; + + //! a menu entry ID + /*! contains the ID of the menuentry for YaST-configuration */ + int YAST_MODULE_MENU_ID; + //! a menu seperator ID + /*! contains the ID of the separator between YaST-entry and the sleep-states */ + int SLEEP_SEPARATOR_MENU_ID; + //! a menu entry ID + /*! contains the ID of the menuentry for suspend-to-disk */ + int SUSPEND2DISK_MENU_ID; + //! a menu entry ID + /*! contains the ID of the menuentry for suspend-to-ram */ + int SUSPEND2RAM_MENU_ID; + //! a menu entry ID + /*! contains the ID of the menuentry for stand-by */ + int STANDBY_MENU_ID; + //! a menu seperator ID + /*! contains the ID of the separator between sleep-states-entries and the cpufreq-submenu */ + int CPUFREQ_SEPARATOR_MENU_ID; + //! a submenu ID + /*! contains the ID of the cpufreq sub menu*/ + int CPUFREQ_MENU_ID; + //! a menu seperator ID + /*! contains the ID of the separator between cpufreq- and scheme-submenu*/ + int SCHEME_SEPARATOR_MENU_ID; + //! a submenu ID + /*! contains the ID of the scheme submenu*/ + int SCHEME_MENU_ID; + //! a menu seperator ID + /*! contains the ID of the separator between scheme-submenu and autosuspend*/ + int AUTOSUSPEND_SEPARATOR_MENU_ID; + //! a menu entry ID + /*! contains the ID of the menuentry for disable inactivity actions */ + int AUTOSUSPEND_MENU_ID; + //! a menu seperator ID + /*! contains the ID of the separator between autosuspend and Help*/ + int HELP_SEPARATOR_MENU_ID; + //! a menu ID + /*! contains the ID of the help menu*/ + int HELP_MENU; + + //! number of white pixel in the kickerapplet icon + /*! + * This integer value represent the number of white pixel in the icon for + * the kickerapplet. with this 'global' variable we don't need to count the + * white pixel on every redraw. + */ + int countWhiteIconPixel; + + //! QTimer-interval for icon background + /*! + * Time intervall to set the colored background of the batteryicon on/off. + * The value is 1000 msec/ 1 sec. + */ + static const int BAT_icon_BG_intervall = 1000; + + //! QTimer-interval for display HAL error message + /*! + * Time intervall to delay display the HAL error message to prevent displayed + * the message if only HAL or powersave is restarted. The value is 15000 msec/ 15 sec. + */ + static const int HAL_ERROR_MSG_intervall = 15000; + + //! type of current running suspend + /*! QString store the name of the current running suspend*/ + QString suspendType; + + //! current name of the pixmap + /*! + * Contains the current name of the icon/pixmap. The value must be a filename of a existing iconfile. + * \sa power_icon, no_battery_icon, charge_icon, battery, battery_RED or battery_ORANGE + */ + QString pixmap_name; + + //! contains the 'real' schemenames + /*! + * This list store the real schemenames (not the i18n()-version) + * regarding to position in the scheme-menu + */ + QStringList org_schemenames; + + //! a sub-menu of the kickerapplet + /*! QPopupMenu for the cpufreq-entries. */ + QPopupMenu *speed_menu; + //! a sub-menu of the kickerapplet + /*! QPopupMenu for the scheme-entries. */ + QPopupMenu *scheme_menu; + //! a sub-menu of the kickerapplet + /*! QPopupMenu for the help-entries. */ + QPopupMenu *help_menu; + + + //! icon-pixmap + /*! QPixmap with the (pre-)loaded icon from \ref pixmap_name .*/ + QPixmap pixmap; + //! icon-pixmap + /*! QPixmap with the full draw applet Icon (to be used in other classes) .*/ + QPixmap fullIcon; + + + //! Timer for the blinking Icon background + /*! + * This timer is used to let blink the background of a icon in kicker. + * The timerinterval is defined in \ref BAT_icon_BG_intervall . + */ + QTimer *BAT_WARN_ICON_Timer; + //! Timer to delay the HAL error message + /*! + * This timer is used to add a delay befor display the HAL error message + * The timerinterval is defined in \ref HAL_ERROR_MSG_intervall . + */ + QTimer *DISPLAY_HAL_ERROR_Timer; + //! Timer to dimm down/up the brightness + /*! + * This timer is used dimm the display up and down. The timerinterval + * depends on calculated timePerStep in the calling function. + */ + QTimer *AUTODIMM_Timer; + + //! draw all icon related things for \ref redrawPixmap() + void drawIcon(); + //! to intialise the menu for the kickerapplet + void initMenu(); + //! load the icon for \ref redrawPixmap() + void loadIcon(); + //! draw/redraw the icon for the kickerapplet + void redrawPixmap(); + //! to set the screensaver settings + void setSchemeSettings(); + //! to update the Tooltip of the kickerapplet + void updateTooltip(); + + //! Eventhandler to catch mouse-press-events and react + void mousePressEvent( QMouseEvent *qme ); + //! Event handler to catch mouse wheel events and react + void wheelEvent( QWheelEvent *qwe ); + //! Eventhandler to catch mouse enter events and react + void enterEvent( QEvent *qee); + + //! to handle mount/umount on resume/suspend + bool handleMounts ( bool suspend ); + + //! to get the i18n string for a suspend type + QString getSuspendString (int type); + +private slots: + + //! send command for stand-by to the HAL daemon + bool do_standby(); + //! send command for suspend_to_disk to the HAL daemon + bool do_suspend2disk(); + //! send command for suspend_to_RAM to the HAL daemon + bool do_suspend2ram(); + + //! show warning dialog or call autosuspend if signal \ref inactivity::inactivityTimeExpired() recieved + void do_autosuspendWarn(); + //! execute the autosuspend + bool do_autosuspend(bool chancel); + //! starts the Yast2-power-management module + void do_config(); + //! sets the new scheme with all settings + void do_setActiveScheme( int ); + //! called if icon background must be changed + void do_setIconBG(); + //! to set the autosuspend on/off over the menu + void do_setAutosuspend(); + //! sets the CPU Freq policy via the HAL daemon + void do_setSpeedPolicy( int ); + //! called if there are problems with starting yast module + void slotConfigProcessExited( KProcess * ); + //! called to open the kpowersave help + void slotHelp(); + //! called to open the kpowersave About dialog + void slotAbout(); + //! called to open website to report bugs + void slotReportBug(); + //! called if the configure dialog is destroyed + void observeConfigDlg(); + //! called if user exit from kpowersave + void _quit(); + + //! called if the user get inactive and the display should get dimmed down + void do_downDimm(); + //! called if the user get active again and the display should get dimmed up + void do_upDimm(); + //! SLOT do do the dimmining for autodimm feature + void do_dimm(); + //! SLOT to set autodimm related stuff and start autodimm monitoring + void setAutoDimm( bool resumed ); + + //! to update the main menu of the kickerapplet + /*! this is bound to generalDataChanged singal in pdaemon */ + void update(); + //! to update the scheme-menu within the main menu + void updateSchemeMenu(); + //! to update the menu with the cpu frequency within the main menu + void updateCPUFreqMenu(); + + //! this set \ref suspendType from signal + void setSuspendType( QString suspendtype ); + //! this set the autosuspend and start the monitoring + void setAutoSuspend( bool ); + + //! called for critical battery event SHUTDOWN + void handleCriticalBatteryActionCall(); + //! set for a battery status the related actions + void handleActionCall ( action action, int value, bool checkAC = false, bool batWarnCall = false ); + + //! this lock/reactivate the screen if a lidcloseStatus() signal is triggered + void handleLidEvent( bool closed ); + //! show the login dialog after locked the screen + void activateLoginScreen(); + + //! handle event for press power button and call action + void handlePowerButtonEvent(); + //! handle event for press s2ram/sleep button and call action + void handleSleepButtonEvent(); + //! handle event for press s2disk button and call action + void handleS2DiskButtonEvent(); + + //! handle changes of the session state + void handleSessionState (bool state); + + //! to show the kpowersave configure_dialog + void showConfigureDialog(); + //! to show the KNotify config dialog + void showConfigureNotificationsDialog(); + + //! this emit the KNotify event for a battery warning state state + void notifyBatteryStatusChange ( int type, int state ); + //! this emit the KNotify event for change AC status + void handleACStatusChange ( bool acstate, bool notifyEvent = true ); + //! this emit the KNotify events if scheme switched + void notifySchemeSwitch(); + //! this emit the KNotify events if the machine go to suspend/Standby + void notifySuspend( int ); + //! to independent handleResumeSignal from event loop + void forwardResumeSignal( int result ); + //! this emit the KNotify events if the machine resumed + void handleResumeSignal(); + + //! to display HAL error msg + void showHalErrorMsg( ); + //! this is invoked to display powersave error message + void showDBusErrorMsg( int ); + //! this show a blocking dialog from kpowersave with the given message + void showErrorMessage( QString msg ); + + //! this is called when detailed dialog is closed + void closedetaileddialog(); + +public: + + //! default constructor + kpowersave( bool force_acpi_check = false, bool trace_func = false); + //! default destructor + virtual ~kpowersave(); + +k_dcop: + //! dcop function to lock the screen + bool lockScreen(); + //! dcop function to set a scheme + bool do_setScheme( QString ); + //! dcop function to set CPU Freq policy + bool do_setCPUFreqPolicy( QString ); + //! dcop function to send 'suspend to disk' command to powersaved + bool do_suspendToDisk(); + //! dcop function to send 'suspend to RAM' command to powersaved + bool do_suspendToRAM(); + //! dcop function to send 'standby' command to powersaved + bool do_standBy(); + //! dcop function to set the brightness down + bool do_brightnessDown(int percentageStep = -1); + //! dcop function to set the brightness up + bool do_brightnessUp(int percentageStep = -1); + + //! dcop function to disable/stop autosuspend + void disableAutosuspend( bool ); + + //! dcop function to show the detailed dialog + void showDetailedDialog(); + //! dcop function to open the configure dialog + bool openConfigureDialog(); + + //! dcop function to find out if kpowersave manages DPMS + bool currentSchemeManagesDPMS(); + //! dcop funtion to get the current brightness level + int brightnessGet(); + + //! dcop function to return the name of the current scheme + QString currentScheme (); + //! dcop function to return the current cpufreqpolicy + QString currentCPUFreqPolicy(); + + //! dcop function to return the supported sleeping states + QStringList allowed_sleepingStates(); + //! dcop function to return the schemes + QStringList listSchemes(); + //! dcop function to return the supported CPU + QStringList listCPUFreqPolicies(); +}; + +#endif // _KPOWERSAVE_H_ diff --git a/src/kpowersave.lsm b/src/kpowersave.lsm new file mode 100644 index 0000000..754d8f1 --- /dev/null +++ b/src/kpowersave.lsm @@ -0,0 +1,16 @@ +Begin3 +Title: kpowersave -- Some description +Version: 0.1 +Entered-date: +Description: +Keywords: KDE Qt +Author: Thomas Renninger <trenn@suse.de> +Maintained-by: Thomas Renninger <trenn@suse.de> +Home-page: +Alternate-site: +Primary-site: ftp://ftp.kde.org/pub/kde/unstable/apps/utils + xxxxxx kpowersave-0.1.tar.gz + xxx kpowersave-0.1.lsm +Platform: Linux. Needs KDE +Copying-policy: GPL +End diff --git a/src/kpowersave_debug.h b/src/kpowersave_debug.h new file mode 100644 index 0000000..6f258ea --- /dev/null +++ b/src/kpowersave_debug.h @@ -0,0 +1,68 @@ +/************************************************************************** +* Copyright (C) * +* 2004-2007 by Danny Kukawka * +* <dkukawka@suse.de>, <danny.kukawka@web.de> * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of version 2 of the GNU General Public License * +* as published by the Free Software Foundation. * +* * +* 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. * +***************************************************************************/ + +#ifndef _KPOWERSAVE_DEBUG_H +#define _KPOWERSAVE_DEBUG_H + +// Global Header +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +// Default Header +#include <stdio.h> +#include <stdlib.h> + +// QT - Header +#include <qdatetime.h> + +// KDE Header +#include <kdebug.h> + +/*! +* \file kpowersave_debug.h +* \brief Headerfile for debug releated defines/macros. Currently this file +* contains the myDebug(...) macro. +*/ + +// to store the value over the different classes +extern bool trace; + +/* + * macro to collect time and k_funcinfo information for kdDebug() + */ +#define funcinfo "[" << QTime::currentTime().toString().ascii() << \ + ":" << QTime::currentTime().msec() << "]" << k_funcinfo + +/* + * macros to trace function entry and leave points + */ +#define kdDebugFuncIn(traceinfo) do { \ + if (traceinfo == true) \ + kdDebug() << funcinfo << "IN " << endl; \ +} while (0) + +#define kdDebugFuncOut(traceinfo) do { \ + if (traceinfo == true) \ + kdDebug() << funcinfo << "OUT " << endl; \ +} while (0) + + +#endif //_KPOWERSAVE_DEBUG_H diff --git a/src/log_viewer.ui b/src/log_viewer.ui new file mode 100644 index 0000000..fae17d0 --- /dev/null +++ b/src/log_viewer.ui @@ -0,0 +1,104 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>log_viewer</class> +<widget class="QDialog"> + <property name="name"> + <cstring>log_viewer</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>480</height> + </rect> + </property> + <property name="caption"> + <string>Form1</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KTextEdit" row="0" column="0"> + <property name="name"> + <cstring>kTextEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>pB_save</cstring> + </property> + <property name="text"> + <string>Save As ...</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>330</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>pB_close</cstring> + </property> + <property name="text"> + <string>Close</string> + </property> + </widget> + </hbox> + </widget> + </grid> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>pB_close</sender> + <signal>clicked()</signal> + <receiver>log_viewer</receiver> + <slot>pB_close_clicked()</slot> + </connection> + <connection> + <sender>pB_save</sender> + <signal>clicked()</signal> + <receiver>log_viewer</receiver> + <slot>pB_save_clicked()</slot> + </connection> +</connections> +<slots> + <slot>pB_close_clicked()</slot> + <slot>pB_save_clicked()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/logviewer.cpp b/src/logviewer.cpp new file mode 100644 index 0000000..cb4d333 --- /dev/null +++ b/src/logviewer.cpp @@ -0,0 +1,124 @@ +/*************************************************************************** + * Copyright (C) 2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! \file logviewer.cpp + * \brief In this file can be found the LogViewer related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \version 0.0.1 + * \date 2007 + */ + +// QT header +#include <qfile.h> +#include <qtextstream.h> + +// KDE header +#include <ktextedit.h> +#include <klocale.h> +#include <kfiledialog.h> +#include <kmessagebox.h> + +// own header +#include "logviewer.h" + +/*! This is the default constructor of the class LogViewer. */ +LogViewer::LogViewer( QString filename, QWidget *parent, const char *name) + :log_viewer(parent, name, false, WDestructiveClose ) { + + this->setCaption(i18n("KPowersave Logfile Viewer: %1").arg(filename)); + + if (!QFile::exists ( filename )) + return; + + log_file = filename; + + QFile file (log_file); + if (file.open(IO_ReadOnly)) { + QTextStream stream ( &file ); + kTextEdit->setText (stream.read()); + kTextEdit->setReadOnly(true); + } + file.close(); +} + +/*! This is the default destructor of the class LogViewer. */ +LogViewer::~LogViewer(){ + // no need to delete child widgets, Qt does it all for us +} + +/*! + * SLOT: Called if the user click on 'Close' Button + */ +void LogViewer::pB_close_clicked() { + + close(); +} + +/*! + * SLOT: Called if the user click on 'Save As ...' Button + */ +void LogViewer::pB_save_clicked() { + + QString sFileName; + bool tryagain = true; + + while (tryagain == true) { + int answer; + QString msg; + + sFileName = KFileDialog::getSaveFileName( QDir::homeDirPath() ); + QFileInfo info (sFileName); + + if (QFile::exists(sFileName) && info.isWritable() && info.isReadable() && info.isFile()) { + msg = i18n("File already exist. Overwrite the file?"); + answer = KMessageBox::questionYesNo(this, msg , i18n("Error while save logfile")); + if (answer == KMessageBox::Yes) { + tryagain = false; + } + } else if (QFile::exists(sFileName)) { + msg = i18n("File already exist."); + answer = KMessageBox::warningContinueCancel(this, msg , + i18n("Error while save logfile"), + i18n("Try other filename ...")); + if (answer == KMessageBox::Cancel) { + tryagain = false; + return; + } + } else { + tryagain = false; + } + } + + QFile in(log_file); + QFile out(sFileName); + if (in.open(IO_ReadOnly)) { + if (out.open(IO_WriteOnly)) { + QByteArray input(4096); + long l = 0; + while (!in.atEnd()) { + l = in.readLine(input.data(), 4096); + out.writeBlock(input, l); + } + out.close(); + } + in.close(); + } +} + +#include "logviewer.moc" diff --git a/src/logviewer.h b/src/logviewer.h new file mode 100644 index 0000000..bf25fd6 --- /dev/null +++ b/src/logviewer.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2007 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +#ifndef LOGVIEWER_H +#define LOGVIEWER_H + +/*! +* \file logviewer.h +* \brief Headerfile for logviewer.cpp and the class \ref LogViewer. +*/ +/*! +* \class LogViewer +* \brief class for view logfiles in KPowersave related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \version 0.0.1 +* \date 2007 +*/ + +// header of the UI +#include "log_viewer.h" + +class LogViewer: public log_viewer { + + Q_OBJECT + +public: + //! default constructor + LogViewer( QString filename, QWidget *parent = 0, const char *name = 0); + //! default destructor + ~LogViewer(); + +private: + //! name of the log file + QString log_file; + +private slots: + + //! called if the user click on 'Close' Button + void pB_close_clicked(); + //! called if the user click on 'Save As ...' Button + void pB_save_clicked(); +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..3001691 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,94 @@ +/************************************************************************** +* Copyright (C) 2004 by Thomas Renninger * +* <trenn@suse.de> * +* 2004-2007 Danny Kukawka * +* <dkukawka@suse.de>, <danny.kukawka@web.de> * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of version 2 of the GNU General Public License * +* as published by the Free Software Foundation. * +* * +* 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. * +***************************************************************************/ + +#include "kpowersave.h" +#include <kuniqueapplication.h> +#include <kaboutdata.h> +#include <kcmdlineargs.h> +#include <klocale.h> +#include <kiconloader.h> + +#include "kpowersave_debug.h" + + /*! + * \file main.cpp + * \brief The file with the \ref kdemain class to start kpowersave. + */ +/*! + * \class kdemain + * \brief The kpowersave kdemain class, which is the startpoint of KPowersave. + * \author Thomas Renninger, <trenn@suse.de> + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2004 - 2007 + */ + +static const char description[] = I18N_NOOP("KDE Frontend for Power Management, Battery Monitoring and Suspend"); + +KCmdLineOptions options[] = { { "force-acpi-check", I18N_NOOP("Force a new check for ACPI support"), 0 }, + { "dbg-trace", I18N_NOOP("Trace function entry and leave points for debug\n"), 0 }, + { 0, 0, 0 }}; + +static const char version[] = "0.7.x (0.7.3)"; +bool trace = false; + +extern "C" +int kdemain(int argc, char **argv) +{ + KAboutData about("kpowersave", I18N_NOOP("KPowersave"), version, description, + KAboutData::License_GPL, I18N_NOOP("(c) 2004-2006, Danny Kukawka\n" + "(c) 2004 Thomas Renninger")); + + about.addAuthor("Danny Kukawka", I18N_NOOP("Current maintainer"), "danny.kukawka@web.de" ); + about.addAuthor("Thomas Renninger", 0, "trenn@suse.de" ); + + about.addCredit("Holger Macht", I18N_NOOP("Powersave developer and for D-Bus integration"), + "hmacht@suse.de"); + about.addCredit("Stefan Seyfried", I18N_NOOP("Powersave developer and tester"), + "seife@suse.de"); + about.addCredit("Daniel Gollub", I18N_NOOP("Added basic detailed dialog"), "dgollub@suse.de"); + about.addCredit("Michael Biebl", I18N_NOOP("Packaging Debian and Ubuntu"), "biebl@teco.edu"); + about.setBugAddress("powersave-users@forge.novell.com"); + about.setHomepage("http://sourceforge.net/projects/powersave"); + about.setTranslator("_: NAME OF TRANSLATORS\\nYour names","_: EMAIL OF TRANSLATORS\\nYour emails"); + + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions (options); + KUniqueApplication::addCmdLineOptions(); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + if (!KUniqueApplication::start()) { + fprintf(stderr, "KPowersave is already running!\n"); + exit(0); + } + + KUniqueApplication app; + app.disableSessionManagement(); + + kpowersave *mainWin = 0; + + mainWin = new kpowersave(args->isSet( "force-acpi-check" ), args->isSet( "dbg-trace" )); + app.setMainWidget( mainWin ); + mainWin->show(); + + // mainWin has WDestructiveClose flag by default, so it will delete itself. + return app.exec(); +} diff --git a/src/pics/Makefile.am b/src/pics/Makefile.am new file mode 100644 index 0000000..c63aa20 --- /dev/null +++ b/src/pics/Makefile.am @@ -0,0 +1,3 @@ +kpowersaveiconsdir = $(kde_datadir)/kpowersave/icons +kpowersaveicons_ICON = AUTO + diff --git a/src/pics/README b/src/pics/README new file mode 100644 index 0000000..7f43d25 --- /dev/null +++ b/src/pics/README @@ -0,0 +1 @@ +cr22-action-processor.png --> from kids-package (kcmprocessor.png) diff --git a/src/pics/cr16-action-configure.png b/src/pics/cr16-action-configure.png Binary files differnew file mode 100644 index 0000000..2c9d529 --- /dev/null +++ b/src/pics/cr16-action-configure.png diff --git a/src/pics/cr16-action-display.png b/src/pics/cr16-action-display.png Binary files differnew file mode 100644 index 0000000..8f6f176 --- /dev/null +++ b/src/pics/cr16-action-display.png diff --git a/src/pics/cr16-action-laptopbattery.png b/src/pics/cr16-action-laptopbattery.png Binary files differnew file mode 100644 index 0000000..26ba26f --- /dev/null +++ b/src/pics/cr16-action-laptopbattery.png diff --git a/src/pics/cr16-action-laptopcharge.png b/src/pics/cr16-action-laptopcharge.png Binary files differnew file mode 100644 index 0000000..61b139f --- /dev/null +++ b/src/pics/cr16-action-laptopcharge.png diff --git a/src/pics/cr16-action-laptopnobattery.png b/src/pics/cr16-action-laptopnobattery.png Binary files differnew file mode 100644 index 0000000..1f66479 --- /dev/null +++ b/src/pics/cr16-action-laptopnobattery.png diff --git a/src/pics/cr16-action-laptoppower.png b/src/pics/cr16-action-laptoppower.png Binary files differnew file mode 100644 index 0000000..6f42aa0 --- /dev/null +++ b/src/pics/cr16-action-laptoppower.png diff --git a/src/pics/cr16-action-scheme_acoustic.png b/src/pics/cr16-action-scheme_acoustic.png Binary files differnew file mode 100644 index 0000000..ec2bb62 --- /dev/null +++ b/src/pics/cr16-action-scheme_acoustic.png diff --git a/src/pics/cr16-action-scheme_advanced_powersave.png b/src/pics/cr16-action-scheme_advanced_powersave.png Binary files differnew file mode 100644 index 0000000..aef8042 --- /dev/null +++ b/src/pics/cr16-action-scheme_advanced_powersave.png diff --git a/src/pics/cr16-action-scheme_power.png b/src/pics/cr16-action-scheme_power.png Binary files differnew file mode 100644 index 0000000..640cfea --- /dev/null +++ b/src/pics/cr16-action-scheme_power.png diff --git a/src/pics/cr16-action-scheme_powersave.png b/src/pics/cr16-action-scheme_powersave.png Binary files differnew file mode 100644 index 0000000..a6d53f6 --- /dev/null +++ b/src/pics/cr16-action-scheme_powersave.png diff --git a/src/pics/cr16-action-scheme_presentation.png b/src/pics/cr16-action-scheme_presentation.png Binary files differnew file mode 100644 index 0000000..63c44b9 --- /dev/null +++ b/src/pics/cr16-action-scheme_presentation.png diff --git a/src/pics/cr16-action-stand_by.png b/src/pics/cr16-action-stand_by.png Binary files differnew file mode 100644 index 0000000..28dd473 --- /dev/null +++ b/src/pics/cr16-action-stand_by.png diff --git a/src/pics/cr16-action-suspend_to_disk.png b/src/pics/cr16-action-suspend_to_disk.png Binary files differnew file mode 100644 index 0000000..8991754 --- /dev/null +++ b/src/pics/cr16-action-suspend_to_disk.png diff --git a/src/pics/cr16-action-suspend_to_ram.png b/src/pics/cr16-action-suspend_to_ram.png Binary files differnew file mode 100644 index 0000000..2eac645 --- /dev/null +++ b/src/pics/cr16-action-suspend_to_ram.png diff --git a/src/pics/cr16-action-yast.png b/src/pics/cr16-action-yast.png Binary files differnew file mode 100644 index 0000000..a7dfa92 --- /dev/null +++ b/src/pics/cr16-action-yast.png diff --git a/src/pics/cr22-action-autodimm.png b/src/pics/cr22-action-autodimm.png Binary files differnew file mode 100644 index 0000000..5ef05ad --- /dev/null +++ b/src/pics/cr22-action-autodimm.png diff --git a/src/pics/cr22-action-button.png b/src/pics/cr22-action-button.png Binary files differnew file mode 100644 index 0000000..76917d5 --- /dev/null +++ b/src/pics/cr22-action-button.png diff --git a/src/pics/cr22-action-configure.png b/src/pics/cr22-action-configure.png Binary files differnew file mode 100644 index 0000000..2c9d529 --- /dev/null +++ b/src/pics/cr22-action-configure.png diff --git a/src/pics/cr22-action-display.png b/src/pics/cr22-action-display.png Binary files differnew file mode 100644 index 0000000..c6530cf --- /dev/null +++ b/src/pics/cr22-action-display.png diff --git a/src/pics/cr22-action-laptopbattery.png b/src/pics/cr22-action-laptopbattery.png Binary files differnew file mode 100644 index 0000000..c50fafe --- /dev/null +++ b/src/pics/cr22-action-laptopbattery.png diff --git a/src/pics/cr22-action-laptopbatteryORANGE.png b/src/pics/cr22-action-laptopbatteryORANGE.png Binary files differnew file mode 100644 index 0000000..6c9bdfb --- /dev/null +++ b/src/pics/cr22-action-laptopbatteryORANGE.png diff --git a/src/pics/cr22-action-laptopbatteryRED.png b/src/pics/cr22-action-laptopbatteryRED.png Binary files differnew file mode 100644 index 0000000..17f1893 --- /dev/null +++ b/src/pics/cr22-action-laptopbatteryRED.png diff --git a/src/pics/cr22-action-laptopcharge.png b/src/pics/cr22-action-laptopcharge.png Binary files differnew file mode 100644 index 0000000..4817a84 --- /dev/null +++ b/src/pics/cr22-action-laptopcharge.png diff --git a/src/pics/cr22-action-laptopnobattery.png b/src/pics/cr22-action-laptopnobattery.png Binary files differnew file mode 100644 index 0000000..6ff3965 --- /dev/null +++ b/src/pics/cr22-action-laptopnobattery.png diff --git a/src/pics/cr22-action-laptoppower.png b/src/pics/cr22-action-laptoppower.png Binary files differnew file mode 100644 index 0000000..6be6f07 --- /dev/null +++ b/src/pics/cr22-action-laptoppower.png diff --git a/src/pics/cr22-action-processor.png b/src/pics/cr22-action-processor.png Binary files differnew file mode 100644 index 0000000..e2d9a0a --- /dev/null +++ b/src/pics/cr22-action-processor.png diff --git a/src/pics/cr22-action-scheme_acoustic.png b/src/pics/cr22-action-scheme_acoustic.png Binary files differnew file mode 100644 index 0000000..6df5489 --- /dev/null +++ b/src/pics/cr22-action-scheme_acoustic.png diff --git a/src/pics/cr22-action-scheme_advanced_powersave.png b/src/pics/cr22-action-scheme_advanced_powersave.png Binary files differnew file mode 100644 index 0000000..f4a1561 --- /dev/null +++ b/src/pics/cr22-action-scheme_advanced_powersave.png diff --git a/src/pics/cr22-action-scheme_power.png b/src/pics/cr22-action-scheme_power.png Binary files differnew file mode 100644 index 0000000..c86841a --- /dev/null +++ b/src/pics/cr22-action-scheme_power.png diff --git a/src/pics/cr22-action-scheme_powersave.png b/src/pics/cr22-action-scheme_powersave.png Binary files differnew file mode 100644 index 0000000..4237f47 --- /dev/null +++ b/src/pics/cr22-action-scheme_powersave.png diff --git a/src/pics/cr22-action-scheme_presentation.png b/src/pics/cr22-action-scheme_presentation.png Binary files differnew file mode 100644 index 0000000..6d9d07a --- /dev/null +++ b/src/pics/cr22-action-scheme_presentation.png diff --git a/src/pics/cr22-action-stand_by.png b/src/pics/cr22-action-stand_by.png Binary files differnew file mode 100644 index 0000000..99e4a7c --- /dev/null +++ b/src/pics/cr22-action-stand_by.png diff --git a/src/pics/cr22-action-suspend_to_disk.png b/src/pics/cr22-action-suspend_to_disk.png Binary files differnew file mode 100644 index 0000000..9666270 --- /dev/null +++ b/src/pics/cr22-action-suspend_to_disk.png diff --git a/src/pics/cr22-action-suspend_to_ram.png b/src/pics/cr22-action-suspend_to_ram.png Binary files differnew file mode 100644 index 0000000..ecdd14c --- /dev/null +++ b/src/pics/cr22-action-suspend_to_ram.png diff --git a/src/pics/cr22-action-yast.png b/src/pics/cr22-action-yast.png Binary files differnew file mode 100644 index 0000000..a13dd4b --- /dev/null +++ b/src/pics/cr22-action-yast.png diff --git a/src/pics/cr48-action-stand_by.png b/src/pics/cr48-action-stand_by.png Binary files differnew file mode 100644 index 0000000..9a0c117 --- /dev/null +++ b/src/pics/cr48-action-stand_by.png diff --git a/src/pics/cr48-action-suspend_to_disk.png b/src/pics/cr48-action-suspend_to_disk.png Binary files differnew file mode 100644 index 0000000..8ce3bc9 --- /dev/null +++ b/src/pics/cr48-action-suspend_to_disk.png diff --git a/src/pics/cr48-action-suspend_to_ram.png b/src/pics/cr48-action-suspend_to_ram.png Binary files differnew file mode 100644 index 0000000..d0fe63a --- /dev/null +++ b/src/pics/cr48-action-suspend_to_ram.png diff --git a/src/privileges.h b/src/privileges.h new file mode 100644 index 0000000..9b45d19 --- /dev/null +++ b/src/privileges.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2007 by Danny Kukawka * + * <dkukawka@suse.de, danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! +* \file privileges.h +* \brief Headerfile containing defines for privileges +* \author Danny Kukawka, <dkukawka@suse.de, danny.kukawka@web.de> +* \date 2007 +*/ + +#ifndef _PRIVILEGES_H_ +#define _PRIVILEGES_H_ + +#ifdef HAVE_HAL_0_5_10 + #define PRIV_SUSPEND "org.freedesktop.hal.power-management.suspend" + #define PRIV_HIBERNATE "org.freedesktop.hal.power-management.hibernate" + #define PRIV_STANDBY "org.freedesktop.hal.power-management.standby" + #define PRIV_CPUFREQ "org.freedesktop.hal.power-management.cpufreq" + #define PRIV_LAPTOP_PANEL "org.freedesktop.hal.power-management.lcd-panel" + #define PRIV_SETPOWERSAVE "org.freedesktop.hal.power-management.set-powersave" +#else + #define PRIV_SUSPEND "hal-power-suspend" + #define PRIV_HIBERNATE "hal-power-hibernate" + #define PRIV_STANDBY "hal-power-standby" + #define PRIV_CPUFREQ "hal-power-cpufreq" + #define PRIV_LAPTOP_PANEL "hal-power-lcd-panel" + #define PRIV_SETPOWERSAVE "hal-power-set-powersave" +#endif + +#endif diff --git a/src/screen.cpp b/src/screen.cpp new file mode 100644 index 0000000..0f58d0f --- /dev/null +++ b/src/screen.cpp @@ -0,0 +1,721 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ +/*! \file screen.cpp + * All here displayed file members of screen.cpp are related to operations with the + * XSreensaver/XServer. This functions are basic/low level operations. They are + * inspired, partly copied and modified from <a href="http://www.mplayerhq.hu/">MPlayer</a> + * code (1.05pre). Thanks for the inspiration. \n \n + * All 'higher level' class members of the class screen can be found here: \ref screen + * \brief In this file can be found all screensaver related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2004 - 2006 + */ + + // own headers +#include "screen.h" +#include "kpowersave_debug.h" + +/* needed for lXext C library linkage */ +extern "C" { + #include <X11/Xproto.h> + #include <X11/extensions/dpms.h> + #include <X11/extensions/XTest.h> +} + +// KDE Headers +#include <kprocess.h> + +/*! The default constructor of the class screen */ +screen::screen() { + kdDebugFuncIn(trace); + + xscreensaver_lock = NULL; + xscreensaver_reset = NULL; + gnomescreensaver_lock = NULL; + gnomeScreensaverCheck = NULL; + xlock = NULL; + + got_XScreensaver = false; + checkDPMSStatus(); + check_xscreensaver_timer_runs = false; + + SCREENSAVER_STATUS = -1; + screen_save_dcop_ref = DCOPRef( "kdesktop", "KScreensaverIface" ); + + check_xscreensaver_timer = new QTimer( this ); + connect( check_xscreensaver_timer, SIGNAL(timeout()), this, SLOT(xscreensaver_ping() )); + + SCREENSAVER_STATUS = checkScreenSaverStatus(); + kdDebugFuncOut(trace); +} + +/*! The default destructor of the class screen */ +screen::~screen() { + kdDebugFuncIn(trace); +} + +/*! +* To enable/disable the KScreensaver/Xscreensaver. +* \param enable true: activate/enable screensaver / false: deactivate/disable screensacer +* \return the result of try to set the screensaver +* \retval true if screensaver set correct +* \retval false if there is a error +*/ +bool screen::setScreenSaver(bool enable){ + kdDebugFuncIn(trace); + + if(SCREENSAVER_STATUS == -1) SCREENSAVER_STATUS = checkScreenSaverStatus(); + if((SCREENSAVER_STATUS == 1) || (SCREENSAVER_STATUS == 0)){ + screen_save_dcop_ref.send( "enable", enable); + kdDebugFuncOut(trace); + return true; + } + + if(SCREENSAVER_STATUS == 11 || SCREENSAVER_STATUS == 10){ + if(enable) { + check_xscreensaver_timer->stop(); + check_xscreensaver_timer_runs = false; + } + else { + check_xscreensaver_timer->start( xScreenSaver_timer_interval ); + check_xscreensaver_timer_runs = true; + } + kdDebugFuncOut(trace); + return true; + } else { + kdDebugFuncOut(trace); + return false; + } +} + + +/* * * * * + * this inspired, partly copied and modified from MPlayer Code (1.05pre) + * START Section + */ +//! to handle information about wrong XWindows +/*! +* This integer represent information about XWindows. +* - got_badwindow == True: if the searched Window is wrong or if there is a problem/error +* - got_badwindow == False: if there is no problem/error +*/ +static int got_badwindow; +//! ErrorHandler +/*! Errorhandler for all X-Server related operations */ +static XErrorHandler defaultHandler; + +//! to find/handle bad XWindows / XSetErrorHandler +/*! +* This function is involved by the search for the window of the Xscreensaver. By this +* function we seperate the BadWindow-error and set \ref got_badwindow if we get a BadWindow. +* For more information take a look at the XServer Documentation! +* \param dpy pointer to the active X-Display +* \param error pointer to XErrorEvent +* \return a info about a window-error +* \retval 0 if the window is a BadWindow as a integer +* \retval n the errorID/XErrorHandler if there is a error != BadWindow +*/ +static int badwindow_handler(Display * dpy, XErrorEvent * error) { + if (error->error_code != BadWindow) + return (*defaultHandler) (dpy, error); + got_badwindow = True; + return 0; +} + +//! to find the X-window of XScreensaver +/*! +* This function search for the X-Window of the active/activated XScreensaver. +* \param dpy pointer to the active X-Display +* \return The WindowID of the active XScreensaver. +* \retval 0 if no Windows/Xscreensaver was found +* \retval n ID of the founded XScreensaver window +*/ +static Window find_xscreensaver_window(Display * dpy) { + kdDebugFuncIn(trace); + + Window root = RootWindowOfScreen(DefaultScreenOfDisplay(dpy)); + Window root2, parent, *kids; + Window retval = 0; + Atom xs_version; + unsigned int i; + unsigned int nkids = 0; + + xs_version = XInternAtom(dpy, "_SCREENSAVER_VERSION", True); + + if (!(xs_version != None && XQueryTree(dpy, root, &root2, &parent, &kids, &nkids) + && kids && nkids)) { + kdDebugFuncOut(trace); + return 0; + } + + defaultHandler = XSetErrorHandler(badwindow_handler); + + for (i = 0; i < nkids; i++) { + Atom type; + int format, status; + unsigned long nitems, bytesafter; + unsigned char *v; + + got_badwindow = False; + status = XGetWindowProperty(dpy, kids[i], xs_version, 0, 200, False, XA_STRING, &type, &format, + &nitems, &bytesafter, &v); + XSync(dpy, False); + if (got_badwindow) status = BadWindow; + + if (status == Success && type != None){ + retval = kids[i]; + break; + } + } + XFree(kids); + XSetErrorHandler(defaultHandler); + kdDebugFuncOut(trace); + return retval; +} + +/*! +* This function is used to ping the XScreensaver. There is no direct way to stop +* the XScreensaver without to kill/stop an restart or modify config-files of the +* current user. \n \n +* We ping the xscreensaver as defined in the QTimer-interval \ref xScreenSaver_timer_interval . +* The value of \ref xScreenSaver_timer_interval is 58 sec at the moment. The intervall must be +* smaller then 1 minute (this is the smallest interval of Xscreensaver a.t.m.). +*/ +void screen::xscreensaver_ping(){ + kdDebugFuncIn(trace); + + if(!got_XScreensaver) { + mDisplay = qt_xdisplay(); + xs_windowid = find_xscreensaver_window(mDisplay); + + Atom deactivate = XInternAtom(mDisplay, "DEACTIVATE", False); + Atom screensaver = XInternAtom(mDisplay, "SCREENSAVER", False); + + ev.xany.type = ClientMessage; + ev.xclient.display = mDisplay; + ev.xclient.window = xs_windowid; + ev.xclient.message_type = screensaver; + ev.xclient.format = 32; + memset(&ev.xclient.data, 0, sizeof(ev.xclient.data)); + ev.xclient.data.l[0] = (long) deactivate; + + if(xs_windowid != 0) got_XScreensaver = true; + } + if(got_XScreensaver){ + if(XSendEvent(mDisplay, xs_windowid, False, 0L, &ev) == 0){ + if(check_xscreensaver_timer->isActive()) { + check_xscreensaver_timer->stop(); + this->got_XScreensaver = false; + } + } + XSync(mDisplay, False); + } + + kdDebugFuncOut(trace); +} +/* + * END Section + * * * * * * */ + +/*! +* Checks if KScreenSaver or XscreenSaver is activated +* \return The result of the check as an integer value. +* \retval 0 KScreensaver is disabled +* \retval 1 KScreensaver is activated +* \retval 10 Xscreensaver is not found or not running +* \retval 11 Xscreensaver is activated +* \retval 99 gnome-screensaver check is running +* \retval -1 else +*/ +int screen::checkScreenSaverStatus() { + kdDebugFuncIn(trace); + + bool get_reply = false; + int kScreenSaver_tmp_status = -1; + int check = -1; + + // check for KScreenSaver + DCOPReply reply = screen_save_dcop_ref.call("isEnabled()"); + if(reply.isValid()){ + if(reply.get(get_reply)){ + if(get_reply) return 1; + /* don't return status her because we must also check if + * XScreensaver is activated !!! + */ + else kScreenSaver_tmp_status = 0; + } + } + // check for XScreensaver + if (got_XScreensaver) return 11; + else if(!got_XScreensaver) { + Display *dpy = qt_xdisplay(); + Window windowid = find_xscreensaver_window(dpy); + if(windowid == 0) { + //Xscreensaver not detected + check_xscreensaver_timer->stop(); + // KScreensaver activ and no XScreensaver found + if(kScreenSaver_tmp_status == 0) return 0; + // no KScreensaver and no XScreensaver found + else check = 10; + } + else return 11; + } + + // check for gnome-screen-saver + if (check == 10) { + delete gnomeScreensaverCheck; + + gnomeScreensaverCheck = new KProcess; + *gnomeScreensaverCheck << "gnome-screensaver-command" << "--query"; + + connect( gnomeScreensaverCheck , SIGNAL(processExited(KProcess *)),SLOT(getGSExited(KProcess *))); + + if(!gnomeScreensaverCheck->start(KProcess::NotifyOnExit)) + { + delete gnomeScreensaverCheck; + gnomeScreensaverCheck = NULL; + return 10; + } + else return 99; + } + + return -1; +} + +/*! + * \b SLOT which called if the call of gnomescreensaver-command exited + * \param gnomecheckcommand the KPocess which called this SLOT + */ +void screen::getGSExited (KProcess *gnomecheckcommand) { + kdDebugFuncIn(trace); + + if (gnomecheckcommand->normalExit()){ + if (gnomecheckcommand->exitStatus() == 1) SCREENSAVER_STATUS = 10; + else if (gnomecheckcommand->exitStatus() == 0) SCREENSAVER_STATUS = 20; + } else { + SCREENSAVER_STATUS = 10; + } + + delete gnomeScreensaverCheck; + gnomeScreensaverCheck=NULL; + + kdDebugFuncOut(trace); + return; +} + +/*! +* This function check if DMPS is activated on the active X-Server. +* \return Integer value with the result of the check +* \retval 1 if DMPS is enabled +* \retval 0 if DMPS is disabled +* \retval -1 if there is a error +*/ +int screen::checkDPMSStatus(){ + kdDebugFuncIn(trace); + + CARD16 state; + BOOL onoff; + int dummy; + + Display *dpy = qt_xdisplay(); + + if (!DPMSQueryExtension(dpy, &dummy, &dummy) || !DPMSCapable(dpy)){ + has_DPMS = false; + kdDebugFuncOut(trace); + return -1; + } + else + has_DPMS = true; + + DPMSInfo(dpy, &state, &onoff); + if(onoff) { + kdDebugFuncOut(trace); + return 1; + } else { + kdDebugFuncOut(trace); + return 0; + } +} + + +/*! +* To set DPMS on X-Server on/off. +* \param enable true: activate/enable DMPS / false: deactivate/disable DPMS +* \return the result of try to set DPMS +* \retval true if DMPS correct set false +* \retval false if fail (DPMS not supported) +* \todo \li check/evaluate for errormessages +* \li check if DPMS-Settings correct set if DPMSEnable(dpy) used +*/ +bool screen::setDPMS( bool enable ){ + kdDebugFuncIn(trace); + + defaultHandler = XSetErrorHandler(badwindow_handler); + + Display *dpy = qt_xdisplay(); + + int dummy; + if (!DPMSQueryExtension(dpy, &dummy, &dummy) || !DPMSCapable(dpy)){ + has_DPMS = false; + XSetErrorHandler(defaultHandler); + kdDebugFuncOut(trace); + return false; + } + + if(enable) DPMSEnable(dpy); + else DPMSDisable(dpy); + + XFlush(dpy); + XSetErrorHandler(defaultHandler); + + kdDebugFuncOut(trace); + return true; +} + +/*! +* This function set the Timeouts for DPMS for the X-Server. +* \param standby_timeout time in seconds to stand-by the display as integer value +* \param suspend_timeout time in seconds to suspend the display as integer value +* \param off_timeout time in seconds to switch off the display as integer value +* \return the result of try to set DPMS-Timeouts +* \retval true if DMPS correct set false +* \retval false if fail (DPMS not supported) +*/ +bool screen::setDPMSTimeouts( int standby_timeout, int suspend_timeout, int off_timeout){ + kdDebugFuncIn(trace); + + //XErrFunc defaultHandler; + defaultHandler = XSetErrorHandler(badwindow_handler); + + Display *dpy = qt_xdisplay(); + + int dummy; + if (!DPMSQueryExtension(dpy, &dummy, &dummy) || !DPMSCapable(dpy)){ + has_DPMS = false; + XSetErrorHandler(defaultHandler); + kdDebugFuncOut(trace); + return false; + } + + DPMSSetTimeouts(dpy, 60 * standby_timeout, 60 * suspend_timeout, 60 * off_timeout); + + XFlush(dpy); + XSetErrorHandler(defaultHandler); + kdDebugFuncOut(trace); + return true; +} + +/*! +* Use this function to lock the screen. This function use automatically the right +* method for KDE or GNOME. +* \return boolean with the result of the operation +* \retval true if the requested method worked +* \retval false if there was a error +*/ +bool screen::lockScreen(){ + kdDebugFuncIn(trace); + + // screensaver status known? + if(SCREENSAVER_STATUS == -1) SCREENSAVER_STATUS = checkScreenSaverStatus(); + + // set lock for KScreensaver + if((SCREENSAVER_STATUS == 1) || (SCREENSAVER_STATUS == 0)){ + DCOPReply reply = screen_save_dcop_ref.call("lock"); + if ( reply.isValid() ) { + return true; + } else { + kdWarning() << "Could not lock KScreensaver, try XScreensaver as fallback." << endl; + goto xscreensaver; + } + } + // set lock for XScreensaver + else if(SCREENSAVER_STATUS == 11){ +xscreensaver: + delete xscreensaver_lock; + + xscreensaver_lock = new KProcess; + *xscreensaver_lock << "xscreensaver-command" << "-lock"; + connect(xscreensaver_lock, SIGNAL(processExited(KProcess*)), + this, SLOT(cleanProcess(KProcess*))); + + bool status = xscreensaver_lock->start(KProcess::DontCare); + if(!status) + { + delete xscreensaver_lock; + xscreensaver_lock = NULL; + } + return status; + } + // lock with gnome-screen-saver + else if(SCREENSAVER_STATUS == 20){ + delete gnomescreensaver_lock; + + gnomescreensaver_lock = new KProcess; + *gnomescreensaver_lock << "gnome-screensaver-command" << "--lock"; + + connect(gnomescreensaver_lock, SIGNAL(processExited(KProcess*)), + this, SLOT(cleanProcess(KProcess*))); + bool status = gnomescreensaver_lock->start(KProcess::DontCare); + if(!status) + { + delete gnomescreensaver_lock; + gnomescreensaver_lock=NULL; + } + return status; + } + // set lock for xlock --> no kscreensaver, no xscreensaver present and + // the check for gnome screensaver is not finished. This should normaly + // not happen, but in this case we use xlock + else if(SCREENSAVER_STATUS == 10 || SCREENSAVER_STATUS == 99){ + delete xlock; + + xlock = new KProcess; + *xlock << "xlock"; //<< "-mode" << "blank"; + connect(xlock, SIGNAL(processExited(KProcess*)), + this, SLOT(cleanProcess(KProcess*))); + bool status = xlock->start(KProcess::DontCare); + if(!status) + { + delete xlock; + xlock = NULL; + } + return status; + } + else return false; +} + +/*! +* Use this function to lock the screen with a specified lock method. +* \param lock_withMethod a QString, which contain the alias for the lock +* command. +* \return boolean with the result of the operation +* \retval true if the requested method worked +* \retval false if there was a error +* \todo check if we should also set blank only if the user would like!!! +*/ +bool screen::lockScreen( QString lock_withMethod ) { + kdDebugFuncIn(trace); + + if (lock_withMethod == "automatic") { + lockScreen(); + return true; + } + else if (lock_withMethod == "xlock") { + delete xlock; + + xlock = new KProcess; + *xlock << "xlock"; + connect(xlock, SIGNAL(processExited(KProcess*)), + this, SLOT(cleanProcess(KProcess*))); + + bool status = xlock->start(KProcess::DontCare); + if(!status) + { + delete xlock; + xlock=NULL; + } + + return status; + } + else if (lock_withMethod == "gnomescreensaver") { + gnomescreensaver_lock = new KProcess; + *gnomescreensaver_lock << "gnome-screensaver-command" << "--lock"; + connect(gnomescreensaver_lock, SIGNAL(processExited(KProcess*)), + this, SLOT(cleanProcess(KProcess*))); + + bool status = gnomescreensaver_lock->start(KProcess::DontCare); + if(!status) + { + delete gnomescreensaver_lock; + gnomescreensaver_lock = NULL; + } + return status; + } + else { + // screensaver status known? + SCREENSAVER_STATUS = checkScreenSaverStatus(); + + if (lock_withMethod == "kscreensaver") { + if((SCREENSAVER_STATUS == 1) || (SCREENSAVER_STATUS == 0)){ + DCOPReply reply = screen_save_dcop_ref.call("lock"); + if ( reply.isValid() ) { + return true; + } else { + kdWarning() << "Could not call lock for KScreensaver, try XScreensaver " + << "as fallback." << endl; + goto xscreensaver; + } + } + else return false; + } + else if (lock_withMethod == "xscreensaver") { + if(SCREENSAVER_STATUS == 11){ +xscreensaver: + delete xscreensaver_lock; + + xscreensaver_lock = new KProcess; + *xscreensaver_lock << "xscreensaver-command" << "-lock"; + connect(xscreensaver_lock, SIGNAL(processExited(KProcess*)), + this, SLOT(cleanProcess(KProcess*))); + + bool status = xscreensaver_lock->start(KProcess::DontCare); + if(!status) + { + delete xscreensaver_lock; + xscreensaver_lock = NULL; + } + return status; + } + else return false; + } + else return false; + } + return false; +} + +/*! +* Use this function to set the screensaver to 'blank only' instead of +* using the in KDE or GNOME set screensaver. +* \todo find a way to set the xscreensaver to 'blank only' +*/ +void screen::blankOnlyScreen( bool blankonly ){ + kdDebugFuncIn(trace); + + if(SCREENSAVER_STATUS == -1) SCREENSAVER_STATUS = checkScreenSaverStatus(); + // set KScreensaver + if((SCREENSAVER_STATUS == 1) || (SCREENSAVER_STATUS == 0)){ + screen_save_dcop_ref.send("setBlankOnly", blankonly); + } + // set XScreensaver + else if(SCREENSAVER_STATUS == 11){ + // implement something !!! + } + + kdDebugFuncOut(trace); +} + +/*! +* Use this function to reset the KDE screensaver/DPMS settings +* \return boolean with the result of the operation +* \retval true if the reset was called +* \retval false if there was a error +*/ +bool screen::resetKDEScreensaver(){ + kdDebugFuncIn(trace); + + if(SCREENSAVER_STATUS == -1) + SCREENSAVER_STATUS = checkScreenSaverStatus(); + + // do this only if the screensaver is not running + if(SCREENSAVER_STATUS == 0){ + DCOPReply reply = screen_save_dcop_ref.call("configure"); + if ( reply.isValid() ) { + kdDebugFuncOut(trace); + return true; + } else { + kdWarning() << "Could not call configure() for the KDE screensaver." << endl; + kdDebugFuncOut(trace); + return false; + } + } else { + kdDebugFuncOut(trace); + return false; + } +} + +/*! +* Use this function to reset the xscreensaver settings +* \return boolean with the result of the operation +* \retval true if the reset was called +* \retval false if there was a error +*/ +bool screen::resetXScreensaver(){ + kdDebugFuncIn(trace); + + if(checkScreenSaverStatus() == 11) { + + delete xscreensaver_reset; + + xscreensaver_reset = new KProcess; + *xscreensaver_reset << "xscreensaver-command" << "-restart"; + connect(xscreensaver_reset, SIGNAL(processExited(KProcess*)), + this, SLOT(cleanProcess(KProcess*))); + + bool status = xscreensaver_reset->start(KProcess::DontCare); + if(!status) + { + delete xscreensaver_reset; + xscreensaver_reset = NULL; + } + kdDebugFuncOut(trace); + return status; + } else { + kdDebugFuncOut(trace); + return false; + } +} + +/*! +* function to call xset commandline tool to force shutdown the display with dpms +*/ +void screen::forceDPMSOff() { + kdDebugFuncIn(trace); + + KProcess *xset = new KProcess; + *xset << "xset" << "dpms" << "force" << "off"; + connect(xset, SIGNAL(processExited(KProcess*)), + this, SLOT(cleanProcess(KProcess*))); + if(!xset->start()) + { + delete xset; + } + + kdDebugFuncOut(trace); +} + +/*! + * function to clean KProcess objects + */ +void screen::cleanProcess(KProcess* proc) +{ + delete proc; + proc = NULL; +} + +/*! +* function to fake a key event for the shift key. Use this to show the login +* passwd dialog after suspend if we locked the screen. +*/ +void screen::fakeShiftKeyEvent() { + kdDebugFuncIn(trace); + + Display *dpy = qt_xdisplay(); + + if (dpy) { + XTestFakeKeyEvent(dpy, 62, 1, 0); + XTestFakeKeyEvent(dpy, 62, 0, 0); + + XFlush(dpy); + } + + kdDebugFuncOut(trace); + return; +} + +#include "screen.moc" diff --git a/src/screen.h b/src/screen.h new file mode 100644 index 0000000..ed6ad17 --- /dev/null +++ b/src/screen.h @@ -0,0 +1,178 @@ +/************************************************************************** +* Copyright (C) 2004-2006 by Danny Kukawka * +* <dkukawka@suse.de>, <danny.kukawka@web.de> * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of version 2 of the GNU General Public License * +* as published by the Free Software Foundation. * +* * +* 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. * +***************************************************************************/ + +#ifndef SCREEN_H +#define SCREEN_H + +/* this is needed to avoid typedef clash with X11/Xmd.h (X11/Xproto.h) + */ +#ifndef QT_CLEAN_NAMESPACE +#define QT_CLEAN_NAMESPACE +#endif + +// KDE Header +#include <dcopref.h> +#include <kprocess.h> +#include <klocale.h> + +// QT Header +#include <qstring.h> +#include <qwidget.h> +//#include <qvector.h> +#include <qtimer.h> +#include <qevent.h> + +// X11 Header +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> + +/*! +* \file screen.h +* \brief Headerfile for screen.cpp and the class \ref screen. +*/ +/*! +* \class screen +* \brief class for all screensaver related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2004 - 2006 +*/ +class screen : public QWidget +{ + Q_OBJECT + +private: + + //! reference to DCOP + /*! + * This is the DCOP-reference to the KScreensaverIface. We use this to send + * commandos to the active KScreensaver. + */ + DCOPRef screen_save_dcop_ref; + //! KProcess to start xlock to lock the screen + KProcess *xlock; + //! KProcess to start xscreensaver with lock command + KProcess *xscreensaver_lock; + //! KProcess to start xscreensaver with restart command + KProcess *xscreensaver_reset; + //! KProcess to start gnome-screen-saver with lock command + KProcess *gnomescreensaver_lock; + //! KProcess to check if gnome-screensaver is running + KProcess *gnomeScreensaverCheck; + + //! contains information about Xscreensaver + /*! + * This boolean represent information if Xscreensaver is active in X. + * \li true: if there is a Xscreensaver + * \li false: if there isn't a Xscreensaver + */ + bool got_XScreensaver; + //! cointains status information about the screensaver + /*! + * The value of this integer represent statusinformation about the + * screensaver (Xscreensaver and KScreensaver): + * \li (value == 0) if KScreensaver is disabled + * \li (value == 1) if KScreensaver is activated + * \li (value == 10) if Xscreensaver is not found or not running + * \li (value == 11) if Xscreensaver is activated + * \li (value == 20) if gnome-screen-saver is available + * \li (value == -1) else + */ + int SCREENSAVER_STATUS; + + //! QTimer - interval + /*! This is the interval to poll the Xscreensaver. The value is 58 sec */ + static const int xScreenSaver_timer_interval = 58000; + //! QTimer to check/ping the Xscreensaver + /*! This is the QTimer to ping the Xscreensaver. The ping-interval is defined + * through \ref xScreenSaver_timer_interval . */ + QTimer *check_xscreensaver_timer; + + //! the active X-Display + /*! Here we store a pointer to the active X-Display of KDE or GNOME */ + Display *mDisplay; + //! Xscreensaver windowsid + /*! The windowid of the active Xscreensaver. */ + Window xs_windowid; + //! XEvent for the Xscreensaver + /*! This XEvent is used so send the commands to Xscreensaver. */ + XEvent ev; + +private slots: + + //! to ping and deactivate the Xscreensaver + void xscreensaver_ping(); + //! to get the return value of gnomescreensaver-command + void getGSExited(KProcess *); + + void cleanProcess(KProcess *); + +public slots: + + //! to fake a keyevent for the login dialog after suspend with lock screen + void fakeShiftKeyEvent(); + +public: + + //! to check if \ref check_xscreensaver_timer is active + /*! + * This boolean contains information about QTimer \ref check_xscreensaver_timer . + * \li true: if the QTtimer is running + * \li false: if the QTimer isn't active/ isn't in use + */ + bool check_xscreensaver_timer_runs; + //! info about DPMS on the machine + /*! + * This variable represent the DPMS status of the machine. + * \li true: if the machine is DPMSable + * \li false: if the machine isn't DPMSable or DPMS is basic deativated + */ + bool has_DPMS; + + //! blank only the screen + void blankOnlyScreen( bool ); + //! reset KDE screensaver settings + bool resetKDEScreensaver(); + //! reset XScreensaver settings + bool resetXScreensaver(); + //! force DPMS off for display + void forceDPMSOff(); + + //! lock the screen + bool lockScreen(); + //! lock the screen with a give alias for the lock method + bool lockScreen( QString ); + //! to set DPMS on/off + bool setDPMS( bool ); + //! to set the DPMS Timeouts + bool setDPMSTimeouts( int, int, int ); + //! to activate/disable the Screensaver + bool setScreenSaver( bool ); + + //! for check the status of the screensaver + int checkScreenSaverStatus(); + //! for check the actual status of DPMS on the machine + int checkDPMSStatus(); + + //! default constructor + screen(); + //! default destructor + virtual ~screen(); +}; +#endif diff --git a/src/settings.cpp b/src/settings.cpp new file mode 100644 index 0000000..342bb81 --- /dev/null +++ b/src/settings.cpp @@ -0,0 +1,381 @@ +/*************************************************************************** + * Copyright (C) 2005 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! + * \file settings.cpp + * \brief In this file can be found the settings ( read ) related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2005 + */ + +// KDE Header +#include <klocale.h> + +// QT Header + +// own headers +#include "settings.h" + +/*! This is the default constructor of the class Settings. */ +Settings::Settings() +{ + kconfig = new KConfig("kpowersaverc", true ); + kde = new KDE_Settings(); + load_kde(); + load_general_settings(); +} + +/*! This is the default destructor of the class Settings. */ +Settings::~Settings() +{ + delete kconfig; + delete kde; +} + + +/*! + * Loads the scheme settings from kpowersaverc and fills the related variables. + * \param schemeName QString with the name (realname not i18n() version) of the + * scheme which setting should be load. If the scheme could not + * be loaded, this function try to load "default-scheme" + * \return the result of the load + * \retval true if the settings could be loaded + * \retval false if there was no group named like schemeName or named "default-scheme" + */ +bool Settings::load_scheme_settings(QString schemeName){ + + kconfig->reparseConfiguration(); + bool setToDefault = false; + + if( schemeName == "Performance" || schemeName == i18n("Performance")) + schemeName = "Performance"; + else if( schemeName == "Powersave" || schemeName == i18n("Powersave")) + schemeName = "Powersave"; + else if( schemeName == "Presentation" || schemeName == i18n("Presentation")) + schemeName = "Presentation"; + else if( schemeName == "Acoustic" || schemeName == i18n("Acoustic")) + schemeName = "Acoustic"; + + if(kconfig->hasGroup(schemeName) || kconfig->hasGroup("default-scheme") ){ + if(kconfig->hasGroup(schemeName)) kconfig->setGroup(schemeName); + else { + // fallback to 'default-scheme' + kconfig->setGroup("default-scheme"); + schemeName = "default-scheme"; + setToDefault = true; + } + currentScheme = schemeName; + + specSsSettings = kconfig->readBoolEntry("specSsSettings",false); + disableSs = kconfig->readBoolEntry("disableSs",false); + blankSs = kconfig->readBoolEntry("blankSs",false); + specPMSettings = kconfig->readBoolEntry("specPMSettings",false); + disableDPMS = kconfig->readBoolEntry("disableDPMS",false); + + int i_standby = kconfig->readNumEntry("standbyAfter", -1); + if (i_standby >= 0) standbyAfter = i_standby; + else { + kconfig->setGroup("default-scheme"); + i_standby = kconfig->readNumEntry("standbyAfter", -1); + if(i_standby >= 0) { + standbyAfter = i_standby; + } + else standbyAfter = 0; + // reset the group + kconfig->setGroup(schemeName); + } + + int i_suspend = kconfig->readNumEntry("suspendAfter", -1); + if (i_suspend >= 0) suspendAfter = i_suspend; + else { + kconfig->setGroup("default-scheme"); + i_suspend = kconfig->readNumEntry("suspendAfter", -1); + if(i_suspend >= 0) { + suspendAfter = i_suspend; + } + else suspendAfter = 0; + // reset the group + kconfig->setGroup(schemeName); + } + + int i_poweroff = kconfig->readNumEntry("powerOffAfter", -1); + if (i_poweroff >= 0) powerOffAfter = i_poweroff; + else { + kconfig->setGroup("default-scheme"); + i_poweroff = kconfig->readNumEntry("powerOffAfter", -1); + if(i_poweroff >= 0) { + powerOffAfter = i_poweroff; + } + else powerOffAfter = 0; + // reset the group + kconfig->setGroup(schemeName); + } + + brightness = kconfig->readBoolEntry("enableBrightness",false); + brightnessValue = kconfig->readNumEntry("brightnessPercent", -1); + if (brightnessValue == -1) { + kconfig->setGroup("default-scheme"); + brightnessValue = kconfig->readNumEntry("brightnessPercent", 100); + // reset the group + kconfig->setGroup(schemeName); + } + + int i_autoInactiveActionAfter = kconfig->readNumEntry("autoInactiveActionAfter", -1); + if (i_autoInactiveActionAfter >= 0) autoInactiveActionAfter = i_autoInactiveActionAfter; + else { + kconfig->setGroup("default-scheme"); + i_autoInactiveActionAfter = kconfig->readNumEntry("autoInactiveActionAfter", -1); + if(i_autoInactiveActionAfter >= 0) { + autoInactiveActionAfter = i_autoInactiveActionAfter; + } + else autoInactiveActionAfter = 0; + // reset the group + kconfig->setGroup(schemeName); + } + + QString _autoInactiveAction = kconfig->readEntry("autoInactiveAction", "NULL"); + if( _autoInactiveAction != "NULL") { + autoInactiveAction = _autoInactiveAction; + } + else { + kconfig->setGroup("default-scheme"); + _autoInactiveAction = kconfig->readEntry("autoInactiveAction", "NULL"); + if(_autoInactiveAction != "NULL") autoInactiveAction = _autoInactiveAction; + else autoInactiveAction = "_NONE_"; + // reset the group + kconfig->setGroup(schemeName); + } + + autoSuspend = kconfig->readBoolEntry("autoSuspend",false); + autoInactiveSBlistEnabled = kconfig->readBoolEntry("autoInactiveSchemeBlacklistEnabled",false); + autoInactiveSBlist = kconfig->readListEntry("autoInactiveSchemeBlacklist", ','); + + int i_autoDimmAfter = kconfig->readNumEntry("autoDimmAfter", -1); + if (i_autoDimmAfter >= 0) autoDimmAfter = i_autoDimmAfter; + else { + kconfig->setGroup("default-scheme"); + i_autoDimmAfter = kconfig->readNumEntry("autoDimmAfter", -1); + if(i_autoDimmAfter >= 0) { + autoDimmAfter = i_autoDimmAfter; + } + else autoDimmAfter = 0; + // reset the group + kconfig->setGroup(schemeName); + } + + int i_autoDimmTo = kconfig->readNumEntry("autoDimmTo", -1); + if (i_autoDimmTo >= 0) autoDimmTo = i_autoDimmTo; + else { + kconfig->setGroup("default-scheme"); + i_autoDimmTo = kconfig->readNumEntry("autoDimmAfter", -1); + if(i_autoDimmTo >= 0) { + autoDimmTo = i_autoDimmTo; + } + else autoDimmTo = 0; + // reset the group + kconfig->setGroup(schemeName); + } + + autoDimm = kconfig->readBoolEntry("autoDimm",false); + autoDimmSBlistEnabled = kconfig->readBoolEntry("autoDimmSchemeBlacklistEnabled",false); + autoDimmSBlist = kconfig->readListEntry("autoDimmSchemeBlacklist", ','); + + disableNotifications = kconfig->readBoolEntry("disableNotifications",false); + + QString _cpufreqpolicy = kconfig->readEntry("cpuFreqPolicy", "NULL"); + if( _cpufreqpolicy == "NULL") { + kconfig->setGroup("default-scheme"); + _cpufreqpolicy = kconfig->readEntry("cpuFreqPolicy", "NULL"); + // reset the group + kconfig->setGroup(schemeName); + } + if (_cpufreqpolicy.startsWith("DYNAMIC")) { + cpuFreqPolicy = DYNAMIC; + } else if (_cpufreqpolicy.startsWith("PERFORMANCE")) { + cpuFreqPolicy = PERFORMANCE; + } else if (_cpufreqpolicy.startsWith("POWERSAVE")) { + cpuFreqPolicy = POWERSAVE; + } else { + // set as default + cpuFreqPolicy = DYNAMIC; + } + + cpuFreqDynamicPerformance = kconfig->readNumEntry("cpuFreqDynamicPerformance", -1); + if( cpuFreqDynamicPerformance == -1) { + kconfig->setGroup("default-scheme"); + cpuFreqDynamicPerformance = kconfig->readNumEntry("cpuFreqDynamicPerformance", 51); + // reset the group + kconfig->setGroup(schemeName); + } + + return true; + } + else return false; +} + + +/*! + * Loads the general settings from kpowersaverc and fills the related variables. + * \return the result of the load + * \retval true if the settings could be loaded + * \retval false if there was no group named 'General' + */ +bool Settings::load_general_settings(){ + + kconfig->reparseConfiguration(); + + if(kconfig->hasGroup("General")) { + kconfig->setGroup("General"); + + lockOnSuspend = kconfig->readBoolEntry("lockOnSuspend",true); + lockOnLidClose = kconfig->readBoolEntry("lockOnLidClose",true); + autostart = kconfig->readBoolEntry("Autostart",false); + autostartNeverAsk = kconfig->readBoolEntry("AutostartNeverAsk",false); + psMsgAsPassivePopup = kconfig->readBoolEntry("psMsgAsPassivePopup",false); + forceDpmsOffOnLidClose = kconfig->readBoolEntry("forceDpmsOffOnLidClose",false); + unmountExternalOnSuspend = kconfig->readBoolEntry("unmountExternalOnSuspend",true); + callSetPowerSaveOnAC = kconfig->readBoolEntry("callSetPowerSaveOnAC",true); + + lockmethod = kconfig->readEntry("lockMethod", "NULL"); + if(lockmethod == "NULL") lockmethod = "automatic"; + + autoInactiveGBlist = kconfig->readListEntry("autoInactiveBlacklist", ','); + autoDimmGBlist = kconfig->readListEntry("autoDimmBlacklist", ','); + + autoSuspendCountdown = kconfig->readBoolEntry("AutoSuspendCountdown", false); + autoSuspendCountdownTimeout = kconfig->readNumEntry("AutoSuspendCountdownTimeOut", 30); + + timeToFakeKeyAfterLock = kconfig->readNumEntry("timeToFakeKeyAfterLock", 5000); + + schemes = kconfig->readListEntry("schemes", ','); + ac_scheme = kconfig->readEntry("ac_scheme", "Performance"); + battery_scheme = kconfig->readEntry("battery_scheme", "Powersave"); + + // Read battery levels and related actions + batteryWarningLevel = kconfig->readNumEntry("batteryWarning", 12); + batteryLowLevel = kconfig->readNumEntry("batteryLow", 7); + batteryCriticalLevel = kconfig->readNumEntry("batteryCritical", 2); + + batteryWarningLevelAction = mapActionToType(kconfig->readEntry("batteryWarningAction","")); + if (batteryWarningLevelAction == BRIGHTNESS) { + batteryWarningLevelActionValue = kconfig->readNumEntry("batteryWarningActionValue", -1); + } + batteryLowLevelAction = mapActionToType(kconfig->readEntry("batteryLowAction","")); + if (batteryLowLevelAction == BRIGHTNESS) { + batteryLowLevelActionValue = kconfig->readNumEntry("batteryLowActionValue", -1); + } + batteryCriticalLevelAction = mapActionToType(kconfig->readEntry("batteryCriticalAction","")); + if (batteryCriticalLevelAction == BRIGHTNESS) { + batteryCriticalLevelActionValue = kconfig->readNumEntry("batteryCriticalActionValue", -1); + } + + lidcloseAction = mapActionToType(kconfig->readEntry("ActionOnLidClose","")); + if (lidcloseAction == BRIGHTNESS) { + lidcloseActionValue = kconfig->readNumEntry("ActionOnLidCloseValue", -1); + } + // avoid logout dialog since this make no sence with lidclose + if (lidcloseAction == LOGOUT_DIALOG) { + lidcloseAction = NONE; + } + + powerButtonAction = mapActionToType(kconfig->readEntry("ActionOnPowerButton","")); + if (powerButtonAction == BRIGHTNESS) { + powerButtonActionValue = kconfig->readNumEntry("ActionOnPowerButtonValue", -1); + } + + sleepButtonAction = mapActionToType(kconfig->readEntry("ActionOnSleepButton","")); + if ((sleepButtonAction != GO_SUSPEND2RAM) && (sleepButtonAction != GO_SUSPEND2DISK)) { + sleepButtonAction = NONE; + } + + s2diskButtonAction = mapActionToType(kconfig->readEntry("ActionOnS2DiskButton","")); + if ((s2diskButtonAction != GO_SUSPEND2RAM) && (s2diskButtonAction != GO_SUSPEND2DISK)) { + s2diskButtonAction = NONE; + } + + return true; + } + else return false; +} + + +/*! + * Map the string value from the config file to the type from \ref action + * \param _action a QString to map + * \return a integer value with the result of the mapping as \ref action + */ +action Settings::mapActionToType (QString _action) { + + if (_action.isEmpty()) { + return NONE; + } else if (_action.startsWith("SHUTDOWN")) { + return GO_SHUTDOWN; + } else if (_action.startsWith("LOGOUT_DIALOG")) { + return LOGOUT_DIALOG; + } else if (_action.startsWith("SUSPEND2DISK")) { + return GO_SUSPEND2DISK; + } else if (_action.startsWith("SUSPEND2RAM")) { + return GO_SUSPEND2RAM; + } else if (_action.startsWith("CPUFREQ_POWERSAVE")) { + return CPUFREQ_POWERSAVE; + } else if (_action.startsWith("CPUFREQ_DYNAMIC")) { + return CPUFREQ_DYNAMIC; + } else if (_action.startsWith("CPUFREQ_PERFORMANCE")) { + return CPUFREQ_PERFORMANCE; + } else if (_action.startsWith("BRIGHTNESS")) { + return BRIGHTNESS; + } else { + return UNKNOWN_ACTION; + } +} + +/*! + * Loads the default KDE Settings from the different configfiles and store + * them to a \ref KDE_Settings 'object'. + * \retval true if the settings could be loaded + * \retval false if there was a error/problem + */ +void Settings::load_kde(){ + KConfig *_kconfig = new KConfig("kcmdisplayrc", true ); + + /* KDE settings [DisplayEnergy] from kcmdisplayrc */ + if(_kconfig->hasGroup("DisplayEnergy")) { + _kconfig->setGroup("DisplayEnergy"); + kde->displayEnergySaving = _kconfig->readBoolEntry("displayEnergySaving", true); + kde->displayStandby = _kconfig->readNumEntry("displayStandby", 7); + kde->displaySuspend = _kconfig->readNumEntry("displaySuspend", 13); + kde->displayPowerOff = _kconfig->readNumEntry("displayPowerOff", 19); + } + delete _kconfig; + _kconfig = new KConfig("kdesktoprc", true ); + /* KDE settings [ScreenSaver] from kdesktoprc */ + if(_kconfig->hasGroup("ScreenSaver")) { + _kconfig->setGroup("ScreenSaver"); + kde->enabled = _kconfig->readBoolEntry("Enabled", true); + kde->lock = _kconfig->readBoolEntry("Lock", true); + + QString _savername = _kconfig->readEntry("Saver", "KBlankscreen.desktop"); + if (_savername.startsWith("KBlankscreen.desktop")) + kde->blanked = true; + else + kde->blanked = false; + } + delete _kconfig; +} + diff --git a/src/settings.h b/src/settings.h new file mode 100644 index 0000000..2cf589e --- /dev/null +++ b/src/settings.h @@ -0,0 +1,496 @@ +/*************************************************************************** + * Copyright (C) 2005 by Danny Kukawka * + * <dkukawka@suse.de>, <danny.kukawka@web.de> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! +* \file settings.h +* \brief Headerfile for settings.cpp and the class \ref Settings. +*/ + +#ifndef SETTINGS_H +#define SETTINGS_H + +// KDE - Header +#include <kconfig.h> + +// QT - Header +#include <qstring.h> +#include <qstringlist.h> + +// own headers +#include "hardware.h" + +enum action{ + UNKNOWN_ACTION = -2, + NONE = -1, + GO_SHUTDOWN, + LOGOUT_DIALOG, + GO_SUSPEND2RAM, + GO_SUSPEND2DISK, + SWITCH_SCHEME, + BRIGHTNESS, + CPUFREQ_POWERSAVE, + CPUFREQ_DYNAMIC, + CPUFREQ_PERFORMANCE +}; + +/*! +* \class KDE_Settings +* \brief class/object for the KDE default settings +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2005 +*/ +class KDE_Settings { + +public: + /* KDE settings [DisplayEnergy] */ + //! if KDE enable DPMS + /*! + * This boolean tells if KDE enable DPMS by global settings. + * \li true: if KDE enable DPMS + * \li false: if not + */ + bool displayEnergySaving; + //! time for DPMS standby + /*! + * This integer represent the time in minutes after which the + * display should do to stand-by. + */ + int displayStandby; + //! time for DPMS suspend + /*! + * This integer represent the time in minutes after which the + * display should suspend. + */ + int displaySuspend; + //! time for DPMS power-off + /*! + * This integer represent the time in minutes after which the + * display should power off. + */ + int displayPowerOff; + + /* KDE settings [ScreenSaver] */ + //! if the KDE screensaver is enabled + /*! + * This boolean tells if the KDE screensaver is enabled. + * \li true: if screensaver enabled + * \li false: if screensaver disabled + */ + bool enabled; + //! if KDE should lock the screen + /*! + * This boolean tells if KDE lock the screen. + * \li true: if lock the screen + * \li false: if not + */ + bool lock; + + //! if KDE already only blank the screensaver + /*! + * This boolean tells if KDE already only use the blank screensaver + * \li true: if blank screensaver + * \li false: if else + */ + bool blanked; + +}; + +/*! +* \class Settings +* \brief class for the Settings ( read ) related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2005 +*/ +class Settings{ + +public: + + //! default constructor + Settings(); + //! default destructor + virtual ~Settings(); + + //! a instance of the KDE global settings. + KDE_Settings *kde; + + /* START ************************** General settings *******************************/ + //! name of the default "onAC" scheme + QString ac_scheme; + //! name of the default "on Battery" scheme + QString battery_scheme; + //! a list with the names of the currently available schemes. + /*! + * List with the names of the currently configured schemes. The name of the + * schemes are the same as we use for the related selection in the configure file. + * Note: Be sure that the name for the default schemes is not translated !!! + */ + QStringList schemes; + + //! the name of the lock method + /*! + * This QString contains a alias to the selected method for lock screen. Possible values: + * \li automatic for automatically selected (sequence: kscreensaver, xscreensaver, xlock) + * \li kscreensaver for KDE KScreensaver + * \li xscreensaver for XScreensaver (default used on GNOME) + * \li xlock for xlock + */ + QString lockmethod; + + //! if the messages from powersave should popup as Kpassivepopup + /*! + * This boolean tells if the messages from powersave should be displayed + * as KPassivePopup or as KMessageBox::error + * \li true: if use KPassivePopup + * \li false: if not + */ + bool psMsgAsPassivePopup; + + //! if the screen should be locked on suspend + /*! + * This boolean tells if the screen should be locked befor a suspend or standby. + * \li true: if the screen should be locked + * \li false: if not lock the screen + */ + bool lockOnSuspend; + //! if the screen should be locked on 'lid close' event + /*! + * This boolean tells if the screen should be locked on a 'Lid close' event. + * \li true: if the screen should be locked + * \li false: if not lock the screen + */ + bool lockOnLidClose; + //! if kpowersave starts on login + /*! + * This boolean tells if kpowersave should be start automatically on userlogin. + * The value could be changed trough the configuration dialog and if the user + * stop kpowersave. + * \li true: if autostart + * \li false: if not start on login + */ + bool autostart; + //! if kpowersave ask for the user for autostart + /*! + * This boolean tells if kpowersave ask for autostart settings if user stop kpowersave. + * \li true: if ask on stop + * \li false: if never ask + */ + bool autostartNeverAsk; + //! if kpowersave should force DPMS shutdown for display for lidclose + /*! + * This boolean tells if kpowersave should force dpms shutdown for the display if a + * lidclose event was recieved + * \li true: if shutdown display + * \li false: if not + */ + bool forceDpmsOffOnLidClose; + //! if kpowersave should call SetPowerSave() on HAL + /*! + * This boolean tells if kpowersave should call SetPowerSave on HAL depending + * on the AC state. + * \li true: if should call + * \li false: if not + */ + bool callSetPowerSaveOnAC; + + //! time after resume to fake keyevent + /*! + * This integere contains the time after wich kpowersave should fake a keyevent + * to show the login dialog if the desktop was locked on suspend. Value is in msec. + */ + int timeToFakeKeyAfterLock; + + //! percentag value of battery level for warning state + /*! + * This integer represent the remaining percentag of the battery + * where we reach the battery warning level. This is a value between 0 and 100. + */ + int batteryWarningLevel; + //! percentag value of battery level for low state + /*! + * This integer represent the remaining percentag of the battery + * where we reach the battery low level. This is a value between 0 and 100 and + * should be lower than \ref batteryWarningLevel and higher than \ref batteryCriticalLevel + */ + int batteryLowLevel; + //! percentag value of battery level for critical state + /*! + * This integer represent the remaining percentag of the battery + * where we reach the battery critical level. This is a value between 0 and 100 and + * should be lower than \ref batteryLowLevel and higher than 0 + */ + int batteryCriticalLevel; + //! the action that should be called if the warning level is reached + action batteryWarningLevelAction; + //! to \ref batteryWarningLevelAction related value + int batteryWarningLevelActionValue; + //! the action that should be called if the low level is reached + action batteryLowLevelAction; + //! to \ref batteryLowLevelAction related value + int batteryLowLevelActionValue; + //! the action that should be called if the critical level is reached + action batteryCriticalLevelAction; + //! to \ref batteryCriticalLevelAction related value + int batteryCriticalLevelActionValue; + + //! the action that should be called if the lid closed + action lidcloseAction; + //! to \ref lidcloseAction related value + int lidcloseActionValue; + + //! the action that should be called if the power button get pressed + action powerButtonAction; + //! to \ref powerButtonAction related value + int powerButtonActionValue; + + //! the action that should be called if the suspend2ram/sleep button get pressed + action sleepButtonAction; + //! the action that should be called if the suspend2disk button get pressed + action s2diskButtonAction; + + /* END ************************** General settings *******************************/ + /* START ************************ Scheme settings and values ***********************/ + + //! name of the scheme representing the current settings + QString currentScheme; + + // ---------- Screensaver/DPMS section ------------ // + //! if kpowersave use own screensaver settings + /*! + * This boolean represent kpowersave userspecific screensaver settings. If kpowersave + * use own screensaver settings the KDE or GNOME settings are overwritten. + * \li true: if kpowersave use own settings + * \li false: if kpowersave don't change any screensaver settings + */ + bool specSsSettings; + //! if kpowersave should disable the screensaver + /*! + * This boolean tells if kpowersave should disable the screensaver. + * \li true: if kpowersave should disable the screensaver + * \li false: if not + */ + bool disableSs; + //! if kpowersave should blank only the screen + /*! + * This boolean tells if kpowersave should blank only the screen instead of + * using the global selected KDE or GNOME screensaver. + * \li true: if kpowersave should blank only the screen + * \li false: if not and don't change anything + */ + bool blankSs; + //! if kpowersave use own DPMS settings + /*! + * This boolean tells if kpowersave should use own userspecific settings for + * Display PowerManagement Settings. If this value is true kpowersave overwritte + * the KDE or GNOME global settings. + * \li true: if kpowersave use own DPMS settings + * \li false: if kpowersave don't change DPMS settings + */ + bool specPMSettings; + //! if kpowersave should disable DPMS + /*! + * This boolean tells if kpowersave should disable DPMS. If this is used, + * kpowersave overwrite the KDE or GNOME global settings. + * \li true: if kpowersave should disable dpms + * \li false: if not + */ + bool disableDPMS; + //! time for DPMS standby + /*! + * This integer represent the time in minutes after which the + * display should do to stand-by. + */ + int standbyAfter; + //! time for DPMS suspend + /*! + * This integer represent the time in minutes after which the + * display should suspend. + */ + int suspendAfter; + //! time for DPMS power-off + /*! + * This integer represent the time in minutes after which the + * display should power off. + */ + int powerOffAfter; + + // ------------ Brightness section ---------------- // + //! if brightness is enabled for the current scheme + /*! + * This boolean tells if brightness is enabled for the + * current scheme + * \li true: if brightness is enabled + * \li false: if not + */ + bool brightness; + //! the value for the brighness + /*! + * This integer represent the value to which the brigthness + * should be set. This value is in percentage. + */ + int brightnessValue; + + // ------------ Autosuspend section ---------------- // + //! if autosuspend is enabled for the current scheme + /*! + * This boolean tells if autosuspend is enabled for the + * current scheme + * \li true: if autosuspend is enabled + * \li false: if not + */ + bool autoSuspend; + //! if scheme specific blacklist is enabled + /*! + * This boolean tells if a scheme specific blacklist + * ( autoInactiveSchemeBlacklist ) should be used. + * \li true: if use scheme specific blacklist + * \li false: if not + */ + bool autoInactiveSBlistEnabled; + //! time of user inactivity to execute a defined action + /*! + * This integer represent the time in minutes after which kpowersave + * should execute a specific through \ref autoInactiveAction defined + * action. + */ + int autoInactiveActionAfter; + //! action which execute after a defined time of inactivity + /*! + * This QString contains the action/command which should be execute + * after a trough \ref autoInactiveActionAfter defined time. If nothing + * should happens this QString is empty or '_NONE_' + */ + QString autoInactiveAction; + //! general list with running programs which prevent the autosuspend + /*! + * This QStringList contains names of programs which prevent, if one of + * them is running/active the autossuspend. + */ + QStringList autoInactiveGBlist; + //! scheme list with running programs which prevent the autosuspend + /*! + * This QStringList contains names of programs which prevent, if one of + * them is running/active the autossuspend. + */ + QStringList autoInactiveSBlist; + + // ------ Autosuspend countdown dialog section -------- // + //! if KPowersave should display a dialog with a warning for autosuspend + /*! + * This boolean tells if KPowersave should show a warning dialog + * with a countdown before call the autosuspend. + * \li true: if show dialog + * \li false: if not + */ + bool autoSuspendCountdown; + //! how long the autosuspend warn dialog should be shown + /*! + * This integer represent the time in seconds how long the autosuspend + * warning dialog should be shown. This time get stripped from + * \ref autoInactiveActionAfter to be sure the suspend get called within + * the expected time. + */ + int autoSuspendCountdownTimeout; + + // -------------- Autodimm section ------------------- // + //! if autodimm is enabled for the current scheme + /*! + * This boolean tells if autodimm is enabled for the current scheme + * \li true: if autosuspend is enabled + * \li false: if not + */ + bool autoDimm; + //! if a scheme specific autodimm blacklist is enabled + /*! + * This boolean tells if a scheme specific autdimm blacklist + * ( autoDimmSBlist ) should be used. + * \li true: if use scheme specific blacklist + * \li false: if not + */ + bool autoDimmSBlistEnabled; + //! time of user inactivity to dimm the display + /*! + * This integer represent the time in minutes after which kpowersave + * should dimm the display to the level defined by \ref autoDimmTo . + */ + int autoDimmAfter; + //! percentage to which the display should dimmed to + /*! + * This integer represent the brightness percentage to which the + * display should get dimmed if the user is the via \ref autoDimmAfter + * defined time inactivit; + */ + int autoDimmTo; + //! general list with running programs which prevent the autodimm + /*! + * This QStringList contains names of programs which prevent, if one of + * them is running/active the autodimm of the display panel. + */ + QStringList autoDimmGBlist; + //! scheme specific list with running programs which prevent the autodimm + /*! + * This QStringList contains names of programs which prevent, if one of + * them is running/active the autodimm of the display panel. This list is + * scheme specific. + */ + QStringList autoDimmSBlist; + + + // ------------ CPU Frequency section ---------------- // + //! represent the CPU Frequency policy to set + cpufreq_type cpuFreqPolicy; + //! represent the performance level (how triggerhappy) for dynamic cpu freq policy + int cpuFreqDynamicPerformance; + + // --------------- misc section -------------------- // + //! if scheme disabled notifications + /*! + * This boolean tells if a scheme should disable notifications. + * \li true: if disable notifications + * \li false: if not + */ + bool disableNotifications; + + //! if umount/remount external volumes on suspend + /*! + * This boolean tells if KPowersave should umount external partitions + * before suspend and remount them after resume. + * \li true: if umount/remount + * \li false: if not + */ + bool unmountExternalOnSuspend; + + /* END ************************ Scheme settings and values ******************************/ + + /******************* Functions ********************/ + //! to load the general settings + bool load_general_settings(); + //! to load the global KDE settings + void load_kde(); + //! to load settings of a specific scheme + bool load_scheme_settings(QString); + +private: + + //! configuration of kpowersave + KConfig *kconfig; + + //! to map a battery action string to the related type + action mapActionToType (QString _action); +}; +#endif diff --git a/src/suspend_Dialog.ui b/src/suspend_Dialog.ui new file mode 100644 index 0000000..b825f06 --- /dev/null +++ b/src/suspend_Dialog.ui @@ -0,0 +1,102 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>suspend_Dialog</class> +<widget class="QDialog"> + <property name="name"> + <cstring>suspend_Dialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>300</width> + <height>90</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>90</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>300</width> + <height>90</height> + </size> + </property> + <widget class="QProgressBar"> + <property name="name"> + <cstring>progressBar</cstring> + </property> + <property name="geometry"> + <rect> + <x>70</x> + <y>21</y> + <width>221</width> + <height>22</height> + </rect> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>message</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>60</y> + <width>280</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>iconPixmap</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>48</width> + <height>48</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + </widget> +</widget> +<images> + <image name="image0"> + <data format="XPM.GZ" length="2304">789c8593c9721a311086ef3cc5947573a5dacc303043a57230b6f1beef4ee530128bc1069bcd5b2aef9e5f52b702d855410cf0a9b7bf5b626d35ba39398c56d74a936931ed99c8dc17e368b5351b0cde7ffefaf1bbb4922411de59354a56be9556681c994895ddcbf12c70eeb8c19cb27d12d8d955c7711efc47cc6ca7a970ece2559739e77c3781bdff85b0f7a71d66c3fecf81bdff8be7b8ccfe75cb71b96c98ef3cc7a27f37b08fbf1266ff3eb3e879779c076e0ab3ff03b3e88985d95eb69cd42b329f4761b6f798a57ed572250efcc12cf56acc92ffd2732af932c775b03f9f4238f1f637cb699c72bc3281bdbe7bcbd5a456653e715c04ce99eb5c6f10d8db9f84b9de3a738bede7c2deae7cbd228bd99e58ae2562a7d47316b37f8bb9caac1c17b9c46f0973fc2db3e8df6716fd1b96b34a883f6516ff0ab3f4776839d745c1f98f2cd7d3c07b81eb8ebbcc6dd64b9e75c2fe078e8d663b5d5b2e52dde67a9bc21cdff36c12d63f0cecfd5bc29c6f9bb9c6f74f0973bc0eecedafc21c7fc65c707c4798ef4fdbb191fa4a0b73fc31b3d433817d3e89977a0533e73f9d06ce3d93a282d4fcb73ccbfbbedf85a5977861f9fa4bb93496a116b53fd798cbdfe1dc5dbaa71ef5e9811e69005aa839af1f11437aa2671ad1982678a634a317c4bc7ea95fc3fbcd79cee81d153e5063e2f80d96aff4af5303b9fbb4419bd0afd1c11635113d428d3658f46fb3ee1df8efd21ee77aa57d3aa043c48fa1f1888e17f41b3a419e199d22dad019f6cee9822e5169cbf5f3f4497f0fbb57748daeb79d36eb7543b788b8c3aff2d27c0ce637418c71bfd7e16975af439546e7638ad14d27e4b7937cc0ee87d36dbdc7e8654c899b5b0f99faf6f4e6f2b7713a53ecb6a802dd13e4f64f0a3d764655d273fa35340fb03b41779b5443fe017237dcca506744f9bff9b8b32d30cf3a229a98e0266ad83b94baf3b027b6a3e8d3fd39c644ed79f695822a5bf34015dc47e6e2b717ee8f565a19d7a93de30f74d9740a6d8d866a7dca8fa5dad0fd8c8899bf71aa8333cfe0ddc5ccf457f71f73eae22c7b98f73b6632806ef4a1eedd348ba5fbc97da81e3e87f018867d7916ef7f31f75feab86f1df6cd57faffbf56fe7c2ffd0519fbee77</data> + </image> +</images> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/suspenddialog.cpp b/src/suspenddialog.cpp new file mode 100644 index 0000000..cb40a74 --- /dev/null +++ b/src/suspenddialog.cpp @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright (C) 2005 by Danny Kukawka * + * danny.kukawka@web.de, dkukawka@suse.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! + * \file suspenddialog.cpp + * \brief In this file can be found the suspend dialog related code. + * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> + * \date 2005 + */ + + // KDE - Headers + #include <klocale.h> + #include <kiconloader.h> + + // QT - Headers + #include <qdialog.h> + #include <qlabel.h> + #include <qstring.h> + #include <qpixmap.h> + #include <qprogressbar.h> + + #include "suspenddialog.h" + +/*! This is the default constructor of the class. */ +suspendDialog::suspendDialog(QWidget *parent, const char *name) + :suspend_Dialog(parent, name, true, Qt::WStyle_StaysOnTop | Qt::WDestructiveClose ) +{ + this->setIcon(SmallIcon("kpowersave", QIconSet::Automatic)); +} + +/*! This is the default destructor of the class. */ +suspendDialog::~suspendDialog() +{ + +} + +/*! + * This used to set Icon/pixmap for the dialog. + * \param type QString with the type of the current suspend + * to set the pixmap in the dialog + */ +void suspendDialog::setPixmap( QString type ) +{ + QPixmap pixmap = 0; + if(type.startsWith("suspend2disk")){// || type.startsWith("NULL")) { + pixmap = KGlobal::iconLoader()->loadIcon("suspend_to_disk", KIcon::NoGroup, KIcon::SizeLarge); + } else if (type.startsWith("suspend2ram")) { + pixmap = KGlobal::iconLoader()->loadIcon("suspend_to_ram", KIcon::NoGroup, KIcon::SizeLarge); + } else if (type.startsWith("standby")) { + pixmap = KGlobal::iconLoader()->loadIcon("stand_by", KIcon::NoGroup, KIcon::SizeLarge); + } else { + pixmap = KGlobal::iconLoader()->loadIcon("kpowersave", KIcon::NoGroup, KIcon::SizeLarge); + } + setCaption(i18n("Preparing Suspend...")); + iconPixmap->setPixmap( pixmap ); +} + +/*! + * This used to set the values of progressbar for the dialog. + * \param percent integer value with current progress stauts of suspend + */ +void suspendDialog::setProgressbar( int percent ) +{ + progressBar->setPercentageVisible(true); + progressBar->setProgress(percent); +} + +/*! + * This used to set the message of current suspend action to the the dialog. + * \param messageText QString with the message of the current running suspend + * prepare action + */ +void suspendDialog::setTextLabel( QString messageText ) +{ + message->show(); + message->setText(messageText); +} + +#include "suspenddialog.moc" diff --git a/src/suspenddialog.h b/src/suspenddialog.h new file mode 100644 index 0000000..22a4527 --- /dev/null +++ b/src/suspenddialog.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2005 by Danny Kukawka * + * danny.kukawka@web.de, dkukawka@suse.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License * + * as published by the Free Software Foundation. * + * * + * 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. * + ***************************************************************************/ + +/*! +* \file suspenddialog.h +* \brief Headerfile for suspenddialog.cpp and the class \ref suspendDialog. +*/ +/*! +* \class suspendDialog +* \brief class for the suspend dialog related funtionality +* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> +* \date 2005 +*/ + +#ifndef SUSPENDDIALOG_H +#define SUSPENDDIALOG_H + +#include "suspend_Dialog.h" + +class suspendDialog: public suspend_Dialog { + + Q_OBJECT + +public: + + //! default constructor + suspendDialog(QWidget *parent = 0, const char *name = 0); + //! default destructor + ~suspendDialog(); + + //! set all needed icons + void setPixmap( QString ); + //! set the value for the progressbar + void setProgressbar( int ); + //! set the message for the textlabel + void setTextLabel( QString ); + +}; + +#endif |