/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 branchview/treeview.py

  • Committer: Jelmer Vernooij
  • Date: 2008-06-29 16:24:24 UTC
  • mto: This revision was merged to the branch mainline in revision 519.
  • Revision ID: jelmer@samba.org-20080629162424-48a6rrjmmpejfcyr
Stop emitting no longer used revisions-loaded message.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
__copyright__ = "Copyright © 2005 Canonical Ltd."
7
7
__author__    = "Daniel Schierbeck <daniel.schierbeck@gmail.com>"
8
8
 
9
 
from gi.repository import Gtk
10
 
from gi.repository import GObject
11
 
from gi.repository import Pango
12
 
 
 
9
import sys
 
10
import string
 
11
import gtk
 
12
import gobject
 
13
import pango
 
14
import re
 
15
import treemodel
13
16
from bzrlib import ui
 
17
 
 
18
from bzrlib.plugins.gtk import _i18n
 
19
from linegraph import linegraph, same_branch
 
20
from graphcell import CellRendererGraph
 
21
from treemodel import TreeModel
14
22
from bzrlib.revision import NULL_REVISION
15
23
 
16
 
from bzrlib.plugins.gtk import lock
17
 
from bzrlib.plugins.gtk.ui import ProgressPanel
18
 
from bzrlib.plugins.gtk.branchview import treemodel
19
 
from bzrlib.plugins.gtk.branchview.linegraph import linegraph, same_branch
20
 
from bzrlib.plugins.gtk.branchview.graphcell import CellRendererGraph
21
 
 
22
 
 
23
 
class TreeView(Gtk.VBox):
 
24
class TreeView(gtk.VBox):
24
25
 
25
26
    __gproperties__ = {
26
 
        'branch': (GObject.TYPE_PYOBJECT,
 
27
        'branch': (gobject.TYPE_PYOBJECT,
27
28
                   'Branch',
28
29
                   'The Bazaar branch being visualized',
29
 
                   GObject.PARAM_CONSTRUCT_ONLY | GObject.PARAM_WRITABLE),
 
30
                   gobject.PARAM_CONSTRUCT_ONLY | gobject.PARAM_WRITABLE),
30
31
 
31
 
        'revision': (GObject.TYPE_PYOBJECT,
 
32
        'revision': (gobject.TYPE_PYOBJECT,
32
33
                     'Revision',
33
34
                     'The currently selected revision',
34
 
                     GObject.PARAM_READWRITE),
 
35
                     gobject.PARAM_READWRITE),
35
36
 
36
 
        'revision-number': (GObject.TYPE_STRING,
 
37
        'revision-number': (gobject.TYPE_STRING,
37
38
                            'Revision number',
38
39
                            'The number of the selected revision',
39
40
                            '',
40
 
                            GObject.PARAM_READABLE),
 
41
                            gobject.PARAM_READABLE),
41
42
 
42
 
        'children': (GObject.TYPE_PYOBJECT,
 
43
        'children': (gobject.TYPE_PYOBJECT,
43
44
                     'Child revisions',
44
45
                     'Children of the currently selected revision',
45
 
                     GObject.PARAM_READABLE),
 
46
                     gobject.PARAM_READABLE),
46
47
 
47
 
        'parents': (GObject.TYPE_PYOBJECT,
 
48
        'parents': (gobject.TYPE_PYOBJECT,
48
49
                    'Parent revisions',
49
50
                    'Parents to the currently selected revision',
50
 
                    GObject.PARAM_READABLE),
 
51
                    gobject.PARAM_READABLE),
51
52
 
52
 
        'revno-column-visible': (GObject.TYPE_BOOLEAN,
 
53
        'revno-column-visible': (gobject.TYPE_BOOLEAN,
53
54
                                 'Revision number column',
54
55
                                 'Show revision number column',
55
56
                                 True,
56
 
                                 GObject.PARAM_READWRITE),
 
57
                                 gobject.PARAM_READWRITE),
57
58
 
58
 
        'graph-column-visible': (GObject.TYPE_BOOLEAN,
 
59
        'graph-column-visible': (gobject.TYPE_BOOLEAN,
59
60
                                 'Graph column',
60
61
                                 'Show graph column',
61
62
                                 True,
62
 
                                 GObject.PARAM_READWRITE),
 
63
                                 gobject.PARAM_READWRITE),
63
64
 
64
 
        'date-column-visible': (GObject.TYPE_BOOLEAN,
 
65
        'date-column-visible': (gobject.TYPE_BOOLEAN,
65
66
                                 'Date',
66
67
                                 'Show date column',
67
68
                                 False,
68
 
                                 GObject.PARAM_READWRITE),
 
69
                                 gobject.PARAM_READWRITE),
69
70
 
70
 
        'compact': (GObject.TYPE_BOOLEAN,
 
71
        'compact': (gobject.TYPE_BOOLEAN,
71
72
                    'Compact view',
72
73
                    'Break ancestry lines to save space',
73
74
                    True,
74
 
                    GObject.PARAM_CONSTRUCT | GObject.PARAM_READWRITE),
 
75
                    gobject.PARAM_CONSTRUCT | gobject.PARAM_READWRITE),
75
76
 
76
 
        'mainline-only': (GObject.TYPE_BOOLEAN,
 
77
        'mainline-only': (gobject.TYPE_BOOLEAN,
77
78
                    'Mainline only',
78
79
                    'Only show the mainline history.',
79
80
                    False,
80
 
                    GObject.PARAM_CONSTRUCT | GObject.PARAM_READWRITE),
 
81
                    gobject.PARAM_CONSTRUCT | gobject.PARAM_READWRITE),
81
82
 
82
83
    }
