/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: 2007-04-03 17:16:07 UTC
  • mfrom: (187 trunk)
  • mto: This revision was merged to the branch mainline in revision 188.
  • Revision ID: jelmer@samba.org-20070403171607-0zaskazouokrm4cq
Tags: bzr-gtk-0.15.2
PrepareĀ forĀ 0.15.2

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.revisionview import RevisionView
32
 
from bzrlib.plugins.gtk.window import Window
 
31
from bzrlib.plugins.gtk.logview import LogView
33
32
 
34
33
 
35
34
(
42
41
) = range(6)
43
42
 
44
43
 
45
 
class GAnnotateWindow(Window):
 
44
class GAnnotateWindow(gtk.Window):
46
45
    """Annotate window."""
47
46
 
48
 
    def __init__(self, all=False, plain=False, parent=None, branch=None):
 
47
    def __init__(self, all=False, plain=False):
49
48
        self.all = all
50
49
        self.plain = plain
51
 
        self._branch = branch
52
50
        
53
 
        Window.__init__(self, parent)
 
51
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
54
52
        
55
53
        self.set_icon(self.render_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_BUTTON))
56
54
        self.annotate_colormap = AnnotateColorSaturation()
65
63
        self.branch = branch
66
64
        self.tree = tree
67
65
        self.file_id = file_id
68
 
        self.revisionview.set_file_id(file_id)
69
66
        self.revision_id = getattr(tree, 'get_revision_id', 
70
67
                                   lambda: CURRENT_REVISION)()
71
68
        
72
 
        # [revision id, line number, author, revno, highlight color, line]
 
69
        # [revision id, line number, committer, revno, highlight color, line]
73
70
        self.annomodel = gtk.ListStore(gobject.TYPE_STRING,
74
71
                                       gobject.TYPE_STRING,
75
72
                                       gobject.TYPE_STRING,
81
78
        try:
82
79
            branch.lock_read()
83
80
            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)
88
81
            for line_no, (revision, revno, line)\
89
82
                    in enumerate(self._annotate(tree, file_id)):
90
83
                if revision.revision_id == last_seen and not self.all:
91
 
                    revno = author = ""
 
84
                    revno = committer = ""
92
85
                else:
93
86
                    last_seen = revision.revision_id
94
 
                    author = ", ".join(revision.get_apparent_authors())
 
87
                    committer = revision.committer
95
88
 
96
89
                if revision.revision_id not in self.revisions:
97
90
                    self.revisions[revision.revision_id] = revision
98
91
 
