/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: Javier Derderian
  • Date: 2008-04-11 20:34:06 UTC
  • mto: (465.1.1 gtk.patch)
  • mto: This revision was merged to the branch mainline in revision 466.
  • Revision ID: javierder@gmail.com-20080411203406-ftlwyodw9vr87olv
Updated "Compare with..." (#78765) to use revbrowser.RevisionBrowser.
Also needed to fix #215872 to make it work.

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