diff --git a/ChangeLog b/ChangeLog index d2432c1c8..dd2f3928c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ Deluge 0.5.7 (xx November 2007) * Blocklist plugin will now display errors, instead of just crashing on a bad list or wrong type * Local discovery of peers + * Add advanced progress bar option - adapted from Arnab Bose * Fix ratio bugs (hopefully for the last time) * Fix ETA from going backwards * UI warning on full HD - no longer just silently pauses torrents diff --git a/TODO b/TODO index 2268dfc6e..b834fcde6 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,2 @@ for 0.5.7 * remap filenames - * decide what to do about the progress bar patch diff --git a/glade/delugegtk.glade b/glade/delugegtk.glade index 2da2f1543..40f35c2d9 100644 --- a/glade/delugegtk.glade +++ b/glade/delugegtk.glade @@ -73,7 +73,6 @@ True - 0 True @@ -85,6 +84,24 @@ True 5 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + 25 + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + + + False + False + + True @@ -93,6 +110,7 @@ False False + 1 @@ -102,277 +120,18 @@ 4 5 - - True - 0 - - - 1 - 2 - - - - + True 0 + True + PANGO_WRAP_WORD_CHAR 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 + @@ -399,24 +158,283 @@ - + + 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 - True - PANGO_WRAP_WORD_CHAR 3 4 - 4 - 5 - + 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 + 2 @@ -444,7 +462,6 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 True @@ -740,7 +757,6 @@ - False True @@ -751,7 +767,6 @@ tab - False False @@ -1104,34 +1119,6 @@ - - - True - False - - - 2 - 3 - 1 - 2 - - GTK_FILL - - - - - True - False - - - 1 - 2 - 1 - 2 - GTK_FILL - GTK_FILL - - True @@ -1285,5 +1272,3 @@ - - diff --git a/glade/preferences_dialog.glade b/glade/preferences_dialog.glade index 03413a094..0cd6335a1 100644 --- a/glade/preferences_dialog.glade +++ b/glade/preferences_dialog.glade @@ -2603,6 +2603,7 @@ Thunar + True GTK_SHADOW_NONE @@ -2612,7 +2613,6 @@ Thunar 12 - True 15 @@ -2661,6 +2661,46 @@ Thunar 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_SHADOW_NONE + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Use the advanced progress bar (uses slightly more CPU/RAM) + 0 + True + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Detailed Progress Bar</b> + True + + + label_item + + + + + False + False + 3 + + True @@ -2709,7 +2749,7 @@ Thunar False False - 3 + 4 @@ -2751,7 +2791,7 @@ information is sent. False False - 4 + 5 diff --git a/src/deluge_core.cpp b/src/deluge_core.cpp index 8109f694a..b7f927457 100644 --- a/src/deluge_core.cpp +++ b/src/deluge_core.cpp @@ -929,8 +929,33 @@ static PyObject *torrent_get_torrent_state(PyObject *self, PyObject *args) total_seeds = s.num_complete != -1? s.num_complete : connected_seeds; total_peers = s.num_incomplete != -1? s.num_incomplete : connected_peers; + // The following section computes the ranges of pieces that have been downloaded + std::vector downloaded_range; + bool range_opened=false; + for (unsigned int i=0; i<=s.pieces->size(); ++i) { + bool downloaded=(isize() && s.pieces->at(i)); + if (!range_opened) { + if (downloaded) { + range_opened=true; + downloaded_range.push_back(i); + } + } else { + if (!downloaded) { + range_opened=false; + downloaded_range.push_back(i-1); + } + } + } + PyObject *pieces_range = PyTuple_New(downloaded_range.size()/2); + for(unsigned long i=0; i* + "pieces", pieces_range, "pieces_done", s.num_pieces, "block_size", s.block_size, "total_size", i.total_size(), diff --git a/src/dialogs.py b/src/dialogs.py index 9f978620f..535391331 100644 --- a/src/dialogs.py +++ b/src/dialogs.py @@ -154,6 +154,7 @@ class PreferencesDlg: self.glade.get_widget("ratio_spinner").set_value(self.preferences.get("auto_seed_ratio")) self.glade.get_widget("chk_dht").set_active(self.preferences.get("enable_dht")) self.glade.get_widget("spin_gui").set_value(self.preferences.get("gui_update_interval")) + self.glade.get_widget("chk_use_advanced_bar").set_active(self.preferences.get("use_advanced_bar")) #smart dialog set sensitivities if(self.preferences.get("use_default_dir")): @@ -269,6 +270,7 @@ class PreferencesDlg: self.preferences.set("queue_seeds_to_bottom", self.glade.get_widget("chk_seedbottom").get_active()) self.preferences.set("enable_dht", self.glade.get_widget("chk_dht").get_active()) self.preferences.set("gui_update_interval", self.glade.get_widget("spin_gui").get_value()) + self.preferences.set("use_advanced_bar", self.glade.get_widget("chk_use_advanced_bar").get_active()) self.preferences.set("clear_max_ratio_torrents", self.glade.get_widget("chk_clear_max_ratio_torrents").get_active()) self.preferences.set("queue_above_completed", self.glade.get_widget("chk_queue_above_completed").get_active()) diff --git a/src/interface.py b/src/interface.py index b17197d4d..34a001d89 100644 --- a/src/interface.py +++ b/src/interface.py @@ -1001,7 +1001,7 @@ window, please enter your password")) # Call update now so everything is up-to-date when the window gains # focus on startup self.update() - gobject.timeout_add(1000, self.update) + gobject.timeout_add(int(1000*self.manager.config.get("gui_update_interval")+0.5), self.update) # Load plugins after we showed main window (if not started in tray) self.load_plugins() diff --git a/src/pref.py b/src/pref.py index 03c106323..5075ebe8a 100644 --- a/src/pref.py +++ b/src/pref.py @@ -147,7 +147,8 @@ if common.windows_check(): "status_width" : 150, "filename_f_width" : 220, "size_f_width" : 90, - "priority_f_width" : 140 + "priority_f_width" : 140, + "use_advanced_bar" : False } else: DEFAULT_PREFS = { @@ -257,7 +258,8 @@ else: "status_width" : 150, "filename_f_width" : 220, "size_f_width" : 90, - "priority_f_width" : 140 + "priority_f_width" : 140, + "use_advanced_bar" : False } class Preferences: @@ -273,6 +275,7 @@ class Preferences: self.config_file = filename if self.config_file is not None: self.load(self.config_file) + self.change_hooks=[] # Allows you to access an item in a Preferences objecy by calling # instance[key] rather than instance.get(key). However, this will @@ -280,10 +283,16 @@ class Preferences: # advisable to use get() if you need the value converted. def __getitem__(self, key): return self.mapping[key] + + def onValueChanged(self,value,method): + self.change_hooks.append([value,method]) def __setitem__(self, key, value): - self.mapping[key] = value - + if key not in self.mapping or self.mapping[key]!=value: + self.mapping[key] = value + for hook in self.change_hooks: + if (hook[0]==key): hook[1]() + def __delitem__(self, key): del self.mapping[key] @@ -320,8 +329,8 @@ class Preferences: pass def set(self, key, value): - self.mapping[key] = value - + self[key] = value + def get(self, key): try: value = self.mapping[key] diff --git a/src/tab_details.py b/src/tab_details.py index ad2714239..63a17fc33 100644 --- a/src/tab_details.py +++ b/src/tab_details.py @@ -31,6 +31,7 @@ # statement from all source files in the program, then also delete it here. import common +import gtk class DetailsTabManager(object): def __init__(self, glade, manager): @@ -40,6 +41,8 @@ class DetailsTabManager(object): # Look into glade's widget prefix function self.progress_bar = glade.get_widget("progressbar") + self.custom_progress = glade.get_widget("custom_progress") + self.custom_progress.connect("expose_event",self.paint_customprogress) self.name = glade.get_widget("summary_name") self.total_size = glade.get_widget("summary_total_size") self.num_files = glade.get_widget("summary_num_files") @@ -58,7 +61,62 @@ class DetailsTabManager(object): self.next_announce = glade.get_widget("summary_next_announce") self.eta = glade.get_widget("summary_eta") self.torrent_path = glade.get_widget("summary_torrent_path") - + self.advanced_progressbar=glade.get_widget("advanced_progressbar") + + self.last_state=None + self.prefchanged_progress() + self.manager.config.onValueChanged('use_advanced_bar',self.prefchanged_progress) + + def prefchanged_progress(self): + self.use_advanced_bar=self.manager.config.get("use_advanced_bar") + if self.use_advanced_bar: + self.progress_bar.hide() + self.advanced_progressbar.show() + else: + self.progress_bar.show() + self.advanced_progressbar.hide() + + # arg1 and arg2 are additional data which we do not need. Most probably + # arg1=widghet, and arg2=event specific data + # If anybody knows of documentation which includes the expose_event + # in PyGtk would be glad to see it. - hirak99 + def paint_customprogress(self,arg1=None,arg2=None): + # Draw the custom progress bar + progress_window=self.custom_progress.window + colormap=self.custom_progress.get_colormap() + gc=progress_window.new_gc() + size=progress_window.get_size() + progress_window.begin_paint_rect(gtk.gdk.Rectangle(0,0,size[0],size[1])) + height=size[1] + if height>25: height=25 + top=(size[1]-height)/2 + gc.set_foreground(colormap.alloc_color('#F0F0FF')) + progress_window.draw_rectangle(gc,True,0,top,size[0],height-1) + gc.set_foreground(colormap.alloc_color('#A0A0AF')) + progress_window.draw_line(gc,0,top+4,size[0],top+4) + state=self.last_state + if state!=None: + gc.set_foreground(colormap.alloc_color('#2020FF')) + progress_window.draw_rectangle(gc,True,0,top,int(size[0]*float(state['progress'])),4) + num_pieces=state["num_pieces"] + for pieces_range in state['pieces']: + range_first=pieces_range[0]*size[0]/num_pieces + range_length=((pieces_range[1]-pieces_range[0]+1)*size[0]/num_pieces) + if range_length==0: + range_length=1 + gc.set_foreground(colormap.alloc_color('#8080FF')) + else: + gc.set_foreground(colormap.alloc_color('#2020FF')) + progress_window.draw_rectangle(gc,True,range_first,top+5,range_length,height-5) + gc.set_foreground(colormap.alloc_color('dim gray')) + progress_window.draw_line(gc,0,top,0,top+height) + progress_window.draw_line(gc,0,top,size[0],top) + gc.set_foreground(colormap.alloc_color('white')) + progress_window.draw_line(gc,0,top+height,size[0]-1,top+height) + progress_window.draw_line(gc,size[0]-1,top,size[0]-1,top+height) + progress_window.end_paint() + # Done drawing custom progress bar + def update(self, unique_id): state = self.manager.get_torrent_state(unique_id) @@ -108,10 +166,18 @@ class DetailsTabManager(object): self.upload_speed.set_text(common.fspeed(state["upload_rate"])) self.seeders.set_text(common.fseed(state)) self.peers.set_text(common.fpeer(state)) - self.progress_bar.set_fraction(float(state['progress'])) - self.progress_bar.set_text(common.fpcnt(state["progress"])) +# self.progress_bar.set_fraction(float(state['progress'])) +# self.progress_bar.set_text(common.fpcnt(state["progress"])) + self.last_state=state + if self.use_advanced_bar: + self.paint_customprogress() + else: + self.progress_bar.set_fraction(float(state['progress'])) + self.progress_bar.set_text(common.fpcnt(state["progress"])) + + self.eta.set_text(common.estimate_eta(state)) - self.share_ratio.set_text( '%.3f' % self.manager.calc_ratio(unique_id, + self.share_ratio.set_text('%.3f' % self.manager.calc_ratio(unique_id, state)) self.torrent_path.set_text(self.manager.get_torrent_path(unique_id))