diff --git a/deluge/ui/common.py b/deluge/ui/common.py
index 1bf1de107..9ad208e28 100644
--- a/deluge/ui/common.py
+++ b/deluge/ui/common.py
@@ -39,10 +39,7 @@ all the interfaces.
"""
import os
-import sys
import logging
-import urlparse
-import locale
from hashlib import sha1 as sha
from deluge import bencode
@@ -51,10 +48,12 @@ import deluge.configmanager
log = logging.getLogger(__name__)
+
# Dummy tranlation dict so Torrent states text is available for Translators
# All entries in deluge.common.TORRENT_STATE should be here. It does not need importing
# as the string matches the translation text so using the _() function is enough.
-def _(message): return message
+def _(message):
+ return message
STATE_TRANSLATION = {
"All": _("All"),
"Active": _("Active"),
@@ -67,8 +66,16 @@ STATE_TRANSLATION = {
"Queued": _("Queued"),
"Error": _("Error"),
}
+
+TRACKER_STATUS_TRANSLATION = {
+ "Error": _("Error"),
+ "Warning": _("Warning"),
+ "Announce OK": _("Announce OK"),
+ "Announce Sent": _("Announce Sent")
+}
del _
+
class TorrentInfo(object):
"""
Collects information about a torrent file.
diff --git a/deluge/ui/gtkui/details_tab.py b/deluge/ui/gtkui/details_tab.py
index 9a5816974..de5989eeb 100644
--- a/deluge/ui/gtkui/details_tab.py
+++ b/deluge/ui/gtkui/details_tab.py
@@ -21,11 +21,11 @@ def fpeer_size_second(first, second):
def fdate_blank(value):
- """Display value as date, eg 05/05/08 or blank"""
+ """Display value as date, eg 05/05/08 or dash"""
if value > 0.0:
return fdate(value)
else:
- return ""
+ return "-"
def str_yes_no(value):
@@ -59,25 +59,22 @@ class DetailsTab(Tab):
(builder.get_object("summary_pieces"), fpeer_size_second, ("num_pieces", "piece_length")),
]
+ self.status_keys = [status for widget in self.label_widgets for status in widget[2]]
+
def update(self):
# Get the first selected torrent
selected = component.get("TorrentView").get_selected_torrents()
# Only use the first torrent in the list or return if None selected
- if len(selected) != 0:
+ if selected:
selected = selected[0]
else:
# No torrent is selected in the torrentview
self.clear()
return
- # Get the torrent status
- status_keys = ["name", "total_size", "num_files", "time_added", "completed_time",
- "download_location", "hash", "comment", "owner", "num_pieces", "piece_length",
- "shared", "private"]
-
session = component.get("SessionProxy")
- session.get_torrent_status(selected, status_keys).addCallback(self._on_get_torrent_status)
+ session.get_torrent_status(selected, self.status_keys).addCallback(self._on_get_torrent_status)
def _on_get_torrent_status(self, status):
# Check to see if we got valid data from the core
@@ -87,14 +84,11 @@ class DetailsTab(Tab):
# Update all the label widgets
for widget in self.label_widgets:
if widget[1] is not None:
- args = []
try:
- for key in widget[2]:
- args.append(status[key])
- except Exception, e:
- log.debug("Unable to get status value: %s", e)
+ args = [status[key] for key in widget[2]]
+ except KeyError, ex:
+ log.debug("Unable to get status value: %s", ex)
continue
-
txt = widget[1](*args)
else:
txt = status[widget[2][0]]
diff --git a/deluge/ui/gtkui/glade/main_window.tabs.ui b/deluge/ui/gtkui/glade/main_window.tabs.ui
index caca91a8a..8c4038744 100644
--- a/deluge/ui/gtkui/glade/main_window.tabs.ui
+++ b/deluge/ui/gtkui/glade/main_window.tabs.ui
@@ -58,15 +58,63 @@
- 4
- 5
+ 6
+ 7
1
2
GTK_FILL
@@ -297,8 +223,8 @@
0
- 5
- 6
+ 7
+ 8
GTK_FILL
@@ -313,148 +239,8 @@
- 4
- 5
- GTK_FILL
-
-
-
-
- True
- False
- 15
- 5
-
-
-
-
-
- 2
- 3
- 3
- 4
- GTK_FILL
-
-
-
-
- True
- False
- 15
- 5
-
-
- True
- False
- 0
- ETA:
-
-
-
-
-
-
-
- 2
- 3
- 2
- 3
- GTK_FILL
-
-
-
-
- True
- False
- 15
- 5
-
-
- True
- False
- 0
- Up Speed:
-
-
-
-
-
-
-
- 2
- 3
- 1
- 2
- GTK_FILL
-
-
-
-
- True
- False
- 15
- 5
-
-
- True
- False
- 0
- Down Speed:
-
-
-
-
-
-
-
- 2
- 3
- GTK_FILL
-
-
-
-
- True
- False
- 5
-
-
- True
- False
- 0
- Next Announce:
-
-
-
-
-
-
-
- 3
- 4
- GTK_FILL
-
-
-
-
- True
- False
- 5
-
-
- True
- False
- 0
- Share Ratio:
-
-
-
-
-
-
-
- 2
- 3
+ 6
+ 7
GTK_FILL
@@ -476,8 +262,8 @@
- 1
- 2
+ 3
+ 4
GTK_FILL
@@ -499,20 +285,8 @@
- GTK_FILL
-
-
-
-
- True
- False
- 0
-
-
- 3
- 4
- 1
- 2
+ 2
+ 3
GTK_FILL
@@ -521,6 +295,94 @@
True
False
0
+ 5
+
+
+ 1
+ 2
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+ True
+ False
+ 0
+ 5
+
+
+ 1
+ 2
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ 0
+ Down Speed:
+
+
+
+
+
+
+
+ GTK_FILL
+
+
+
+
+ True
+ False
+ 0
+ 5
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ 0
+ Up Speed:
+
+
+
+
+
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ False
+ 0
+ 5
1
@@ -531,10 +393,21 @@
-
+
True
False
- 0
+ 5
+
+
+ True
+ False
+ 0
+ ETA:
+
+
+
+
+
3
@@ -543,14 +416,78 @@
-
+
True
False
0
- 1
- 2
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+ True
+ False
+ 0
+ Active Time:
+
+
+
+
+
+ 3
+ 4
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ False
+ 0
+
+
+ 4
+ 5
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+ True
+ False
+ 0
+ Seeding Time:
+
+
+
+
+
+ 3
+ 4
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ False
+ 0
+
+
+ 4
+ 5
+ 2
+ 3
GTK_FILL
@@ -559,7 +496,6 @@
True
False
0
- 0
Complete Seen:
@@ -568,10 +504,9 @@
6
7
- 2
- 3
+ 3
+ 4
GTK_FILL
- GTK_FILL
@@ -585,9 +520,65 @@
7
8
- 2
- 3
- GTK_FILL
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+ True
+ False
+ 0
+ Share Ratio:
+
+
+
+
+
+ 3
+ 4
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+ True
+ False
+ 0
+
+
+ 4
+ 5
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ 2
+ 3
+ 5
+ GTK_SHRINK
+
+
+
+
+ True
+ False
+
+
+ 5
+ 6
+ 5
+ GTK_SHRINK
@@ -601,10 +592,10 @@
- 6
- 7
- 3
- 4
+ 3
+ 4
+ 4
+ 5
GTK_FILL
@@ -614,133 +605,11 @@
False
0
-
- 7
- 8
- 3
- 4
- GTK_FILL
-
-
-
-
- True
- False
- 0
- char
- True
-
-
- 1
- 4
- 5
- 6
-
-
-
-
-
- True
- False
- 0
- True
- char
- True
-
-
- 5
- 8
- 5
- 6
- GTK_FILL
-
-
-
-
- True
- False
- 0
- 0
- Tracker Status:
-
-
-
-
4
5
- 5
- 6
- GTK_FILL
- GTK_FILL
-
-
-
-
- True
- False
- 5
-
-
- True
- False
- 0
- 1
- Tracker:
-
-
-
-
-
-
-
- 5
- 6
- GTK_FILL
-
-
-
-
- True
- False
- 0
- 1
- Torrent Status:
-
-
-
-
-
4
5
-
-
-
-
- True
- False
- 0
- True
-
-
- 1
- 4
- 4
- 5
-
-
-
-
-
- True
- False
- 0
-
-
- 3
- 4
- 2
- 3
GTK_FILL
@@ -756,14 +625,11 @@
-
-
-
False
False
- 1
+ 2
@@ -783,6 +649,7 @@
True
False
+ 2
gtk-dialog-info
@@ -825,53 +692,23 @@
True
False
+ 0
+ 0
10
10
- 15
+ 10
15
True
False
- 7
- 2
+ 6
+ 5
10
- 6
-
-
-
- 6
- 7
- GTK_SHRINK | GTK_FILL
- GTK_FILL
-
-
-
-
-
- 1
- 2
- 6
- 7
-
-
-
+ 5
+ 200
True
False
0
@@ -882,23 +719,178 @@
1
2
-
+ GTK_EXPAND
-
+
True
False
0
- 1
- Name:
+ Added:
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+
+ 100
+ True
+ False
+ 0
+
+
+ 4
+ 5
GTK_SHRINK | GTK_FILL
- GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ Completed:
+
+
+
+
+
+ 3
+ 4
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+
+
+ 4
+ 5
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ Owner:
+
+
+
+
+
+ 3
+ 4
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ char
+ True
+
+
+ 4
+ 5
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ Shared:
+
+
+
+
+
+ 3
+ 4
+ 5
+ 6
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ char
+ True
+
+
+ 4
+ 5
+ 5
+ 6
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ Download Folder:
+
+
+
+
+
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ True
+ char
+ True
+
+
+ 1
+ 2
+ 3
+ 4
+
@@ -912,9 +904,9 @@
- 5
- 6
- GTK_SHRINK | GTK_FILL
+ 4
+ 5
+ GTK_FILL
@@ -930,341 +922,206 @@
1
2
- 5
- 6
+ 4
+ 5
-
- True
- False
- 3
- 6
- 10
- 5
-
-
- True
- False
- 0
- 1
- Total Files:
-
-
-
-
-
- 2
- 3
- GTK_FILL
-
-
-
-
- True
- False
- 0
- 1
- Total Size:
-
-
-
-
-
- GTK_SHRINK | GTK_FILL
-
-
-
-
- True
- False
- 0
- True
-
-
- 1
- 2
- GTK_FILL
-
-
-
-
-
- True
- False
- 0
- True
-
-
- 3
- 4
- GTK_FILL
-
-
-
-
-
- True
- False
- 0
- Pieces:
-
-
-
-
-
- 4
- 5
- GTK_FILL
- GTK_FILL
-
-
-
-
- True
- False
- 0
-
-
- 5
- 6
- GTK_FILL
-
-
-
-
- True
- False
- 0
- 1
- Private:
-
-
-
-
-
- 4
- 5
- 1
- 2
- GTK_SHRINK | GTK_FILL
-
-
-
-
-
- True
- False
- 0
- char
- True
-
-
- 5
- 6
- 1
- 2
- GTK_FILL
-
-
-
-
-
- True
- False
- 0
- Added:
-
-
-
-
-
- 1
- 2
- GTK_SHRINK | GTK_FILL
-
-
-
-
- True
- False
- 0
- Completed:
-
-
-
-
-
- 2
- 3
- GTK_SHRINK | GTK_FILL
-
-
-
-
- True
- False
- 0
-
-
- 1
- 2
- 2
- 3
- GTK_FILL
-
-
-
-
- True
- False
- 0
- 1
- Owner:
-
-
-
-
-
- 2
- 3
- 1
- 2
- GTK_SHRINK | GTK_FILL
-
-
-
-
-
- True
- False
- 0
- 1
- Shared:
-
-
-
-
-
- 2
- 3
- 2
- 3
- GTK_SHRINK | GTK_FILL
-
-
-
-
-
- True
- False
- 0
- char
- True
-
-
- 3
- 4
- 2
- 3
- GTK_FILL
-
-
-
-
-
- True
- False
- 0
- 20
-
-
- True
- False
- 0
-
-
-
-
- 1
- 2
- 1
- 2
- GTK_FILL
-
-
-
-
- True
- False
- 0
- 20
-
-
- True
- False
- 0
- char
- True
-
-
-
-
- 3
- 4
- 1
- 2
- GTK_FILL
-
-
-
-
-
-
-
-
-
-
-
- 2
- 1
- 4
- GTK_SHRINK | GTK_FILL
-
-
-
-
-
+
- 4
- 5
- GTK_SHRINK | GTK_FILL
- GTK_FILL
+ 5
+ 6
+ GTK_FILL
+
-
+
1
2
- 4
- 5
+ 5
+ 6
+
+
+
+
+
+ True
+ False
+
+
+ 2
+ 3
+ 6
+ GTK_SHRINK
+
+
+
+
+ True
+ False
+ 0
+ Name:
+
+
+
+
+
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ Total Size:
+
+
+
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+ 60
+ True
+ False
+ 0
+ True
+
+
+ 1
+ 2
+ 1
+ 2
+ GTK_SHRINK | GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ Total Files:
+
+
+
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ True
+
+
+ 1
+ 2
+ 2
+ 3
+ GTK_SHRINK | GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ Private:
+
+
+
+
+
+ 3
+ 4
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ char
+ True
+
+
+ 4
+ 5
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ Pieces:
+
+
+
+
+
+ 3
+ 4
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+
+
+ 4
+ 5
+ 2
+ 3
+ GTK_SHRINK | GTK_FILL
@@ -1288,6 +1145,7 @@
True
False
+ 2
gtk-properties
@@ -1341,6 +1199,7 @@
True
False
+ 2
gtk-copy
@@ -1394,6 +1253,7 @@
True
False
+ 2
gtk-network
@@ -1431,253 +1291,375 @@
True
False
- 5
queue
none
-
+
True
False
- 3
+ 10
+ 10
+ 5
+ 15
-
+
True
False
- 0
- none
+ 5
+
+
+ True
+ False
+
+
+ 1
+ 2
+
+
+
+
+
+ True
+ False
+
+
+ 3
+ 4
+
+
+
+
+
+ True
+ False
+ 0
+ none
+
+
+ True
+ False
+ 0
+ 0
+ 0
+
+
+ True
+ False
+ 5
+ 4
+ 3
+ 4
+ 2
+
+
+ True
+ True
+ •
+ 6
+ 1
+ True
+ False
+ False
+ True
+ True
+ spin_max_connections_adjustment
+ True
+
+
+ 1
+ 2
+ 2
+ 3
+
+
+
+
+
+
+ True
+ True
+ •
+ 6
+ 1
+ True
+ False
+ False
+ True
+ True
+ spin_max_upload_adjustment
+ 1
+ True
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+
+
+ True
+ True
+ •
+ 6
+ 1
+ True
+ False
+ False
+ True
+ True
+ spin_max_download_adjustment
+ 1
+ 1
+ True
+
+
+ 1
+ 2
+
+
+
+
+
+
+ True
+ False
+ 0
+ Connections:
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ Upload Speed:
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ Download Speed:
+
+
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ KiB/s
+
+
+ 2
+ 3
+
+
+
+
+
+
+ True
+ False
+ KiB/s
+
+
+ 2
+ 3
+ 1
+ 2
+
+
+
+
+
+
+ True
+ False
+ 0
+ Upload Slots:
+
+
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+
+ True
+ True
+ •
+ 6
+ 1
+ True
+ False
+ False
+ True
+ True
+ spin_max_upload_slots_adjustment
+ True
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ False
+ Bandwidth Limits
+
+
+
+
+
+
+
+
+ GTK_FILL
+
+
True
False
- 12
+ 0
+ 10
-
+
True
False
- 5
- 4
- 3
- 5
- 2
-
+
+ Shared
+ False
True
True
- •
- 6
- 1
- True
- False
- False
- True
- True
- spin_max_connections_adjustment
- True
+ False
+ True
+
- 1
- 2
- 2
- 3
-
-
+ False
+ True
+ 0
-
+
+ Prioritize First/Last
+ False
True
True
- •
- 6
- 1
- True
- False
- False
- True
- True
- spin_max_upload_adjustment
- 1
- True
+ False
+ True
+
- 1
- 2
- 1
- 2
-
-
+ False
+ True
+ 1
-
+
+ Sequential Download
+ False
True
True
- •
- 6
- 1
- True
- False
- False
- True
- True
- spin_max_download_adjustment
- 1
- 1
- True
+ False
+ True
+
- 1
- 2
-
-
+ False
+ True
+ 2
-
- True
- False
- 0
- Max Connections:
-
-
- 2
- 3
- GTK_FILL
-
-
-
-
-
- True
- False
- 0
- Max Upload Speed:
-
-
- 1
- 2
- GTK_FILL
-
-
-
-
-
- True
- False
- 0
- Max Download Speed:
-
-
- GTK_FILL
-
-
-
-
-
- True
- False
- KiB/s
-
-
- 2
- 3
-
-
-
-
-
-
- True
- False
- KiB/s
-
-
- 2
- 3
- 1
- 2
-
-
-
-
-
-
- True
- False
- 0
- Max Upload Slots:
-
-
- 3
- 4
- GTK_FILL
-
-
-
-
-
+
+ Move completed:
+ False
True
True
- •
- 6
- 1
- True
- False
- False
- True
- True
- spin_max_upload_slots_adjustment
- True
+ False
+ True
+
- 1
- 2
- 3
- 4
-
-
+ False
+ False
+ 3
-
-
-
-
+
+ True
+ False
+
+
+
+
+
+ False
+ True
+ 4
+
+
+ 4
+ 5
+
-
-
- True
- False
- Bandwidth
-
-
-
-
-
-
-
-
- GTK_FILL
-
-
-
-
- True
- False
- 0
- none
True
False
- 5
- 12
+ 2
+ 5
+ 5
-
+
True
False
@@ -1697,217 +1679,91 @@
-
+
+ Stop seed at ratio:
+ False
True
- False
-
-
- True
- False
- 5
-
-
- Stop seed at ratio:
- False
- True
- True
- False
- True
-
-
-
- False
- False
- 0
-
-
-
-
- True
- True
- •
- 1
- True
- False
- False
- True
- True
- spin_stop_ratio_adjustment
- 1
- True
-
-
- False
- False
- 1
-
-
-
-
- False
- False
- 0
-
-
-
-
- True
- False
- 10
-
-
- Remove at ratio
- False
- True
- True
- False
- True
-
-
-
-
-
- False
- False
- 1
-
-
+ True
+ False
+ True
+
- True
+ False
True
1
-
-
-
-
-
-
- True
- False
- Queue
-
-
-
-
-
-
-
- 1
- 2
-
- GTK_FILL
-
-
-
-
- True
- False
- 2
- 2
-
-
- True
- False
- 0
- none
-
-
- True
- False
- 0
- 0
- 5
- 12
-
+
True
False
- 3
- 2
+ 10
+ 10
-
- Prioritize First/Last
- False
+
+ 50
True
True
- False
- True
-
+ •
+ True
+ False
+ False
+ True
+ True
+ spin_stop_ratio_adjustment
+ 1
+ True
-
- 2
- 1
- 2
-
-
-
-
-
- Sequential Download
- False
- True
- True
- False
- True
-
-
-
- 2
- 2
- 3
-
-
-
-
-
- Shared
- False
- True
- True
- False
- True
-
-
-
- 2
-
-
+
+ False
+ False
+ 2
+
-
-
-
-
- True
- False
- <b>General</b>
- True
-
-
-
-
- GTK_EXPAND | GTK_SHRINK | GTK_FILL
-
-
-
-
- True
- False
- 0
- none
-
-
- True
- False
- 12
-
+
True
False
+ 10
+
+
+ Remove at ratio
+ False
+ True
+ True
+ False
+ True
+
+
+
+
+
+ False
+ False
+ 3
+
+
+
+
+ True
+ False
+
+
+ False
+ True
+ 7
+ 4
+
+
+
+
+ True
+ False
+ 1
+ 0.69999998807907104
gtk-apply
@@ -1919,139 +1775,24 @@
True
-
- False
- False
- 0
-
-
-
- False
- True
- True
- True
- 0
- 0
-
-
-
- True
- False
- 5
-
-
- True
- False
- gtk-edit
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- _Edit Trackers
- True
-
-
- False
- False
- 1
-
-
-
-
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
- True
- False
- General
-
-
-
-
-
-
-
- 1
- 2
-
- GTK_FILL
-
-
-
-
- True
- False
- 0
- 14
-
-
- True
- False
-
-
- Move completed:
- False
- True
- True
- False
- True
-
False
- False
- 0
-
-
-
-
- True
- False
-
-
-
-
-
- True
True
- 1
+ 5
- 1
- 2
+ 2
+ 3
+ GTK_FILL
-
-
-
-
- 2
- 3
-
-
@@ -2071,6 +1812,7 @@
True
False
+ 2
gtk-preferences
@@ -2080,7 +1822,7 @@
-
+
True
False
_Options
@@ -2098,6 +1840,268 @@
False
+
+
+ True
+ True
+ automatic
+ automatic
+
+
+ True
+ False
+ none
+
+
+ True
+ False
+ 10
+ 10
+ 10
+ 15
+
+
+ True
+ False
+ 5
+ 2
+ 10
+ 5
+
+
+ True
+ False
+ 0
+ Current Tracker:
+
+
+
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ True
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+
+ True
+ False
+ 0
+ Next Announce:
+
+
+
+
+
+ 3
+ 4
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ True
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+
+ True
+ False
+ 0
+ 0
+ Tracker Status:
+
+
+
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ True
+ char
+ True
+
+
+ 1
+ 2
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ False
+ 0
+ 0
+ 5
+ 5
+
+
+ False
+ True
+ True
+ True
+ 0
+ 0
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ gtk-edit
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ _Edit Trackers
+ True
+
+
+ False
+ False
+ 1
+
+
+
+
+
+
+
+
+ 2
+ 4
+ 5
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ Total Trackers:
+
+
+
+
+
+ GTK_FILL
+
+
+
+
+
+ True
+ False
+ 0
+ True
+
+
+ 1
+ 2
+ GTK_FILL
+
+
+
+
+
+
+
+
+
+
+ 5
+
+
+
+
+ True
+ False
+ 2
+
+
+ True
+ False
+ 2
+ gtk-goto-last
+
+
+ True
+ True
+ 0
+
+
+
+
+ True
+ False
+ _Trackers
+ True
+
+
+ True
+ True
+ 1
+
+
+
+
+ 5
+ False
+
+
diff --git a/deluge/ui/gtkui/options_tab.py b/deluge/ui/gtkui/options_tab.py
index 5595bae7b..a93ccb7e3 100644
--- a/deluge/ui/gtkui/options_tab.py
+++ b/deluge/ui/gtkui/options_tab.py
@@ -77,7 +77,6 @@ class OptionsTab(Tab):
component.get("MainWindow").connect_signals({
"on_button_apply_clicked": self._on_button_apply_clicked,
- "on_button_edit_trackers_clicked": self._on_button_edit_trackers_clicked,
"on_chk_move_completed_toggled": self._on_chk_move_completed_toggled,
"on_chk_stop_at_ratio_toggled": self._on_chk_stop_at_ratio_toggled,
"on_chk_toggled": self._on_chk_toggled,
@@ -102,7 +101,7 @@ class OptionsTab(Tab):
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:
+ if torrent_id:
torrent_id = torrent_id[0]
self._child_widget.set_sensitive(True)
else:
@@ -250,17 +249,6 @@ class OptionsTab(Tab):
)
self.button_apply.set_sensitive(False)
- def _on_button_edit_trackers_clicked(self, button):
- from edittrackersdialog import EditTrackersDialog
- dialog = EditTrackersDialog(
- self.prev_torrent_id,
- component.get("MainWindow").window)
-
- def on_response(result):
- if result:
- self.button_apply.set_sensitive(True)
- dialog.run().addCallback(on_response)
-
def _on_chk_move_completed_toggled(self, widget):
value = self.chk_move_completed.get_active()
self.move_completed_path_chooser.set_sensitive(value)
diff --git a/deluge/ui/gtkui/piecesbar.py b/deluge/ui/gtkui/piecesbar.py
index 329d0aa93..ce5a186b1 100644
--- a/deluge/ui/gtkui/piecesbar.py
+++ b/deluge/ui/gtkui/piecesbar.py
@@ -52,6 +52,7 @@ COLOR_STATES = {
3: "completed"
}
+
class PiecesBar(gtk.DrawingArea):
# Draw in response to an expose-event
__gsignals__ = {"expose-event": "override"}
@@ -141,7 +142,7 @@ class PiecesBar(gtk.DrawingArea):
def __draw_pieces(self):
if (self.__resized() or self.__pieces != self.__old_pieces or
- self.__pieces_overlay == None):
+ self.__pieces_overlay is None):
# Need to recreate the cache drawing
self.__pieces_overlay = cairo.ImageSurface(
cairo.FORMAT_ARGB32, self.__width, self.__height
@@ -194,14 +195,13 @@ class PiecesBar(gtk.DrawingArea):
if not self.__state:
# Nothing useful to draw, return now!
return
- if (self.__resized() or self.__fraction != self.__old_fraction) or \
- self.__progress_overlay is None:
+ if (self.__resized() or self.__fraction != self.__old_fraction) or self.__progress_overlay is None:
# Need to recreate the cache drawing
self.__progress_overlay = cairo.ImageSurface(
cairo.FORMAT_ARGB32, self.__width, self.__height
)
ctx = cairo.Context(self.__progress_overlay)
- ctx.set_source_rgba(0.1, 0.1, 0.1, 0.3) # Transparent
+ ctx.set_source_rgba(0.1, 0.1, 0.1, 0.3) # Transparent
ctx.rectangle(0.0, 0.0, self.__width*self.__fraction, self.__height)
ctx.fill()
self.__cr.set_source_surface(self.__progress_overlay)
@@ -230,7 +230,7 @@ class PiecesBar(gtk.DrawingArea):
text += self.__text
else:
if self.__state:
- text += self.__state + " "
+ text += _(self.__state) + " "
if self.__fraction == 1.0:
format = "%d%%"
else:
diff --git a/deluge/ui/gtkui/status_tab.py b/deluge/ui/gtkui/status_tab.py
index 2c46f6e63..f199d744f 100644
--- a/deluge/ui/gtkui/status_tab.py
+++ b/deluge/ui/gtkui/status_tab.py
@@ -55,8 +55,10 @@ def fratio(value):
return "%.3f" % value
-def fpcnt(value):
- return "%.2f%%" % value
+def fpcnt(value, state):
+ if state:
+ state = _(state) + " "
+ return "%s%.2f%%" % (state, value)
def fspeed(value, max_value=-1):
@@ -102,40 +104,32 @@ class StatusTab(Tab):
(builder.get_object("summary_peers"), deluge.common.fpeer, ("num_peers", "total_peers")),
(builder.get_object("summary_eta"), deluge.common.ftime, ("eta",)),
(builder.get_object("summary_share_ratio"), fratio, ("ratio",)),
- (builder.get_object("summary_tracker_status"), None, ("tracker_status",)),
- (builder.get_object("summary_next_announce"), deluge.common.ftime, ("next_announce",)),
(builder.get_object("summary_active_time"), deluge.common.ftime, ("active_time",)),
(builder.get_object("summary_seed_time"), deluge.common.ftime, ("seeding_time",)),
(builder.get_object("summary_seed_rank"), str, ("seed_rank",)),
- (builder.get_object("summary_auto_managed"), str, ("is_auto_managed",)),
- (builder.get_object("progressbar"), fpcnt, ("progress",)),
+ (builder.get_object("progressbar"), fpcnt, ("progress", "state")),
(builder.get_object("summary_last_seen_complete"), fdate_or_never, ("last_seen_complete",)),
(builder.get_object("summary_torrent_status"), str, ("message",)),
- (builder.get_object("summary_tracker"), None, ("tracker_host",)),
]
+ self.status_keys = [status for widget in self.label_widgets for status in widget[2]]
+
def update(self):
# Get the first selected torrent
selected = component.get("TorrentView").get_selected_torrents()
# Only use the first torrent in the list or return if None selected
- if len(selected) != 0:
+ if selected:
selected = selected[0]
else:
# No torrent is selected in the torrentview
+ self.clear()
return
# Get the torrent status
- status_keys = [
- "distributed_copies", "all_time_download", "total_payload_download",
- "total_uploaded", "total_payload_upload", "download_payload_rate", "max_download_speed",
- "upload_payload_rate", "max_upload_speed", "num_peers", "num_seeds", "total_peers",
- "total_seeds", "eta", "ratio", "tracker_status", "next_announce", "active_time",
- "seeding_time", "seed_rank", "is_auto_managed", "progress", "last_seen_complete",
- "message", "tracker_host"
- ]
+ status_keys = self.status_keys
if self.config['show_piecesbar']:
- status_keys.extend(["pieces", "state", "num_pieces"])
+ status_keys = self.status_keys + ["pieces", "num_pieces"]
component.get("SessionProxy").get_torrent_status(
selected, status_keys).addCallback(self._on_get_torrent_status)
@@ -145,33 +139,14 @@ class StatusTab(Tab):
if status is None:
return
- if status["is_auto_managed"]:
- status["is_auto_managed"] = _("On")
- else:
- status["is_auto_managed"] = _("Off")
-
- translate_tracker_status = {
- "Error": _("Error"),
- "Warning": _("Warning"),
- "Announce OK": _("Announce OK"),
- "Announce Sent": _("Announce Sent")
- }
- for key, value in translate_tracker_status.iteritems():
- if key in status["tracker_status"]:
- status["tracker_status"] = status["tracker_status"].replace(key, value, 1)
- break
-
# Update all the label widgets
for widget in self.label_widgets:
if widget[1] is not None:
- args = []
try:
- for key in widget[2]:
- args.append(status[key])
- except Exception, e:
- log.debug("Unable to get status value: %s", e)
+ args = [status[key] for key in widget[2]]
+ except KeyError, ex:
+ log.debug("Unable to get status value: %s", ex)
continue
-
txt = widget[1](*args)
else:
txt = status[widget[2][0]]
@@ -202,7 +177,7 @@ class StatusTab(Tab):
if show:
self.piecesbar = PiecesBar()
self.builder.get_object("status_progress_vbox").pack_start(
- self.piecesbar, False, False, 5
+ self.piecesbar, False, False, 0
)
self.progressbar.hide()
diff --git a/deluge/ui/gtkui/torrentdetails.py b/deluge/ui/gtkui/torrentdetails.py
index 3de609dd7..d915a95f8 100644
--- a/deluge/ui/gtkui/torrentdetails.py
+++ b/deluge/ui/gtkui/torrentdetails.py
@@ -1,36 +1,10 @@
-#
-# torrentdetails.py
+# -*- coding: utf-8 -*-
#
# Copyright (C) 2007 Andrew Resch
#
-# 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 3 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.
-#
+# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+# the additional special exception to link portions of this program with the OpenSSL library.
+# See LICENSE for more details.
#
@@ -45,6 +19,7 @@ from deluge.ui.gtkui.common import save_pickled_state_file, load_pickled_state_f
log = logging.getLogger(__name__)
+
class Tab:
def __init__(self):
self.is_visible = True
@@ -69,6 +44,7 @@ class Tab:
return self._tab_label
+
class TorrentDetails(component.Component):
def __init__(self):
component.Component.__init__(self, "TorrentDetails", interval=2)
@@ -91,13 +67,15 @@ class TorrentDetails(component.Component):
from files_tab import FilesTab
from peers_tab import PeersTab
from options_tab import OptionsTab
+ from trackers_tab import TrackersTab
default_tabs = {
"Status": StatusTab,
"Details": DetailsTab,
"Files": FilesTab,
"Peers": PeersTab,
- "Options": OptionsTab
+ "Options": OptionsTab,
+ "Trackers": TrackersTab
}
# tab_name, visible
@@ -106,17 +84,19 @@ class TorrentDetails(component.Component):
("Details", True),
("Files", True),
("Peers", True),
- ("Options", True)
+ ("Options", True),
+ ("Trackers", True)
]
self.translate_tabs = {
- "All" : _("_All"),
- "Status" : _("_Status"),
- "Details" : _("_Details"),
- "Files" : _("_Files"),
- "Peers" : _("_Peers"),
- "Options" : _("_Options")
- }
+ "All": _("_All"),
+ "Status": _("_Status"),
+ "Details": _("_Details"),
+ "Files": _("_Files"),
+ "Peers": _("_Peers"),
+ "Options": _("_Options"),
+ "Trackers": _("_Trackers")
+ }
# Get the state from saved file
state = self.load_state()
@@ -129,13 +109,12 @@ class TorrentDetails(component.Component):
break
# The state is a list of tab_names in the order they should appear
- if state == None:
+ if state is None:
# Set the default order
state = default_order
# We need to rename the tab in the state for backwards compat
- self.state = [(tab_name.replace("Statistics", "Status"), visible) for
- tab_name, visible in state]
+ self.state = [(tab_name.replace("Statistics", "Status"), visible) for tab_name, visible in state]
for tab in default_tabs.itervalues():
self.add_tab(tab(), generate_menu=False)
@@ -162,7 +141,6 @@ class TorrentDetails(component.Component):
break
return position
-
def add_tab(self, tab, generate_menu=True, visible=None):
name = tab.get_name()
@@ -208,10 +186,8 @@ class TorrentDetails(component.Component):
if generate_menu:
self.generate_menu()
-
def regenerate_positions(self):
- """This will sync up the positions in the tab, with the position stored
- in the tab object"""
+ """Sync the positions in the tab, with the position stored in the tab object"""
for tab in self.tabs:
page_num = self.notebook.page_num(self.tabs[tab]._child_widget)
if page_num > -1:
@@ -262,8 +238,7 @@ class TorrentDetails(component.Component):
def show_tab(self, tab_name, generate_menu=True):
log.debug("%s\n%s\n%s", self.tabs[tab_name].get_child_widget(),
- self.tabs[tab_name].get_tab_label(),
- self.tabs[tab_name].position)
+ self.tabs[tab_name].get_tab_label(), self.tabs[tab_name].position)
position = self.tab_insert_position(self.tabs[tab_name].weight)
@@ -344,7 +319,6 @@ class TorrentDetails(component.Component):
except AttributeError:
pass
-
def shutdown(self):
# Save the state of the tabs
for tab in self.tabs:
@@ -362,7 +336,7 @@ class TorrentDetails(component.Component):
self.clear()
if self.notebook.get_property("visible"):
- if page_num == None:
+ if page_num is None:
page_num = self.notebook.get_current_page()
try:
# Get the tab name
diff --git a/deluge/ui/gtkui/trackers_tab.py b/deluge/ui/gtkui/trackers_tab.py
new file mode 100644
index 000000000..b92cb1f7d
--- /dev/null
+++ b/deluge/ui/gtkui/trackers_tab.py
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2008 Andrew Resch
+#
+# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+# the additional special exception to link portions of this program with the OpenSSL library.
+# See LICENSE for more details.
+#
+
+import logging
+
+import deluge.component as component
+from deluge.common import ftime
+from deluge.ui.gtkui.torrentdetails import Tab
+
+log = logging.getLogger(__name__)
+
+
+def fcount(value):
+ return "%s" % len(value)
+
+
+def ftranslate(text):
+ if text:
+ text = _(text)
+ return text
+
+
+class TrackersTab(Tab):
+ def __init__(self):
+ Tab.__init__(self)
+ # Get the labels we need to update.
+ # widget name, modifier function, status keys
+ builder = component.get("MainWindow").get_builder()
+
+ self._name = "Trackers"
+ self._child_widget = builder.get_object("trackers_tab")
+ self._tab_label = builder.get_object("trackers_tab_label")
+
+ self.label_widgets = [
+ (builder.get_object("summary_next_announce"), ftime, ("next_announce",)),
+ (builder.get_object("summary_tracker"), None, ("tracker_host",)),
+ (builder.get_object("summary_tracker_status"), ftranslate, ("tracker_status",)),
+ (builder.get_object("summary_tracker_total"), fcount, ("trackers",)),
+ ]
+
+ self.status_keys = [status for widget in self.label_widgets for status in widget[2]]
+
+ component.get("MainWindow").connect_signals({
+ "on_button_edit_trackers_clicked": self._on_button_edit_trackers_clicked,
+ })
+
+ def update(self):
+ # Get the first selected torrent
+ selected = component.get("TorrentView").get_selected_torrents()
+
+ # Only use the first torrent in the list or return if None selected
+ if selected:
+ selected = selected[0]
+ else:
+ self.clear()
+ return
+
+ session = component.get("SessionProxy")
+ session.get_torrent_status(selected, self.status_keys).addCallback(self._on_get_torrent_status)
+
+ def _on_get_torrent_status(self, status):
+ # Check to see if we got valid data from the core
+ if not status:
+ return
+
+ # Update all the label widgets
+ for widget in self.label_widgets:
+ if widget[1] is None:
+ txt = status[widget[2][0]]
+ else:
+ try:
+ args = [status[key] for key in widget[2]]
+ except KeyError, ex:
+ log.debug("Unable to get status value: %s", ex)
+ continue
+ txt = widget[1](*args)
+
+ if widget[0].get_text() != txt:
+ widget[0].set_text(txt)
+
+ def clear(self):
+ for widget in self.label_widgets:
+ widget[0].set_text("")
+
+ def _on_button_edit_trackers_clicked(self, button):
+ torrent_id = component.get("TorrentView").get_selected_torrent()
+ if torrent_id:
+ from edittrackersdialog import EditTrackersDialog
+ dialog = EditTrackersDialog(torrent_id, component.get("MainWindow").window)
+ dialog.run()