/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-06-29 15:54:40 UTC
  • mto: This revision was merged to the branch mainline in revision 519.
  • Revision ID: jelmer@samba.org-20080629155440-iuzfrlfifnplp9jq
Add simple test for linegraph.

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
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
22
 
 
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
26
24
 
27
25
class BranchWindow(Window):
28
26
    """Branch window.
48
46
        self.maxnum      = maxnum
49
47
        self.config      = GlobalConfig()
50
48
 
51
 
        self._sizes      = {} # window and widget sizes
52
 
 
53
49
        if self.config.get_user_option('viz-compact-view') == 'yes':
54
50
            self.compact_view = True
55
51
        else:
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')
67
 
        if size:
68
 
            width, height = 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')
72
62
 
73
63
        # FIXME AndyFitz!
74
64
        icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
112
102
        self.add(vbox)
113
103
 
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()
118
108
 
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
 
 
 
109
        vbox.pack_start(self.construct_menubar(), expand=False, fill=True)
 
110
        vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
 
111
        
124
112
        vbox.pack_start(self.paned, expand=True, fill=True)
125
113
        vbox.set_focus_child(self.paned)
126
114
 
147
135
        edit_menuitem = gtk.MenuItem("_Edit")
148
136
        edit_menuitem.set_submenu(edit_menu)
149
137
 
 
138
        edit_menu_find = gtk.ImageMenuItem(gtk.STOCK_FIND)
 
139
 
150
140
        edit_menu_branchopts = gtk.MenuItem("Branch Settings")
151
141
        edit_menu_branchopts.connect('activate', lambda x: PreferencesWindow(self.branch.get_config()).show())
152
142
 
153
143
        edit_menu_globopts = gtk.MenuItem("Global Settings")
154
144
        edit_menu_globopts.connect('activate', lambda x: PreferencesWindow().show())
155
145
 
 
146
        edit_menu.add(edit_menu_find)
156
147
        edit_menu.add(edit_menu_branchopts)
157
148
        edit_menu.add(edit_menu_globopts)
158
149
 
168
159
 
169
160
        view_menu_toolbar = gtk.CheckMenuItem("Show Toolbar")
170
161
        view_menu_toolbar.set_active(True)
171
 
        if self.config.get_user_option('viz-toolbar-visible') == 'False':
172
 
            view_menu_toolbar.set_active(False)
173
 
            self.toolbar.hide()
174
162
        view_menu_toolbar.connect('toggled', self._toolbar_visibility_changed)
175
163
 
176
164
        view_menu_compact = gtk.CheckMenuItem("Show Compact Graph")
177
165
        view_menu_compact.set_active(self.compact_view)
178
166
        view_menu_compact.connect('activate', self._brokenlines_toggled_cb)
179
167
 
180
 
        view_menu_diffs = gtk.CheckMenuItem("Show Diffs")
181
 
        view_menu_diffs.set_active(False)
182
 
        if self.config.get_user_option('viz-show-diffs') == 'True':
183
 
            view_menu_diffs.set_active(True)
184
 
        view_menu_diffs.connect('toggled', self._diff_visibility_changed)
185
 
 
186
 
        view_menu_wide_diffs = gtk.CheckMenuItem("Wide Diffs")
187
 
        view_menu_wide_diffs.set_active(False)
188
 
        if self.config.get_user_option('viz-wide-diffs') == 'True':
189
 
            view_menu_wide_diffs.set_active(True)
190
 
        view_menu_wide_diffs.connect('toggled', self._diff_placement_changed)
191
 
 
192
168
        view_menu.add(view_menu_toolbar)
193
169
        view_menu.add(view_menu_compact)
194
 
        view_menu.add(view_menu_diffs)
195
 
        view_menu.add(view_menu_wide_diffs)
196
170
        view_menu.add(gtk.SeparatorMenuItem())
197
171
 
198
172
        self.mnu_show_revno_column = gtk.CheckMenuItem("Show Revision _Number Column")
228
202
        go_menu.add(gtk.SeparatorMenuItem())
229
203
        go_menu.add(self.go_menu_tags)
230
204
 
231
 
        self.revision_menu = RevisionMenu(self.branch.repository, [], self.branch, parent=self)
 
205
        revision_menu = gtk.Menu()
232
206
        revision_menuitem = gtk.MenuItem("_Revision")
233
 
        revision_menuitem.set_submenu(self.revision_menu)
 
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)
234
223
 
235
224
        branch_menu = gtk.Menu()
236
225
        branch_menuitem = gtk.MenuItem("_Branch")
239
228
        branch_menu.add(gtk.MenuItem("Pu_ll Revisions"))
240
229
        branch_menu.add(gtk.MenuItem("Pu_sh Revisions"))
241
230
 
242
 
        try:
243
 
            from bzrlib.plugins import search
244
 
        except ImportError:
245
 
            mutter("Didn't find search plugin")
246
 
        else:
247
 
            branch_menu.add(gtk.SeparatorMenuItem())
248
 
 
249
 
            branch_index_menuitem = gtk.MenuItem("_Index")
250
 
            branch_index_menuitem.connect('activate', self._branch_index_cb)
251
 
            branch_menu.add(branch_index_menuitem)
252
 
 
253
 
            branch_search_menuitem = gtk.MenuItem("_Search")
254
 
            branch_search_menuitem.connect('activate', self._branch_search_cb)
255
 
            branch_menu.add(branch_search_menuitem)
256
 
 
257
231
        help_menu = gtk.Menu()
258
232
        help_menuitem = gtk.MenuItem("_Help")
259
233
        help_menuitem.set_submenu(help_menu)
299
273
        align = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
300
274
        align.set_padding(5, 0, 0, 0)
301
275
        align.add(self.treeview)
302
 
        # user-configured size
303
 
        size = self._load_size('viz-graph-size')
304
 
        if size:
305
 
            width, height = size
306
 
            align.set_size_request(width, height)
307
 
        else:
308
 
            (width, height) = self.get_size()
309
 
            align.set_size_request(width, int(height / 2.5))
310
 
        align.connect('size-allocate', self._on_size_allocate, 'viz-graph-size')
311
276
        align.show()
312
277
 
313
278
        return align
335
300
 
336
301
    def construct_bottom(self):
337
302
        """Construct the bottom half of the window."""
338
 
        if self.config.get_user_option('viz-wide-diffs') == 'True':
339
 
            self.diff_paned = gtk.VPaned()
340
 
        else:
341
 
            self.diff_paned = gtk.HPaned()
342
 
        (width, height) = self.get_size()
343
 
        self.diff_paned.set_size_request(20, 20) # shrinkable
344
 
 
345
303
        from bzrlib.plugins.gtk.revisionview import RevisionView
346
304
        self.revisionview = RevisionView(branch=self.branch)
347
 
        self.revisionview.set_size_request(width/3, int(height / 2.5))
348
 
        # user-configured size
349
 
        size = self._load_size('viz-revisionview-size')
350
 
        if size:
351
 
            width, height = size
352
 
            self.revisionview.set_size_request(width, height)
353
 
        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))
354
307
        self.revisionview.show()
355
308
        self.revisionview.set_show_callback(self._show_clicked_cb)
356
309
        self.revisionview.connect('notify::revision', self._go_clicked_cb)
357
310
        self.treeview.connect('tag-added', lambda w, t, r: self.revisionview.update_tags())
358
 
        self.diff_paned.pack1(self.revisionview)
359
 
 
360
 
        from bzrlib.plugins.gtk.diff import DiffWidget
361
 
        self.diff = DiffWidget()
362
 
        self.diff_paned.pack2(self.diff)
363
 
 
364
 
        self.diff_paned.show_all()
365
 
        if self.config.get_user_option('viz-show-diffs') != 'True':
366
 
            self.diff.hide()
367
 
 
368
 
        return self.diff_paned
 
311
        return self.revisionview
369
312
 
370
313
    def _tag_selected_cb(self, menuitem, revid):
371
314
        self.treeview.set_revision_id(revid)
376
319
        parents  = self.treeview.get_parents()
377
320
        children = self.treeview.get_children()
378
321
 
379
 
        self.revision_menu.set_revision_ids([revision.revision_id])
380
 
 
381
322
        if revision and revision != NULL_REVISION:
382
323
            prev_menu = gtk.Menu()
383
324
            if len(parents) > 0:
422
363
 
423
364
            self.revisionview.set_revision(revision)
424
365
            self.revisionview.set_children(children)
425
 
 
426
 
            self.update_diff_panel(revision, parents)
427
 
 
 
366
    
428
367
    def _tree_revision_activated(self, widget, path, col):
429
368
        # TODO: more than one parent
430
369
        """Callback for when a treeview row gets activated."""
439
378
        self.show_diff(revision.revision_id, parent_id)
440
379
        self.treeview.grab_focus()
441
380
        
 
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
 
442
394
    def _back_clicked_cb(self, *args):
443
395
        """Callback for when the back button is clicked."""
444
396
        self.treeview.back()
457
409
        self.show_diff(revid, parentid)
458
410
        self.treeview.grab_focus()
459
411
 
 
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
            
460
428
    def _set_revision_cb(self, w, revision_id):
461
429
        self.treeview.set_revision_id(revision_id)
462
430
 
472
440
        self.treeview.set_property('compact', self.compact_view)
473
441
        self.treeview.refresh()
474
442
 
475
 
    def _branch_index_cb(self, w):
476
 
        from bzrlib.plugins.search import index as _mod_index
477
 
        _mod_index.index_url(self.branch.base)
478
 
 
479
 
    def _branch_search_cb(self, w):
480
 
        from bzrlib.plugins.search import index as _mod_index
481
 
        from bzrlib.plugins.gtk.search import SearchDialog
482
 
        from bzrlib.plugins.search import errors as search_errors
483
 
 
 
443
    def _tag_revision_cb(self, w):
484
444
        try:
485
 
            index = _mod_index.open_index_url(self.branch.base)
486
 
        except search_errors.NoSearchIndex:
487
 
            dialog = gtk.MessageDialog(self, type=gtk.MESSAGE_QUESTION, 
488
 
                buttons=gtk.BUTTONS_OK_CANCEL, 
489
 
                message_format="This branch has not been indexed yet. "
490
 
                               "Index now?")
491
 
            if dialog.run() == gtk.RESPONSE_OK:
492
 
                dialog.destroy()
493
 
                index = _mod_index.index_url(self.branch.base)
494
 
            else:
495
 
                dialog.destroy()
496
 
                return
497
 
 
498
 
        dialog = SearchDialog(index)
499
 
        
500
 
        if dialog.run() == gtk.RESPONSE_OK:
501
 
            self.set_revision(dialog.get_revision())
502
 
 
503
 
        dialog.destroy()
 
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)
504
458
 
505
459
    def _about_dialog_cb(self, w):
506
460
        from bzrlib.plugins.gtk.about import AboutDialog
513
467
 
514
468
    def _toolbar_visibility_changed(self, col):
515
469
        if col.get_active():
516
 
            self.toolbar.show()
 
470
            self.toolbar.show() 
517
471
        else:
518
472
            self.toolbar.hide()
519
 
        self.config.set_user_option('viz-toolbar-visible', col.get_active())
520
 
 
521
 
    def _make_diff_nonzero_size(self):
522
 
        """make sure the diff isn't zero-width or zero-height"""
