/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to viz/branchwin.py

  • Committer: Jelmer Vernooij
  • Date: 2012-07-09 15:23:26 UTC
  • mto: This revision was merged to the branch mainline in revision 794.
  • Revision ID: jelmer@samba.org-20120709152326-dzxb8zoz0btull7n
Remove bzr-notify.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: UTF-8 -*-
2
1
"""Branch window.
3
2
 
4
3
This module contains the code to manage the branch information window,
5
4
which contains both the revision graph and details panes.
6
5
"""
7
6
 
8
 
__copyright__ = "Copyright © 2005 Canonical Ltd."
 
7
__copyright__ = "Copyright (c) 2005 Canonical Ltd."
9
8
__author__    = "Scott James Remnant <scott@ubuntu.com>"
10
9
 
11
10
 
12
 
import gtk
13
 
import gobject
14
 
import pango
 
11
from gi.repository import Gdk
 
12
from gi.repository import Gtk
15
13
 
16
14
from bzrlib.plugins.gtk import icon_path
17
 
from bzrlib.plugins.gtk.branchview import TreeView, treemodel
18
 
from bzrlib.plugins.gtk.tags import AddTagDialog
 
15
from bzrlib.plugins.gtk.branchview import TreeView
19
16
from bzrlib.plugins.gtk.preferences import PreferencesWindow
20
17
from bzrlib.plugins.gtk.revisionmenu import RevisionMenu
21
18
from bzrlib.plugins.gtk.window import Window
22
19
 
23
 
from bzrlib.config import BranchConfig, GlobalConfig
24
 
from bzrlib.revision import Revision, NULL_REVISION
 
20
from bzrlib.config import GlobalConfig
 
21
from bzrlib.revision import NULL_REVISION
25
22
from bzrlib.trace import mutter
26
23
 
 
24
 
27
25
class BranchWindow(Window):
28
26
    """Branch window.
29
27
 
40
38
                       None for no limit.
41
39
        """
42
40
 
43
 
        Window.__init__(self, parent=parent)
 
41
        super(BranchWindow, self).__init__(parent=parent)
44
42
        self.set_border_width(0)
45
43
 
46
44
        self.branch      = branch
48
46
        self.maxnum      = maxnum
49
47
        self.config      = GlobalConfig()
50
48
 
51
 
        self._sizes      = {} # window and widget sizes
52
 
 
53
49
        if self.config.get_user_option('viz-compact-view') == 'yes':
54
50
            self.compact_view = True
55
51
        else:
56
52
            self.compact_view = False
57
53
 
58
 
        self.set_title(branch.nick + " - revision history")
 
54
        self.set_title(branch._get_nick(local=True) + " - revision history")
59
55
 
60
56
        # user-configured window size
61
57
        size = self._load_size('viz-window-size')
69
65
            height = int(monitor.height * 0.75)
70
66
        self.set_default_size(width, height)
71
67
        self.set_size_request(width/3, height/3)
72
 
        self.connect("size-allocate", self._on_size_allocate, 'viz-window-size')
 
68
        self._save_size_on_destroy(self, 'viz-window-size')
73
69
 
74
70
        # FIXME AndyFitz!
75
 
        icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
 
71
        icon = self.render_icon_pixbuf(Gtk.STOCK_INDEX, Gtk.IconSize.BUTTON)
76
72
        self.set_icon(icon)
77
73
 
78
 
        gtk.accel_map_add_entry("<viz>/Go/Next Revision", gtk.keysyms.Up, gtk.gdk.MOD1_MASK)
79
 
        gtk.accel_map_add_entry("<viz>/Go/Previous Revision", gtk.keysyms.Down, gtk.gdk.MOD1_MASK)
80
 
        gtk.accel_map_add_entry("<viz>/View/Refresh", gtk.keysyms.F5, 0)
 
74
        Gtk.AccelMap.add_entry("<viz>/Go/Next Revision", Gdk.KEY_Up, Gdk.ModifierType.MOD1_MASK)
 
75
        Gtk.AccelMap.add_entry("<viz>/Go/Previous Revision", Gdk.KEY_Down, Gdk.ModifierType.MOD1_MASK)
 
76
        Gtk.AccelMap.add_entry("<viz>/View/Refresh", Gdk.KEY_F5, 0)
81
77
 
82
 
        self.accel_group = gtk.AccelGroup()
 
78
        self.accel_group = Gtk.AccelGroup()
83
79
        self.add_accel_group(self.accel_group)
84
80
 
85
 
        gtk.Action.set_tool_item_type(gtk.MenuToolButton)
86
 
 
87
 
        self.prev_rev_action = gtk.Action("prev-rev", "_Previous Revision", "Go to the previous revision", gtk.STOCK_GO_DOWN)
 
81
        self.prev_rev_action = Gtk.Action("prev-rev", "_Previous Revision", "Go to the previous revision", Gtk.STOCK_GO_DOWN)
88
82
        self.prev_rev_action.set_accel_path("<viz>/Go/Previous Revision")
89
83
        self.prev_rev_action.set_accel_group(self.accel_group)
90
84
        self.prev_rev_action.connect("activate", self._back_clicked_cb)
91
85
        self.prev_rev_action.connect_accelerator()
92
86
 
93
 
        self.next_rev_action = gtk.Action("next-rev", "_Next Revision", "Go to the next revision", gtk.STOCK_GO_UP)
 
87
        self.next_rev_action = Gtk.Action("next-rev", "_Next Revision", "Go to the next revision", Gtk.STOCK_GO_UP)
94
88
        self.next_rev_action.set_accel_path("<viz>/Go/Next Revision")
95
89
        self.next_rev_action.set_accel_group(self.accel_group)
96
90
        self.next_rev_action.connect("activate", self._fwd_clicked_cb)
97
91
        self.next_rev_action.connect_accelerator()
98
92
 
99
 
        self.refresh_action = gtk.Action("refresh", "_Refresh", "Refresh view", gtk.STOCK_REFRESH)
 
93
        self.refresh_action = Gtk.Action("refresh", "_Refresh", "Refresh view", Gtk.STOCK_REFRESH)
100
94
        self.refresh_action.set_accel_path("<viz>/View/Refresh")
101
95
        self.refresh_action.set_accel_group(self.accel_group)
102
96
        self.refresh_action.connect("activate", self._refresh_clicked)
103
97
        self.refresh_action.connect_accelerator()
104
98
 
105
 
        self.construct()
 
99
        self.vbox = self.construct()
 
100
 
 
101
    def _save_size_on_destroy(self, widget, config_name):
 
102
        """Creates a hook that saves the size of widget to config option 
 
103
           config_name when the window is destroyed/closed."""
 
104
        def save_size(src):
 
105
            allocation = widget.get_allocation()
 
106
            width, height = allocation.width, allocation.height
 
107
            value = '%sx%s' % (width, height)
 
108
            self.config.set_user_option(config_name, value)
 
109
        self.connect("destroy", save_size)
106
110
 
107
111
    def set_revision(self, revid):
108
112
        self.treeview.set_revision_id(revid)
109
113
 
110
114
    def construct(self):
111
115
        """Construct the window contents."""
112
 
        vbox = gtk.VBox(spacing=0)
 
116
        vbox = Gtk.VBox(spacing=0)
113
117
        self.add(vbox)
114
118
 
115
 
        self.paned = gtk.VPaned()
116
 
        self.paned.pack1(self.construct_top(), resize=False, shrink=True)
117
 
        self.paned.pack2(self.construct_bottom(), resize=True, shrink=False)
118
 
        self.paned.show()
119
 
 
 
119
        # order is important here
 
120
        paned = self.construct_paned()
120
121
        nav = self.construct_navigation()
121
122
        menubar = self.construct_menubar()
122
 
        vbox.pack_start(menubar, expand=False, fill=True)
123
 
        vbox.pack_start(nav, expand=False, fill=True)
124
 
 
125
 
        vbox.pack_start(self.paned, expand=True, fill=True)
126
 
        vbox.set_focus_child(self.paned)
 
123
 
 
124
        vbox.pack_start(menubar, False, True, 0)
 
125
        vbox.pack_start(nav, False, True, 0)
 
126
        vbox.pack_start(paned, True, True, 0)
 
127
        vbox.set_focus_child(paned)
 
128
 
127
129
 
128
130
        vbox.show()
129
 
    
 
131
 
 
132
        return vbox
 
133
 
 
134
    def construct_paned(self):
 
135
        """Construct the main HPaned/VPaned contents."""
 
136
        if self.config.get_user_option('viz-vertical') == 'True':
 
137
            self.paned = Gtk.Paned.new(Gtk.Orientation.HORIZONTAL)
 
138
        else:
 
139
            self.paned = Gtk.Paned.new(Gtk.Orientation.VERTICAL)
 
140
 
 
141
        self.paned.pack1(self.construct_top(), resize=False, shrink=True)
 
142
        self.paned.pack2(self.construct_bottom(), resize=True, shrink=False)
 
143
        self.paned.show()
 
144
 
 
145
        return self.paned
 
146
 
130
147
    def construct_menubar(self):
131
 
        menubar = gtk.MenuBar()
 
148
        menubar = Gtk.MenuBar()
132
149
 
133
 
        file_menu = gtk.Menu()
