16
from bzrlib.plugins.gtk.window import Window
17
16
from bzrlib.plugins.gtk import icon_path
17
from bzrlib.plugins.gtk.branchview import TreeView, treemodel
18
18
from bzrlib.plugins.gtk.tags import AddTagDialog
19
19
from bzrlib.plugins.gtk.preferences import PreferencesWindow
20
from bzrlib.plugins.gtk.branchview import TreeView, treemodel
20
from bzrlib.plugins.gtk.revisionmenu import RevisionMenu
21
from bzrlib.plugins.gtk.window import Window
22
23
from bzrlib.config import BranchConfig, GlobalConfig
23
24
from bzrlib.revision import Revision, NULL_REVISION
59
62
monitor = screen.get_monitor_geometry(0)
60
63
width = int(monitor.width * 0.75)
61
64
height = int(monitor.height * 0.75)
65
# user-configured window size
66
size = self._load_size('viz-window-size')
62
69
self.set_default_size(width, height)
70
self.set_size_request(width/3, height/3)
71
self.connect("size-allocate", self._on_size_allocate, 'viz-window-size')
65
74
icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
105
114
self.paned = gtk.VPaned()
106
self.paned.pack1(self.construct_top(), resize=True, shrink=False)
107
self.paned.pack2(self.construct_bottom(), resize=False, shrink=True)
115
self.paned.pack1(self.construct_top(), resize=False, shrink=True)
116
self.paned.pack2(self.construct_bottom(), resize=True, shrink=False)
108
117
self.paned.show()
110
vbox.pack_start(self.construct_menubar(), expand=False, fill=True)
111
vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
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)
113
124
vbox.pack_start(self.paned, expand=True, fill=True)
114
125
vbox.set_focus_child(self.paned)
161
172
view_menu_toolbar = gtk.CheckMenuItem("Show Toolbar")
162
173
view_menu_toolbar.set_active(True)
174
if self.config.get_user_option('viz-toolbar-visible') == 'False':
175
view_menu_toolbar.set_active(False)
163
177
view_menu_toolbar.connect('toggled', self._toolbar_visibility_changed)
165
179
view_menu_compact = gtk.CheckMenuItem("Show Compact Graph")
166
180
view_menu_compact.set_active(self.compact_view)
167
181
view_menu_compact.connect('activate', self._brokenlines_toggled_cb)
183
view_menu_diffs = gtk.CheckMenuItem("Show Diffs")
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)
187
view_menu_diffs.connect('toggled', self._diff_visibility_changed)
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)
169
195
view_menu.add(view_menu_toolbar)
170
196
view_menu.add(view_menu_compact)
197
view_menu.add(view_menu_diffs)
198
view_menu.add(view_menu_wide_diffs)
171
199
view_menu.add(gtk.SeparatorMenuItem())
173
201
self.mnu_show_revno_column = gtk.CheckMenuItem("Show Revision _Number Column")
203
231
go_menu.add(gtk.SeparatorMenuItem())
204
232
go_menu.add(self.go_menu_tags)
206
revision_menu = gtk.Menu()
234
self.revision_menu = RevisionMenu(self.branch.repository, [], self.branch, parent=self)
207
235
revision_menuitem = gtk.MenuItem("_Revision")
208
revision_menuitem.set_submenu(revision_menu)
210
revision_menu_diff = gtk.MenuItem("View Changes")
211
revision_menu_diff.connect('activate',
214
revision_menu_compare = gtk.MenuItem("Compare with...")
215
revision_menu_compare.connect('activate',
216
self._compare_with_cb)
218
revision_menu_tag = gtk.MenuItem("Tag Revision")
219
revision_menu_tag.connect('activate', self._tag_revision_cb)
221
revision_menu.add(revision_menu_tag)
222
revision_menu.add(revision_menu_diff)
223
revision_menu.add(revision_menu_compare)
236
revision_menuitem.set_submenu(self.revision_menu)
225
238
branch_menu = gtk.Menu()
226
239
branch_menuitem = gtk.MenuItem("_Branch")
234
247
except ImportError:
235
248
mutter("Didn't find search plugin")
250
branch_menu.add(gtk.SeparatorMenuItem())
237
252
branch_index_menuitem = gtk.MenuItem("_Index")
238
253
branch_index_menuitem.connect('activate', self._branch_index_cb)
239
254
branch_menu.add(branch_index_menuitem)
256
branch_search_menuitem = gtk.MenuItem("_Search")
257
branch_search_menuitem.connect('activate', self._branch_search_cb)
258
branch_menu.add(branch_search_menuitem)
241
260
help_menu = gtk.Menu()
242
261
help_menuitem = gtk.MenuItem("_Help")
243
262
help_menuitem.set_submenu(help_menu)
283
302
align = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
284
303
align.set_padding(5, 0, 0, 0)
285
304
align.add(self.treeview)
305
# user-configured size
306
size = self._load_size('viz-graph-size')
309
align.set_size_request(width, height)
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')
311
339
def construct_bottom(self):
312
340
"""Construct the bottom half of the window."""
341
if self.config.get_user_option('viz-wide-diffs') == 'True':
342
self.diff_paned = gtk.VPaned()
344
self.diff_paned = gtk.HPaned()
345
(width, height) = self.get_size()
346
self.diff_paned.set_size_request(20, 20) # shrinkable
313
348
from bzrlib.plugins.gtk.revisionview import RevisionView
314
349
self.revisionview = RevisionView(branch=self.branch)
315
(width, height) = self.get_size()
316
self.revisionview.set_size_request(width, int(height / 2.5))
350
self.revisionview.set_size_request(width/3, int(height / 2.5))
351
# user-configured size
352
size = self._load_size('viz-revisionview-size')
355
self.revisionview.set_size_request(width, height)
356
self.revisionview.connect('size-allocate', self._on_size_allocate, 'viz-revisionview-size')
317
357
self.revisionview.show()
318
358
self.revisionview.set_show_callback(self._show_clicked_cb)
319
359
self.revisionview.connect('notify::revision', self._go_clicked_cb)
320
360
self.treeview.connect('tag-added', lambda w, t, r: self.revisionview.update_tags())
321
return self.revisionview
361
self.diff_paned.pack1(self.revisionview)
363
from bzrlib.plugins.gtk.diff import DiffWidget
364
self.diff = DiffWidget()
365
self.diff_paned.pack2(self.diff)
367
self.diff_paned.show_all()
368
if self.config.get_user_option('viz-show-diffs') != 'True':
371
return self.diff_paned
323
373
def _tag_selected_cb(self, menuitem, revid):
324
374
self.treeview.set_revision_id(revid)
374
426
self.revisionview.set_revision(revision)
375
427
self.revisionview.set_children(children)
429
self.update_diff_panel(revision, parents)
377
431
def _tree_revision_activated(self, widget, path, col):
378
432
# TODO: more than one parent
379
433
"""Callback for when a treeview row gets activated."""
388
442
self.show_diff(revision.revision_id, parent_id)
389
443
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)
404
445
def _back_clicked_cb(self, *args):
405
446
"""Callback for when the back button is clicked."""
406
447
self.treeview.back()
419
460
self.show_diff(revid, parentid)
420
461
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)
438
463
def _set_revision_cb(self, w, revision_id):
439
464
self.treeview.set_revision_id(revision_id)
450
475
self.treeview.set_property('compact', self.compact_view)
451
476
self.treeview.refresh()
453
def _tag_revision_cb(self, w):
455
self.treeview.set_sensitive(False)
456
dialog = AddTagDialog(self.branch.repository, self.treeview.get_revision().revision_id, self.branch)
457
response = dialog.run()
458
if response != gtk.RESPONSE_NONE:
461
if response == gtk.RESPONSE_OK:
462
self.treeview.add_tag(dialog.tagname, dialog._revid)
467
self.treeview.set_sensitive(True)
469
478
def _branch_index_cb(self, w):
470
479
from bzrlib.plugins.search import index as _mod_index
471
480
_mod_index.index_url(self.branch.base)
482
def _branch_search_cb(self, w):
483
from bzrlib.plugins.gtk.search import SearchDialog
484
dialog = SearchDialog(self.branch)
486
if dialog.run() == gtk.RESPONSE_OK:
487
self.set_revision(dialog.get_revision())
473
491
def _about_dialog_cb(self, w):
474
492
from bzrlib.plugins.gtk.about import AboutDialog
482
500
def _toolbar_visibility_changed(self, col):
483
501
if col.get_active():
486
504
self.toolbar.hide()
505
self.config.set_user_option('viz-toolbar-visible', col.get_active())
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))
514
def _diff_visibility_changed(self, col):
515
"""Hide or show the diff panel."""
518
self._make_diff_nonzero_size()
521
self.config.set_user_option('viz-show-diffs', str(col.get_active()))
522
self.update_diff_panel()
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()))
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()
533
self.treeview.emit('revision-selected')
488
535
def _show_about_cb(self, w):
489
536
dialog = AboutDialog()
516
563
self.go_menu_tags.show_all()
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)
570
size = self.config.get_user_option(name)
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)
578
def _on_size_allocate(self, widget, allocation, name):
579
"""When window has been resized, save the new size."""
581
if name in self._sizes:
582
width, height = self._sizes[name]
584
size_changed = (width != allocation.width) or \
585
(height != allocation.height)
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)
518
593
def show_diff(self, revid=None, parentid=None):
519
594
"""Open a new window to show a diff between the given revisions."""
520
595
from bzrlib.plugins.gtk.diff import DiffWindow
530
605
window.set_diff(description, rev_tree, parent_tree)
608
def update_diff_panel(self, revision=None, parents=None):
609
"""Show the current revision in the diff panel."""
610
if self.config.get_user_option('viz-show-diffs') != 'True':
613
if not revision: # default to selected row
614
revision = self.treeview.get_revision()
615
if (not revision) or (revision == NULL_REVISION):
618
if not parents: # default to selected row's parents
619
parents = self.treeview.get_parents()
620
if len(parents) == 0:
623
parent_id = parents[0]
625
rev_tree = self.branch.repository.revision_tree(revision.revision_id)
626
parent_tree = self.branch.repository.revision_tree(parent_id)
628
self.diff.set_diff(rev_tree, parent_tree)