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()