83
84
 
84
85
    __gsignals__ = {
85
 
        'revision-selected': (GObject.SignalFlags.RUN_FIRST,
86
 
                              None,
 
86
        'revision-selected': (gobject.SIGNAL_RUN_FIRST,
 
87
                              gobject.TYPE_NONE,
87
88
                              ()),
88
 
        'revision-activated': (GObject.SignalFlags.RUN_FIRST,
89
 
                              None,
90
 
                              (GObject.TYPE_PYOBJECT, GObject.TYPE_PYOBJECT)),
91
 
        'tag-added': (GObject.SignalFlags.RUN_FIRST,
92
 
                              None,
93
 
                              (GObject.TYPE_STRING, GObject.TYPE_STRING)),
94
 
        'refreshed': (GObject.SignalFlags.RUN_FIRST, None,
95
 
                              ())
 
89
        'revision-activated': (gobject.SIGNAL_RUN_FIRST,
 
90
                              gobject.TYPE_NONE,
 
91
                              (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)),
 
92
        'tag-added': (gobject.SIGNAL_RUN_FIRST,
 
93
                              gobject.TYPE_NONE,
 
94
                              (gobject.TYPE_STRING, gobject.TYPE_STRING))
96
95
    }
97
96
 
98
97
    def __init__(self, branch, start, maxnum, compact=True):
105
104
        :param broken_line_length: After how much lines to break 
106
105
                                   branches.
107
106
        """
108
 
        super(TreeView, self).__init__(homogeneous=False, spacing=0)
109
 
 
110
 
        self.progress_widget = ProgressPanel()
111
 
        self.pack_start(self.progress_widget, False, True, 0)
112
 
        if getattr(ui.ui_factory, "set_progress_bar_widget", None) is not None:
113
 
            # We'are using our own ui, let's tell it to use our widget.
114
 
            ui.ui_factory.set_progress_bar_widget(self.progress_widget)
115
 
 
116
 
        self.scrolled_window = Gtk.ScrolledWindow()
117
 
        self.scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
118
 
                                        Gtk.PolicyType.AUTOMATIC)
119
 
        self.scrolled_window.set_shadow_type(Gtk.ShadowType.IN)
 
107
        gtk.VBox.__init__(self, spacing=0)
 
108
 
 
109
        self.scrolled_window = gtk.ScrolledWindow()
 
110
        self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
 
111
                                        gtk.POLICY_AUTOMATIC)
 
112
        self.scrolled_window.set_shadow_type(gtk.SHADOW_IN)
120
113
        self.scrolled_window.show()
121
 
        self.pack_start(self.scrolled_window, True, True, 0)
 
114
        self.pack_start(self.scrolled_window, expand=True, fill=True)
122
115
 
123
116
        self.scrolled_window.add(self.construct_treeview())
124
117
 
125
 
        self.path = None
 
118
        self.iter = None
126
119
        self.branch = branch
127
120
        self.revision = None
128
 
        self.index = {}
129
121
 
130
122
        self.start = start
131
123
        self.maxnum = maxnum
132
124
        self.compact = compact
133
125
 
134
 
        self.model = treemodel.BranchTreeModel(self.branch, [])
135
 
        GObject.idle_add(self.populate)
136
 
 
137
 
        self.connect("destroy", self._on_destroy)
138
 
 
139
 
    def _on_destroy(self, *ignored):
140
 
        self.branch.unlock()
141
 
        if getattr(ui.ui_factory, "set_progress_bar_widget", None) is not None:
142
 
            # We'are using our own ui, let's tell it to stop using our widget.
143
 
            ui.ui_factory.set_progress_bar_widget(None)
 
126
        gobject.idle_add(self.populate)
 
127
 
 
128
        self.connect("destroy", lambda x: self.branch.unlock())
144
129
 
145
130
    def do_get_property(self, property):
146
131
        if property.name == 'revno-column-visible':
156
141
        elif property.name == 'branch':
157
142
            return self.branch
158
143
        elif property.name == 'revision':
159
 
            if self.path is None:
160
 
                return None
161
 
            return self.model.get_value(self.model.get_iter(self.path),
162
 
                                        treemodel.REVISION)
 
144
            return self.model.get_value(self.iter, treemodel.REVISION)
163
145
        elif property.name == 'revision-number':
164
 
            if self.path is None:
165
 
                return None
166
 
            return self.model.get_value(self.model.get_iter(self.path),
167
 
                                        treemodel.REVNO)
 
146
            return self.model.get_value(self.iter, treemodel.REVNO)
168
147
        elif property.name == 'children':
169
 
            if self.path is None:
170
 
                return None
171
 
            return self.model.get_value(self.model.get_iter(self.path),
172
 
                                        treemodel.CHILDREN)
 
148
            return self.model.get_value(self.iter, treemodel.CHILDREN)
173
149
        elif property.name == 'parents':
174
 
            if self.path is None:
175
 
                return None
176
 
            return self.model.get_value(self.model.get_iter(self.path),
177
 
                                        treemodel.PARENTS)
 
150
            return self.model.get_value(self.iter, treemodel.PARENTS)
178
151
        else:
179
152
            raise AttributeError, 'unknown property %s' % property.name
180
153
 
200
173
        """Return revision id of currently selected revision, or None."""
201
174
        return self.get_property('revision')
202
175
 
203
 
    def has_revision_id(self, revision_id):
204
 
        return (revision_id in self.index)
205
 
 
206
176
    def set_revision(self, revision):
207
177
        self.set_property('revision', revision)
208
178
 
211
181
 
212
182
        :param revid: Revision id of revision to display.
213
183
        """
214
 
        self.treeview.set_cursor(
215
 
            Gtk.TreePath(path=self.index[revid]), None, False)
 
184
        self.treeview.set_cursor(self.index[revid])
216
185
        self.treeview.grab_focus()
217
186
 
218
187
    def get_children(self):
232
201
    def add_tag(self, tag, revid=None):
233
202
        if revid is None: revid = self.revision.revision_id
234
203
 
235
 
        if lock.release(self.branch):
 
204
        try:
 
205
            self.branch.unlock()
 
206
 
236
207
            try:
237
 
                lock.acquire(self.branch, lock.WRITE)
 
208
                self.branch.lock_write()
238
209
                self.model.add_tag(tag, revid)
239
210
            finally:
240
 
                lock.release(self.branch)
241
 
 
242
 
            lock.acquire(self.branch, lock.READ)
243
 
 
244
 
            self.emit('tag-added', tag, revid)
245
 
 
 
211
                self.branch.unlock()
 
212
 
 
213
        finally:
 
214
            self.branch.lock_read()
 
215
 
 
216
        self.emit('tag-added', tag, revid)
 
217
        
246
218
    def refresh(self):
247
 
        GObject.idle_add(self.populate, self.get_revision())
 
219
        gobject.idle_add(self.populate, self.get_revision())
248
220
 
249
221
    def update(self):
250
222
        try:
260
232
    def back(self):
261
233
        """Signal handler for the Back button."""
262
234
        parents = self.get_parents()
263
 
        if not parents:
 
235
        if not len(parents):
264
236
            return
265
237
 
266
238
        for parent_id in parents:
275
247
    def forward(self):
276
248
        """Signal handler for the Forward button."""
277
249
        children = self.get_children()
278
 
        if not children:
 
250
        if not len(children):
279
251
            return
280
252
 
281
253
        for child_id in children:
297
269
                       should be broken.
298
270
        """
299
271
 
300
 
        if getattr(ui.ui_factory, "set_progress_bar_widget", None) is not None:
301
 
            # We'are using our own ui, let's tell it to use our widget.
302
 
            ui.ui_factory.set_progress_bar_widget(self.progress_widget)
303
 
        self.progress_bar = ui.ui_factory.nested_progress_bar()
304
 
        self.progress_bar.update("Loading ancestry graph", 0, 5)
 
272
        loading_progress = ui.ui_factory.nested_progress_bar()
 
273
        loading_progress.update(msg="Loading ancestry graph", total=5)
305
274
 
306
275
        try:
307
276
            if self.compact:
308
277
                broken_line_length = 32
309
278
            else:
310
279
                broken_line_length = None
311
 
 
 
280
            
312
281
            show_graph = self.graph_column.get_visible()
313
282
 
314
283
            self.branch.lock_read()
315
 
            (linegraphdata, index, columns_len) = linegraph(
316
 
                self.branch.repository.get_graph(),
317
 
                self.start,
318
 
                self.maxnum, 
319
 
                broken_line_length,
320
 
                show_graph,
321
 
                self.mainline_only,
322
 
                self.progress_bar)
 
284
            (linegraphdata, index, columns_len) = linegraph(self.branch.repository.get_graph(),
 
285
                                                            self.start,
 
286
                                                            self.maxnum, 
 
287
                                                            broken_line_length,
 
288
                                                            show_graph,
 
289
                                                            self.mainline_only,
 
290
                                                            loading_progress)
323
291
 
324
 
            self.model.set_line_graph_data(linegraphdata)
 
292
            self.model = TreeModel(self.branch, linegraphdata)
325
293
            self.graph_cell.columns_len = columns_len
326
 
            width = self.graph_cell.get_preferred_width(self.treeview)[1]
 
294
            width = self.graph_cell.get_size(self.treeview)[2]
327
295
            if width > 500:
328
296
                width = 500
329
 
            elif width == 0:
330
 
                # The get_preferred_width() call got an insane value.
331
 
                width = 200
332
297
            self.graph_column.set_fixed_width(width)
333
298
            self.graph_column.set_max_width(width)
334
299
            self.index = index
335
300
            self.treeview.set_model(self.model)
336
301
 
337
302
            if not revision or revision == NULL_REVISION:
338
 
                self.treeview.set_cursor(Gtk.TreePath(path=0), None, False)
 
303
                self.treeview.set_cursor(0)
339
304
            else:
340
305
                self.set_revision(revision)
341
306
 
342
 
            self.emit('refreshed')
343
307
            return False
344
308
        finally:
345
 
            self.progress_bar.finished()
 
309
            loading_progress.finished()
346
310
 
347
311
    def construct_treeview(self):
348
 
        self.treeview = Gtk.TreeView()
 
312
        self.treeview = gtk.TreeView()
349
313
 
350
314
        self.treeview.set_rules_hint(True)
351
 
        # combined revno/summary interactive search
352
 
        #
353
 
        # the row in a treemodel is considered "matched" if a REVNO *starts*
354
 
        # from the key (that is the key is found in a REVNO at the offset 0)
355
 
        # or if a MESSAGE *contains* the key anywhere (that is, the key is
356
 
        # found case insensitively in a MESSAGE at any offset)
357
 
        def search_equal_func(model, column, key, iter, ignored):
358
 
            return (model.get_value(iter, treemodel.REVNO).find(key) != 0
359
 
                and model.get_value(iter, treemodel.MESSAGE).lower().find(key.lower()) == -1)
360
 
 
361
 
        self.treeview.set_search_equal_func(search_equal_func, None)
362
 
        self.treeview.set_enable_search(True)
363
 
 
364
 
        self.treeview.set_tooltip_column(treemodel.MESSAGE)
365
 
        self.treeview.set_headers_visible(True)
366
 
 
367
 
        self._prev_cursor_path = None
 
315
        self.treeview.set_search_column(treemodel.REVNO)
 
316
        
 
317
        # Fix old PyGTK bug - by JAM
 
318
        set_tooltip = getattr(self.treeview, 'set_tooltip_column', None)
 
319
        if set_tooltip is not None:
 
320
            set_tooltip(treemodel.MESSAGE)
 
321
 
368
322
        self.treeview.connect("cursor-changed",
369
323
                self._on_selection_changed)
370
324
 
378
332
 
379
333
        self.treeview.show()
380
334
 
381
 
        cell = Gtk.CellRendererText()
 
335
        cell = gtk.CellRendererText()
382
336
        cell.set_property("width-chars", 15)
383
 
        cell.set_property("ellipsize", Pango.EllipsizeMode.END)
384
 
        self.revno_column = Gtk.TreeViewColumn("Revision No")
385
 
        self.revno_column.set_resizable(True)
386
 
        self.revno_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
387
 
        self.revno_column.set_fixed_width(
388
 
            cell.get_preferred_width(self.treeview)[1])
389
 
        self.revno_column.pack_start(cell, True)
 
337
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
 
338
        self.revno_column = gtk.TreeViewColumn("Revision No")
 
339
        self.revno_column.set_resizable(False)
 
340
        self.revno_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
 
341
        self.revno_column.set_fixed_width(cell.get_size(self.treeview)[2])
 
342
        self.revno_column.pack_start(cell, expand=True)
390
343
        self.revno_column.add_attribute(cell, "text", treemodel.REVNO)
391
344
        self.treeview.append_column(self.revno_column)
392
345
 
393
346
        self.graph_cell = CellRendererGraph()
394
 
        self.graph_column = Gtk.TreeViewColumn()
395
 
        self.graph_column.set_resizable(True)
396
 
        self.graph_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
397
 
        self.graph_column.pack_start(self.graph_cell, True)
398
 
        self.graph_column.add_attribute(
399
 
            self.graph_cell, "node", treemodel.NODE)
400
 
        self.graph_column.add_attribute(
401
 
            self.graph_cell, "tags", treemodel.TAGS)
402
 
        self.graph_column.add_attribute(
403
 
            self.graph_cell, "in-lines", treemodel.LAST_LINES)
404
 
        self.graph_column.add_attribute(
405
 
            self.graph_cell, "out-lines", treemodel.LINES)
 
347
        self.graph_column = gtk.TreeViewColumn()
 
348
        self.graph_column.set_resizable(False)
 
349
        self.graph_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
 
350
        self.graph_column.pack_start(self.graph_cell, expand=True)
 
351
        self.graph_column.add_attribute(self.graph_cell, "node", treemodel.NODE)
 
352
        self.graph_column.add_attribute(self.graph_cell, "tags", treemodel.TAGS)
 
353
        self.graph_column.add_attribute(self.graph_cell, "in-lines", treemodel.LAST_LINES)
 
354
        self.graph_column.add_attribute(self.graph_cell, "out-lines", treemodel.LINES)
406
355
        self.treeview.append_column(self.graph_column)
407
356
 
408
 
        cell = Gtk.CellRendererText()
 
357
        cell = gtk.CellRendererText()
409
358
        cell.set_property("width-chars", 65)
410
 
        cell.set_property("ellipsize", Pango.EllipsizeMode.END)
411
 
        self.summary_column = Gtk.TreeViewColumn("Summary")
412
 
        self.summary_column.set_resizable(True)
 
359
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
 
360
        self.summary_column = gtk.TreeViewColumn("Summary")
 
361
        self.summary_column.set_resizable(False)
413
362
        self.summary_column.set_expand(True)
414
 
        self.summary_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
415
 
        self.summary_column.set_fixed_width(
416
 
            cell.get_preferred_width(self.treeview)[1])
417
 
        self.summary_column.pack_start(cell, True)
 
363
        self.summary_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
 
364
        self.summary_column.set_fixed_width(cell.get_size(self.treeview)[2])
 
365
        self.summary_column.pack_start(cell, expand=True)
418
366
        self.summary_column.add_attribute(cell, "markup", treemodel.SUMMARY)
419
367
        self.treeview.append_column(self.summary_column)
420
368
 
421
 
        cell = Gtk.CellRendererText()
 
369
        cell = gtk.CellRendererText()
422
370
        cell.set_property("width-chars", 15)
423
 
        cell.set_property("ellipsize", Pango.EllipsizeMode.END)
424
 
        self.authors_column = Gtk.TreeViewColumn("Author(s)")
425
 
        self.authors_column.set_resizable(False)
426
 
        self.authors_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
427
 
        self.authors_column.set_fixed_width(200)
428
 
        self.authors_column.pack_start(cell, True)
429
 
        self.authors_column.add_attribute(cell, "text", treemodel.AUTHORS)
430
 
        self.treeview.append_column(self.authors_column)
 
371
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
 
372
        self.committer_column = gtk.TreeViewColumn("Committer")
 
373
        self.committer_column.set_resizable(False)
 
374
        self.committer_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
 
375
        self.committer_column.set_fixed_width(200)
 
376
        self.committer_column.pack_start(cell, expand=True)
 
377
        self.committer_column.add_attribute(cell, "text", treemodel.COMMITTER)
 
378
        self.treeview.append_column(self.committer_column)
431
379
 
432
 
        cell = Gtk.CellRendererText()
 
380
        cell = gtk.CellRendererText()
433
381
        cell.set_property("width-chars", 20)
434
 
        cell.set_property("ellipsize", Pango.EllipsizeMode.END)
435
 
        self.date_column = Gtk.TreeViewColumn("Date")
 
382
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
 
383
        self.date_column = gtk.TreeViewColumn("Date")
436
384
        self.date_column.set_visible(False)
437
 
        self.date_column.set_resizable(True)
438
 
        self.date_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
 
385
        self.date_column.set_resizable(False)
 
386
        self.date_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
439
387
        self.date_column.set_fixed_width(130)
440
 
        self.date_column.pack_start(cell, True)
 
388
        self.date_column.pack_start(cell, expand=True)
441
389
        self.date_column.add_attribute(cell, "text", treemodel.TIMESTAMP)
442
390
        self.treeview.append_column(self.date_column)
443
 
 
 
391
        
444
392
        return self.treeview
445
393
 
446
394
    def _on_selection_changed(self, treeview):
447
395
        """callback for when the treeview changes."""
448
396
        (path, focus) = treeview.get_cursor()
449
 
        if (path is not None) and (path != self._prev_cursor_path):
450
 
            self._prev_cursor_path = path # avoid emitting twice per click
451
 
            self.path = path
 
397
        if path is not None:
 
398
            self.iter = self.model.get_iter(path)
452
399
            self.emit('revision-selected')
453
400
 
454
401
    def _on_revision_selected(self, widget, event):
455
 
        from bzrlib.plugins.gtk.revisionmenu import RevisionMenu
 
402
        from bzrlib.plugins.gtk.revisionmenu import RevisionPopupMenu
456
403
        if event.button == 3:
457
 
            revs = []
458
 
            rev = self.get_revision()
459
 
            if rev is not None:
460
 
                revs.append(rev.revision_id)
461
 
            menu = RevisionMenu(self.branch.repository, revs, self.branch)
 
404
            menu = RevisionPopupMenu(self.branch.repository, 
 
405
                [self.get_revision().revision_id],
 
406
                self.branch)
462
407
            menu.connect('tag-added', lambda w, t, r: self.add_tag(t, r))
463
 
            menu.popup(None, None, None, None, event.button, event.get_time())
 
408
            menu.popup(None, None, None, event.button, event.get_time())
464
409
 
465
410
    def _on_revision_activated(self, widget, path, col):
466
411
        self.emit('revision-activated', path, col)