diff --git a/glade/delugegtk.glade b/glade/delugegtk.glade index 80259df55..127b92f6d 100644 --- a/glade/delugegtk.glade +++ b/glade/delugegtk.glade @@ -13,180 +13,737 @@ 4 3 - + True - False - - True - Add Torrent - Add - True - gtk-add - - - - False - - - - - True - False - Remove Torrent - Remove - True - gtk-remove - - - - False - - - - - True - Clear Finished Torrents - Clear - True - gtk-clear - - - - False - - - - - True - - - False - False - - - - - True - False - Start or Pause torrent - Resume - True - gtk-media-play - - - - False - - - - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Pause - gtk-media-pause - + + + True + False + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + + + True + True + True + True + False + + + + - False + True + False - + True - False - Queue Torrent Up - Up - True - gtk-go-up - + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + False + True + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_POLICY_AUTOMATIC + GTK_POLICY_NEVER + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_RESIZE_QUEUE + GTK_SHADOW_NONE + + + True + 1 + 2 + 10 + + + True + 0 + + + True + 10 + 10 + 15 + 15 + + + True + 5 + + + True + 0.10000000149 + + + False + False + + + + + True + 5 + 4 + 5 + + + True + 0 + + + 1 + 2 + + + + + True + 0 + + + 3 + 4 + + + + + True + 0 + + + 1 + 2 + 1 + 2 + + + + + True + 0 + + + 3 + 4 + 1 + 2 + + + + + True + 0 + + + 1 + 2 + 2 + 3 + + + + + True + 0 + + + 3 + 4 + 2 + 3 + + + + + True + 0 + + + 1 + 2 + 3 + 4 + + + + + True + 0 + + + 3 + 4 + 3 + 4 + + + + + True + 5 + + + True + 0 + <b>Downloaded:</b> + True + + + + + + + True + 5 + + + True + 0 + <b>Uploaded:</b> + True + + + + + 1 + 2 + + + + + True + 5 + + + True + 0 + <b>Seeders:</b> + True + + + + + 2 + 3 + + + + + True + 5 + + + True + 0 + <b>Share Ratio:</b> + True + + + + + 3 + 4 + + + + + True + 15 + 5 + + + True + 0 + <b>Speed:</b> + True + + + + + 2 + 3 + + + + + True + 15 + 5 + + + True + 0 + <b>Speed:</b> + True + + + + + 2 + 3 + 1 + 2 + + + + + True + 15 + 5 + + + True + 0 + <b>Peers:</b> + True + + + + + 2 + 3 + 2 + 3 + + + + + True + 15 + 5 + + + True + 0 + <b>ETA:</b> + True + + + + + 2 + 3 + 3 + 4 + + + + + True + 0 + 1 + <b>Pieces:</b> + True + + + 4 + 5 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + 0 + + + + + 1 + 2 + 4 + 5 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 15 + 5 + + + True + 0 + 1 + <b>Availability:</b> + True + + + + + 2 + 3 + 4 + 5 + + + + + True + 0 + True + PANGO_WRAP_WORD_CHAR + + + 3 + 4 + 4 + 5 + + + + + + False + 1 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Statistics</b> + True + + + label_item + + + + + + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 10 + 10 + 15 + 15 + + + True + 6 + 2 + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + 0 + 1 + <b># of files:</b> + True + + + + + 2 + 3 + GTK_FILL + + + + + True + 0 + + + 1 + 2 + 2 + 3 + + + + + + True + 0 + + + 1 + 2 + 1 + 2 + + + + + + True + 0 + True + PANGO_WRAP_WORD_CHAR + + + 1 + 2 + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + 0 + 1 + <b>Total Size:</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 + 5 + + + True + 0 + 1 + <b>Tracker:</b> + True + + + + + + + 3 + 4 + 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 + 5 + + + True + 0 + 1 + <b>Tracker 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 + 5 + + + True + 0 + 1 + <b>Next Announce:</b> + True + + + + + 5 + 6 + 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_WORD_CHAR + + + 1 + 2 + 3 + 4 + + + + + + True + 0 + + + 1 + 2 + 4 + 5 + + + + + + True + 0 + + + 1 + 2 + 5 + 6 + + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Torrent Info</b> + True + + + label_item + + + + + 1 + 2 + GTK_FILL + + + + + + + + + False + + + + + True + Details + + + tab + False + False + + + + - False - - - - - True - False - Queue Torrent Down - Down - True - gtk-go-down - - - - False - - - - - True - - - False - False - - - - - True - Change Deluge preferences - Preferences - True - gtk-preferences - - - - False - - - - - True - Open the plugins dialog - Plugins - True - gtk-disconnect - - - - False + False + False - 1 - 2 - GTK_FILL - - - - - True - False - - - 1 - 2 - 1 - 2 - GTK_FILL - GTK_FILL - - - - - True - False - - - 2 3 - 1 - 2 - - GTK_FILL + 2 + 3 + + + + + True + + + 3 + 3 + 4 + @@ -488,801 +1045,183 @@ - + True + False + 2 3 - 3 - 4 - + 1 + 2 + + GTK_FILL - + True + False + + + 1 + 2 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + False - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - - - True - True - True - True - False - - - - + Add Torrent + Add + True + gtk-add + - True - False + False - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - True - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - GTK_POLICY_AUTOMATIC - GTK_POLICY_NEVER - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - GTK_RESIZE_QUEUE - GTK_SHADOW_NONE - - - True - 1 - 2 - 10 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 10 - 10 - 15 - 15 - - - True - 6 - 2 - 2 - - - True - 0 - - - 1 - 2 - 5 - 6 - - - - - - True - 0 - - - 1 - 2 - 4 - 5 - - - - - - True - 0 - True - PANGO_WRAP_WORD_CHAR - - - 1 - 2 - 3 - 4 - - - - - - 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 - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 1 - <b>Next Announce:</b> - True - - - - - 5 - 6 - 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 - 5 - - - True - 0 - 1 - <b>Tracker 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 - 5 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 1 - <b>Tracker:</b> - True - - - - - - - 3 - 4 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 1 - <b>Total Size:</b> - True - - - - - 1 - 2 - GTK_FILL - - - - - True - 0 - True - PANGO_WRAP_WORD_CHAR - - - 1 - 2 - - - - - - True - 0 - - - 1 - 2 - 1 - 2 - - - - - - True - 0 - - - 1 - 2 - 2 - 3 - - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - 0 - 1 - <b># of files:</b> - True - - - - - 2 - 3 - GTK_FILL - - - - - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Torrent Info</b> - True - - - label_item - - - - - 1 - 2 - GTK_FILL - - - - - True - 0 - - - True - 10 - 10 - 15 - 15 - - - True - 5 - - - True - 0.10000000149 - - - False - False - - - - - True - 5 - 4 - 5 - - - True - 0 - True - PANGO_WRAP_WORD_CHAR - - - 3 - 4 - 4 - 5 - - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 15 - 5 - - - True - 0 - 1 - <b>Availability:</b> - True - - - - - 2 - 3 - 4 - 5 - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - - - True - 0 - - - - - 1 - 2 - 4 - 5 - - - - - True - 0 - 1 - <b>Pieces:</b> - True - - - 4 - 5 - - - - - True - 15 - 5 - - - True - 0 - <b>ETA:</b> - True - - - - - 2 - 3 - 3 - 4 - - - - - True - 15 - 5 - - - True - 0 - <b>Peers:</b> - True - - - - - 2 - 3 - 2 - 3 - - - - - True - 15 - 5 - - - True - 0 - <b>Speed:</b> - True - - - - - 2 - 3 - 1 - 2 - - - - - True - 15 - 5 - - - True - 0 - <b>Speed:</b> - True - - - - - 2 - 3 - - - - - True - 5 - - - True - 0 - <b>Share Ratio:</b> - True - - - - - 3 - 4 - - - - - True - 5 - - - True - 0 - <b>Seeders:</b> - True - - - - - 2 - 3 - - - - - True - 5 - - - True - 0 - <b>Uploaded:</b> - True - - - - - 1 - 2 - - - - - True - 5 - - - True - 0 - <b>Downloaded:</b> - True - - - - - - - True - 0 - - - 3 - 4 - 3 - 4 - - - - - True - 0 - - - 1 - 2 - 3 - 4 - - - - - True - 0 - - - 3 - 4 - 2 - 3 - - - - - True - 0 - - - 1 - 2 - 2 - 3 - - - - - True - 0 - - - 3 - 4 - 1 - 2 - - - - - True - 0 - - - 1 - 2 - 1 - 2 - - - - - True - 0 - - - 3 - 4 - - - - - True - 0 - - - 1 - 2 - - - - - False - 1 - - - - - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Statistics</b> - True - - - label_item - - - - - - GTK_FILL - - - - - - - - - False - - - - - True - Details - - - tab - False - False - - - - - True - False - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - - - True - - - - - 1 - False - - - - - True - Peers - - - tab - 1 - False - False - - - - - True - False - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - - - True - True - - - - - 2 - False - - - - - True - Files - - - tab - 2 - False - False - - - - + False + Remove Torrent + Remove + True + gtk-remove + - False - False + False + + + + + True + Clear Finished Torrents + Clear + True + gtk-clear + + + + False + + + + + True + + + False + False + + + + + True + False + Start or Pause torrent + Resume + True + gtk-media-play + + + + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Pause + gtk-media-pause + + + + False + + + + + True + False + Queue Torrent Up + Up + True + gtk-go-up + + + + False + + + + + True + False + Queue Torrent Down + Down + True + gtk-go-down + + + + False + + + + + True + + + False + False + + + + + True + Change Deluge preferences + Preferences + True + gtk-preferences + + + + False + + + + + True + Open the plugins dialog + Plugins + True + gtk-disconnect + + + + False - 3 - 2 - 3 + 1 + 2 + GTK_FILL - diff --git a/plugins/EventLogging/__init__.py b/plugins/EventLogging/__init__.py index 0e61eab57..29f4cc9ed 100644 --- a/plugins/EventLogging/__init__.py +++ b/plugins/EventLogging/__init__.py @@ -52,7 +52,7 @@ def enable(core, interface): ### The Plugin ### import deluge import gtk -from EventLogging.tab_log import LogManager +from EventLogging.tab_log import LogTabManager class EventLogging: @@ -86,8 +86,8 @@ class EventLogging: self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Event Log"))) self.viewport.show() self.scrolledWindow.show() - self.tab_log = LogManager(self.viewport, self.manager) - self.tab_log.prepare_log_store() + self.tab_log = LogTabManager(self.viewport, self.manager) + self.tab_log.build_log_view() if self.config.get("enable_finished"): self.manager.connect_event(self.manager.constants['EVENT_FINISHED'], self.tab_log.handle_event) if self.config.get("enable_peer_error"): diff --git a/plugins/EventLogging/tab_log.py b/plugins/EventLogging/tab_log.py index bbce95e08..1e30a161d 100644 --- a/plugins/EventLogging/tab_log.py +++ b/plugins/EventLogging/tab_log.py @@ -5,7 +5,7 @@ import time CONFIG_DIR = xdg.BaseDirectory.save_config_path('deluge') -class LogManager(object): +class LogTabManager(object): def __init__(self, viewport, manager): self.log_files = False self.viewport = viewport @@ -21,7 +21,7 @@ class LogManager(object): self.vbox.destroy() self.vbox = None - def prepare_log_store(self): + def build_log_view(self): self.vbox = gtk.VBox() self.viewport.add(self.vbox) self.vbox.show_all() diff --git a/plugins/NetworkGraph/__init__.py b/plugins/NetworkGraph/__init__.py index d11f87189..865c98948 100644 --- a/plugins/NetworkGraph/__init__.py +++ b/plugins/NetworkGraph/__init__.py @@ -8,8 +8,55 @@ def deluge_init(deluge_path): global path path = deluge_path -from NetworkGraph.plugin import plugin_NetGraph - def enable(core, interface): global path - return plugin_NetGraph(path, core, interface) + return NetworkGraph(path, core, interface) + +from NetworkGraph.tab_graph import GraphTabManager + +class NetworkGraph: + def __init__(self, path, core, interface): + import gtk + self.parent = interface + self.location = path + self.manager = core + scrolledWindow = gtk.ScrolledWindow() + scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + image = gtk.Image() + + viewport = gtk.Viewport() + viewport.add(image) + scrolledWindow.add(viewport) + + image.show() + viewport.show() + self.topWidget = scrolledWindow + + self.parentNotebook = self.parent.notebook +# print "Parent NOTEBOOK:", self.parentNotebook + self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Graph"))) +# print "My INDEX in parentNoteBook:", self.index + self.bootupRuns = 3 # This ensures that we pass the resizing phase, with scrollbars, etc. + # So the first time it is viewed, we are all ready + scrolledWindow.show() + import pango + pangoContext = self.parent.window.get_pango_context() + pangoLayout = pango.Layout(pangoContext) + self.tab_graph = GraphTabManager(scrolledWindow, image, pangoLayout, self.manager) + + def unload(self): # Shutdown is called when the plugin is deactivated + numPages = self.parentNotebook.get_n_pages() + for page in range(numPages): + if self.parentNotebook.get_nth_page(page) == self.topWidget: + self.parentNotebook.remove_page(page) + break + + def update(self): + if (not self.parentNotebook.get_nth_page(self.parentNotebook.get_current_page()) == \ + self.topWidget\ + or not self.parent.update_interface)\ + and not self.bootupRuns > 0: + return + self.bootupRuns = max(self.bootupRuns - 1, 0) + self.tab_graph.update_graph_store() + self.tab_graph.update_graph_view() diff --git a/plugins/NetworkGraph/plugin.py b/plugins/NetworkGraph/plugin.py index f3e11058e..e69de29bb 100644 --- a/plugins/NetworkGraph/plugin.py +++ b/plugins/NetworkGraph/plugin.py @@ -1,159 +0,0 @@ -# netgraph plugin - -class plugin_NetGraph: - def __init__(self, path, deluge_core, deluge_interface): - import gtk - self.parent = deluge_interface - self.location = path - self.core = deluge_core - - self.image = gtk.Image() - - self.viewPort = gtk.Viewport() - self.viewPort.add(self.image) - - self.scrolledWindow = gtk.ScrolledWindow() - self.scrolledWindow.add(self.viewPort) - self.scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - - self.topWidget = self.scrolledWindow - - self.parentNotebook = self.parent.notebook -# print "Parent NOTEBOOK:", self.parentNotebook - self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Graph"))) -# print "My INDEX in parentNoteBook:", self.index - - self.image.show() - self.viewPort.show() - self.scrolledWindow.show() - - self.length = 60 - - self.width = -1 - self.height = -1 - - import pango - - self.pangoContext = self.parent.window.get_pango_context() - self.pangoLayout = pango.Layout(self.pangoContext) - - self.savedUpSpeeds = [] - self.savedDownSpeeds = [] - - self.bootupRuns = 3 # This ensures that we pass the resizing phase, with scrollbars, etc. - # So the first time it is viewed, we are all ready - - def unload(self): # Shutdown is called when the plugin is deactivated - numPages = self.parentNotebook.get_n_pages() - for page in range(numPages): - if self.parentNotebook.get_nth_page(page) == self.topWidget: - self.parentNotebook.remove_page(page) - break - - def update(self): - if self.parent.update_interface: - import gtk - session_info = self.core.get_state() - self.savedUpSpeeds.insert(0, session_info['upload_rate']) - if len(self.savedUpSpeeds) > self.length: - self.savedUpSpeeds.pop() - self.savedDownSpeeds.insert(0, session_info['download_rate']) - if len(self.savedDownSpeeds) > self.length: - self.savedDownSpeeds.pop() - - if not self.parentNotebook.get_nth_page(self.parentNotebook.get_current_page()) == \ - self.topWidget and not self.bootupRuns > 0: - return - - self.bootupRuns = max(self.bootupRuns - 1, 0) - - extraWidth = self.scrolledWindow.get_vscrollbar().get_allocation().width * 1.5 - extraHeight = self.scrolledWindow.get_hscrollbar().get_allocation().height * 1.5 - allocation = self.scrolledWindow.get_allocation() - allocation.width = int(allocation.width) - extraWidth - allocation.height = int(allocation.height) - extraHeight - - # Don't try to allocate a size too small, or you might crash - if allocation.width < 2 or allocation.height < 2: - return - -# savedDownSpeeds = [1,2,3,2,1] -# savedUpSpeeds = [5,8,0,0,1,2] - -# allocation = self.image.get_allocation() -# allocation.width = 300 -# allocation.height = 200 - - if not allocation.width == self.width or not allocation.height == self.height: -# print "New Pixmap!" - self.width = allocation.width - self.height = allocation.height - - self.networkPixmap = gtk.gdk.Pixmap(None, self.width, - self.height, gtk.gdk.visual_get_system().depth) - self.image.set_from_pixmap(self.networkPixmap, None) - self.ctx = self.networkPixmap.cairo_create() - - self.networkPixmap.draw_rectangle(self.image.get_style().white_gc,True, 0, 0, self.width, self.height) - - maxSpeed = max(max(self.savedDownSpeeds),max(self.savedUpSpeeds)) - - if maxSpeed == 0: - return - - maxSpeed = maxSpeed*1.1 # Give some extra room on top - - self.drawSpeedPoly(self.savedDownSpeeds, (0.5,1, 0.5, 1.0), maxSpeed, True) - self.drawSpeedPoly(self.savedDownSpeeds, (0, 0.75,0, 1.0), maxSpeed, False) - - self.drawSpeedPoly(self.savedUpSpeeds, (0.33,0.33,1.0, 0.5), maxSpeed, True) - self.drawSpeedPoly(self.savedUpSpeeds, (0, 0, 1.0, 0.75), maxSpeed, False) - - meanUpSpeed = sum(self.savedUpSpeeds) /len(self.savedUpSpeeds) - meanDownSpeed = sum(self.savedDownSpeeds)/len(self.savedDownSpeeds) - shownSpeed = max(meanUpSpeed, meanDownSpeed) - - import deluge.common - - self.pangoLayout.set_text(deluge.common.fspeed(shownSpeed)) - self.networkPixmap.draw_layout(self.image.get_style().black_gc, - 4, - int(self.height - 1 - (self.height*shownSpeed/maxSpeed)), - self.pangoLayout) - - self.networkPixmap.draw_line(self.image.get_style().black_gc, - 0, - int(self.height - (self.height*shownSpeed/maxSpeed)), - self.width, - int(self.height - (self.height*shownSpeed/maxSpeed))) - - self.networkPixmap.draw_rectangle(self.image.get_style().black_gc,False, 0, 0, self.width-1, self.height-1) - - self.image.queue_draw() - - def tracePath(self, speeds, maxSpeed): - lineWidth = 4 - - self.ctx.set_line_width(lineWidth) - - self.ctx.move_to(self.width + lineWidth,self.height + lineWidth) - self.ctx.line_to(self.width + lineWidth,int(self.height-(self.height*speeds[0]/maxSpeed))) - - for i in range(len(speeds)): - self.ctx.line_to(int(self.width-1-((i*self.width)/(self.length-1))), - int(self.height-1-(self.height*speeds[i]/maxSpeed))) - - self.ctx.line_to(int(self.width-1-(((len(speeds)-1)*self.width)/(self.length-1))), - int(self.height)-1 + lineWidth) - - self.ctx.close_path() - - def drawSpeedPoly(self, speeds, color, maxSpeed, fill): - - self.tracePath(speeds, maxSpeed) - self.ctx.set_source_rgba(color[0],color[1],color[2], color[3]) - - if fill: - self.ctx.fill() - else: - self.ctx.stroke() diff --git a/plugins/TorrentFiles/__init__.py b/plugins/TorrentFiles/__init__.py new file mode 100644 index 000000000..e9320d248 --- /dev/null +++ b/plugins/TorrentFiles/__init__.py @@ -0,0 +1,85 @@ +# Copyright (C) 2007 +# +# This program is free software; you can 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, or (at your option) +# any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +### Initialization ### + +plugin_name = _("Torrent Files") +plugin_author = "Deluge" +plugin_version = "0.2" +plugin_description = _(""" +This is just the files tab as a plugin. +""") + +def deluge_init(deluge_path): + global path + path = deluge_path + +def enable(core, interface): + global path + return TorrentFiles(path, core, interface) + +### The Plugin ### +import deluge +import gtk +from TorrentFiles.tab_files import FilesTabManager + +class TorrentFiles: + + def __init__(self, path, core, interface): + print "Loading TorrentFiles plugin..." + self.manager = core + self.parent = interface + self.treeView = gtk.TreeView() + self.scrolledWindow = gtk.ScrolledWindow() + self.scrolledWindow.add(self.treeView) + self.scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + + self.topWidget = self.scrolledWindow + + self.parentNotebook = self.parent.notebook + + self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Files"))) + self.treeView.show() + self.scrolledWindow.show() + self.tab_files = FilesTabManager(self.treeView, self.manager) + self.tab_files.build_file_view() + + def unload(self): + self.tab_files.clear_file_store() + numPages = self.parentNotebook.get_n_pages() + for page in xrange(numPages): + if self.parentNotebook.get_nth_page(page) == self.topWidget: + self.parentNotebook.remove_page(page) + break + + def update(self): + if not self.parent.update_interface: + return + numPages = self.parentNotebook.get_n_pages() + for page in xrange(numPages): + if self.parentNotebook.get_nth_page(page) == self.topWidget: + unique_id = self.parent.get_selected_torrent() + if unique_id is None: + #if no torrents added or more than one torrent selected + self.tab_files.clear_file_store() + return + if self.tab_files.file_unique_id != unique_id: + self.tab_files.clear_file_store() + self.tab_files.set_unique_id(unique_id) + self.tab_files.prepare_file_store() + else: + self.tab_files.update_file_store() + break diff --git a/plugins/TorrentFiles/tab_files.py b/plugins/TorrentFiles/tab_files.py new file mode 100644 index 000000000..2854cb073 --- /dev/null +++ b/plugins/TorrentFiles/tab_files.py @@ -0,0 +1,68 @@ +from itertools import izip +from deluge.files import FilesBaseManager +from deluge import dgtk +import gobject +import gtk +class FilesTabManager(FilesBaseManager): + def __init__(self, file_view, manager): + file_store = gtk.ListStore(str, gobject.TYPE_UINT64, + gobject.TYPE_UINT, float) + + super(FilesTabManager, self).__init__(file_view, file_store) + + self.manager = manager + self.file_unique_id = None + + # Stores file path -> gtk.TreeIter's iter mapping for quick look up + # in self.update_file_store() + self.file_store_dict = {} + + def build_file_view(self): + super(FilesTabManager, self).build_file_view() + + def percent(column, cell, model, iter, data): + percent = float(model.get_value(iter, data)) + percent_str = "%.2f%%"%percent + cell.set_property("text", percent_str) + dgtk.add_func_column(self.file_view, _("Progress"), percent, 3) + + def set_unique_id(self, unique_id): + self.file_unique_id = unique_id + + def priority_clicked(self, widget): + state = self.manager.get_torrent_state(self.file_unique_id) + if state["compact_mode"]: + self.compact_allocation_warning() + else: + super(FilesTabManager, self).priority_clicked(widget) + + # From core to UI + def prepare_file_store(self): + if not self.file_store_dict: + all_files = self.manager.get_torrent_file_info(self.file_unique_id) + file_priorities = self.manager.get_priorities(self.file_unique_id) + for file, priority in izip(all_files, file_priorities): + iter = self.file_store.append([file['path'], file['size'], + priority, round(file['progress'], 2)]) + self.file_store_dict[file['path']] = iter + + # From core to UI + def update_file_store(self): + new_file_info = self.manager.get_torrent_file_info(self.file_unique_id) + for file in new_file_info: + iter = self.file_store_dict[file['path']] + dgtk.update_store(self.file_store, iter, (3,), + (round(file['progress'], 2),)) + + # From UI to core + def update_priorities(self): + prev_file_priorities = self.manager.get_priorities(self.file_unique_id) + file_priorities = [] + update = False + for x, priority in izip(self.file_store, prev_file_priorities): + file_priorities.append(x[2]) + if x[2] > 0 and priority == 0: + update = True + if x[2] == 0: + update = True + self.manager.prioritize_files(self.file_unique_id, file_priorities, update_files_removed=update) diff --git a/plugins/TorrentPeers/__init__.py b/plugins/TorrentPeers/__init__.py new file mode 100644 index 000000000..75bd3fae0 --- /dev/null +++ b/plugins/TorrentPeers/__init__.py @@ -0,0 +1,85 @@ +# Copyright (C) 2007 +# +# This program is free software; you can 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, or (at your option) +# any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +### Initialization ### + +plugin_name = _("Torrent Peers") +plugin_author = "Deluge" +plugin_version = "0.2" +plugin_description = _(""" +This is just the peers tab as a plugin. +""") + +def deluge_init(deluge_path): + global path + path = deluge_path + +def enable(core, interface): + global path + return TorrentPeers(path, core, interface) + +### The Plugin ### +import deluge +import gtk +from TorrentPeers.tab_peers import PeersTabManager + +class TorrentPeers: + + def __init__(self, path, core, interface): + print "Loading TorrentPeers plugin..." + self.manager = core + self.parent = interface + treeView = gtk.TreeView() + scrolledWindow = gtk.ScrolledWindow() + scrolledWindow.add(treeView) + scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + + self.topWidget = scrolledWindow + + self.parentNotebook = self.parent.notebook + + self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Peers"))) + treeView.show() + scrolledWindow.show() + self.tab_peers = PeersTabManager(treeView, self.manager) + self.tab_peers.build_peers_view() + + def unload(self): + self.tab_peers.clear_peer_store() + numPages = self.parentNotebook.get_n_pages() + for page in xrange(numPages): + if self.parentNotebook.get_nth_page(page) == self.topWidget: + self.parentNotebook.remove_page(page) + break + + def update(self): + if not self.parent.update_interface: + return + numPages = self.parentNotebook.get_n_pages() + for page in xrange(numPages): + if self.parentNotebook.get_nth_page(page) == self.topWidget: + unique_id = self.parent.get_selected_torrent() + if unique_id is None: + #if no torrents added or more than one torrent selected + self.tab_peers.clear_peer_store() + return + if self.tab_peers.peer_unique_id != unique_id: + self.tab_peers.clear_peer_store() + self.tab_peers.set_unique_id(unique_id) + self.tab_peers.update_peer_store() + else: + self.tab_peers.update_peer_store() + break diff --git a/src/tab_peers.py b/plugins/TorrentPeers/tab_peers.py similarity index 91% rename from src/tab_peers.py rename to plugins/TorrentPeers/tab_peers.py index 5b630f7e7..08e225c70 100644 --- a/src/tab_peers.py +++ b/plugins/TorrentPeers/tab_peers.py @@ -1,31 +1,30 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# tab_details.py - from itertools import izip - +from deluge import dgtk +from deluge import common import gobject import gtk - -import common -import dgtk - class PeersTabManager(object): def __init__(self, peer_view, manager): self.peer_view = peer_view self.manager = manager - + self.peer_unique_id = None # IP int, IP string, Client, Percent Complete, Down Speed, Up Speed # IP int is for faster sorting self.peer_store = gtk.ListStore(gobject.TYPE_UINT, gtk.gdk.Pixbuf, str, str, float, int, int) # Stores IP -> gtk.TreeIter's iter mapping for quick look up # in update_torrent_info_widget - self.peer_store_dict = {} - + self.peer_store_dict = {} self._cached_flags = {} - + + def clear_peer_store(self): + self.peer_store.clear() + self.peer_store_dict = {} + self.peer_unique_id = None + + def set_unique_id(self, unique_id): + self.peer_unique_id = unique_id + def build_peers_view(self): def percent(column, cell, model, iter, data): percent = float(model.get_value(iter, data)) @@ -44,11 +43,7 @@ class PeersTabManager(object): dgtk.cell_data_speed, 5) dgtk.add_func_column(self.peer_view, _("Up Speed"), dgtk.cell_data_speed, 6) - - def clear_store(self): - self.peer_store.clear() - self.peer_store_dict = {} - + def get_country_flag_image(self, country): flag_image = None if country.isalpha(): @@ -65,9 +60,9 @@ class PeersTabManager(object): self._cached_flags[country] = flag_image return flag_image - - def update(self, unique_id): - new_peer_info = self.manager.get_torrent_peer_info(unique_id) + + def update_peer_store(self): + new_peer_info = self.manager.get_torrent_peer_info(self.peer_unique_id) new_ips = set() for peer in new_peer_info: diff --git a/plugins/TorrentPieces/__init__.py b/plugins/TorrentPieces/__init__.py index 8d0f0dc28..b363d53a9 100644 --- a/plugins/TorrentPieces/__init__.py +++ b/plugins/TorrentPieces/__init__.py @@ -50,7 +50,7 @@ def enable(core, interface): ### The Plugin ### import deluge import gtk -from TorrentPieces.tab_pieces import PiecesManager +from TorrentPieces.tab_pieces import PiecesTabManager class TorrentPieces: @@ -66,7 +66,7 @@ class TorrentPieces: self.parentNotebook.append_page(self.topWidget, gtk.Label(_("Pieces"))) self.topWidget.show_all() - self.tab_pieces = PiecesManager(self.manager) + self.tab_pieces = PiecesTabManager(self.manager) def unload(self): self.manager.disconnect_event(self.manager.constants['EVENT_PIECE_FINISHED'], self.tab_pieces.handle_event) diff --git a/plugins/TorrentPieces/tab_pieces.py b/plugins/TorrentPieces/tab_pieces.py index 88ae8e2b7..cebf553a6 100644 --- a/plugins/TorrentPieces/tab_pieces.py +++ b/plugins/TorrentPieces/tab_pieces.py @@ -1,7 +1,7 @@ import gtk import math -class PiecesManager(object): +class PiecesTabManager(object): def __init__(self, manager): self.vbox = None self.manager = manager @@ -15,8 +15,6 @@ class PiecesManager(object): self.unique_id = -1 self.peer_speed = [] self.piece_info = [] - self.first_indexes = [] - self.last_indexes = [] self.all_files = None self.file_priorities = None self.index = 0 @@ -24,6 +22,8 @@ class PiecesManager(object): self.file_index = 0 self.next_file_index = 1 self.num_files = 0 + self.current_first_index = None + self.current_last_index = None def set_unique_id(self, unique_id): self.unique_id = unique_id @@ -36,10 +36,10 @@ class PiecesManager(object): self.progress = [] self.piece_info = [] self.tooltips = [] - self.first_indexes = [] - self.last_indexes = [] self.all_files = None self.file_priorities = None + self.current_first_index = None + self.current_last_index = None self.index = 0 self.num_files = 0 self.prev_file_index = -1 @@ -57,16 +57,13 @@ class PiecesManager(object): scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.vbox = gtk.VBox() viewport.add(self.vbox) - self.all_files = self.manager.get_torrent_file_info(self.unique_id) + self.all_files = self.manager.get_file_piece_range(self.unique_id) self.file_priorities = self.manager.get_priorities(self.unique_id) state = self.manager.get_torrent_state(self.unique_id) self.num_pieces = state["num_pieces"] for priority in self.file_priorities: - if self.file_index == 0: - file_piece_range = self.manager.get_file_piece_range(self.unique_id,\ - self.file_index, self.all_files[self.file_index]['size']) - self.first_indexes.append(file_piece_range['first_index']) - self.last_indexes.append(file_piece_range['last_index']) + self.current_first_index = self.all_files[self.file_index]['first_index'] + self.current_last_index = self.all_files[self.file_index]['last_index'] if priority > 0: #if file is being downloaded build the file pieces information self.build_file_pieces() @@ -87,11 +84,11 @@ class PiecesManager(object): label.set_text(self.all_files[self.file_index]['path']) self.vbox.pack_start(label, expand=False) table = gtk.Table() - self.rows = int(math.ceil((self.last_indexes[self.file_index]-self.first_indexes[self.file_index])/self.columns)+1) + self.rows = int(math.ceil((self.current_last_index-self.current_first_index)/self.columns)+1) self.vbox.pack_start(table, expand=False) table.resize(self.rows, self.columns) table.set_size_request((self.columns+1)*self.piece_width, (self.rows+1)*self.piece_height) - if self.last_indexes[self.file_index] != self.first_indexes[self.file_index]: + if self.current_last_index != self.current_first_index: #if there is more than one piece self.build_pieces_table(table) only_one_piece = False @@ -99,14 +96,12 @@ class PiecesManager(object): #if file only has one piece self.index = 0 only_one_piece = True - main_index = self.last_indexes[self.file_index] - # do the following even if file has only one piece and that piece has already been created - if self.next_file_index < len(self.all_files): - #if there is another file - file_piece_range = self.manager.get_file_piece_range(self.unique_id,\ - self.next_file_index, self.all_files[self.next_file_index]['size']) - self.first_indexes.append(file_piece_range['first_index']) - self.last_indexes.append(file_piece_range['last_index']) + self.piece_info.append({'blocks_total':0, 'blocks_finished':0, 'blocks_requested':0}) + self.progress.append(gtk.ProgressBar()) + self.tooltips.append(gtk.Tooltips()) + self.eventboxes.append(gtk.EventBox()) + self.peer_speed.append("unknown") + main_index = self.current_last_index if self.file_index > 0 and not self.piece_info[main_index] is None and only_one_piece: #if file has only one piece and it is shared destroy the table table.destroy() @@ -117,10 +112,11 @@ class PiecesManager(object): def build_pieces_table(self, table): temp_prev_priority = 1 - if self.first_indexes[self.file_index] == 0\ - or self.first_indexes[self.file_index] != self.last_indexes[self.prev_file_index]: + if self.current_first_index == 0\ + or self.current_first_index !=\ + self.all_files[self.prev_file_index]['last_index']: #if first piece is not a shared piece - temp_range = self.last_indexes[self.file_index]-self.first_indexes[self.file_index] + temp_range = self.current_last_index-self.current_first_index diff = 0 else: #if first piece is shared @@ -128,15 +124,16 @@ class PiecesManager(object): if temp_prev_priority > 0: #if last file was not skipped, skip the first piece diff = 1 - temp_range = self.last_indexes[self.file_index]-(self.first_indexes[self.file_index]+1) + temp_range = self.current_last_index-(self.current_first_index+1) #otherwise keep the first piece else: diff = 0 - temp_range = self.last_indexes[self.file_index]-self.first_indexes[self.file_index] + temp_range = self.current_last_index-self.current_first_index #last piece handled outside of loop, skip it from range + temp_first_index = self.current_first_index for index in xrange(temp_range): gtk.main_iteration_do(False) - main_index = diff+self.first_indexes[self.file_index]+index + main_index = diff+temp_first_index+index if temp_prev_priority > 0: #normal behavior self.piece_info.append({'blocks_total':0, 'blocks_finished':0, 'blocks_requested':0}) @@ -161,23 +158,18 @@ class PiecesManager(object): else: #if piece is not already finished self.tooltips[main_index].set_tip(self.eventboxes[main_index], _("Piece not started")) - self.piece_info.append({'blocks_total':0, 'blocks_finished':0, 'blocks_requested':0}) - self.progress.append(gtk.ProgressBar()) - self.tooltips.append(gtk.Tooltips()) - self.eventboxes.append(gtk.EventBox()) - self.peer_speed.append("unknown") - self.index = index+1 + self.index = temp_range def build_last_file_piece(self, table, main_index, only_one_piece): gtk.main_iteration_do(False) - if only_one_piece: + if only_one_piece and self.file_index > 0: #if piece is shared with a skipped file self.share_skipped_piece(main_index) self.progress[main_index].set_size_request(self.piece_width, self.piece_height) if self.next_file_index < len(self.all_files): # if there is another file if self.file_priorities[self.next_file_index]==0\ - or self.last_indexes[self.file_index] != self.first_indexes[self.next_file_index]: + or self.current_last_index != self.all_files[self.next_file_index]['first_index']: #if next file is skipped or there is no shared piece, keep last piece row=self.index/self.columns column=self.index%self.columns @@ -185,7 +177,7 @@ class PiecesManager(object): xoptions=0, yoptions=0, xpadding=0, ypadding=0) self.eventboxes[main_index].add(self.progress[main_index]) if self.file_priorities[self.next_file_index]>0\ - and self.last_indexes[self.file_index] == self.first_indexes[self.next_file_index]: + and self.current_last_index == self.all_files[self.next_file_index]['first_index']: #if next file is not skipped and there is a shared piece, do not keep last piece if only_one_piece: #only piece in file is shared, destroy table for file @@ -224,26 +216,20 @@ class PiecesManager(object): self.peer_speed[main_index] = "unknown" def skip_current_file(self): - if self.first_indexes[self.file_index] == 0 or self.first_indexes[self.file_index] != self.last_indexes[self.prev_file_index]: + if self.current_first_index == 0\ + or self.current_first_index !=\ + self.all_files[self.prev_file_index]['last_index']: #if first piece is not shared - temp_range = 1+self.last_indexes[self.file_index]-self.first_indexes[self.file_index] + temp_range = 1+self.current_last_index-self.current_first_index else: #if first piece is shared - temp_range = self.last_indexes[self.file_index]-self.first_indexes[self.file_index] + temp_range = self.current_last_index-self.current_first_index for index in xrange(temp_range): self.piece_info.append(None) self.progress.append(None) self.eventboxes.append(None) self.tooltips.append(None) self.peer_speed.append(None) - if self.next_file_index < len(self.all_files): - #if there is another file - file_piece_range = self.manager.get_file_piece_range(self.unique_id,\ - self.next_file_index, self.all_files[self.next_file_index]['size']) - self.first_indexes.append(file_piece_range['first_index']) - self.last_indexes.append(file_piece_range['last_index']) - if self.last_indexes[self.next_file_index] >= self.num_pieces: - self.last_indexes[self.next_file_index] = self.num_pieces-1 def handle_event(self, event): #protect against pieces trying to display after file priority changed diff --git a/src/core.py b/src/core.py index 41205b7c3..7c04c5796 100644 --- a/src/core.py +++ b/src/core.py @@ -322,10 +322,8 @@ class Manager: return self.config.get(key) # Get file piece range - def get_file_piece_range(self, unique_id,\ - file_index, file_size): - return deluge_core.get_file_piece_range(unique_id,\ - file_index, file_size) + def get_file_piece_range(self, unique_id): + return deluge_core.get_file_piece_range(unique_id) # Check if piece is finished def has_piece(self, unique_id, piece_index): diff --git a/src/deluge_core.cpp b/src/deluge_core.cpp index 572fdd8cc..76393b021 100644 --- a/src/deluge_core.cpp +++ b/src/deluge_core.cpp @@ -1269,21 +1269,40 @@ static PyObject *torrent_get_file_info(PyObject *self, PyObject *args) static PyObject *torrent_get_file_piece_range(PyObject *self, PyObject *args) { python_long unique_ID; - int file_index, file_size; - if (!PyArg_ParseTuple(args, "iii", &unique_ID, &file_index, &file_size)) + if (!PyArg_ParseTuple(args, "i", &unique_ID)) return NULL; long index = get_index_from_unique_ID(unique_ID); if (PyErr_Occurred()) return NULL; + + std::vector temp_files; + torrent_info const &info = M_torrents->at(index).handle.get_torrent_info(); - peer_request first_index = info.map_file(file_index, 0, 1); - peer_request last_index = info.map_file(file_index, file_size-1, 1); - return Py_BuildValue( - "{s:i,s:i}", - "first_index", first_index.piece, - "last_index", last_index.piece - ); + int file_index = 0; + PyObject *file_info; + + for(torrent_info::file_iterator i = info.begin_files(); i != info.end_files(); ++i) + { + file_entry const &currFile = (*i); + peer_request first_index = info.map_file(file_index, 0, 1); + peer_request last_index = info.map_file(file_index, currFile.size-1, 1); + file_info = Py_BuildValue( + "{s:i,s:i,s:s}", + "first_index", first_index.piece, + "last_index", last_index.piece, + "path", currFile.path.string().c_str() + ); + file_index++; + temp_files.push_back(file_info); + }; + + PyObject *ret = PyTuple_New(temp_files.size()); + + for (unsigned long i = 0; i < temp_files.size(); i++) + PyTuple_SetItem(ret, i, temp_files[i]); + + return ret; }; /*static PyObject *torrent_get_unique_IDs(PyObject *self, PyObject *args) diff --git a/src/dialogs.py b/src/dialogs.py index cd2468e8b..756e068b6 100644 --- a/src/dialogs.py +++ b/src/dialogs.py @@ -34,7 +34,7 @@ import gtk import common import dgtk -import tab_files +import files import pref PREFS_FILENAME = "prefs.state" @@ -284,7 +284,7 @@ class FilesDlg: self.dialog = self.glade.get_widget("file_dialog") self.dialog.set_icon_from_file(common.get_pixmap("deluge32.png")) - self.files_manager = tab_files.FilesDialogManager( + self.files_manager = files.FilesDialogManager( self.glade.get_widget("file_view"), dumped_torrent) self.files_manager.build_file_view() diff --git a/src/tab_files.py b/src/files.py similarity index 71% rename from src/tab_files.py rename to src/files.py index 9023fd89f..b3f547870 100644 --- a/src/tab_files.py +++ b/src/files.py @@ -137,70 +137,6 @@ class FilesBaseManager(object): def update_priorities(self): pass -class FilesTabManager(FilesBaseManager): - def __init__(self, file_view, manager): - file_store = gtk.ListStore(str, gobject.TYPE_UINT64, - gobject.TYPE_UINT, float) - - super(FilesTabManager, self).__init__(file_view, file_store) - - self.manager = manager - self.file_unique_id = None - - # Stores file path -> gtk.TreeIter's iter mapping for quick look up - # in self.update_file_store() - self.file_store_dict = {} - - def build_file_view(self): - super(FilesTabManager, self).build_file_view() - - def percent(column, cell, model, iter, data): - percent = float(model.get_value(iter, data)) - percent_str = "%.2f%%"%percent - cell.set_property("text", percent_str) - dgtk.add_func_column(self.file_view, _("Progress"), percent, 3) - - def set_unique_id(self, unique_id): - self.file_unique_id = unique_id - - def priority_clicked(self, widget): - state = self.manager.get_torrent_state(self.file_unique_id) - if state["compact_mode"]: - self.compact_allocation_warning() - else: - super(FilesTabManager, self).priority_clicked(widget) - - # From core to UI - def prepare_file_store(self): - if not self.file_store_dict: - all_files = self.manager.get_torrent_file_info(self.file_unique_id) - file_priorities = self.manager.get_priorities(self.file_unique_id) - for file, priority in izip(all_files, file_priorities): - iter = self.file_store.append([file['path'], file['size'], - priority, round(file['progress'], 2)]) - self.file_store_dict[file['path']] = iter - - # From core to UI - def update_file_store(self): - new_file_info = self.manager.get_torrent_file_info(self.file_unique_id) - for file in new_file_info: - iter = self.file_store_dict[file['path']] - dgtk.update_store(self.file_store, iter, (3,), - (round(file['progress'], 2),)) - - # From UI to core - def update_priorities(self): - prev_file_priorities = self.manager.get_priorities(self.file_unique_id) - file_priorities = [] - update = False - for x, priority in izip(self.file_store, prev_file_priorities): - file_priorities.append(x[2]) - if x[2] > 0 and priority == 0: - update = True - if x[2] == 0: - update = True - self.manager.prioritize_files(self.file_unique_id, file_priorities, update_files_removed=update) - class FilesDialogManager(FilesBaseManager): def __init__(self, file_view, dumped_torrent): file_store = gtk.ListStore(str, gobject.TYPE_UINT64, diff --git a/src/interface.py b/src/interface.py index d2b7f8468..cc2553c36 100644 --- a/src/interface.py +++ b/src/interface.py @@ -47,8 +47,7 @@ import dgtk import ipc_manager import plugins import tab_details -import tab_files -import tab_peers +import files class DelugeGTK: def __init__(self): @@ -81,12 +80,6 @@ class DelugeGTK: # Tabs self.tab_details = tab_details.DetailsTabManager(self.wtree, self.manager) - self.tab_peers = tab_peers.PeersTabManager( - self.wtree.get_widget("peer_view"), self.manager) - self.tab_peers.build_peers_view() - self.tab_files = tab_files.FilesTabManager( - self.wtree.get_widget("file_view"), self.manager) - self.tab_files.build_file_view() self.statusbar = self.wtree.get_widget("statusbar") @@ -579,9 +572,6 @@ class DelugeGTK: # Torrent is already selected, we don't need to do anything return True - self.tab_peers.clear_store() - self.tab_files.clear_file_store() - unique_id = model.get_value(model.get_iter(path), 0) self.update_torrent_info_widget(unique_id) @@ -982,14 +972,6 @@ class DelugeGTK: if page_num == 0: # Details self.tab_details.update(unique_id) - elif page_num == 1: # Peers - self.tab_peers.update(unique_id) - elif page_num == 2: # Files - # Fill self.file_store with files only once and only when we click to - # Files tab or it's already open - self.tab_files.set_unique_id(unique_id) - self.tab_files.prepare_file_store() - self.tab_files.update_file_store() # Return the id of the last single selected torrent def get_selected_torrent(self): @@ -1152,8 +1134,6 @@ class DelugeGTK: def clear_details_pane(self): self.tab_details.clear() - self.tab_peers.clear_store() - self.tab_files.clear_file_store() def remove_toggle_warning(self, args, warning): if not args.get_active():