134
 
        file_menuitem = gtk.MenuItem("_File")
 
150
        file_menu = Gtk.Menu()
 
151
        file_menuitem = Gtk.MenuItem.new_with_mnemonic("_File")
135
152
        file_menuitem.set_submenu(file_menu)
136
153
 
137
 
        file_menu_close = gtk.ImageMenuItem(gtk.STOCK_CLOSE, self.accel_group)
 
154
        file_menu_close = Gtk.ImageMenuItem.new_from_stock(
 
155
            Gtk.STOCK_CLOSE, self.accel_group)
138
156
        file_menu_close.connect('activate', lambda x: self.destroy())
139
 
        
140
 
        file_menu_quit = gtk.ImageMenuItem(gtk.STOCK_QUIT, self.accel_group)
141
 
        file_menu_quit.connect('activate', lambda x: gtk.main_quit())
142
 
        
 
157
 
 
158
        file_menu_quit = Gtk.ImageMenuItem.new_from_stock(
 
159
            Gtk.STOCK_QUIT, self.accel_group)
 
160
        file_menu_quit.connect('activate', lambda x: Gtk.main_quit())
 
161
 
143
162
        if self._parent is not None:
144
163
            file_menu.add(file_menu_close)
145
164
        file_menu.add(file_menu_quit)
146
165
 
147
 
        edit_menu = gtk.Menu()
148
 
        edit_menuitem = gtk.MenuItem("_Edit")
 
166
        edit_menu = Gtk.Menu()
 
167
        edit_menuitem = Gtk.MenuItem.new_with_mnemonic("_Edit")
149
168
        edit_menuitem.set_submenu(edit_menu)
150
169
 
151
 
        edit_menu_branchopts = gtk.MenuItem("Branch Settings")
 
170
        edit_menu_branchopts = Gtk.MenuItem(label="Branch Settings")
152
171
        edit_menu_branchopts.connect('activate', lambda x: PreferencesWindow(self.branch.get_config()).show())
153
172
 
154
 
        edit_menu_globopts = gtk.MenuItem("Global Settings")
 
173
        edit_menu_globopts = Gtk.MenuItem(label="Global Settings")
155
174
        edit_menu_globopts.connect('activate', lambda x: PreferencesWindow().show())
156
175
 
157
176
        edit_menu.add(edit_menu_branchopts)
158
177
        edit_menu.add(edit_menu_globopts)
159
178
 
160
 
        view_menu = gtk.Menu()
161
 
        view_menuitem = gtk.MenuItem("_View")
 
179
        view_menu = Gtk.Menu()
 
180
        view_menuitem = Gtk.MenuItem.new_with_mnemonic("_View")
162
181
        view_menuitem.set_submenu(view_menu)
163
182
 
164
183
        view_menu_refresh = self.refresh_action.create_menu_item()
165
184
        view_menu_refresh.connect('activate', self._refresh_clicked)
166
185
 
167
186
        view_menu.add(view_menu_refresh)
168
 
        view_menu.add(gtk.SeparatorMenuItem())
 
187
        view_menu.add(Gtk.SeparatorMenuItem())
169
188
 
170
 
        view_menu_toolbar = gtk.CheckMenuItem("Show Toolbar")
 
189
        view_menu_toolbar = Gtk.CheckMenuItem(label="Show Toolbar")
171
190
        view_menu_toolbar.set_active(True)
172
191
        if self.config.get_user_option('viz-toolbar-visible') == 'False':
173
192
            view_menu_toolbar.set_active(False)
174
193
            self.toolbar.hide()
175
194
        view_menu_toolbar.connect('toggled', self._toolbar_visibility_changed)
176
195
 
177
 
        view_menu_compact = gtk.CheckMenuItem("Show Compact Graph")
 
196
        view_menu_compact = Gtk.CheckMenuItem(label="Show Compact Graph")
178
197
        view_menu_compact.set_active(self.compact_view)
179
198
        view_menu_compact.connect('activate', self._brokenlines_toggled_cb)
180
 
        
181
 
        view_menu_diffs = gtk.CheckMenuItem("Show Diffs")
 
199
 
 
200
        view_menu_vertical = Gtk.CheckMenuItem(label="Side-by-side Layout")
 
201
        view_menu_vertical.set_active(False)
 
202
        if self.config.get_user_option('viz-vertical') == 'True':
 
203
            view_menu_vertical.set_active(True)
 
204
        view_menu_vertical.connect('toggled', self._vertical_layout)
 
205
 
 
206
        view_menu_diffs = Gtk.CheckMenuItem(label="Show Diffs")
182
207
        view_menu_diffs.set_active(False)
183
208
        if self.config.get_user_option('viz-show-diffs') == 'True':
