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