/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: 2011-11-29 10:06:50 UTC
  • Revision ID: jelmer@samba.org-20111129100650-9oit3f44pxre4uq8
Credit Curtis.

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