184
209
            view_menu_diffs.set_active(True)
185
210
        view_menu_diffs.connect('toggled', self._diff_visibility_changed)
186
 
        
187
 
        view_menu_wide_diffs = gtk.CheckMenuItem("Wide Diffs")
 
211
 
 
212
        view_menu_wide_diffs = Gtk.CheckMenuItem(label="Wide Diffs")
188
213
        view_menu_wide_diffs.set_active(False)
189
214
        if self.config.get_user_option('viz-wide-diffs') == 'True':
190
215
            view_menu_wide_diffs.set_active(True)
191
216
        view_menu_wide_diffs.connect('toggled', self._diff_placement_changed)
192
 
        
193
 
        view_menu_wrap_diffs = gtk.CheckMenuItem("Wrap _Long Lines in Diffs")
 
217
 
 
218
        view_menu_wrap_diffs = Gtk.CheckMenuItem.new_with_mnemonic(
 
219
            "Wrap _Long Lines in Diffs")
194
220
        view_menu_wrap_diffs.set_active(False)
195
221
        if self.config.get_user_option('viz-wrap-diffs') == 'True':
196
222
            view_menu_wrap_diffs.set_active(True)
197
223
        view_menu_wrap_diffs.connect('toggled', self._diff_wrap_changed)
198
 
                
 
224
 
199
225
        view_menu.add(view_menu_toolbar)
200
226
        view_menu.add(view_menu_compact)
201
 
        view_menu.add(gtk.SeparatorMenuItem())
 
227
        view_menu.add(view_menu_vertical)
 
228
        view_menu.add(Gtk.SeparatorMenuItem())
202
229
        view_menu.add(view_menu_diffs)
203
230
        view_menu.add(view_menu_wide_diffs)
204
231
        view_menu.add(view_menu_wrap_diffs)
205
 
        view_menu.add(gtk.SeparatorMenuItem())
 
232
        view_menu.add(Gtk.SeparatorMenuItem())
206
233
 
207
 
        self.mnu_show_revno_column = gtk.CheckMenuItem("Show Revision _Number Column")
208
 
        self.mnu_show_date_column = gtk.CheckMenuItem("Show _Date Column")
 
234
        self.mnu_show_revno_column = Gtk.CheckMenuItem.new_with_mnemonic(
 
235
            "Show Revision _Number Column")
 
236
        self.mnu_show_date_column = Gtk.CheckMenuItem.new_with_mnemonic(
 
237
            "Show _Date Column")
209
238
 
210
239
        # Revision numbers are pointless if there are multiple branches
211
240
        if len(self.start_revs) > 1:
218
247
            col.connect('toggled', self._col_visibility_changed, name)
219
248
            view_menu.add(col)
220
249
 
221
 
        go_menu = gtk.Menu()
 
250
        go_menu = Gtk.Menu()
222
251
        go_menu.set_accel_group(self.accel_group)
223
 
        go_menuitem = gtk.MenuItem("_Go")
 
252
        go_menuitem = Gtk.MenuItem.new_with_mnemonic("_Go")
224
253
        go_menuitem.set_submenu(go_menu)
225
 
        
 
254
 
226
255
        go_menu_next = self.next_rev_action.create_menu_item()
227
256
        go_menu_prev = self.prev_rev_action.create_menu_item()
228
257
 
229
 
        tag_image = gtk.Image()
 
258
        tag_image = Gtk.Image()
230
259
        tag_image.set_from_file(icon_path("tag-16.png"))
231
 
        self.go_menu_tags = gtk.ImageMenuItem("_Tags")
 
260
        self.go_menu_tags = Gtk.ImageMenuItem.new_with_mnemonic("_Tags")
232
261
        self.go_menu_tags.set_image(tag_image)
233
 
        self._update_tags()
 
262
        self.treeview.connect('refreshed', lambda w: self._update_tags())
234
263
 
235
264
        go_menu.add(go_menu_next)
236
265
        go_menu.add(go_menu_prev)
237
 
        go_menu.add(gtk.SeparatorMenuItem())
 
266
        go_menu.add(Gtk.SeparatorMenuItem())
238
267
        go_menu.add(self.go_menu_tags)
239
268
 
240
 
        self.revision_menu = RevisionMenu(self.branch.repository, [], self.branch, parent=self)
241
 
        revision_menuitem = gtk.MenuItem("_Revision")
 
269
        self.revision_menu = RevisionMenu(self.branch.repository, [],
 
270
            self.branch, parent=self)
 
271
        revision_menuitem = Gtk.MenuItem.new_with_mnemonic("_Revision")
242
272
        revision_menuitem.set_submenu(self.revision_menu)
243
273
 
