/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 19:34:29 UTC
  • mto: This revision was merged to the branch mainline in revision 520.
  • Revision ID: jelmer@samba.org-20080629193429-ir2ilmbko6qkubg5
Add Branch/Index option if bzr-search is available.

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
 
20
from bzrlib.plugins.gtk.branchview import TreeView, treemodel
22
21
 
23
22
from bzrlib.config import BranchConfig, GlobalConfig
24
23
from bzrlib.revision import Revision, NULL_REVISION
48
47
        self.maxnum      = maxnum
49
48
        self.config      = GlobalConfig()
50
49
 
51
 
        self._sizes      = {} # window and widget sizes
52
 
 
53
50
        if self.config.get_user_option('viz-compact-view') == 'yes':
54
51
            self.compact_view = True
55
52
        else:
62
59
        monitor = screen.get_monitor_geometry(0)
63
60
        width = int(monitor.width * 0.75)
64
61
        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
62
        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
63
 
73
64
        # FIXME AndyFitz!
74
65
        icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
112
103
        self.add(vbox)
113
104
 
114
105
        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)
 
106
        self.paned.pack1(self.construct_top(), resize=True, shrink=False)
 
107
        self.paned.pack2(self.construct_bottom(), resize=False, shrink=True)
117
108
        self.paned.show()
118
109
 
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
 
 
 
110
        vbox.pack_start(self.construct_menubar(), expand=False, fill=True)
 
111
        vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
 
112
        
124
113
        vbox.pack_start(self.paned, expand=True, fill=True)
125
114
        vbox.set_focus_child(self.paned)
126
115
 
147
136
        edit_menuitem = gtk.MenuItem("_Edit")
148
137
        edit_menuitem.set_submenu(edit_menu)
149
138
 
 
139
        edit_menu_find = gtk.ImageMenuItem(gtk.STOCK_FIND)
 
140
 
150
141
        edit_menu_branchopts = gtk.MenuItem("Branch Settings")
151
142
        edit_menu_branchopts.connect('activate', lambda x: PreferencesWindow(self.branch.get_config()).show())
152
143
 
153
144
        edit_menu_globopts = gtk.MenuItem("Global Settings")
154
145
        edit_menu_globopts.connect('activate', lambda x: PreferencesWindow().show())
155
146
 
 
147
        edit_menu.add(edit_menu_find)
156
148
        edit_menu.add(edit_menu_branchopts)
157
149
        edit_menu.add(edit_menu_globopts)
158
150
 
168
160
 
169
161
        view_menu_toolbar = gtk.CheckMenuItem("Show Toolbar")
170
162
        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
163
        view_menu_toolbar.connect('toggled', self._toolbar_visibility_changed)
175
164
 
176
165
        view_menu_compact = gtk.CheckMenuItem("Show Compact Graph")
177
166
        view_menu_compact.set_active(self.compact_view)
178
167
        view_menu_compact.connect('activate', self._brokenlines_toggled_cb)
179
168
 
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
169
        view_menu.add(view_menu_toolbar)
193
170
        view_menu.add(view_menu_compact)
194
 
        view_menu.add(view_menu_diffs)
195
 
        view_menu.add(view_menu_wide_diffs)
196
171
        view_menu.add(gtk.SeparatorMenuItem())
197
172
 
198
173
        self.mnu_show_revno_column = gtk.CheckMenuItem("Show Revision _Number Column")
228
203
        go_menu.add(gtk.SeparatorMenuItem())
229
204
        go_menu.add(self.go_menu_tags)
230
205
 
231
 
        self.revision_menu = RevisionMenu(self.branch.repository, [], self.branch, parent=self)
 
206
        revision_menu = gtk.Menu()
232
207
        revision_menuitem = gtk.MenuItem("_Revision")
233
 
        revision_menuitem.set_submenu(self.revision_menu)
 
208
        revision_menuitem.set_submenu(revision_menu)
 
209
 
 
210
        revision_menu_diff = gtk.MenuItem("View Changes")
 
211
        revision_menu_diff.connect('activate', 
 
212
                self._menu_diff_cb)
 
213
        
 
214
        revision_menu_compare = gtk.MenuItem("Compare with...")
 
215
        revision_menu_compare.connect('activate',
 
216
                self._compare_with_cb)
 
217
 
 
218
        revision_menu_tag = gtk.MenuItem("Tag Revision")
 
219
        revision_menu_tag.connect('activate', self._tag_revision_cb)
 
220
 
 
221
        revision_menu.add(revision_menu_tag)
 
222
        revision_menu.add(revision_menu_diff)
 
223
        revision_menu.add(revision_menu_compare)
234
224
 
235
225
        branch_menu = gtk.Menu()
236
226
        branch_menuitem = gtk.MenuItem("_Branch")
244
234
        except ImportError:
245
235
            mutter("Didn't find search plugin")
246
236
        else:
247
 
            branch_menu.add(gtk.SeparatorMenuItem())
