/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
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
189
        view_menu_wide_diffs = gtk.CheckMenuItem("Wide Diffs")
190
        view_menu_wide_diffs.set_active(False)
191
        if self.config.get_user_option('viz-wide-diffs') == 'True':
192
            view_menu_wide_diffs.set_active(True)
193
        view_menu_wide_diffs.connect('toggled', self._diff_placement_changed)
194
351 by Daniel Schierbeck
Added option to hide the toolbar.
195
        view_menu.add(view_menu_toolbar)
370 by Daniel Schierbeck
Moved compact graph toggle to the menubar.
196
        view_menu.add(view_menu_compact)
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
197
        view_menu.add(view_menu_diffs)
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
198
        view_menu.add(view_menu_wide_diffs)
351 by Daniel Schierbeck
Added option to hide the toolbar.
199
        view_menu.add(gtk.SeparatorMenuItem())
358 by Daniel Schierbeck
Generalized the hiding/showing code.
200
452.4.2 by Jelmer Vernooij
Hide revision number column if more than one branch was specified.
201
        self.mnu_show_revno_column = gtk.CheckMenuItem("Show Revision _Number Column")
202
        self.mnu_show_date_column = gtk.CheckMenuItem("Show _Date Column")
203
204
        # Revision numbers are pointless if there are multiple branches
205
        if len(self.start_revs) > 1:
206
            self.mnu_show_revno_column.set_sensitive(False)
207
            self.treeview.set_property('revno-column-visible', False)
208
209
        for (col, name) in [(self.mnu_show_revno_column, "revno"), 
210
                            (self.mnu_show_date_column, "date")]:
358 by Daniel Schierbeck
Generalized the hiding/showing code.
211
            col.set_active(self.treeview.get_property(name + "-column-visible"))
212
            col.connect('toggled', self._col_visibility_changed, name)
213
            view_menu.add(col)
348 by Daniel Schierbeck
Added toggle item for revision number column.
214
331 by Daniel Schierbeck
Added basic menu bar.
215
        go_menu = gtk.Menu()
382 by Daniel Schierbeck
Made accelerator for Previous Revision work.
216
        go_menu.set_accel_group(self.accel_group)
334 by Daniel Schierbeck
Added icons to menus.
217
        go_menuitem = gtk.MenuItem("_Go")
331 by Daniel Schierbeck
Added basic menu bar.
218
        go_menuitem.set_submenu(go_menu)
219
        
390 by Daniel Schierbeck
Made the Previous/Next Revision menu items local variables.
220
        go_menu_next = self.next_rev_action.create_menu_item()
221
        go_menu_prev = self.prev_rev_action.create_menu_item()
334 by Daniel Schierbeck
Added icons to menus.
222
450.4.1 by Daniel Schierbeck
Added tag icon to branch history window.
223
        tag_image = gtk.Image()
224
        tag_image.set_from_file(icon_path("tag-16.png"))
225
        self.go_menu_tags = gtk.ImageMenuItem("_Tags")
226
        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.
227
        self._update_tags()
399 by Daniel Schierbeck
Made tags menu insensitive when there are no tags to display.
228
390 by Daniel Schierbeck
Made the Previous/Next Revision menu items local variables.
229
        go_menu.add(go_menu_next)
230
        go_menu.add(go_menu_prev)
334 by Daniel Schierbeck
Added icons to menus.
231
        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.
232
        go_menu.add(self.go_menu_tags)
334 by Daniel Schierbeck
Added icons to menus.
233
523.3.2 by Jelmer Vernooij
Share same menu for context menu and main menu.
234
        self.revision_menu = RevisionMenu(self.branch.repository, [], self.branch, parent=self)
335 by Daniel Schierbeck
Added Revision menu.
235
        revision_menuitem = gtk.MenuItem("_Revision")
523.3.2 by Jelmer Vernooij
Share same menu for context menu and main menu.
236
        revision_menuitem.set_submenu(self.revision_menu)
335 by Daniel Schierbeck
Added Revision menu.
237
334 by Daniel Schierbeck
Added icons to menus.
238
        branch_menu = gtk.Menu()
239
        branch_menuitem = gtk.MenuItem("_Branch")
240
        branch_menuitem.set_submenu(branch_menu)
241
336 by Daniel Schierbeck
Changed wording to comply with HIG guidelines.
242
        branch_menu.add(gtk.MenuItem("Pu_ll Revisions"))
243
        branch_menu.add(gtk.MenuItem("Pu_sh Revisions"))
371.1.1 by Daniel Schierbeck
Added About dialog to the viz.
244
511.6.1 by Jelmer Vernooij
Add Branch/Index option if bzr-search is available.
245
        try:
246
            from bzrlib.plugins import search
247
        except ImportError:
248
            mutter("Didn't find search plugin")
249
        else:
526 by Jelmer Vernooij
Switch to found revision when clicking ok in search window.
250
            branch_menu.add(gtk.SeparatorMenuItem())
251
511.6.1 by Jelmer Vernooij
Add Branch/Index option if bzr-search is available.
252
            branch_index_menuitem = gtk.MenuItem("_Index")
253
            branch_index_menuitem.connect('activate', self._branch_index_cb)
254
            branch_menu.add(branch_index_menuitem)
255
524 by Jelmer Vernooij
Add search dialog.
256
            branch_search_menuitem = gtk.MenuItem("_Search")
257
            branch_search_menuitem.connect('activate', self._branch_search_cb)
258
            branch_menu.add(branch_search_menuitem)
259
423.9.1 by Daniel Schierbeck
Added Help->About menu item to the viz.
260
        help_menu = gtk.Menu()
261
        help_menuitem = gtk.MenuItem("_Help")
262
        help_menuitem.set_submenu(help_menu)
263
264
        help_about_menuitem = gtk.ImageMenuItem(gtk.STOCK_ABOUT, self.accel_group)
265
        help_about_menuitem.connect('activate', self._about_dialog_cb)
266
267
        help_menu.add(help_about_menuitem)
268
331 by Daniel Schierbeck
Added basic menu bar.
269
        menubar.add(file_menuitem)
338 by Daniel Schierbeck
Added Preferences menu item.
270
        menubar.add(edit_menuitem)
348 by Daniel Schierbeck
Added toggle item for revision number column.
271
        menubar.add(view_menuitem)
331 by Daniel Schierbeck
Added basic menu bar.
272
        menubar.add(go_menuitem)
335 by Daniel Schierbeck
Added Revision menu.
273
        menubar.add(revision_menuitem)
331 by Daniel Schierbeck
Added basic menu bar.
274
        menubar.add(branch_menuitem)
423.9.1 by Daniel Schierbeck
Added Help->About menu item to the viz.
275
        menubar.add(help_menuitem)
331 by Daniel Schierbeck
Added basic menu bar.
276
        menubar.show_all()
277
278
        return menubar
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
279
280
    def construct_top(self):
281
        """Construct the top-half of the window."""
329 by Jelmer Vernooij
Make broken_line_length setting from higher up.
282
        # FIXME: Make broken_line_length configurable
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
283
452.4.1 by Jelmer Vernooij
Support displaying multiple tips in viz.
284
        self.treeview = TreeView(self.branch, self.start_revs, self.maxnum, self.compact_view)
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
285
373 by Daniel Schierbeck
Made column display options persisted.
286
        self.treeview.connect('revision-selected',
303 by Daniel Schierbeck
Made basic signaling work.
287
                self._treeselection_changed_cb)
423.1.17 by Gary van der Merwe
Reuse the viz treeview in the revision browser.
288
        self.treeview.connect('revision-activated',
289
                self._tree_revision_activated)
303 by Daniel Schierbeck
Made basic signaling work.
290
423.7.5 by Daniel Schierbeck
Made the revision history window update the Go->Tags menu when a tag is added.
291
        self.treeview.connect('tag-added', lambda w, t, r: self._update_tags())