99
92
                self.annomodel.append([revision.revision_id,
100
93
                                       line_no + 1,
101
 
                                       author,
 
94
                                       committer,
102
95
                                       revno,
103
96
                                       None,
104
97
                                       line.rstrip("\r\n")
114
107
 
115
108
        self.annoview.set_model(self.annomodel)
116
109
        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)
120
110
 
121
111
    def jump_to_line(self, lineno):
122
112
        if lineno > len(self.annomodel) or lineno < 1:
132
122
        self.annoview.set_cursor(row)
133
123
        self.annoview.scroll_to_cell(row, use_align=True)
134
124
 
 
125
    def _dotted_revnos(self, repository, revision_id):
 
126
        """Return a dict of revision_id -> dotted revno
 
127
        
 
128
        :param repository: The repository to get the graph from
 
129
        :param revision_id: The last revision for which this info is needed
 
130
        """
 
131
        graph = repository.get_revision_graph(revision_id)
 
132
        dotted = {}
 
133
        for n, revision_id, d, revno, e in tsort.merge_sort(graph, 
 
134
            revision_id, generate_revno=True):
 
135
            dotted[revision_id] = '.'.join(str(num) for num in revno)
 
136
        return dotted
135
137
 
136
138
    def _annotate(self, tree, file_id):
137
139
        current_revision = FakeRevision(CURRENT_REVISION)
139
141
        current_revision.timestamp = time.time()
140
142
        current_revision.message = '[Not yet committed]'
141
143
        current_revision.parent_ids = tree.get_parent_ids()
142
 
        current_revision.properties['branch-nick'] = self.branch._get_nick(local=True)
 
144
        current_revision.properties['branch-nick'] = self.branch.nick
143
145
        current_revno = '%d?' % (self.branch.revno() + 1)
144
146
        repository = self.branch.repository
145
147
        if self.revision_id == CURRENT_REVISION:
146
148
            revision_id = self.branch.last_revision()
147
149
        else:
148
150
            revision_id = self.revision_id
 
151
        dotted = self._dotted_revnos(repository, revision_id)
149
152
        revision_cache = RevisionCache(repository, self.revisions)
150
153
        for origin, text in tree.annotate_iter(file_id):
151
154
            rev_id = origin
155
158
            else:
156
159
                try:
157
160
                    revision = revision_cache.get_revision(rev_id)
158
 
                    revno = self.dotted.get(rev_id, 'merge')
 
161
                    revno = dotted.get(rev_id, 'merge')
159
162
                    if len(revno) > 15:
160
163
                        revno = 'merge'
161
164
                except NoSuchRevision:
178
181
 
179
182
    def _activate_selected_revision(self, w):
180
183
        rev_id = self._selected_revision()
181
 
        if not rev_id or rev_id == NULL_REVISION:
 
184
        if rev_id is None:
182
185
            return
183
186
        selected = self.revisions[rev_id]
184
 
        self.revisionview.set_revision(selected)
 
187
        self.logview.set_revision(selected)
185
188
        if (len(selected.parent_ids) != 0 and selected.parent_ids[0] not in
186
189
            self._no_back):
187
190
            enable_back = True
190
193
        self.back_button.set_sensitive(enable_back)
191
194
 
192
195
    def _create(self):
193
 
        self.revisionview = self._create_log_view()
 
196
        self.logview = self._create_log_view()
194
197
        self.annoview = self._create_annotate_view()
195
198
 
196
199
        vbox = gtk.VBox(False)
212
215
        hbox.pack_start(self.back_button, expand=False, fill=True)
213
216
        self.forward_button = self._create_forward_button()
214
217
        hbox.pack_start(self.forward_button, expand=False, fill=True)
215
 
        self.find_button = self._create_find_button()
216
 
        hbox.pack_start(self.find_button, expand=False, fill=True)
217
 
        self.goto_button = self._create_goto_button()
218
 
        hbox.pack_start(self.goto_button, expand=False, fill=True)
219
218
        hbox.show()
220
219
        vbox.pack_start(hbox, expand=False, fill=True)
221
220
        
222
221
        self.pane = pane = gtk.VPaned()
223
222
        pane.add1(swbox)
224
 
        pane.add2(self.revisionview)
 
223
        pane.add2(self.logview)
225
224
        pane.show()
226
225
        vbox.pack_start(pane, expand=True, fill=True)
227
226
 
238
237
 
239
238
        self.add(vbox)
240
239
 
241
 
    def _search_by_text(self, *ignored): # (accel_group, window, key, modifiers):
 
240
    def _search_by_text(self, accel_group, window, key, modifiers):
242
241
        self._search.show_for('text')
243
242
        self._search.set_target(self.annoview, TEXT_LINE_COL)
244
243
 
245
 
    def _search_by_line(self, *ignored): # accel_group, window, key, modifiers):
 
244
    def _search_by_line(self, accel_group, window, key, modifiers):
246
245
        self._search.show_for('line')
247
246
        self._search.set_target(self.annoview, LINE_NUM_COL)
248
247
 
249
 
    def line_diff(self, tv, path, tvc):
 
248
    def row_diff(self, tv, path, tvc):
250
249
        row = path[0]
251
250
        revision = self.annotations[row]
252
251
        repository = self.branch.repository
261
260
                tree2 = repository.revision_tree(NULL_REVISION)
262
261
        from bzrlib.plugins.gtk.diff import DiffWindow
263
262
        window = DiffWindow()
264
 
        window.set_diff("Diff for line %d" % (row+1), tree1, tree2)
 
263
        window.set_diff("Diff for row %d" % (row+1), tree1, tree2)
265
264
        window.set_file(tree1.id2path(self.file_id))
266
265
        window.show()
267
266
 
271
270
        tv.set_rules_hint(False)
272
271
        tv.connect("cursor-changed", self._activate_selected_revision)
273
272
        tv.show()
274
 
        tv.connect("row-activated", self.line_diff)
 
273
        tv.connect("row-activated", self.row_diff)
275
274
 
276
275
        cell = gtk.CellRendererText()
277
276
        cell.set_property("xalign", 1.0)
325
324
        return tv
326
325
 
327
326
    def _create_log_view(self):
328
 
        lv = RevisionView(self._branch)
 
327
        lv = LogView()
329
328
        lv.show()
330
329
        return lv
331
330
 
348
347
        button.set_sensitive(False)
349
348
        return button
350
349
 
351
 
    def _create_find_button(self):
352
 
        button = gtk.Button()
353
 
        button.set_use_stock(True)
354
 
        button.set_label("gtk-find")
355
 
        button.set_tooltip_text("Search for text (Ctrl+F)")
356
 
        button.connect("clicked", self._search_by_text)
357
 
        button.set_relief(gtk.RELIEF_NONE)
358
 
        button.show()
359
 
        button.set_sensitive(True)
360
 
        return button
361
 
 
362
 
    def _create_goto_button(self):
363
 
        button = gtk.Button()
364
 
        button.set_label("Goto Line")
365
 
        button.set_tooltip_text("Scroll to a line by entering its number (Ctrl+G)")
366
 
        button.connect("clicked", self._search_by_line)
367
 
        button.set_relief(gtk.RELIEF_NONE)
368
 
        button.show()
369
 
        button.set_sensitive(True)
370
 
        return button
371
 
 
372
350
    def go_back(self):
373
351
        last_tree = self.tree
374
352
        rev_id = self._selected_revision()
414
392
                return j - i
415
393
 
416
394
 
417
 
class FakeRevision(object):
 
395
 
 
396
class FakeRevision:
418
397
    """ A fake revision.
419
398
 
420
399
    For when a revision is referenced but not present.
429
408
        self.timezone = 0
430
409
        self.properties = {}
431
410
 
432
 
    def get_apparent_authors(self):
433
 
        return [self.committer]
434
 
 
435
411
 
436
412
class RevisionCache(object):
437
413
    """A caching revision source"""
438
 
 
439
414
    def __init__(self, real_source, seed_cache=None):
440
415
        self.__real_source = real_source
441
416
        if seed_cache is None: