1# Copyright (C) 2010 Johannes Schwarz 2# 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 1, or (at your option) 6# any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program; if not, write to the Free Software 15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 17import dbus 18from gi.repository import GLib 19from gi.repository import Gtk 20 21from xl import event, providers 22from xl.nls import gettext as _ 23from xlgui.widgets import dialogs, menu 24 25SHUTDOWN = None 26 27 28class Shutdown: 29 def __init__(self, exaile): 30 self.exaile = exaile 31 self.do_shutdown = False 32 33 # add menuitem to tools menu 34 providers.register( 35 'menubar-tools-menu', 36 menu.simple_separator('plugin-sep', ['track-properties']), 37 ) 38 39 item = menu.check_menu_item( 40 'shutdown', 41 ['plugin-sep'], 42 _('Shutdown after Playback'), 43 # checked func # callback func 44 lambda *x: self.do_shutdown, 45 lambda w, n, p, c: self.on_toggled(w), 46 ) 47 providers.register('menubar-tools-menu', item) 48 49 self.countdown = None 50 self.counter = 10 51 52 self.message = dialogs.MessageBar( 53 parent=exaile.gui.builder.get_object('player_box'), 54 buttons=Gtk.ButtonsType.CLOSE, 55 ) 56 self.message.connect('response', self.on_response) 57 58 def on_toggled(self, menuitem): 59 """ 60 Enables or disables defered shutdown 61 """ 62 if menuitem.get_active(): 63 self.do_shutdown = True 64 event.add_ui_callback(self.on_playback_player_end, 'playback_player_end') 65 66 self.message.show_info( 67 _('Shutdown scheduled'), 68 _('Computer will be shutdown at the end of playback.'), 69 ) 70 else: 71 self.disable_shutdown() 72 73 def disable_shutdown(self): 74 self.do_shutdown = False 75 event.remove_callback(self.on_playback_player_end, 'playback_player_end') 76 77 # Stop possible countdown 78 if self.countdown is not None: 79 GLib.source_remove(self.countdown) 80 self.countdown = None 81 82 # Prepare for a new run 83 self.counter = 10 84 85 # Reset message button layout 86 self.message.hide() 87 self.message.clear_buttons() 88 self.message.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) 89 90 def on_playback_player_end(self, event, player, track): 91 """ 92 Tries to shutdown the computer 93 """ 94 self.message.set_message_type(Gtk.MessageType.INFO) 95 self.message.set_markup(_('Imminent Shutdown')) 96 self.message.clear_buttons() 97 self.message.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL) 98 99 if self.countdown is not None: 100 GLib.source_remove(self.countdown) 101 102 self.counter = 10 103 self.countdown = GLib.timeout_add_seconds(1, self.on_timeout) 104 105 def on_response(self, widget, response): 106 """ 107 Cancels shutdown if requested 108 """ 109 if response == Gtk.ResponseType.CANCEL: 110 self.disable_shutdown() 111 112 def on_timeout(self): 113 """ 114 Tries to shutdown the computer 115 """ 116 self.countdown = None 117 if self.counter > 0: 118 self.message.set_secondary_text( 119 _('The computer will be shut down in %d seconds.') % self.counter 120 ) 121 self.message.show() 122 123 self.counter -= 1 124 125 return True 126 127 self.do_shutdown = False 128 129 bus = dbus.SystemBus() 130 131 try: 132 proxy = bus.get_object('org.freedesktop.login1', '/org/freedesktop/login1') 133 proxy.PowerOff(False, dbus_interface='org.freedesktop.login1.Manager') 134 except dbus.exceptions.DBusException: 135 try: 136 proxy = bus.get_object( 137 'org.freedesktop.ConsoleKit', '/org/freedesktop/ConsoleKit/Manager' 138 ) 139 proxy.Stop(dbus_interface='org.freedesktop.ConsoleKit.Manager') 140 except dbus.exceptions.DBusException: 141 try: 142 proxy = bus.get_object( 143 'org.freedesktop.Hal', '/org/freedesktop/Hal/devices/computer' 144 ) 145 proxy.Shutdown( 146 dbus_interface='org.freedesktop.Hal.Device.SystemPowerManagement' 147 ) 148 except dbus.exceptions.DBusException: 149 self.message.show_warning( 150 _('Shutdown failed'), 151 _('Computer could not be shutdown using D-Bus.'), 152 ) 153 154 def destroy(self): 155 """ 156 Cleans up 157 """ 158 if self.countdown is not None: 159 GLib.source_remove(self.countdown) 160 161 event.remove_callback(self.on_playback_player_end, 'playback_player_end') 162 for item in providers.get('menubar-tools-menu'): 163 if item.name == 'shutdown': 164 providers.unregister('menubar-tools-menu', item) 165 break 166 167 168def enable(exaile): 169 if exaile.loading: 170 event.add_callback(_enable, 'exaile_loaded') 171 else: 172 _enable(None, exaile, None) 173 174 175def _enable(eventname, exaile, nothing): 176 global SHUTDOWN 177 SHUTDOWN = Shutdown(exaile) 178 179 180def disable(exaile): 181 global SHUTDOWN 182 SHUTDOWN.destroy() 183