summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--deluge/core/alertmanager.py3
-rw-r--r--deluge/core/rpcserver.py2
-rw-r--r--deluge/core/torrentmanager.py22
-rw-r--r--deluge/main.py51
-rw-r--r--deluge/plugins/Label/deluge/plugins/label/gtkui/__init__.py3
-rw-r--r--deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py2
-rw-r--r--deluge/ui/gtkui/addtorrentdialog.py9
-rw-r--r--deluge/ui/gtkui/listview.py55
-rw-r--r--deluge/ui/gtkui/mainwindow.py16
-rw-r--r--deluge/ui/gtkui/torrentview.py97
-rw-r--r--deluge/ui/sessionproxy.py2
-rw-r--r--deluge/ui/web/auth.py1
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/ProxyField.js15
14 files changed, 169 insertions, 110 deletions
diff --git a/ChangeLog b/ChangeLog
index 5b080bc78..3af70b95a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -104,6 +104,7 @@
* Fix the Open Folder option not working with non-ascii paths
* Fix the daemon starting with config dir containing spaces
* Fix Windows tray submenu items requiring right-click instead of left-click
+ * Fix issue with adding some torrents with illegal characters via url in gtk client
==== OS X ====
* Fix Open File/Folder option
diff --git a/deluge/core/alertmanager.py b/deluge/core/alertmanager.py
index 970a1506e..bcc60fedf 100644
--- a/deluge/core/alertmanager.py
+++ b/deluge/core/alertmanager.py
@@ -46,6 +46,7 @@ from twisted.internet import reactor
import deluge.component as component
from deluge._libtorrent import lt
+from deluge.common import decode_string
log = logging.getLogger(__name__)
@@ -123,7 +124,7 @@ class AlertManager(component.Component):
alert_type = type(alert).__name__
# Display the alert message
if log.isEnabledFor(logging.DEBUG):
- log.debug("%s: %s", alert_type, alert.message())
+ log.debug("%s: %s", alert_type, decode_string(alert.message()))
# Call any handlers for this alert type
if alert_type in self.handlers:
for handler in self.handlers[alert_type]:
diff --git a/deluge/core/rpcserver.py b/deluge/core/rpcserver.py
index 3ecbd39e8..649c2ce29 100644
--- a/deluge/core/rpcserver.py
+++ b/deluge/core/rpcserver.py
@@ -509,7 +509,7 @@ class RPCServer(component.Component):
"""
log.debug("intevents: %s", self.factory.interested_events)
# Find sessions interested in this event
- for session_id, interest in self.factory.interested_events.iteritems():
+ for session_id, interest in self.factory.interested_events.items():
if event.name in interest:
log.debug("Emit Event: %s %s", event.name, event.args)
# This session is interested so send a RPC_EVENT
diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py
index 3efc9a400..6dafd1939 100644
--- a/deluge/core/torrentmanager.py
+++ b/deluge/core/torrentmanager.py
@@ -57,7 +57,7 @@ from deluge.core.authmanager import AUTH_LEVEL_ADMIN
from deluge.core.torrent import Torrent
from deluge.core.torrent import TorrentOptions
import deluge.core.oldstateupgrader
-from deluge.common import utf8_encoded
+from deluge.common import utf8_encoded, decode_string
log = logging.getLogger(__name__)
@@ -390,7 +390,8 @@ class TorrentManager(component.Component):
resume_data = self.legacy_get_resume_data_from_file(state.torrent_id)
self.legacy_delete_resume_data(state.torrent_id)
- add_torrent_params["resume_data"] = resume_data
+ if resume_data:
+ add_torrent_params["resume_data"] = resume_data
else:
# We have a torrent_info object or magnet uri so we're not loading from state.
if torrent_info:
@@ -970,15 +971,14 @@ class TorrentManager(component.Component):
def on_alert_tracker_reply(self, alert):
if log.isEnabledFor(logging.DEBUG):
- log.debug("on_alert_tracker_reply: %s", alert.message().decode("utf8"))
+ log.debug("on_alert_tracker_reply: %s", decode_string(alert.message()))
try:
torrent = self.torrents[str(alert.handle.info_hash())]
except:
return
# Set the tracker status for the torrent
- if alert.message() != "Got peers from DHT":
- torrent.set_tracker_status(_("Announce OK"))
+ torrent.set_tracker_status(_("Announce OK"))
# Check to see if we got any peer information from the tracker
if alert.handle.status().num_complete == -1 or \
@@ -1003,7 +1003,7 @@ class TorrentManager(component.Component):
torrent = self.torrents[str(alert.handle.info_hash())]
except:
return
- tracker_status = '%s: %s' % (_("Warning"), str(alert.message()))
+ tracker_status = '%s: %s' % (_("Warning"), decode_string(alert.message()))
# Set the tracker status for the torrent
torrent.set_tracker_status(tracker_status)
@@ -1013,7 +1013,7 @@ class TorrentManager(component.Component):
torrent = self.torrents[str(alert.handle.info_hash())]
except:
return
- tracker_status = "%s: %s" % (_("Error"), alert.msg)
+ tracker_status = "%s: %s" % (_("Error"), decode_string(alert.msg))
torrent.set_tracker_status(tracker_status)
def on_alert_storage_moved(self, alert):
@@ -1073,11 +1073,11 @@ class TorrentManager(component.Component):
self.waiting_on_resume_data[torrent_id].callback(None)
def on_alert_save_resume_data_failed(self, alert):
- log.debug("on_alert_save_resume_data_failed: %s", alert.message())
+ log.debug("on_alert_save_resume_data_failed: %s", decode_string(alert.message()))
torrent_id = str(alert.handle.info_hash())
if torrent_id in self.waiting_on_resume_data:
- self.waiting_on_resume_data[torrent_id].errback(Exception(alert.message()))
+ self.waiting_on_resume_data[torrent_id].errback(Exception(decode_string(alert.message())))
def on_alert_file_renamed(self, alert):
log.debug("on_alert_file_renamed")
@@ -1107,7 +1107,7 @@ class TorrentManager(component.Component):
torrent.write_torrentfile()
def on_alert_file_error(self, alert):
- log.debug("on_alert_file_error: %s", alert.message())
+ log.debug("on_alert_file_error: %s", decode_string(alert.message()))
try:
torrent = self.torrents[str(alert.handle.info_hash())]
except:
@@ -1115,7 +1115,7 @@ class TorrentManager(component.Component):
torrent.update_state()
def on_alert_file_completed(self, alert):
- log.debug("file_completed_alert: %s", alert.message())
+ log.debug("file_completed_alert: %s", decode_string(alert.message()))
try:
torrent_id = str(alert.handle.info_hash())
except:
diff --git a/deluge/main.py b/deluge/main.py
index a1525df1c..c68ab3d5e 100644
--- a/deluge/main.py
+++ b/deluge/main.py
@@ -247,27 +247,32 @@ this should be an IP address", metavar="IFACE",
open_logfile()
+ def run_daemon(options, args):
+ try:
+ from deluge.core.daemon import Daemon
+ Daemon(options, args)
+ except deluge.error.DaemonRunningError, e:
+ log.error(e)
+ log.error("You cannot run multiple daemons with the same config directory set.")
+ log.error("If you believe this is an error, you can force a start by deleting %s.", deluge.configmanager.get_config_dir("deluged.pid"))
+ sys.exit(1)
+ except Exception, e:
+ log.exception(e)
+ sys.exit(1)
+
if options.profile:
- import hotshot
- hsp = hotshot.Profile(deluge.configmanager.get_config_dir("deluged.profile"))
- hsp.start()
- try:
- from deluge.core.daemon import Daemon
- Daemon(options, args)
- except deluge.error.DaemonRunningError, e:
- log.error(e)
- log.error("You cannot run multiple daemons with the same config directory set.")
- log.error("If you believe this is an error, you can force a start by deleting %s.", deluge.configmanager.get_config_dir("deluged.pid"))
- sys.exit(1)
- except Exception, e:
- log.exception(e)
- sys.exit(1)
- finally:
- if options.profile:
- hsp.stop()
- hsp.close()
- import hotshot.stats
- stats = hotshot.stats.load(deluge.configmanager.get_config_dir("deluged.profile"))
- stats.strip_dirs()
- stats.sort_stats("time", "calls")
- stats.print_stats(400)
+ import cProfile
+ profiler = cProfile.Profile()
+ profile_output = deluge.configmanager.get_config_dir("deluged.profile")
+
+ # Twisted catches signals to terminate
+ def save_profile_stats():
+ profiler.dump_stats(profile_output)
+ print "Profile stats saved to %s" % profile_output
+
+ from twisted.internet import reactor
+ reactor.addSystemEventTrigger("before", "shutdown", save_profile_stats)
+ print "Running with profiler..."
+ profiler.runcall(run_daemon, options, args)
+ else:
+ run_daemon(options, args)
diff --git a/deluge/plugins/Label/deluge/plugins/label/gtkui/__init__.py b/deluge/plugins/Label/deluge/plugins/label/gtkui/__init__.py
index 8ee0d3c59..bf69e289b 100644
--- a/deluge/plugins/Label/deluge/plugins/label/gtkui/__init__.py
+++ b/deluge/plugins/Label/deluge/plugins/label/gtkui/__init__.py
@@ -74,11 +74,8 @@ class GtkUI(GtkPluginBase):
self.sidebar_menu.unload()
del self.sidebar_menu
-
-
component.get("TorrentView").remove_column(_("Label"))
log.debug(1.1)
- component.get("TorrentView").create_model_filter() #todo:improve.
except Exception, e:
log.debug(e)
diff --git a/deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py b/deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py
index b3e5acbb3..44558fda4 100644
--- a/deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py
+++ b/deluge/plugins/Notifications/deluge/plugins/notifications/gtkui.py
@@ -242,7 +242,7 @@ class GtkUiNotifications(CustomNotifications):
log.debug("Handler for TorrentFinishedEvent GTKUI called. "
"Got Torrent Status")
title = _("Finished Torrent")
- message = _("The torrent \"%(name)s\" including %(num_files)i "
+ message = _("The torrent \"%(name)s\" including %(num_files)i file(s) "
"has finished downloading.") % torrent_status
return title, message
diff --git a/deluge/ui/gtkui/addtorrentdialog.py b/deluge/ui/gtkui/addtorrentdialog.py
index 06bdd6c90..13ac640d6 100644
--- a/deluge/ui/gtkui/addtorrentdialog.py
+++ b/deluge/ui/gtkui/addtorrentdialog.py
@@ -180,7 +180,11 @@ class AddTorrentDialog(component.Component):
self.builder.get_object("button_move_completed_location").hide()
self.builder.get_object("entry_move_completed_path").show()
- self.dialog.set_transient_for(component.get("MainWindow").window)
+ if component.get("MainWindow").is_on_active_workspace():
+ self.dialog.set_transient_for(component.get("MainWindow").window)
+ else:
+ self.dialog.set_transient_for(None)
+
self.dialog.present()
if focus:
self.dialog.window.focus()
@@ -690,8 +694,7 @@ class AddTorrentDialog(component.Component):
# Create a tmp file path
import tempfile
- import os.path
- tmp_file = os.path.join(tempfile.gettempdir(), url.split("/")[-1])
+ (tmp_handle, tmp_file) = tempfile.mkstemp()
def on_part(data, current_length, total_length):
if total_length:
diff --git a/deluge/ui/gtkui/listview.py b/deluge/ui/gtkui/listview.py
index 204f09bdb..120dda3e7 100644
--- a/deluge/ui/gtkui/listview.py
+++ b/deluge/ui/gtkui/listview.py
@@ -237,17 +237,30 @@ class ListView:
model_filter = self.liststore.filter_new()
model_filter.set_visible_column(
self.columns["filter"].column_indices[0])
- sort_info = None
- if self.model_filter:
- sort_info = self.model_filter.get_sort_column_id()
-
self.model_filter = gtk.TreeModelSort(model_filter)
- if sort_info and sort_info[0] and sort_info[1] > -1:
- self.model_filter.set_sort_column_id(sort_info[0], sort_info[1])
- self.set_sort_functions()
self.model_filter.connect("sort-column-changed", self.on_model_sort_changed)
self.model_filter.connect("row-inserted", self.on_model_row_inserted)
self.treeview.set_model(self.model_filter)
+ self.set_sort_functions()
+ self.set_model_sort()
+
+ def set_model_sort(self):
+ column_state = self.get_sort_column_from_state()
+ if column_state:
+ self.treeview.get_model().set_sort_column_id(column_state.sort, column_state.sort_order)
+ # Using the default sort column
+ elif self.default_sort_column_id:
+ self.model_filter.set_sort_column_id(self.default_sort_column_id, gtk.SORT_ASCENDING)
+ self.model_filter.set_default_sort_func(None)
+
+ def get_sort_column_from_state(self):
+ """Find the first (should only be one) state with sort enabled"""
+ if self.state is None:
+ return None
+ for column_state in self.state:
+ if column_state.sort is not None and column_state.sort > -1:
+ return column_state
+ return None
def on_model_sort_changed(self, model):
if self.unique_column_id:
@@ -281,7 +294,6 @@ class ListView:
return cmp(model[iter1][data], model[iter2][data])
def set_sort_functions(self):
- self.model_filter.set_default_sort_func(None)
for column in self.columns.values():
sort_func = column.sort_func or self.generic_sort_func
self.model_filter.set_sort_func(
@@ -297,9 +309,10 @@ class ListView:
position = index
break
sort = None
- sort_id, order = self.model_filter.get_sort_column_id()
- if self.get_column_name(sort_id) == column.get_title():
- sort = sort_id
+ if self.model_filter:
+ sort_id, order = self.model_filter.get_sort_column_id()
+ if self.get_column_name(sort_id) == column.get_title():
+ sort = sort_id
return ListViewColumnState(column.get_title(), position,
column.get_width(), column.get_visible(),
@@ -449,10 +462,6 @@ class ListView:
self.liststore.foreach(copy_row, (new_list, self.columns))
self.liststore = new_list
- # Create the model
- self.create_model_filter()
-
- return
def remove_column(self, header):
"""Removes the column with the name 'header' from the listview"""
@@ -481,10 +490,11 @@ class ListView:
# Create a new liststore
self.create_new_liststore()
+ # Create new model for the treeview
+ self.create_model_filter()
# Re-create the menu
self.create_checklist_menu()
-
return
def add_column(self, header, render, col_types, hidden, position,
@@ -523,6 +533,10 @@ class ListView:
# Create a new list with the added column
self.create_new_liststore()
+ # Happens only on columns added after the torrent list has been loaded
+ if self.model_filter:
+ self.create_model_filter()
+
column = self.TreeviewColumn(header)
if column_type == "text":
@@ -575,11 +589,6 @@ class ListView:
if tooltip:
column.get_widget().set_tooltip_markup(tooltip)
- if default_sort:
- if self.model_filter.get_sort_column_id()[0] is None:
- self.model_filter.set_sort_column_id(column_indices[sortid],
- gtk.SORT_ASCENDING)
-
# Check for loaded state and apply
column_in_state = False
if self.state != None:
@@ -591,10 +600,6 @@ class ListView:
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_fixed_width(column_state.width)
- if column_state.sort is not None and column_state.sort > -1:
- self.model_filter.set_sort_column_id(
- column_state.sort, column_state.sort_order
- )
column.set_visible(column_state.visible)
position = column_state.position
break
diff --git a/deluge/ui/gtkui/mainwindow.py b/deluge/ui/gtkui/mainwindow.py
index d491441d0..4d07a5750 100644
--- a/deluge/ui/gtkui/mainwindow.py
+++ b/deluge/ui/gtkui/mainwindow.py
@@ -42,6 +42,11 @@ import gtk
import logging
import urllib
+try:
+ import wnck
+except ImportError:
+ wnck = None
+
from deluge.ui.client import client
import deluge.component as component
from deluge.configmanager import ConfigManager
@@ -76,6 +81,8 @@ class _GtkBuilderSignalsHolder(object):
class MainWindow(component.Component):
def __init__(self):
+ if wnck:
+ self.screen = wnck.screen_get_default()
component.Component.__init__(self, "MainWindow", interval=2)
self.config = ConfigManager("gtkui.conf")
self.gtk_builder_signals_holder = _GtkBuilderSignalsHolder()
@@ -167,7 +174,6 @@ class MainWindow(component.Component):
component.resume("TorrentDetails")
except:
pass
-
self.window.show()
@@ -324,3 +330,11 @@ class MainWindow(component.Component):
def on_torrentfinished_event(self, torrent_id):
from deluge.ui.gtkui.notification import Notification
Notification().notify(torrent_id)
+
+ def is_on_active_workspace(self):
+ # Returns True if mainwindow is on active workspace or wnck module not available
+ if not wnck:
+ return True
+ for win in self.screen.get_windows():
+ if win.get_xid() == self.window.window.xid:
+ return win.is_on_workspace(win.get_screen().get_active_workspace())
diff --git a/deluge/ui/gtkui/torrentview.py b/deluge/ui/gtkui/torrentview.py
index 79fd99831..b75f593fc 100644
--- a/deluge/ui/gtkui/torrentview.py
+++ b/deluge/ui/gtkui/torrentview.py
@@ -452,18 +452,12 @@ class TorrentView(listview.ListView, component.Component):
{}, status_fields).addCallback(self._on_session_state)
def _on_session_state(self, state):
- self.treeview.freeze_child_notify()
- model = self.treeview.get_model()
- for torrent_id in state:
- self.add_row(torrent_id, update=False)
- self.mark_dirty(torrent_id)
- self.treeview.set_model(model)
- self.treeview.thaw_child_notify()
+ self.add_rows(state)
self.got_state = True
# Update the view right away with our status
self.status = state
self.set_columns_to_update()
- self.update_view()
+ self.update_view(load_new_list=True)
def stop(self):
"""Stops the torrentview"""
@@ -551,43 +545,66 @@ class TorrentView(listview.ListView, component.Component):
# Send a status request
gobject.idle_add(self.send_status_request)
- def update_view(self, columns=None):
- """Update the view. If columns is not None, it will attempt to only
- update those columns selected.
- """
+ def update_view(self, load_new_list=False):
+ """Update the torrent view model with data we've received."""
filter_column = self.columns["filter"].column_indices[0]
- # Update the torrent view model with data we've received
status = self.status
+ if not load_new_list:
+ # Freeze notications while updating
+ self.treeview.freeze_child_notify()
+
+ # Get the columns to update from one of the torrents
+ if status:
+ torrent_id = status.keys()[0]
+ fields_to_update = []
+ for column in self.columns_to_update:
+ column_index = self.get_column_index(column)
+ for i, status_field in enumerate(self.columns[column].status_field):
+ # Only use columns that the torrent has in the state
+ if status_field in status[torrent_id]:
+ fields_to_update.append((column_index[i], status_field))
+
for row in self.liststore:
torrent_id = row[self.columns["torrent_id"].column_indices[0]]
+ # We expect the torrent_id to be in status and prev_status,
+ # as it will be as long as the list isn't changed by the user
- if not torrent_id in status.keys():
- row[filter_column] = False
- else:
- row[filter_column] = True
- if torrent_id in self.prev_status and status[torrent_id] == self.prev_status[torrent_id]:
- # The status dict is the same, so do not update
+ torrent_id_in_status = False
+ try:
+ torrent_status = status[torrent_id]
+ torrent_id_in_status = True
+ if torrent_status == self.prev_status[torrent_id]:
+ # The status dict is the same, so do nothing to update for this torrent
continue
+ except KeyError, e:
+ pass
- # Set values for each column in the row
- for column in self.columns_to_update:
- column_index = self.get_column_index(column)
- for i, status_field in enumerate(self.columns[column].status_field):
- if status_field in status[torrent_id]:
- try:
- # Only update if different
- row_value = status[torrent_id][status_field]
- if row[column_index[i]] != row_value:
- row[column_index[i]] = row_value
- except Exception, e:
- log.debug("Error while updating row for column "
- "index %d, status field %r, value %r:"
- " %s", column_index[0], status_field,
- row_value, e)
+ if not torrent_id_in_status:
+ if row[filter_column] is True:
+ row[filter_column] = False
+ else:
+ if row[filter_column] is False:
+ row[filter_column] = True
+
+ # Find the fields to update
+ to_update = []
+ for i, status_field in fields_to_update:
+ row_value = status[torrent_id][status_field]
+ if row[i] != row_value:
+ to_update.append(i)
+ to_update.append(row_value)
+ # Update fields in the liststore
+ if to_update:
+ self.liststore.set(row.iter, *to_update)
+
+ if load_new_list:
+ # Create the model filter. This sets the model for the treeview and enables sorting.
+ self.create_model_filter()
+ else:
+ self.treeview.thaw_child_notify()
component.get("MenuBar").update_menu()
-
self.prev_status = status
def _on_get_torrents_status(self, status):
@@ -602,6 +619,16 @@ class TorrentView(listview.ListView, component.Component):
return
gobject.idle_add(self.update_view)
+ def add_rows(self, state):
+ """Adds all the torrents from state to self.liststore"""
+ torrent_id_column = self.columns["torrent_id"].column_indices[0]
+ dirty_column = self.columns["dirty"].column_indices[0]
+ filter_column = self.columns["filter"].column_indices[0]
+ for i, torrent_id in enumerate(state):
+ # Insert a new row to the liststore
+ row = self.liststore.append()
+ self.liststore.set(row, torrent_id_column, torrent_id, dirty_column, True, filter_column, True)
+
def add_row(self, torrent_id, update=True):
"""Adds a new torrent row to the treeview"""
# Make sure this torrent isn't already in the list
diff --git a/deluge/ui/sessionproxy.py b/deluge/ui/sessionproxy.py
index 676dfabb7..0b5234704 100644
--- a/deluge/ui/sessionproxy.py
+++ b/deluge/ui/sessionproxy.py
@@ -65,11 +65,11 @@ class SessionProxy(component.Component):
# Holds the time of the last key update.. {torrent_id: {key1, time, ...}, ...}
self.cache_times = {}
+ def start(self):
client.register_event_handler("TorrentStateChangedEvent", self.on_torrent_state_changed)
client.register_event_handler("TorrentRemovedEvent", self.on_torrent_removed)
client.register_event_handler("TorrentAddedEvent", self.on_torrent_added)
- def start(self):
def on_get_session_state(torrent_ids):
for torrent_id in torrent_ids:
# Let's at least store the torrent ids with empty statuses
diff --git a/deluge/ui/web/auth.py b/deluge/ui/web/auth.py
index 5cd345e2c..e26eab486 100644
--- a/deluge/ui/web/auth.py
+++ b/deluge/ui/web/auth.py
@@ -322,4 +322,5 @@ class Auth(JSONComponent):
if self.check_password(password):
return self._create_session(__request__)
else:
+ log.error('Login failed (ClientIP %s)', __request__.getClientIP())
return False
diff --git a/deluge/ui/web/js/deluge-all/preferences/ProxyField.js b/deluge/ui/web/js/deluge-all/preferences/ProxyField.js
index 811372128..fe969b9ba 100644
--- a/deluge/ui/web/js/deluge-all/preferences/ProxyField.js
+++ b/deluge/ui/web/js/deluge-all/preferences/ProxyField.js
@@ -1,6 +1,6 @@
/*!
* Deluge.preferences.ProxyField.js
- *
+ *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -58,19 +58,23 @@ Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
[3, _('Socksv5 with Auth')],
[4, _('HTTP')],
[5, _('HTTP with Auth')]
- ]
- }),
+ ]
+ }),
editable: false,
triggerAction: 'all',
valueField: 'id',
displayField: 'text'
});
+ this.proxyType.on('change', this.onFieldChange, this);
+ this.proxyType.on('select', this.onTypeSelect, this);
+
this.hostname = this.add({
xtype: 'textfield',
name: 'hostname',
fieldLabel: _('Host'),
width: 220
});
+ this.hostname.on('change', this.onFieldChange, this);
this.port = this.add({
xtype: 'spinnerfield',
@@ -81,6 +85,7 @@ Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
minValue: -1,
maxValue: 99999
});
+ this.port.on('change', this.onFieldChange, this);
this.username = this.add({
xtype: 'textfield',
@@ -88,6 +93,7 @@ Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
fieldLabel: _('Username'),
width: 220
});
+ this.username.on('change', this.onFieldChange, this);
this.password = this.add({
xtype: 'textfield',
@@ -96,9 +102,8 @@ Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
inputType: 'password',
width: 220
});
+ this.password.on('change', this.onFieldChange, this);
- this.proxyType.on('change', this.onFieldChange, this);
- this.proxyType.on('select', this.onTypeSelect, this);
this.setting = false;
},