244
 
        branch_menu = gtk.Menu()
245
 
        branch_menuitem = gtk.MenuItem("_Branch")
 
274
        branch_menu = Gtk.Menu()
 
275
        branch_menuitem = Gtk.MenuItem.new_with_mnemonic("_Branch")
246
276
        branch_menuitem.set_submenu(branch_menu)
247
277
 
248
 
        branch_menu.add(gtk.MenuItem("Pu_ll Revisions"))
249
 
        branch_menu.add(gtk.MenuItem("Pu_sh Revisions"))
 
278
        branch_menu.add(Gtk.MenuItem.new_with_mnemonic("Pu_ll Revisions"))
 
279
        branch_menu.add(Gtk.MenuItem.new_with_mnemonic("Pu_sh Revisions"))
250
280
 
251
281
        try:
252
282
            from bzrlib.plugins import search
253
283
        except ImportError:
254
284
            mutter("Didn't find search plugin")
255
285
        else:
256
 
            branch_menu.add(gtk.SeparatorMenuItem())
 
286
            branch_menu.add(Gtk.SeparatorMenuItem())
257
287
 
258
 
            branch_index_menuitem = gtk.MenuItem("_Index")
 
288
            branch_index_menuitem = Gtk.MenuItem.new_with_mnemonic("_Index")
259
289
            branch_index_menuitem.connect('activate', self._branch_index_cb)
260
290
            branch_menu.add(branch_index_menuitem)
261
291
 
262
 
            branch_search_menuitem = gtk.MenuItem("_Search")
 
292
            branch_search_menuitem = Gtk.MenuItem.new_with_mnemonic("_Search")
263
293
            branch_search_menuitem.connect('activate', self._branch_search_cb)
264
294
            branch_menu.add(branch_search_menuitem)
265
295
 
266
 
        help_menu = gtk.Menu()
267
 
        help_menuitem = gtk.MenuItem("_Help")
 
296
        help_menu = Gtk.Menu()
 
297
        help_menuitem = Gtk.MenuItem.new_with_mnemonic("_Help")
268
298
        help_menuitem.set_submenu(help_menu)
269
299
 
270
 
        help_about_menuitem = gtk.ImageMenuItem(gtk.STOCK_ABOUT, self.accel_group)
 
300
        help_about_menuitem = Gtk.ImageMenuItem.new_from_stock(
 
301
            Gtk.STOCK_ABOUT, self.accel_group)
271
302
        help_about_menuitem.connect('activate', self._about_dialog_cb)
272
303
 
273
304
        help_menu.add(help_about_menuitem)
287
318
        """Construct the top-half of the window."""
288
319
        # FIXME: Make broken_line_length configurable
289
320
 
290
 
        self.treeview = TreeView(self.branch, self.start_revs, self.maxnum, self.compact_view)
291
 
 
292
 
        self.treeview.connect('revision-selected',
293
 
                self._treeselection_changed_cb)
294
 
        self.treeview.connect('revision-activated',
295
 
                self._tree_revision_activated)
296
 
 
297
 
        self.treeview.connect('tag-added', lambda w, t, r: self._update_tags())
 
321
        self.treeview = TreeView(self.branch, self.start_revs, self.maxnum,
 
322
            self.compact_view)
298
323
 
299
324
        for col in ["revno", "date"]:
300
325
            option = self.config.get_user_option(col + '-column-visible')
301
326
            if option is not None:
302
 
                self.treeview.set_property(col + '-column-visible', option == 'True')
 
327
                self.treeview.set_property(col + '-column-visible',
 
328
                    option == 'True')
303
329
            else:
304
330
                self.treeview.set_property(col + '-column-visible', False)
305
331
 
306
332
        self.treeview.show()
307
333
 
308
 
        align = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
 
334
        align = Gtk.Alignment.new(0.0, 0.0, 1.0, 1.0)
309
335
        align.set_padding(5, 0, 0, 0)
310
336
        align.add(self.treeview)
311
337
        # user-configured size
316
342
        else:
317
343
            (width, height) = self.get_size()
318
344
            align.set_size_request(width, int(height / 2.5))
319
 
        align.connect('size-allocate', self._on_size_allocate, 'viz-graph-size')
 
345
        self._save_size_on_destroy(align, 'viz-graph-size')
320
346
        align.show()
321
347
 
322
348
        return align
323
349
 
324
350
    def construct_navigation(self):
325
351
        """Construct the navigation buttons."""
326
 
        self.toolbar = gtk.Toolbar()
327
 
        self.toolbar.set_style(gtk.TOOLBAR_BOTH_HORIZ)
 
352
        self.toolbar = Gtk.Toolbar()
 
