/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
1 by Scott James Remnant
Commit the first version of bzrk.
1
"""Branch window.
2
3
This module contains the code to manage the branch information window,
4
which contains both the revision graph and details panes.
5
"""
6
671.2.1 by Vincent Ladeuil
Ensure compatibility with PyGtk-2.8.
7
__copyright__ = "Copyright (c) 2005 Canonical Ltd."
1 by Scott James Remnant
Commit the first version of bzrk.
8
__author__    = "Scott James Remnant <scott@ubuntu.com>"
9
10
11
import gtk
12
450.4.1 by Daniel Schierbeck
Added tag icon to branch history window.
13
from bzrlib.plugins.gtk import icon_path
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
14
from bzrlib.plugins.gtk.branchview import TreeView
338 by Daniel Schierbeck
Added Preferences menu item.
15
from bzrlib.plugins.gtk.preferences import PreferencesWindow
523.3.2 by Jelmer Vernooij
Share same menu for context menu and main menu.
16
from bzrlib.plugins.gtk.revisionmenu import RevisionMenu
17
from bzrlib.plugins.gtk.window import Window
511.6.1 by Jelmer Vernooij
Add Branch/Index option if bzr-search is available.
18
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
19
from bzrlib.config import GlobalConfig
20
from bzrlib.revision import NULL_REVISION
511.6.1 by Jelmer Vernooij
Add Branch/Index option if bzr-search is available.
21
from bzrlib.trace import mutter
1 by Scott James Remnant
Commit the first version of bzrk.
22
724 by Jelmer Vernooij
Fix formatting, imports.
23
298.2.1 by Daniel Schierbeck
Refactored the GTK window code, creating a single base window class that handles keyboard events.
24
class BranchWindow(Window):
1 by Scott James Remnant
Commit the first version of bzrk.
25
    """Branch window.
26
27
    This object represents and manages a single window containing information
28
    for a particular branch.
29
    """
30
452.4.1 by Jelmer Vernooij
Support displaying multiple tips in viz.
31
    def __init__(self, branch, start_revs, maxnum, parent=None):
322 by Jelmer Vernooij
Add docstrings.
32
        """Create a new BranchWindow.
33
34
        :param branch: Branch object for branch to show.
452.4.1 by Jelmer Vernooij
Support displaying multiple tips in viz.
35
        :param start_revs: Revision ids of top revisions.
322 by Jelmer Vernooij
Add docstrings.
36
        :param maxnum: Maximum number of revisions to display, 
37
                       None for no limit.
38
        """
39
298.2.1 by Daniel Schierbeck
Refactored the GTK window code, creating a single base window class that handles keyboard events.
40
        Window.__init__(self, parent=parent)
1 by Scott James Remnant
Commit the first version of bzrk.
41
        self.set_border_width(0)
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
42
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
43
        self.branch      = branch
452.4.1 by Jelmer Vernooij
Support displaying multiple tips in viz.
44
        self.start_revs  = start_revs
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
45
        self.maxnum      = maxnum
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
46
        self.config      = GlobalConfig()
47
48
        if self.config.get_user_option('viz-compact-view') == 'yes':
49
            self.compact_view = True
50
        else:
51
            self.compact_view = False
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
52
630 by Jelmer Vernooij
Use _get_nick(local=True) rather than .nick to get at a branches' nick, since
53
        self.set_title(branch._get_nick(local=True) + " - revision history")
1 by Scott James Remnant
Commit the first version of bzrk.
54
531.7.9 by Scott Scriven
Made vis remember window and panel sizes.
55
        # user-configured window size
531.7.10 by Scott Scriven
Simplified size-loading code. No longer saves identical config every time vis runs.
56
        size = self._load_size('viz-window-size')
57
        if size:
58
            width, height = size
555.2.1 by Jasper Groenewegen
Modify DiffWidget to include a checkbutton to wrap long lines in the diff view
59
        else:
60
            # Use three-quarters of the screen by default
61
            screen = self.get_screen()
62
            monitor = screen.get_monitor_geometry(0)
63
            width = int(monitor.width * 0.75)
64
            height = int(monitor.height * 0.75)
1 by Scott James Remnant
Commit the first version of bzrk.
65
        self.set_default_size(width, height)
531.7.8 by Scott Scriven
Made viz window shrinkable.
66
        self.set_size_request(width/3, height/3)
625.1.8 by Torsten Landschoff
Save widget sizes only when closing the BranchWindow.
67
        self._save_size_on_destroy(self, 'viz-window-size')
1 by Scott James Remnant
Commit the first version of bzrk.
68
69
        # FIXME AndyFitz!
70
        icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
71
        self.set_icon(icon)
72
384 by Daniel Schierbeck
Added accelerator for Next Revision action.
73
        gtk.accel_map_add_entry("<viz>/Go/Next Revision", gtk.keysyms.Up, gtk.gdk.MOD1_MASK)
383 by Daniel Schierbeck
Switched to using symbolic names for keyvals.
74
        gtk.accel_map_add_entry("<viz>/Go/Previous Revision", gtk.keysyms.Down, gtk.gdk.MOD1_MASK)
499.1.1 by Russ Brown
Added Refresh menu option with keyboard shortcut to viz
75
        gtk.accel_map_add_entry("<viz>/View/Refresh", gtk.keysyms.F5, 0)
382 by Daniel Schierbeck
Made accelerator for Previous Revision work.
76
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
77
        self.accel_group = gtk.AccelGroup()
78
        self.add_accel_group(self.accel_group)
79
671.2.1 by Vincent Ladeuil
Ensure compatibility with PyGtk-2.8.
80
        if getattr(gtk.Action, 'set_tool_item_type', None) is not None:
81
            # Not available before PyGtk-2.10
82
            gtk.Action.set_tool_item_type(gtk.MenuToolButton)
388 by Daniel Schierbeck
Switched to using the Previous/Next Revision actions to create tool buttons.
83
385 by Daniel Schierbeck
Created a single action for Previous Revision.
84
        self.prev_rev_action = gtk.Action("prev-rev", "_Previous Revision", "Go to the previous revision", gtk.STOCK_GO_DOWN)
85
        self.prev_rev_action.set_accel_path("<viz>/Go/Previous Revision")
86
        self.prev_rev_action.set_accel_group(self.accel_group)
87
        self.prev_rev_action.connect("activate", self._back_clicked_cb)
88
        self.prev_rev_action.connect_accelerator()
89
386 by Daniel Schierbeck
Created a single action for Next Revision.
90
        self.next_rev_action = gtk.Action("next-rev", "_Next Revision", "Go to the next revision", gtk.STOCK_GO_UP)
91
        self.next_rev_action.set_accel_path("<viz>/Go/Next Revision")
92
        self.next_rev_action.set_accel_group(self.accel_group)
93
        self.next_rev_action.connect("activate", self._fwd_clicked_cb)
94
        self.next_rev_action.connect_accelerator()
95
499.1.1 by Russ Brown
Added Refresh menu option with keyboard shortcut to viz
96
        self.refresh_action = gtk.Action("refresh", "_Refresh", "Refresh view", gtk.STOCK_REFRESH)
97
        self.refresh_action.set_accel_path("<viz>/View/Refresh")
98
        self.refresh_action.set_accel_group(self.accel_group)
99
        self.refresh_action.connect("activate", self._refresh_clicked)
100
        self.refresh_action.connect_accelerator()
101
713.2.1 by Ximin Luo
Add option to use 'bzr viz' with a vertical layout.
102
        self.vbox = self.construct()
1 by Scott James Remnant
Commit the first version of bzrk.
103
625.1.8 by Torsten Landschoff
Save widget sizes only when closing the BranchWindow.
104
    def _save_size_on_destroy(self, widget, config_name):
105
        """Creates a hook that saves the size of widget to config option 
106
           config_name when the window is destroyed/closed."""
107
        def save_size(src):
108
            width, height = widget.allocation.width, widget.allocation.height
109
            value = '%sx%s' % (width, height)
110
            self.config.set_user_option(config_name, value)
111
        self.connect("destroy", save_size)
112
369 by Daniel Schierbeck
Fixed bug with compact view toggling.
113
    def set_revision(self, revid):
114
        self.treeview.set_revision_id(revid)
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
115
1 by Scott James Remnant
Commit the first version of bzrk.
116
    def construct(self):
117
        """Construct the window contents."""
331 by Daniel Schierbeck
Added basic menu bar.
118
        vbox = gtk.VBox(spacing=0)
44 by David Allouche
reorganise branch window
119
        self.add(vbox)
120
713.2.1 by Ximin Luo
Add option to use 'bzr viz' with a vertical layout.
121
        # order is important here
122
        paned = self.construct_paned()
531.7.2 by Scott Scriven
Made 'vis' save/load visibility of its toolbar.
123
        nav = self.construct_navigation()
124
        menubar = self.construct_menubar()
713.2.1 by Ximin Luo
Add option to use 'bzr viz' with a vertical layout.
125
531.7.2 by Scott Scriven
Made 'vis' save/load visibility of its toolbar.
126
        vbox.pack_start(menubar, expand=False, fill=True)
127
        vbox.pack_start(nav, expand=False, fill=True)
713.2.1 by Ximin Luo
Add option to use 'bzr viz' with a vertical layout.
128
        vbox.pack_start(paned, expand=True, fill=True)
129
        vbox.set_focus_child(paned)
44 by David Allouche
reorganise branch window
130
624 by Jelmer Vernooij
Delay registration of signals to prevent problems when signal handlers use not yet constructed widgets.
131
        self.treeview.connect('revision-selected',
132
                self._treeselection_changed_cb)
133
        self.treeview.connect('revision-activated',
134
                self._tree_revision_activated)
135
136
        self.treeview.connect('tag-added', lambda w, t, r: self._update_tags())
44 by David Allouche
reorganise branch window
137
        vbox.show()
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
138
713.2.1 by Ximin Luo
Add option to use 'bzr viz' with a vertical layout.
139
        return vbox
140
141
    def construct_paned(self):
142
        """Construct the main HPaned/VPaned contents."""
143
        if self.config.get_user_option('viz-vertical') == 'True':
144
            self.paned = gtk.HPaned()
145
        else:
146
            self.paned = gtk.VPaned()
147
148
        self.paned.pack1(self.construct_top(), resize=False, shrink=True)
149
        self.paned.pack2(self.construct_bottom(), resize=True, shrink=False)
150
        self.paned.show()
151
152
        return self.paned
153
331 by Daniel Schierbeck
Added basic menu bar.
154
    def construct_menubar(self):
155
        menubar = gtk.MenuBar()
156
157
        file_menu = gtk.Menu()
334 by Daniel Schierbeck
Added icons to menus.
158
        file_menuitem = gtk.MenuItem("_File")
331 by Daniel Schierbeck
Added basic menu bar.
159
        file_menuitem.set_submenu(file_menu)
160
362 by Daniel Schierbeck
Added accel group to File -> Close menu item.
161
        file_menu_close = gtk.ImageMenuItem(gtk.STOCK_CLOSE, self.accel_group)
331 by Daniel Schierbeck
Added basic menu bar.
162
        file_menu_close.connect('activate', lambda x: self.destroy())
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
163
363 by Daniel Schierbeck
Added File -> Quit menu item.
164
        file_menu_quit = gtk.ImageMenuItem(gtk.STOCK_QUIT, self.accel_group)
165
        file_menu_quit.connect('activate', lambda x: gtk.main_quit())
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
166
408 by Daniel Schierbeck
Made the close menu item actually appear when the viz is opened from another window.
167
        if self._parent is not None:
406 by Daniel Schierbeck
Made the viz show the close menu item only if opened from another window.
168
            file_menu.add(file_menu_close)
363 by Daniel Schierbeck
Added File -> Quit menu item.
169
        file_menu.add(file_menu_quit)
331 by Daniel Schierbeck
Added basic menu bar.
170
338 by Daniel Schierbeck
Added Preferences menu item.
171
        edit_menu = gtk.Menu()
172
        edit_menuitem = gtk.MenuItem("_Edit")
173
        edit_menuitem.set_submenu(edit_menu)
174
361 by Daniel Schierbeck
Added branch settings menu item.
175
        edit_menu_branchopts = gtk.MenuItem("Branch Settings")
176
        edit_menu_branchopts.connect('activate', lambda x: PreferencesWindow(self.branch.get_config()).show())
177
407 by Daniel Schierbeck
Renamed Preferences menu item into Global Settings.
178
        edit_menu_globopts = gtk.MenuItem("Global Settings")
179
        edit_menu_globopts.connect('activate', lambda x: PreferencesWindow().show())
338 by Daniel Schierbeck
Added Preferences menu item.
180
361 by Daniel Schierbeck
Added branch settings menu item.
181
        edit_menu.add(edit_menu_branchopts)
407 by Daniel Schierbeck
Renamed Preferences menu item into Global Settings.
182
        edit_menu.add(edit_menu_globopts)
338 by Daniel Schierbeck
Added Preferences menu item.
183
348 by Daniel Schierbeck
Added toggle item for revision number column.
184
        view_menu = gtk.Menu()
185
        view_menuitem = gtk.MenuItem("_View")
186
        view_menuitem.set_submenu(view_menu)
187
499.1.1 by Russ Brown
Added Refresh menu option with keyboard shortcut to viz
188
        view_menu_refresh = self.refresh_action.create_menu_item()
189
        view_menu_refresh.connect('activate', self._refresh_clicked)
190
191
        view_menu.add(view_menu_refresh)
192
        view_menu.add(gtk.SeparatorMenuItem())
193
351 by Daniel Schierbeck
Added option to hide the toolbar.
194
        view_menu_toolbar = gtk.CheckMenuItem("Show Toolbar")
195
        view_menu_toolbar.set_active(True)
531.7.2 by Scott Scriven
Made 'vis' save/load visibility of its toolbar.
196
        if self.config.get_user_option('viz-toolbar-visible') == 'False':
197
            view_menu_toolbar.set_active(False)
198
            self.toolbar.hide()
351 by Daniel Schierbeck
Added option to hide the toolbar.
199
        view_menu_toolbar.connect('toggled', self._toolbar_visibility_changed)
200
370 by Daniel Schierbeck
Moved compact graph toggle to the menubar.
201
        view_menu_compact = gtk.CheckMenuItem("Show Compact Graph")
202
        view_menu_compact.set_active(self.compact_view)
203
        view_menu_compact.connect('activate', self._brokenlines_toggled_cb)
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
204
713.2.1 by Ximin Luo
Add option to use 'bzr viz' with a vertical layout.
205
        view_menu_vertical = gtk.CheckMenuItem("Side-by-side Layout")
206
        view_menu_vertical.set_active(False)
207
        if self.config.get_user_option('viz-vertical') == 'True':
208
            view_menu_vertical.set_active(True)
209
        view_menu_vertical.connect('toggled', self._vertical_layout)
210
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
211
        view_menu_diffs = gtk.CheckMenuItem("Show Diffs")
531.7.12 by Scott Scriven
Made diff panel default to off.
212
        view_menu_diffs.set_active(False)
213
        if self.config.get_user_option('viz-show-diffs') == 'True':
214
            view_menu_diffs.set_active(True)
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
215
        view_menu_diffs.connect('toggled', self._diff_visibility_changed)
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
216
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
217
        view_menu_wide_diffs = gtk.CheckMenuItem("Wide Diffs")
218
        view_menu_wide_diffs.set_active(False)
219
        if self.config.get_user_option('viz-wide-diffs') == 'True':
220
            view_menu_wide_diffs.set_active(True)
221
        view_menu_wide_diffs.connect('toggled', self._diff_placement_changed)
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
222
571 by Jasper Groenewegen
Merge addition of word wrap control to gdiff and visualise windows
223
        view_menu_wrap_diffs = gtk.CheckMenuItem("Wrap _Long Lines in Diffs")
555.2.2 by Jasper Groenewegen
Change from checkbox to menu item in bzr vis, add menu bar + item in gdiff
224
        view_menu_wrap_diffs.set_active(False)
225
        if self.config.get_user_option('viz-wrap-diffs') == 'True':
226
            view_menu_wrap_diffs.set_active(True)
227
        view_menu_wrap_diffs.connect('toggled', self._diff_wrap_changed)
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
228
351 by Daniel Schierbeck
Added option to hide the toolbar.
229
        view_menu.add(view_menu_toolbar)
370 by Daniel Schierbeck
Moved compact graph toggle to the menubar.
230
        view_menu.add(view_menu_compact)
713.2.1 by Ximin Luo
Add option to use 'bzr viz' with a vertical layout.
231
        view_menu.add(view_menu_vertical)
555.2.2 by Jasper Groenewegen
Change from checkbox to menu item in bzr vis, add menu bar + item in gdiff
232
        view_menu.add(gtk.SeparatorMenuItem())
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
233
        view_menu.add(view_menu_diffs)
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
234
        view_menu.add(view_menu_wide_diffs)
555.2.2 by Jasper Groenewegen
Change from checkbox to menu item in bzr vis, add menu bar + item in gdiff
235
        view_menu.add(view_menu_wrap_diffs)
351 by Daniel Schierbeck
Added option to hide the toolbar.
236
        view_menu.add(gtk.SeparatorMenuItem())
358 by Daniel Schierbeck
Generalized the hiding/showing code.
237
452.4.2 by Jelmer Vernooij
Hide revision number column if more than one branch was specified.
238
        self.mnu_show_revno_column = gtk.CheckMenuItem("Show Revision _Number Column")
239
        self.mnu_show_date_column = gtk.CheckMenuItem("Show _Date Column")
240
241
        # Revision numbers are pointless if there are multiple branches
242
        if len(self.start_revs) > 1:
243
            self.mnu_show_revno_column.set_sensitive(False)
244
            self.treeview.set_property('revno-column-visible', False)
245
246
        for (col, name) in [(self.mnu_show_revno_column, "revno"), 
247
                            (self.mnu_show_date_column, "date")]:
358 by Daniel Schierbeck
Generalized the hiding/showing code.
248
            col.set_active(self.treeview.get_property(name + "-column-visible"))
249
            col.connect('toggled', self._col_visibility_changed, name)
250
            view_menu.add(col)
348 by Daniel Schierbeck
Added toggle item for revision number column.
251
331 by Daniel Schierbeck
Added basic menu bar.
252
        go_menu = gtk.Menu()
382 by Daniel Schierbeck
Made accelerator for Previous Revision work.
253
        go_menu.set_accel_group(self.accel_group)
334 by Daniel Schierbeck
Added icons to menus.
254
        go_menuitem = gtk.MenuItem("_Go")
331 by Daniel Schierbeck
Added basic menu bar.
255
        go_menuitem.set_submenu(go_menu)
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
256
390 by Daniel Schierbeck
Made the Previous/Next Revision menu items local variables.
257
        go_menu_next = self.next_rev_action.create_menu_item()
258
        go_menu_prev = self.prev_rev_action.create_menu_item()
334 by Daniel Schierbeck
Added icons to menus.
259
450.4.1 by Daniel Schierbeck
Added tag icon to branch history window.
260
        tag_image = gtk.Image()
261
        tag_image.set_from_file(icon_path("tag-16.png"))
262
        self.go_menu_tags = gtk.ImageMenuItem("_Tags")
263
        self.go_menu_tags.set_image(tag_image)
587 by Jelmer Vernooij
Avoid determining tags until tags widget has been added.
264
        self.treeview.connect('refreshed', lambda w: self._update_tags())
399 by Daniel Schierbeck
Made tags menu insensitive when there are no tags to display.
265
390 by Daniel Schierbeck
Made the Previous/Next Revision menu items local variables.
266
        go_menu.add(go_menu_next)
267
        go_menu.add(go_menu_prev)
334 by Daniel Schierbeck
Added icons to menus.
268
        go_menu.add(gtk.SeparatorMenuItem())
423.7.5 by Daniel Schierbeck
Made the revision history window update the Go->Tags menu when a tag is added.
269
        go_menu.add(self.go_menu_tags)
334 by Daniel Schierbeck
Added icons to menus.
270
713.2.4 by Jelmer Vernooij
Fix some formatting.
271
        self.revision_menu = RevisionMenu(self.branch.repository, [],
272
            self.branch, parent=self)
335 by Daniel Schierbeck
Added Revision menu.
273
        revision_menuitem = gtk.MenuItem("_Revision")
523.3.2 by Jelmer Vernooij
Share same menu for context menu and main menu.
274
        revision_menuitem.set_submenu(self.revision_menu)
335 by Daniel Schierbeck
Added Revision menu.
275
334 by Daniel Schierbeck
Added icons to menus.
276
        branch_menu = gtk.Menu()
277
        branch_menuitem = gtk.MenuItem("_Branch")
278
        branch_menuitem.set_submenu(branch_menu)
279
336 by Daniel Schierbeck
Changed wording to comply with HIG guidelines.
280
        branch_menu.add(gtk.MenuItem("Pu_ll Revisions"))
281
        branch_menu.add(gtk.MenuItem("Pu_sh Revisions"))
371.1.1 by Daniel Schierbeck
Added About dialog to the viz.
282
511.6.1 by Jelmer Vernooij
Add Branch/Index option if bzr-search is available.
283
        try:
284
            from bzrlib.plugins import search
285
        except ImportError:
286
            mutter("Didn't find search plugin")
287
        else:
526 by Jelmer Vernooij
Switch to found revision when clicking ok in search window.
288
            branch_menu.add(gtk.SeparatorMenuItem())
289
511.6.1 by Jelmer Vernooij
Add Branch/Index option if bzr-search is available.
290
            branch_index_menuitem = gtk.MenuItem("_Index")
291
            branch_index_menuitem.connect('activate', self._branch_index_cb)
292
            branch_menu.add(branch_index_menuitem)
293
524 by Jelmer Vernooij
Add search dialog.
294
            branch_search_menuitem = gtk.MenuItem("_Search")
295
            branch_search_menuitem.connect('activate', self._branch_search_cb)
296
            branch_menu.add(branch_search_menuitem)
297
423.9.1 by Daniel Schierbeck
Added Help->About menu item to the viz.
298
        help_menu = gtk.Menu()
299
        help_menuitem = gtk.MenuItem("_Help")
300
        help_menuitem.set_submenu(help_menu)
301
713.2.4 by Jelmer Vernooij
Fix some formatting.
302
        help_about_menuitem = gtk.ImageMenuItem(gtk.STOCK_ABOUT,
303
            self.accel_group)
423.9.1 by Daniel Schierbeck
Added Help->About menu item to the viz.
304
        help_about_menuitem.connect('activate', self._about_dialog_cb)
305
306
        help_menu.add(help_about_menuitem)
307
331 by Daniel Schierbeck
Added basic menu bar.
308
        menubar.add(file_menuitem)
338 by Daniel Schierbeck
Added Preferences menu item.
309
        menubar.add(edit_menuitem)
348 by Daniel Schierbeck
Added toggle item for revision number column.
310
        menubar.add(view_menuitem)
331 by Daniel Schierbeck
Added basic menu bar.
311
        menubar.add(go_menuitem)
335 by Daniel Schierbeck
Added Revision menu.
312
        menubar.add(revision_menuitem)
331 by Daniel Schierbeck
Added basic menu bar.
313
        menubar.add(branch_menuitem)
423.9.1 by Daniel Schierbeck
Added Help->About menu item to the viz.
314
        menubar.add(help_menuitem)
331 by Daniel Schierbeck
Added basic menu bar.
315
        menubar.show_all()
316
317
        return menubar
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
318
319
    def construct_top(self):
320
        """Construct the top-half of the window."""
329 by Jelmer Vernooij
Make broken_line_length setting from higher up.
321
        # FIXME: Make broken_line_length configurable
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
322
713.2.4 by Jelmer Vernooij
Fix some formatting.
323
        self.treeview = TreeView(self.branch, self.start_revs, self.maxnum,
324
            self.compact_view)
423.7.5 by Daniel Schierbeck
Made the revision history window update the Go->Tags menu when a tag is added.
325
373 by Daniel Schierbeck
Made column display options persisted.
326
        for col in ["revno", "date"]:
327
            option = self.config.get_user_option(col + '-column-visible')
328
            if option is not None:
713.2.4 by Jelmer Vernooij
Fix some formatting.
329
                self.treeview.set_property(col + '-column-visible',
330
                    option == 'True')
464.1.1 by Adrian Wilkins
Fixed column visibility properties not loading
331
            else:
332
                self.treeview.set_property(col + '-column-visible', False)
373 by Daniel Schierbeck
Made column display options persisted.
333
1 by Scott James Remnant
Commit the first version of bzrk.
334
        self.treeview.show()
335
375 by Daniel Schierbeck
Fixed crash when toggling compact view.
336
        align = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
337
        align.set_padding(5, 0, 0, 0)
338
        align.add(self.treeview)
531.7.9 by Scott Scriven
Made vis remember window and panel sizes.
339
        # user-configured size
531.7.10 by Scott Scriven
Simplified size-loading code. No longer saves identical config every time vis runs.
340
        size = self._load_size('viz-graph-size')
341
        if size:
342
            width, height = size
531.7.9 by Scott Scriven
Made vis remember window and panel sizes.
343
            align.set_size_request(width, height)
344
        else:
345
            (width, height) = self.get_size()
346
            align.set_size_request(width, int(height / 2.5))
625.1.8 by Torsten Landschoff
Save widget sizes only when closing the BranchWindow.
347
        self._save_size_on_destroy(align, 'viz-graph-size')
375 by Daniel Schierbeck
Fixed crash when toggling compact view.
348
        align.show()
349
350
        return align
44 by David Allouche
reorganise branch window
351
352
    def construct_navigation(self):
353
        """Construct the navigation buttons."""
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
354
        self.toolbar = gtk.Toolbar()
355
        self.toolbar.set_style(gtk.TOOLBAR_BOTH_HORIZ)
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
356
388 by Daniel Schierbeck
Switched to using the Previous/Next Revision actions to create tool buttons.
357
        self.prev_button = self.prev_rev_action.create_tool_item()
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
358
        self.toolbar.insert(self.prev_button, -1)
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
359
388 by Daniel Schierbeck
Switched to using the Previous/Next Revision actions to create tool buttons.
360
        self.next_button = self.next_rev_action.create_tool_item()
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
361
        self.toolbar.insert(self.next_button, -1)
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
362
401.1.2 by Daniel Schierbeck
Allowed the treeview to be refreshed.
363
        self.toolbar.insert(gtk.SeparatorToolItem(), -1)
364
365
        refresh_button = gtk.ToolButton(gtk.STOCK_REFRESH)
404 by Daniel Schierbeck
Made the refresh use proper locking.
366
        refresh_button.connect('clicked', self._refresh_clicked)
401.1.2 by Daniel Schierbeck
Allowed the treeview to be refreshed.
367
        self.toolbar.insert(refresh_button, -1)
368
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
369
        self.toolbar.show_all()
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
370
371
        return self.toolbar
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
372
373
    def construct_bottom(self):
374
        """Construct the bottom half of the window."""
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
375
        if self.config.get_user_option('viz-wide-diffs') == 'True':
376
            self.diff_paned = gtk.VPaned()
377
        else:
378
            self.diff_paned = gtk.HPaned()
531.7.1 by Scott Scriven
Added a diff panel to otherwise-blank area in 'bzr vis'.
379
        (width, height) = self.get_size()
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
380
        self.diff_paned.set_size_request(20, 20) # shrinkable
531.7.1 by Scott Scriven
Added a diff panel to otherwise-blank area in 'bzr vis'.
381
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
382
        from bzrlib.plugins.gtk.revisionview import RevisionView
412.1.2 by Daniel Schierbeck
Moved retrieval of tags into the revisionview itself.
383
        self.revisionview = RevisionView(branch=self.branch)
531.7.1 by Scott Scriven
Added a diff panel to otherwise-blank area in 'bzr vis'.
384
        self.revisionview.set_size_request(width/3, int(height / 2.5))
531.7.9 by Scott Scriven
Made vis remember window and panel sizes.
385
        # user-configured size
531.7.10 by Scott Scriven
Simplified size-loading code. No longer saves identical config every time vis runs.
386
        size = self._load_size('viz-revisionview-size')
387
        if size:
388
            width, height = size
531.7.9 by Scott Scriven
Made vis remember window and panel sizes.
389
            self.revisionview.set_size_request(width, height)
625.1.8 by Torsten Landschoff
Save widget sizes only when closing the BranchWindow.
390
        self._save_size_on_destroy(self.revisionview, 'viz-revisionview-size')
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
391
        self.revisionview.show()
392
        self.revisionview.set_show_callback(self._show_clicked_cb)
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
393
        self.revisionview.connect('notify::revision', self._go_clicked_cb)
713.2.4 by Jelmer Vernooij
Fix some formatting.
394
        self.treeview.connect('tag-added',
395
            lambda w, t, r: self.revisionview.update_tags())
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
396
        self.diff_paned.pack1(self.revisionview)
531.7.1 by Scott Scriven
Added a diff panel to otherwise-blank area in 'bzr vis'.
397
398
        from bzrlib.plugins.gtk.diff import DiffWidget
399
        self.diff = DiffWidget()
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
400
        self.diff_paned.pack2(self.diff)
531.7.1 by Scott Scriven
Added a diff panel to otherwise-blank area in 'bzr vis'.
401
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
402
        self.diff_paned.show_all()
531.7.12 by Scott Scriven
Made diff panel default to off.
403
        if self.config.get_user_option('viz-show-diffs') != 'True':
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
404
            self.diff.hide()
405
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
406
        return self.diff_paned
332 by Daniel Schierbeck
Made tag selection work.
407
408
    def _tag_selected_cb(self, menuitem, revid):
356 by Daniel Schierbeck
Made revision a property on TreeView.
409
        self.treeview.set_revision_id(revid)
341 by Daniel Schierbeck
Merged with trunk.
410
280.1.2 by Daniel Schierbeck
Switched to handle the 'changed' signal from the treeview's treeselection instead of the 'cursor-changed' signal from the treeview itself, allowing more flexibility (particularly the ability to handle programmatic selections)
411
    def _treeselection_changed_cb(self, selection, *args):
303 by Daniel Schierbeck
Made basic signaling work.
412
        """callback for when the treeview changes."""
413
        revision = self.treeview.get_revision()
414
        parents  = self.treeview.get_parents()
415
        children = self.treeview.get_children()
416
523.3.2 by Jelmer Vernooij
Share same menu for context menu and main menu.
417
        self.revision_menu.set_revision_ids([revision.revision_id])
418
464.2.1 by Adrian Wilkins
Detect the reserved null: revision in appropriate places.
419
        if revision and revision != NULL_REVISION:
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
420
            prev_menu = gtk.Menu()
352.1.1 by Daniel Schierbeck
Added dropdown menu to Back button.
421
            if len(parents) > 0:
385 by Daniel Schierbeck
Created a single action for Previous Revision.
422
                self.prev_rev_action.set_sensitive(True)
352.1.1 by Daniel Schierbeck
Added dropdown menu to Back button.
423
                for parent_id in parents:
464.2.1 by Adrian Wilkins
Detect the reserved null: revision in appropriate places.
424
                    if parent_id and parent_id != NULL_REVISION:
425
                        parent = self.branch.repository.get_revision(parent_id)
426
                        try:
713.2.4 by Jelmer Vernooij
Fix some formatting.
427
                            str = ' (%s)' % parent.properties['branch-nick']
464.2.1 by Adrian Wilkins
Detect the reserved null: revision in appropriate places.
428
                        except KeyError:
429
                            str = ""
355 by Daniel Schierbeck
Appended branch nick to parent and child popup menus.
430
464.2.1 by Adrian Wilkins
Detect the reserved null: revision in appropriate places.
431
                        item = gtk.MenuItem(parent.message.split("\n")[0] + str)
432
                        item.connect('activate', self._set_revision_cb, parent_id)
433
                        prev_menu.add(item)
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
434
                prev_menu.show_all()
352.1.1 by Daniel Schierbeck
Added dropdown menu to Back button.
435
            else:
385 by Daniel Schierbeck
Created a single action for Previous Revision.
436
                self.prev_rev_action.set_sensitive(False)
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
437
                prev_menu.hide()
438
671.1.2 by David Roberts
Further consequential changes for PyGtk-2.8
439
            if getattr(self.prev_button, 'set_menu', None) is not None:
724 by Jelmer Vernooij
Fix formatting, imports.
440
                self.prev_button.set_menu(prev_menu)
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
441
442
            next_menu = gtk.Menu()
352.1.2 by Daniel Schierbeck
Added dropdown menu to Forward button.
443
            if len(children) > 0:
386 by Daniel Schierbeck
Created a single action for Next Revision.
444
                self.next_rev_action.set_sensitive(True)
352.1.2 by Daniel Schierbeck
Added dropdown menu to Forward button.
445
                for child_id in children:
446
                    child = self.branch.repository.get_revision(child_id)
355 by Daniel Schierbeck
Appended branch nick to parent and child popup menus.
447
                    try:
713.2.4 by Jelmer Vernooij
Fix some formatting.
448
                        str = ' (%s)' % child.properties['branch-nick']
355 by Daniel Schierbeck
Appended branch nick to parent and child popup menus.
449
                    except KeyError:
450
                        str = ""
451
452
                    item = gtk.MenuItem(child.message.split("\n")[0] + str)
352.1.2 by Daniel Schierbeck
Added dropdown menu to Forward button.
453
                    item.connect('activate', self._set_revision_cb, child_id)
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
454
                    next_menu.add(item)
455
                next_menu.show_all()
352.1.2 by Daniel Schierbeck
Added dropdown menu to Forward button.
456
            else:
386 by Daniel Schierbeck
Created a single action for Next Revision.
457
                self.next_rev_action.set_sensitive(False)
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
458
                next_menu.hide()
352.1.2 by Daniel Schierbeck
Added dropdown menu to Forward button.
459
671.1.2 by David Roberts
Further consequential changes for PyGtk-2.8
460
            if getattr(self.next_button, 'set_menu', None) is not None:
724 by Jelmer Vernooij
Fix formatting, imports.
461
                self.next_button.set_menu(next_menu)
352.1.2 by Daniel Schierbeck
Added dropdown menu to Forward button.
462
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
463
            self.revisionview.set_revision(revision)
464
            self.revisionview.set_children(children)
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
465
            self.update_diff_panel(revision, parents)
531.7.1 by Scott Scriven
Added a diff panel to otherwise-blank area in 'bzr vis'.
466
423.1.17 by Gary van der Merwe
Reuse the viz treeview in the revision browser.
467
    def _tree_revision_activated(self, widget, path, col):
468
        # TODO: more than one parent
469
        """Callback for when a treeview row gets activated."""
470
        revision = self.treeview.get_revision()
471
        parents  = self.treeview.get_parents()
472
473
        if len(parents) == 0:
627 by Jelmer Vernooij
Use NULL_REVISION rather than None.
474
            parent_id = NULL_REVISION
423.1.17 by Gary van der Merwe
Reuse the viz treeview in the revision browser.
475
        else:
476
            parent_id = parents[0]
477
478
        self.show_diff(revision.revision_id, parent_id)
479
        self.treeview.grab_focus()
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
480
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
481
    def _back_clicked_cb(self, *args):
482
        """Callback for when the back button is clicked."""
304 by Daniel Schierbeck
Made forward/back buttons work again.
483
        self.treeview.back()
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
484
5 by Scott James Remnant
Reverse the meaning of the Back and Forward buttons so Back actually
485
    def _fwd_clicked_cb(self, *args):
486
        """Callback for when the forward button is clicked."""
