/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-03-14 02:19:21 UTC
  • mto: (452.2.3 trunk)
  • mto: This revision was merged to the branch mainline in revision 453.
  • Revision ID: jelmer@samba.org-20080314021921-2dgptk62dhp7pd91
Honor child_submit_to in the submit_branch if no email address was specified.
Consistent with the changes in bzr.dev.

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