353
        self.toolbar.set_style(Gtk.ToolbarStyle.BOTH_HORIZ)
328
354
 
329
355
        self.prev_button = self.prev_rev_action.create_tool_item()
330
356
        self.toolbar.insert(self.prev_button, -1)
332
358
        self.next_button = self.next_rev_action.create_tool_item()
333
359
        self.toolbar.insert(self.next_button, -1)
334
360
 
335
 
        self.toolbar.insert(gtk.SeparatorToolItem(), -1)
 
361
        self.toolbar.insert(Gtk.SeparatorToolItem(), -1)
336
362
 
337
 
        refresh_button = gtk.ToolButton(gtk.STOCK_REFRESH)
 
363
        refresh_button = Gtk.ToolButton.new_from_stock(Gtk.STOCK_REFRESH)
338
364
        refresh_button.connect('clicked', self._refresh_clicked)
339
365
        self.toolbar.insert(refresh_button, -1)
340
366
 
345
371
    def construct_bottom(self):
346
372
        """Construct the bottom half of the window."""
347
373
        if self.config.get_user_option('viz-wide-diffs') == 'True':
348
 
            self.diff_paned = gtk.VPaned()
 
374
            self.diff_paned = Gtk.Paned.new(Gtk.Orientation.VERTICAL)
349
375
        else:
350
 
            self.diff_paned = gtk.HPaned()
 
376
            self.diff_paned = Gtk.Paned.new(Gtk.Orientation.HORIZONTAL)
351
377
        (width, height) = self.get_size()
352
378
        self.diff_paned.set_size_request(20, 20) # shrinkable
353
379
 
359
385
        if size:
360
386
            width, height = size
361
387
            self.revisionview.set_size_request(width, height)
362
 
        self.revisionview.connect('size-allocate', self._on_size_allocate, 'viz-revisionview-size')
 
388
        self._save_size_on_destroy(self.revisionview, 'viz-revisionview-size')
363
389
        self.revisionview.show()
364
390
        self.revisionview.set_show_callback(self._show_clicked_cb)
365
391
        self.revisionview.connect('notify::revision', self._go_clicked_cb)
366
 
        self.treeview.connect('tag-added', lambda w, t, r: self.revisionview.update_tags())
 
392
        self.treeview.connect('tag-added',
 
393
            lambda w, t, r: self.revisionview.update_tags())
 
394
        self.treeview.connect('revision-selected',
 
395
                self._treeselection_changed_cb)
 
396
        self.treeview.connect('revision-activated',
 
397
                self._tree_revision_activated)
367
398
        self.diff_paned.pack1(self.revisionview)
368
399
 
369
400
        from bzrlib.plugins.gtk.diff import DiffWidget
385
416
        parents  = self.treeview.get_parents()
386
417
        children = self.treeview.get_children()
387
418
 
388
 
        self.revision_menu.set_revision_ids([revision.revision_id])
389
 
 
390
 
        if revision and revision != NULL_REVISION:
391
 
            prev_menu = gtk.Menu()
 
419
        if revision and revision.revision_id != NULL_REVISION:
 
420
            self.revision_menu.set_revision_ids([revision.revision_id])
 
421
            prev_menu = Gtk.Menu()
392
422
            if len(parents) > 0:
393
423
                self.prev_rev_action.set_sensitive(True)
394
424
                for parent_id in parents:
395
425
                    if parent_id and parent_id != NULL_REVISION:
396
426
                        parent = self.branch.repository.get_revision(parent_id)
397
427
                        try:
398
 
                            str = ' (' + parent.properties['branch-nick'] + ')'
 
428
                            str = ' (%s)' % parent.properties['branch-nick']
399
429
                        except KeyError:
400
430
                            str = ""
401
431
 
402
 
                        item = gtk.MenuItem(parent.message.split("\n")[0] + str)
 
432
                        item = Gtk.MenuItem(
 
433
                            label=parent.message.split("\n")[0] + str)
403
434
                        item.connect('activate', self._set_revision_cb, parent_id)
404
435
                        prev_menu.add(item)
405
436
                prev_menu.show_all()
407
438
                self.prev_rev_action.set_sensitive(False)
408
439
                prev_menu.hide()
409
440
 
410
 
            self.prev_button.set_menu(prev_menu)
 
441
            if getattr(self.prev_button, 'set_menu', None) is not None:
 
442
                self.prev_button.set_menu(prev_menu)
411
443
 
412
 
            next_menu = gtk.Menu()
 
444
            next_menu = Gtk.Menu()
413
445
            if len(children) > 0:
414
446
                self.next_rev_action.set_sensitive(True)
415
447
                for child_id in children:
416
448
                    child = self.branch.repository.get_revision(child_id)
417
449
                    try:
