/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-02-01 15:50:40 UTC
  • Revision ID: jelmer@samba.org-20070201155040-3hq4mfbxs99kzazy
add framework for tests.

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 logview import LogView
 
32
from spanselector import SpanSelector
32
33
 
33
34
 
34
35
(
44
45
class GAnnotateWindow(gtk.Window):
45
46
    """Annotate window."""
46
47
 
47
 
    def __init__(self, all=False, plain=False, parent=None):
 
48
    def __init__(self, all=False, plain=False):
48
49
        self.all = all
49
50
        self.plain = plain
50
 
        self._parent = parent
51
51
        
52
52
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
53
 
 
54
 
        self.connect("key-press-event", self._on_key_pressed)
55
53
        
56
54
        self.set_icon(self.render_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_BUTTON))
57
55
        self.annotate_colormap = AnnotateColorSaturation()
58
56
 
59
57
        self._create()
60
58
        self.revisions = {}
61
 
        self.history = []
62
 
        self._no_back = set()
63
59
 
64
60
    def annotate(self, tree, branch, file_id):
65
61
        self.annotations = []
69
65
        self.revision_id = getattr(tree, 'get_revision_id', 
70
66
                                   lambda: CURRENT_REVISION)()
71
67
        
72
 
        # [revision id, line number, author, revno, highlight color, line]
 
68
        # [revision id, line number, committer, revno, highlight color, line]
