/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: Jelmer Vernooij
  • Date: 2008-06-29 19:07:23 UTC
  • mto: This revision was merged to the branch mainline in revision 515.
  • Revision ID: jelmer@samba.org-20080629190723-l8mzg9x4oec0lhsl
Return cleartext from seahorse module

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
from bzrlib.revision import NULL_REVISION, CURRENT_REVISION
29
29
 
30
30
from colormap import AnnotateColorMap, AnnotateColorSaturation
31
 
from bzrlib.plugins.gtk.logview import LogView
 
31
from bzrlib.plugins.gtk.revisionview import RevisionView
 
32
from bzrlib.plugins.gtk.window import Window
32
33
 
33
34
 
34
35
(
41
42
) = range(6)
42
43
 
43
44
 
44
 
class GAnnotateWindow(gtk.Window):
 
45
class GAnnotateWindow(Window):
45
46
    """Annotate window."""
46
47
 
47
 
    def __init__(self, all=False, plain=False):
 
48
    def __init__(self, all=False, plain=False, parent=None, branch=None):
48
49
        self.all = all
49
50
        self.plain = plain
 
51
        self._branch = branch
50
52
        
51
 
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
 
53
        Window.__init__(self, parent)
52
54
        
53
55
        self.set_icon(self.render_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_BUTTON))
54
56
        self.annotate_colormap = AnnotateColorSaturation()
56
58
        self._create()
57
59
        self.revisions = {}
58
60
        self.history = []
 
61
        self._no_back = set()
59
62
 
60
63
    def annotate(self, tree, branch, file_id):
61
64
        self.annotations = []
62
65
        self.branch = branch
63
66
        self.tree = tree
64
67
        self.file_id = file_id
 
68
        self.revisionview.set_file_id(file_id)
65
69
        self.revision_id = getattr(tree, 'get_revision_id', 
66
70
                                   lambda: CURRENT_REVISION)()
67
71
        
68
 
        # [revision id, line number, committer, revno, highlight color, line]
 
72
        # [revision id, line number, author, revno, highlight color, line]
