diff --git a/deluge/ui/gtkui/dialogs.py b/deluge/ui/gtkui/dialogs.py index c5fe9089f..55d31c827 100644 --- a/deluge/ui/gtkui/dialogs.py +++ b/deluge/ui/gtkui/dialogs.py @@ -403,3 +403,43 @@ class OtherDialog(BaseDialog): value = self.spinbutton.get_value() self.deferred.callback(value) self.destroy() + + +class PasswordDialog(BaseDialog): + """ + Displays a dialog with an entry field asking for a password. + + When run(), it will return either a gtk.RESPONSE_CANCEL or a gtk.RESPONSE_OK. + """ + def __init__(self, password_msg="", parent=None): + """ + :param password_msg: the error message we got back from the server + :type password_msg: string + """ + super(PasswordDialog, self).__init__( + _("Password Protected"), password_msg, + gtk.STOCK_DIALOG_AUTHENTICATION, + (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_CONNECT, gtk.RESPONSE_OK), + parent) + + table = gtk.Table(1, 2, False) + self.password_label = gtk.Label() + self.password_label.set_markup("" + _("Password:") + "") + self.password_label.set_alignment(1.0, 0.5) + self.password_label.set_padding(5, 5) + self.password_entry = gtk.Entry() + self.password_entry.set_visibility(False) + self.password_entry.connect("activate", self.on_password_activate) + table.attach(self.password_label, 0, 1, 1, 2) + table.attach(self.password_entry, 1, 2, 1, 2) + + self.vbox.pack_start(table, False, False, padding=5) + self.set_focus(self.password_entry) + + self.show_all() + + def get_password(self): + return self.password_entry.get_text() + + def on_password_activate(self, widget): + self.response(gtk.RESPONSE_OK) diff --git a/deluge/ui/gtkui/mainwindow.py b/deluge/ui/gtkui/mainwindow.py index 85c2d526b..e5337bc1a 100644 --- a/deluge/ui/gtkui/mainwindow.py +++ b/deluge/ui/gtkui/mainwindow.py @@ -41,21 +41,25 @@ pygtk.require('2.0') import gtk import logging import urllib +from hashlib import sha1 as sha + +from twisted.internet import reactor +from twisted.internet.error import ReactorNotRunning try: import wnck except ImportError: wnck = None -from deluge.ui.client import client +import deluge.common +import deluge.ui.gtkui.common import deluge.component as component +from deluge.ui.client import client from deluge.configmanager import ConfigManager from deluge.ui.gtkui.ipcinterface import process_args -from twisted.internet import reactor -from twisted.internet.error import ReactorNotRunning +from deluge.ui.gtkui.dialogs import PasswordDialog + -import deluge.common -import common log = logging.getLogger(__name__) @@ -123,10 +127,9 @@ class MainWindow(component.Component): "deluge.ui.gtkui", os.path.join("glade", "main_window.tabs.menu_peer.ui")) ) - self.window = self.main_builder.get_object("main_window") - self.window.set_icon(common.get_deluge_icon()) + self.window.set_icon(deluge.ui.gtkui.common.get_deluge_icon()) self.vpaned = self.main_builder.get_object("vpaned") self.initial_vpaned_position = self.config["window_pane_position"] @@ -176,7 +179,6 @@ class MainWindow(component.Component): pass self.window.show() - def hide(self): component.pause("TorrentView") component.get("TorrentView").save_state() @@ -188,21 +190,32 @@ class MainWindow(component.Component): self.window.hide() def present(self): - # Restore the proper x,y coords for the window prior to showing it - try: - self.config["window_x_pos"] = self.window_x_pos - self.config["window_y_pos"] = self.window_y_pos - except: - pass - try: - component.resume("TorrentView") - component.resume("StatusBar") - component.resume("TorrentDetails") - except: - pass + def restore(): + # Restore the proper x,y coords for the window prior to showing it + try: + self.config["window_x_pos"] = self.window_x_pos + self.config["window_y_pos"] = self.window_y_pos + except: + pass + try: + component.resume("TorrentView") + component.resume("StatusBar") + component.resume("TorrentDetails") + except: + pass - self.window.present() - self.load_window_state() + self.window.present() + self.load_window_state() + + if self.config["tray_password"] and not self.visible(): + dialog = PasswordDialog("Enter your pasword to open Deluge.") + def on_dialog_response(response_id): + if response_id == gtk.RESPONSE_OK: + if self.config["tray_password"] == sha(dialog.get_password()).hexdigest(): + restore() + dialog.run().addCallback(on_dialog_response) + else: + restore() def active(self): """Returns True if the window is active, False if not.""" diff --git a/deluge/ui/gtkui/systemtray.py b/deluge/ui/gtkui/systemtray.py index 9b399034c..916d2248c 100644 --- a/deluge/ui/gtkui/systemtray.py +++ b/deluge/ui/gtkui/systemtray.py @@ -208,7 +208,6 @@ class SystemTray(component.Component): def config_value_changed(self, key, value): """This is called when we received a config_value_changed signal from the core.""" - if key in self.config_value_changed_dict.keys(): self.config_value_changed_dict[key](value) @@ -232,6 +231,10 @@ class SystemTray(component.Component): # Tool tip text not available for appindicator if appindicator and self.config["enable_appindicator"]: + if self.window.visible(): + self.builder.get_object("menuitem_show_deluge").set_active(True) + else: + self.builder.get_object("menuitem_show_deluge").set_active(False) return # Set the tool tip text @@ -334,10 +337,7 @@ class SystemTray(component.Component): if self.window.active(): self.window.hide() else: - if self.config["lock_tray"]: - self.unlock_tray() - else: - self.window.present() + self.window.present() def on_tray_popup(self, status_icon, button, activate_time): """Called when the tray icon is right clicked.""" @@ -357,10 +357,7 @@ class SystemTray(component.Component): def on_menuitem_show_deluge_activate(self, menuitem): log.debug("on_menuitem_show_deluge_activate") if menuitem.get_active() and not self.window.visible(): - if self.config["lock_tray"]: - self.unlock_tray() - else: - self.window.present() + self.window.present() elif not menuitem.get_active() and self.window.visible(): self.window.hide() @@ -379,14 +376,14 @@ class SystemTray(component.Component): def on_menuitem_quit_activate(self, menuitem): log.debug("on_menuitem_quit_activate") if self.config["lock_tray"] and not self.window.visible(): - self.unlock_tray() + self.window.present() self.window.quit() def on_menuitem_quitdaemon_activate(self, menuitem): log.debug("on_menuitem_quitdaemon_activate") if self.config["lock_tray"] and not self.window.visible(): - self.unlock_tray() + self.window.present() self.window.quit(shutdown=True) @@ -428,6 +425,7 @@ class SystemTray(component.Component): value = -1 # Set the config in the core client.core.set_config({core_key: value}) + if widget.get_name() == "unlimited": set_value(-1) elif widget.get_name() == "other": @@ -435,61 +433,3 @@ class SystemTray(component.Component): dialog.run().addCallback(set_value) else: set_value(widget.get_children()[0].get_text().split(" ")[0]) - - def unlock_tray(self, is_showing_dlg=[False]): - from hashlib import sha1 as sha - - log.debug("Show tray lock dialog") - - if is_showing_dlg[0]: - return - is_showing_dlg[0] = True - - entered_pass = gtk.Entry(25) - entered_pass.set_activates_default(True) - entered_pass.set_width_chars(25) - entered_pass.set_visibility(False) - - self.tray_lock = gtk.Dialog(title="", parent=self.window.window, - buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, - gtk.STOCK_OK, gtk.RESPONSE_OK)) - self.tray_lock.set_default_response(gtk.RESPONSE_OK) - self.tray_lock.set_has_separator(False) - - self.tray_lock.set_border_width(5) - - hbox = gtk.HBox(spacing=5) - - image = gtk.image_new_from_file(deluge.common.get_pixmap("lock48.png")) - image.set_alignment(0.5, 0.0) - hbox.pack_start(image, False) - - vbox = gtk.VBox(spacing=5) - hbox.pack_start(vbox, False) - - label = gtk.Label("%s" % _("Deluge is password protected!")) - label.set_use_markup(True) - label.set_alignment(0.0, 0.5) - label.set_line_wrap(True) - vbox.pack_start(label, False) - - tlabel = gtk.Label("%s" % _("Enter your password to continue")) - tlabel.set_use_markup(True) - tlabel.set_alignment(0.0, 0.5) - tlabel.set_line_wrap(True) - vbox.pack_start(tlabel, False) - - vbox.pack_start(entered_pass) - - self.tray_lock.vbox.pack_start(hbox) - - def on_response(dialog, response_id): - if response_id == gtk.RESPONSE_OK: - if self.config["tray_password"] == sha(entered_pass.get_text()).hexdigest(): - self.window.present() - - self.tray_lock.destroy() - is_showing_dlg[0] = False - - self.tray_lock.connect("response", on_response) - self.tray_lock.show_all()