/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: Vincent Ladeuil
  • Date: 2008-10-23 08:14:59 UTC
  • mto: This revision was merged to the branch mainline in revision 618.
  • Revision ID: v.ladeuil+lp@free.fr-20081023081459-3rgjsohomf8rbe44
Fix bug #131589 by using a gtk.Window instead of a gtk.Dialog.

* status.py:
(StatusWindow): Renamed from StatusDialog, we're a window now.
(StatusWindow.__init__, StatusWindow._create): Adjusted to Window
inheritance.

* __init__.py:
(cmd_gstatus.run): Use a Window instead of a dialog.

Show diffs side-by-side

added added

removed removed

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