summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--deluge/ui/gtkui/dialogs.py38
-rw-r--r--deluge/ui/gtkui/mainwindow.py44
-rw-r--r--deluge/ui/gtkui/systemtray.py80
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("<b>" + _("Password:") + "</b>")
+ 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("<b><big>%s</big></b>" % _("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("<i>%s</i>" % _("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()