/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: 2011-04-10 18:44:39 UTC
  • mto: This revision was merged to the branch mainline in revision 730.
  • Revision ID: jelmer@samba.org-20110410184439-g7hqaacexqtviq13
Move i18n support to a separate file, so gettext files aren't loaded unless bzr-gtk is used.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: UTF-8 -*-
2
1
"""Branch window.
3
2
 
4
3
This module contains the code to manage the branch information window,
5
4
which contains both the revision graph and details panes.
6
5
"""
7
6
 
8
 
__copyright__ = "Copyright © 2005 Canonical Ltd."
 
7
__copyright__ = "Copyright (c) 2005 Canonical Ltd."
9
8
__author__    = "Scott James Remnant <scott@ubuntu.com>"
10
9
 
11
10
 
12
11
import gtk
13
 
import gobject
14
 
import pango
15
12
 
16
13
from bzrlib.plugins.gtk import icon_path
17
 
from bzrlib.plugins.gtk.branchview import TreeView, treemodel
18
 
from bzrlib.plugins.gtk.tags import AddTagDialog
 
14
from bzrlib.plugins.gtk.branchview import TreeView
19
15
from bzrlib.plugins.gtk.preferences import PreferencesWindow
20
16
from bzrlib.plugins.gtk.revisionmenu import RevisionMenu
21
17
from bzrlib.plugins.gtk.window import Window
22
18
 
23
 
from bzrlib.config import BranchConfig, GlobalConfig
24
 
from bzrlib.revision import Revision, NULL_REVISION
 
19
from bzrlib.config import GlobalConfig
 
20
from bzrlib.revision import NULL_REVISION
25
21
from bzrlib.trace import mutter
26
22
 
 
23
 
27
24
class BranchWindow(Window):
28
25
    """Branch window.
29
26
 
48
45
        self.maxnum      = maxnum
49
46
        self.config      = GlobalConfig()
50
47
 
51
 
        self._sizes      = {} # window and widget sizes
52
 
 
53
48
        if self.config.get_user_option('viz-compact-view') == 'yes':
54
49
            self.compact_view = True
55
50
        else:
56
51
            self.compact_view = False
57
52
 
58
 
        self.set_title(branch.nick + " - revision history")
 
53
        self.set_title(branch._get_nick(local=True) + " - revision history")
59
54
 
60
55
        # user-configured window size
61
56
        size = self._load_size('viz-window-size')
69
64
            height = int(monitor.height * 0.75)
70
65
        self.set_default_size(width, height)
71
66
        self.set_size_request(width/3, height/3)
72
 
        self.connect("size-allocate", self._on_size_allocate, 'viz-window-size')
 
67
        self._save_size_on_destroy(self, 'viz-window-size')
73
68
 
74
69
        # FIXME AndyFitz!
75
70
        icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
82
77
        self.accel_group = gtk.AccelGroup()
83
78
        self.add_accel_group(self.accel_group)
84
79
 
85
 
        gtk.Action.set_tool_item_type(gtk.MenuToolButton)
 
80
        if getattr(gtk.Action, 'set_tool_item_type', None) is not None:
 
81
            # Not available before PyGtk-2.10
 
82
            gtk.Action.set_tool_item_type(gtk.MenuToolButton)
86
83
 
87
84
        self.prev_rev_action = gtk.Action("prev-rev", "_Previous Revision", "Go to the previous revision", gtk.STOCK_GO_DOWN)
88
85
        self.prev_rev_action.set_accel_path("<viz>/Go/Previous Revision")
104
101
 
105
102
        self.construct()
106
103
 
 
104
    def _save_size_on_destroy(self, widget, config_name):
 
105
        """Creates a hook that saves the size of widget to config option 
 
106
           config_name when the window is destroyed/closed."""
 
107
        def save_size(src):
 
108
            width, height = widget.allocation.width, widget.allocation.height
 
109
            value = '%sx%s' % (width, height)
 
110
            self.config.set_user_option(config_name, value)
 
111
        self.connect("destroy", save_size)
 
112
 
107
113
    def set_revision(self, revid):
108
114
        self.treeview.set_revision_id(revid)
109
115
 
125
131
        vbox.pack_start(self.paned, expand=True, fill=True)
126
132
        vbox.set_focus_child(self.paned)
127
133
 
 
134
        self.treeview.connect('revision-selected',
 
135
                self._treeselection_changed_cb)
 
136
        self.treeview.connect('revision-activated',
 
137
                self._tree_revision_activated)
 
138
 
 
139
        self.treeview.connect('tag-added', lambda w, t, r: self._update_tags())
128
140
        vbox.show()
129
 
    
 
141
 
130
142
    def construct_menubar(self):
131
143
        menubar = gtk.MenuBar()
132
144
 
136
148
 
137
149
        file_menu_close = gtk.ImageMenuItem(gtk.STOCK_CLOSE, self.accel_group)
138
150
        file_menu_close.connect('activate', lambda x: self.destroy())
139
 
        
 
151
 
140
152
        file_menu_quit = gtk.ImageMenuItem(gtk.STOCK_QUIT, self.accel_group)
141
153
        file_menu_quit.connect('activate', lambda x: gtk.main_quit())
142
 
        
 
154
 
143
155
        if self._parent is not None:
144
156
            file_menu.add(file_menu_close)
145
157
        file_menu.add(file_menu_quit)
177
189
        view_menu_compact = gtk.CheckMenuItem("Show Compact Graph")
178
190
        view_menu_compact.set_active(self.compact_view)
179
191
        view_menu_compact.connect('activate', self._brokenlines_toggled_cb)
180
 
        
 
192
 
181
193
        view_menu_diffs = gtk.CheckMenuItem("Show Diffs")
182
194
        view_menu_diffs.set_active(False)
183
195
        if self.config.get_user_option('viz-show-diffs') == 'True':
184
196
            view_menu_diffs.set_active(True)
185
197
        view_menu_diffs.connect('toggled', self._diff_visibility_changed)
186
 
        
 
198
 
187
199
        view_menu_wide_diffs = gtk.CheckMenuItem("Wide Diffs")
188
200
        view_menu_wide_diffs.set_active(False)
189
201
        if self.config.get_user_option('viz-wide-diffs') == 'True':
190
202
            view_menu_wide_diffs.set_active(True)
191
203
        view_menu_wide_diffs.connect('toggled', self._diff_placement_changed)
192
 
        
 
204
 
193
205
        view_menu_wrap_diffs = gtk.CheckMenuItem("Wrap _Long Lines in Diffs")
194
206
        view_menu_wrap_diffs.set_active(False)
195
207
        if self.config.get_user_option('viz-wrap-diffs') == 'True':
196
208
            view_menu_wrap_diffs.set_active(True)
197
209
        view_menu_wrap_diffs.connect('toggled', self._diff_wrap_changed)
198
 
                
 
210
 
199
211
        view_menu.add(view_menu_toolbar)
200
212
        view_menu.add(view_menu_compact)
201
213
        view_menu.add(gtk.SeparatorMenuItem())
222
234
        go_menu.set_accel_group(self.accel_group)
223
235
        go_menuitem = gtk.MenuItem("_Go")
224
236
        go_menuitem.set_submenu(go_menu)
225
 
        
 
237
 
226
238
        go_menu_next = self.next_rev_action.create_menu_item()
227
239
        go_menu_prev = self.prev_rev_action.create_menu_item()
228
240
 
230
242
        tag_image.set_from_file(icon_path("tag-16.png"))
231
243
        self.go_menu_tags = gtk.ImageMenuItem("_Tags")
232
244
        self.go_menu_tags.set_image(tag_image)
233
 
        self._update_tags()
 
245
        self.treeview.connect('refreshed', lambda w: self._update_tags())
234
246
 
235
247
        go_menu.add(go_menu_next)
236
248
        go_menu.add(go_menu_prev)
289
301
 
290
302
        self.treeview = TreeView(self.branch, self.start_revs, self.maxnum, self.compact_view)
291
303
 
292
 
        self.treeview.connect('revision-selected',
293
 
                self._treeselection_changed_cb)
294
 
        self.treeview.connect('revision-activated',
295
 
                self._tree_revision_activated)
296
 
 
297
 
        self.treeview.connect('tag-added', lambda w, t, r: self._update_tags())
298
 
 
299
304
        for col in ["revno", "date"]:
300
305
            option = self.config.get_user_option(col + '-column-visible')
301
306
            if option is not None:
316
321
        else:
317
322
            (width, height) = self.get_size()
318
323
            align.set_size_request(width, int(height / 2.5))
319
 
        align.connect('size-allocate', self._on_size_allocate, 'viz-graph-size')
 
324
        self._save_size_on_destroy(align, 'viz-graph-size')
320
325
        align.show()
321
326
 
322
327
        return align
359
364
        if size:
360
365
            width, height = size
361
366
            self.revisionview.set_size_request(width, height)
362
 
        self.revisionview.connect('size-allocate', self._on_size_allocate, 'viz-revisionview-size')
 
367
        self._save_size_on_destroy(self.revisionview, 'viz-revisionview-size')
363
368
        self.revisionview.show()
364
369
        self.revisionview.set_show_callback(self._show_clicked_cb)
365
370
        self.revisionview.connect('notify::revision', self._go_clicked_cb)
407
412
                self.prev_rev_action.set_sensitive(False)
408
413
                prev_menu.hide()
409
414
 
410
 
            self.prev_button.set_menu(prev_menu)
 
415
            if getattr(self.prev_button, 'set_menu', None) is not None:
 
416
                self.prev_button.set_menu(prev_menu)
411
417
 
412
418
            next_menu = gtk.Menu()
413
419
            if len(children) > 0:
427
433
                self.next_rev_action.set_sensitive(False)
428
434
                next_menu.hide()
429
435
 
430
 
            self.next_button.set_menu(next_menu)
 
436
            if getattr(self.next_button, 'set_menu', None) is not None:
 
437
                self.next_button.set_menu(next_menu)
431
438
 
432
439
            self.revisionview.set_revision(revision)
433
440
            self.revisionview.set_children(children)
440
447
        parents  = self.treeview.get_parents()
441
448
 
442
449
        if len(parents) == 0:
443
 
            parent_id = None
 
450
            parent_id = NULL_REVISION
444
451
        else:
445
452
            parent_id = parents[0]
446
453
 
447
454
        self.show_diff(revision.revision_id, parent_id)
448
455
        self.treeview.grab_focus()
449
 
        
 
456
 
450
457
    def _back_clicked_cb(self, *args):
451
458
        """Callback for when the back button is clicked."""
452
459
        self.treeview.back()
453
 
        
 
460
 
454
461
    def _fwd_clicked_cb(self, *args):
455
462
        """Callback for when the forward button is clicked."""
456
463
        self.treeview.forward()
504
511
                return
505
512
 
506
513
        dialog = SearchDialog(index)
507
 
        
 
514
 
508
515
        if dialog.run() == gtk.RESPONSE_OK:
509
516
            self.set_revision(dialog.get_revision())
510
517
 
512
519
 
513
520
    def _about_dialog_cb(self, w):
514
521
        from bzrlib.plugins.gtk.about import AboutDialog
515
 
 
516
522
        AboutDialog().run()
517
523
 
518
524
    def _col_visibility_changed(self, col, property):
553
559
        self._make_diff_nonzero_size()
554
560
 
555
561
        self.treeview.emit('revision-selected')
556
 
    
 
562
 
557
563
    def _diff_wrap_changed(self, widget):
558
564
        """Toggle word wrap in the diff widget."""
559
565
        self.config.set_user_option('viz-wrap-diffs', widget.get_active())
560
566
        self.diff._on_wraplines_toggled(widget)
561
 
    
562
 
    def _show_about_cb(self, w):
563
 
        dialog = AboutDialog()
564
 
        dialog.connect('response', lambda d,r: d.destroy())
565
 
        dialog.run()
566
567
 
567
568
    def _refresh_clicked(self, w):
568
569
        self.treeview.refresh()
572
573
 
573
574
        if self.branch.supports_tags():
574
575
            tags = self.branch.tags.get_tag_dict().items()
575
 
            tags.sort()
576
 
            tags.reverse()
 
576
            tags.sort(reverse=True)
577
577
            for tag, revid in tags:
578
578
                tag_image = gtk.Image()
579
579
                tag_image.set_from_file(icon_path('tag-16.png'))
580
580
                tag_item = gtk.ImageMenuItem(tag.replace('_', '__'))
581
581
                tag_item.set_image(tag_image)
582
582
                tag_item.connect('activate', self._tag_selected_cb, revid)
 
583
                tag_item.set_sensitive(self.treeview.has_revision_id(revid))
583
584
                menu.add(tag_item)
584
585
            self.go_menu_tags.set_submenu(menu)
585
586
 
598
599
        if size:
599
600
            width, height = [int(num) for num in size.split('x')]
600
601
            # avoid writing config every time we start
601
 
            self._sizes[name] = (width, height)
602
602
            return width, height
603
603
        return None
604
604
 
605
 
    def _on_size_allocate(self, widget, allocation, name):
606
 
        """When window has been resized, save the new size."""
607
 
        width, height = 0, 0
608
 
        if name in self._sizes:
609
 
            width, height = self._sizes[name]
610
 
 
611
 
        size_changed = (width != allocation.width) or \
612
 
                (height != allocation.height)
613
 
 
614
 
        if size_changed:
615
 
            width, height = allocation.width, allocation.height
616
 
            self._sizes[name] = (width, height)
617
 
            value = '%sx%s' % (width, height)
618
 
            self.config.set_user_option(name, value)
619
 
 
620
 
    def show_diff(self, revid=None, parentid=None):
 
605
    def show_diff(self, revid=None, parentid=NULL_REVISION):
621
606
        """Open a new window to show a diff between the given revisions."""
622
607
        from bzrlib.plugins.gtk.diff import DiffWindow
623
608
        window = DiffWindow(parent=self)
624
609
 
625
 
        if parentid is None:
626
 
            parentid = NULL_REVISION
627
 
 
628
610
        rev_tree    = self.branch.repository.revision_tree(revid)
629
611
        parent_tree = self.branch.repository.revision_tree(parentid)
630
612
 
631
 
        description = revid + " - " + self.branch.nick
 
613
        description = revid + " - " + self.branch._get_nick(local=True)
632
614
        window.set_diff(description, rev_tree, parent_tree)
633
615
        window.show()
634
616
 
639
621
 
640
622
        if not revision: # default to selected row
641
623
            revision = self.treeview.get_revision()
642
 
        if (not revision) or (revision == NULL_REVISION):
 
624
        if revision == NULL_REVISION:
643
625
            return
644
626
 
645
627
        if not parents: # default to selected row's parents
646
628
            parents  = self.treeview.get_parents()
647
629
        if len(parents) == 0:
648
 
            parent_id = None
 
630
            parent_id = NULL_REVISION
649
631
        else:
650
632
            parent_id = parents[0]
651
633