16
16
from bzrlib.plugins.gtk.window import Window
17
from bzrlib.plugins.gtk import icon_path
17
18
from bzrlib.plugins.gtk.tags import AddTagDialog
18
19
from bzrlib.plugins.gtk.preferences import PreferencesWindow
19
from bzrlib.plugins.gtk.branchview import TreeView
20
from bzrlib.revision import Revision
21
from bzrlib.config import BranchConfig
22
from bzrlib.config import GlobalConfig
20
from bzrlib.plugins.gtk.branchview import TreeView, treemodel
22
from bzrlib.config import BranchConfig, GlobalConfig
23
from bzrlib.revision import Revision, NULL_REVISION
24
from bzrlib.trace import mutter
24
26
class BranchWindow(Window):
28
30
for a particular branch.
31
def __init__(self, branch, start, maxnum, parent=None):
33
def __init__(self, branch, start_revs, maxnum, parent=None):
32
34
"""Create a new BranchWindow.
34
36
:param branch: Branch object for branch to show.
35
:param start: Revision id of top revision.
37
:param start_revs: Revision ids of top revisions.
36
38
:param maxnum: Maximum number of revisions to display,
66
68
gtk.accel_map_add_entry("<viz>/Go/Next Revision", gtk.keysyms.Up, gtk.gdk.MOD1_MASK)
67
69
gtk.accel_map_add_entry("<viz>/Go/Previous Revision", gtk.keysyms.Down, gtk.gdk.MOD1_MASK)
70
gtk.accel_map_add_entry("<viz>/View/Refresh", gtk.keysyms.F5, 0)
69
72
self.accel_group = gtk.AccelGroup()
70
73
self.add_accel_group(self.accel_group)
83
86
self.next_rev_action.connect("activate", self._fwd_clicked_cb)
84
87
self.next_rev_action.connect_accelerator()
89
self.refresh_action = gtk.Action("refresh", "_Refresh", "Refresh view", gtk.STOCK_REFRESH)
90
self.refresh_action.set_accel_path("<viz>/View/Refresh")
91
self.refresh_action.set_accel_group(self.accel_group)
92
self.refresh_action.connect("activate", self._refresh_clicked)
93
self.refresh_action.connect_accelerator()
88
97
def set_revision(self, revid):
101
110
vbox.pack_start(self.construct_menubar(), expand=False, fill=True)
102
111
vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
103
vbox.pack_start(self.construct_loading_msg(), expand=False, fill=True)
105
113
vbox.pack_start(self.paned, expand=True, fill=True)
106
114
vbox.set_focus_child(self.paned)
144
152
view_menuitem = gtk.MenuItem("_View")
145
153
view_menuitem.set_submenu(view_menu)
155
view_menu_refresh = self.refresh_action.create_menu_item()
156
view_menu_refresh.connect('activate', self._refresh_clicked)
158
view_menu.add(view_menu_refresh)
159
view_menu.add(gtk.SeparatorMenuItem())
147
161
view_menu_toolbar = gtk.CheckMenuItem("Show Toolbar")
148
162
view_menu_toolbar.set_active(True)
149
163
view_menu_toolbar.connect('toggled', self._toolbar_visibility_changed)
156
170
view_menu.add(view_menu_compact)
157
171
view_menu.add(gtk.SeparatorMenuItem())
159
for (label, name) in [("Revision _Number", "revno"), ("_Date", "date")]:
160
col = gtk.CheckMenuItem("Show " + label + " Column")
173
self.mnu_show_revno_column = gtk.CheckMenuItem("Show Revision _Number Column")
174
self.mnu_show_date_column = gtk.CheckMenuItem("Show _Date Column")
176
# Revision numbers are pointless if there are multiple branches
177
if len(self.start_revs) > 1:
178
self.mnu_show_revno_column.set_sensitive(False)
179
self.treeview.set_property('revno-column-visible', False)
181
for (col, name) in [(self.mnu_show_revno_column, "revno"),
182
(self.mnu_show_date_column, "date")]:
161
183
col.set_active(self.treeview.get_property(name + "-column-visible"))
162
184
col.connect('toggled', self._col_visibility_changed, name)
163
185
view_menu.add(col)
170
192
go_menu_next = self.next_rev_action.create_menu_item()
171
193
go_menu_prev = self.prev_rev_action.create_menu_item()
173
self.go_menu_tags = gtk.MenuItem("_Tags")
195
tag_image = gtk.Image()
196
tag_image.set_from_file(icon_path("tag-16.png"))
197
self.go_menu_tags = gtk.ImageMenuItem("_Tags")
198
self.go_menu_tags.set_image(tag_image)
174
199
self._update_tags()
176
201
go_menu.add(go_menu_next)
185
210
revision_menu_diff = gtk.MenuItem("View Changes")
186
211
revision_menu_diff.connect('activate',
187
lambda w: self.treeview.show_diff())
214
revision_menu_compare = gtk.MenuItem("Compare with...")
215
revision_menu_compare.connect('activate',
216
self._compare_with_cb)
189
218
revision_menu_tag = gtk.MenuItem("Tag Revision")
190
219
revision_menu_tag.connect('activate', self._tag_revision_cb)
192
221
revision_menu.add(revision_menu_tag)
193
222
revision_menu.add(revision_menu_diff)
223
revision_menu.add(revision_menu_compare)
195
225
branch_menu = gtk.Menu()
196
226
branch_menuitem = gtk.MenuItem("_Branch")
199
229
branch_menu.add(gtk.MenuItem("Pu_ll Revisions"))
200
230
branch_menu.add(gtk.MenuItem("Pu_sh Revisions"))
233
from bzrlib.plugins import search
235
mutter("Didn't find search plugin")
237
branch_index_menuitem = gtk.MenuItem("_Index")
238
branch_index_menuitem.connect('activate', self._branch_index_cb)
239
branch_menu.add(branch_index_menuitem)
202
241
help_menu = gtk.Menu()
203
242
help_menuitem = gtk.MenuItem("_Help")
204
243
help_menuitem.set_submenu(help_menu)
218
257
menubar.show_all()
222
def construct_loading_msg(self):
223
image_loading = gtk.image_new_from_stock(gtk.STOCK_REFRESH,
224
gtk.ICON_SIZE_BUTTON)
227
label_loading = gtk.Label(_("Please wait, loading ancestral graph..."))
228
label_loading.set_alignment(0.0, 0.5)
231
self.loading_msg_box = gtk.HBox()
232
self.loading_msg_box.set_spacing(5)
233
self.loading_msg_box.set_border_width(5)
234
self.loading_msg_box.pack_start(image_loading, False, False)
235
self.loading_msg_box.pack_start(label_loading, True, True)
236
self.loading_msg_box.show()
238
return self.loading_msg_box
240
261
def construct_top(self):
241
262
"""Construct the top-half of the window."""
242
263
# FIXME: Make broken_line_length configurable
244
self.treeview = TreeView(self.branch, self.start, self.maxnum, self.compact_view)
265
self.treeview = TreeView(self.branch, self.start_revs, self.maxnum, self.compact_view)
246
267
self.treeview.connect('revision-selected',
247
268
self._treeselection_changed_cb)
249
self.treeview.connect('revisions-loaded',
250
lambda x: self.loading_msg_box.hide())
269
self.treeview.connect('revision-activated',
270
self._tree_revision_activated)
252
272
self.treeview.connect('tag-added', lambda w, t, r: self._update_tags())
307
329
parents = self.treeview.get_parents()
308
330
children = self.treeview.get_children()
310
if revision is not None:
332
if revision and revision != NULL_REVISION:
311
333
prev_menu = gtk.Menu()
312
334
if len(parents) > 0:
313
335
self.prev_rev_action.set_sensitive(True)
314
336
for parent_id in parents:
315
parent = self.branch.repository.get_revision(parent_id)
317
str = ' (' + parent.properties['branch-nick'] + ')'
337
if parent_id and parent_id != NULL_REVISION:
338
parent = self.branch.repository.get_revision(parent_id)
340
str = ' (' + parent.properties['branch-nick'] + ')'
321
item = gtk.MenuItem(parent.message.split("\n")[0] + str)
322
item.connect('activate', self._set_revision_cb, parent_id)
344
item = gtk.MenuItem(parent.message.split("\n")[0] + str)
345
item.connect('activate', self._set_revision_cb, parent_id)
324
347
prev_menu.show_all()
326
349
self.prev_rev_action.set_sensitive(False)
351
374
self.revisionview.set_revision(revision)
352
375
self.revisionview.set_children(children)
377
def _tree_revision_activated(self, widget, path, col):
378
# TODO: more than one parent
379
"""Callback for when a treeview row gets activated."""
380
revision = self.treeview.get_revision()
381
parents = self.treeview.get_parents()
383
if len(parents) == 0:
386
parent_id = parents[0]
388
self.show_diff(revision.revision_id, parent_id)
389
self.treeview.grab_focus()
391
def _menu_diff_cb(self,w):
392
(path, focus) = self.treeview.treeview.get_cursor()
393
revid = self.treeview.model[path][treemodel.REVID]
395
parentids = self.branch.repository.revision_parents(revid)
397
if len(parentids) == 0:
398
parentid = NULL_REVISION
400
parentid = parentids[0]
402
self.show_diff(revid,parentid)
354
404
def _back_clicked_cb(self, *args):
355
405
"""Callback for when the back button is clicked."""
367
417
def _show_clicked_cb(self, revid, parentid):
368
418
"""Callback for when the show button for a parent is clicked."""
369
self.treeview.show_diff(revid, parentid)
419
self.show_diff(revid, parentid)
370
420
self.treeview.grab_focus()
422
def _compare_with_cb(self,w):
423
"""Callback for revision 'compare with' menu. Will show a small
424
dialog with branch revisions to compare with selected revision in TreeView"""
426
from bzrlib.plugins.gtk.revbrowser import RevisionBrowser
428
rb = RevisionBrowser(self.branch,self)
431
if ret == gtk.RESPONSE_OK:
432
(path, focus) = self.treeview.treeview.get_cursor()
433
revid = self.treeview.model[path][treemodel.REVID]
434
self.show_diff(revid, rb.selected_revid)
372
438
def _set_revision_cb(self, w, revision_id):
373
439
self.treeview.set_revision_id(revision_id)
401
467
self.treeview.set_sensitive(True)
469
def _branch_index_cb(self, w):
470
from bzrlib.plugins.search import index as _mod_index
471
_mod_index.index_url(self.branch.base)
403
473
def _about_dialog_cb(self, w):
404
474
from bzrlib.plugins.gtk.about import AboutDialog
433
503
for tag, revid in tags:
434
tag_item = gtk.MenuItem(tag)
504
tag_image = gtk.Image()
505
tag_image.set_from_file(icon_path('tag-16.png'))
506
tag_item = gtk.ImageMenuItem(tag.replace('_', '__'))
507
tag_item.set_image(tag_image)
435
508
tag_item.connect('activate', self._tag_selected_cb, revid)
436
509
menu.add(tag_item)
437
510
self.go_menu_tags.set_submenu(menu)
443
516
self.go_menu_tags.show_all()
518
def show_diff(self, revid=None, parentid=None):
519
"""Open a new window to show a diff between the given revisions."""
520
from bzrlib.plugins.gtk.diff import DiffWindow
521
window = DiffWindow(parent=self)
524
parentid = NULL_REVISION
526
rev_tree = self.branch.repository.revision_tree(revid)
527
parent_tree = self.branch.repository.revision_tree(parentid)
529
description = revid + " - " + self.branch.nick
530
window.set_diff(description, rev_tree, parent_tree)