418
 
                        str = ' (' + child.properties['branch-nick'] + ')'
 
450
                        str = ' (%s)' % child.properties['branch-nick']
419
451
                    except KeyError:
420
452
                        str = ""
421
453
 
422
 
                    item = gtk.MenuItem(child.message.split("\n")[0] + str)
 
454
                    item = Gtk.MenuItem(
 
455
                        label=child.message.split("\n")[0] + str)
423
456
                    item.connect('activate', self._set_revision_cb, child_id)
424
457
                    next_menu.add(item)
425
458
                next_menu.show_all()
427
460
                self.next_rev_action.set_sensitive(False)
428
461
                next_menu.hide()
429
462
 
430
 
            self.next_button.set_menu(next_menu)
 
463
            if getattr(self.next_button, 'set_menu', None) is not None:
 
464
                self.next_button.set_menu(next_menu)
431
465
 
432
466
            self.revisionview.set_revision(revision)
433
467
            self.revisionview.set_children(children)
440
474
        parents  = self.treeview.get_parents()
441
475
 
442
476
        if len(parents) == 0:
443
 
            parent_id = None
 
477
            parent_id = NULL_REVISION
444
478
        else:
445
479
            parent_id = parents[0]
446
480
 
447
 
        self.show_diff(revision.revision_id, parent_id)
 
481
        if revision is not None:
 
482
            self.show_diff(revision.revision_id, parent_id)
 
483
        else:
 
484
            self.show_diff(NULL_REVISION)
448
485
        self.treeview.grab_focus()
449
 
        
 
486
 
450
487
    def _back_clicked_cb(self, *args):
451
488
        """Callback for when the back button is clicked."""
452
489
        self.treeview.back()
453
 
        
 
490
 
454
491
    def _fwd_clicked_cb(self, *args):
455
492
        """Callback for when the forward button is clicked."""
456
493
        self.treeview.forward()
485
522
        _mod_index.index_url(self.branch.base)
486
523
 
487
524
    def _branch_search_cb(self, w):
488
 
        from bzrlib.plugins.search import index as _mod_index
 
525
        from bzrlib.plugins.search import (
 
526
            index as _mod_index,
 
527
            errors as search_errors,
 
528
            )
489
529
        from bzrlib.plugins.gtk.search import SearchDialog
490
 
        from bzrlib.plugins.search import errors as search_errors
491
530
 
492
531
        try:
493
532
            index = _mod_index.open_index_url(self.branch.base)
494
533
        except search_errors.NoSearchIndex:
495
 
            dialog = gtk.MessageDialog(self, type=gtk.MESSAGE_QUESTION, 
496
 
                buttons=gtk.BUTTONS_OK_CANCEL, 
 
534
            dialog = Gtk.MessageDialog(self, type=Gtk.MessageType.QUESTION, 
 
535
                buttons=Gtk.ButtonsType.OK_CANCEL, 
497
536
                message_format="This branch has not been indexed yet. "
498
537
                               "Index now?")
499
 
            if dialog.run() == gtk.RESPONSE_OK:
 
538
            if dialog.run() == Gtk.ResponseType.OK:
500
539
                dialog.destroy()
501
540
                index = _mod_index.index_url(self.branch.base)
502
541
            else:
504
543
                return
505
544
 
506
545
        dialog = SearchDialog(index)
507
 
        
508
 
        if dialog.run() == gtk.RESPONSE_OK:
509
 
            self.set_revision(dialog.get_revision())
 
546
 
 
547
        if dialog.run() == Gtk.ResponseType.OK:
 
548
            revid = dialog.get_revision()
 
549
            if revid is not None:
 
550
                self.set_revision(revid)
510
551
 
511
552
        dialog.destroy()
512
553
 
513
554
    def _about_dialog_cb(self, w):
514
555
        from bzrlib.plugins.gtk.about import AboutDialog
515
 
 
516
556
        AboutDialog().run()
517
557
 
518
558
    def _col_visibility_changed(self, col, property):
526
566
            self.toolbar.hide()
527
567
        self.config.set_user_option('viz-toolbar-visible', col.get_active())
528
568
 
 
569
    def _vertical_layout(self, col):
 
570
        """Toggle the layout vertical/horizontal"""
 
571
        self.config.set_user_option('viz-vertical', str(col.get_active()))
 
572
 
 
573
        old = self.paned
 
574
        self.vbox.remove(old)
 
575
        self.vbox.pack_start(
 
576
            self.construct_paned(), True, True, 0)
 
577
        self._make_diff_paned_nonzero_size()
 
578
        self._make_diff_nonzero_size()
 
579
 
 
580
        self.treeview.emit('revision-selected')
 
581
 
 
582
    def _make_diff_paned_nonzero_size(self):
 
583
        """make sure the diff/revision pane isn't zero-width or zero-height"""
 
584
        alloc = self.diff_paned.get_allocation()
 
585
        if (alloc.width < 10) or (alloc.height < 10):
 
586
            width, height = self.get_size()
 
587
            self.diff_paned.set_size_request(width/3, int(height / 2.5))
 
588
 
529
589
    def _make_diff_nonzero_size(self):
530
590
        """make sure the diff isn't zero-width or zero-height"""
531
591
        alloc = self.diff.get_allocation()
553
613
        self._make_diff_nonzero_size()
554
614
 
555
615
        self.treeview.emit('revision-selected')
556
 
    
 
616
 
557
617
    def _diff_wrap_changed(self, widget):
558
618
        """Toggle word wrap in the diff widget."""
559
619
        self.config.set_user_option('viz-wrap-diffs', widget.get_active())
560
620
        self.diff._on_wraplines_toggled(widget)
561
 
    
562
 
    def _show_about_cb(self, w):
563
 
        dialog = AboutDialog()
564
 
        dialog.connect('response', lambda d,r: d.destroy())
565
 
        dialog.run()
566
621
 
567
622
    def _refresh_clicked(self, w):
568
623
        self.treeview.refresh()
569
624
 
570
625
    def _update_tags(self):
571
 
        menu = gtk.Menu()
 
626
        menu = Gtk.Menu()
572
627
 
573
628
        if self.branch.supports_tags():
574
629
            tags = self.branch.tags.get_tag_dict().items()
575
 
            tags.sort()
576
 
            tags.reverse()
 
630
            tags.sort(reverse=True)
577
631
            for tag, revid in tags:
578
 
                tag_image = gtk.Image()
 
632
                tag_image = Gtk.Image()
579
633
                tag_image.set_from_file(icon_path('tag-16.png'))
580
 
                tag_item = gtk.ImageMenuItem(tag.replace('_', '__'))
 
634
                tag_item = Gtk.ImageMenuItem.new_with_mnemonic(
 
635
                    tag.replace('_', '__'))
581
636
                tag_item.set_image(tag_image)
582
637
                tag_item.connect('activate', self._tag_selected_cb, revid)
 
638
                tag_item.set_sensitive(self.treeview.has_revision_id(revid))
583
639
                menu.add(tag_item)
584
640
            self.go_menu_tags.set_submenu(menu)
585
641
 
598
654
        if size:
599
655
            width, height = [int(num) for num in size.split('x')]
600
656
            # avoid writing config every time we start
601
 
            self._sizes[name] = (width, height)
602
657
            return width, height
603
658
        return None
604
659
 
605
 
    def _on_size_allocate(self, widget, allocation, name):
606
 
        """When window has been resized, save the new size."""
607
 
        width, height = 0, 0
608
 
        if name in self._sizes:
609
 
            width, height = self._sizes[name]
610
 
 
611
 
        size_changed = (width != allocation.width) or \
612
 
                (height != allocation.height)
613
 
 
614
 
        if size_changed:
615
 
            width, height = allocation.width, allocation.height
616
 
            self._sizes[name] = (width, height)
617
 
            value = '%sx%s' % (width, height)
618
 
            self.config.set_user_option(name, value)
619
 
 
620
 
    def show_diff(self, revid=None, parentid=None):
 
660
    def show_diff(self, revid, parentid=NULL_REVISION):
621
661
        """Open a new window to show a diff between the given revisions."""
622
662
        from bzrlib.plugins.gtk.diff import DiffWindow
623
663
        window = DiffWindow(parent=self)
624
664
 
625
 
        if parentid is None:
626
 
            parentid = NULL_REVISION
627
 
 
628
665
        rev_tree    = self.branch.repository.revision_tree(revid)
629
666
        parent_tree = self.branch.repository.revision_tree(parentid)
630
667
 
631
 
        description = revid + " - " + self.branch.nick
 
668
        description = revid + " - " + self.branch._get_nick(local=True)
632
669
        window.set_diff(description, rev_tree, parent_tree)
633
670
        window.show()
634
671
 
639
676
 
640
677
        if not revision: # default to selected row
641
678
            revision = self.treeview.get_revision()
642
 
        if (not revision) or (revision == NULL_REVISION):
 
679
        if revision == NULL_REVISION:
643
680
            return
644
681
 
645
682
        if not parents: # default to selected row's parents
646
683
            parents  = self.treeview.get_parents()
647
684
        if len(parents) == 0:
648
 
            parent_id = None
 
685
            parent_id = NULL_REVISION
649
686
        else:
650
687
            parent_id = parents[0]
651
688