523
 
        alloc = self.diff.get_allocation()
524
 
        if (alloc.width < 10) or (alloc.height < 10):
525
 
            width, height = self.get_size()
526
 
            self.revisionview.set_size_request(width/3, int(height / 2.5))
527
 
 
528
 
    def _diff_visibility_changed(self, col):
529
 
        """Hide or show the diff panel."""
530
 
        if col.get_active():
531
 
            self.diff.show()
532
 
            self._make_diff_nonzero_size()
533
 
        else:
534
 
            self.diff.hide()
535
 
        self.config.set_user_option('viz-show-diffs', str(col.get_active()))
536
 
        self.update_diff_panel()
537
 
 
538
 
    def _diff_placement_changed(self, col):
539
 
        """Toggle the diff panel's position."""
540
 
        self.config.set_user_option('viz-wide-diffs', str(col.get_active()))
541
 
 
542
 
        old = self.paned.get_child2()
543
 
        self.paned.remove(old)
544
 
        self.paned.pack2(self.construct_bottom(), resize=True, shrink=False)
545
 
        self._make_diff_nonzero_size()
546
 
 
547
 
        self.treeview.emit('revision-selected')
548
473
 
549
474
    def _show_about_cb(self, w):
550
475
        dialog = AboutDialog()
576
501
 
