/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: 2008-07-18 12:29:56 UTC
  • mfrom: (531.7.14 vis-enhancements)
  • Revision ID: jelmer@samba.org-20080718122956-27468cxu2b613ib8
Merge diff widget in viz.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
import gobject
14
14
import pango
15
15
 
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
21
24
from bzrlib.revision import Revision, NULL_REVISION
22
 
from bzrlib.config import BranchConfig
23
 
from bzrlib.config import GlobalConfig
 
25
from bzrlib.trace import mutter
24
26
 
25
27
class BranchWindow(Window):
26
28
    """Branch window.
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:
58
62
        monitor = screen.get_monitor_geometry(0)
59
63
        width = int(monitor.width * 0.75)
60
64
        height = int(monitor.height * 0.75)
 
65
        # user-configured window size
 
66
        size = self._load_size('viz-window-size')
 
67
        if size:
 
68
            width, height = size
61
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')
62
72
 
63
73
        # FIXME AndyFitz!
64
74
        icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
102
112
        self.add(vbox)
103
113
 
104
114
        self.paned = gtk.VPaned()
105
 
        self.paned.pack1(self.construct_top(), resize=True, shrink=False)
106
 
        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)
107
117
        self.paned.show()
108
118
 
109
 
        vbox.pack_start(self.construct_menubar(), expand=False, fill=True)
110
 
        vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
111
 
        
 
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)
 
123
 
112
124
        vbox.pack_start(self.paned, expand=True, fill=True)
113
125
        vbox.set_focus_child(self.paned)
114
126
 
159
171
 
160
172
        view_menu_toolbar = gtk.CheckMenuItem("Show Toolbar")
161
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)
 
176
            self.toolbar.hide()
162
177
        view_menu_toolbar.connect('toggled', self._toolbar_visibility_changed)
163
178
 
164
179
        view_menu_compact = gtk.CheckMenuItem("Show Compact Graph")
165
180
        view_menu_compact.set_active(self.compact_view)
166
181
        view_menu_compact.connect('activate', self._brokenlines_toggled_cb)
167
182
 
 
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)
 
188
 
 
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)
 
194
 
168
195
        view_menu.add(view_menu_toolbar)
169
196
        view_menu.add(view_menu_compact)
 
197
        view_menu.add(view_menu_diffs)
 
198
        view_menu.add(view_menu_wide_diffs)
170
199
        view_menu.add(gtk.SeparatorMenuItem())
171
200
 
172
201
        self.mnu_show_revno_column = gtk.CheckMenuItem("Show Revision _Number Column")
202
231
        go_menu.add(gtk.SeparatorMenuItem())
203
232
        go_menu.add(self.go_menu_tags)
204
233
 
205
 
        revision_menu = gtk.Menu()
 
234
        self.revision_menu = RevisionMenu(self.branch.repository, [], self.branch, parent=self)
206
235
        revision_menuitem = gtk.MenuItem("_Revision")
207
 
        revision_menuitem.set_submenu(revision_menu)
208
 
 
209
 
        revision_menu_diff = gtk.MenuItem("View Changes")
210
 
        revision_menu_diff.connect('activate', 
211
 
                self._menu_diff_cb)
212
 
        
213
 
        revision_menu_compare = gtk.MenuItem("Compare with...")
214
 
        revision_menu_compare.connect('activate',
215
 
                self._compare_with_cb)
216
 
 
217
 
        revision_menu_tag = gtk.MenuItem("Tag Revision")
218
 
        revision_menu_tag.connect('activate', self._tag_revision_cb)
219
 
 
220
 
        revision_menu.add(revision_menu_tag)
221
 
        revision_menu.add(revision_menu_diff)
222
 
        revision_menu.add(revision_menu_compare)
 
236
        revision_menuitem.set_submenu(self.revision_menu)
223
237
 
224
238
        branch_menu = gtk.Menu()
225
239
        branch_menuitem = gtk.MenuItem("_Branch")
228
242
        branch_menu.add(gtk.MenuItem("Pu_ll Revisions"))
229
243
        branch_menu.add(gtk.MenuItem("Pu_sh Revisions"))
230
244
 
 
245
        try:
 
246
            from bzrlib.plugins import search
 
247
        except ImportError:
 
248
            mutter("Didn't find search plugin")
 
249
        else:
 
250
            branch_menu.add(gtk.SeparatorMenuItem())
 
251
 
 
252
            branch_index_menuitem = gtk.MenuItem("_Index")
 
253
            branch_index_menuitem.connect('activate', self._branch_index_cb)
 
254
            branch_menu.add(branch_index_menuitem)
 
255
 
 
256
            branch_search_menuitem = gtk.MenuItem("_Search")
 
257
            branch_search_menuitem.connect('activate', self._branch_search_cb)
 
258
            branch_menu.add(branch_search_menuitem)
 
259
 
231
260
        help_menu = gtk.Menu()
232
261
        help_menuitem = gtk.MenuItem("_Help")
233
262
        help_menuitem.set_submenu(help_menu)
273
302
        align = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
274
303
        align.set_padding(5, 0, 0, 0)
275
304
        align.add(self.treeview)
 
305
        # user-configured size
 
306
        size = self._load_size('viz-graph-size')
 
307
        if size:
 
308
            width, height = size
 
309
            align.set_size_request(width, height)
 
310
        else:
 
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')
276
314
        align.show()
277
315
 
278
316
        return align
300
338
 
301
339
    def construct_bottom(self):
302
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()
 
343
        else:
 
344
            self.diff_paned = gtk.HPaned()
 
345
        (width, height) = self.get_size()
 
346
        self.diff_paned.set_size_request(20, 20) # shrinkable
 
347
 
303
348
        from bzrlib.plugins.gtk.revisionview import RevisionView
304
349
        self.revisionview = RevisionView(branch=self.branch)
305
 
        (width, height) = self.get_size()
306
 
        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')
 
353
        if size:
 
354
            width, height = size
 
355
            self.revisionview.set_size_request(width, height)
 
356
        self.revisionview.connect('size-allocate', self._on_size_allocate, 'viz-revisionview-size')
307
357
        self.revisionview.show()
308
358
        self.revisionview.set_show_callback(self._show_clicked_cb)
309
359
        self.revisionview.connect('notify::revision', self._go_clicked_cb)
310
360
        self.treeview.connect('tag-added', lambda w, t, r: self.revisionview.update_tags())
311
 
        return self.revisionview
 
361
        self.diff_paned.pack1(self.revisionview)
 
362
 
 
363
        from bzrlib.plugins.gtk.diff import DiffWidget
 
364
        self.diff = DiffWidget()
 
365
        self.diff_paned.pack2(self.diff)
 
366
 
 
367
        self.diff_paned.show_all()
 
368
        if self.config.get_user_option('viz-show-diffs') != 'True':
 
369
            self.diff.hide()
 
370
 
 
371
        return self.diff_paned
312
372
 
313
373
    def _tag_selected_cb(self, menuitem, revid):
314
374
        self.treeview.set_revision_id(revid)
319
379
        parents  = self.treeview.get_parents()
320
380
        children = self.treeview.get_children()
321
381
 
 
382
        self.revision_menu.set_revision_ids([revision.revision_id])
 
383
 
322
384
        if revision and revision != NULL_REVISION:
323
385
            prev_menu = gtk.Menu()
324
386
            if len(parents) > 0:
363
425
 
364
426
            self.revisionview.set_revision(revision)
365
427
            self.revisionview.set_children(children)
366
 
    
 
428
 
 
429
            self.update_diff_panel(revision, parents)
 
430
 
367
431
    def _tree_revision_activated(self, widget, path, col):
368
432
        # TODO: more than one parent
369
433
        """Callback for when a treeview row gets activated."""
378
442
        self.show_diff(revision.revision_id, parent_id)
379
443
        self.treeview.grab_focus()
380
444
        
381
 
    def _menu_diff_cb(self,w):
382
 
        (path, focus) = self.treeview.treeview.get_cursor()
383
 
        revid = self.treeview.model[path][treemodel.REVID]
384
 
        
385
 
        parentids = self.branch.repository.revision_parents(revid)
386
 
 
387
 
        if len(parentids) == 0:
388
 
            parentid = NULL_REVISION
389
 
        else:
390
 
            parentid = parentids[0]
391
 
        
392
 
        self.show_diff(revid,parentid)    
393
 
 
394
445
    def _back_clicked_cb(self, *args):
395
446
        """Callback for when the back button is clicked."""
396
447
        self.treeview.back()
409
460
        self.show_diff(revid, parentid)
410
461
        self.treeview.grab_focus()
411
462
 
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"""
415
 
        
416
 
        from bzrlib.plugins.gtk.revbrowser import RevisionBrowser
