More changes related to automatic connections.

Auto-connecting on start of the gtk ui is now fully working.
Auto-staring localhost if needed is now also working.
Authentication failures now get passed correctly to the client implementation which will allow the user to enter username and/or password to complete authentication.
It's now possible to shutdown the daemon from the connection manager even if not on localhost, it just needs all required information to be present on the liststore.
This commit is contained in:
Pedro Algarvio 2011-04-30 07:42:06 +01:00
commit dd3f78bd36
7 changed files with 375 additions and 296 deletions

View file

@ -56,7 +56,7 @@ except ImportError:
import deluge.component as component import deluge.component as component
import deluge.configmanager import deluge.configmanager
from deluge.core.authmanager import AUTH_LEVEL_NONE, AUTH_LEVEL_DEFAULT, AUTH_LEVEL_ADMIN from deluge.core.authmanager import AUTH_LEVEL_NONE, AUTH_LEVEL_DEFAULT, AUTH_LEVEL_ADMIN
from deluge.error import DelugeError, NotAuthorizedError, __PassthroughError from deluge.error import DelugeError, NotAuthorizedError, _PassthroughError
RPC_RESPONSE = 1 RPC_RESPONSE = 1
RPC_ERROR = 2 RPC_ERROR = 2
@ -266,7 +266,7 @@ class DelugeRPCProtocol(Protocol):
self.factory.authorized_sessions[self.transport.sessionno] = (ret, args[0]) self.factory.authorized_sessions[self.transport.sessionno] = (ret, args[0])
self.factory.session_protocols[self.transport.sessionno] = self self.factory.session_protocols[self.transport.sessionno] = self
except Exception, e: except Exception, e:
if isinstance(e, __PassthroughError): if isinstance(e, _PassthroughError):
self.sendData( self.sendData(
(RPC_EVENT_AUTH, request_id, (RPC_EVENT_AUTH, request_id,
e.__class__.__name__, e.__class__.__name__,

View file

@ -448,7 +448,9 @@ class TorrentManager(component.Component):
# Set auto_managed to False because the torrent is paused # Set auto_managed to False because the torrent is paused
handle.auto_managed(False) handle.auto_managed(False)
# Create a Torrent object # Create a Torrent object
owner = state.owner if state else (owner if owner else component.get("RPCServer").get_session_user()) owner = state.owner if state else (
owner if owner else component.get("RPCServer").get_session_user()
)
account_exists = component.get("AuthManager").has_account(owner) account_exists = component.get("AuthManager").has_account(owner)
if not account_exists: if not account_exists:
owner = 'localclient' owner = 'localclient'

View file

@ -50,14 +50,23 @@ class InvalidTorrentError(DelugeError):
class InvalidPathError(DelugeError): class InvalidPathError(DelugeError):
pass pass
class __PassthroughError(DelugeError): class _PassthroughError(DelugeError):
def _get_message(self):
return self._message
def _set_message(self, message):
self._message = message
message = property(_get_message, _set_message)
del _get_message, _set_message
def __new__(cls, *args, **kwargs): def __new__(cls, *args, **kwargs):
inst = super(__PassthroughError, cls).__new__(cls, *args, **kwargs) inst = super(_PassthroughError, cls).__new__(cls, *args, **kwargs)
inst._args = args inst._args = args
inst._kwargs = kwargs inst._kwargs = kwargs
return inst return inst
class NotAuthorizedError(__PassthroughError): class NotAuthorizedError(_PassthroughError):
def __init__(self, current_level, required_level): def __init__(self, current_level, required_level):
self.message = _( self.message = _(
"Auth level too low: %(current_level)s < %(required_level)s" % "Auth level too low: %(current_level)s < %(required_level)s" %
@ -67,14 +76,7 @@ class NotAuthorizedError(__PassthroughError):
self.required_level = required_level self.required_level = required_level
class __UsernameBasedPasstroughError(__PassthroughError): class _UsernameBasedPasstroughError(_PassthroughError):
def _get_message(self):
return self._message
def _set_message(self, message):
self._message = message
message = property(_get_message, _set_message)
del _get_message, _set_message
def _get_username(self): def _get_username(self):
return self._username return self._username
@ -84,16 +86,16 @@ class __UsernameBasedPasstroughError(__PassthroughError):
del _get_username, _set_username del _get_username, _set_username
def __init__(self, message, username): def __init__(self, message, username):
super(__UsernameBasedPasstroughError, self).__init__(message) super(_UsernameBasedPasstroughError, self).__init__(message)
self.message = message self.message = message
self.username = username self.username = username
class BadLoginError(__UsernameBasedPasstroughError): class BadLoginError(_UsernameBasedPasstroughError):
pass pass
class AuthenticationRequired(__UsernameBasedPasstroughError): class AuthenticationRequired(_UsernameBasedPasstroughError):
pass pass
class AuthManagerError(__UsernameBasedPasstroughError): class AuthManagerError(_UsernameBasedPasstroughError):
pass pass

View file

@ -421,7 +421,7 @@ class DaemonSSLProxy(DaemonProxy):
# Still log these errors # Still log these errors
log.error(error_data.value.logable()) log.error(error_data.value.logable())
return error_data return error_data
if isinstance(error_data.value, error.__PassthroughError): if isinstance(error_data.value, error._PassthroughError):
return error_data return error_data
except: except:
pass pass
@ -472,7 +472,7 @@ class DaemonSSLProxy(DaemonProxy):
self.login_deferred.callback(result) self.login_deferred.callback(result)
def __on_login_fail(self, result): def __on_login_fail(self, result):
log.debug("_on_login_fail(): %s", result) log.debug("_on_login_fail(): %s", result.value)
self.login_deferred.errback(result) self.login_deferred.errback(result)
def __on_auth_levels_mappings(self, result): def __on_auth_levels_mappings(self, result):
@ -529,12 +529,14 @@ class DaemonClassicProxy(DaemonProxy):
log.exception(e) log.exception(e)
return defer.fail(e) return defer.fail(e)
else: else:
return defer.maybeDeferred(m, *copy.deepcopy(args), **copy.deepcopy(kwargs)) return defer.maybeDeferred(
m, *copy.deepcopy(args), **copy.deepcopy(kwargs)
)
def register_event_handler(self, event, handler): def register_event_handler(self, event, handler):
""" """
Registers a handler function to be called when `:param:event` is received Registers a handler function to be called when `:param:event` is
from the daemon. received from the daemon.
:param event: the name of the event to handle :param event: the name of the event to handle
:type event: str :type event: str
@ -604,37 +606,39 @@ class Client(object):
:returns: a Deferred object that will be called once the connection :returns: a Deferred object that will be called once the connection
has been established or fails has been established or fails
""" """
self._daemon_proxy = DaemonSSLProxy(dict(self.__event_handlers)) self._daemon_proxy = DaemonSSLProxy(dict(self.__event_handlers))
self._daemon_proxy.set_disconnect_callback(self.__on_disconnect) self._daemon_proxy.set_disconnect_callback(self.__on_disconnect)
d = self._daemon_proxy.connect(host, port) d = self._daemon_proxy.connect(host, port)
auth_deferred = defer.Deferred()
def on_connect_fail(reason): def on_connect_fail(reason):
self.disconnect() self.disconnect()
auth_deferred.errback(reason)
return reason return reason
def on_authenticate(result, daemon_info):
log.debug("Authentication sucessfull: %s", result)
return result
def on_authenticate_fail(reason):
log.debug("Failed to authenticate: %s", reason.value)
return reason
def on_connected(daemon_version):
log.debug("Client.connect.on_connected. Daemon version: %s",
daemon_version)
return daemon_version
def authenticate(daemon_version, username, password):
d = self._daemon_proxy.authenticate(username, password)
d.addCallback(on_authenticate, daemon_version)
d.addErrback(on_authenticate_fail)
return d
d.addCallback(on_connected)
d.addErrback(on_connect_fail) d.addErrback(on_connect_fail)
if not skip_authentication: if not skip_authentication:
d.addCallback(authenticate, username, password)
def on_authenticate(result, daemon_info):
log.debug("Authentication sucessfull: %s", result)
auth_deferred.callback(daemon_info)
def on_authenticate_fail(reason):
log.debug("Failed to authenticate")
log.exception(reason)
auth_deferred.errback(reason)
def on_connected(daemon_version):
log.debug("Client.connect.on_connected. Daemon version: %s",
daemon_version)
d = self._daemon_proxy.authenticate(username, password)
d.addCallback(on_authenticate, daemon_version)
d.addErrback(on_authenticate_fail)
d.addCallback(on_connected)
return auth_deferred
return d return d
def disconnect(self): def disconnect(self):

View file

@ -48,8 +48,7 @@ from deluge.ui.common import get_localhost_auth
from deluge.ui.client import client from deluge.ui.client import client
import deluge.ui.client import deluge.ui.client
from deluge.configmanager import ConfigManager from deluge.configmanager import ConfigManager
from deluge.error import AuthenticationRequired from deluge.error import AuthenticationRequired, BadLoginError
from deluge.log import LOG as log
import dialogs import dialogs
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -187,6 +186,9 @@ class ConnectionManager(component.Component):
# Connect the signals to the handlers # Connect the signals to the handlers
self.glade.signal_autoconnect(self) self.glade.signal_autoconnect(self)
self.hostlist.get_selection().connect(
"changed", self.on_hostlist_selection_changed
)
# Load any saved host entries # Load any saved host entries
self.__load_hostlist() self.__load_hostlist()
@ -361,7 +363,9 @@ class ConnectionManager(component.Component):
""" """
Set the widgets to show the correct options from the config. Set the widgets to show the correct options from the config.
""" """
self.autoconnect_host_id = self.gtkui_config['autoconnect_host_id'] self.glade.get_widget("chk_autoconnect").set_active(
self.gtkui_config["autoconnect"]
)
self.glade.get_widget("chk_autostart").set_active( self.glade.get_widget("chk_autostart").set_active(
self.gtkui_config["autostart_localhost"] self.gtkui_config["autostart_localhost"]
) )
@ -389,25 +393,20 @@ class ConnectionManager(component.Component):
self.glade.get_widget("image_startdaemon").set_from_stock( self.glade.get_widget("image_startdaemon").set_from_stock(
gtk.STOCK_EXECUTE, gtk.ICON_SIZE_MENU) gtk.STOCK_EXECUTE, gtk.ICON_SIZE_MENU)
self.glade.get_widget("label_startdaemon").set_text("_Start Daemon") self.glade.get_widget("label_startdaemon").set_text("_Start Daemon")
self.glade.get_widget("chk_autoconnect").set_sensitive(False)
model, row = self.hostlist.get_selection().get_selected() model, row = self.hostlist.get_selection().get_selected()
if not row: if not row:
self.glade.get_widget("button_edithost").set_sensitive(False) self.glade.get_widget("button_edithost").set_sensitive(False)
self.glade.get_widget("chk_autoconnect").set_sensitive(False)
return return
self.glade.get_widget("button_edithost").set_sensitive(True) self.glade.get_widget("button_edithost").set_sensitive(True)
self.glade.get_widget("chk_autoconnect").set_sensitive(True)
# Get some values about the selected host # Get some values about the selected host
status = model[row][HOSTLIST_COL_STATUS] status = model[row][HOSTLIST_COL_STATUS]
hostid = model[row][HOSTLIST_COL_ID]
host = model[row][HOSTLIST_COL_HOST] host = model[row][HOSTLIST_COL_HOST]
port = model[row][HOSTLIST_COL_PORT]
self.glade.get_widget("chk_autoconnect").set_active( user = model[row][HOSTLIST_COL_USER]
hostid == self.gtkui_config["autoconnect_host_id"] passwd = model[row][HOSTLIST_COL_PASS]
)
log.debug("Status: %s", status) log.debug("Status: %s", status)
# Check to see if we have a localhost entry selected # Check to see if we have a localhost entry selected
@ -445,8 +444,14 @@ class ConnectionManager(component.Component):
self.glade.get_widget("label_startdaemon").set_text( self.glade.get_widget("label_startdaemon").set_text(
_("_Start Daemon")) _("_Start Daemon"))
if not localhost: if client.connected() and (host, port, user) == client.connection_info():
# An offline host # If we're connected, we can stop the dameon
self.glade.get_widget("button_startdaemon").set_sensitive(True)
elif user and passwd:
# In this case we also have all the info to shutdown the dameon
self.glade.get_widget("button_startdaemon").set_sensitive(True)
else:
# Can't stop non localhost daemons, specially without the necessary info
self.glade.get_widget("button_startdaemon").set_sensitive(False) self.glade.get_widget("button_startdaemon").set_sensitive(False)
# Make sure label is displayed correctly using mnemonics # Make sure label is displayed correctly using mnemonics
@ -493,16 +498,16 @@ class ConnectionManager(component.Component):
def __on_connected(self, daemon_info, host_id): def __on_connected(self, daemon_info, host_id):
if self.gtkui_config["autoconnect"]: if self.gtkui_config["autoconnect"]:
self.gtkui_config["autoconnect_host_id"] = host_id self.gtkui_config["autoconnect_host_id"] = host_id
self.connection_manager.response(gtk.RESPONSE_OK) self.connection_manager.response(gtk.RESPONSE_OK)
component.start() component.start()
def __on_connected_failed(self, reason, host_id, host, port, user): def __on_connected_failed(self, reason, host_id, host, port, user):
log.debug("Failed to connect: %s", reason) log.debug("Failed to connect: %s", reason)
if reason.check(AuthenticationRequired): if reason.check(AuthenticationRequired, BadLoginError):
log.debug("PasswordRequired exception") log.debug("PasswordRequired exception")
dialog = dialogs.AuthenticationDialog(reason.value.message, dialog = dialogs.AuthenticationDialog(
reason.value.username) reason.value.message, reason.value.username
)
def dialog_finished(response_id, host, port, user): def dialog_finished(response_id, host, port, user):
if response_id == gtk.RESPONSE_OK: if response_id == gtk.RESPONSE_OK:
self.__connect(host_id, host, port, self.__connect(host_id, host, port,
@ -547,6 +552,7 @@ class ConnectionManager(component.Component):
time.sleep(0.5) time.sleep(0.5)
do_retry_connect(try_counter) do_retry_connect(try_counter)
return result return result
def do_retry_connect(try_counter): def do_retry_connect(try_counter):
d = client.connect(host, port, user, password) d = client.connect(host, port, user, password)
d.addCallback(self.__on_connected, host_id) d.addCallback(self.__on_connected, host_id)
@ -657,9 +663,11 @@ class ConnectionManager(component.Component):
log.debug("on_button_startdaemon_clicked") log.debug("on_button_startdaemon_clicked")
if self.liststore.iter_n_children(None) < 1: if self.liststore.iter_n_children(None) < 1:
# There is nothing in the list, so lets create a localhost entry # There is nothing in the list, so lets create a localhost entry
self.add_host(DEFAULT_HOST, DEFAULT_PORT) self.add_host(DEFAULT_HOST, DEFAULT_PORT, *get_localhost_auth())
# ..and start the daemon. # ..and start the daemon.
self.start_daemon(DEFAULT_PORT, deluge.configmanager.get_config_dir()) self.start_daemon(
DEFAULT_PORT, deluge.configmanager.get_config_dir()
)
return return
paths = self.hostlist.get_selection().get_selected_rows()[1] paths = self.hostlist.get_selection().get_selected_rows()[1]
@ -681,9 +689,10 @@ class ConnectionManager(component.Component):
def on_daemon_shutdown(d): def on_daemon_shutdown(d):
# Update display to show change # Update display to show change
self.__update_list() self.__update_list()
if client.connected() and client.connection_info() == (host, port, user): if client.connected() and client.connection_info() == (host, port, user):
client.daemon.shutdown().addCallback(on_daemon_shutdown) client.daemon.shutdown().addCallback(on_daemon_shutdown)
else: elif user and password:
# Create a new client instance # Create a new client instance
c = deluge.ui.client.Client() c = deluge.ui.client.Client()
def on_connect(d, c): def on_connect(d, c):
@ -712,44 +721,6 @@ class ConnectionManager(component.Component):
def on_askpassword_dialog_entry_activate(self, entry): def on_askpassword_dialog_entry_activate(self, entry):
self.askpassword_dialog.response(gtk.RESPONSE_OK) self.askpassword_dialog.response(gtk.RESPONSE_OK)
def on_hostlist_cursor_changed(self, widget):
paths = self.hostlist.get_selection().get_selected_rows()[1]
if len(paths) < 1:
self.glade.get_widget("chk_autoconnect").set_sensitive(False)
return
else:
self.glade.get_widget("chk_autoconnect").set_sensitive(True)
hostid = self.liststore[paths[0]][HOSTLIST_COL_ID]
self.glade.get_widget("chk_autoconnect").set_active(
hostid == self.gtkui_config["autoconnect_host_id"]
)
def on_chk_autoconnect_toggled(self, widget):
paths = self.hostlist.get_selection().get_selected_rows()[1]
if len(paths) < 1:
self.glade.get_widget("chk_autoconnect").set_sensitive(False)
self.glade.get_widget("chk_autostart").set_sensitive(False)
return
else:
self.glade.get_widget("chk_autoconnect").set_sensitive(True)
self.glade.get_widget("chk_autostart").set_sensitive(widget.get_active())
hostid = self.liststore[paths[0]][HOSTLIST_COL_ID]
if widget.get_active():
if self.autoconnect_host_id != hostid:
self.gtkui_config["autoconnect_host_id"] = hostid
self.autoconnect_host_id = hostid
self.gtkui_config.save()
return
if self.autoconnect_host_id == hostid:
self.gtkui_config["autoconnect_host_id"] = None
self.autoconnect_host_id = None
self.gtkui_config.save()
def __migrate_config_1_to_2(self, config): def __migrate_config_1_to_2(self, config):
localclient_username, localclient_password = get_localhost_auth() localclient_username, localclient_password = get_localhost_auth()
if not localclient_username: if not localclient_username:

View file

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<glade-interface> <glade-interface>
<!-- interface-requires gtk+ 2.6 --> <!-- interface-requires gtk+ 2.22 -->
<!-- interface-naming-policy toplevel-contextual --> <!-- interface-naming-policy toplevel-contextual -->
<widget class="GtkDialog" id="addhost_dialog"> <widget class="GtkDialog" id="addhost_dialog">
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="border_width">5</property> <property name="border_width">5</property>
<property name="title" translatable="yes">Add Host</property> <property name="title" translatable="yes">Add Host</property>
@ -13,16 +14,83 @@
<child internal-child="vbox"> <child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox3"> <widget class="GtkVBox" id="dialog-vbox3">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">2</property> <property name="spacing">2</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="layout_style">end</property>
<child>
<widget class="GtkButton" id="button_addhost_cancel">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button_addhost_add">
<property name="label">gtk-add</property>
<property name="response_id">1</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button_addhost_save">
<property name="label">gtk-save</property>
<property name="response_id">2</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child> <child>
<widget class="GtkHBox" id="hbox2"> <widget class="GtkHBox" id="hbox2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">5</property> <property name="spacing">5</property>
<child> <child>
<widget class="GtkLabel" id="label3"> <widget class="GtkLabel" id="label3">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Hostname:</property> <property name="label" translatable="yes">Hostname:</property>
</widget> </widget>
@ -35,6 +103,7 @@
<child> <child>
<widget class="GtkAlignment" id="alignment4"> <widget class="GtkAlignment" id="alignment4">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">1</property> <property name="left_padding">1</property>
<child> <child>
<widget class="GtkEntry" id="entry_hostname"> <widget class="GtkEntry" id="entry_hostname">
@ -42,16 +111,23 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="activates_default">True</property> <property name="activates_default">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</widget> </widget>
</child> </child>
</widget> </widget>
<packing> <packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
<child> <child>
<widget class="GtkLabel" id="label4"> <widget class="GtkLabel" id="label4">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Port:</property> <property name="label" translatable="yes">Port:</property>
</widget> </widget>
@ -69,6 +145,10 @@
<property name="max_length">5</property> <property name="max_length">5</property>
<property name="width_chars">5</property> <property name="width_chars">5</property>
<property name="xalign">1</property> <property name="xalign">1</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
<property name="adjustment">58846 0 65535 1 10 0</property> <property name="adjustment">58846 0 65535 1 10 0</property>
<property name="climb_rate">1</property> <property name="climb_rate">1</property>
<property name="numeric">True</property> <property name="numeric">True</property>
@ -89,17 +169,23 @@
<child> <child>
<widget class="GtkTable" id="table1"> <widget class="GtkTable" id="table1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">2</property> <property name="n_rows">2</property>
<property name="n_columns">2</property> <property name="n_columns">2</property>
<child> <child>
<widget class="GtkAlignment" id="alignment3"> <widget class="GtkAlignment" id="alignment3">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">5</property> <property name="left_padding">5</property>
<child> <child>
<widget class="GtkEntry" id="entry_password"> <widget class="GtkEntry" id="entry_password">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="visibility">False</property> <property name="visibility">False</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</widget> </widget>
</child> </child>
</widget> </widget>
@ -113,11 +199,16 @@
<child> <child>
<widget class="GtkAlignment" id="alignment2"> <widget class="GtkAlignment" id="alignment2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">5</property> <property name="left_padding">5</property>
<child> <child>
<widget class="GtkEntry" id="entry_username"> <widget class="GtkEntry" id="entry_username">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</widget> </widget>
</child> </child>
</widget> </widget>
@ -129,6 +220,7 @@
<child> <child>
<widget class="GtkLabel" id="label6"> <widget class="GtkLabel" id="label6">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Password:</property> <property name="label" translatable="yes">Password:</property>
</widget> </widget>
<packing> <packing>
@ -140,6 +232,7 @@
<child> <child>
<widget class="GtkLabel" id="label5"> <widget class="GtkLabel" id="label5">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Username:</property> <property name="label" translatable="yes">Username:</property>
</widget> </widget>
<packing> <packing>
@ -149,25 +242,46 @@
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
<child> <child>
<placeholder/> <placeholder/>
</child> </child>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="askpassword_dialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Password Required</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
<property name="default_width">320</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">dialog</property>
<property name="skip_taskbar_hint">True</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">2</property>
<child internal-child="action_area"> <child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area3"> <widget class="GtkHButtonBox" id="dialog-action_area5">
<property name="visible">True</property> <property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="can_focus">False</property>
<property name="layout_style">end</property> <property name="layout_style">end</property>
<child> <child>
<widget class="GtkButton" id="button_addhost_cancel"> <widget class="GtkButton" id="askpassword_dialog_connect_button">
<property name="label">gtk-cancel</property> <property name="label">gtk-connect</property>
<property name="response_id">1</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="clicked" handler="on_askpassword_dialog_connect_button_clicked"/>
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -175,49 +289,61 @@
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child> <child>
<widget class="GtkButton" id="button_addhost_add"> <widget class="GtkImage" id="askpassword_dialog_image">
<property name="label">gtk-add</property>
<property name="response_id">1</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">False</property>
<property name="can_default">True</property> <property name="stock">gtk-dialog-authentication</property>
<property name="has_default">True</property> <property name="icon-size">6</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_stock">True</property>
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">True</property>
<property name="fill">False</property> <property name="fill">True</property>
<property name="position">1</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child> <child>
<widget class="GtkButton" id="button_addhost_save"> <widget class="GtkEntry" id="askpassword_dialog_entry">
<property name="label">gtk-save</property> <property name="visible">True</property>
<property name="response_id">2</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="visibility">False</property>
<property name="use_stock">True</property> <property name="invisible_char">●</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
<signal name="activate" handler="on_askpassword_dialog_entry_activate"/>
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">True</property>
<property name="fill">False</property> <property name="fill">True</property>
<property name="position">2</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">True</property>
<property name="pack_type">end</property> <property name="fill">True</property>
<property name="position">0</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
</widget> </widget>
</child> </child>
</widget> </widget>
<widget class="GtkDialog" id="connection_manager"> <widget class="GtkDialog" id="connection_manager">
<property name="can_focus">False</property>
<property name="has_focus">True</property> <property name="has_focus">True</property>
<property name="is_focus">True</property> <property name="is_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@ -232,16 +358,33 @@
<child internal-child="vbox"> <child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox2"> <widget class="GtkVBox" id="dialog-vbox2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">2</property> <property name="spacing">2</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area2">
<property name="sensitive">False</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="layout_style">end</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child> <child>
<widget class="GtkHBox" id="hbox1"> <widget class="GtkHBox" id="hbox1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">5</property> <property name="spacing">5</property>
<child> <child>
<widget class="GtkImage" id="image1"> <widget class="GtkImage" id="image1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-missing-image</property> <property name="stock">gtk-missing-image</property>
</widget> </widget>
@ -254,18 +397,21 @@
<child> <child>
<widget class="GtkLabel" id="label1"> <widget class="GtkLabel" id="label1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">&lt;big&gt;&lt;b&gt;Connection Manager&lt;/b&gt;&lt;/big&gt;</property> <property name="label" translatable="yes">&lt;big&gt;&lt;b&gt;Connection Manager&lt;/b&gt;&lt;/big&gt;</property>
<property name="use_markup">True</property> <property name="use_markup">True</property>
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">5</property> <property name="padding">5</property>
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
@ -273,11 +419,13 @@
<child> <child>
<widget class="GtkVBox" id="vbox3"> <widget class="GtkVBox" id="vbox3">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">5</property> <property name="spacing">5</property>
<child> <child>
<widget class="GtkViewport" id="viewport1"> <widget class="GtkViewport" id="viewport1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="resize_mode">queue</property> <property name="resize_mode">queue</property>
<child> <child>
@ -292,7 +440,6 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<signal name="cursor_changed" handler="on_hostlist_cursor_changed"/>
<signal name="row_activated" handler="on_hostlist_row_activated"/> <signal name="row_activated" handler="on_hostlist_row_activated"/>
</widget> </widget>
</child> </child>
@ -300,16 +447,20 @@
</child> </child>
</widget> </widget>
<packing> <packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child> <child>
<widget class="GtkHBox" id="hbox3"> <widget class="GtkHBox" id="hbox3">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child> <child>
<widget class="GtkHButtonBox" id="hbuttonbox2"> <widget class="GtkHButtonBox" id="hbuttonbox2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="layout_style">start</property> <property name="layout_style">start</property>
<child> <child>
@ -319,6 +470,7 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="clicked" handler="on_button_addhost_clicked"/> <signal name="clicked" handler="on_button_addhost_clicked"/>
</widget> </widget>
@ -332,9 +484,9 @@
<widget class="GtkButton" id="button_edithost"> <widget class="GtkButton" id="button_edithost">
<property name="label">gtk-edit</property> <property name="label">gtk-edit</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="clicked" handler="on_button_edithost_clicked"/> <signal name="clicked" handler="on_button_edithost_clicked"/>
</widget> </widget>
@ -351,6 +503,7 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="clicked" handler="on_button_removehost_clicked"/> <signal name="clicked" handler="on_button_removehost_clicked"/>
</widget> </widget>
@ -367,51 +520,44 @@
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkButton" id="button_refresh">
<property name="label">gtk-refresh</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_button_refresh_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child> <child>
<widget class="GtkButton" id="button_startdaemon"> <widget class="GtkButton" id="button_startdaemon">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_button_startdaemon_clicked"/> <signal name="clicked" handler="on_button_startdaemon_clicked"/>
<child> <child>
<widget class="GtkHBox" id="hbox4"> <widget class="GtkHBox" id="hbox4">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">2</property> <property name="spacing">2</property>
<child> <child>
<widget class="GtkImage" id="image_startdaemon"> <widget class="GtkImage" id="image_startdaemon">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-execute</property> <property name="stock">gtk-execute</property>
</widget> </widget>
<packing> <packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child> <child>
<widget class="GtkLabel" id="label_startdaemon"> <widget class="GtkLabel" id="label_startdaemon">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">_Start local daemon</property> <property name="label" translatable="yes">_Start local daemon</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
</widget> </widget>
<packing> <packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
@ -425,6 +571,22 @@
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkButton" id="button_refresh">
<property name="label">gtk-refresh</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_button_refresh_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -434,6 +596,8 @@
</child> </child>
</widget> </widget>
<packing> <packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="padding">10</property> <property name="padding">10</property>
<property name="position">2</property> <property name="position">2</property>
</packing> </packing>
@ -446,6 +610,7 @@
<child> <child>
<widget class="GtkAlignment" id="alignment1"> <widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="top_padding">5</property> <property name="top_padding">5</property>
<property name="bottom_padding">5</property> <property name="bottom_padding">5</property>
@ -454,6 +619,7 @@
<child> <child>
<widget class="GtkVBox" id="vbox2"> <widget class="GtkVBox" id="vbox2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child> <child>
<widget class="GtkCheckButton" id="chk_autoconnect"> <widget class="GtkCheckButton" id="chk_autoconnect">
@ -462,31 +628,30 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
<signal name="toggled" handler="on_chk_autoconnect_toggled"/> <signal name="toggled" handler="on_chk_autoconnect_toggled"/>
</widget> </widget>
<packing> <packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child> <child>
<widget class="GtkAlignment" id="alignment2"> <widget class="GtkCheckButton" id="chk_autostart">
<property name="label" translatable="yes">Automatically start localhost if needed</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="left_padding">15</property> <property name="can_focus">True</property>
<child> <property name="receives_default">False</property>
<widget class="GtkCheckButton" id="chk_autostart"> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Automatically start localhost if needed</property> <property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="draw_indicator">True</property>
<property name="sensitive">False</property> <signal name="toggled" handler="on_chk_autostart_toggled"/>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_chk_autostart_toggled"/>
</widget>
</child>
</widget> </widget>
<packing> <packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
@ -497,10 +662,13 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
<signal name="toggled" handler="on_chk_donotshow_toggled"/> <signal name="toggled" handler="on_chk_donotshow_toggled"/>
</widget> </widget>
<packing> <packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
@ -511,6 +679,7 @@
<child> <child>
<widget class="GtkLabel" id="label2"> <widget class="GtkLabel" id="label2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Options</property> <property name="label" translatable="yes">Options</property>
</widget> </widget>
@ -521,12 +690,14 @@
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
<child> <child>
<widget class="GtkHButtonBox" id="hbuttonbox1"> <widget class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property> <property name="layout_style">end</property>
<child> <child>
<widget class="GtkButton" id="button_close"> <widget class="GtkButton" id="button_close">
@ -535,6 +706,7 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="clicked" handler="on_button_close_clicked"/> <signal name="clicked" handler="on_button_close_clicked"/>
</widget> </widget>
@ -550,6 +722,7 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="clicked" handler="on_button_connect_clicked"/> <signal name="clicked" handler="on_button_connect_clicked"/>
</widget> </widget>
@ -566,92 +739,6 @@
<property name="position">4</property> <property name="position">4</property>
</packing> </packing>
</child> </child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area2">
<property name="sensitive">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="layout_style">end</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="askpassword_dialog">
<property name="border_width">5</property>
<property name="title" translatable="yes">Password Required</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
<property name="default_width">320</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">dialog</property>
<property name="skip_taskbar_hint">True</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox5">
<property name="visible">True</property>
<property name="spacing">2</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<child>
<widget class="GtkImage" id="askpassword_dialog_image">
<property name="visible">True</property>
<property name="stock">gtk-dialog-authentication</property>
<property name="icon-size">6</property>
</widget>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="askpassword_dialog_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="invisible_char">●</property>
<signal name="activate" handler="on_askpassword_dialog_entry_activate"/>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area5">
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
<widget class="GtkButton" id="askpassword_dialog_connect_button">
<property name="label">gtk-connect</property>
<property name="response_id">1</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_askpassword_dialog_connect_button_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</widget> </widget>
</child> </child>
</widget> </widget>

View file

@ -327,14 +327,30 @@ Please see the details below for more information."), details=traceback.format_e
def __start_non_classic(self): def __start_non_classic(self):
# Autoconnect to a host # Autoconnect to a host
if self.config["autoconnect"]: if self.config["autoconnect"]:
for host in self.connectionmanager.config["hosts"]:
if host[0] == self.config["autoconnect_host_id"]: def update_connection_manager():
if not self.connectionmanager.running:
return
self.connectionmanager.glade.get_widget(
"button_refresh"
).emit("clicked")
def close_connection_manager():
if not self.connectionmanager.running:
return
self.connectionmanager.glade.get_widget(
"button_close"
).emit("clicked")
for host_config in self.connectionmanager.config["hosts"]:
hostid, host, port, user, passwd = host_config
if hostid == self.config["autoconnect_host_id"]:
try_connect = True try_connect = True
# Check to see if we need to start the localhost daemon # Check to see if we need to start the localhost daemon
if self.config["autostart_localhost"] and host[1] in ("localhost", "127.0.0.1"): if self.config["autostart_localhost"] and host in ("localhost", "127.0.0.1"):
log.debug("Autostarting localhost:%s", host[2]) log.debug("Autostarting localhost:%s", host)
try_connect = client.start_daemon( try_connect = client.start_daemon(
host[2], deluge.configmanager.get_config_dir() port, deluge.configmanager.get_config_dir()
) )
log.debug("Localhost started: %s", try_connect) log.debug("Localhost started: %s", try_connect)
if not try_connect: if not try_connect:
@ -345,57 +361,54 @@ Please see the details below for more information."), details=traceback.format_e
"to see if there is an error.") "to see if there is an error.")
).run() ).run()
# def refresh_connection_manager_list(): # Daemon Started, let's update it's info
# try: reactor.callLater(0.5, update_connection_manager)
# self.connectionmanager.glade.get_widget(
# "button_refresh"
# ).emit("clicked")
# except:
# pass
#
# reactor.callLatter(1, refresh_connection_manager_list)
def update_connection_manager():
if not self.connectionmanager.running:
return
self.connectionmanager.glade.get_widget(
"button_refresh"
).emit("clicked")
def close_connection_manager():
if not self.connectionmanager.running:
return
self.connectionmanager.glade.get_widget(
"button_close"
).emit("clicked")
def on_connect(connector): def on_connect(connector):
print 'ON GTK UI CONNECT!!!!\n\n'
component.start() component.start()
reactor.callLater(0.5, update_connection_manager) reactor.callLater(0.2, update_connection_manager)
reactor.callLater(1, close_connection_manager) reactor.callLater(0.5, close_connection_manager)
def on_connect_fail(reason, try_counter,
host, port, user, passwd):
if not try_counter:
return
if reason.check(deluge.error.AuthenticationRequired,
deluge.error.BadLoginError):
log.debug("PasswordRequired exception")
dialog = dialogs.AuthenticationDialog(
reason.value.message, reason.value.username
)
def dialog_finished(response_id, host, port):
if response_id == gtk.RESPONSE_OK:
reactor.callLater(
0.5, do_connect, try_counter-1,
host, port, dialog.get_username(),
dialog.get_password())
dialog.run().addCallback(dialog_finished,
host, port)
return
def on_connect_fail(result, try_counter):
log.error("Connection to host failed..") log.error("Connection to host failed..")
# We failed connecting to the daemon, but lets try again log.info("Retrying connection.. Retries left: "
if try_counter: "%s", try_counter)
log.info("Retrying connection.. Retries left: " reactor.callLater(0.5, update_connection_manager)
"%s", try_counter) reactor.callLater(0.5, do_connect, try_counter-1,
try_counter -= 1 host, port, user, passwd)
import time
time.sleep(0.5)
do_connect(try_counter)
reactor.callLater(0.5, update_connection_manager)
return result
def do_connect(try_counter): def do_connect(try_counter, host, port, user, passwd):
d = client.connect(*host[1:]) log.debug("Trying to connect to %s@%s:%s",
user, host, port)
d = client.connect(host, port, user, passwd)
d.addCallback(on_connect) d.addCallback(on_connect)
d.addErrback(on_connect_fail, try_counter) d.addErrback(on_connect_fail, try_counter,
host, port, user, passwd)
if try_connect: if try_connect:
do_connect(6) reactor.callLater(
0.5, do_connect, 6, host, port, user, passwd
)
break break
if self.config["show_connection_manager_on_start"]: if self.config["show_connection_manager_on_start"]: