diff options
author | Florian Pritz <f-p@gmx.at> | 2009-02-22 21:56:40 +0100 |
---|---|---|
committer | Florian Pritz <f-p@gmx.at> | 2009-02-22 21:56:40 +0100 |
commit | b5485475de82ac0743c37e3eb0c35e877f7213ff (patch) | |
tree | 23c4a52507a34ece514889b4888d627ec0e38a5c /python | |
parent | 1978be4439657a04d2e23227f5c66bb7d4124c18 (diff) | |
download | bin-b5485475de82ac0743c37e3eb0c35e877f7213ff.tar.gz bin-b5485475de82ac0743c37e3eb0c35e877f7213ff.tar.xz |
updated
Diffstat (limited to 'python')
-rw-r--r-- | python/openbox-shutdown.conf | 40 | ||||
-rwxr-xr-x | python/openbox-shutdown.py | 190 | ||||
-rwxr-xr-x | python/shutdown.py | 99 |
3 files changed, 277 insertions, 52 deletions
diff --git a/python/openbox-shutdown.conf b/python/openbox-shutdown.conf new file mode 100644 index 0000000..7448640 --- /dev/null +++ b/python/openbox-shutdown.conf @@ -0,0 +1,40 @@ +# configuration for openbox-shutdown +# +# buttons are shown in the order they are listed in this file +# +# each section contains the following values: +# command - command to execute when button is pressed +# can be used several times to execute more commands +# commands are executed in the order they are listed in this +# file +# image - location of the image for the button +# absolute path is recommended +# set to None if no image should be shown +# info_text - small text to show in the footer +# set to None if not requested +# label - label for the button +# uses mnemics +# set to None to disable + +[reboot] +command = openbox --exit +command = sudo shutdown -r now +image = /usr/share/icons/hydroxygen/72x72/apps/gnome-session-reboot.png +info_text = Reboot +#label = _Neu starten +label = None + +[shutdown] +command = openbox --exit +command = sudo shutdown -h now +image = /usr/share/icons/hydroxygen/72x72/apps/gnome-session-halt.png +info_text = Halt +#label = _Herunterfahren +label = None + +[suspend] +command = sudo pm-suspend +image = /usr/share/icons/hydroxygen/72x72/apps/gnome-session-suspend.png +info_text = Suspend2Ram +#label = _Suspend +label = None diff --git a/python/openbox-shutdown.py b/python/openbox-shutdown.py new file mode 100755 index 0000000..cfdd67b --- /dev/null +++ b/python/openbox-shutdown.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python +""" + +shutdown script for Openbox with configurable buttons and actions +needs pygtk for gui +""" + +# standard stuff +import os +import re +import sys + +# gui modules +try: + import gtk + import pygtk +except ImportError: + sys.stderr.write('pygtk is needed for using this script') + sys.exit(1) + +if sys.version_info < (2, 5, 0): + sys.stderr.write('Python 2.5.0 or higher is needed') + sys.exit(1) + +# a simple parser for the configuration +class ConfigParser(dict): + """ + ConfigParser(file) -> dict + + reads file and creates dict object containing corresponding + configuration + """ + + def __init__(self, filename): + self._section_match_regexp = re.compile(r'\[(\w+)\]') + self._key_val_match_regexp = re.compile(r'\s*=\s*') + self._comment_remov_regexp = re.compile(r'#.*') + try: + config_handle = open(filename, 'r') + except IOError: + sys.stderr.write('Could not read %s. Aborting ...\n' % filename) + sys.exit(1) + linecount = 0 + for line in config_handle.readlines(): + linecount += 1 + line = self._comment_remov_regexp.sub('', line.strip()) + if len(line) == 0: + continue + if self._section_match_regexp.match(line): + section = self._section_match_regexp.match(line).groups()[0] + self[section] = {} + continue + try: + (key, value) = self._key_val_match_regexp.split(line) + except ValueError: + sys.stderr.write('Syntax error in line %d of %s.' % (linecount, + filename)) + sys.exit(1) + if key == 'command' and not key in self[section]: + self[section][key] = [value] + continue + if key in self[section] and key == 'command': + self[section][key].append(value) + else: + self[section][key] = value + + def check(self): + """ + checks if configuration is complete + """ + for section in self: + for needed_key in ['command', 'image', 'info_text', 'label']: + if not needed_key in self[section]: + sys.stderr.write('Missing option %s in %s.' % (needed_key, section)) + sys.exit(1) + +# the main class for this script +class OpenBoxShutdown(object): + """ + main class for this script + + reads configuration and displays buttons as requested + + on click, the specified actions are made + """ + + def __init__(self, basedir): + self._config = ConfigParser(os.path.join(basedir, 'openbox-shutdown.conf')) + self._config.check() + # button box on top for the action buttons + button_box = gtk.HButtonBox() + for key in self._config: + button_box.pack_start(self._create_button(key, + self._config[key]['label'], + self._config[key]['info_text'], + self._config[key]['image'])) + button_box.show() + # create cancel button + cancel_button = gtk.Button(stock = gtk.STOCK_CANCEL) + cancel_button.connect('clicked', self._click_callback, 'cancel') + cancel_button.show() + # label widget for small hints + self._label = gtk.Label() + self._label.show() + # frame widget to contain label + frame = gtk.Frame() + frame.set_shadow_type(gtk.SHADOW_NONE) + frame.add(self._label) + frame.show() + # area containing hints and cancel button + action_area = gtk.HBox() + action_area.pack_end(cancel_button, expand=False) + action_area.pack_end(frame) + action_area.show() + # box containing button box and action area + vbox = gtk.VBox() + vbox.pack_start(button_box) + vbox.pack_end(action_area) + vbox.show() + # the main window with all widgets + # always on top and on all desktops + window = gtk.Window() + window.set_position('center') + window.set_decorated(False) + window.stick() + window.set_keep_above(True) + window.set_skip_pager_hint(True) + window.set_skip_taskbar_hint(True) + window.add(vbox) + window.show() + # give control to gtk + gtk.main() + + def _click_callback(self, event, action): + """ + _click_callback(event, action) + + executes commands on button click + """ + gtk.main_quit() + if action == 'cancel': + sys.exit(0) + for command in self._config[action]['command']: + os.system(command) + + def _create_button(self, key, label_text, info_text, image_file): + """ + _create_button(key, label, info, image) -> button + + creates a button widget with key (used for handling actions), + a label for the button, a small text as hint and an image + """ + button = gtk.Button() + if label_text != 'None': + button.set_label(label_text) + if image_file != 'None': + button.set_image(self._create_image(image_file)) + button.set_image_position(gtk.POS_TOP) + button.connect('clicked', self._click_callback, key) + button.connect('leave', lambda event: self._label.set_text('')) + button.connect('enter', self._set_label, info_text) + button.show() + return button + + def _create_image(self, image_file): + """ + _create_image(image) -> image + + creates an image widget from the specified file + """ + image = gtk.Image() + image.set_from_file(image_file) + return image + + def _set_label(self, event, info_text): + """ + _set_label(event, info_text) + + set label on entering the widget + """ + if info_text != 'None': + self._label.set_markup('<span size="smaller">%s</span>' % info_text) + +# start the script if called standalone +if __name__ == '__main__': + # get the real path for the configuration file + conf_path = os.path.realpath(os.path.dirname(os.readlink(__file__))) \ + if os.path.islink(__file__) \ + else os.path.realpath(os.path.dirname(__file__)) + shutdown = OpenBoxShutdown(conf_path) diff --git a/python/shutdown.py b/python/shutdown.py index 5f350bb..2888394 100755 --- a/python/shutdown.py +++ b/python/shutdown.py @@ -1,8 +1,8 @@ #!/usr/bin/env python #----------------------------------------------------# # File: shutdown.py -# Version: 0.1 -# Date: 2009-01-17 +# Version: 0.1.1 +# Date: 2009-02-15 # Author: Florian "Bluewind" Pritz <f-p@gmx.at> # Display a small shutdown Dialog # Please change the image paths @@ -24,27 +24,27 @@ import gtk import os def create_bbox(title=None, spacing=0, layout=gtk.BUTTONBOX_SPREAD): - bbox = gtk.VButtonBox() + bbox = gtk.VButtonBox() - bbox.set_spacing(spacing) + bbox.set_spacing(spacing) - buttons = (('Cancel', 'gtk-cancel'), - ('Suspend', 'gnome-session-suspend'), - ('Reboot', 'gnome-session-reboot'), - ('Halt', 'gnome-session-halt') - ) - for text, stock_id in buttons: - image = gtk.Image() - image.set_from_stock(stock_id, gtk.ICON_SIZE_LARGE_TOOLBAR) - b = gtk.Button(text) - b.set_image(image) - b.set_data("user_data", text) - b.connect("clicked", click, b) - b.set_size_request(100, -1) - b.set_alignment(0,1) - bbox.add(b) + buttons = (('Cancel', 'gtk-cancel'), + ('Suspend', 'gnome-session-suspend'), + ('Reboot', 'gnome-session-reboot'), + ('Halt', 'gnome-session-halt') + ) + for text, stock_id in buttons: + image = gtk.Image() + image.set_from_stock(stock_id, gtk.ICON_SIZE_LARGE_TOOLBAR) + b = gtk.Button(text) + b.set_image(image) + b.set_data("user_data", text) + b.connect("clicked", click, b) + b.set_size_request(100, -1) + b.set_alignment(0,1) + bbox.add(b) - return bbox + return bbox def click(self, button): ret = button.get_data("user_data") @@ -60,47 +60,42 @@ def click(self, button): os.system("sudo shutdown -h now") class ButtonBox(gtk.Window): - def __init__(self, parent=None): - # Create the toplevel window - gtk.Window.__init__(self) - try: - self.set_screen(parent.get_screen()) - except AttributeError: - self.connect('destroy', lambda *w: gtk.main_quit()) + def __init__(self, parent=None): + # Create the toplevel window + gtk.Window.__init__(self) + try: + self.set_screen(parent.get_screen()) + except AttributeError: + self.connect('destroy', lambda *w: gtk.main_quit()) - self.set_title("Shutdown") - self.set_decorated(False) - self.set_position(gtk.WIN_POS_CENTER) + self.set_title("Shutdown") + #self.set_decorated(False) + self.set_position(gtk.WIN_POS_CENTER) - hbox = gtk.HBox() - hbox.set_border_width(10) - - self.add(hbox) - hbox.pack_start(create_bbox(None, 8, gtk.BUTTONBOX_START), - padding=0) + hbox = gtk.HBox() + hbox.set_border_width(10) - self.show_all() + self.add(hbox) + hbox.pack_start(create_bbox(None, 8, gtk.BUTTONBOX_START), + padding=0) -def main(): - ButtonBox() - gtk.main() + self.show_all() def register_iconsets(icon_info): - iconfactory = gtk.IconFactory() - stock_ids = gtk.stock_list_ids() - for stock_id, file in icon_info: - # only load image files when our stock_id is not present - if stock_id not in stock_ids: - pixbuf = gtk.gdk.pixbuf_new_from_file(file) - iconset = gtk.IconSet(pixbuf) - iconfactory.add(stock_id, iconset) - iconfactory.add_default() + iconfactory = gtk.IconFactory() + stock_ids = gtk.stock_list_ids() + for stock_id, file in icon_info: + # only load image files when our stock_id is not present + if stock_id not in stock_ids: + pixbuf = gtk.gdk.pixbuf_new_from_file(file) + iconset = gtk.IconSet(pixbuf) + iconfactory.add(stock_id, iconset) + iconfactory.add_default() register_iconsets([('gnome-session-suspend', '/usr/share/icons/hydroxygen/128x128/apps/gnome-session-suspend.png'), ('gnome-session-halt', '/usr/share/icons/hydroxygen/128x128/apps/gnome-session-halt.png'), ('gnome-session-reboot', '/usr/share/icons/hydroxygen/128x128/apps/gnome-session-reboot.png') ]) - -if __name__ == '__main__': - main() +ButtonBox() +gtk.main() |