417
 
        
418
 
        rb = RevisionBrowser(self.branch,self)
419
 
        ret = rb.run()
420
 
        
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)
425
 
            
426
 
        rb.destroy()
427
 
            
428
463
    def _set_revision_cb(self, w, revision_id):
429
464
        self.treeview.set_revision_id(revision_id)
430
465
 
440
475
        self.treeview.set_property('compact', self.compact_view)
441
476
        self.treeview.refresh()
442
477
 
443
 
    def _tag_revision_cb(self, w):
444
 
        try:
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:
449
 
                dialog.hide()
450
 
            
451
 
                if response == gtk.RESPONSE_OK:
452
 
                    self.treeview.add_tag(dialog.tagname, dialog._revid)
453
 
                
454
 
                dialog.destroy()
455
 
 
456
 
        finally:
457
 
            self.treeview.set_sensitive(True)
 
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)
 
481
 
 
482
    def _branch_search_cb(self, w):
 
483
        from bzrlib.plugins.gtk.search import SearchDialog
 
484
        dialog = SearchDialog(self.branch)
 
485
        
 
486
        if dialog.run() == gtk.RESPONSE_OK:
 
487
            self.set_revision(dialog.get_revision())
 
488
 
 
489
        dialog.destroy()
458
490
 
459
491
    def _about_dialog_cb(self, w):
