/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to annotate/gannotate.py

  • Committer: Vincent Ladeuil
  • Date: 2007-01-26 11:48:08 UTC
  • mfrom: (66.6.7 bzr-gtk-meld)
  • Revision ID: v.ladeuil+lp@free.fr-20070126114808-qvsp1nbo1g1gz6dp
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
import pango
24
24
import re
25
25
 
26
 
from bzrlib import tsort
 
26
from bzrlib import patiencediff, tsort
27
27
from bzrlib.errors import NoSuchRevision
28
28
from bzrlib.revision import NULL_REVISION, CURRENT_REVISION
29
29
 
55
55
        self.annotate_colormap = AnnotateColorSaturation()
56
56
 
57
57
        self._create()
58
 
 
59
 
        if self.plain:
60
 
            self.span_selector.hide()
 
58
        self.revisions = {}
61
59
 
62
60
    def annotate(self, tree, branch, file_id):
63
 
        self.revisions = {}
64
61
        self.annotations = []
65
62
        self.branch = branch
66
63
        self.tree = tree
101
98
                self.annotations.append(revision)
102
99
 
103
100
            if not self.plain:
104
 
                self._set_oldest_newest()
105
 
                # Recall that calling activate_default will emit "span-changed",
106
 
                # so self._span_changed_cb will take care of initial highlighting
107
 
                self.span_selector.activate_default()
 
101
                now = time.time()
 
102
                self.annomodel.foreach(self._highlight_annotation, now)
108
103
        finally:
109
104
            branch.repository.unlock()
110
105
            branch.unlock()
144
139
        current_revision.committer = self.branch.get_config().username()
145
140
        current_revision.timestamp = time.time()
146
141
        current_revision.message = '[Not yet committed]'
 
142
        current_revision.parent_ids = tree.get_parent_ids()
147
143
        current_revno = '%d?' % (self.branch.revno() + 1)
148
144
        repository = self.branch.repository
149
145
        if self.revision_id == CURRENT_REVISION:
151
147
        else:
152
148
            revision_id = self.revision_id
153
149
        dotted = self._dotted_revnos(repository, revision_id)
154
 
        revision_cache = RevisionCache(repository)
 
150
        revision_cache = RevisionCache(repository, self.revisions)
155
151
        for origin, text in tree.annotate_iter(file_id):
156
152
            rev_id = origin
157
 
            try:
158
 
                revision = revision_cache.get_revision(rev_id)
159
 
                revno = dotted.get(rev_id, 'merge')
160
 
                if len(revno) > 15:
161
 
                    revno = 'merge'
162
 
            except NoSuchRevision:
163
 
                committer = "?"
164
 
                if rev_id == CURRENT_REVISION:
165
 
                    revision = current_revision
166
 
                    revno = current_revno
167
 
                else:
 
153
            if rev_id == CURRENT_REVISION:
 
154
                revision = current_revision
 
155
                revno = current_revno
 
156
            else:
 
157
                try:
 
158
                    revision = revision_cache.get_revision(rev_id)
 
159
                    revno = dotted.get(rev_id, 'merge')
 
160
                    if len(revno) > 15:
 
161
                        revno = 'merge'
 
162
                except NoSuchRevision:
168
163
                    revision = FakeRevision(rev_id)
169
164
                    revno = "?"
170
165
 
171
166
            yield revision, revno, text
172
167
 
173
 
    def _set_oldest_newest(self):
174
 
        rev_dates = map(lambda i: self.revisions[i].timestamp, self.revisions)
175
 
        if len(rev_dates) == 0:
176
 
            return
177
 
        oldest = min(rev_dates)
178
 
        newest = max(rev_dates)
179
 
 
180
 
        span = self._span_from_seconds(time.time() - oldest)
181
 
        self.span_selector.set_to_oldest_span(span)
182
 
        
183
 
        span = self._span_from_seconds(newest - oldest)
184
 
        self.span_selector.set_newest_to_oldest_span(span)
185
 
 
186
 
    def _span_from_seconds(self, seconds):
187
 
        return (seconds / (24 * 60 * 60))
188
 
    
189
 
    def _span_changed_cb(self, w, span):
190
 
        self.annotate_colormap.set_span(span)
191
 
        now = time.time()
192
 
        self.annomodel.foreach(self._highlight_annotation, now)
193
 
 
194
168
    def _highlight_annotation(self, model, path, iter, now):
195
169
        revision_id, = model.get(iter, REVISION_ID_COL)
196
170
        revision = self.revisions[revision_id]
197
171
        model.set(iter, HIGHLIGHT_COLOR_COL,
198
172
                  self.annotate_colormap.get_color(revision, now))
199
173
 
200
 
    def _show_log(self, w):
 
174
    def _selected_revision(self):
201
175
        (path, col) = self.annoview.get_cursor()
202
176
        if path is None:
 
177
            return None
 
178
        return self.annomodel[path][REVISION_ID_COL]
 
179
 
 
180
    def _show_log(self, w):
 
181
        rev_id = self._selected_revision()
 
182
        if rev_id is None:
203
183
            return
204
 
        rev_id = self.annomodel[path][REVISION_ID_COL]
205
184
        self.logview.set_revision(self.revisions[rev_id])
206
185
 
207
186
    def _create(self):
208
187
        self.logview = self._create_log_view()
209
188
        self.annoview = self._create_annotate_view()
210
 
        self.span_selector = self._create_span_selector()
211
189
 
212
190
        vbox = gtk.VBox(False, 12)
213
191
        vbox.set_border_width(12)
238
216
        self.add_accel_group(accels)
239
217
 
240
218
        hbox = gtk.HBox(True, 6)
241
 
        hbox.pack_start(self.span_selector, expand=False, fill=True)
242
 
        hbox.pack_start(self._create_button_box(), expand=False, fill=True)
 
219
        hbox.pack_start(self._create_prev_button(), expand=False, fill=True)
 
220
        hbox.pack_end(self._create_button_box(), expand=False, fill=True)
243
221
        hbox.show()
244
222
        vbox.pack_start(hbox, expand=False, fill=True)
245
223
 
331
309
 
332
310
        return tv
333
311
 
334
 
    def _create_span_selector(self):
335
 
        ss = SpanSelector()
336
 
        ss.connect("span-changed", self._span_changed_cb)
337
 
        ss.show()
338
 
 
339
 
        return ss
340
 
 
341
312
    def _create_log_view(self):
342
313
        lv = LogView()
343
314
        lv.show()
359
330
 
360
331
        return box
361
332
 
 
333
    def _create_prev_button(self):
 
334
        box = gtk.HButtonBox()
 
335
        box.set_layout(gtk.BUTTONBOX_START)
 
336
        box.show()
 
337
        
 
338
        button = gtk.Button()
 
339
        button.set_use_stock(True)
 
340
        button.set_label("gtk-go-back")
 
341
        button.connect("clicked", lambda w: self.go_back())
 
342
        button.show()
 
343
        box.pack_start(button, expand=False, fill=False)
 
344
        return box
 
345
 
 
346
    def go_back(self):
 
347
        rev_id = self._selected_revision()
 
348
        parent_id = self.revisions[rev_id].parent_ids[0]
 
349
        tree = self.branch.repository.revision_tree(parent_id)
 
350
        if self.file_id in tree:
 
351
            offset = self.get_scroll_offset(tree)
 
352
            (row,), col = self.annoview.get_cursor()
 
353
            self.annotate(tree, self.branch, self.file_id)
 
354
            self.annoview.set_cursor(row+offset)
 
355
 
 
356
    def get_scroll_offset(self, tree):
 
357
        old = self.tree.get_file(self.file_id)
 
358
        new = tree.get_file(self.file_id)
 
359
        (row,), col = self.annoview.get_cursor()
 
360
        matcher = patiencediff.PatienceSequenceMatcher(None, old.readlines(),
 
361
                                                       new.readlines())
 
362
        for i, j, n in matcher.get_matching_blocks():
 
363
            if i + n >= row:
 
364
                return j - i
 
365
 
 
366
 
362
367
 
363
368
class FakeRevision:
364
369
    """ A fake revision.
377
382
 
378
383
class RevisionCache(object):
379
384
    """A caching revision source"""
380
 
    def __init__(self, real_source):
 
385
    def __init__(self, real_source, seed_cache=None):
381
386
        self.__real_source = real_source
382
 
        self.__cache = {}
 
387
        if seed_cache is None:
 
388
            self.__cache = {}
 
389
        else:
 
390
            self.__cache = dict(seed_cache)
383
391
 
384
392
    def get_revision(self, revision_id):
385
393
        if revision_id not in self.__cache: