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