304 by Daniel Schierbeck
Made forward/back buttons work again.
487
        self.treeview.forward()
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
488
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
489
    def _go_clicked_cb(self, w, p):
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
490
        """Callback for when the go button for a parent is clicked."""
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
491
        if self.revisionview.get_revision() is not None:
492
            self.treeview.set_revision(self.revisionview.get_revision())
152 by Jelmer Vernooij
Cleanup some more code.
493
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
494
    def _show_clicked_cb(self, revid, parentid):
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
495
        """Callback for when the show button for a parent is clicked."""
423.1.17 by Gary van der Merwe
Reuse the viz treeview in the revision browser.
496
        self.show_diff(revid, parentid)
13 by Scott James Remnant
Keep the focus on the treeview
497
        self.treeview.grab_focus()
46 by Wouter van Heyst
show diff on row activation, LP# 44591
498
352.1.1 by Daniel Schierbeck
Added dropdown menu to Back button.
499
    def _set_revision_cb(self, w, revision_id):
356 by Daniel Schierbeck
Made revision a property on TreeView.
500
        self.treeview.set_revision_id(revision_id)
352.1.1 by Daniel Schierbeck
Added dropdown menu to Back button.
501
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
502
    def _brokenlines_toggled_cb(self, button):
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
503
        self.compact_view = button.get_active()
504
505
        if self.compact_view:
506
            option = 'yes'
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
507
        else:
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
508
            option = 'no'
509
510
        self.config.set_user_option('viz-compact-view', option)
401.1.3 by Daniel Schierbeck
Made the compact view toggling cleaner.
511
        self.treeview.set_property('compact', self.compact_view)
512
        self.treeview.refresh()
368 by Daniel Schierbeck
Merged with mainline.
513
511.6.1 by Jelmer Vernooij
Add Branch/Index option if bzr-search is available.
514
    def _branch_index_cb(self, w):
515
        from bzrlib.plugins.search import index as _mod_index
516
        _mod_index.index_url(self.branch.base)
517
524 by Jelmer Vernooij
Add search dialog.
518
    def _branch_search_cb(self, w):
713.2.4 by Jelmer Vernooij
Fix some formatting.
519
        from bzrlib.plugins.search import (
520
            index as _mod_index,
521
            errors as search_errors,
522
            )
524 by Jelmer Vernooij
Add search dialog.
523
        from bzrlib.plugins.gtk.search import SearchDialog
533.11.1 by Jelmer Vernooij
Ask user whether to index if there is no index present yet.
524
525
        try:
526
            index = _mod_index.open_index_url(self.branch.base)
527
        except search_errors.NoSearchIndex:
528
            dialog = gtk.MessageDialog(self, type=gtk.MESSAGE_QUESTION, 
529
                buttons=gtk.BUTTONS_OK_CANCEL, 
530
                message_format="This branch has not been indexed yet. "
531
                               "Index now?")
532
            if dialog.run() == gtk.RESPONSE_OK:
553 by Jelmer Vernooij
Merge asking the user whether to create an index.
533
                dialog.destroy()
533.11.1 by Jelmer Vernooij
Ask user whether to index if there is no index present yet.
534
                index = _mod_index.index_url(self.branch.base)
535
            else:
553 by Jelmer Vernooij
Merge asking the user whether to create an index.
536
                dialog.destroy()
533.11.1 by Jelmer Vernooij
Ask user whether to index if there is no index present yet.
537
                return
538
539
        dialog = SearchDialog(index)
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
540
526 by Jelmer Vernooij
Switch to found revision when clicking ok in search window.
541
        if dialog.run() == gtk.RESPONSE_OK:
542
            self.set_revision(dialog.get_revision())
543
544
        dialog.destroy()
524 by Jelmer Vernooij
Add search dialog.
545
423.9.1 by Daniel Schierbeck
Added Help->About menu item to the viz.
546
    def _about_dialog_cb(self, w):
547
        from bzrlib.plugins.gtk.about import AboutDialog
548
        AboutDialog().run()
549
348 by Daniel Schierbeck
Added toggle item for revision number column.
550
    def _col_visibility_changed(self, col, property):
373 by Daniel Schierbeck
Made column display options persisted.
551
        self.config.set_user_option(property + '-column-visible', col.get_active())
348 by Daniel Schierbeck
Added toggle item for revision number column.
552
        self.treeview.set_property(property + '-column-visible', col.get_active())
351 by Daniel Schierbeck
Added option to hide the toolbar.
553
554
    def _toolbar_visibility_changed(self, col):
555
        if col.get_active():
531.7.2 by Scott Scriven
Made 'vis' save/load visibility of its toolbar.
556
            self.toolbar.show()
351 by Daniel Schierbeck
Added option to hide the toolbar.
557
        else:
558
            self.toolbar.hide()
531.7.2 by Scott Scriven
Made 'vis' save/load visibility of its toolbar.
559
        self.config.set_user_option('viz-toolbar-visible', col.get_active())
371.1.1 by Daniel Schierbeck
Added About dialog to the viz.
560
713.2.1 by Ximin Luo
Add option to use 'bzr viz' with a vertical layout.
561
    def _vertical_layout(self, col):
562
        """Toggle the layout vertical/horizontal"""
563
        self.config.set_user_option('viz-vertical', str(col.get_active()))
564
565
        old = self.paned
566
        self.vbox.remove(old)
567
        self.vbox.pack_start(self.construct_paned(), expand=True, fill=True)
568
        self._make_diff_paned_nonzero_size()
569
        self._make_diff_nonzero_size()
570
571
        self.treeview.emit('revision-selected')
572
573
    def _make_diff_paned_nonzero_size(self):
574
        """make sure the diff/revision pane isn't zero-width or zero-height"""
575
        alloc = self.diff_paned.get_allocation()
576
        if (alloc.width < 10) or (alloc.height < 10):
577
            width, height = self.get_size()
578
            self.diff_paned.set_size_request(width/3, int(height / 2.5))
579
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
580
    def _make_diff_nonzero_size(self):
581
        """make sure the diff isn't zero-width or zero-height"""
582
        alloc = self.diff.get_allocation()
583
        if (alloc.width < 10) or (alloc.height < 10):
584
            width, height = self.get_size()
585
            self.revisionview.set_size_request(width/3, int(height / 2.5))
586
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
587
    def _diff_visibility_changed(self, col):
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
588
        """Hide or show the diff panel."""
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
589
        if col.get_active():
590
            self.diff.show()
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
591
            self._make_diff_nonzero_size()
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
592
        else:
593
            self.diff.hide()
594
        self.config.set_user_option('viz-show-diffs', str(col.get_active()))
595
        self.update_diff_panel()
596
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
597
    def _diff_placement_changed(self, col):
598
        """Toggle the diff panel's position."""
599
        self.config.set_user_option('viz-wide-diffs', str(col.get_active()))
600
601
        old = self.paned.get_child2()
602
        self.paned.remove(old)
603
        self.paned.pack2(self.construct_bottom(), resize=True, shrink=False)
604
        self._make_diff_nonzero_size()
605
606
        self.treeview.emit('revision-selected')
713 by Jelmer Vernooij
Remove some unused imports, fix some formatting.
607
555.2.2 by Jasper Groenewegen
Change from checkbox to menu item in bzr vis, add menu bar + item in gdiff
608
    def _diff_wrap_changed(self, widget):
609
        """Toggle word wrap in the diff widget."""
610
        self.config.set_user_option('viz-wrap-diffs', widget.get_active())
611
        self.diff._on_wraplines_toggled(widget)
404 by Daniel Schierbeck
Made the refresh use proper locking.
612
613
    def _refresh_clicked(self, w):
423.1.13 by Gary van der Merwe
Move viz loading msg from branchwin to treeview.
614
        self.treeview.refresh()
423.7.5 by Daniel Schierbeck
Made the revision history window update the Go->Tags menu when a tag is added.
615
616
    def _update_tags(self):
617
        menu = gtk.Menu()
618
619
        if self.branch.supports_tags():
620
            tags = self.branch.tags.get_tag_dict().items()
576.5.1 by Jelmer Vernooij
Disable the ability to click on tags that are not available in the current view.
621
            tags.sort(reverse=True)
423.7.5 by Daniel Schierbeck
Made the revision history window update the Go->Tags menu when a tag is added.
622
            for tag, revid in tags:
450.4.1 by Daniel Schierbeck
Added tag icon to branch history window.
623
                tag_image = gtk.Image()
624
                tag_image.set_from_file(icon_path('tag-16.png'))
625
                tag_item = gtk.ImageMenuItem(tag.replace('_', '__'))
626
                tag_item.set_image(tag_image)
423.7.5 by Daniel Schierbeck
Made the revision history window update the Go->Tags menu when a tag is added.
627
                tag_item.connect('activate', self._tag_selected_cb, revid)
576.5.1 by Jelmer Vernooij
Disable the ability to click on tags that are not available in the current view.
628
                tag_item.set_sensitive(self.treeview.has_revision_id(revid))
423.7.5 by Daniel Schierbeck
Made the revision history window update the Go->Tags menu when a tag is added.
629
                menu.add(tag_item)
630
            self.go_menu_tags.set_submenu(menu)
631
632
            self.go_menu_tags.set_sensitive(len(tags) != 0)
633
        else:
634
            self.go_menu_tags.set_sensitive(False)
635
636
        self.go_menu_tags.show_all()
637
531.7.10 by Scott Scriven
Simplified size-loading code. No longer saves identical config every time vis runs.
638
    def _load_size(self, name):
639
        """Read and parse 'name' from self.config.
640
        The value is a string, formatted as WIDTHxHEIGHT
641
        Returns None, or (width, height)
642
        """
643
        size = self.config.get_user_option(name)
644
        if size:
645
            width, height = [int(num) for num in size.split('x')]
646
            # avoid writing config every time we start
647
            return width, height
648
        return None
649
627 by Jelmer Vernooij
Use NULL_REVISION rather than None.
650
    def show_diff(self, revid=None, parentid=NULL_REVISION):
423.1.17 by Gary van der Merwe
Reuse the viz treeview in the revision browser.
651
        """Open a new window to show a diff between the given revisions."""
652
        from bzrlib.plugins.gtk.diff import DiffWindow
653
        window = DiffWindow(parent=self)
654
655
        rev_tree    = self.branch.repository.revision_tree(revid)
656
        parent_tree = self.branch.repository.revision_tree(parentid)
657
630 by Jelmer Vernooij
Use _get_nick(local=True) rather than .nick to get at a branches' nick, since
658
        description = revid + " - " + self.branch._get_nick(local=True)
423.1.17 by Gary van der Merwe
Reuse the viz treeview in the revision browser.
659
        window.set_diff(description, rev_tree, parent_tree)
660
        window.show()
661
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
662
    def update_diff_panel(self, revision=None, parents=None):
663
        """Show the current revision in the diff panel."""
531.7.12 by Scott Scriven
Made diff panel default to off.
664
        if self.config.get_user_option('viz-show-diffs') != 'True':
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
665
            return
666
667
        if not revision: # default to selected row
668
            revision = self.treeview.get_revision()
627 by Jelmer Vernooij
Use NULL_REVISION rather than None.
669
        if revision == NULL_REVISION:
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
670
            return
671
672
        if not parents: # default to selected row's parents
673
            parents  = self.treeview.get_parents()
674
        if len(parents) == 0:
627 by Jelmer Vernooij
Use NULL_REVISION rather than None.
675
            parent_id = NULL_REVISION
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
676
        else:
677
            parent_id = parents[0]
678
679
        rev_tree    = self.branch.repository.revision_tree(revision.revision_id)
680
        parent_tree = self.branch.repository.revision_tree(parent_id)
531.7.5 by Scott Scriven
Fixed DiffWidget so more than one call to set_diff() will work.
681
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
682
        self.diff.set_diff(rev_tree, parent_tree)
555.2.2 by Jasper Groenewegen
Change from checkbox to menu item in bzr vis, add menu bar + item in gdiff
683
        if self.config.get_user_option('viz-wrap-diffs') == 'True':
684
            self.diff._on_wraplines_toggled(wrap=True)
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
685
        self.diff.show_all()