69
73
        self.annomodel = gtk.ListStore(gobject.TYPE_STRING,
70
74
                                       gobject.TYPE_STRING,
71
75
                                       gobject.TYPE_STRING,
77
81
        try:
78
82
            branch.lock_read()
79
83
            branch.repository.lock_read()
 
84
            self.dotted = {}
 
85
            revno_map = self.branch.get_revision_id_to_revno_map()
 
86
            for revision_id, revno in revno_map.iteritems():
 
87
                self.dotted[revision_id] = '.'.join(str(num) for num in revno)
80
88
            for line_no, (revision, revno, line)\
81
89
                    in enumerate(self._annotate(tree, file_id)):
82
90
                if revision.revision_id == last_seen and not self.all:
83
 
                    revno = committer = ""
 
91
                    revno = author = ""
84
92
                else:
85
93
                    last_seen = revision.revision_id
86
 
                    committer = revision.committer
 
94
                    author = revision.get_apparent_author()
87
95
 
88
96
                if revision.revision_id not in self.revisions:
89
97
                    self.revisions[revision.revision_id] = revision
90
98
 
91
99
                self.annomodel.append([revision.revision_id,
92
100
                                       line_no + 1,
93
 
                                       committer,
 
101
                                       author,
94
102
                                       revno,
95
103
                                       None,
96
104
                                       line.rstrip("\r\n")
106
114
 
107
115
        self.annoview.set_model(self.annomodel)
108
116
        self.annoview.grab_focus()
 
117
        my_revno = self.dotted.get(self.revision_id, 'current')
 
118
        title = '%s (%s) - gannotate' % (self.tree.id2path(file_id), my_revno)
 
119
        self.set_title(title)
109
120
 
110
121
    def jump_to_line(self, lineno):
111
122
        if lineno > len(self.annomodel) or lineno < 1:
121
132
        self.annoview.set_cursor(row)
122
133
        self.annoview.scroll_to_cell(row, use_align=True)
123
134
 
124
 
    def _dotted_revnos(self, repository, revision_id):
125
 
        """Return a dict of revision_id -> dotted revno
126
 
        
127
 
        :param repository: The repository to get the graph from
128
 
        :param revision_id: The last revision for which this info is needed
129
 
        """
130
 
        graph = repository.get_revision_graph(revision_id)
131
 
        dotted = {}
132
 
        for n, revision_id, d, revno, e in tsort.merge_sort(graph, 
133
 
            revision_id, generate_revno=True):
134
 
            dotted[revision_id] = '.'.join(str(num) for num in revno)
135
 
        return dotted
136
135
 
137
136
    def _annotate(self, tree, file_id):
138
137
        current_revision = FakeRevision(CURRENT_REVISION)
147
146
            revision_id = self.branch.last_revision()
148
147
        else:
149
148
            revision_id = self.revision_id
150
 
        dotted = self._dotted_revnos(repository, revision_id)
151
149
        revision_cache = RevisionCache(repository, self.revisions)
152
150
        for origin, text in tree.annotate_iter(file_id):
153
151
            rev_id = origin
157
155
            else:
158
156
                try:
159
157
                    revision = revision_cache.get_revision(rev_id)
160
 
                    revno = dotted.get(rev_id, 'merge')
 
158
                    revno = self.dotted.get(rev_id, 'merge')
161
159
                    if len(revno) > 15:
162
160
                        revno = 'merge'
163
161
                except NoSuchRevision:
180
178
 
181
179
    def _activate_selected_revision(self, w):
182
180
        rev_id = self._selected_revision()
183
 
        if rev_id is None:
 
181
        if not rev_id or rev_id == NULL_REVISION:
184
182
            return
185
183
        selected = self.revisions[rev_id]
186
 
        self.logview.set_revision(selected)
187
 
        self.back_button.set_sensitive(len(selected.parent_ids) != 0)
 
184
        self.revisionview.set_revision(selected)
 
185
        if (len(selected.parent_ids) != 0 and selected.parent_ids[0] not in
 
186
            self._no_back):
 
187
            enable_back = True
 
188
        else:
 
189
            enable_back = False
 
190
        self.back_button.set_sensitive(enable_back)
188
191
 
189
192
    def _create(self):
190
 
        self.logview = self._create_log_view()
 
193
        self.revisionview = self._create_log_view()
191
194
        self.annoview = self._create_annotate_view()
192
195
 
193
196
        vbox = gtk.VBox(False)
214
217
        
215
218
        self.pane = pane = gtk.VPaned()
216
219
        pane.add1(swbox)
217
 
        pane.add2(self.logview)
 
220
        pane.add2(self.revisionview)
218
221
        pane.show()
219
222
        vbox.pack_start(pane, expand=True, fill=True)
220
223
 
239
242
        self._search.show_for('line')
240
243
        self._search.set_target(self.annoview, LINE_NUM_COL)
241
244
 
242
 
    def row_diff(self, tv, path, tvc):
 
245
    def line_diff(self, tv, path, tvc):
243
246
        row = path[0]
244
247
        revision = self.annotations[row]
245
248
        repository = self.branch.repository
254
257
                tree2 = repository.revision_tree(NULL_REVISION)
255
258
        from bzrlib.plugins.gtk.diff import DiffWindow
256
259
        window = DiffWindow()
257
 
        window.set_diff("Diff for row %d" % (row+1), tree1, tree2)
 
260
        window.set_diff("Diff for line %d" % (row+1), tree1, tree2)
258
261
        window.set_file(tree1.id2path(self.file_id))
259
262
        window.show()
260
263
 
264
267
        tv.set_rules_hint(False)
265
268
        tv.connect("cursor-changed", self._activate_selected_revision)
266
269
        tv.show()
267
 
        tv.connect("row-activated", self.row_diff)
 
270
        tv.connect("row-activated", self.line_diff)
268
271
 
269
272
        cell = gtk.CellRendererText()
270
273
        cell.set_property("xalign", 1.0)
318
321
        return tv
319
322
 
320
323
    def _create_log_view(self):
321
 
        lv = LogView()
 
324
        lv = RevisionView(self._branch)
322
325
        lv.show()
323
326
        return lv
324
327
 
342
345
        return button
343
346
 
344
347
    def go_back(self):
345
 
        self.history.append(self.tree)
346
 
        self.forward_button.set_sensitive(True)
 
348
        last_tree = self.tree
347
349
        rev_id = self._selected_revision()
348
350
        parent_id = self.revisions[rev_id].parent_ids[0]
349
351
        target_tree = self.branch.repository.revision_tree(parent_id)
350
 
        self._go(target_tree)
 
352
        if self._go(target_tree):
 
353
            self.history.append(last_tree)
 
354
            self.forward_button.set_sensitive(True)
 
355
        else:
 
356
            self._no_back.add(parent_id)
 
357
            self.back_button.set_sensitive(False)
351
358
 
352
359
    def go_forward(self):
353
360
        if len(self.history) == 0:
367
374
            if new_row < 0:
368
375
                new_row = 0
369
376
            self.annoview.set_cursor(new_row)
 
377
            return True
 
378
        else:
 
379
            return False
370
380
 
371
381
    def get_scroll_offset(self, tree):
372
382
        old = self.tree.get_file(self.file_id)
379
389
                return j - i
380
390
 
381
391
 
382
 
 
383
392
class FakeRevision:
384
393
    """ A fake revision.
385
394
 
395
404
        self.timezone = 0
396
405
        self.properties = {}
397
406
 
 
407
    def get_apparent_author(self):
 
408
        return self.committer
 
409
 
398
410
 
399
411
class RevisionCache(object):
400
412
    """A caching revision source"""