diff --git a/TODO b/TODO
index 76d022c60..33a4e186d 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,5 @@
For 0.6 release:
* Implement open folder
-* Add per-torrent settings to the details pane.. max_download_speed, etc.. So
- the user know what limits are set on the torrent.
* Add a 'move storage' on completion option
* Address issue where torrents will redownload if the storage is moved outside
of deluge.
@@ -11,14 +9,15 @@ For 0.6 release:
* Translations
* Show proper priority levels in Files tab, plus add menu to alter priorities
* Implement add by hash
+* Implement 'Classic' mode
+* Add tabs to view menu
+* Add command line option to change config dir.. --config
After 0.6 release:
* Figure out easy way for user-made plugins to add i18n support.
* Restart daemon function
* Docstrings!
-* Implement 'Classic' mode
* Add wizard
-* Add command line option to change config dir.. --config
* Add method for plugins to add labels
* Add context menus for labels.. ie. setting options for all torrents in label
* Implement caching in core
diff --git a/deluge/ui/gtkui/glade/main_window.glade b/deluge/ui/gtkui/glade/main_window.glade
index a41ddfbd0..f9dd3f06c 100644
--- a/deluge/ui/gtkui/glade/main_window.glade
+++ b/deluge/ui/gtkui/glade/main_window.glade
@@ -521,188 +521,169 @@
-
+
True
0
+ True
+ True
1
2
- GTK_FILL
-
-
-
-
- True
- 0
-
-
- 3
- 4
- GTK_FILL
-
-
-
-
- True
- 0
-
-
- 1
- 2
- 1
- 2
- GTK_FILL
-
-
-
-
- True
- 0
-
-
- 3
- 4
- 1
- 2
- GTK_FILL
-
-
-
-
- True
- 5
-
-
- True
- 0
- <b>Downloaded:</b>
- True
-
-
-
-
- GTK_FILL
-
-
-
-
- True
- 5
-
-
- True
- 0
- <b>Uploaded:</b>
- True
-
-
-
-
- 1
- 2
- GTK_FILL
-
-
-
-
- True
- 5
-
-
- True
- 0
- <b>Share Ratio:</b>
- True
-
-
-
-
- 2
- 3
- GTK_FILL
-
-
-
-
- True
- 5
-
-
- True
- 0
- <b>Next Announce:</b>
- True
-
-
-
-
3
4
GTK_FILL
-
+
True
- 15
- 5
-
-
- True
- 0
- <b>Speed:</b>
- True
-
-
+ 0
- 2
- 3
+ 3
+ 4
+ 3
+ 4
GTK_FILL
-
+
True
- 15
- 5
-
-
- True
- 0
- <b>Speed:</b>
- True
-
-
+ 0
+ PANGO_WRAP_CHAR
+ True
- 2
- 3
+ 1
+ 6
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ <b>Tracker Status:</b>
+ True
+
+
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+
+ True
+ 0
+ True
+ PANGO_WRAP_WORD_CHAR
+
+
+ 5
+ 6
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+
+ True
+ 0
+ 1
+ <b>Availability:</b>
+ True
+
+
+ 4
+ 5
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ 0
+
+
+ 3
+ 4
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ 0
+
+
+ 1
+ 2
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ 0
+
+
+ 5
+ 6
1
2
GTK_FILL
-
+
True
- 15
- 5
-
-
- True
- 0
- <b>ETA:</b>
- True
-
-
+ 0
+ <b>Peers:</b>
+ True
- 2
- 3
- 2
- 3
+ 4
+ 5
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ 0
+
+
+ 5
+ 6
+ GTK_FILL
+
+
+
+
+ True
+ 0
+ <b>Seeders:</b>
+ True
+
+
+ 4
+ 5
GTK_FILL
@@ -729,169 +710,188 @@
-
+
True
- 0
- <b>Seeders:</b>
- True
+ 15
+ 5
+
+
+ True
+ 0
+ <b>ETA:</b>
+ True
+
+
- 4
- 5
+ 2
+ 3
+ 2
+ 3
GTK_FILL
-
+
True
- 0
+ 15
+ 5
+
+
+ True
+ 0
+ <b>Speed:</b>
+ True
+
+
- 5
- 6
- GTK_FILL
-
-
-
-
- True
- 0
- <b>Peers:</b>
- True
-
-
- 4
- 5
+ 2
+ 3
1
2
GTK_FILL
-
+
True
- 0
+ 15
+ 5
+
+
+ True
+ 0
+ <b>Speed:</b>
+ True
+
+
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ 5
+
+
+ True
+ 0
+ <b>Next Announce:</b>
+ True
+
+
+
+
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+ True
+ 5
+
+
+ True
+ 0
+ <b>Share Ratio:</b>
+ True
+
+
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ 5
+
+
+ True
+ 0
+ <b>Uploaded:</b>
+ True
+
+
- 5
- 6
1
2
GTK_FILL
-
+
True
- 0
+ 5
+
+
+ True
+ 0
+ <b>Downloaded:</b>
+ True
+
+
- 1
- 2
- 2
- 3
GTK_FILL
-
+
True
0
3
4
- 2
- 3
+ 1
+ 2
GTK_FILL
-
+
True
0
- 1
- <b>Availability:</b>
- True
-
-
- 4
- 5
- 2
- 3
- GTK_FILL
-
-
-
-
- True
- 0
- True
- PANGO_WRAP_WORD_CHAR
-
-
- 5
- 6
- 2
- 3
- GTK_FILL
-
-
-
-
-
- True
- 0
- <b>Tracker Status:</b>
- True
-
-
- 4
- 5
- GTK_FILL
-
-
-
-
-
- True
- 0
- PANGO_WRAP_CHAR
- True
1
- 6
- 4
- 5
+ 2
+ 1
+ 2
GTK_FILL
-
+
True
0
3
4
- 3
- 4
GTK_FILL
-
+
True
0
- True
- True
1
2
- 3
- 4
GTK_FILL
@@ -966,114 +966,7 @@
4
2
-
- True
- 0
- True
- PANGO_WRAP_CHAR
- True
-
-
- 3
- 4
- 2
- 3
-
-
-
-
-
- True
- 0
- 1
- <b>Private:</b>
- True
-
-
- 2
- 3
- 2
- 3
- GTK_FILL
-
-
-
-
-
- True
- 0
- True
-
-
- 1
- 2
- 3
- 4
-
-
-
-
-
- True
- 0
- True
-
-
- 3
- 4
- 3
- 4
-
-
-
-
-
- True
- 0
- 1
- <b># of files:</b>
- True
-
-
- 2
- 3
- 3
- 4
- GTK_FILL
-
-
-
-
-
- True
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- 0
-
-
- 1
- 4
- 4
- 5
-
-
-
-
-
- True
- 0
- 1
- <b>Status:</b>
- True
-
-
- 4
- 5
- GTK_FILL
-
-
-
-
-
+
True
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
0
@@ -1083,66 +976,53 @@
1
- 2
- 2
- 3
+ 4
+ 1
+ 2
-
+
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
- 0
- <b>Path:</b>
- True
-
-
+ 0
+ <b>Hash:</b>
+ True
- 2
- 3
+ 1
+ 2
GTK_FILL
-
- True
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- 5
-
-
- True
- 0
- 0
- 1
- <b>Name:</b>
- True
-
-
-
-
- GTK_FILL
-
-
-
-
-
+
True
0
- True
- PANGO_WRAP_CHAR
True
1
4
+ 5
+ 6
+
+
+
+
+
+ True
+ 0
+ 1
+ <b>Tracker:</b>
+ True
+
+
+ 5
+ 6
+ GTK_FILL
@@ -1169,51 +1049,64 @@
-
- True
- 0
- 1
- <b>Tracker:</b>
- True
-
-
- 5
- 6
- GTK_FILL
-
-
-
-
-
+
True
0
+ True
+ PANGO_WRAP_CHAR
True
1
4
- 5
- 6
-
+
True
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- 0
- <b>Hash:</b>
- True
+ 5
+
+
+ True
+ 0
+ 0
+ 1
+ <b>Name:</b>
+ 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
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+ <b>Path:</b>
+ True
+
+
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+
True
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
0
@@ -1221,11 +1114,118 @@
PANGO_WRAP_CHAR
True
+
+ 1
+ 2
+ 2
+ 3
+
+
+
+
+
+ True
+ 0
+ 1
+ <b>Status:</b>
+ True
+
+
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 0
+
1
4
- 1
- 2
+ 4
+ 5
+
+
+
+
+
+ True
+ 0
+ 1
+ <b># of files:</b>
+ True
+
+
+ 2
+ 3
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+
+ True
+ 0
+ True
+
+
+ 3
+ 4
+ 3
+ 4
+
+
+
+
+
+ True
+ 0
+ True
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+
+ True
+ 0
+ 1
+ <b>Private:</b>
+ True
+
+
+ 2
+ 3
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+
+ True
+ 0
+ True
+ PANGO_WRAP_CHAR
+ True
+
+
+ 3
+ 4
+ 2
+ 3
@@ -1370,6 +1370,387 @@
False
+
+
+ True
+ True
+ GTK_POLICY_AUTOMATIC
+ GTK_POLICY_AUTOMATIC
+
+
+ True
+ 5
+ GTK_RESIZE_QUEUE
+ GTK_SHADOW_NONE
+
+
+ True
+
+
+ True
+ 0
+ GTK_SHADOW_NONE
+
+
+ True
+ 12
+
+
+ True
+ 5
+ 4
+ 3
+ 5
+
+
+
+
+
+
+
+
+ True
+ True
+ 6
+ 1
+ -1 -1 999999 1 10 10
+
+
+ 1
+ 2
+ 2
+ 3
+
+
+
+
+
+
+ True
+ True
+ 6
+ 1
+ -1 -1 99999 0.10000000000000001 10 10
+ 1
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+
+
+ True
+ True
+ 6
+ 1
+ -1 -1 999999 0.10000000000000001 10 10
+ 1
+
+
+ 1
+ 2
+
+
+
+
+
+
+ True
+ 0
+ Max Connections:
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+
+ True
+ 0
+ Max Upload Speed:
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+ True
+ 0
+ Max Download Speed:
+
+
+ GTK_FILL
+
+
+
+
+
+ True
+ KiB/s
+
+
+ 2
+ 3
+
+
+
+
+
+
+ True
+ KiB/s
+
+
+ 2
+ 3
+ 1
+ 2
+
+
+
+
+
+
+ True
+ 0
+ Max Upload Slots:
+
+
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+
+ True
+ True
+ 6
+ 1
+ -1 -1 999999 1 10 10
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+
+
+
+
+
+
+ True
+ <b>Bandwidth</b>
+ True
+
+
+ label_item
+
+
+
+
+ False
+ False
+
+
+
+
+ True
+
+
+ True
+ 0
+ GTK_SHADOW_NONE
+
+
+ True
+ 12
+
+
+ True
+
+
+ True
+ True
+ Private
+ 0
+ True
+
+
+ False
+ False
+
+
+
+
+ True
+ True
+ Prioritize First/Last
+ 0
+ True
+
+
+ False
+ False
+ 1
+
+
+
+
+ True
+ True
+ True
+ 0
+
+
+ True
+ 5
+
+
+ True
+ gtk-edit
+
+
+ False
+ False
+
+
+
+
+ True
+ _Edit Trackers
+ True
+
+
+ False
+ False
+ 1
+
+
+
+
+
+
+ False
+ False
+ 2
+
+
+
+
+
+
+
+
+ True
+ <b>General</b>
+ True
+
+
+ label_item
+
+
+
+
+ False
+ False
+
+
+
+
+ True
+ 0
+ GTK_SHADOW_NONE
+
+
+ True
+ 12
+
+
+ True
+ True
+ True
+ gtk-apply
+ True
+ 0
+
+
+
+
+
+
+
+ label_item
+
+
+
+
+ False
+ False
+ 1
+
+
+
+
+ False
+ False
+ 1
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
+ True
+ 2
+
+
+ True
+ gtk-preferences
+
+
+
+
+ True
+ _Options
+ True
+
+
+ 1
+
+
+
+
+ tab
+ 4
+ False
+
+
False
diff --git a/deluge/ui/gtkui/options_tab.py b/deluge/ui/gtkui/options_tab.py
new file mode 100644
index 000000000..3a9191f35
--- /dev/null
+++ b/deluge/ui/gtkui/options_tab.py
@@ -0,0 +1,95 @@
+#
+# options_tab.py
+#
+# Copyright (C) 2008 Andrew Resch ('andar')
+#
+# Deluge is free software.
+#
+# You may redistribute it and/or modify it under the terms of the
+# GNU General Public License, as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# deluge is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with deluge. If not, write to:
+# The Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor
+# Boston, MA 02110-1301, USA.
+#
+# In addition, as a special exception, the copyright holders give
+# permission to link the code of portions of this program with the OpenSSL
+# library.
+# You must obey the GNU General Public License in all respects for all of
+# the code used other than OpenSSL. If you modify file(s) with this
+# exception, you may extend this exception to your version of the file(s),
+# but you are not obligated to do so. If you do not wish to do so, delete
+# this exception statement from your version. If you delete this exception
+# statement from all source files in the program, then also delete it here.
+
+import deluge.component as component
+from deluge.ui.client import aclient as client
+
+class OptionsTab:
+ def __init__(self):
+ glade = component.get("MainWindow").get_glade()
+ self.spin_max_download = glade.get_widget("spin_max_download")
+ self.spin_max_upload = glade.get_widget("spin_max_upload")
+ self.spin_max_connections = glade.get_widget("spin_max_connections")
+ self.spin_max_upload_slots = glade.get_widget("spin_max_upload_slots")
+ self.chk_private = glade.get_widget("chk_private")
+ self.chk_prioritize_first_last = glade.get_widget("chk_prioritize_first_last")
+
+ self.prev_torrent_id = None
+ self.prev_status = None
+
+ def update(self):
+ # Get the first selected torrent
+ torrent_id = component.get("TorrentView").get_selected_torrents()
+
+ # Only use the first torrent in the list or return if None selected
+ if len(torrent_id) != 0:
+ torrent_id = torrent_id[0]
+ else:
+ # No torrent is selected in the torrentview
+ return
+
+ if torrent_id != self.prev_torrent_id:
+ self.prev_status = None
+
+ client.get_torrent_status(self._on_get_torrent_status, torrent_id,
+ ["max_download_speed",
+ "max_upload_speed",
+ "max_connections",
+ "max_upload_slots",
+ "private",
+ "prioritize_first_last"])
+ self.prev_torrent_id = torrent_id
+
+ def _on_get_torrent_status(self, status):
+ # We only want to update values that have been applied in the core. This
+ # is so we don't overwrite the user changes that haven't been applied yet.
+ if self.prev_status == None:
+ self.prev_status = {}.fromkeys(status.keys(), None)
+
+ if status != self.prev_status and status.keys() == self.prev_status.keys():
+ if status["max_download_speed"] != self.prev_status["max_download_speed"]:
+ self.spin_max_download.set_value(status["max_download_speed"])
+ if status["max_upload_speed"] != self.prev_status["max_upload_speed"]:
+ self.spin_max_upload.set_value(status["max_upload_speed"])
+ if status["max_connections"] != self.prev_status["max_connections"]:
+ self.spin_max_connections.set_value(status["max_connections"])
+ if status["max_upload_slots"] != self.prev_status["max_upload_slots"]:
+ self.spin_max_upload_slots.set_value(status["max_upload_slots"])
+ if status["private"] != self.prev_status["private"]:
+ self.chk_private.set_active(status["private"])
+ if status["prioritize_first_last"] != self.prev_status["prioritize_first_last"]:
+ self.chk_prioritize_first_last.set_active(status["prioritize_first_last"])
+ self.prev_status = status
+
+ def clear(self):
+ pass
diff --git a/deluge/ui/gtkui/torrentdetails.py b/deluge/ui/gtkui/torrentdetails.py
index 3146dad0f..53c368021 100644
--- a/deluge/ui/gtkui/torrentdetails.py
+++ b/deluge/ui/gtkui/torrentdetails.py
@@ -41,6 +41,7 @@ from statistics_tab import StatisticsTab
from details_tab import DetailsTab
from files_tab import FilesTab
from peers_tab import PeersTab
+from options_tab import OptionsTab
from deluge.log import LOG as log
@@ -59,12 +60,14 @@ class TorrentDetails(component.Component):
details_tab = DetailsTab()
files_tab = FilesTab()
peers_tab = PeersTab()
+ options_tab = OptionsTab()
self.tabs = []
self.tabs.insert(0, statistics_tab)
self.tabs.insert(1, details_tab)
self.tabs.insert(2, files_tab)
self.tabs.insert(3, peers_tab)
+ self.tabs.insert(4, options_tab)
def visible(self, visible):
if visible: