Ticket #378: pieces_bar.patch

File pieces_bar.patch, 9.8 KB (added by James_Kern, 14 years ago)

patch for adding pieces bar to status tab, against 1.2.1

  • deluge/core/torrent.py

    diff -urp deluge-1.2.1-original/deluge/core/torrent.py deluge-1.2.1/deluge/core/torrent.py
    old new class Torrent: 
    479479        """Returns the torrents queue position""" 
    480480        return self.handle.queue_position() 
    481481 
     482    def get_pieces_status(self): 
     483        if not self.handle.has_metadata(): 
     484            return [] 
     485 
     486        status = self.handle.status() 
     487        return status.pieces 
     488         
    482489    def get_file_progress(self): 
    483490        """Returns the file progress as a list of floats.. 0.0 -> 1.0""" 
    484491        if not self.handle.has_metadata(): 
    class Torrent: 
    642649            "num_pieces": ti_num_pieces, 
    643650            "peers": self.get_peers, 
    644651            "piece_length": ti_piece_length, 
     652            "pieces": self.get_pieces_status, 
    645653            "private": ti_priv, 
    646654            "queue": self.handle.queue_position, 
    647655            "ratio": self.get_ratio, 
  • deluge/ui/gtkui/glade/main_window.glade

    diff -urp deluge-1.2.1-original/deluge/ui/gtkui/glade/main_window.glade deluge-1.2.1/deluge/ui/gtkui/glade/main_window.glade
    old new  
    643643                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> 
    644644                        <property name="spacing">5</property> 
    645645                        <child> 
    646                           <widget class="GtkProgressBar" id="progressbar"> 
     646                          <widget class="GtkVBox" id="vbox8"> 
    647647                            <property name="visible">True</property> 
    648                             <property name="show_text">True</property> 
    649                             <property name="pulse_step">0.10000000149</property> 
     648                            <child> 
     649                              <widget class="GtkLabel" id="label28"> 
     650                                <property name="visible">True</property> 
     651                                <property name="xalign">0</property> 
     652                                <property name="label" translatable="yes">&lt;b&gt;Completed Pieces:&lt;/b&gt;</property> 
     653                                <property name="use_markup">True</property> 
     654                              </widget> 
     655                              <packing> 
     656                                <property name="expand">False</property> 
     657                              </packing> 
     658                            </child> 
     659                            <child> 
     660                              <widget class="GtkAlignment" id="alignment12"> 
     661                                <property name="visible">True</property> 
     662                                <property name="top_padding">3</property> 
     663                                <property name="left_padding">12</property> 
     664                                <child> 
     665                                  <placeholder/> 
     666                                </child> 
     667                              </widget> 
     668                              <packing> 
     669                                <property name="position">1</property> 
     670                              </packing> 
     671                            </child> 
    650672                          </widget> 
    651                           <packing> 
    652                             <property name="expand">False</property> 
    653                             <property name="fill">False</property> 
    654                           </packing> 
    655673                        </child> 
    656674                        <child> 
    657675                          <widget class="GtkTable" id="table8"> 
     
    19671985                                          <widget class="GtkFileChooserButton" id="filechooser_move_completed"> 
    19681986                                            <property name="visible">True</property> 
    19691987                                            <property name="sensitive">False</property> 
    1970                                             <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property> 
    19711988                                            <property name="local_only">False</property> 
     1989                                            <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property> 
    19721990                                            <property name="title" translatable="yes">Select A Folder</property> 
    19731991                                          </widget> 
    19741992                                          <packing> 
  • deluge/ui/gtkui/status_tab.py

    diff -urp deluge-1.2.1-original/deluge/ui/gtkui/status_tab.py deluge-1.2.1/deluge/ui/gtkui/status_tab.py
    old new class StatusTab(Tab): 
    7474        self._child_widget = glade.get_widget("status_tab") 
    7575        self._tab_label = glade.get_widget("status_tab_label") 
    7676 
     77        self.pieces_bar = PiecesBar() 
     78        glade.get_widget("alignment12").add(self.pieces_bar) 
     79         
    7780        self.label_widgets = [ 
    7881            (glade.get_widget("summary_pieces"), fpeer_size_second, ("num_pieces", "piece_length")), 
    7982            (glade.get_widget("summary_availability"), fratio, ("distributed_copies",)), 
    class StatusTab(Tab): 
    9194            (glade.get_widget("summary_seed_time"), deluge.common.ftime, ("seeding_time",)), 
    9295            (glade.get_widget("summary_seed_rank"), str, ("seed_rank",)), 
    9396            (glade.get_widget("summary_auto_managed"), str, ("is_auto_managed",)), 
    94             (glade.get_widget("progressbar"), fpcnt, ("progress",)), 
     97            (self.pieces_bar, None, ("pieces",)), 
    9598            (glade.get_widget("summary_date_added"), deluge.common.fdate, ("time_added",)) 
    9699        ] 
    97100 
    class StatusTab(Tab): 
    107110            return 
    108111 
    109112        # Get the torrent status 
    110         status_keys = ["progress", "num_pieces", "piece_length", 
     113        status_keys = ["pieces", "num_pieces", "piece_length", 
    111114            "distributed_copies", "all_time_download", "total_payload_download", 
    112115            "total_uploaded", "total_payload_upload", "download_payload_rate", 
    113116            "upload_payload_rate", "num_peers", "num_seeds", "total_peers", 
    class StatusTab(Tab): 
    141144 
    142145            if widget[0].get_text() != txt: 
    143146                widget[0].set_text(txt) 
    144  
    145         # Do the progress bar because it's a special case (not a label) 
    146         w = component.get("MainWindow").main_glade.get_widget("progressbar") 
    147         fraction = status["progress"] / 100 
    148         if w.get_fraction() != fraction: 
    149             w.set_fraction(fraction) 
    150  
     147     
     148        # If this is true the torrent should be completely downloaded 
     149        # so display a full bar 
     150        if int(status["num_pieces"]) != len(status["pieces"]): 
     151            self.pieces_bar.pieces = [True] 
     152            self.pieces_bar.update() 
     153        # Don't update if the pieces are the same     
     154        elif status["pieces"] != self.pieces_bar.pieces: 
     155            self.pieces_bar.pieces = status["pieces"] 
     156            self.pieces_bar.update() 
     157         
    151158    def clear(self): 
    152159        for widget in self.label_widgets: 
    153160            widget[0].set_text("") 
    154161 
    155         component.get("MainWindow").main_glade.get_widget("progressbar").set_fraction(0.0) 
     162        self.pieces_bar.clear() 
     163 
     164class PiecesBar(gtk.DrawingArea): 
     165    def __init__(self): 
     166        gtk.DrawingArea.__init__(self) 
     167        self.gc = None 
     168        self.width = 0 
     169        self.height = 0 
     170        self.pieces = [] 
     171         
     172        self.connect('size-allocate', self.on_size_allocate) 
     173        self.connect('expose-event', self.update) 
     174        self.connect('realize', self.on_realize) 
     175 
     176        self.show() 
     177 
     178    def on_realize(self, widget): 
     179        map = widget.get_colormap() 
     180        done_color = map.alloc_color("#325891") 
     181        wait_color = map.alloc_color("#a8a8a9") 
     182        outline_color = map.alloc_color("#555555") 
     183         
     184        self.gc_done = widget.window.new_gc(foreground=done_color) 
     185        self.gc_wait = widget.window.new_gc(foreground=wait_color) 
     186        self.gc_outline = widget.window.new_gc(foreground=outline_color) 
     187     
     188    def on_size_allocate(self, widget, size): 
     189        self.width = size.width 
     190        self.height = size.height 
     191         
     192    def update(self, widget=None, event=None): 
     193        num_pieces = len(self.pieces) 
     194         
     195        if num_pieces < 1: 
     196            self.clear() 
     197            return 
     198         
     199        piece_size = (self.width - 2) / num_pieces 
     200        padding = [1] * ((self.width - 2) - (piece_size * num_pieces)) 
     201         
     202        self.window.draw_rectangle(self.gc_outline, False, 0, 0, 
     203                                   self.width - 1, self.height - 1) 
     204         
     205        start_pos = 1 
     206        for piece in self.pieces: 
     207            if len(padding) > 0: 
     208                this_piece_size = piece_size + padding.pop() 
     209            else: 
     210                this_piece_size = piece_size 
     211         
     212            if piece is True: 
     213                self.window.draw_rectangle(self.gc_done, True, start_pos, 1,  
     214                                           this_piece_size, self.height - 2) 
     215            else: 
     216                self.window.draw_rectangle(self.gc_wait, True, start_pos, 1,  
     217                                           this_piece_size, self.height - 2)  
     218            start_pos += this_piece_size 
     219     
     220    def clear(self): 
     221        self.window.draw_rectangle(self.gc_wait, True, 0, 0, 
     222                                   self.width, self.height) 
     223        self.window.draw_rectangle(self.gc_outline, False, 0, 0, 
     224                                   self.width - 1, self.height - 1) 
     225     
     226    def get_text(self): 
     227        return "" 
     228     
     229    def set_text(self, text): 
     230        pass