292
373 by Daniel Schierbeck
Made column display options persisted.
293
        for col in ["revno", "date"]:
294
            option = self.config.get_user_option(col + '-column-visible')
295
            if option is not None:
296
                self.treeview.set_property(col + '-column-visible', option == 'True')
464.1.1 by Adrian Wilkins
Fixed column visibility properties not loading
297
            else:
298
                self.treeview.set_property(col + '-column-visible', False)
373 by Daniel Schierbeck
Made column display options persisted.
299
1 by Scott James Remnant
Commit the first version of bzrk.
300
        self.treeview.show()
301
375 by Daniel Schierbeck
Fixed crash when toggling compact view.
302
        align = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
303
        align.set_padding(5, 0, 0, 0)
304
        align.add(self.treeview)
531.7.9 by Scott Scriven
Made vis remember window and panel sizes.
305
        # user-configured size
531.7.10 by Scott Scriven
Simplified size-loading code. No longer saves identical config every time vis runs.
306
        size = self._load_size('viz-graph-size')
307
        if size:
308
            width, height = size
531.7.9 by Scott Scriven
Made vis remember window and panel sizes.
309
            align.set_size_request(width, height)
310
        else:
311
            (width, height) = self.get_size()
312
            align.set_size_request(width, int(height / 2.5))
313
        align.connect('size-allocate', self._on_size_allocate, 'viz-graph-size')
375 by Daniel Schierbeck
Fixed crash when toggling compact view.
314
        align.show()
315
316
        return align
44 by David Allouche
reorganise branch window
317
318
    def construct_navigation(self):
319
        """Construct the navigation buttons."""
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
320
        self.toolbar = gtk.Toolbar()
321
        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
322
388 by Daniel Schierbeck
Switched to using the Previous/Next Revision actions to create tool buttons.
323
        self.prev_button = self.prev_rev_action.create_tool_item()
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
324
        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
325
388 by Daniel Schierbeck
Switched to using the Previous/Next Revision actions to create tool buttons.
326
        self.next_button = self.next_rev_action.create_tool_item()
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
327
        self.toolbar.insert(self.next_button, -1)
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
328
401.1.2 by Daniel Schierbeck
Allowed the treeview to be refreshed.
329
        self.toolbar.insert(gtk.SeparatorToolItem(), -1)
330
331
        refresh_button = gtk.ToolButton(gtk.STOCK_REFRESH)
404 by Daniel Schierbeck
Made the refresh use proper locking.
332
        refresh_button.connect('clicked', self._refresh_clicked)
401.1.2 by Daniel Schierbeck
Allowed the treeview to be refreshed.
333
        self.toolbar.insert(refresh_button, -1)
334
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
335
        self.toolbar.show_all()
325 by Daniel Schierbeck
Switched to using a real toolbar for the viz navigation.
336
337
        return self.toolbar
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
338
339
    def construct_bottom(self):
340
        """Construct the bottom half of the window."""
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
341
        if self.config.get_user_option('viz-wide-diffs') == 'True':
342
            self.diff_paned = gtk.VPaned()
343
        else:
344
            self.diff_paned = gtk.HPaned()
531.7.1 by Scott Scriven
Added a diff panel to otherwise-blank area in 'bzr vis'.
345
        (width, height) = self.get_size()
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
346
        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'.
347
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
348
        from bzrlib.plugins.gtk.revisionview import RevisionView
412.1.2 by Daniel Schierbeck
Moved retrieval of tags into the revisionview itself.
349
        self.revisionview = RevisionView(branch=self.branch)
531.7.1 by Scott Scriven
Added a diff panel to otherwise-blank area in 'bzr vis'.
350
        self.revisionview.set_size_request(width/3, int(height / 2.5))
531.7.9 by Scott Scriven
Made vis remember window and panel sizes.
351
        # user-configured size
531.7.10 by Scott Scriven
Simplified size-loading code. No longer saves identical config every time vis runs.
352
        size = self._load_size('viz-revisionview-size')
353
        if size:
354
            width, height = size