460
492
        from bzrlib.plugins.gtk.about import AboutDialog
467
499
 
468
500
    def _toolbar_visibility_changed(self, col):
469
501
        if col.get_active():
470
 
            self.toolbar.show() 
 
502
            self.toolbar.show()
471
503
        else:
472
504
            self.toolbar.hide()
 
505
        self.config.set_user_option('viz-toolbar-visible', col.get_active())
 
506
 
 
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))
 
513
 
 
514
    def _diff_visibility_changed(self, col):
 
515
        """Hide or show the diff panel."""
 
516
        if col.get_active():
 
517
            self.diff.show()
 
518
            self._make_diff_nonzero_size()
 
519
        else:
 
520
            self.diff.hide()
 
521
        self.config.set_user_option('viz-show-diffs', str(col.get_active()))
 
522
        self.update_diff_panel()
 
523
 
 
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()))
 
527
 
 
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()
 
532
 
 
533
        self.treeview.emit('revision-selected')
473
534
 
474
535
    def _show_about_cb(self, w):
475
536
        dialog = AboutDialog()
501
562
 
502
563
        self.go_menu_tags.show_all()
503
564
 
 
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)
 
569
        """
 
570
        size = self.config.get_user_option(name)
 
571
        if size:
 
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)
 
575
            return width, height
 
576
        return None
 
577
 
 
578
    def _on_size_allocate(self, widget, allocation, name):
 
579
        """When window has been resized, save the new size."""
 
580
        width, height = 0, 0
 
581
        if name in self._sizes:
 
582
            width, height = self._sizes[name]
 
583
 
 
584
        size_changed = (width != allocation.width) or \
 
585
                (height != allocation.height)
 
586
 
 
587
        if size_changed:
 
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)
 
592
 
504
593
    def show_diff(self, revid=None, parentid=None):
505
594
        """Open a new window to show a diff between the given revisions."""
506
595
        from bzrlib.plugins.gtk.diff import DiffWindow
516
605
        window.set_diff(description, rev_tree, parent_tree)
517
606
        window.show()
518
607
 
519
 
 
 
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':
 
611
            return
 
612
 
 
613
        if not revision: # default to selected row
 
614
            revision = self.treeview.get_revision()
 
615
        if (not revision) or (revision == NULL_REVISION):
 
616
            return
 
617
 
 
618
        if not parents: # default to selected row's parents
 
619
            parents  = self.treeview.get_parents()
 
620
        if len(parents) == 0:
 
621
            parent_id = None
 
622
        else:
 
623
            parent_id = parents[0]
 
624
 
 
625
        rev_tree    = self.branch.repository.revision_tree(revision.revision_id)
 
626
        parent_tree = self.branch.repository.revision_tree(parent_id)
 
627
 
 
628
        self.diff.set_diff(rev_tree, parent_tree)
 
629
        self.diff.show_all()