/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 revisionview.py

  • Committer: Jelmer Vernooij
  • Date: 2008-07-17 11:51:03 UTC
  • Revision ID: jelmer@samba.org-20080717115103-djh5sb0pvpse2zkb
Add note about glade.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
17
 
18
 
from gi.repository import Gtk
19
 
from gi.repository import Pango
20
 
from gi.repository import GObject
 
18
import pygtk
 
19
pygtk.require("2.0")
 
20
import gtk
 
21
import pango
 
22
import gobject
21
23
import webbrowser
22
24
 
23
 
from bzrlib import trace
24
25
from bzrlib.osutils import format_date
25
 
try:
26
 
    from bzrlib.bencode import bdecode
27
 
except ImportError:
28
 
    from bzrlib.util.bencode import bdecode
 
26
from bzrlib.util.bencode import bdecode
29
27
from bzrlib.testament import Testament
30
28
 
31
29
from bzrlib.plugins.gtk import icon_path
32
30
 
33
 
from bzrlib.plugins.gtk.avatarsbox import AvatarsBox
34
 
 
35
31
try:
36
32
    from bzrlib.plugins.gtk import seahorse
37
33
except ImportError:
51
47
            webbrowser._tryorder.insert(0, '%s "%%s"' % cmd)
52
48
    webbrowser.open(uri)
53
49
 
54
 
if getattr(Gtk, 'link_button_set_uri_hook', None) is not None:
55
 
    Gtk.link_button_set_uri_hook(_open_link)
 
50
gtk.link_button_set_uri_hook(_open_link)
56
51
 
57
 
class BugsTab(Gtk.VBox):
 
52
class BugsTab(gtk.VBox):
58
53
 
59
54
    def __init__(self):
60
 
        super(BugsTab, self).__init__(homogeneous=False, spacing=6)
61
 
 
62
 
        table = Gtk.Table(rows=2, columns=2)
 
55
        super(BugsTab, self).__init__(False, 6)
 
56
    
 
57
        table = gtk.Table(rows=2, columns=2)
63
58
 
64
59
        table.set_row_spacings(6)
65
60
        table.set_col_spacing(0, 16)
66
61
 
67
 
        image = Gtk.Image()
 
62
        image = gtk.Image()
68
63
        image.set_from_file(icon_path("bug.png"))
69
 
        table.attach(image, 0, 1, 0, 1, Gtk.AttachOptions.FILL)
 
64
        table.attach(image, 0, 1, 0, 1, gtk.FILL)
70
65
 
71
 
        align = Gtk.Alignment.new(0.0, 0.1, 0, 0)
72
 
        self.label = Gtk.Label()
 
66
        align = gtk.Alignment(0.0, 0.1)
 
67
        self.label = gtk.Label()
73
68
        align.add(self.label)
74
 
        table.attach(align, 1, 2, 0, 1, Gtk.AttachOptions.FILL)
 
69
        table.attach(align, 1, 2, 0, 1, gtk.FILL)
75
70
 
76
71
        treeview = self.construct_treeview()
77
 
        table.attach(treeview, 1, 2, 1, 2, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND)
 
72
        table.attach(treeview, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND)
78
73
 
79
74
        self.set_border_width(6)
80
 
        self.pack_start(table, False, True, 0)
 
75
        self.pack_start(table, expand=False)
81
76
 
82
77
        self.clear()
83
78
        self.show_all()
92
87
                (url, status) = bugline.split(" ")
93
88
                if status == "fixed":
94
89
                    self.add_bug(url, status)
95
 
 
 
90
        
96
91
        if self.num_bugs == 0:
97
92
            return
98
93
        elif self.num_bugs == 1:
105
100
                              "%d %s." % (self.num_bugs, label))
106
101
 
107
102
    def construct_treeview(self):
108
 
        self.bugs = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
109
 
        self.treeview = Gtk.TreeView(model=self.bugs)
 
103
        self.bugs = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
 
104
        self.treeview = gtk.TreeView(self.bugs)
110
105
        self.treeview.set_headers_visible(False)
111
106
 
112
 
        uri_column = Gtk.TreeViewColumn('Bug URI', Gtk.CellRendererText(), text=0)
 