531.7.9 by Scott Scriven
Made vis remember window and panel sizes.
355
            self.revisionview.set_size_request(width, height)
356
        self.revisionview.connect('size-allocate', self._on_size_allocate, 'viz-revisionview-size')
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
357
        self.revisionview.show()
358
        self.revisionview.set_show_callback(self._show_clicked_cb)
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
359
        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.
360
        self.treeview.connect('tag-added', lambda w, t, r: self.revisionview.update_tags())
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
361
        self.diff_paned.pack1(self.revisionview)
531.7.1 by Scott Scriven
Added a diff panel to otherwise-blank area in 'bzr vis'.
362
363
        from bzrlib.plugins.gtk.diff import DiffWidget
364
        self.diff = DiffWidget()
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
365
        self.diff_paned.pack2(self.diff)
531.7.1 by Scott Scriven
Added a diff panel to otherwise-blank area in 'bzr vis'.
366
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
367
        self.diff_paned.show_all()
531.7.12 by Scott Scriven
Made diff panel default to off.
368
        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.
369
            self.diff.hide()
370
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
371
        return self.diff_paned
332 by Daniel Schierbeck
Made tag selection work.
372
373
    def _tag_selected_cb(self, menuitem, revid):
356 by Daniel Schierbeck
Made revision a property on TreeView.
374
        self.treeview.set_revision_id(revid)
341 by Daniel Schierbeck
Merged with trunk.
375
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)
376
    def _treeselection_changed_cb(self, selection, *args):
303 by Daniel Schierbeck
Made basic signaling work.
377
        """callback for when the treeview changes."""
378
        revision = self.treeview.get_revision()
379
        parents  = self.treeview.get_parents()
380
        children = self.treeview.get_children()
381
523.3.2 by Jelmer Vernooij
Share same menu for context menu and main menu.
382
        self.revision_menu.set_revision_ids([revision.revision_id])
383
464.2.1 by Adrian Wilkins
Detect the reserved null: revision in appropriate places.
384
        if revision and revision != NULL_REVISION:
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
385
            prev_menu = gtk.Menu()
352.1.1 by Daniel Schierbeck
Added dropdown menu to Back button.
386
            if len(parents) > 0:
385 by Daniel Schierbeck
Created a single action for Previous Revision.
387
                self.prev_rev_action.set_sensitive(True)
352.1.1 by Daniel Schierbeck
Added dropdown menu to Back button.
388
                for parent_id in parents:
464.2.1 by Adrian Wilkins
Detect the reserved null: revision in appropriate places.
389
                    if parent_id and parent_id != NULL_REVISION:
390
                        parent = self.branch.repository.get_revision(parent_id)
391
                        try:
392
                            str = ' (' + parent.properties['branch-nick'] + ')'
393
                        except KeyError:
394
                            str = ""
355 by Daniel Schierbeck
Appended branch nick to parent and child popup menus.
395
464.2.1 by Adrian Wilkins
Detect the reserved null: revision in appropriate places.
396
                        item = gtk.MenuItem(parent.message.split("\n")[0] + str)
397
                        item.connect('activate', self._set_revision_cb, parent_id)
398
                        prev_menu.add(item)
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
399
                prev_menu.show_all()
352.1.1 by Daniel Schierbeck
Added dropdown menu to Back button.
400
            else:
385 by Daniel Schierbeck
Created a single action for Previous Revision.
401
                self.prev_rev_action.set_sensitive(False)
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
402
                prev_menu.hide()
403
404
            self.prev_button.set_menu(prev_menu)
405
406
            next_menu = gtk.Menu()
352.1.2 by Daniel Schierbeck
Added dropdown menu to Forward button.
407
            if len(children) > 0:
386 by Daniel Schierbeck
Created a single action for Next Revision.
408
                self.next_rev_action.set_sensitive(True)
352.1.2 by Daniel Schierbeck
Added dropdown menu to Forward button.
409
                for child_id in children:
410
                    child = self.branch.repository.get_revision(child_id)
355 by Daniel Schierbeck
Appended branch nick to parent and child popup menus.
411
                    try:
412
                        str = ' (' + child.properties['branch-nick'] + ')'
413
                    except KeyError:
414
                        str = ""
415
416
                    item = gtk.MenuItem(child.message.split("\n")[0] + str)
352.1.2 by Daniel Schierbeck
Added dropdown menu to Forward button.
417
                    item.connect('activate', self._set_revision_cb, child_id)
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
418
                    next_menu.add(item)
419
                next_menu.show_all()
352.1.2 by Daniel Schierbeck
Added dropdown menu to Forward button.
420
            else:
386 by Daniel Schierbeck
Created a single action for Next Revision.
421
                self.next_rev_action.set_sensitive(False)
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
422
                next_menu.hide()
352.1.2 by Daniel Schierbeck
Added dropdown menu to Forward button.
423
376 by Daniel Schierbeck
Changed 'back' into 'prev' and 'fwd' into 'next'.
424
            self.next_button.set_menu(next_menu)
352.1.2 by Daniel Schierbeck
Added dropdown menu to Forward button.
425
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
426
            self.revisionview.set_revision(revision)
427
            self.revisionview.set_children(children)
531.7.1 by Scott Scriven
Added a diff panel to otherwise-blank area in 'bzr vis'.
428
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
429
            self.update_diff_panel(revision, parents)
531.7.1 by Scott Scriven
Added a diff panel to otherwise-blank area in 'bzr vis'.
430
423.1.17 by Gary van der Merwe
Reuse the viz treeview in the revision browser.
431
    def _tree_revision_activated(self, widget, path, col):
432
        # TODO: more than one parent
433
        """Callback for when a treeview row gets activated."""
434
        revision = self.treeview.get_revision()
435
        parents  = self.treeview.get_parents()
436
437
        if len(parents) == 0:
438
            parent_id = None
439
        else:
440
            parent_id = parents[0]
441
442
        self.show_diff(revision.revision_id, parent_id)
443
        self.treeview.grab_focus()
463.3.1 by Javier Derderian
Fixed menu entry 'View Changes'. Bug #215350
444
        
3 by Scott James Remnant
Split the display in two with a pane, we'll use the bottom half to show
445
    def _back_clicked_cb(self, *args):
446
        """Callback for when the back button is clicked."""
304 by Daniel Schierbeck
Made forward/back buttons work again.
447
        self.treeview.back()
448
        
5 by Scott James Remnant
Reverse the meaning of the Back and Forward buttons so Back actually
449
    def _fwd_clicked_cb(self, *args):
450
        """Callback for when the forward button is clicked."""
304 by Daniel Schierbeck
Made forward/back buttons work again.
451
        self.treeview.forward()
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
452
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
453
    def _go_clicked_cb(self, w, p):
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
454
        """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().
455
        if self.revisionview.get_revision() is not None:
456
            self.treeview.set_revision(self.revisionview.get_revision())
152 by Jelmer Vernooij
Cleanup some more code.
457
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
458
    def _show_clicked_cb(self, revid, parentid):
7 by Scott James Remnant
Put some information about the highlighted revision in the bottom pane,
459
        """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.
460
        self.show_diff(revid, parentid)
13 by Scott James Remnant
Keep the focus on the treeview
461
        self.treeview.grab_focus()
46 by Wouter van Heyst
show diff on row activation, LP# 44591
462
352.1.1 by Daniel Schierbeck
Added dropdown menu to Back button.
463
    def _set_revision_cb(self, w, revision_id):
356 by Daniel Schierbeck
Made revision a property on TreeView.
464
        self.treeview.set_revision_id(revision_id)
352.1.1 by Daniel Schierbeck
Added dropdown menu to Back button.
465
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
466
    def _brokenlines_toggled_cb(self, button):
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
467
        self.compact_view = button.get_active()
468
469
        if self.compact_view:
470
            option = 'yes'
330.2.4 by Daniel Schierbeck
Made use of compact view optional.
471
        else:
330.2.5 by Daniel Schierbeck
Support persistence of compact view option.
472
            option = 'no'
473
474
        self.config.set_user_option('viz-compact-view', option)
401.1.3 by Daniel Schierbeck
Made the compact view toggling cleaner.
475
        self.treeview.set_property('compact', self.compact_view)
476
        self.treeview.refresh()
368 by Daniel Schierbeck
Merged with mainline.
477
511.6.1 by Jelmer Vernooij
Add Branch/Index option if bzr-search is available.
478
    def _branch_index_cb(self, w):
479
        from bzrlib.plugins.search import index as _mod_index
480
        _mod_index.index_url(self.branch.base)
481
524 by Jelmer Vernooij
Add search dialog.
482
    def _branch_search_cb(self, w):
483
        from bzrlib.plugins.gtk.search import SearchDialog
526 by Jelmer Vernooij
Switch to found revision when clicking ok in search window.
484
        dialog = SearchDialog(self.branch)
485
        
486
        if dialog.run() == gtk.RESPONSE_OK:
487
            self.set_revision(dialog.get_revision())
488
489
        dialog.destroy()
524 by Jelmer Vernooij
Add search dialog.
490
423.9.1 by Daniel Schierbeck
Added Help->About menu item to the viz.
491
    def _about_dialog_cb(self, w):
492
        from bzrlib.plugins.gtk.about import AboutDialog
493
494
        AboutDialog().run()
495
348 by Daniel Schierbeck
Added toggle item for revision number column.
496
    def _col_visibility_changed(self, col, property):
373 by Daniel Schierbeck
Made column display options persisted.
497
        self.config.set_user_option(property + '-column-visible', col.get_active())
348 by Daniel Schierbeck
Added toggle item for revision number column.
498
        self.treeview.set_property(property + '-column-visible', col.get_active())
351 by Daniel Schierbeck
Added option to hide the toolbar.
499
500
    def _toolbar_visibility_changed(self, col):
501
        if col.get_active():
531.7.2 by Scott Scriven
Made 'vis' save/load visibility of its toolbar.
502
            self.toolbar.show()
351 by Daniel Schierbeck
Added option to hide the toolbar.
503
        else:
504
            self.toolbar.hide()
531.7.2 by Scott Scriven
Made 'vis' save/load visibility of its toolbar.
505
        self.config.set_user_option('viz-toolbar-visible', col.get_active())
371.1.1 by Daniel Schierbeck
Added About dialog to the viz.
506
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
507
    def _make_diff_nonzero_size(self):
508
        """make sure the diff isn't zero-width or zero-height"""
509
        alloc = self.diff.get_allocation()
510
        if (alloc.width < 10) or (alloc.height < 10):
511
            width, height = self.get_size()
512
            self.revisionview.set_size_request(width/3, int(height / 2.5))
513
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
514
    def _diff_visibility_changed(self, col):
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
515
        """Hide or show the diff panel."""
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
516
        if col.get_active():
517
            self.diff.show()
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
518
            self._make_diff_nonzero_size()
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
519
        else:
520
            self.diff.hide()
521
        self.config.set_user_option('viz-show-diffs', str(col.get_active()))
522
        self.update_diff_panel()
523
531.7.14 by Scott Scriven
Made diff placement configurable (bottom-right, or bottom full-width).
524
    def _diff_placement_changed(self, col):
525
        """Toggle the diff panel's position."""
526
        self.config.set_user_option('viz-wide-diffs', str(col.get_active()))
527
528
        old = self.paned.get_child2()
529
        self.paned.remove(old)
530
        self.paned.pack2(self.construct_bottom(), resize=True, shrink=False)
531
        self._make_diff_nonzero_size()
532
533
        self.treeview.emit('revision-selected')
534
371.1.1 by Daniel Schierbeck
Added About dialog to the viz.
535
    def _show_about_cb(self, w):
536
        dialog = AboutDialog()
537
        dialog.connect('response', lambda d,r: d.destroy())
538
        dialog.run()
404 by Daniel Schierbeck
Made the refresh use proper locking.
539
540
    def _refresh_clicked(self, w):
423.1.13 by Gary van der Merwe
Move viz loading msg from branchwin to treeview.
541
        self.treeview.refresh()
423.7.5 by Daniel Schierbeck
Made the revision history window update the Go->Tags menu when a tag is added.
542
543
    def _update_tags(self):
544
        menu = gtk.Menu()
545
546
        if self.branch.supports_tags():
547
            tags = self.branch.tags.get_tag_dict().items()
548
            tags.sort()
549
            tags.reverse()
550
            for tag, revid in tags:
450.4.1 by Daniel Schierbeck
Added tag icon to branch history window.
551
                tag_image = gtk.Image()
552
                tag_image.set_from_file(icon_path('tag-16.png'))
553
                tag_item = gtk.ImageMenuItem(tag.replace('_', '__'))
554
                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.
555
                tag_item.connect('activate', self._tag_selected_cb, revid)
556
                menu.add(tag_item)
557
            self.go_menu_tags.set_submenu(menu)
558
559
            self.go_menu_tags.set_sensitive(len(tags) != 0)
560
        else:
561
            self.go_menu_tags.set_sensitive(False)
562
563
        self.go_menu_tags.show_all()
564
531.7.10 by Scott Scriven
Simplified size-loading code. No longer saves identical config every time vis runs.
565
    def _load_size(self, name):
566
        """Read and parse 'name' from self.config.
567
        The value is a string, formatted as WIDTHxHEIGHT
568
        Returns None, or (width, height)
569
        """
570
        size = self.config.get_user_option(name)
571
        if size:
572
            width, height = [int(num) for num in size.split('x')]
573
            # avoid writing config every time we start
574
            self._sizes[name] = (width, height)
575
            return width, height
576
        return None
577
531.7.9 by Scott Scriven
Made vis remember window and panel sizes.
578
    def _on_size_allocate(self, widget, allocation, name):
579
        """When window has been resized, save the new size."""
580
        width, height = 0, 0
581
        if name in self._sizes:
582
            width, height = self._sizes[name]
583
584
        size_changed = (width != allocation.width) or \
585
                (height != allocation.height)
586
587
        if size_changed:
588
            width, height = allocation.width, allocation.height
589
            self._sizes[name] = (width, height)
590
            value = '%sx%s' % (width, height)
591
            self.config.set_user_option(name, value)
592
423.1.17 by Gary van der Merwe
Reuse the viz treeview in the revision browser.
593
    def show_diff(self, revid=None, parentid=None):
594
        """Open a new window to show a diff between the given revisions."""
595
        from bzrlib.plugins.gtk.diff import DiffWindow
596
        window = DiffWindow(parent=self)
597
598
        if parentid is None:
599
            parentid = NULL_REVISION
600
601
        rev_tree    = self.branch.repository.revision_tree(revid)
602
        parent_tree = self.branch.repository.revision_tree(parentid)
603
604
        description = revid + " - " + self.branch.nick
605
        window.set_diff(description, rev_tree, parent_tree)
606
        window.show()
607
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
608
    def update_diff_panel(self, revision=None, parents=None):
609
        """Show the current revision in the diff panel."""
531.7.12 by Scott Scriven
Made diff panel default to off.
610
        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.
611
            return
612
613
        if not revision: # default to selected row
614
            revision = self.treeview.get_revision()
615
        if (not revision) or (revision == NULL_REVISION):
616
            return
617
618
        if not parents: # default to selected row's parents
619
            parents  = self.treeview.get_parents()
620
        if len(parents) == 0:
621
            parent_id = None
622
        else:
623
            parent_id = parents[0]
624
625
        rev_tree    = self.branch.repository.revision_tree(revision.revision_id)
626
        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.
627
531.7.3 by Scott Scriven
Added an option to show/hide the diff panel.
628
        self.diff.set_diff(rev_tree, parent_tree)
629
        self.diff.show_all()