73
69
        self.annomodel = gtk.ListStore(gobject.TYPE_STRING,
74
70
                                       gobject.TYPE_STRING,
75
71
                                       gobject.TYPE_STRING,
84
80
            for line_no, (revision, revno, line)\
85
81
                    in enumerate(self._annotate(tree, file_id)):
86
82
                if revision.revision_id == last_seen and not self.all:
87
 
                    revno = author = ""
 
83
                    revno = committer = ""
88
84
                else:
89
85
                    last_seen = revision.revision_id
90
 
                    author = revision.get_apparent_author()
 
86
                    committer = revision.committer
91
87
 
92
88
                if revision.revision_id not in self.revisions:
93
89
                    self.revisions[revision.revision_id] = revision
94
90
 
95
91
                self.annomodel.append([revision.revision_id,
96
92
                                       line_no + 1,
97
 
                                       author,
 
93
                                       committer,
98
94
                                       revno,
99
95
                                       None,
100
96
                                       line.rstrip("\r\n")
144
140
        current_revision.timestamp = time.time()
145
141
        current_revision.message = '[Not yet committed]'
146
142
        current_revision.parent_ids = tree.get_parent_ids()
147
 
        current_revision.properties['branch-nick'] = self.branch.nick
148
143
        current_revno = '%d?' % (self.branch.revno() + 1)
149
144
        repository = self.branch.repository
150
145
        if self.revision_id == CURRENT_REVISION:
182
177
            return None
183
178
        return self.annomodel[path][REVISION_ID_COL]
184
179
 
185
 
    def _activate_selected_revision(self, w):
 
180
    def _show_log(self, w):
186
181
        rev_id = self._selected_revision()
187
182
        if rev_id is None:
188
183
            return
189
 
        selected = self.revisions[rev_id]
190
 
        self.logview.set_revision(selected)
191
 
        if (len(selected.parent_ids) != 0 and selected.parent_ids[0] not in
192
 
            self._no_back):
193
 
            enable_back = True
194
 
        else:
195
 
            enable_back = False
196
 
        self.back_button.set_sensitive(enable_back)
 
184
        self.logview.set_revision(self.revisions[rev_id])
197
185
 
198
186
    def _create(self):
199
187
        self.logview = self._create_log_view()
200
188
        self.annoview = self._create_annotate_view()
201
189
 
202
 
        vbox = gtk.VBox(False)
 
190
        vbox = gtk.VBox(False, 12)
 
191
        vbox.set_border_width(12)
203
192
        vbox.show()
204
193
 
205
194
        sw = gtk.ScrolledWindow()
208
197
        sw.add(self.annoview)
209
198
        self.annoview.gwindow = self
210
199
        sw.show()
211
 
 
212
 
        swbox = gtk.VBox()
213
 
        swbox.pack_start(sw)
214
 
        swbox.show()
215
 
 
216
 
        hbox = gtk.HBox(False, 6)
217
 
        self.back_button = self._create_back_button()
218
 
        hbox.pack_start(self.back_button, expand=False, fill=True)
219
 
        self.forward_button = self._create_forward_button()
220
 
        hbox.pack_start(self.forward_button, expand=False, fill=True)
221
 
        hbox.show()
222
 
        vbox.pack_start(hbox, expand=False, fill=True)
223
200
        
224
201
        self.pane = pane = gtk.VPaned()
225
 
        pane.add1(swbox)
 
202
        pane.add1(sw)
226
203
        pane.add2(self.logview)
227
204
        pane.show()
228
205
        vbox.pack_start(pane, expand=True, fill=True)
229
206
 
230
207
        self._search = SearchBox()
231
 
        swbox.pack_start(self._search, expand=False, fill=True)
 
208
        vbox.pack_start(self._search, expand=False, fill=True)
232
209
        accels = gtk.AccelGroup()
233
210
        accels.connect_group(gtk.keysyms.f, gtk.gdk.CONTROL_MASK,
234
211
                             gtk.ACCEL_LOCKED,
238
215
                             self._search_by_line)
239
216
        self.add_accel_group(accels)
240
217
 
 
218
        hbox = gtk.HBox(True, 6)
 
219
        hbox.pack_start(self._create_prev_button(), expand=False, fill=True)
 
220
        hbox.pack_end(self._create_button_box(), expand=False, fill=True)
 
221
        hbox.show()
 
222
        vbox.pack_start(hbox, expand=False, fill=True)
 
223
 
241
224
        self.add(vbox)
242
225
 
243
226
    def _search_by_text(self, accel_group, window, key, modifiers):
261
244
                tree2 = repository.revision_tree(revision.parent_ids[0])
262
245
            else:
263
246
                tree2 = repository.revision_tree(NULL_REVISION)
264
 
        from bzrlib.plugins.gtk.diff import DiffWindow
 
247
        from bzrlib.plugins.gtk.viz.diffwin import DiffWindow
265
248
        window = DiffWindow()
266
249
        window.set_diff("Diff for row %d" % (row+1), tree1, tree2)
267
250
        window.set_file(tree1.id2path(self.file_id))
271
254
    def _create_annotate_view(self):
272
255
        tv = gtk.TreeView()
273
256
        tv.set_rules_hint(False)
274
 
        tv.connect("cursor-changed", self._activate_selected_revision)
 
257
        tv.connect("cursor-changed", self._show_log)
275
258
        tv.show()
276
259
        tv.connect("row-activated", self.row_diff)
277
260
 
329
312
    def _create_log_view(self):
330
313
        lv = LogView()
331
314
        lv.show()
 
315
 
332
316
        return lv
333
317
 
334
 
    def _create_back_button(self):
 
318
    def _create_button_box(self):
 
319
        box = gtk.HButtonBox()
 
320
        box.set_layout(gtk.BUTTONBOX_END)
 
321
        box.show()
 
322
 
 
323
        button = gtk.Button()
 
324
        button.set_use_stock(True)
 
325
        button.set_label("gtk-close")
 
326
        button.connect("clicked", lambda w: self.destroy())
 
327
        button.show()
 
328
 
 
329
        box.pack_start(button, expand=False, fill=False)
 
330
 
 
331
        return box
 
332
 
 
333
    def _create_prev_button(self):
 
334
        box = gtk.HButtonBox()
 
335
        box.set_layout(gtk.BUTTONBOX_START)
 
336
        box.show()
 
337
        
335
338
        button = gtk.Button()
336
339
        button.set_use_stock(True)
337
340
        button.set_label("gtk-go-back")
338
341
        button.connect("clicked", lambda w: self.go_back())
339
 
        button.set_relief(gtk.RELIEF_NONE)
340
 
        button.show()
341
 
        return button
342
 
 
343
 
    def _create_forward_button(self):
344
 
        button = gtk.Button()
345
 
        button.set_use_stock(True)
346
 
        button.set_label("gtk-go-forward")
347
 
        button.connect("clicked", lambda w: self.go_forward())
348
 
        button.set_relief(gtk.RELIEF_NONE)
349
 
        button.show()
350
 
        button.set_sensitive(False)
351
 
        return button
 
342
        button.show()
 
343
        box.pack_start(button, expand=False, fill=False)
 
344
        return box
352
345
 
353
346
    def go_back(self):
354
 
        last_tree = self.tree
355
347
        rev_id = self._selected_revision()
356
348
        parent_id = self.revisions[rev_id].parent_ids[0]
357
 
        target_tree = self.branch.repository.revision_tree(parent_id)
358
 
        if self._go(target_tree):
359
 
            self.history.append(last_tree)
360
 
            self.forward_button.set_sensitive(True)
361
 
        else:
362
 
            self._no_back.add(parent_id)
363
 
            self.back_button.set_sensitive(False)
364
 
 
365
 
    def go_forward(self):
366
 
        if len(self.history) == 0:
367
 
            return
368
 
        target_tree = self.history.pop()
369
 
        if len(self.history) == 0:
370
 
            self.forward_button.set_sensitive(False)
371
 
        self._go(target_tree)
372
 
 
373
 
    def _go(self, target_tree):
374
 
        rev_id = self._selected_revision()
375
 
        if self.file_id in target_tree:
376
 
            offset = self.get_scroll_offset(target_tree)
 
349
        tree = self.branch.repository.revision_tree(parent_id)
 
350
        if self.file_id in tree:
 
351
            offset = self.get_scroll_offset(tree)
377
352
            (row,), col = self.annoview.get_cursor()
378
 
            self.annotate(target_tree, self.branch, self.file_id)
379
 
            new_row = row+offset
380
 
            if new_row < 0:
381
 
                new_row = 0
382
 
            self.annoview.set_cursor(new_row)
383
 
            return True
384
 
        else:
385
 
            return False
 
353
            self.annotate(tree, self.branch, self.file_id)
 
354
            self.annoview.set_cursor(row+offset)
386
355
 
387
356
    def get_scroll_offset(self, tree):
388
357
        old = self.tree.get_file(self.file_id)
394
363
            if i + n >= row:
395
364
                return j - i
396
365
 
397
 
    def _on_key_pressed(self, widget, event):
398
 
        """ Key press event handler. """
399
 
        keyname = gtk.gdk.keyval_name(event.keyval)
400
 
        func = getattr(self, '_on_key_press_' + keyname, None)
401
 
        if func:
402
 
            return func(event)
403
 
 
404
 
    def _on_key_press_w(self, event):
405
 
        if event.state & gtk.gdk.CONTROL_MASK:
406
 
            self.destroy()
407
 
            if self._parent is None:
408
 
                gtk.main_quit()
409
 
 
410
 
    def _on_key_press_q(self, event):
411
 
        if event.state & gtk.gdk.CONTROL_MASK:
412
 
            gtk.main_quit()
413
 
    
414
 
 
415
366
 
416
367
 
417
368
class FakeRevision:
420
371
    For when a revision is referenced but not present.
421
372
    """
422
373
 
423
 
    def __init__(self, revision_id, committer='?', nick=None):
 
374
    def __init__(self, revision_id, committer='?'):
424
375
        self.revision_id = revision_id
425
376
        self.parent_ids = []
426
377
        self.committer = committer
427
378
        self.message = "?"
428
379
        self.timestamp = 0.0
429
380
        self.timezone = 0
430
 
        self.properties = {}
431
 
 
432
 
    def get_apparent_author(self):
433
 
        return self.committer
434
381
 
435
382
 
436
383
class RevisionCache(object):