Ticket #378: pieces_bar.patch

File pieces_bar.patch, 9.8 KB (added by James_Kern, 15 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