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 @@ True False - 10 + 5 10 - 15 - 15 + 10 + 10 True False 5 + + + True + False + + + True + False + 5 + + + True + False + 0 + 1 + Status: + + + + + + + + False + False + 0 + + + + + True + False + 0 + True + + + True + True + 1 + + + + + False + False + 0 + + True @@ -91,124 +139,17 @@ False True - 0 + 1 True False - 6 + 5 8 10 5 - - - True - False - 0 - - - 5 - 6 - 3 - 4 - GTK_FILL - - - - - True - False - 0 - Auto Managed: - - - - - - 4 - 5 - 3 - 4 - GTK_FILL - - - - - True - False - 0 - - - 7 - 8 - 1 - 2 - GTK_FILL - - - - - True - False - 0 - Seeding Time: - - - - - - 6 - 7 - 1 - 2 - GTK_FILL - - - - - True - False - 0 - - - 7 - 8 - GTK_FILL - - - - - True - False - 0 - Active Time: - - - - - - 6 - 7 - GTK_FILL - - - - - True - False - 0 - True - - - 1 - 2 - 3 - 4 - GTK_FILL - - True @@ -218,8 +159,8 @@ word-char - 5 - 6 + 7 + 8 2 3 GTK_FILL @@ -230,29 +171,14 @@ True False 0 - 1 Availability: - 4 - 5 - 2 - 3 - GTK_FILL - - - - - True - False - 0 - - - 1 - 2 + 6 + 7 2 3 GTK_FILL @@ -265,8 +191,8 @@ 0 - 5 - 6 + 7 + 8 1 2 GTK_FILL @@ -283,8 +209,8 @@ - 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 - - - True - False - 0 - Comments: - - - - - - 6 - 7 - GTK_SHRINK | GTK_FILL - GTK_FILL - - - - - True - False - 0 - char - True - - - 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 - - - - - + True False 0 - Download Folder: + Comments: - 4 - 5 - GTK_SHRINK | GTK_FILL - GTK_FILL + 5 + 6 + GTK_FILL + - + + 150 True False 0 - True char True 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()