diff --git a/deluge/ui/gtkui/glade/preferences/bandwidth.glade b/deluge/ui/gtkui/glade/preferences/bandwidth.glade
new file mode 100644
index 000000000..6349e4376
--- /dev/null
+++ b/deluge/ui/gtkui/glade/preferences/bandwidth.glade
@@ -0,0 +1,490 @@
+
+
+
+
+
+
+ -1
+ 9000
+ 1
+ 10
+
+
+ -1
+ 9000
+ 1
+ 10
+
+
+ -1
+ 9000
+ 1
+ 10
+
+
+ -1
+ 9000
+ 1
+ 10
+
+
+ -1
+ 9000
+ 1
+ 10
+
+
+ -1
+ 60000
+ 1
+ 10
+
+
+ -1
+ 60000
+ 1
+ 10
+
+
+ -1
+ 9000
+ 1
+ 10
+
+
+ -1
+ 9999
+ 1
+ 10
+
+
+ -1
+ 9999
+ 1
+ 10
+
+
diff --git a/deluge/ui/gtkui/glade/preferences/cache.glade b/deluge/ui/gtkui/glade/preferences/cache.glade
new file mode 100644
index 000000000..f57e22597
--- /dev/null
+++ b/deluge/ui/gtkui/glade/preferences/cache.glade
@@ -0,0 +1,474 @@
+
+
+
+
+
+
+
+ True
+ vertical
+
+
+ True
+ 0
+ none
+
+
+ True
+ 5
+ 12
+
+
+ True
+ 2
+ 2
+ 5
+
+
+ True
+ 0
+ Cache Size (16 KiB blocks):
+
+
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Cache Expiry (seconds):
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ True
+ ●
+ 1
+ True
+ if-valid
+
+
+ 1
+ 2
+
+
+
+
+
+ True
+ True
+ 5
+ ●
+ 5
+ 1
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+
+
+
+
+
+ True
+ <b>Settings</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 0
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 5
+ 12
+
+
+ True
+ vertical
+
+
+ True
+ 0
+ none
+
+
+ True
+ 12
+
+
+ True
+ 3
+ 2
+ 5
+
+
+ True
+ 0
+ Blocks Written:
+
+
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Writes:
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Write Cache Hit Ratio:
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ 1
+
+
+ 1
+ 2
+
+
+
+
+
+ True
+ 1
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+
+ True
+ 1
+
+
+ 1
+ 2
+ 2
+ 3
+
+
+
+
+
+
+
+
+
+ True
+ <b>Write</b>
+ True
+
+
+
+
+ 0
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 12
+
+
+ True
+ 4
+ 2
+ 5
+
+
+ True
+ 0
+ Blocks Read:
+
+
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Blocks Read Hit:
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Read Cache Hit Ratio:
+
+
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+ True
+ 1
+
+
+ 1
+ 2
+
+
+
+
+
+ True
+ 1
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+
+ True
+ 1
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+
+ True
+ 0
+ Reads:
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+
+
+ 1
+ 2
+ 2
+ 3
+
+
+
+
+
+
+
+
+
+ True
+ <b>Read</b>
+ True
+
+
+
+
+ 1
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 12
+
+
+ True
+ 2
+ 2
+ 5
+
+
+ True
+ 0
+ Cache Size:
+
+
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Read Cache Size:
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ 1
+
+
+ 1
+ 2
+
+
+
+
+
+ True
+ 1
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+
+
+
+
+
+ True
+ <b>Size</b>
+ True
+
+
+
+
+ 2
+
+
+
+
+ True
+ start
+
+
+ gtk-refresh
+ True
+ True
+ True
+ True
+
+
+ False
+ False
+ 0
+
+
+
+
+ 3
+
+
+
+
+
+
+
+
+ True
+ <b>Status</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 1
+
+
+
+
+
+
+ 1
+ 32000
+ 1
+ 10
+
+
+ 99999
+ 1
+ 10
+
+
diff --git a/deluge/ui/gtkui/glade/preferences/daemon.glade b/deluge/ui/gtkui/glade/preferences/daemon.glade
new file mode 100644
index 000000000..d7ed1f25f
--- /dev/null
+++ b/deluge/ui/gtkui/glade/preferences/daemon.glade
@@ -0,0 +1,174 @@
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ none
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 2
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ Daemon port:
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+ 1
+
+
+ False
+ False
+ 1
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>Port</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 0
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ none
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ 10
+
+
+ Allow Remote Connections
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>Connections</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 1
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ none
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ 10
+
+
+ Periodically check the website for new releases
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>Other</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 2
+
+
+
+
+
+
+ 65535
+ 1
+ 10
+
+
diff --git a/deluge/ui/gtkui/glade/preferences/downloads.glade b/deluge/ui/gtkui/glade/preferences/downloads.glade
new file mode 100644
index 000000000..afd228bfc
--- /dev/null
+++ b/deluge/ui/gtkui/glade/preferences/downloads.glade
@@ -0,0 +1,393 @@
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ 0
+ none
+
+
+ True
+ 2
+ 2
+ 12
+
+
+ True
+ 5
+ 2
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ select-folder
+
+
+ 0
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+
+
+ 1
+
+
+
+
+
+
+ 1
+ 2
+ 2
+ 3
+
+
+
+
+ True
+
+
+ True
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ select-folder
+ Select A Folder
+
+
+ 0
+
+
+
+
+ True
+ ●
+
+
+ 1
+
+
+
+
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+ Auto add .torrents from:
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ Move completed to:
+ True
+ True
+ False
+ True
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ select-folder
+ Select A Folder
+
+
+ 0
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+
+
+ 1
+
+
+
+
+ 1
+ 2
+
+
+
+
+ True
+ 0
+ Download to:
+
+
+ GTK_FILL
+
+
+
+
+ Copy of .torrent files to:
+ True
+ True
+ False
+ True
+
+
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ select-folder
+ Select A Folder
+
+
+ 0
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+
+
+ 1
+
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+ Delete copy of torrent file on remove
+ True
+ True
+ False
+ True
+
+
+ 2
+ 4
+ 5
+ 15
+
+
+
+
+
+
+
+
+ True
+ <b>Folders</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 0
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 2
+ 2
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 10
+
+
+ Use Full Allocation
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+ True
+
+
+ False
+ False
+ 0
+
+
+
+
+ Use Compact Allocation
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+ radio_full_allocation
+
+
+ False
+ False
+ 1
+
+
+
+
+
+
+
+
+ True
+ <b>Allocation</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 1
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 2
+ 2
+ 12
+
+
+ True
+ vertical
+
+
+ Prioritize first and last pieces of torrent
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+ False
+ 0
+
+
+
+
+ Add torrents in Paused state
+ True
+ True
+ False
+ True
+
+
+ 1
+
+
+
+
+
+
+
+
+ True
+ <b>Options</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 2
+
+
+
+
+
+
diff --git a/deluge/ui/gtkui/glade/preferences/interface.glade b/deluge/ui/gtkui/glade/preferences/interface.glade
new file mode 100644
index 000000000..69ed50acc
--- /dev/null
+++ b/deluge/ui/gtkui/glade/preferences/interface.glade
@@ -0,0 +1,322 @@
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ none
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 2
+ 2
+ 12
+
+
+ Enable
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>Classic Mode</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 0
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 2
+ 2
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ Show session speed in titlebar
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+ 0
+
+
+
+
+
+
+
+
+ True
+ <b>Main Window</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 1
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 2
+ 2
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ Always show
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+ 0
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+ Bring the dialog to focus
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ True
+ <b>Add Torrents Dialog</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 2
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 2
+ 2
+ 12
+
+
+ True
+ vertical
+
+
+ Enable system tray icon
+ True
+ True
+ False
+ True
+ True
+
+
+ 0
+
+
+
+
+ True
+ 10
+
+
+ Minimize to tray on close
+ True
+ False
+ True
+ False
+ True
+ True
+
+
+
+
+ 1
+
+
+
+
+ True
+ 10
+
+
+ Start in tray
+ True
+ False
+ True
+ False
+ True
+ True
+
+
+
+
+ 2
+
+
+
+
+ True
+ 3
+ 10
+
+
+ Password protect system tray
+ True
+ False
+ True
+ False
+ True
+ True
+
+
+
+
+ False
+ 3
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 20
+
+
+ True
+ 5
+
+
+ True
+ False
+ 0
+ Password:
+
+
+ False
+ 0
+
+
+
+
+ True
+ False
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ False
+ ●
+ 16
+ ********
+
+
+ False
+ 1
+
+
+
+
+
+
+ 4
+
+
+
+
+
+
+
+
+ True
+ <b>System Tray</b>
+ True
+
+
+
+
+ False
+ 5
+ 3
+
+
+
+
+
+
diff --git a/deluge/ui/gtkui/glade/preferences/network.glade b/deluge/ui/gtkui/glade/preferences/network.glade
new file mode 100644
index 000000000..b1e45f703
--- /dev/null
+++ b/deluge/ui/gtkui/glade/preferences/network.glade
@@ -0,0 +1,799 @@
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ 0
+ none
+
+
+ True
+ 2
+ 2
+ 12
+
+
+ True
+ vertical
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 20
+
+
+ Use Random Ports
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+ False
+ 5
+ 0
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+ True
+ 1
+ Active Port:
+ right
+
+
+ False
+ 5
+ 0
+
+
+
+
+ True
+ 0
+ 0000
+ 5
+
+
+ False
+ 5
+ 1
+
+
+
+
+ False
+ 5
+ 1
+
+
+
+
+ 5
+ 0
+
+
+
+
+ True
+
+
+ True
+ From:
+
+
+ False
+ 0
+
+
+
+
+ True
+ False
+ True
+ 5
+ ●
+ 1
+ adjustment28
+ 1
+ True
+ True
+
+
+ False
+ 5
+ 1
+
+
+
+
+ True
+ 5
+ To:
+
+
+ False
+ False
+ 2
+
+
+
+
+ True
+ False
+ True
+ 5
+ ●
+ 1
+ adjustment27
+ 1
+ True
+ True
+
+
+ False
+ 5
+ 3
+
+
+
+
+ Test Active Port
+ True
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+ False
+ False
+ 4
+
+
+
+
+ True
+ 5
+
+
+ gtk-missing-image
+
+
+
+
+ False
+ 5
+
+
+
+
+ 5
+ 1
+
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>Incoming Ports</b>
+ True
+
+
+
+
+ False
+ 5
+ 0
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 5
+ 12
+
+
+ True
+ vertical
+ 5
+
+
+ Use Random Ports
+ True
+ True
+ False
+ True
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ 5
+
+
+ True
+ From:
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ False
+ True
+ 5
+ ●
+ 1
+ adjustment26
+ 1
+ True
+ True
+
+
+ False
+ 5
+ 1
+
+
+
+
+ True
+ To:
+
+
+ False
+ False
+ 2
+
+
+
+
+ True
+ False
+ True
+ 5
+ ●
+ 1
+ adjustment25
+ 1
+ True
+ True
+
+
+ False
+ 5
+ 3
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ True
+ <b>Outgoing Ports</b>
+ True
+
+
+
+
+ False
+ False
+ 1
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 2
+ 2
+ 12
+
+
+ True
+
+
+ True
+ True
+ 60
+ ●
+ 30
+
+
+ False
+ False
+ 0
+
+
+
+
+
+
+
+
+
+
+
+ True
+ <b>Interface</b>
+ True
+
+
+
+
+ False
+ False
+ 2
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 2
+ 2
+ 12
+
+
+ True
+ vertical
+
+
+ True
+ 5
+
+
+ True
+ Peer TOS Byte:
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ True
+ ●
+ 4
+ 0x00
+
+
+ False
+ False
+ 1
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+ True
+ <b>TOS</b>
+ True
+
+
+
+
+ False
+ 5
+ 3
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 2
+ 2
+ 12
+
+
+ True
+ 2
+ 3
+ 5
+
+
+ UPnP
+ True
+ True
+ False
+ True
+ True
+ True
+
+
+ GTK_FILL
+
+
+
+
+ NAT-PMP
+ True
+ True
+ False
+ True
+ True
+ True
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ Peer Exchange
+ True
+ True
+ False
+ True
+ True
+ True
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ LSD
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ DHT
+ True
+ True
+ False
+ True
+ True
+
+
+ 1
+ 2
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+
+
+
+
+
+
+ True
+ <b>Network Extras</b>
+ True
+
+
+
+
+ False
+ 5
+ 4
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 2
+ 2
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ 1
+ Inbound:
+
+
+ 0
+
+
+
+
+ True
+ 0
+ Level:
+
+
+ 1
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ liststore7
+
+
+
+ 0
+
+
+
+
+ 0
+
+
+
+
+ True
+ liststore6
+
+
+
+ 0
+
+
+
+
+ 1
+
+
+
+
+ False
+ False
+ 1
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+ True
+ 1
+ Outbound:
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ liststore5
+
+
+
+ 0
+
+
+
+
+ False
+ 1
+
+
+
+
+ 0
+
+
+
+
+ Encrypt entire stream
+ True
+ True
+ False
+ True
+ True
+
+
+ False
+ 3
+ 1
+
+
+
+
+ 2
+
+
+
+
+
+
+
+
+ True
+ <b>Encryption</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 5
+
+
+
+
+
+
+
+
+
+
+
+
+ Forced
+
+
+ Enabled
+
+
+ Disabled
+
+
+
+
+
+
+
+
+
+
+ Handshake
+
+
+ Full Stream
+
+
+ Either
+
+
+
+
+
+
+
+
+
+
+ Forced
+
+
+ Enabled
+
+
+ Disabled
+
+
+
+
+ 65535
+ 1
+ 10
+
+
+ 65535
+ 1
+ 10
+
+
+ 65535
+ 1
+ 10
+
+
+ 65535
+ 1
+ 10
+
+
diff --git a/deluge/ui/gtkui/glade/preferences/other.glade b/deluge/ui/gtkui/glade/preferences/other.glade
new file mode 100644
index 000000000..ecb9145a0
--- /dev/null
+++ b/deluge/ui/gtkui/glade/preferences/other.glade
@@ -0,0 +1,273 @@
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ none
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 2
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+ Be alerted about new releases
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>Updates</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 0
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ none
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 2
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Help us improve Deluge by sending us your Python version, PyGTK version, OS and processor types. Absolutely no other information is sent.
+ True
+
+
+ False
+ False
+ 2
+ 0
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 10
+
+
+ Yes, please send anonymous statistics
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+
+
+ False
+ 1
+
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>System Information</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 1
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ none
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 2
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+ True
+ 5
+
+
+ True
+ Location:
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ True
+ ●
+
+
+ 1
+
+
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>GeoIP Database</b>
+ True
+
+
+
+
+ False
+ False
+ 5
+ 2
+
+
+
+
+ True
+ 12
+
+
+ True
+ start
+
+
+ True
+ True
+ True
+
+
+ True
+ 2
+
+
+ True
+ gtk-missing-image
+
+
+ 0
+
+
+
+
+ True
+ Associate Magnet links with Deluge
+
+
+ 1
+
+
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+
+
+ False
+ False
+ 3
+
+
+
+
+
+
diff --git a/deluge/ui/gtkui/glade/preferences/plugins.glade b/deluge/ui/gtkui/glade/preferences/plugins.glade
new file mode 100644
index 000000000..3981e9520
--- /dev/null
+++ b/deluge/ui/gtkui/glade/preferences/plugins.glade
@@ -0,0 +1,367 @@
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+ 1
+
+
+ True
+ True
+ automatic
+ automatic
+ in
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+
+
+ False
+ True
+
+
+
+
+ True
+ True
+ automatic
+ automatic
+
+
+ True
+ queue
+ none
+
+
+ True
+ 0
+ none
+
+
+ True
+ 12
+
+
+ True
+ 5
+ 2
+ 5
+
+
+ True
+ 0
+
+
+ 1
+ 2
+ 4
+ 5
+
+
+
+
+
+ True
+ 0
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+
+ True
+ 0
+
+
+ 1
+ 2
+
+
+
+
+
+ True
+ 0
+ 0
+ Details:
+
+
+ 4
+ 5
+ GTK_FILL
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Version:
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+ True
+ 0
+ Author:
+
+
+ GTK_FILL
+
+
+
+
+
+ True
+ 0
+ Homepage:
+
+
+ 3
+ 4
+ GTK_FILL
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Author Email:
+
+
+ 2
+ 3
+ GTK_FILL
+ GTK_FILL
+
+
+
+
+ True
+ 0
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+
+ True
+ 0
+
+
+ 1
+ 2
+ 2
+ 3
+
+
+
+
+
+
+
+
+
+ True
+ <b>Info</b>
+ True
+
+
+
+
+
+
+
+
+ False
+ False
+
+
+
+
+ 0
+
+
+
+
+ True
+ center
+
+
+ True
+ True
+ True
+
+
+ True
+ 5
+
+
+ True
+ gtk-add
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ _Install Plugin
+ True
+ True
+
+
+ False
+ False
+ 1
+
+
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ True
+ True
+
+
+ True
+ 5
+
+
+ True
+ gtk-refresh
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ _Rescan Plugins
+ True
+ True
+
+
+ False
+ False
+ 1
+
+
+
+
+
+
+ False
+ False
+ 1
+
+
+
+
+ False
+ False
+ 1
+
+
+
+
+ True
+
+
+ True
+ True
+ True
+
+
+ True
+ 5
+
+
+ True
+ gtk-find
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ _Find More Plugins
+ True
+ True
+
+
+ False
+ False
+ 1
+
+
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+ False
+ False
+ 2
+
+
+
+
+
+
diff --git a/deluge/ui/gtkui/glade/preferences/proxy.glade b/deluge/ui/gtkui/glade/preferences/proxy.glade
new file mode 100644
index 000000000..dc220dd1b
--- /dev/null
+++ b/deluge/ui/gtkui/glade/preferences/proxy.glade
@@ -0,0 +1,874 @@
+
+
+
+
+
+
+
+ True
+ vertical
+ 5
+
+
+ True
+ 0
+ none
+
+
+ True
+ 12
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ 2
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Password:
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ False
+ ●
+
+
+ 1
+ 2
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Host:
+
+
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+ True
+ 0
+ Port:
+
+
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ 0
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+ True
+
+
+
+
+ 1
+ 2
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+
+
+ 1
+ 2
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+
+ 0
+
+
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Type:
+
+
+ GTK_FILL
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Username:
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+
+
+
+ True
+ <b>Peer</b>
+ True
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 12
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ 2
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Password:
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ False
+ ●
+
+
+ 1
+ 2
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Host:
+
+
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+ True
+ 0
+ Port:
+
+
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ 0
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+ True
+
+
+
+
+ 1
+ 2
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+
+
+ 1
+ 2
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+
+ 0
+
+
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Type:
+
+
+ GTK_FILL
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Username:
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+
+
+
+ True
+ <b>Web Seed</b>
+ True
+
+
+
+
+ False
+ False
+ 1
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 12
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ 2
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Password:
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ False
+ ●
+
+
+ 1
+ 2
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Host:
+
+
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+ True
+ 0
+ Port:
+
+
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ 0
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+ True
+
+
+
+
+ 1
+ 2
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+
+
+ 1
+ 2
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+
+ 0
+
+
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Type:
+
+
+ GTK_FILL
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Username:
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+
+
+
+ True
+ <b>Tracker</b>
+ True
+
+
+
+
+ False
+ False
+ 2
+
+
+
+
+ True
+ 0
+ none
+
+
+ True
+ 12
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ 2
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Password:
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ False
+ ●
+
+
+ 1
+ 2
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Host:
+
+
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+ True
+ 0
+ Port:
+
+
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+
+ True
+ 0
+ 0
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+ True
+
+
+
+
+ 1
+ 2
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+
+
+ 1
+ 2
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+
+ 0
+
+
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Type:
+
+
+ GTK_FILL
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Username:
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+
+
+
+
+ True
+ <b>DHT</b>
+ True
+
+
+
+
+ False
+ False
+ 3
+
+
+
+
+
+
+ 65535
+ 1
+ 10
+
+
+ 65535
+ 1
+ 10
+
+
+ 65535
+ 1
+ 10
+
+
+ 65535
+ 1
+ 10
+
+
+
+
+
+
+
+
+ None
+
+
+ Socksv4
+
+
+ Socksv5
+
+
+ Socksv5 W/ Auth
+
+
+ HTTP
+
+
+ HTTP W/ Auth
+
+
+
+
+
+
+
+
+
+
+ None
+
+
+ Socksv4
+
+
+ Socksv5
+
+
+ Socksv5 W/ Auth
+
+
+ HTTP
+
+
+ HTTP W/ Auth
+
+
+
+
+
+
+
+
+
+
+ None
+
+
+ Socksv4
+
+
+ Socksv5
+
+
+ Socksv5 W/ Auth
+
+
+ HTTP
+
+
+ HTTP W/ Auth
+
+
+
+
+
+
+
+
+
+
+ None
+
+
+ Socksv4
+
+
+ Socksv5
+
+
+ Socksv5 W/ Auth
+
+
+ HTTP
+
+
+ HTTP W/ Auth
+
+
+
+
diff --git a/deluge/ui/gtkui/glade/preferences/queue.glade b/deluge/ui/gtkui/glade/preferences/queue.glade
new file mode 100644
index 000000000..017022a64
--- /dev/null
+++ b/deluge/ui/gtkui/glade/preferences/queue.glade
@@ -0,0 +1,449 @@
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ none
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+
+
+ Queue new torrents to top
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+ 0
+
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>General</b>
+ True
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ none
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ 12
+
+
+ True
+ vertical
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 3
+ 2
+ 10
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+ 1
+ True
+ True
+
+
+ 1
+ 2
+
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+ 1
+ True
+ True
+
+
+ 1
+ 2
+ 2
+ 3
+
+
+
+
+
+ True
+ 0
+ Total active seeding:
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Total active:
+
+
+ GTK_FILL
+
+
+
+
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+ 1
+ True
+ True
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ Total active downloading:
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ 0
+
+
+
+
+ Do not count slow torrents
+ True
+ True
+ False
+ True
+
+
+ 1
+
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>Active Torrents</b>
+ True
+
+
+
+
+ False
+ False
+ 1
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ none
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ 12
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ vertical
+ 2
+
+
+ True
+ 3
+ 2
+ 10
+
+
+ True
+ 0
+ Share Ratio Limit:
+
+
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Seed Time Ratio:
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ Seed Time (m):
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ True
+ ●
+ 6
+ 1
+ 2
+
+
+ 1
+ 2
+
+
+
+
+
+ True
+ True
+ ●
+ 6
+ 1
+ 2
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+
+ True
+ True
+ ●
+ 6
+ 1
+
+
+ 1
+ 2
+ 2
+ 3
+
+
+
+
+
+ 0
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ Stop seeding when share ratio reaches:
+ True
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ False
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ ●
+ 1
+ 2
+ True
+
+
+ False
+ False
+ 1
+
+
+
+
+ False
+ False
+ 1
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 10
+
+
+ Remove torrent when share ratio reached
+ True
+ False
+ True
+ False
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+
+
+ 2
+
+
+
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>Seeding</b>
+ True
+
+
+
+
+ False
+ False
+ 2
+
+
+
+
+
+
+ 0.5
+ 100
+ 0.10000000000000001
+ 1
+
+
+ -1
+ 10000
+ 1
+ 10
+
+
+ -1
+ 100
+ 0.10000000000000001
+ 10
+
+
+ -1
+ 100
+ 0.10000000000000001
+ 10
+
+
+ -1
+ 9999
+ 1
+ 10
+
+
+ -1
+ 9999
+ 1
+ 10
+
+
+ -1
+ 9999
+ 1
+ 10
+
+
diff --git a/deluge/ui/gtkui/preferences.py b/deluge/ui/gtkui/preferences.py
index a13937a2d..6eb0063c4 100644
--- a/deluge/ui/gtkui/preferences.py
+++ b/deluge/ui/gtkui/preferences.py
@@ -1,7 +1,7 @@
#
# preferences.py
#
-# Copyright (C) 2007, 2008 Andrew Resch
+# Copyright (C) 2007-2010 Andrew Resch
#
# Deluge is free software.
#
@@ -33,99 +33,59 @@
#
#
-
-import pygtk
-pygtk.require('2.0')
+import os
import gtk
-import gtk.glade
+
import logging
import pkg_resources
+from twisted.internet.defer import maybeDeferred
import deluge.component as component
+import dialogs
from deluge.ui.client import client
import deluge.common
import deluge.error
import common
-from deluge.configmanager import ConfigManager
-import deluge.configmanager
log = logging.getLogger(__name__)
-class Preferences(component.Component):
+class PreferencePage(object):
+ """
+ Must set a name and widget prior to adding to them Preferences dialog.
+ """
def __init__(self):
- component.Component.__init__(self, "Preferences")
- self.window = component.get("MainWindow")
- self.glade = gtk.glade.XML(pkg_resources.resource_filename(
- "deluge.ui.gtkui", "glade/preferences_dialog.glade"
- ))
- self.pref_dialog = self.glade.get_widget("pref_dialog")
- self.pref_dialog.set_icon(common.get_deluge_icon())
- self.treeview = self.glade.get_widget("treeview")
- self.notebook = self.glade.get_widget("notebook")
- self.gtkui_config = ConfigManager("gtkui.conf")
+ self.name = ""
+ self.widget = None
+ self.builder = None
- self.glade.get_widget("image_magnet").set_from_file(
- deluge.common.get_pixmap("magnet.png"))
+ # Set the core widgets and their config keys
+ # {widget: (accessor, core_key, non_localhost_widget), ...}
+ self.core_widgets = {}
+ # Likewise for local widgets
+ self.local_widgets = {}
- # Setup the liststore for the categories (tab pages)
- self.liststore = gtk.ListStore(int, str)
- self.treeview.set_model(self.liststore)
- render = gtk.CellRendererText()
- column = gtk.TreeViewColumn(_("Categories"), render, text=1)
- self.treeview.append_column(column)
- # Add the default categories
- i = 0
- for category in [_("Downloads"), _("Network"), _("Bandwidth"),
- _("Interface"), _("Other"), _("Daemon"), _("Queue"), _("Proxy"),
- _("Cache"), _("Plugins")]:
- self.liststore.append([i, category])
- i += 1
+ def show(self):
+ """
+ Called when the page needs to have it's values updated.
+ """
+ raise NotImplementedError
- # Setup plugin tab listview
- self.plugin_liststore = gtk.ListStore(str, bool)
- self.plugin_liststore.set_sort_column_id(0, gtk.SORT_ASCENDING)
- self.plugin_listview = self.glade.get_widget("plugin_listview")
- self.plugin_listview.set_model(self.plugin_liststore)
- render = gtk.CellRendererToggle()
- render.connect("toggled", self.on_plugin_toggled)
- render.set_property("activatable", True)
- self.plugin_listview.append_column(
- gtk.TreeViewColumn(_("Enabled"), render, active=1))
- self.plugin_listview.append_column(
- gtk.TreeViewColumn(_("Plugin"), gtk.CellRendererText(), text=0))
+ def apply(self):
+ """
+ Called when the settings need to be saved. This method needs to be
+ defined by the subclass.
+ """
+ raise NotImplementedError
- # Connect to the 'changed' event of TreeViewSelection to get selection
- # changes.
- self.treeview.get_selection().connect("changed",
- self.on_selection_changed)
+ def set_widget(self, widget):
+ """
+ Creates a scrolled window with a proper header for the widget. The
+ widget is likely a gtk.VBox or similar container.
- self.plugin_listview.get_selection().connect("changed",
- self.on_plugin_selection_changed)
+ :param widget: the container widget for all the pref widgets
+ :type widget: gtk.Widget
- self.glade.signal_autoconnect({
- "on_pref_dialog_delete_event": self.on_pref_dialog_delete_event,
- "on_button_ok_clicked": self.on_button_ok_clicked,
- "on_button_apply_clicked": self.on_button_apply_clicked,
- "on_button_cancel_clicked": self.on_button_cancel_clicked,
- "on_toggle": self.on_toggle,
- "on_test_port_clicked": self.on_test_port_clicked,
- "on_button_plugin_install_clicked": self._on_button_plugin_install_clicked,
- "on_button_rescan_plugins_clicked": self._on_button_rescan_plugins_clicked,
- "on_button_find_plugins_clicked": self._on_button_find_plugins_clicked,
- "on_button_cache_refresh_clicked": self._on_button_cache_refresh_clicked,
- "on_combo_proxy_type_changed": self._on_combo_proxy_type_changed,
- "on_button_associate_magnet_clicked": self._on_button_associate_magnet_clicked
- })
-
- # These get updated by requests done to the core
- self.all_plugins = []
- self.enabled_plugins = []
-
- def __del__(self):
- del self.gtkui_config
-
- def add_page(self, name, widget):
- """Add a another page to the notebook"""
+ """
# Create a header and scrolled window for the preferences tab
parent = widget.get_parent()
if parent:
@@ -133,7 +93,7 @@ class Preferences(component.Component):
vbox = gtk.VBox()
label = gtk.Label()
label.set_use_markup(True)
- label.set_markup("" + name + "")
+ label.set_markup("" + self.name + "")
label.set_alignment(0.00, 0.50)
label.set_padding(10, 10)
vbox.pack_start(label, False, True, 0)
@@ -150,814 +110,316 @@ class Preferences(component.Component):
viewport.add(vbox)
scrolled.add(viewport)
scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scrolled.show_all()
+ self.widget = scrolled
+
+ def set_widget_from_file(self, xmlfile, obj):
+ """
+ Sets the widget from an object in a gtkBuilder xml file.
+
+ :param xmlfile: the path to the xml file
+ :type xmlfile: string
+ :param obj: the object name to use
+ :type obj: string
+
+ """
+ builder = gtk.Builder()
+ builder.add_from_file(xmlfile)
+ self.set_widget(builder.get_object(obj))
+
+
+class GtkUIPreferencePage(PreferencePage):
+ def __init__(self, name, xml, widget):
+ super(GtkUIPreferencePage, self).__init__()
+ self.name = name
+ self.set_widget_from_file(xml, widget)
+
+ def show(self):
+ """
+ Called when the page needs to have it's values updated.
+ """
+ if self.core_widgets:
+ coreconfig = component.get("CoreConfig")
+ for name, (accessor, key, non_localhost) in self.core_widgets.items():
+ widget = self.builder.get_object(name)
+ getattr(widget, "set_" + accessor)(coreconfig[key])
+ if client.is_localhost():
+ # Hide any non_localhost widgets
+ if non_localhost:
+ self.builder.get_object(non_localhost).hide()
+ widget.show()
+ else:
+ if non_localhost:
+ # Hide this widget because it should only be shown
+ # if core is a localhost, but show its non_localhost widget
+ self.builder.get_object(non_localhost).show()
+ widget.hide()
+
+
+class DownloadsPreferencePage(GtkUIPreferencePage):
+ def __init__(self, name, xml, widget):
+ super(DownloadsPreferencePage, self).__init__(name, xml, widget)
+ self.core_widgets = {
+ "download_path_button": ("current_folder", "download_location", "entry_download_path"),
+ "entry_download_path": ("text", "download_location", ""),
+ "chk_move_completed": ("active", "move_completed", ""),
+ "move_completed_path_button": ("current_folder", "move_completed_path", "entry_move_completed_path"),
+ "entry_move_completed_path": ("text", "move_completed_path", ""),
+ "chk_autoadd": ("active", "autoadd_enable", ""),
+ "folder_autoadd": ("current_folder", "autoadd_location", "entry_autoadd"),
+ "entry_autoadd": ("text", "autoadd_location", ""),
+ "chk_copy_torrent_file": ("active", "copy_torrent_file", ""),
+ "torrent_files_button": ("current_folder", "torrentfiles_location", "entry_torrents_path"),
+ "entry_torrents_path": ("text", "torrentfiles_location", ""),
+ "chk_del_copy_torrent_file": ("active", "del_copy_torrent_file", ""),
+ "radio_compact_allocation": ("active", "compact_allocation", ""),
+ "radio_full_allocation": ("active", "compact_allocation", ""),
+ "chk_prioritize_first_last_pieces": ("active", "prioritize_first_last_pieces", ""),
+ "chk_add_paused": ("active", "add_paused", "")
+ }
+
+class NetworkPreferencePage(PreferencePage):
+ pass
+
+class BandwidthPreferencePage(PreferencePage):
+ def __init__(self):
+ self.name = _("Bandwidth")
+ #xml = pkg_resources.resource_filename("deluge.ui.gtkui",
+ # "glade/preferences/bandwidth.glade")
+ xml = "glade/preferences/bandwidth.glade"
+ self.set_widget_from_file(xml, "bandwidth_prefs_page")
+
+ def update(self):
+ pass
+
+class InterfacePreferencePage(PreferencePage):
+ def __init__(self):
+ self.name = _("Interface")
+ #xml = pkg_resources.resource_filename("deluge.ui.gtkui",
+ # "glade/preferences/interface.glade")
+ xml = "glade/preferences/interface.glade"
+ self.set_widget_from_file(xml, "interface_prefs_page")
+
+ def update(self):
+ pass
+
+class OtherPreferencePage(PreferencePage):
+ def __init__(self):
+ self.name = _("Other")
+ #xml = pkg_resources.resource_filename("deluge.ui.gtkui",
+ # "glade/preferences/other.glade")
+ xml = "glade/preferences/other.glade"
+ self.set_widget_from_file(xml, "other_prefs_page")
+
+ def update(self):
+ pass
+
+class DaemonPreferencePage(PreferencePage):
+ def __init__(self):
+ self.name = _("Daemon")
+ #xml = pkg_resources.resource_filename("deluge.ui.gtkui",
+ # "glade/preferences/daemon.glade")
+ xml = "glade/preferences/daemon.glade"
+ self.set_widget_from_file(xml, "daemon_prefs_page")
+
+ def update(self):
+ pass
+
+class QueuePreferencePage(PreferencePage):
+ def __init__(self):
+ self.name = _("Queue")
+ #xml = pkg_resources.resource_filename("deluge.ui.gtkui",
+ # "glade/preferences/queue.glade")
+ xml = "glade/preferences/queue.glade"
+ self.set_widget_from_file(xml, "queue_prefs_page")
+
+ def update(self):
+ pass
+
+class ProxyPreferencePage(PreferencePage):
+ def __init__(self):
+ self.name = _("Proxy")
+ #xml = pkg_resources.resource_filename("deluge.ui.gtkui",
+ # "glade/preferences/proxy.glade")
+ xml = "glade/preferences/proxy.glade"
+ self.set_widget_from_file(xml, "proxy_prefs_page")
+
+ def update(self):
+ pass
+
+class CachePreferencePage(PreferencePage):
+ def __init__(self):
+ self.name = _("Cache")
+ #xml = pkg_resources.resource_filename("deluge.ui.gtkui",
+ # "glade/preferences/cache.glade")
+ xml = "glade/preferences/cache.glade"
+ self.set_widget_from_file(xml, "cache_prefs_page")
+
+ def update(self):
+ pass
+
+class PluginsPreferencePage(PreferencePage):
+ def __init__(self):
+ self.name = _("Plugins")
+ #xml = pkg_resources.resource_filename("deluge.ui.gtkui",
+ # "glade/preferences/plugins.glade")
+ xml = "glade/preferences/plugins.glade"
+ self.set_widget_from_file(xml, "plugins_prefs_page")
+
+ def update(self):
+ pass
+
+class Preferences(component.Component):
+ def __init__(self):
+ component.Component.__init__(self, "Preferences")
+
+ self.dialog = gtk.Dialog(_("Preferences"))
+ self.dialog.set_default_size(560, 530)
+ #self.dialog.set_transient_for(component.get("MainWindow").window)
+
+ # Set the buttons for the dialog
+ self.button_cancel = self.dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+ self.button_apply = self.dialog.add_button(gtk.STOCK_APPLY, gtk.RESPONSE_APPLY)
+ self.button_ok = self.dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
+
+ # Setup the content area
+ self.dialog_hpaned = gtk.HPaned()
+ vp = gtk.Viewport()
+ self.listview = gtk.TreeView()
+ vp.add(self.listview)
+ self.dialog_hpaned.pack1(vp)
+
+ self.notebook = gtk.Notebook()
+ self.notebook.set_show_tabs(False)
+ self.dialog_hpaned.pack2(self.notebook)
+ self.dialog.get_content_area().pack_start(self.dialog_hpaned)
+
+ # Setup the listview for the preference categories
+ self.liststore = gtk.ListStore(str)
+ render = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(_("Categories"), render, text=0)
+ self.listview.append_column(column)
+ self.listview.set_model(self.liststore)
+
+ self.listview.get_selection().connect("changed", self._on_selection_changed)
+
+ # Store the PreferencePages currently in the Preferences dialog
+ self.pages = {}
+
+ self.add_page(DownloadsPreferencePage(_("Downloads"), "glade/preferences/downloads.glade", "downloads_prefs_page"))
+
+
+ def add_page(self, page):
+ """
+ Add a Preference page.
+
+ :param page: the preference page to add
+ :type page: PreferencePage
+
+ """
+ if not isinstance(page, PreferencePage):
+ raise ValueError("Must be a PreferencePage!")
+
# Add this page to the notebook
- index = self.notebook.append_page(scrolled)
- self.liststore.append([index, name])
- return name
+ index = self.notebook.append_page(page.widget)
+ self.liststore.append([page.name])
+ self.pages[index] = page
+ return page.name
def remove_page(self, name):
- """Removes a page from the notebook"""
- self.page_num_to_remove = None
- self.iter_to_remove = None
+ """
+ Removes a Preference page.
- def check_row(model, path, iter, user_data):
- row_name = model.get_value(iter, 1)
- if row_name == user_data:
- # This is the row we need to remove
- self.page_num_to_remove = model.get_value(iter, 0)
- self.iter_to_remove = iter
- return
+ :param name: the name of the preference page
+ :type name: string
+ """
+ index = self.get_page_index(name)
+ if index:
+ del self.liststore[index]
+ self.notebook.remove_page(index)
- self.liststore.foreach(check_row, name)
- # Remove the page and row
- if self.page_num_to_remove != None:
- self.notebook.remove_page(self.page_num_to_remove)
- if self.iter_to_remove != None:
- self.liststore.remove(self.iter_to_remove)
+ def get_page_index(self, page):
+ """
+ Returns the index for the page.
+
+ :param page: the name of the preference page
+ :type page: string
+
+ :returns: the index
+ :rtype: int
+
+ """
+ for index, row in enumerate(self.liststore):
+ if page == row[0]:
+ return index
+
+ return None
# We need to re-adjust the index values for the remaining pages
for i, (index, name) in enumerate(self.liststore):
self.liststore[i][0] = i
def show(self, page=None):
- """Page should be the string in the left list.. ie, 'Network' or
- 'Bandwidth'"""
- if page != None:
- for (index, string) in self.liststore:
- if page == string:
- self.treeview.get_selection().select_path(index)
- break
-
- component.get("PluginManager").run_on_show_prefs()
-
- # Update the preferences dialog to reflect current config settings
- self.core_config = {}
- if client.connected():
- def _on_get_config(config):
- self.core_config = config
- client.core.get_available_plugins().addCallback(_on_get_available_plugins)
-
- def _on_get_available_plugins(plugins):
- self.all_plugins = plugins
- client.core.get_enabled_plugins().addCallback(_on_get_enabled_plugins)
-
- def _on_get_enabled_plugins(plugins):
- self.enabled_plugins = plugins
- client.core.get_listen_port().addCallback(_on_get_listen_port)
-
- def _on_get_listen_port(port):
- self.active_port = port
- client.core.get_cache_status().addCallback(_on_get_cache_status)
-
- def _on_get_cache_status(status):
- self.cache_status = status
- self._show()
-
- # This starts a series of client.core requests prior to showing the window
- client.core.get_config().addCallback(_on_get_config)
- else:
- self._show()
-
- def _show(self):
- if self.core_config != {} and self.core_config != None:
- core_widgets = {
- "download_path_button": \
- ("filename", self.core_config["download_location"]),
- "chk_move_completed": \
- ("active", self.core_config["move_completed"]),
- "move_completed_path_button": \
- ("filename", self.core_config["move_completed_path"]),
- "chk_copy_torrent_file": \
- ("active", self.core_config["copy_torrent_file"]),
- "chk_del_copy_torrent_file": \
- ("active", self.core_config["del_copy_torrent_file"]),
- "torrent_files_button": \
- ("filename", self.core_config["torrentfiles_location"]),
- "chk_autoadd": \
- ("active", self.core_config["autoadd_enable"]),
- "folder_autoadd": \
- ("filename", self.core_config["autoadd_location"]),
- "radio_compact_allocation": \
- ("active", self.core_config["compact_allocation"]),
- "radio_full_allocation": \
- ("not_active", self.core_config["compact_allocation"]),
- "chk_prioritize_first_last_pieces": \
- ("active",
- self.core_config["prioritize_first_last_pieces"]),
- "chk_add_paused": ("active", self.core_config["add_paused"]),
- "spin_port_min": ("value", self.core_config["listen_ports"][0]),
- "spin_port_max": ("value", self.core_config["listen_ports"][1]),
- "active_port_label": ("text", str(self.active_port)),
- "chk_random_port": ("active", self.core_config["random_port"]),
- "spin_outgoing_port_min": ("value", self.core_config["outgoing_ports"][0]),
- "spin_outgoing_port_max": ("value", self.core_config["outgoing_ports"][1]),
- "chk_random_outgoing_ports": ("active", self.core_config["random_outgoing_ports"]),
- "entry_interface": ("text", self.core_config["listen_interface"]),
- "entry_peer_tos": ("text", self.core_config["peer_tos"]),
- "chk_dht": ("active", self.core_config["dht"]),
- "chk_upnp": ("active", self.core_config["upnp"]),
- "chk_natpmp": ("active", self.core_config["natpmp"]),
- "chk_utpex": ("active", self.core_config["utpex"]),
- "chk_lsd": ("active", self.core_config["lsd"]),
- "chk_new_releases": ("active", self.core_config["new_release_check"]),
- "chk_send_info": ("active", self.core_config["send_info"]),
- "entry_geoip": ("text", self.core_config["geoip_db_location"]),
- "combo_encin": ("active", self.core_config["enc_in_policy"]),
- "combo_encout": ("active", self.core_config["enc_out_policy"]),
- "combo_enclevel": ("active", self.core_config["enc_level"]),
- "chk_pref_rc4": ("active", self.core_config["enc_prefer_rc4"]),
- "spin_max_connections_global": \
- ("value", self.core_config["max_connections_global"]),
- "spin_max_download": \
- ("value", self.core_config["max_download_speed"]),
- "spin_max_upload": \
- ("value", self.core_config["max_upload_speed"]),
- "spin_max_upload_slots_global": \
- ("value", self.core_config["max_upload_slots_global"]),
- "spin_max_half_open_connections": \
- ("value", self.core_config["max_half_open_connections"]),
- "spin_max_connections_per_second": \
- ("value", self.core_config["max_connections_per_second"]),
- "chk_ignore_limits_on_local_network": \
- ("active", self.core_config["ignore_limits_on_local_network"]),
- "chk_rate_limit_ip_overhead": \
- ("active", self.core_config["rate_limit_ip_overhead"]),
- "spin_max_connections_per_torrent": \
- ("value", self.core_config["max_connections_per_torrent"]),
- "spin_max_upload_slots_per_torrent": \
- ("value", self.core_config["max_upload_slots_per_torrent"]),
- "spin_max_download_per_torrent": \
- ("value", self.core_config["max_download_speed_per_torrent"]),
- "spin_max_upload_per_torrent": \
- ("value", self.core_config["max_upload_speed_per_torrent"]),
- "spin_daemon_port": \
- ("value", self.core_config["daemon_port"]),
- "chk_allow_remote_connections": \
- ("active", self.core_config["allow_remote"]),
- "spin_active": ("value", self.core_config["max_active_limit"]),
- "spin_seeding": ("value", self.core_config["max_active_seeding"]),
- "spin_downloading": ("value", self.core_config["max_active_downloading"]),
- "chk_dont_count_slow_torrents": ("active", self.core_config["dont_count_slow_torrents"]),
- "chk_queue_new_top": ("active", self.core_config["queue_new_to_top"]),
- "spin_share_ratio_limit": ("value", self.core_config["share_ratio_limit"]),
- "spin_seed_time_ratio_limit": \
- ("value", self.core_config["seed_time_ratio_limit"]),
- "spin_seed_time_limit": ("value", self.core_config["seed_time_limit"]),
- "chk_seed_ratio": ("active", self.core_config["stop_seed_at_ratio"]),
- "spin_share_ratio": ("value", self.core_config["stop_seed_ratio"]),
- "chk_remove_ratio": ("active", self.core_config["remove_seed_at_ratio"]),
- "spin_cache_size": ("value", self.core_config["cache_size"]),
- "spin_cache_expiry": ("value", self.core_config["cache_expiry"])
- }
- # Add proxy stuff
- for t in ("peer", "web_seed", "tracker", "dht"):
- core_widgets["spin_proxy_port_%s" % t] = ("value", self.core_config["proxies"][t]["port"])
- core_widgets["combo_proxy_type_%s" % t] = ("active", self.core_config["proxies"][t]["type"])
- core_widgets["txt_proxy_server_%s" % t] = ("text", self.core_config["proxies"][t]["hostname"])
- core_widgets["txt_proxy_username_%s" % t] = ("text", self.core_config["proxies"][t]["username"])
- core_widgets["txt_proxy_password_%s" % t] = ("text", self.core_config["proxies"][t]["password"])
-
- # Change a few widgets if we're connected to a remote host
- if not client.is_localhost():
- self.glade.get_widget("entry_download_path").show()
- self.glade.get_widget("download_path_button").hide()
- core_widgets.pop("download_path_button")
- core_widgets["entry_download_path"] = ("text", self.core_config["download_location"])
-
- self.glade.get_widget("entry_move_completed_path").show()
- self.glade.get_widget("move_completed_path_button").hide()
- core_widgets.pop("move_completed_path_button")
- core_widgets["entry_move_completed_path"] = ("text", self.core_config["move_completed_path"])
-
- self.glade.get_widget("entry_torrents_path").show()
- self.glade.get_widget("torrent_files_button").hide()
- core_widgets.pop("torrent_files_button")
- core_widgets["entry_torrents_path"] = ("text", self.core_config["torrentfiles_location"])
-
- self.glade.get_widget("entry_autoadd").show()
- self.glade.get_widget("folder_autoadd").hide()
- core_widgets.pop("folder_autoadd")
- core_widgets["entry_autoadd"] = ("text", self.core_config["autoadd_location"])
- else:
- self.glade.get_widget("entry_download_path").hide()
- self.glade.get_widget("download_path_button").show()
- self.glade.get_widget("entry_move_completed_path").hide()
- self.glade.get_widget("move_completed_path_button").show()
- self.glade.get_widget("entry_torrents_path").hide()
- self.glade.get_widget("torrent_files_button").show()
- self.glade.get_widget("entry_autoadd").hide()
- self.glade.get_widget("folder_autoadd").show()
-
- # Update the widgets accordingly
- for key in core_widgets.keys():
- modifier = core_widgets[key][0]
- value = core_widgets[key][1]
- widget = self.glade.get_widget(key)
- if type(widget) == gtk.FileChooserButton:
- for child in widget.get_children():
- child.set_sensitive(True)
- widget.set_sensitive(True)
-
- if modifier == "filename":
- if value:
- try:
- widget.set_current_folder(value)
- except Exception, e:
- log.debug("Unable to set_current_folder: %s", e)
- elif modifier == "active":
- widget.set_active(value)
- elif modifier == "not_active":
- widget.set_active(not value)
- elif modifier == "value":
- widget.set_value(float(value))
- elif modifier == "text":
- widget.set_text(value)
-
- for key in core_widgets.keys():
- widget = self.glade.get_widget(key)
- # Update the toggle status if necessary
- self.on_toggle(widget)
- else:
- core_widget_list = [
- "download_path_button",
- "chk_move_completed",
- "move_completed_path_button",
- "chk_copy_torrent_file",
- "chk_del_copy_torrent_file",
- "torrent_files_button",
- "chk_autoadd",
- "folder_autoadd",
- "radio_compact_allocation",
- "radio_full_allocation",
- "chk_prioritize_first_last_pieces",
- "chk_add_paused",
- "spin_port_min",
- "spin_port_max",
- "active_port_label",
- "chk_random_port",
- "spin_outgoing_port_min",
- "spin_outgoing_port_max",
- "chk_random_outgoing_ports",
- "entry_interface",
- "entry_peer_tos",
- "chk_dht",
- "chk_upnp",
- "chk_natpmp",
- "chk_utpex",
- "chk_lsd",
- "chk_send_info",
- "chk_new_releases",
- "entry_geoip",
- "combo_encin",
- "combo_encout",
- "combo_enclevel",
- "chk_pref_rc4",
- "spin_max_connections_global",
- "spin_max_download",
- "spin_max_upload",
- "spin_max_upload_slots_global",
- "spin_max_half_open_connections",
- "spin_max_connections_per_second",
- "chk_ignore_limits_on_local_network",
- "chk_rate_limit_ip_overhead",
- "spin_max_connections_per_torrent",
- "spin_max_upload_slots_per_torrent",
- "spin_max_download_per_torrent",
- "spin_max_upload_per_torrent",
- "spin_daemon_port",
- "chk_allow_remote_connections",
- "spin_seeding",
- "spin_downloading",
- "spin_active",
- "chk_dont_count_slow_torrents",
- "chk_queue_new_top",
- "chk_seed_ratio",
- "spin_share_ratio",
- "chk_remove_ratio",
- "spin_share_ratio_limit",
- "spin_seed_time_ratio_limit",
- "spin_seed_time_limit",
- "spin_cache_size",
- "spin_cache_expiry",
- "button_cache_refresh",
- "btn_testport"
- ]
- for t in ("peer", "web_seed", "tracker", "dht"):
- core_widget_list.append("spin_proxy_port_%s" % t)
- core_widget_list.append("combo_proxy_type_%s" % t)
- core_widget_list.append("txt_proxy_username_%s" % t)
- core_widget_list.append("txt_proxy_password_%s" % t)
- core_widget_list.append("txt_proxy_server_%s" % t)
-
- # We don't appear to be connected to a daemon
- for key in core_widget_list:
- widget = self.glade.get_widget(key)
- if type(widget) == gtk.FileChooserButton:
- for child in widget.get_children():
- child.set_sensitive(False)
- widget.set_sensitive(False)
-
- ## Downloads tab ##
- self.glade.get_widget("chk_show_dialog").set_active(
- self.gtkui_config["interactive_add"])
- self.glade.get_widget("chk_focus_dialog").set_active(
- self.gtkui_config["focus_add_dialog"])
-
- ## Interface tab ##
- self.glade.get_widget("chk_use_tray").set_active(
- self.gtkui_config["enable_system_tray"])
- self.glade.get_widget("chk_min_on_close").set_active(
- self.gtkui_config["close_to_tray"])
- self.glade.get_widget("chk_start_in_tray").set_active(
- self.gtkui_config["start_in_tray"])
- self.glade.get_widget("chk_enable_appindicator").set_active(
- self.gtkui_config["enable_appindicator"])
- self.glade.get_widget("chk_lock_tray").set_active(
- self.gtkui_config["lock_tray"])
- self.glade.get_widget("chk_classic_mode").set_active(
- self.gtkui_config["classic_mode"])
- self.glade.get_widget("chk_show_rate_in_title").set_active(
- self.gtkui_config["show_rate_in_title"])
-
- ## Other tab ##
- self.glade.get_widget("chk_show_new_releases").set_active(
- self.gtkui_config["show_new_releases"])
-
-
- ## Cache tab ##
- if client.connected():
- self.__update_cache_status()
-
- ## Plugins tab ##
- all_plugins = self.all_plugins
- enabled_plugins = self.enabled_plugins
- # Clear the existing list so we don't duplicate entries.
- self.plugin_liststore.clear()
- # Iterate through the lists and add them to the liststore
- for plugin in all_plugins:
- if plugin in enabled_plugins:
- enabled = True
- else:
- enabled = False
- row = self.plugin_liststore.append()
- self.plugin_liststore.set_value(row, 0, plugin)
- self.plugin_liststore.set_value(row, 1, enabled)
-
- # Now show the dialog
- self.pref_dialog.show()
-
- def set_config(self, hide=False):
"""
- Sets all altered config values in the core.
+ Shows the Preferences dialog.
+
+ :param page: the name of the page to show initially
+ :type page: string
- :param hide: bool, if True, will not re-show the dialog and will hide it instead
"""
- try:
- from hashlib import sha1 as sha_hash
- except ImportError:
- from sha import new as sha_hash
-
- # Get the values from the dialog
- new_core_config = {}
- new_gtkui_config = {}
-
- ## Downloads tab ##
- new_gtkui_config["interactive_add"] = \
- self.glade.get_widget("chk_show_dialog").get_active()
- new_gtkui_config["focus_add_dialog"] = \
- self.glade.get_widget("chk_focus_dialog").get_active()
- new_core_config["copy_torrent_file"] = \
- self.glade.get_widget("chk_copy_torrent_file").get_active()
- new_core_config["del_copy_torrent_file"] = \
- self.glade.get_widget("chk_del_copy_torrent_file").get_active()
- new_core_config["move_completed"] = \
- self.glade.get_widget("chk_move_completed").get_active()
- if client.is_localhost():
- new_core_config["download_location"] = \
- self.glade.get_widget("download_path_button").get_filename()
- new_core_config["move_completed_path"] = \
- self.glade.get_widget("move_completed_path_button").get_filename()
- new_core_config["torrentfiles_location"] = \
- self.glade.get_widget("torrent_files_button").get_filename()
+ if page:
+ index = self.get_page_index(page)
+ if index:
+ self.pages[index].show()
+ self.listview.get_selection().select_path(index)
else:
- new_core_config["download_location"] = \
- self.glade.get_widget("entry_download_path").get_text()
- new_core_config["move_completed_path"] = \
- self.glade.get_widget("entry_move_completed_path").get_text()
- new_core_config["torrentfiles_location"] = \
- self.glade.get_widget("entry_torrents_path").get_text()
+ self.listview.get_selection().select_path(0)
- new_core_config["autoadd_enable"] = \
- self.glade.get_widget("chk_autoadd").get_active()
- if client.is_localhost():
- new_core_config["autoadd_location"] = \
- self.glade.get_widget("folder_autoadd").get_filename()
- else:
- new_core_config["autoadd_location"] = \
- self.glade.get_widget("entry_autoadd").get_text()
+ self.dialog.show_all()
- new_core_config["compact_allocation"] = \
- self.glade.get_widget("radio_compact_allocation").get_active()
- new_core_config["prioritize_first_last_pieces"] = \
- self.glade.get_widget(
- "chk_prioritize_first_last_pieces").get_active()
- new_core_config["add_paused"] = \
- self.glade.get_widget("chk_add_paused").get_active()
-
- ## Network tab ##
- listen_ports = (
- self.glade.get_widget("spin_port_min").get_value_as_int(),
- self.glade.get_widget("spin_port_max").get_value_as_int()
- )
- new_core_config["listen_ports"] = listen_ports
- new_core_config["random_port"] = \
- self.glade.get_widget("chk_random_port").get_active()
- outgoing_ports = (
- self.glade.get_widget("spin_outgoing_port_min").get_value_as_int(),
- self.glade.get_widget("spin_outgoing_port_max").get_value_as_int()
- )
- new_core_config["outgoing_ports"] = outgoing_ports
- new_core_config["random_outgoing_ports"] = \
- self.glade.get_widget("chk_random_outgoing_ports").get_active()
- new_core_config["listen_interface"] = self.glade.get_widget("entry_interface").get_text()
- new_core_config["peer_tos"] = self.glade.get_widget("entry_peer_tos").get_text()
- new_core_config["dht"] = self.glade.get_widget("chk_dht").get_active()
- new_core_config["upnp"] = self.glade.get_widget("chk_upnp").get_active()
- new_core_config["natpmp"] = \
- self.glade.get_widget("chk_natpmp").get_active()
- new_core_config["utpex"] = \
- self.glade.get_widget("chk_utpex").get_active()
- new_core_config["lsd"] = \
- self.glade.get_widget("chk_lsd").get_active()
- new_core_config["enc_in_policy"] = \
- self.glade.get_widget("combo_encin").get_active()
- new_core_config["enc_out_policy"] = \
- self.glade.get_widget("combo_encout").get_active()
- new_core_config["enc_level"] = \
- self.glade.get_widget("combo_enclevel").get_active()
- new_core_config["enc_prefer_rc4"] = \
- self.glade.get_widget("chk_pref_rc4").get_active()
-
- ## Bandwidth tab ##
- new_core_config["max_connections_global"] = \
- self.glade.get_widget(
- "spin_max_connections_global").get_value_as_int()
- new_core_config["max_download_speed"] = \
- self.glade.get_widget("spin_max_download").get_value()
- new_core_config["max_upload_speed"] = \
- self.glade.get_widget("spin_max_upload").get_value()
- new_core_config["max_upload_slots_global"] = \
- self.glade.get_widget(
- "spin_max_upload_slots_global").get_value_as_int()
- new_core_config["max_half_open_connections"] = \
- self.glade.get_widget("spin_max_half_open_connections").get_value_as_int()
- new_core_config["max_connections_per_second"] = \
- self.glade.get_widget(
- "spin_max_connections_per_second").get_value_as_int()
- new_core_config["max_connections_per_torrent"] = \
- self.glade.get_widget(
- "spin_max_connections_per_torrent").get_value_as_int()
- new_core_config["max_upload_slots_per_torrent"] = \
- self.glade.get_widget(
- "spin_max_upload_slots_per_torrent").get_value_as_int()
- new_core_config["max_upload_speed_per_torrent"] = \
- self.glade.get_widget(
- "spin_max_upload_per_torrent").get_value()
- new_core_config["max_download_speed_per_torrent"] = \
- self.glade.get_widget(
- "spin_max_download_per_torrent").get_value()
- new_core_config["ignore_limits_on_local_network"] = \
- self.glade.get_widget("chk_ignore_limits_on_local_network").get_active()
- new_core_config["rate_limit_ip_overhead"] = \
- self.glade.get_widget("chk_rate_limit_ip_overhead").get_active()
-
- ## Interface tab ##
- new_gtkui_config["enable_system_tray"] = \
- self.glade.get_widget("chk_use_tray").get_active()
- new_gtkui_config["close_to_tray"] = \
- self.glade.get_widget("chk_min_on_close").get_active()
- new_gtkui_config["start_in_tray"] = \
- self.glade.get_widget("chk_start_in_tray").get_active()
- new_gtkui_config["enable_appindicator"] = \
- self.glade.get_widget("chk_enable_appindicator").get_active()
- new_gtkui_config["lock_tray"] = \
- self.glade.get_widget("chk_lock_tray").get_active()
- passhex = sha_hash(\
- self.glade.get_widget("txt_tray_password").get_text()).hexdigest()
- if passhex != "c07eb5a8c0dc7bb81c217b67f11c3b7a5e95ffd7":
- new_gtkui_config["tray_password"] = passhex
- new_gtkui_config["classic_mode"] = \
- self.glade.get_widget("chk_classic_mode").get_active()
- new_gtkui_config["show_rate_in_title"] = \
- self.glade.get_widget("chk_show_rate_in_title").get_active()
-
- ## Other tab ##
- new_gtkui_config["show_new_releases"] = \
- self.glade.get_widget("chk_show_new_releases").get_active()
- new_core_config["send_info"] = \
- self.glade.get_widget("chk_send_info").get_active()
- new_core_config["geoip_db_location"] = \
- self.glade.get_widget("entry_geoip").get_text()
-
- ## Daemon tab ##
- new_core_config["daemon_port"] = \
- self.glade.get_widget("spin_daemon_port").get_value_as_int()
- new_core_config["allow_remote"] = \
- self.glade.get_widget("chk_allow_remote_connections").get_active()
- new_core_config["new_release_check"] = \
- self.glade.get_widget("chk_new_releases").get_active()
-
- ## Proxy tab ##
- new_core_config["proxies"] = {}
- for t in ("peer", "web_seed", "tracker", "dht"):
- new_core_config["proxies"][t] = {}
- new_core_config["proxies"][t]["type"] = \
- self.glade.get_widget("combo_proxy_type_%s" % t).get_active()
- new_core_config["proxies"][t]["port"] = \
- self.glade.get_widget("spin_proxy_port_%s" % t).get_value_as_int()
- new_core_config["proxies"][t]["username"] = \
- self.glade.get_widget("txt_proxy_username_%s" % t).get_text()
- new_core_config["proxies"][t]["password"] = \
- self.glade.get_widget("txt_proxy_password_%s" % t).get_text()
- new_core_config["proxies"][t]["hostname"] = \
- self.glade.get_widget("txt_proxy_server_%s" % t).get_text()
-
- ## Queue tab ##
- new_core_config["queue_new_to_top"] = \
- self.glade.get_widget("chk_queue_new_top").get_active()
- new_core_config["max_active_seeding"] = \
- self.glade.get_widget("spin_seeding").get_value_as_int()
- new_core_config["max_active_downloading"] = \
- self.glade.get_widget("spin_downloading").get_value_as_int()
- new_core_config["max_active_limit"] = \
- self.glade.get_widget("spin_active").get_value_as_int()
- new_core_config["dont_count_slow_torrents"] = \
- self.glade.get_widget("chk_dont_count_slow_torrents").get_active()
- new_core_config["stop_seed_at_ratio"] = \
- self.glade.get_widget("chk_seed_ratio").get_active()
- new_core_config["remove_seed_at_ratio"] = \
- self.glade.get_widget("chk_remove_ratio").get_active()
- new_core_config["stop_seed_ratio"] = \
- self.glade.get_widget("spin_share_ratio").get_value()
- new_core_config["share_ratio_limit"] = \
- self.glade.get_widget("spin_share_ratio_limit").get_value()
- new_core_config["seed_time_ratio_limit"] = \
- self.glade.get_widget("spin_seed_time_ratio_limit").get_value()
- new_core_config["seed_time_limit"] = \
- self.glade.get_widget("spin_seed_time_limit").get_value()
-
- ## Cache tab ##
- new_core_config["cache_size"] = \
- self.glade.get_widget("spin_cache_size").get_value_as_int()
- new_core_config["cache_expiry"] = \
- self.glade.get_widget("spin_cache_expiry").get_value_as_int()
-
- # Run plugin hook to apply preferences
- component.get("PluginManager").run_on_apply_prefs()
-
- # GtkUI
- for key in new_gtkui_config.keys():
- # The values do not match so this needs to be updated
- if self.gtkui_config[key] != new_gtkui_config[key]:
- self.gtkui_config[key] = new_gtkui_config[key]
-
- # Core
- if client.connected():
- # Only do this if we're connected to a daemon
- config_to_set = {}
- for key in new_core_config.keys():
- # The values do not match so this needs to be updated
- if self.core_config[key] != new_core_config[key]:
- config_to_set[key] = new_core_config[key]
-
- if config_to_set:
- # Set each changed config value in the core
- client.core.set_config(config_to_set)
- client.force_call(True)
- # Update the configuration
- self.core_config.update(config_to_set)
-
- if hide:
- self.hide()
- else:
- # Re-show the dialog to make sure everything has been updated
- self.show()
-
- def hide(self):
- self.glade.get_widget("port_img").hide()
- self.pref_dialog.hide()
-
- def __update_cache_status(self):
- # Updates the cache status labels with the info in the dict
- for widget in self.glade.get_widget_prefix("label_cache_"):
- key = widget.get_name()[len("label_cache_"):]
- value = self.cache_status[key]
- if type(value) == float:
- value = "%.2f" % value
- else:
- value = str(value)
-
- widget.set_text(value)
-
- def _on_button_cache_refresh_clicked(self, widget):
- def on_get_cache_status(status):
- self.cache_status = status
- self.__update_cache_status()
-
- client.core.get_cache_status().addCallback(on_get_cache_status)
-
- def on_pref_dialog_delete_event(self, widget, event):
- self.hide()
- return True
-
- def on_toggle(self, widget):
- """Handles widget sensitivity based on radio/check button values."""
- try:
- value = widget.get_active()
- except:
- return
-
- dependents = {
- "chk_show_dialog": {"chk_focus_dialog": True},
- "chk_random_port": {"spin_port_min": False,
- "spin_port_max": False},
- "chk_random_outgoing_ports": {"spin_outgoing_port_min": False,
- "spin_outgoing_port_max": False},
- "chk_use_tray": {"chk_min_on_close": True,
- "chk_start_in_tray": True,
- "chk_enable_appindicator": True,
- "chk_lock_tray": True},
- "chk_lock_tray": {"txt_tray_password": True,
- "password_label": True},
- "radio_open_folder_custom": {"combo_file_manager": False,
- "txt_open_folder_location": True},
- "chk_move_completed" : {"move_completed_path_button" : True},
- "chk_copy_torrent_file" : {"torrent_files_button" : True,
- "chk_del_copy_torrent_file" : True},
- "chk_autoadd" : {"folder_autoadd" : True},
- "chk_seed_ratio" : {"spin_share_ratio": True,
- "chk_remove_ratio" : True}
- }
-
- def update_dependent_widgets(name, value):
- dependency = dependents[name]
- for dep in dependency.keys():
- depwidget = self.glade.get_widget(dep)
- sensitive = [not value, value][dependency[dep]]
- depwidget.set_sensitive(sensitive)
- if dep in dependents:
- update_dependent_widgets(dep, depwidget.get_active() and sensitive)
-
- for key in dependents.keys():
- if widget != self.glade.get_widget(key):
- continue
- update_dependent_widgets(key, value)
-
- def on_button_ok_clicked(self, data):
- log.debug("on_button_ok_clicked")
- self.set_config(hide=True)
- return True
-
- def on_button_apply_clicked(self, data):
- log.debug("on_button_apply_clicked")
- self.set_config()
-
- def on_button_cancel_clicked(self, data):
- log.debug("on_button_cancel_clicked")
- self.hide()
- return True
-
- def on_selection_changed(self, treeselection):
- # Show the correct notebook page based on what row is selected.
+ def _on_selection_changed(self, treeselection):
+ """
+ This is called when the preference page changes or when it's initially
+ showed. We must call the page's update() method prior to showing the
+ page.
+ """
(model, row) = treeselection.get_selected()
+ index = self.get_page_index(model[row][0])
+ if index is None:
+ return
+
+ def on_page_show(result):
+ self.notebook.set_current_page(index)
try:
- self.notebook.set_current_page(model.get_value(row, 0))
- except TypeError:
- pass
+ maybeDeferred(self.pages[index].show).addCallback(on_page_show)
+ except Exception, e:
+ dialogs.ErrorDialog(
+ _("Error with preference page"),
+ _("Could not show preference page correctly."),
+ self.dialog,
+ traceback=True).run()
- def on_test_port_clicked(self, data):
- log.debug("on_test_port_clicked")
- def on_get_test(status):
- if status:
- self.glade.get_widget("port_img").set_from_stock(gtk.STOCK_YES, 4)
- self.glade.get_widget("port_img").show()
- else:
- self.glade.get_widget("port_img").set_from_stock(gtk.STOCK_DIALOG_WARNING, 4)
- self.glade.get_widget("port_img").show()
- client.core.test_listen_port().addCallback(on_get_test)
- self.glade.get_widget("port_img").set_from_file(
- deluge.common.get_pixmap('loading.gif')
- )
- self.glade.get_widget("port_img").show()
- client.force_call()
+if __name__ == "__main__":
+ p = Preferences()
+ d = DownloadsPreferencePage(_("Downloads"), "glade/preferences/downloads.glade", "downloads_prefs_page")
+ p.add_page(d)
+ #d2 = NetworkPreferencePage(_("Network"), "glade/preferences/network.glade", "network_prefs_page")
+ #p.add_page(d2)
+ ##d3 = BandwidthPreferencePage()
+ ##p.add_page(d3)
+ ##d4 = InterfacePreferencePage()
+ ##p.add_page(d4)
+ ##d5 = OtherPreferencePage()
+ ##p.add_page(d5)
+ ##d6 = DaemonPreferencePage()
+ ##p.add_page(d6)
+ ##d7 = QueuePreferencePage()
+ ##p.add_page(d7)
+ ##d8 = ProxyPreferencePage()
+ ##p.add_page(d8)
+ ##d9 = CachePreferencePage()
+ ##p.add_page(d9)
+ ##d10 = PluginsPreferencePage()
+ ##p.add_page(d10)
+ p.show()
+ gtk.main()
- def on_plugin_toggled(self, renderer, path):
- log.debug("on_plugin_toggled")
- row = self.plugin_liststore.get_iter_from_string(path)
- name = self.plugin_liststore.get_value(row, 0)
- value = self.plugin_liststore.get_value(row, 1)
- self.plugin_liststore.set_value(row, 1, not value)
- if not value:
- client.core.enable_plugin(name)
- else:
- client.core.disable_plugin(name)
- component.get("PluginManager").disable_plugin(name)
-
- def on_plugin_selection_changed(self, treeselection):
- log.debug("on_plugin_selection_changed")
- (model, itr) = treeselection.get_selected()
- if not itr:
- return
- name = model[itr][0]
- plugin_info = component.get("PluginManager").get_plugin_info(name)
- self.glade.get_widget("label_plugin_author").set_text(plugin_info["Author"])
- self.glade.get_widget("label_plugin_version").set_text(plugin_info["Version"])
- self.glade.get_widget("label_plugin_email").set_text(plugin_info["Author-email"])
- self.glade.get_widget("label_plugin_homepage").set_text(plugin_info["Home-page"])
- self.glade.get_widget("label_plugin_details").set_text(plugin_info["Description"])
-
- def _on_button_plugin_install_clicked(self, widget):
- log.debug("_on_button_plugin_install_clicked")
- chooser = gtk.FileChooserDialog(_("Select the Plugin"),
- self.pref_dialog,
- gtk.FILE_CHOOSER_ACTION_OPEN,
- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN,
- gtk.RESPONSE_OK))
-
- chooser.set_transient_for(self.pref_dialog)
- chooser.set_select_multiple(False)
- chooser.set_property("skip-taskbar-hint", True)
-
- file_filter = gtk.FileFilter()
- file_filter.set_name(_("Plugin Eggs"))
- file_filter.add_pattern("*." + "egg")
- chooser.add_filter(file_filter)
-
- # Run the dialog
- response = chooser.run()
-
- if response == gtk.RESPONSE_OK:
- filepath = chooser.get_filename()
- else:
- chooser.destroy()
- return
-
- import base64
- import shutil
- import os.path
- filename = os.path.split(filepath)[1]
- shutil.copyfile(
- filepath,
- os.path.join(deluge.configmanager.get_config_dir(), "plugins", filename))
-
- component.get("PluginManager").scan_for_plugins()
-
- if not client.is_localhost():
- # We need to send this plugin to the daemon
- filedump = base64.encodestring(open(filepath, "rb").read())
- client.core.upload_plugin(filename, filedump)
-
- client.core.rescan_plugins()
- chooser.destroy()
- # We need to re-show the preferences dialog to show the new plugins
- self.show()
-
- def _on_button_rescan_plugins_clicked(self, widget):
- component.get("PluginManager").scan_for_plugins()
- if client.connected():
- client.core.rescan_plugins()
- self.show()
-
- def _on_button_find_plugins_clicked(self, widget):
- deluge.common.open_url_in_browser("http://dev.deluge-torrent.org/wiki/Plugins")
-
- def _on_combo_proxy_type_changed(self, widget):
- name = widget.get_name().replace("combo_proxy_type_", "")
- proxy_type = widget.get_model()[widget.get_active()][0]
-
- prefixes = ["txt_proxy_", "label_proxy_", "spin_proxy_"]
- hides = []
- shows = []
-
- if proxy_type == "None":
- hides.extend(["password", "username", "server", "port"])
- elif proxy_type in ("Socksv4", "Socksv5", "HTTP"):
- hides.extend(["password", "username"])
- shows.extend(["server", "port"])
- elif proxy_type in ("Socksv5 W/ Auth", "HTTP W/ Auth"):
- shows.extend(["password", "username", "server", "port"])
-
- for h in hides:
- for p in prefixes:
- w = self.glade.get_widget(p + h + "_" + name)
- if w:
- w.hide()
- for s in shows:
- for p in prefixes:
- w = self.glade.get_widget(p + s + "_" + name)
- if w:
- w.show()
-
- def _on_button_associate_magnet_clicked(self, widget):
- common.associate_magnet_links(True)