107
        uri_column = gtk.TreeViewColumn('Bug URI', gtk.CellRendererText(), text=0)
113
108
        self.treeview.append_column(uri_column)
114
109
 
115
110
        self.treeview.connect('row-activated', self.on_row_activated)
116
111
 
117
 
        win = Gtk.ScrolledWindow()
118
 
        win.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
119
 
        win.set_shadow_type(Gtk.ShadowType.IN)
 
112
        win = gtk.ScrolledWindow()
 
113
        win.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
 
114
        win.set_shadow_type(gtk.SHADOW_IN)
120
115
        win.add(self.treeview)
121
116
 
122
117
        return win
141
136
        _open_link(self, uri)
142
137
 
143
138
 
144
 
class SignatureTab(Gtk.VBox):
 
139
class SignatureTab(gtk.VBox):
145
140
 
146
141
    def __init__(self, repository):
147
142
        self.key = None
148
143
        self.revision = None
149
144
        self.repository = repository
150
145
 
151
 
        super(SignatureTab, self).__init__(homogeneous=False, spacing=6)
152
 
        signature_box = Gtk.Table(rows=3, columns=3)
 
146
        super(SignatureTab, self).__init__(False, 6)
 
147
        signature_box = gtk.Table(rows=3, columns=3)
153
148
        signature_box.set_col_spacing(0, 16)
154
149
        signature_box.set_col_spacing(1, 12)
155
150
        signature_box.set_row_spacings(6)
156
151
 
157
 
        self.signature_image = Gtk.Image()
158
 
        signature_box.attach(self.signature_image, 0, 1, 0, 1, Gtk.AttachOptions.FILL)
 
152
        self.signature_image = gtk.Image()
 
153
        signature_box.attach(self.signature_image, 0, 1, 0, 1, gtk.FILL)
159
154
 
160
 
        align = Gtk.Alignment.new(0.0, 0.1, 0.0, 0.0)
161
 
        self.signature_label = Gtk.Label()
 
155
        align = gtk.Alignment(0.0, 0.1)
 
156
        self.signature_label = gtk.Label()
162
157
        align.add(self.signature_label)
163
 
        signature_box.attach(align, 1, 3, 0, 1, Gtk.AttachOptions.FILL)
 
158
        signature_box.attach(align, 1, 3, 0, 1, gtk.FILL)
164
159
 
165
 
        align = Gtk.Alignment.new(0.0, 0.5, 0.0, 0.0)
166
 
        self.signature_key_id_label = Gtk.Label()
 
160
        align = gtk.Alignment(0.0, 0.5)
 
161
        self.signature_key_id_label = gtk.Label()
167
162
        self.signature_key_id_label.set_markup("<b>Key Id:</b>")
168
163
        align.add(self.signature_key_id_label)
169
 
        signature_box.attach(align, 1, 2, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
164
        signature_box.attach(align, 1, 2, 1, 2, gtk.FILL, gtk.FILL)
170
165
 
171
 
        align = Gtk.Alignment.new(0.0, 0.5, 0.0, 0.0)
172
 
        self.signature_key_id = Gtk.Label()
 
166
        align = gtk.Alignment(0.0, 0.5)
 
167
        self.signature_key_id = gtk.Label()
173
168
        self.signature_key_id.set_selectable(True)
174
169
        align.add(self.signature_key_id)
175
 
        signature_box.attach(align, 2, 3, 1, 2, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
170
        signature_box.attach(align, 2, 3, 1, 2, gtk.EXPAND | gtk.FILL, gtk.FILL)
176
171
 
177
 
        align = Gtk.Alignment.new(0.0, 0.5, 0.0, 0.0)
178
 
        self.signature_fingerprint_label = Gtk.Label()
 
172
        align = gtk.Alignment(0.0, 0.5)
 
173
        self.signature_fingerprint_label = gtk.Label()
179
174
        self.signature_fingerprint_label.set_markup("<b>Fingerprint:</b>")
180
175
        align.add(self.signature_fingerprint_label)
181
 
        signature_box.attach(align, 1, 2, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
176
        signature_box.attach(align, 1, 2, 2, 3, gtk.FILL, gtk.FILL)
182
177
 
183
 
        align = Gtk.Alignment.new(0.0, 0.5, 0.0, 0.0)
184
 
        self.signature_fingerprint = Gtk.Label()
 
178
        align = gtk.Alignment(0.0, 0.5)
 
179
        self.signature_fingerprint = gtk.Label()
185
180
        self.signature_fingerprint.set_selectable(True)
186
181
        align.add(self.signature_fingerprint)
187
 
        signature_box.attach(align, 2, 3, 2, 3, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
182
        signature_box.attach(align, 2, 3, 2, 3, gtk.EXPAND | gtk.FILL, gtk.FILL)
188
183
 
189
 
        align = Gtk.Alignment.new(0.0, 0.5, 0.0, 0.0)
190
 
        self.signature_trust_label = Gtk.Label()
 
184
        align = gtk.Alignment(0.0, 0.5)
 
185
        self.signature_trust_label = gtk.Label()
191
186
        self.signature_trust_label.set_markup("<b>Trust:</b>")
192
187
        align.add(self.signature_trust_label)
193
 
        signature_box.attach(align, 1, 2, 3, 4, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
188
        signature_box.attach(align, 1, 2, 3, 4, gtk.FILL, gtk.FILL)
194
189
 
195
 
        align = Gtk.Alignment.new(0.0, 0.5, 0.0, 0.0)
196
 
        self.signature_trust = Gtk.Label()
 
190
        align = gtk.Alignment(0.0, 0.5)
 
191
        self.signature_trust = gtk.Label()
197
192
        self.signature_trust.set_selectable(True)
198
193
        align.add(self.signature_trust)
199
 
        signature_box.attach(align, 2, 3, 3, 4, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
194
        signature_box.attach(align, 2, 3, 3, 4, gtk.EXPAND | gtk.FILL, gtk.FILL)
200
195
 
201
196
        self.set_border_width(6)
202
 
        self.pack_start(signature_box, False, True, 0)
 
197
        self.pack_start(signature_box, expand=False)
203
198
        self.show_all()
204
199
 
205
200
    def set_revision(self, revision):
289
284
        self.signature_trust.set_text('This key is ' + trust_text)
290
285
 
291
286
 
292
 
class RevisionView(Gtk.Notebook):
 
287
class RevisionView(gtk.Notebook):
293
288
    """ Custom widget for commit log details.
294
289
 
295
290
    A variety of bzr tools may need to implement such a thing. This is a
298
293
 
299
294
    __gproperties__ = {
300
295
        'branch': (
301
 
            GObject.TYPE_PYOBJECT,
 
296
            gobject.TYPE_PYOBJECT,
302
297
            'Branch',
303
298
            'The branch holding the revision being displayed',
304
 
            GObject.PARAM_CONSTRUCT_ONLY | GObject.PARAM_WRITABLE
 
299
            gobject.PARAM_CONSTRUCT_ONLY | gobject.PARAM_WRITABLE
305
300
        ),
306
301
 
307
302
        'revision': (
308
 
            GObject.TYPE_PYOBJECT,
 
303
            gobject.TYPE_PYOBJECT,
309
304
            'Revision',
310
305
            'The revision being displayed',
311
 
            GObject.PARAM_READWRITE
 
306
            gobject.PARAM_READWRITE
312
307
        ),
313
308
 
314
309
        'children': (
315
 
            GObject.TYPE_PYOBJECT,
 
310
            gobject.TYPE_PYOBJECT,
316
311
            'Children',
317
312
            'Child revisions',
318
 
            GObject.PARAM_READWRITE
 
313
            gobject.PARAM_READWRITE
319
314
        ),
320
315
 
321
316
        'file-id': (
322
 
            GObject.TYPE_PYOBJECT,
 
317
            gobject.TYPE_PYOBJECT,
323
318
            'File Id',
324
319
            'The file id',
325
 
            GObject.PARAM_READWRITE
 
320
            gobject.PARAM_READWRITE
326
321
        )
327
322
    }
328
323
 
329
324
    def __init__(self, branch=None, repository=None):
330
 
        Gtk.Notebook.__init__(self)
 
325
        gtk.Notebook.__init__(self)
331
326
 
332
327
        self._revision = None
333
328
        self._branch = branch
335
330
            self._repository = branch.repository
336
331
        else:
337
332
            self._repository = repository
338
 
        self.signature_table = None
339
333
 
340
334
        self._create_general()
341
335
        self._create_relations()
402
396
 
403
397
    def _set_revision(self, revision):
404
398
        if revision is None: return
405
 
        
406
 
        self.avatarsbox.reset()
407
 
        
 
399
 
408
400
        self._revision = revision
409
401
        if revision.committer is not None:
410
402
            self.committer.set_text(revision.committer)
411
 
            self.avatarsbox.add(revision.committer, "committer")
412
403
        else:
413
404
            self.committer.set_text("")
414
 
            self.avatarsbox.hide()
415
405
        author = revision.properties.get('author', '')
416
 
        self.avatarsbox.merge(revision.get_apparent_authors(), "author")
417
406
        if author != '':
418
407
            self.author.set_text(author)
419
408
            self.author.show()
426
415
            self.timestamp.set_text(format_date(revision.timestamp,
427
416
                                                revision.timezone))
428
417
        try:
429
 
            self.branchnick.show()
430
 
            self.branchnick_label.show()
431
 
            self.branchnick.set_text(revision.properties['branch-nick'])
 
418
            self.branchnick_label.set_text(revision.properties['branch-nick'])
432
419
        except KeyError:
433
 
            self.branchnick.hide()
434
 
            self.branchnick_label.hide()
 
420
            self.branchnick_label.set_text("")
435
421
 
436
422
        self._add_parents_or_children(revision.parent_ids,
437
423
                                      self.parents_widgets,
438
424
                                      self.parents_table)
439
 
 
 
425
        
440
426
        file_info = revision.properties.get('file-info', None)
441
427
        if file_info is not None:
442
 
            try:
443
 
                file_info = bdecode(file_info.encode('UTF-8'))
444
 
            except ValueError:
445
 
                trace.note('Invalid per-file info for revision:%s, value: %r',
446
 
                           revision.revision_id, file_info)
447
 
                file_info = None
 
428
            file_info = bdecode(file_info.encode('UTF-8'))
448
429
 
449
430
        if file_info:
450
431
            if self._file_id is None:
475
456
        self._add_tags()
476
457
 
477
458
    def _update_signature(self, widget, param):
478
 
        if not has_seahorse:
479
 
            return
480
459
        if self.get_current_page() == PAGE_SIGNATURE:
481
460
            self.signature_table.set_revision(self._revision)
482
461
 
491
470
                                      self.children_table)
492
471
 
493
472
    def _switch_page_cb(self, notebook, page, page_num):
494
 
        if not has_seahorse:
495
 
            return
496
473
        if page_num == PAGE_SIGNATURE:
497
474
            self.signature_table.set_revision(self._revision)
498
475
 
532
509
        table.resize(max(len(revids), 1), 2)
533
510
 
534
511
        for idx, revid in enumerate(revids):
535
 
            align = Gtk.Alignment.new(0.0, 0.0, 1, 1)
 
512
            align = gtk.Alignment(0.0, 0.0)
536
513
            widgets.append(align)
537
514
            table.attach(align, 1, 2, idx, idx + 1,
538
 
                                      Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
515
                                      gtk.EXPAND | gtk.FILL, gtk.FILL)
539
516
            align.show()
540
517
 
541
 
            hbox = Gtk.HBox(homogeneous=False, spacing=6)
 
518
            hbox = gtk.HBox(False, spacing=6)
542
519
            align.add(hbox)
543
520
            hbox.show()
544
521
 
545
 
            image = Gtk.Image()
 
522
            image = gtk.Image()
546
523
            image.set_from_stock(
547
 
                Gtk.STOCK_FIND, Gtk.IconSize.SMALL_TOOLBAR)
 
524
                gtk.STOCK_FIND, gtk.ICON_SIZE_SMALL_TOOLBAR)
548
525
            image.show()
549
526
 
550
527
            if self._show_callback is not None:
551
 
                button = Gtk.Button()
 
528
                button = gtk.Button()
552
529
                button.add(image)
553
530
                button.connect("clicked", self._show_clicked_cb,
554
531
                               self._revision.revision_id, revid)
555
 
                hbox.pack_start(button, False, True, True, 0)
 
532
                hbox.pack_start(button, expand=False, fill=True)
556
533
                button.show()
557
534
 
558
 
            button = Gtk.Button()
559
 
            revid_label = Gtk.Label(label=str(revid))
560
 
            revid_label.set_ellipsize(Pango.EllipsizeMode.MIDDLE)
561
 
            revid_label.set_alignment(0.0, 0.5)
562
 
            button.add(revid_label)
 
535
            button = gtk.Button(revid)
563
536
            button.connect("clicked",
564
 
                    lambda w, r: self.set_revision(
565
 
                        self._repository.get_revision(r)), revid)
 
537
                    lambda w, r: self.set_revision(self._repository.get_revision(r)), revid)
566
538
            button.set_use_underline(False)
567
 
            hbox.pack_start(button, True, True, 0)
568
 
            button.show_all()
 
539
            hbox.pack_start(button, expand=False, fill=True)
 
540
            button.show()
569
541
 
570
542
    def _create_general(self):
571
 
        vbox = Gtk.VBox(homogeneous=False, spacing=6)
 
543
        vbox = gtk.VBox(False, 6)
572
544
        vbox.set_border_width(6)
573
 
        vbox.pack_start(self._create_headers(), False, True, 0)
574
 
        vbox.pack_start(self._create_message_view(), True, True, 0)
575
 
        self.append_page(vbox, Gtk.Label(label="General"))
 
545
        vbox.pack_start(self._create_headers(), expand=False, fill=True)
 
546
        vbox.pack_start(self._create_message_view())
 
547
        self.append_page(vbox, tab_label=gtk.Label("General"))
576
548
        vbox.show()
577
549
 
578
550
    def _create_relations(self):
579
 
        vbox = Gtk.VBox(homogeneous=False, spacing=6)
 
551
        vbox = gtk.VBox(False, 6)
580
552
        vbox.set_border_width(6)
581
 
        vbox.pack_start(self._create_parents(), False, True, 0)
582
 
        vbox.pack_start(self._create_children(), False, True, 0)
583
 
        self.append_page(vbox, Gtk.Label(label="Relations"))
 
553
        vbox.pack_start(self._create_parents(), expand=False, fill=True)
 
554
        vbox.pack_start(self._create_children(), expand=False, fill=True)
 
555
        self.append_page(vbox, tab_label=gtk.Label("Relations"))
584
556
        vbox.show()
585
557
 
586
558
    def _create_signature(self):
587
559
        self.signature_table = SignatureTab(self._repository)
588
 
        self.append_page(
589
 
            self.signature_table, Gtk.Label(label='Signature'))
 
560
        self.append_page(self.signature_table, tab_label=gtk.Label('Signature'))
590
561
        self.connect_after('notify::revision', self._update_signature)
591
562
 
592
563
    def _create_headers(self):
593
 
        self.avatarsbox = AvatarsBox()
594
 
        
595
 
        self.table = Gtk.Table(rows=5, columns=2)
 
564
        self.table = gtk.Table(rows=5, columns=2)
596
565
        self.table.set_row_spacings(6)
597
566
        self.table.set_col_spacings(6)
598
567
        self.table.show()
599
 
        
600
 
        self.avatarsbox.pack_start(self.table, True, True, 0)
601
 
        self.avatarsbox.show()
602
 
 
603
 
        row = 0
604
 
 
605
 
        label = Gtk.Label()
606
 
        label.set_alignment(1.0, 0.5)
 
568
 
 
569
        align = gtk.Alignment(1.0, 0.5)
 
570
        label = gtk.Label()
607
571
        label.set_markup("<b>Revision Id:</b>")
608
 
        self.table.attach(label, 0, 1, row, row+1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
572
        align.add(label)
 
573
        self.table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
 
574
        align.show()
609
575
        label.show()
610
576
 
611
 
        revision_id = Gtk.Label()
612
 
        revision_id.set_ellipsize(Pango.EllipsizeMode.MIDDLE)
613
 
        revision_id.set_alignment(0.0, 0.5)
 
577
        align = gtk.Alignment(0.0, 0.5)
 
578
        revision_id = gtk.Label()
614
579
        revision_id.set_selectable(True)
615
580
        self.connect('notify::revision', 
616
581
                lambda w, p: revision_id.set_text(self._revision.revision_id))
617
 
        self.table.attach(revision_id, 1, 2, row, row+1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
582
        align.add(revision_id)
 
583
        self.table.attach(align, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
584
        align.show()
618
585
        revision_id.show()
619
586
 
620
 
        row += 1
621
 
        self.author_label = Gtk.Label()
622
 
        self.author_label.set_alignment(1.0, 0.5)
 
587
        align = gtk.Alignment(1.0, 0.5)
 
588
        self.author_label = gtk.Label()
623
589
        self.author_label.set_markup("<b>Author:</b>")
624
 
        self.table.attach(self.author_label, 0, 1, row, row+1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
590
        align.add(self.author_label)
 
591
        self.table.attach(align, 0, 1, 1, 2, gtk.FILL, gtk.FILL)
 
592
        align.show()
625
593
        self.author_label.show()
626
594
 
627
 
        self.author = Gtk.Label()
628
 
        self.author.set_ellipsize(Pango.EllipsizeMode.END)
629
 
        self.author.set_alignment(0.0, 0.5)
 
595
        align = gtk.Alignment(0.0, 0.5)
 
596
        self.author = gtk.Label()
630
597
        self.author.set_selectable(True)
631
 
        self.table.attach(self.author, 1, 2, row, row+1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
598
        align.add(self.author)
 
599
        self.table.attach(align, 1, 2, 1, 2, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
600
        align.show()
632
601
        self.author.show()
633
602
        self.author.hide()
634
603
 
635
 
        row += 1
636
 
        label = Gtk.Label()
637
 
        label.set_alignment(1.0, 0.5)
 
604
        align = gtk.Alignment(1.0, 0.5)
 
605
        label = gtk.Label()
638
606
        label.set_markup("<b>Committer:</b>")
639
 
        self.table.attach(label, 0, 1, row, row+1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
607
        align.add(label)
 
608
        self.table.attach(align, 0, 1, 2, 3, gtk.FILL, gtk.FILL)
 
609
        align.show()
640
610
        label.show()
641
611
 
642
 
        self.committer = Gtk.Label()
643
 
        self.committer.set_ellipsize(Pango.EllipsizeMode.END)
644
 
        self.committer.set_alignment(0.0, 0.5)
 
612
        align = gtk.Alignment(0.0, 0.5)
 
613
        self.committer = gtk.Label()
645
614
        self.committer.set_selectable(True)
646
 
        self.table.attach(self.committer, 1, 2, row, row+1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
615
        align.add(self.committer)
 
616
        self.table.attach(align, 1, 2, 2, 3, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
617
        align.show()
647
618
        self.committer.show()
648
619
 
649
 
        row += 1
650
 
        self.branchnick_label = Gtk.Label()
651
 
        self.branchnick_label.set_alignment(1.0, 0.5)
652
 
        self.branchnick_label.set_markup("<b>Branch nick:</b>")
653
 
        self.table.attach(self.branchnick_label, 0, 1, row, row+1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
620
        align = gtk.Alignment(0.0, 0.5)
 
621
        label = gtk.Label()
 
622
        label.set_markup("<b>Branch nick:</b>")
 
623
        align.add(label)
 
624
        self.table.attach(align, 0, 1, 3, 4, gtk.FILL, gtk.FILL)
 
625
        label.show()
 
626
        align.show()
 
627
 
 
628
        align = gtk.Alignment(0.0, 0.5)
 
629
        self.branchnick_label = gtk.Label()
 
630
        self.branchnick_label.set_selectable(True)
 
631
        align.add(self.branchnick_label)
 
632
        self.table.attach(align, 1, 2, 3, 4, gtk.EXPAND | gtk.FILL, gtk.FILL)
654
633
        self.branchnick_label.show()
655
 
 
656
 
        self.branchnick = Gtk.Label()
657
 
        self.branchnick.set_ellipsize(Pango.EllipsizeMode.MIDDLE)
658
 
        self.branchnick.set_alignment(0.0, 0.5)
659
 
        self.branchnick.set_selectable(True)
660
 
        self.table.attach(self.branchnick, 1, 2, row, row+1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
661
 
        self.branchnick.show()
662
 
 
663
 
        row += 1
664
 
        label = Gtk.Label()
665
 
        label.set_alignment(1.0, 0.5)
 
634
        align.show()
 
635
 
 
636
        align = gtk.Alignment(1.0, 0.5)
 
637
        label = gtk.Label()
666
638
        label.set_markup("<b>Timestamp:</b>")
667
 
        self.table.attach(label, 0, 1, row, row+1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
639
        align.add(label)
 
640
        self.table.attach(align, 0, 1, 4, 5, gtk.FILL, gtk.FILL)
 
641
        align.show()
668
642
        label.show()
669
643
 
670
 
        self.timestamp = Gtk.Label()
671
 
        self.timestamp.set_ellipsize(Pango.EllipsizeMode.END)
672
 
        self.timestamp.set_alignment(0.0, 0.5)
 
644
        align = gtk.Alignment(0.0, 0.5)
 
645
        self.timestamp = gtk.Label()
673
646
        self.timestamp.set_selectable(True)
674
 
        self.table.attach(self.timestamp, 1, 2, row, row+1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
647
        align.add(self.timestamp)
 
648
        self.table.attach(align, 1, 2, 4, 5, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
649
        align.show()
675
650
        self.timestamp.show()
676
651
 
677
 
        row += 1
678
 
        self.tags_label = Gtk.Label()
679
 
        self.tags_label.set_alignment(1.0, 0.5)
 
652
        align = gtk.Alignment(1.0, 0.5)
 
653
        self.tags_label = gtk.Label()
680
654
        self.tags_label.set_markup("<b>Tags:</b>")
681
 
        self.table.attach(self.tags_label, 0, 1, row, row+1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
655
        align.add(self.tags_label)
 
656
        align.show()
 
657
        self.table.attach(align, 0, 1, 5, 6, gtk.FILL, gtk.FILL)
682
658
        self.tags_label.show()
683
659
 
684
 
        self.tags_list = Gtk.Label()
685
 
        self.tags_list.set_ellipsize(Pango.EllipsizeMode.MIDDLE)
686
 
        self.tags_list.set_alignment(0.0, 0.5)
687
 
        self.table.attach(self.tags_list, 1, 2, row, row+1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
660
        align = gtk.Alignment(0.0, 0.5)
 
661
        self.tags_list = gtk.Label()
 
662
        align.add(self.tags_list)
 
663
        self.table.attach(align, 1, 2, 5, 6, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
664
        align.show()
688
665
        self.tags_list.show()
689
666
 
690
667
        self.connect('notify::revision', self._add_tags)
691
668
 
692
 
        self.avatarsbox.show()
693
 
        return self.avatarsbox
 
669
        return self.table
694
670
    
695
671
    def _create_parents(self):
696
 
        hbox = Gtk.HBox(homogeneous=True, spacing=3)
 
672
        hbox = gtk.HBox(True, 3)
697
673
        
698
674
        self.parents_table = self._create_parents_or_children_table(
699
675
            "<b>Parents:</b>")
700
676
        self.parents_widgets = []
701
 
        hbox.pack_start(self.parents_table, True, True, 0)
 
677
        hbox.pack_start(self.parents_table)
702
678
 
703
679
        hbox.show()
704
680
        return hbox
705
681
 
706
682
    def _create_children(self):
707
 
        hbox = Gtk.HBox(homogeneous=True, spacing=3)
 
683
        hbox = gtk.HBox(True, 3)
708
684
        self.children_table = self._create_parents_or_children_table(
709
685
            "<b>Children:</b>")
710
686
        self.children_widgets = []
711
 
        hbox.pack_start(self.children_table, True, True, 0)
 
687
        hbox.pack_start(self.children_table)
712
688
        hbox.show()
713
689
        return hbox
714
690
        
715
691
    def _create_parents_or_children_table(self, text):
716
 
        table = Gtk.Table(rows=1, columns=2)
 
692
        table = gtk.Table(rows=1, columns=2)
717
693
        table.set_row_spacings(3)
718
694
        table.set_col_spacings(6)
719
695
        table.show()
720
696
 
721
 
        label = Gtk.Label()
 
697
        label = gtk.Label()
722
698
        label.set_markup(text)
723
 
        align = Gtk.Alignment.new(0.0, 0.5, 0, 0)
 
699
        align = gtk.Alignment(0.0, 0.5)
724
700
        align.add(label)
725
 
        table.attach(align, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL)
 
701
        table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
726
702
        label.show()
727
703
        align.show()
728
704
 
729
705
        return table
730
706
 
731
707
    def _create_message_view(self):
732
 
        msg_buffer = Gtk.TextBuffer()
 
708
        msg_buffer = gtk.TextBuffer()
733
709
        self.connect('notify::revision',
734
710
                lambda w, p: msg_buffer.set_text(self._revision.message))
735
 
        window = Gtk.ScrolledWindow()
736
 
        window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
737
 
        window.set_shadow_type(Gtk.ShadowType.IN)
738
 
        tv = Gtk.TextView(buffer=msg_buffer)
 
711
        window = gtk.ScrolledWindow()
 
712
        window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
 
713
        window.set_shadow_type(gtk.SHADOW_IN)
 
714
        tv = gtk.TextView(msg_buffer)
739
715
        tv.set_editable(False)
740
 
        tv.set_wrap_mode(Gtk.WrapMode.WORD)
 
716
        tv.set_wrap_mode(gtk.WRAP_WORD)
741
717
 
742
 
        tv.modify_font(Pango.FontDescription("Monospace"))
 
718
        tv.modify_font(pango.FontDescription("Monospace"))
743
719
        tv.show()
744
720
        window.add(tv)
745
721
        window.show()
748
724
    def _create_bugs(self):
749
725
        self.bugs_page = BugsTab()
750
726
        self.connect_after('notify::revision', self._update_bugs) 
751
 
        self.append_page(self.bugs_page, Gtk.Label(label='Bugs'))
 
727
        self.append_page(self.bugs_page, tab_label=gtk.Label('Bugs'))
752
728
 
753
729
    def _create_file_info_view(self):
754
 
        self.file_info_box = Gtk.VBox(homogeneous=False, spacing=6)
 
730
        self.file_info_box = gtk.VBox(False, 6)
755
731
        self.file_info_box.set_border_width(6)
756
 
        self.file_info_buffer = Gtk.TextBuffer()
757
 
        window = Gtk.ScrolledWindow()
758
 
        window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
759
 
        window.set_shadow_type(Gtk.ShadowType.IN)
760
 
        tv = Gtk.TextView(buffer=self.file_info_buffer)
 
732
        self.file_info_buffer = gtk.TextBuffer()
 
733
        window = gtk.ScrolledWindow()
 
734
        window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
 
735
        window.set_shadow_type(gtk.SHADOW_IN)
 
736
        tv = gtk.TextView(self.file_info_buffer)
761
737
        tv.set_editable(False)
762
 
        tv.set_wrap_mode(Gtk.WrapMode.WORD)
763
 
        tv.modify_font(Pango.FontDescription("Monospace"))
 
738
        tv.set_wrap_mode(gtk.WRAP_WORD)
 
739
        tv.modify_font(pango.FontDescription("Monospace"))
764
740
        tv.show()
765
741
        window.add(tv)
766
742
        window.show()
767
 
        self.file_info_box.pack_start(window, True, True, 0)
 
743
        self.file_info_box.pack_start(window)
768
744
        self.file_info_box.hide() # Only shown when there are per-file messages
769
 
        self.append_page(self.file_info_box, Gtk.Label(label='Per-file'))
 
745
        self.append_page(self.file_info_box, tab_label=gtk.Label('Per-file'))
770
746