From c5ad5589df01d48f3b0b1e10d63930015e59d162 Mon Sep 17 00:00:00 2001 From: Calum Lind Date: Mon, 7 Jul 2014 17:55:37 +0100 Subject: [#2369] [GTKUI] Fix bypassing tray password dialog Created a generic password dialog and moved the unlock code out of systemtray so any call to window.present will now show the dialog. Also fixed the appindicator not showing the correct visible status --- deluge/ui/gtkui/dialogs.py | 38 ++++++++++++++++++++ deluge/ui/gtkui/mainwindow.py | 44 +++++++++++++++--------- deluge/ui/gtkui/systemtray.py | 80 +++++-------------------------------------- 3 files changed, 74 insertions(+), 88 deletions(-) diff --git a/deluge/ui/gtkui/dialogs.py b/deluge/ui/gtkui/dialogs.py index cf1cf910c..89f5eb41a 100644 --- a/deluge/ui/gtkui/dialogs.py +++ b/deluge/ui/gtkui/dialogs.py @@ -176,3 +176,41 @@ class ErrorDialog(BaseDialog): self.vbox.pack_start(label, False, False) self.vbox.pack_start(sw) self.vbox.show_all() + +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 4606726a6..aef8318cf 100644 --- a/deluge/ui/gtkui/mainwindow.py +++ b/deluge/ui/gtkui/mainwindow.py @@ -39,6 +39,7 @@ pygtk.require('2.0') import gtk, gtk.glade import gobject import pkg_resources +from hashlib import sha1 as sha try: import wnck @@ -49,6 +50,7 @@ from deluge.ui.client import client import deluge.component as component from deluge.configmanager import ConfigManager from deluge.ui.gtkui.ipcinterface import process_args +from deluge.ui.gtkui.dialogs import PasswordDialog from twisted.internet import reactor, defer from twisted.internet.error import ReactorNotRunning @@ -117,7 +119,6 @@ class MainWindow(component.Component): pass self.window.show() - def hide(self): component.pause("TorrentView") component.get("TorrentView").save_state() @@ -129,21 +130,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 - - self.window.present() - self.load_window_state() + 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() + + 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 6f9d10097..bcfccb43a 100644 --- a/deluge/ui/gtkui/systemtray.py +++ b/deluge/ui/gtkui/systemtray.py @@ -212,7 +212,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) @@ -236,6 +235,10 @@ class SystemTray(component.Component): # Tool tip text not available for appindicator if appindicator and self.config["enable_appindicator"]: + if self.window.visible(): + self.tray_glade.get_widget("menuitem_show_deluge").set_active(True) + else: + self.tray_glade.get_widget("menuitem_show_deluge").set_active(False) return # Set the tool tip text @@ -335,10 +338,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.""" @@ -359,10 +359,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() @@ -381,14 +378,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) @@ -432,64 +429,3 @@ class SystemTray(component.Component): value = -1 # Set the config in the core client.core.set_config({core_key: value}) - - def unlock_tray(self, is_showing_dlg=[False]): - try: - from hashlib import sha1 as sha_hash - except ImportError: - from sha import new as sha_hash - - 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_hash(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() -- cgit