16
from bzrlib.plugins.gtk.window import Window
16
17
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.revisionmenu import RevisionMenu
21
from bzrlib.plugins.gtk.window import Window
23
from bzrlib.config import BranchConfig, GlobalConfig
20
from bzrlib.plugins.gtk.branchview import TreeView, treemodel
24
21
from bzrlib.revision import Revision, NULL_REVISION
25
from bzrlib.trace import mutter
22
from bzrlib.config import BranchConfig
23
from bzrlib.config import GlobalConfig
27
25
class BranchWindow(Window):
62
58
monitor = screen.get_monitor_geometry(0)
63
59
width = int(monitor.width * 0.75)
64
60
height = int(monitor.height * 0.75)
65
# user-configured window size
66
size = self._load_size('viz-window-size')
69
61
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')
74
64
icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
114
104
self.paned = gtk.VPaned()
115
self.paned.pack1(self.construct_top(), resize=False, shrink=True)
116
self.paned.pack2(self.construct_bottom(), resize=True, shrink=False)
105
self.paned.pack1(self.construct_top(), resize=True, shrink=False)
106
self.paned.pack2(self.construct_bottom(), resize=False, shrink=True)
117
107
self.paned.show()
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)
109
vbox.pack_start(self.construct_menubar(), expand=False, fill=True)
110
vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
124
112
vbox.pack_start(self.paned, expand=True, fill=True)
125
113
vbox.set_focus_child(self.paned)
172
160
view_menu_toolbar = gtk.CheckMenuItem("Show Toolbar")
173
161
view_menu_toolbar.set_active(True)
174
if self.config.get_user_option('viz-toolbar-visible') == 'False':
175
view_menu_toolbar.set_active(False)
177
162
view_menu_toolbar.connect('toggled', self._toolbar_visibility_changed)
179
164
view_menu_compact = gtk.CheckMenuItem("Show Compact Graph")
180
165
view_menu_compact.set_active(self.compact_view)
181
166
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)
195
168
view_menu.add(view_menu_toolbar)
196
169
view_menu.add(view_menu_compact)
197
view_menu.add(view_menu_diffs)
198
view_menu.add(view_menu_wide_diffs)
199
170
view_menu.add(gtk.SeparatorMenuItem())
201
172
self.mnu_show_revno_column = gtk.CheckMenuItem("Show Revision _Number Column")
231
202
go_menu.add(gtk.SeparatorMenuItem())
232
203
go_menu.add(self.go_menu_tags)
234
self.revision_menu = RevisionMenu(self.branch.repository, [], self.branch, parent=self)
205
revision_menu = gtk.Menu()
235
206
revision_menuitem = gtk.MenuItem("_Revision")
236
revision_menuitem.set_submenu(self.revision_menu)
207
revision_menuitem.set_submenu(revision_menu)
209
revision_menu_diff = gtk.MenuItem("View Changes")
210
revision_menu_diff.connect('activate',
213
revision_menu_compare = gtk.MenuItem("Compare with...")
214
revision_menu_compare.connect('activate',
215
self._compare_with_cb)
217
revision_menu_tag = gtk.MenuItem("Tag Revision")
218
revision_menu_tag.connect('activate', self._tag_revision_cb)
220
revision_menu.add(revision_menu_tag)
221
revision_menu.add(revision_menu_diff)
222
revision_menu.add(revision_menu_compare)
238
224
branch_menu = gtk.Menu()
239
225
branch_menuitem = gtk.MenuItem("_Branch")
242
228
branch_menu.add(gtk.MenuItem("Pu_ll Revisions"))
243
229
branch_menu.add(gtk.MenuItem("Pu_sh Revisions"))
246
from bzrlib.plugins import search
248
mutter("Didn't find search plugin")
250
branch_menu.add(gtk.SeparatorMenuItem())
252
branch_index_menuitem = gtk.MenuItem("_Index")
253
branch_index_menuitem.connect('activate', self._branch_index_cb)
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)
260
231
help_menu = gtk.Menu()
261
232
help_menuitem = gtk.MenuItem("_Help")
262
233
help_menuitem.set_submenu(help_menu)
302
273
align = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
303
274
align.set_padding(5, 0, 0, 0)
304
275
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')
339
301
def construct_bottom(self):
340
302
"""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
348
303
from bzrlib.plugins.gtk.revisionview import RevisionView
349
304
self.revisionview = RevisionView(branch=self.branch)
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')
305
(width, height) = self.get_size()
306
self.revisionview.set_size_request(width, int(height / 2.5))
357
307
self.revisionview.show()
358
308
self.revisionview.set_show_callback(self._show_clicked_cb)
359
309
self.revisionview.connect('notify::revision', self._go_clicked_cb)
360
310
self.treeview.connect('tag-added', lambda w, t, r: self.revisionview.update_tags())
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
311
return self.revisionview
373
313
def _tag_selected_cb(self, menuitem, revid):
374
314
self.treeview.set_revision_id(revid)
426
364
self.revisionview.set_revision(revision)
427
365
self.revisionview.set_children(children)
429
self.update_diff_panel(revision, parents)
431
367
def _tree_revision_activated(self, widget, path, col):
432
368
# TODO: more than one parent
433
369
"""Callback for when a treeview row gets activated."""
442
378
self.show_diff(revision.revision_id, parent_id)
443
379
self.treeview.grab_focus()
381
def _menu_diff_cb(self,w):
382
(path, focus) = self.treeview.treeview.get_cursor()
383
revid = self.treeview.model[path][treemodel.REVID]
385
parentids = self.branch.repository.revision_parents(revid)
387
if len(parentids) == 0:
388
parentid = NULL_REVISION
390
parentid = parentids[0]
392
self.show_diff(revid,parentid)
445
394
def _back_clicked_cb(self, *args):
446
395
"""Callback for when the back button is clicked."""
447
396
self.treeview.back()
460
409
self.show_diff(revid, parentid)
461
410
self.treeview.grab_focus()
412
def _compare_with_cb(self,w):
413
"""Callback for revision 'compare with' menu. Will show a small
414
dialog with branch revisions to compare with selected revision in TreeView"""
416
from bzrlib.plugins.gtk.revbrowser import RevisionBrowser
418
rb = RevisionBrowser(self.branch,self)
421
if ret == gtk.RESPONSE_OK:
422
(path, focus) = self.treeview.treeview.get_cursor()
423
revid = self.treeview.model[path][treemodel.REVID]
424
self.show_diff(revid, rb.selected_revid)
463
428
def _set_revision_cb(self, w, revision_id):
464
429
self.treeview.set_revision_id(revision_id)
475
440
self.treeview.set_property('compact', self.compact_view)
476
441
self.treeview.refresh()
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)
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())
443
def _tag_revision_cb(self, w):
445
self.treeview.set_sensitive(False)
446
dialog = AddTagDialog(self.branch.repository, self.treeview.get_revision().revision_id, self.branch)
447
response = dialog.run()
448
if response != gtk.RESPONSE_NONE:
451
if response == gtk.RESPONSE_OK:
452
self.treeview.add_tag(dialog.tagname, dialog._revid)
457
self.treeview.set_sensitive(True)
491
459
def _about_dialog_cb(self, w):
492
460
from bzrlib.plugins.gtk.about import AboutDialog
500
468
def _toolbar_visibility_changed(self, col):
501
469
if col.get_active():
504
472
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')
535
474
def _show_about_cb(self, w):
536
475
dialog = AboutDialog()
563
502
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)
593
504
def show_diff(self, revid=None, parentid=None):
594
505
"""Open a new window to show a diff between the given revisions."""
595
506
from bzrlib.plugins.gtk.diff import DiffWindow
605
516
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)