577
502
        self.go_menu_tags.show_all()
578
503
 
579
 
    def _load_size(self, name):
580
 
        """Read and parse 'name' from self.config.
581
 
        The value is a string, formatted as WIDTHxHEIGHT
582
 
        Returns None, or (width, height)
583
 
        """
584
 
        size = self.config.get_user_option(name)
585
 
        if size:
586
 
            width, height = [int(num) for num in size.split('x')]
587
 
            # avoid writing config every time we start
588
 
            self._sizes[name] = (width, height)
589
 
            return width, height
590
 
        return None
591
 
 
592
 
    def _on_size_allocate(self, widget, allocation, name):
593
 
        """When window has been resized, save the new size."""
594
 
        width, height = 0, 0
595
 
        if name in self._sizes:
596
 
            width, height = self._sizes[name]
597
 
 
598
 
        size_changed = (width != allocation.width) or \
599
 
                (height != allocation.height)
600
 
 
601
 
        if size_changed:
602
 
            width, height = allocation.width, allocation.height
603
 
            self._sizes[name] = (width, height)
604
 
            value = '%sx%s' % (width, height)
605
 
            self.config.set_user_option(name, value)
606
 
 
607
504
    def show_diff(self, revid=None, parentid=None):
608
505
        """Open a new window to show a diff between the given revisions."""
609
506
        from bzrlib.plugins.gtk.diff import DiffWindow
619
516
        window.set_diff(description, rev_tree, parent_tree)
620
517
        window.show()
621
518
 
622
 
    def update_diff_panel(self, revision=None, parents=None):
623
 
        """Show the current revision in the diff panel."""
624
 
        if self.config.get_user_option('viz-show-diffs') != 'True':
625
 
            return
626
 
 
627
 
        if not revision: # default to selected row
628
 
            revision = self.treeview.get_revision()
629
 
        if (not revision) or (revision == NULL_REVISION):
630
 
            return
631
 
 
632
 
        if not parents: # default to selected row's parents
633
 
            parents  = self.treeview.get_parents()
634
 
        if len(parents) == 0:
635
 
            parent_id = None
636
 
        else:
637
 
            parent_id = parents[0]
638
 
 
639
 
        rev_tree    = self.branch.repository.revision_tree(revision.revision_id)
640
 
        parent_tree = self.branch.repository.revision_tree(parent_id)
641
 
 
642
 
        self.diff.set_diff(rev_tree, parent_tree)
643
 
        self.diff.show_all()
 
519