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: