/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: Martin Albisetti
  • Date: 2008-06-03 01:43:08 UTC
  • Revision ID: argentina@gmail.com-20080603014308-9e6ao0hsike02m2b
Add GTK;GNOME; to olive-gtk.desktop Categories

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