summaryrefslogtreecommitdiffstats
path: root/powermanager/guidance-power-manager.py
diff options
context:
space:
mode:
Diffstat (limited to 'powermanager/guidance-power-manager.py')
-rwxr-xr-xpowermanager/guidance-power-manager.py1147
1 files changed, 0 insertions, 1147 deletions
diff --git a/powermanager/guidance-power-manager.py b/powermanager/guidance-power-manager.py
deleted file mode 100755
index aeccf2f..0000000
--- a/powermanager/guidance-power-manager.py
+++ /dev/null
@@ -1,1147 +0,0 @@
-#!/usr/bin/python
-# -*- coding: UTF-8 -*-
-"""
-Copyright 2006-2007 Sebastian Kügler, Canonical Ltd, Luka Renko
-
-Authors:
- Sebastian Kügler <[email protected]>
- Jonathan Riddell <[email protected]>
- Luka Renko <[email protected]>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-"""
-
-"""
-A frontend to HAL's power features for KDE.
-Supports screen brightness, battery level, plugged/unplugged notices, laptop lid closing actions
-Specification at https://wiki.kubuntu.org/KubuntuPowerManagement
-
-Issues:
- - We have to keep polling HAL rather than listening for signals because the Python DBUS bindings
- don't have TQt mainloop integration
- - Written in Python so will be slow to load up, will probably port to C++ TQt 4.2 in future
- - Should also handle UPS and bluetooth batteries
- - systray applet should be hidden if no battery, but then how do you suspend if no battery?
- (ksmserver integration please)
- - Needs lots more testing
- - Use KUniqueApplication again as soon as dcop problem is sorted outc
- - dcop calls need patch to dcopexport.py, already submitted upstream
-"""
-
-import sys
-import os
-import os.path
-# Trinity-specific paths
-tqt_modules = []
-for m_path in sys.path:
- if os.path.exists(os.path.join(m_path, 'sip4_tqt')):
- m_sip_dir = os.path.join(m_path, 'sip4_tqt')
- tqt_modules.insert(0, m_sip_dir)
- if os.path.exists(os.path.join(m_path, 'python_tqt')):
- m_pyqt_dir = os.path.join(m_path, 'python_tqt')
- tqt_modules.insert(0, m_pyqt_dir)
-for m_path in tqt_modules:
- sys.path.insert(0, m_path)
-
-import subprocess
-import dbus
-
-from qt import *
-from tdecore import *
-from tdeui import *
-
-from dcopext import DCOPClient, DCOPApp # used to lock the screen
-from dcopexport import DCOPExObj
-
-from guidance_power_manager_ui import PowerManagerUI
-from notify import NotifyWidget
-from tooltip import ToolTip
-
-from powermanage import *
-
-POLL_INTERVAL = 5000 # in milliseconds
-
-class Notify(NotifyWidget):
- """ Pop up a passive notication windows. """
-
- def __init__(self,parent,msg,icon,caption=None):
- NotifyWidget.__init__(self,parent,"notify")
- self.setIcon(icon)
- self.setText(msg)
- if caption:
- self.Caption(caption)
-
- def setIcon(self,pixmap):
- """ Set an icon to be displayed in the notification. """
- if pixmap:
- self.Icon.setPixmap(pixmap)
-
- def setCaption(self,caption):
- """ Text to show in bold letters. """
- self.Caption.setText(TQString("<b>")+caption+QString("</b>"))
-
- def setText(self,msg):
- """" Set actual notification message. """
- self.Text.setText(msg)
-
-
-class PowerManager(PowerManagerUI):
- """ Our configuration dialog. """
-
- def __init__ (self, parent, name):
- PowerManagerUI.__init__(self, parent, name)
- TDEGlobal.iconLoader().addAppDir("guidance")
-
- # The systray icon should show and hide the KDialogBase, not only this widget,
- # therefore, it gets our parent as parent.
- self.systray = KSystemTray(parent)
- self.icon = "battery-charging-100"
- self.systray.setPixmap(TQPixmap(UserIcon(self.icon)))
- self.connect(self.systray, SIGNAL("quitSelected()"), self.quit)
-
- # Configuration filename
- self.config = TDEConfig("power-managerrc")
-
- self.powermanager = PowerManage()
-
- def prepare(self):
- """ Prepare UI. """
- self._initBrightness()
- self._initLid()
- self._initBattery()
- self.lastidlesec = 0
-
- self._initConfigKeywords()
-
- self._initUI(self.parent())
-
- self.configToUi()
-
- # Polling: evil. can't receive signals in python-dbus unless we have a glib mainloop,
- # so we need to poll
- self.pollTimer = TQTimer(self)
- self.connect(self.pollTimer, SIGNAL("timeout()"), self.poll)
- self.pollTimer.start(POLL_INTERVAL) # 5 second poll, maybe make this configurable
- self.poll(False)
-
- # check CPU freq policy and notify if it was changed
- msg = self.checkCpuFreq()
- if msg != "":
- self.notify(msg)
-
- self.systray.show()
-
- def _initBrightness(self):
- """ Check for brightness support and disable widgets if it's not there. """
- if not self.powermanager.hasBrightness:
- self.PoweredBrightnessLabel.hide()
- self.PoweredBrightnessSlider.hide()
- self.BatteryBrightnessLabel.hide()
- self.BatteryBrightnessSlider.hide()
-
- def _initLid(self):
- """ Check for lid support and disable widgets if it's not there. """
- if not self.powermanager.hasLid:
- self.LaptopLidRadios.setEnabled(False)
-
- def _initCB(self, combo, options, values):
- """ Initialize TQComboBox with proper values from provided options. """
- combo.clear()
- for option in options:
- combo.insertItem(values[option])
-
- def _getCB(self, combo, options):
- """ Get current item from TQComboBox from config file (string) value. """
- try:
- return options[combo.currentItem()]
- except IndexError:
- return ""
-
- def _setCB(self, combo, options, default, value):
- """ Set current item in TQComboBox from string value. """
- try:
- num = options.index(value)
- except ValueError:
- num = default
- pass
- combo.setCurrentItem(num)
-
- def _getRB(self, radios, options):
- """ Get current item from TQRadioButton from config file (string) value. """
- try:
- return options[radios.selectedId()]
- except IndexError:
- return ""
-
- def _setRB(self, radios, options, default, value):
- """ Set current item in TQRadioButton from string value. """
- try:
- num = options.index(value)
- except ValueError:
- num = default
- pass
- radios.setButton(num)
-
- def _checkOldConfig(self, value, blank):
- """ Convert old numerical values to keywords. """
- try:
- num_val = int(value)
- except ValueError:
- return value
- if blank:
- if num_val == 0: return 'nothing'
- if num_val == 1: return 'blank'
- if num_val == 2: return 'suspend'
- if num_val == 3: return 'hibernate'
- if num_val == 4: return 'shutdown'
- else:
- if num_val == 0: return 'nothing'
- if num_val == 1: return 'suspend'
- if num_val == 2: return 'hibernate'
- if num_val == 3: return 'shutdown'
- return value
-
-
- def _initConfigKeywords(self):
- """ Define helper maps used with config file keywords. """
- # map action keyword to displayed name (l10n)
- self.act_name = {}
- self.act_name['nothing'] = i18n("Do nothing")
- self.act_name['blank'] = i18n("Blank screen")
- self.act_name['suspend'] = i18n("Suspend")
- self.act_name['hibernate'] = i18n("Hibernate")
- self.act_name['shutdown'] = i18n("Shutdown")
-
- # map action keyword to action methods
- self.act_call = {}
- self.act_call['nothing'] = None
- self.act_call['blank'] = self.blankScreen
- self.act_call['suspend'] = self.suspend
- self.act_call['hibernate'] = self.hibernate
- self.act_call['shutdown'] = self.shutdown
-
- # map action keyword to notification description (l10n)
- self.act_notify = {}
- self.act_notify['nothing'] = i18n("doing nothing")
- self.act_notify['blank'] = i18n("blanking screen")
- self.act_notify['suspend'] = i18n("suspending")
- self.act_notify['hibernate'] = i18n("hibernating")
- self.act_notify['shutdown'] = i18n("shutting down")
-
- # map action keyword to action icon used in notification window
- self.act_icon = {}
- self.act_icon['nothing'] = None
- self.act_icon['blank'] = None
- self.act_icon['suspend'] = SmallIcon("suspend")
- self.act_icon['hibernate'] = SmallIcon("hibernate")
- self.act_icon['shutdown'] = SmallIcon("exit")
-
- # map policy keyword to displayed name (l10n)
- self.freq_name = {}
- self.freq_name['dynamic'] = i18n("Dynamic")
- self.freq_name['powersave'] = i18n("Powersave")
- self.freq_name['performance'] = i18n("Performance")
-
- # map policy keyword to policy change methods
- self.freq_call = {}
- self.freq_call['dynamic'] = self.setCpuPolicyDynamic
- self.freq_call['powersave'] = self.setCpuPolicyPowersave
- self.freq_call['performance'] = self.setCpuPolicyPerformance
-
-
- def _initUI(self, parent):
- """ Build dynamic parts of the UI: context menu and tooltip. """
- self.canSuspend = self.powermanager.canSuspend and not self.config.readBoolEntry("disableSuspend", False)
- self.canHibernate = self.powermanager.canHibernate and not self.config.readBoolEntry("disableHibernate", False)
-
- # Connect some signals. Updates in the dialogue apply instantly
- self.connect(self.PoweredBrightnessSlider, SIGNAL("valueChanged(int)"), self.changePoweredBrightness)
- self.connect(self.BatteryBrightnessSlider, SIGNAL("valueChanged(int)"), self.changeBatteryBrightness)
-
- #Add a blank tooltip, the tooltipgroup signals are then used for our KPassivePopup
- toolTipGroup = TQToolTipGroup(self.systray)
- TQToolTip.add(self.systray, "", toolTipGroup, "blah")
- self.connect(toolTipGroup, SIGNAL("showTip(const TQString&)"), self.showTip)
- self.connect(toolTipGroup, SIGNAL("removeTip()"), self.hideTip)
-
- # Popup tooltip showing battery level
- self.popup = KPassivePopup(self.systray)
-
- self.tooltip = ToolTip(self.popup)
-
- self._addBatteryWidgets()
-
- self._addCpuWidgets()
- self.popup.setView(self.tooltip)
-
- # fill actions for LID
- self.lid_act = ['nothing', 'blank', 'suspend', 'hibernate', 'shutdown']
- self.lid_act_def = 0
- # hide LID close actions that are not supported
- if not self.canSuspend:
- self.laptopClosedSuspend.hide()
- if not self.canHibernate:
- self.laptopClosedHibernate.hide()
-
- # fill in only CPU policies that are supported by HW
- self.cb_freq = [] # list of supported cpu freq policies
- self.cb_freq_def = 0 # always use first policy as default
- if self.powermanager.hasCpuFreqGovernors:
- self.cb_freq = self.powermanager.getSupportedCpuPolicies()
- if len(self.cb_freq) > 0:
- self._initCB(self.PoweredFreqCombo, self.cb_freq, self.freq_name)
- self._initCB(self.BatteryFreqCombo, self.cb_freq, self.freq_name)
- else:
- self.PoweredFreqLabel.hide()
- self.PoweredFreqCombo.hide()
- self.BatteryFreqLabel.hide()
- self.BatteryFreqCombo.hide()
-
- # fill actions in Idle/Critical battery combo boxes
- self.cb_act = ['nothing'] # list of supported actions (keywords)
- self.cb_act_def_critical = 0 # default action when critical battery
- if self.canSuspend:
- self.cb_act.append('suspend')
- if self.canHibernate:
- self.cb_act.append('hibernate')
- self.cb_act_def_critical = len(self.cb_act) - 1 # hibernate
- self.cb_act.append('shutdown')
- if self.cb_act_def_critical == 0:
- self.cb_act_def_critical = len(self.cb_act) - 1 # shutdown
- self._initCB(self.PoweredIdleCombo, self.cb_act, self.act_name)
- self._initCB(self.BatteryIdleCombo, self.cb_act, self.act_name)
- self._initCB(self.BatteryCriticalCombo, self.cb_act, self.act_name)
-
- self.connect(self.PoweredIdleCombo,SIGNAL("activated(int)"),self.slotPoweredIdleActivated)
- self.connect(self.BatteryIdleCombo,SIGNAL("activated(int)"),self.slotBatteryIdleActivated)
- self.connect(self.BatteryCriticalCombo,SIGNAL("activated(int)"),self.slotBatteryCriticalActivated)
-
- # add suspend/hibernate to tray's context menu
- menu = self.systray.contextMenu()
- if self.canSuspend:
- action = TDEAction( i18n("Suspend"), TDEShortcut(), self.suspend,
- self.systray.actionCollection(), "suspend")
- action.setIcon("suspend")
- action.plug(menu)
- if self.canHibernate:
- action = TDEAction( i18n("Hibernate"), TDEShortcut(), self.hibernate,
- self.systray.actionCollection(), "hibernate")
- action.setIcon("hibernate")
- action.plug(menu)
-
- # add list of governators
- if self.powermanager.hasCpuFreqGovernors and len(self.cb_freq) > 0:
- submenu = TDEPopupMenu(menu)
- for policy in self.cb_freq:
- action = TDERadioAction(self.freq_name[policy], TDEShortcut(),
- self.freq_call[policy],
- self.systray.actionCollection(), policy)
- action.setExclusiveGroup("freqs")
- action.plug(submenu)
-
- policy = self.powermanager.getCpuPolicy()
- if policy in self.cb_freq:
- self.systray.actionCollection().action(policy).setChecked(True);
- menu.insertItem(i18n("CPU policy"), submenu)
-
-
- # TDEGlobalAccel crashes the application in pytde
- # see http://mats.gmd.de/pipermail/pytde/2006-May/013224.html
- #self.globalActions = TDEGlobalAccel(self)
- #self.suspendShortcut = TDEShortcut("XF86Sleep")
- #self.hibernateShortcut = TDEShortcut("XF86Standby")
- #self.hshutdownShortcut = TDEShortcut("XF86PowerOff")
- #self.globalActions.insert("suspend", i18n("Suspend"), i18n("what's this?"), self.suspendShortcut, #self.suspendShortcut, self.suspend)
- #self.globalActions.updateConnections()
-
- def _initBattery(self):
- """ Remove non-battery-related widgets if there's no battery bay. """
- if not self.powermanager.hasBattery:
- # Disable the Batterybox in the config dialogue,
- self.BatteryBox.setEnabled(False)
- # And change the icon in the systray, remove the restore option
- # This way, we're basically becoming a systray applet, you can
- # hibernate and suspend from
- self.systray.setPixmap(TQPixmap(UserIcon(self.icon)))
- if self.powermanager.hasAC:
- self.wasOnBattery = self.powermanager.onBattery()
-
- def configToUi(self):
- """ Setup the the values from the config file in the UI."""
- # brightness.
- if self.powermanager.hasBrightness:
- brightness_high = self.powermanager.brightness_levels
- self.BatteryBrightnessSlider.setMaxValue(self.powermanager.brightness_levels-1)
- self.PoweredBrightnessSlider.setMaxValue(self.powermanager.brightness_levels-1)
- self.BatteryBrightnessSlider.setValue(self.config.readNumEntry("batteryBrightness", int(brightness_high/2))) #default middle
- self.PoweredBrightnessSlider.setValue(self.config.readNumEntry("poweredBrightness", brightness_high)) #default highest
-
- tt_text = "Every step increases or decreases the brightness by %i%%" % int(100/brightness_high)
- TQToolTip.add(self.BatteryBrightnessSlider, tt_text)
- TQToolTip.add(self.PoweredBrightnessSlider, tt_text)
-
- self.lockScreenOnResume.setChecked(self.config.readBoolEntry("lockOnResume", True))
-
- # Idletime-related configuration
- self._setCB(self.PoweredIdleCombo, self.cb_act, 0, str(self.config.readEntry("poweredIdleAction")))
- self.PoweredIdleTime.setValue(self.config.readNumEntry("poweredIdleTime", 60))
- self._setCB(self.BatteryIdleCombo, self.cb_act, 0, str(self.config.readEntry("batteryIdleAction")))
- self.BatteryIdleTime.setValue(self.config.readNumEntry("batteryIdleTime", 10))
-
- self._setCB(self.PoweredFreqCombo, self.cb_freq, self.cb_freq_def, str(self.config.readEntry("poweredFreqPolicy")))
- self._setCB(self.BatteryFreqCombo, self.cb_freq, self.cb_freq_def, str(self.config.readEntry("batteryFreqPolicy")))
-
- self.BatteryIdleTime.setValue(self.config.readNumEntry("batteryIdleTime", 10)) # default Do nothing
- # battery critical and lid actions.
- self._setCB(self.BatteryCriticalCombo, self.cb_act, self.cb_act_def_critical, self._checkOldConfig(self.config.readEntry("batteryCriticalAction", ""), False))
- self._setRB(self.LaptopLidRadios, self.lid_act, self.lid_act_def, self._checkOldConfig(self.config.readEntry("laptopLidAction", ""), True))
- self.CriticalRemainTime.setValue(self.config.readNumEntry("criticalRemainTime", BATTERY_CRITICAL_MINUTES))
- self.criticalLevel = self.CriticalRemainTime.value()
-
- # Call some slots to disable various spinboxes if necessary
- self.slotBatteryCriticalActivated()
- self.slotPoweredIdleActivated()
- self.slotBatteryIdleActivated()
-
-
- def uiToConfig(self):
- """ Read all values from the UI and write them to the config file. """
- self.config.writeEntry("poweredBrightness", self.PoweredBrightnessSlider.value())
- self.config.writeEntry("batteryBrightness", self.BatteryBrightnessSlider.value())
-
- self.config.writeEntry("poweredIdleTime", self.PoweredIdleTime.value())
- self.config.writeEntry("poweredIdleAction", self._getCB(self.PoweredIdleCombo, self.cb_act))
- self.config.writeEntry("batteryIdleTime", self.BatteryIdleTime.value())
- self.config.writeEntry("batteryIdleAction", self._getCB(self.BatteryIdleCombo, self.cb_act))
- self.config.writeEntry("poweredFreqPolicy", self._getCB(self.PoweredFreqCombo, self.cb_freq))
- self.config.writeEntry("batteryFreqPolicy", self._getCB(self.BatteryFreqCombo, self.cb_freq))
-
- self.config.writeEntry("batteryCriticalAction", self._getCB(self.BatteryCriticalCombo, self.cb_act))
- self.config.writeEntry("criticalRemainTime", self.CriticalRemainTime.value())
-
- self.config.writeEntry("laptopLidAction", self._getRB(self.LaptopLidRadios, self.lid_act))
- self.config.writeEntry("lockOnResume", self.lockScreenOnResume.isChecked())
-
- self.criticalLevel = self.CriticalRemainTime.value()
-
- self.config.sync()
-
- def quit(self):
- """ TQuit application. """
- kapp.quit()
-
- def showTip(self, text=""):
- """ Pop up the tooltip showing battery data and CPU frequencies. """
- self.popup.show()
-
-
- def showBrightnessPopup(self):
- if self.powermanager.onBattery():
- value=self.BatteryBrightnessSlider.value()*100/self.BatteryBrightnessSlider.maxValue()
- else:
- value=self.PoweredBrightnessSlider.value()*100/self.PoweredBrightnessSlider.maxValue()
- self.brightnessPopup = KPassivePopup.message('<b>Brightness:</b> '+str(value)+'%', self.systray)
- """pop.setTimeout(3000)"""
- self.brightnessPopup.show()
-
- def setBrightnessUp(self):
- """Increments slider value by 10%"""
- if self.powermanager.onBattery():
- self.BatteryBrightnessSlider.setValue(float(self.BatteryBrightnessSlider.value())+max(float(self.BatteryBrightnessSlider.maxValue())/float(10),1))
- else:
- self.PoweredBrightnessSlider.setValue(float(self.PoweredBrightnessSlider.value())+max(float(self.PoweredBrightnessSlider.maxValue())/float(10),1))
- self.showBrightnessPopup()
-
- def setBrightnessDown(self):
- """Decrements slider value by 10%"""
- if self.powermanager.onBattery():
- self.BatteryBrightnessSlider.setValue(float(self.BatteryBrightnessSlider.value())-max(float(self.BatteryBrightnessSlider.maxValue())/float(10),1))
- else:
- self.PoweredBrightnessSlider.setValue(float(self.PoweredBrightnessSlider.value())-max(float(self.PoweredBrightnessSlider.maxValue())/float(10),1))
- self.showBrightnessPopup()
-
- def getBrightness(self):
- """Work with percentages - it's a bit nicer"""
- if self.powermanager.onBattery():
- value=self.BatteryBrightnessSlider.value()*100/self.BatteryBrightnessSlider.maxValue()
- else:
- value=self.PoweredBrightnessSlider.value()*100/self.PoweredBrightnessSlider.maxValue()
- return TQString(str(value))
-
- def hideTip(self):
- """ Hide the tooltip."""
- self.popup.hide()
-
- def lockScreen(self):
- """ locks the screen using kdesktop """
- # create a new DCOP-Client:
- client = DCOPClient()
- # connect the client to the local DCOP-server:
- client.attach()
- # create a DCOP-Application-Object to talk to kdesktop:
- kdesktop = DCOPApp('kdesktop', client)
- # call a DCOP-function:
- try:
- ok, foo = kdesktop.KScreensaverIface.lock()
- except:
- print "Unable to lock the screen. The KDE Screensaver does not seem to be running."
- def suspend(self):
- """ Lock the screen and initiate a suspend to RAM (S3). """
- if self.config.readBoolEntry("lockOnResume", True):
- self.lockScreen()
- try:
- self.warningPopup.hide()
- except AttributeError:
- pass # No warningpopup, that's OK.
- self.powermanager.suspend()
- self.powermanager.resetIdleSeconds()
-
- def hibernate(self):
- """ Lock the screen and initiate a suspend to disk (S4). """
- if self.config.readBoolEntry("lockOnResume", True):
- self.lockScreen()
- try:
- self.warningPopup.hide()
- except AttributeError:
- pass # No warningpopup, that's OK.
- self.powermanager.hibernate()
- self.powermanager.resetIdleSeconds()
-
- def shutdown(self):
- """ Perform system shutdown. """
- self.powermanager.shutdown()
-
- def setCpuPolicyDynamic(self):
- """Change frequ for all cpu"""
- self.powermanager.setCpuPolicy('dynamic')
- self.notify(i18n("CPU frequency policy changed to %1.").arg(self.freq_name['dynamic']))
-
- def setCpuPolicyPerformance(self):
- """Change frequ for all cpu"""
- self.powermanager.setCpuPolicy('performance')
- self.notify(i18n("CPU frequency policy changed to %1.").arg(self.freq_name['performance']))
-
- def setCpuPolicyPowersave(self):
- """Change frequ for all cpu"""
- self.powermanager.setCpuPolicy('powersave')
- self.notify(i18n("CPU frequency policy changed to %1.").arg(self.freq_name['powersave']))
-
- def trySuspend(self):
- """ If supported, lock the screen and initiate a suspend to RAM (S3). """
- if self.canSuspend:
- self.suspend()
- else:
- print "Warning: DCOP suspend() called, but not supported."
-
- def tryHibernate(self):
- """ If supported, lock the screen and initiate a suspend to disk (S4). """
- if self.canHibernate:
- self.hibernate()
- else:
- print "Warning: DCOP hibernate() called, but not supported."
-
- def blankScreen(self):
- """ Lock and blank screen. """
- if self.config.readBoolEntry("lockOnResume", True):
- self.lockScreen()
- self.powermanager.blankScreen()
-
- def _getIcon(self):
- """ Set systray icon depending on battery status/level. """
- if self.powermanager.hasBattery:
- if self.batt_state == "not present":
- self.icon = "ac-adapter"
- if self.batt_state == "charged":
- self.icon = "battery-charging-100"
- elif self.batt_state == "discharging":
- if self.batt_level >= 95:
- self.icon = "battery-discharging-100"
- elif self.batt_level < 95 and self.batt_level >= 85:
- self.icon = "battery-discharging-090"
- elif self.batt_level < 85 and self.batt_level >= 75:
- self.icon = "battery-discharging-070"
- elif self.batt_level < 75 and self.batt_level >= 60:
- self.icon = "battery-discharging-060"
- elif self.batt_level < 65 and self.batt_level >= 45:
- self.icon = "battery-discharging-050"
- elif self.batt_level < 45 and self.batt_level >= 30:
- self.icon = "battery-discharging-040"
- elif self.batt_level < 30 and self.batt_level >= 20:
- self.icon = "battery-discharging-030"
- elif self.batt_level < 20 and self.batt_level >= 10:
- self.icon = "battery-discharging-020"
- elif self.batt_level < 10 and self.batt_level >= 5:
- self.icon = "battery-discharging-010"
- else:
- self.icon = "battery-discharging-000"
- elif self.batt_state == "charging":
- if self.batt_level >= 95:
- self.icon = "battery-charging-100"
- elif self.batt_level < 95 and self.batt_level >= 85:
- self.icon = "battery-charging-090"
- elif self.batt_level < 85 and self.batt_level >= 75:
- self.icon = "battery-charging-070"
- elif self.batt_level < 75 and self.batt_level >= 60:
- self.icon = "battery-charging-060"
- elif self.batt_level < 65 and self.batt_level >= 45:
- self.icon = "battery-charging-050"
- elif self.batt_level < 45 and self.batt_level >= 30:
- self.icon = "battery-charging-040"
- elif self.batt_level < 30 and self.batt_level >= 20:
- self.icon = "battery-charging-030"
- elif self.batt_level < 20 and self.batt_level >= 10:
- self.icon = "battery-charging-020"
- elif self.batt_level < 10 and self.batt_level >= 5:
- self.icon = "battery-charging-010"
- else:
- self.icon = "battery-charging-000"
- else:
- self.icon = "ac-adapter"
- return self.icon
-
- def getIcon(self):
- """ Return current icon."""
- return UserIcon(self.icon)
-
- def setIcon(self):
- """ Change the systray/tooltip icon."""
- oldIcon = self.icon
- self.icon = self._getIcon()
- if self.icon != oldIcon:
- self.systray.setPixmap(TQPixmap(UserIcon(self.icon)))
- self.BattPixmap.setPixmap(TQPixmap(UserIcon(self.icon)))
-
- def notify(self, msg, icon=None):
- """ Send a notification popup. """
- if icon:
- icon = TQPixmap(icon)
- else:
- icon = TQPixmap(SmallIcon("messagebox_info"))
- try:
- del self.warningPopup
- except:
- pass
- self.warningPopup = KPassivePopup(self.systray)
- label = Notify(self.warningPopup, msg, icon)
- self.warningPopup.setView(label)
- position = TQPoint(5,5)
- self.warningPopup.show(position)
-
- def poll(self,notify=True):
- """ Check for changes in plugged in status, battery status and laptop lid closed status. """
- debug( "------------ POLL ---------------")
-
- self.powermanager.checkHAL()
- # Battery stuff:
- # check for last state, and run plugged / unplugged message if the state changed.
- if self.powermanager.hasBattery:
- plugged_num = 0
- self.batt_state = "not present" # unknown yet
- self.batt_level = self.batt_remain = 0
- self.batt_rate = self.batt_charge = self.batt_full = 0
- for batt in self.powermanager.batteries:
- state, level, remain, rate, current, full = self.powermanager.getBatteryState(batt)
- self._updateBatteryWidget(batt, state, level, remain, rate)
-
- ## notify plugged/unplugged batteries
- if state == "not present":
- if self.powermanager.batteryIsPresent[batt]:
- self.notify(i18n("The battery has been removed."))
- self.powermanager.batteryIsPresent[batt] = False
- else: # battery present
- if not self.powermanager.batteryIsPresent[batt]:
- self.notify(i18n("The battery has been inserted."))
- self.powermanager.batteryIsPresent[batt] = True
-
- ## get cumulative charge levels/rate
- self.batt_rate += rate
- self.batt_charge += current
- self.batt_full += full
-
- ## calculate overall level (average of present batteries)
- self.batt_remain += remain
- self.batt_level += level
- plugged_num += 1
-
- ## calculate overall state (charging/discharging/charged)
- if state in ("charging","discharging"):
- self.batt_state = state
- elif not self.batt_state in ("charging, discharging"):
- self.batt_state = state
-
- # if we know charge and full -> recalculate overall level
- if self.batt_full > 0 and self.batt_charge > 0:
- self.batt_level = 100 * self.batt_charge / self.batt_full
- else:
- # if more than one battery present, we need to calculate average level
- if plugged_num > 1:
- self.batt_level /= plugged_num
-
- # if rate is reported, calculate remaining time on our own
- if self.batt_rate > 0:
- if self.batt_state == "charging":
- self.batt_remain = 3600 * (float(self.batt_full - self.batt_charge) / self.batt_rate)
- if self.batt_state == "discharging":
- self.batt_remain = 3600 * (float(self.batt_charge) / self.batt_rate)
-
- remain_h = self.batt_remain/3600
- remain_m = (self.batt_remain/60)%60
-
- blabel = i18n("<b>Battery:</b>")
- if self.batt_state == "charged":
- blabel += i18n(" fully charged")
- elif self.batt_state == "charging":
- blabel += i18n(" %i:%02ih to charge" % (remain_h,remain_m))
- elif self.batt_state == "discharging":
- blabel += i18n(" %i:%02ih remaining" % (remain_h,remain_m))
- self.BattMainLabel.setText(blabel)
-
- # update tray icon if needed
- self.setIcon()
-
- # check battery state
- self.checkBatteryCritical()
-
- # check Idletime
- self.checkIdletime()
-
- # CPU stuff
- self._updateCpuWidgets()
-
- if self.powermanager.hasBattery:
- on_battery = self.powermanager.onBattery()
- if self.powermanager.wasOnBattery != on_battery:
- self.powermanager.wasOnBattery = on_battery
- debug("poll: states differ")
- if not on_battery:
- debug("poll: Now on AC")
- if notify:
- self.powerHasBeenPlugged()
- else:
- debug("poll: Now on battery")
- if notify:
- self.powerHasBeenUnplugged()
- else:
- debug("poll: state is the same")
-
- # Lid stuff
- if self.powermanager.hasLid:
- if self.powermanager.getLidClosedState():
- if not self.powermanager.lidClosedState:
- self.powermanager.lidClosedState = True
-
- action = self._getRB(self.LaptopLidRadios, self.lid_act)
- if not self.act_name.has_key(action):
- action = self.act_name[self.lid_act_def]
-
- if self.act_call[action] != None:
- note = i18n("Laptop lid is closed, %1 now.").arg(self.act_notify[action])
- self.notify(note, self.act_icon[action])
- TQTimer.singleShot(2000, self.act_call[action])
- else:
- self.powermanager.lidClosedState = False
-
- def _addBatteryWidgets(self):
- """ Adds progressbars to show battery status to the tooltip."""
- BattLayout = TQHBoxLayout(None,0,6,"BattLayout")
-
- self.BattPixmap = TQLabel(self.tooltip,"BattLabLayout")
- self.BattPixmap.setSizePolicy(TQSizePolicy(TQSizePolicy.Fixed,TQSizePolicy.Fixed,0,0,self.BattPixmap.sizePolicy().hasHeightForWidth()))
- self.BattPixmap.setPixmap(TQPixmap(UserIcon(self.icon)))
- self.BattPixmap.setScaledContents(1)
- BattLayout.addWidget(self.BattPixmap)
- self.BattMainLabel = TQLabel(self.tooltip,"BattMainLabel")
- self.BattMainLabel.setText(i18n("<b>Battery:</b>"))
- BattLayout.addWidget(self.BattMainLabel)
-
- # Add to tooltip
- self.tooltip.layout().addLayout(BattLayout)
-
- # Create a progressbar and a label for every battery found, and add it to tooltip
- self.BattLabel = {}
- self.BattLayout = {}
- self.BattProgress = {}
- i = 1
- for batt in self.powermanager.batteries:
- self.BattLayout[batt] = TQHBoxLayout(None,0,6,"BattBarLayout")
- self.BattLabel[batt] = TQLabel(self.tooltip,"BattLabel")
- if len(self.powermanager.batteries) > 1:
- self.BattLabel[batt].setText(i18n("Battery %i" % i))
- self.BattLayout[batt].addWidget(self.BattLabel[batt])
- self.BattProgress[batt] = KProgress(self.tooltip,"BattProgress")
- self.BattProgress[batt].setMinimumSize(TQSize(200,0))
- self.BattLayout[batt].addWidget(self.BattProgress[batt])
- self.tooltip.layout().addLayout(self.BattLayout[batt])
- i += 1
-
-
- def _updateBatteryWidget(self, batt, state, level, remain, rate):
- """ Retrieve battery information and update the related widgets accordingly. """
- self.BattProgress[batt].setEnabled(True)
- self.BattProgress[batt].setTotalSteps(100)
- self.BattProgress[batt].setProgress(level)
- if state == "not present":
- self.BattProgress[batt].setFormat(i18n("not present"))
- elif state == "charging":
- self.BattProgress[batt].setFormat(i18n("Charging (%p%)"))
- elif state == "discharging":
- if rate > 0:
- showrate = rate/1000
- self.BattProgress[batt].setFormat(i18n("Discharging (%p%)") + " - %.d W" % showrate)
- else:
- self.BattProgress[batt].setFormat(i18n("Discharging (%p%)"))
- else:
- self.BattProgress[batt].setFormat("%p%")
-
- def _addCpuWidgets(self):
- """ Adds progressbars to show CPU frequencies to the tooltip."""
- if not SHOW_CPUFREQ:
- return
- if len(self.powermanager.cpus) == 0:
- return
-
- LabelLayout = TQHBoxLayout(None,0,6,"layout5")
-
- self.CpuPixmap = TQLabel(self.tooltip,"CpuPixmap")
- self.CpuPixmap.setSizePolicy(TQSizePolicy(TQSizePolicy.Fixed,TQSizePolicy.Fixed,0,0,self.CpuPixmap.sizePolicy().hasHeightForWidth()))
- self.CpuPixmap.setPixmap(TQPixmap(UserIcon("processor")))
- self.CpuPixmap.setScaledContents(1)
- LabelLayout.addWidget(self.CpuPixmap)
- self.CpuMainLabel = TQLabel(self.tooltip,"CpuMainLabel")
- self.CpuMainLabel.setText(i18n("<b>CPU Frequency:</b>"))
- LabelLayout.addWidget(self.CpuMainLabel)
-
- # Add to tooltip
- self.tooltip.layout().addLayout(LabelLayout)
-
- # Create a progressbar and a label for every CPU found, and add it to tooltip
- self.CpuLabel = {}
- self.CpuLayout = {}
- self.CpuProgress = {}
- i = 1
- for cpu in self.powermanager.cpus:
- self.CpuLayout[cpu] = TQHBoxLayout(None,0,6,"layout2")
- self.CpuLabel[cpu] = TQLabel(self.tooltip,"CpuLabel")
- if len(self.powermanager.cpus) > 1:
- self.CpuLabel[cpu].setText(i18n("Processor %i" % i))
- self.CpuLayout[cpu].addWidget(self.CpuLabel[cpu])
- self.CpuProgress[cpu] = KProgress(self.tooltip,"CpuProgress")
- self.CpuProgress[cpu].setFormat("%v MHz")
- self.CpuLayout[cpu].addWidget(self.CpuProgress[cpu])
- self.tooltip.layout().addLayout(self.CpuLayout[cpu])
- i += 1
-
- def slotPoweredIdleActivated(self, index=False):
- """ Signal slot for activated powered idle action. """
- if not index:
- index = self.PoweredIdleCombo.currentItem()
- self.PoweredIdleTime.setEnabled(index != 0)
-
- def slotBatteryIdleActivated(self, index=False):
- """ Signal slot for activated battery idle action. """
- if not index:
- index = self.BatteryIdleCombo.currentItem()
- self.BatteryIdleTime.setEnabled(index != 0)
-
- def slotBatteryCriticalActivated(self, index=False):
- """ Signal slot for activated battery critical action. """
- if not index:
- index = self.BatteryCriticalCombo.currentItem()
- self.CriticalRemainTime.setEnabled(index != 0)
-
- def _updateCpuWidgets(self):
- """ Retrieve CPU freq information and update the related widgets accordingly. """
- if not SHOW_CPUFREQ:
- return
- if len(self.powermanager.cpus) == 0:
- return
-
- clabel = i18n("<b>CPU Frequency:</b>") + " "
- policy = self.powermanager.getCpuPolicy()
- if self.freq_name.has_key(policy):
- clabel += self.freq_name[policy] # get l10n name
- else:
- clabel += policy
- self.CpuMainLabel.setText(clabel)
-
- for cpu in self.powermanager.cpus:
- cpustate = self.powermanager.getCpuState(cpu)
- if not cpustate['online']:
- self.CpuProgress[cpu].setEnabled(False)
- else:
- self.CpuProgress[cpu].setEnabled(True)
- self.CpuProgress[cpu].setTotalSteps(cpustate['max'])
- self.CpuProgress[cpu].setProgress(cpustate['cur'])
- if policy != "":
- self.systray.actionCollection().action(policy).setChecked(True)
- if policy in self.cb_freq:
- self.systray.actionCollection().action(policy).setChecked(True)
-
- def changePoweredBrightness(self, level=None):
- """ Mains-powered brigthness slider has been moved. """
- # Check if the state applies and adjust brightness immediately.
- if not self.powermanager.onBattery() and self.powermanager.hasBrightness:
- if not level:
- level = self.PoweredBrightnessSlider.value()
- self.powermanager.adjustBrightness(level)
-
- def changeBatteryBrightness(self, level=None):
- """ Battery-powered brigthness slider has been moved. """
- # Check if the state applies and adjust brightness immediately.
- if self.powermanager.onBattery() and self.powermanager.hasBrightness:
- if not level:
- level = self.BatteryBrightnessSlider.value()
- self.powermanager.adjustBrightness(level)
-
-
-
-
- def checkCpuFreq(self):
- """ Adjust CPU frequency policy according to current state """
- if not self.powermanager.hasCpuFreqGovernors:
- return ""
-
- if self.powermanager.onBattery():
- policy = str(self.config.readEntry("batteryFreqPolicy"))
- else:
- policy = str(self.config.readEntry("poweredFreqPolicy"))
- if policy == "":
- policy = 'dynamic'
-
- # check if specified policy is supported by HW
- if not policy in self.cb_freq:
- print "Warning: policy from config file not supported: ", policy
- return ""
-
- current_policy = self.powermanager.getCpuPolicy()
- if current_policy != policy:
- debug("Switching CPU policy from %s to %s." % (current_policy, policy))
- self.powermanager.setCpuPolicy(policy)
- return i18n("CPU frequency policy changed to %1.").arg(self.freq_name[policy])
- elif current_policy == 'dynamic':
- debug("Dynamic policy -> update policy (conservative/ondemand)")
- self.powermanager.setCpuPolicy(policy)
-
- debug("CPU policy will stay %s" % current_policy)
- return ""
-
- def powerHasBeenUnplugged(self):
- """ Actions to perform when the plug has been pulled."""
- if self.powermanager.hasBrightness:
- self.powermanager.adjustBrightness(self.BatteryBrightnessSlider.value())
- self.powermanager.setPowerSave(True)
- self.checkBatteryCritical()
- self.changeBatteryBrightness()
- self.powermanager.setScreensaverBlankOnly(True)
- self.powermanager.resetIdleSeconds()
- msg = self.checkCpuFreq()
- if self.powermanager.hasAC:
- self.notify(i18n("The AC adapter has been unplugged, switching to battery mode.")+"\n"+msg, self.getIcon())
-
- def powerHasBeenPlugged(self):
- """ Actions to perform when AC adapter has been plugged in. """
- if self.powermanager.hasBrightness:
- self.powermanager.adjustBrightness(self.PoweredBrightnessSlider.value())
- self.powermanager.setPowerSave(False)
- self.changePoweredBrightness()
- self.powermanager.setScreensaverBlankOnly(False)
- msg = self.checkCpuFreq()
- self.powermanager.resetIdleSeconds()
- self.notify(i18n("The AC adapter has been plugged in, switching to AC mode.")+"\n"+msg, self.getIcon())
-
- def checkBatteryCritical(self):
- """ Check for warning and critical battery label and notify-warn or
- initiate the configured action. """
-
- if not self.powermanager.hasBattery:
- return
-
- if self.batt_state == "discharging":
- currentLevel = int(self.batt_remain/60)
-
- warningLevel = self.criticalLevel + 5 # warn five minutes before critical
- criticalLevel = self.criticalLevel
-
- debug("CurrentBat: %i, WarningBat: %i, CriticalBat: %i" % (currentLevel, warningLevel, criticalLevel))
- # We only want to suspend if the chargelevel is above a certain threshold,
- # it sometimes takes some time for HAL to report remaining time correctly
- if currentLevel <= criticalLevel and self.batt_level < CHARGE_LEVEL_THRESHOLD:
- if not self.powermanager.criticalBatteryState and self.powermanager.onBattery():
- self.powermanager.criticalBatteryState = True
-
- action = str(self.config.readEntry("batteryCriticalAction"))
- if not self.act_name.has_key(action):
- action = self.act_name[self.cb_act_def_critical]
-
- note = i18n("You are about to run out of battery power, %1 now.").arg(self.act_notify[action])
- self.notify(note, self.act_icon[action])
- if self.act_call[action] != None:
- TQTimer.singleShot(2000, self.act_call[action])
- else:
- self.powermanager.criticalBatteryState = False
- if currentLevel <= warningLevel and self.batt_level < CHARGE_LEVEL_THRESHOLD:
- if not self.powermanager.warningBatteryState:
- self.powermanager.warningBatteryState = True
- self.notify(i18n("You are low on battery power."), self.getIcon())
- else:
- self.powermanager.warningBatteryState = False
-
- def checkIdletime(self):
- """ Reads the idle time and does some action. """
- idlesec = round(self.powermanager.getIdleSeconds()/60, 2)
- if self.powermanager.onBattery():
- idleTime = self.config.readNumEntry("batteryIdleTime", 10)
- action = str(self.config.readEntry("batteryIdleAction"))
- else:
- idleTime = self.config.readNumEntry("poweredIdleTime", 60)
- action = str(self.config.readEntry("poweredIdleAction"))
- if not self.act_name.has_key(action):
- action = 'nothing'
-
- if idlesec - self.lastidlesec > 100:
- debug("last: %u" % (idlesec - self.lastidlesec))
- return # probably bogus idleseconds right after suspend
- self.lastidlesec = idlesec
- if self.act_call[action] == None:
- return # doing nothing anyway
- if idlesec > idleTime:
- note = i18n("System idle for at least %1 minutes, %2 now.").arg(idleTime).arg(self.act_notify[action])
- self.notify(note, self.act_icon[action])
- TQTimer.singleShot(2000, self.act_call[action])
-
-
-
-def doDcop(kapp):
- """ Register kvandale in dcop, so it can be controlled from outside. """
- my_dcop = kapp.dcopClient()
- #my_dcop.attach()
- #my_dcop.registerAs("power-manager")
-
-
-class DcopIface (DCOPExObj):
- """ Add some interface so we can use powermanager from the outside. """
- def __init__ (self, app, id='power-manager'):
- DCOPExObj.__init__ (self, id)
- # addMethod (<signature>, <Python method>)
- #self.addMethod ('QString getQuery()', gvd.getZoekbegrip)
-
- # PM related.
- self.addMethod ('void suspend ()', app.trySuspend)
- self.addMethod ('void hibernate ()', app.tryHibernate)
- self.addMethod ('void shutdown ()', app.shutdown)
-
- # UI related.
- self.addMethod ('void showTip ()', app.showTip)
- #self.addMethod ('void show ()', app.parent().show)
- #self.addMethod ('void hide ()', app.parent().hide)
-
- #self.addMethod ('void plugged ()', app.powerHasBeenPlugged)
- #self.addMethod ('void unplugged ()', app.powerHasBeenUnplugged)
- self.addMethod ('bool onBattery ()', app.powermanager.onBattery)
-
- self.addMethod('void brightnessUp ()', app.setBrightnessUp)
- self.addMethod('void brightnessDown ()', app.setBrightnessDown)
- self.addMethod('QString getBrightness ()', app.getBrightness)
-
- #self.addMethod ('QString getCurrentResult()', gvd.getRawResult)
-
-
-class PowermanagerApp(KDialogBase):
- """ The KDialog providing the OK, Apply and Cancel buttons."""
-
- def __init__(self,parent=None,name=None):
- """ Initialise dialog and set mainwidget. """
- TDEGlobal.locale().insertCatalogue("guidance")
- TDEGlobal.iconLoader().addAppDir("guidance")
-
- # We would like to use a KUniqueApplication, but that breaks dcop due to some
- # strange bug. The following line is the revenge code for this bug, it is
- # intentionally ugly.
- if len(os.popen("dcop |grep guidance-").readlines()) > 1:
- print "There is already an instance of power manager running. Exiting."
- sys.exit(0)
-
- # Which buttons do we want?
- KDialogBase.__init__(self,KJanusWidget.Swallow,i18n("Power Manager"),
- KDialogBase.Ok|KDialogBase.Apply|KDialogBase.Cancel|KDialogBase.User1, KDialogBase.Close)
- self.pmwidget = PowerManager(self,name)
- self.setButtonText(KDialogBase.User1, i18n("About"))
-
- if not self.pmwidget.powermanager.isLaptop():
- print "This is not a laptop, quitting ... "
- sys.exit(1)
-
- self.pmwidget.prepare()
-
- self.setMainWidget(self.pmwidget)
- self.aboutus = TDEAboutApplication(self)
-
- def slotOk(self):
- """ The OK button has been pressed, save configuration and pass on do whatever
- needs to be done by KDialog. """
- self.pmwidget.uiToConfig()
- self.pmwidget.checkCpuFreq()
- KDialogBase.slotOk(self)
-
- def slotApply(self):
- """ The Apply button has been pressed, save configuration and pass on do whatever
- needs to be done by KDialog. """
- self.pmwidget.uiToConfig()
- self.pmwidget.checkCpuFreq()
- KDialogBase.slotApply(self)
-
- def slotCancel(self):
- """ The Cancel button has been pressed, reset some values and hide dialogue. """
- # In case brightness has changed, we reset it to the configured value.
- if self.pmwidget.powermanager.hasBrightness:
- brightness_high = self.pmwidget.powermanager.brightness_levels
- if not self.pmwidget.powermanager.onBattery():
- level = self.pmwidget.config.readNumEntry("poweredBrightness", brightness_high)
- else:
- level = self.pmwidget.config.readNumEntry("batteryBrightness", int(brightness_high/2))
- self.pmwidget.powermanager.adjustBrightness(level)
- self.pmwidget.configToUi()
- KDialogBase.slotCancel(self)
-
- def slotUser1(self):
- self.aboutus.show()
-
-# There's a bug in KUniqueApplication that shows the pid in the dcop name,
-# this fugly hack works around it.
-class PMApp(TDEApplication):
-
- def name(self):
- return "power-manager"
-
-
-if __name__ == "__main__":
- aboutdata = TDEAboutData("guidance", "Power Manager", "0.8.0",
- "Handles battery, display and suspend modes for your computer.", TDEAboutData.License_GPL,
- "(C) 2006-2007 Sebastian Kügler, Canonical Ltd, Luka Renko",
- None, None, "[email protected]")
- aboutdata.addAuthor("Sebastian Kügler", "Developer", "[email protected]","http://vizZzion.org")
- aboutdata.addAuthor("Jonathan Riddell", "Developer", "[email protected]")
- aboutdata.addAuthor("Luka Renko", "Developer", "[email protected]")
- aboutdata.setProgramLogo(TQImage("power-manager.png"))
- TDECmdLineArgs.init(sys.argv, aboutdata)
- #kapp = KUniqueApplication(True, True, False)
- #kapp = TDEApplication()
- kapp = PMApp(True, True)
- mainWindow = PowermanagerApp(None, "main window")
- doDcop(kapp)
- dcop_iface = DcopIface(mainWindow.pmwidget)
- """Start helper module / button listener"""
- try:
- helperPid = os.spawnl(os.P_NOWAIT, os.path.dirname(__file__)+'/gpmhelper.py', 'gpmhelper.py')
- except:
- """Non-fatal if this fails"""
- print "Unable to start button-listener"
-
- kapp.exec_loop()
-
- """Kill helper module / button listener"""
- os.system('kill '+str(helperPid))