248
 
 
249
237
            branch_index_menuitem = gtk.MenuItem("_Index")
250
238
            branch_index_menuitem.connect('activate', self._branch_index_cb)
251
239
            branch_menu.add(branch_index_menuitem)
252
240
 
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
241
        help_menu = gtk.Menu()
258
242
        help_menuitem = gtk.MenuItem("_Help")
259
243
        help_menuitem.set_submenu(help_menu)
299
283
        align = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
300
284
        align.set_padding(5, 0, 0, 0)
301
285
        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
286
        align.show()
312
287
 
313
288
        return align
335
310
 
336
311
    def construct_bottom(self):
337
312
        """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
313
        from bzrlib.plugins.gtk.revisionview import RevisionView
346
314
        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')
 
315
        (width, height) = self.get_size()
 
316
        self.revisionview.set_size_request(width, int(height / 2.5))
354
317
        self.revisionview.show()
355
318
        self.revisionview.set_show_callback(self._show_clicked_cb)
356
319
        self.revisionview.connect('notify::revision', self._go_clicked_cb)
357
320
        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
 
321
        return self.revisionview
369
322
 
370
323
    def _tag_selected_cb(self, menuitem, revid):
371
324
        self.treeview.set_revision_id(revid)
376
329
        parents  = self.treeview.get_parents()
377
330
        children = self.treeview.get_children()
378
331
 
379
 
        self.revision_menu.set_revision_ids([revision.revision_id])
380
 
 
381
332
        if revision and revision != NULL_REVISION:
382
333
            prev_menu = gtk.Menu()
383
334
            if len(parents) > 0:
422
373
 
423
374
            self.revisionview.set_revision(revision)
424
375
            self.revisionview.set_children(children)
425
 
 
426
 
            self.update_diff_panel(revision, parents)
427
 
 
 
376
    
428
377
    def _tree_revision_activated(self, widget, path, col):
429
378
        # TODO: more than one parent
430
379
        """Callback for when a treeview row gets activated."""
439
388
        self.show_diff(revision.revision_id, parent_id)
440
389
        self.treeview.grab_focus()
441
390
        
 
391
    def _menu_diff_cb(self,w):
 
392
        (path, focus) = self.treeview.treeview.get_cursor()
 
393
        revid = self.treeview.model[path][treemodel.REVID]
 
394
        
 
395
        parentids = self.branch.repository.revision_parents(revid)
 
396
 
 
397
        if len(parentids) == 0:
 
398
            parentid = NULL_REVISION
 
399
        else:
 
400
            parentid = parentids[0]
 
401
        
 
402
        self.show_diff(revid,parentid)    
 
403
 
442
404
    def _back_clicked_cb(self, *args):
443
405
        """Callback for when the back button is clicked."""
444
406
        self.treeview.back()
457
419
        self.show_diff(revid, parentid)
458
420
        self.treeview.grab_focus()
459
421
 
 
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"""
 
425
        
 
426
        from bzrlib.plugins.gtk.revbrowser import RevisionBrowser
 
427
        
 
428
        rb = RevisionBrowser(self.branch,self)
 
429
        ret = rb.run()
 
430
        
 
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)
 
435
            
 
436
        rb.destroy()
 
437
            
460
438
    def _set_revision_cb(self, w, revision_id):
461
439
        self.treeview.set_revision_id(revision_id)
462
440
 
472
450
        self.treeview.set_property('compact', self.compact_view)
473
451
        self.treeview.refresh()
474
452
 
 
453
    def _tag_revision_cb(self, w):
 
454
        try:
 
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:
 
459
                dialog.hide()
 
460
            
 
461
                if response == gtk.RESPONSE_OK:
 
462
                    self.treeview.add_tag(dialog.tagname, dialog._revid)
 
463
                
 
464
                dialog.destroy()
 
465
 
 
466
        finally:
 
467
            self.treeview.set_sensitive(True)
 
468
 
475
469
    def _branch_index_cb(self, w):
476
470
        from bzrlib.plugins.search import index as _mod_index
477
471
        _mod_index.index_url(self.branch.base)
478
472
 
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
 
 
484
 
        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()
504
 
 
505
473
    def _about_dialog_cb(self, w):
506
474
        from bzrlib.plugins.gtk.about import AboutDialog
507
475
 
513
481
 
514
482
    def _toolbar_visibility_changed(self, col):
515
483
        if col.get_active():
516
 
            self.toolbar.show()
 
484
            self.toolbar.show() 
517
485
        else:
518
486
            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
487
 
549
488
    def _show_about_cb(self, w):
550
489
        dialog = AboutDialog()
576
515
 
577
516
        self.go_menu_tags.show_all()
578
517
 
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
518
    def show_diff(self, revid=None, parentid=None):
608
519
        """Open a new window to show a diff between the given revisions."""
609
520
        from bzrlib.plugins.gtk.diff import DiffWindow
619
530
        window.set_diff(description, rev_tree, parent_tree)
620
531
        window.show()
621
532
 
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()
 
533