/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
0.1.1 by Dan Loda
First working version of xannotate.
1
# Copyright (C) 2005 Dan Loda <danloda@gmail.com>
175 by Jelmer Vernooij
Add very simple gmissing command.
2
# Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
0.1.1 by Dan Loda
First working version of xannotate.
3
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
18
import pygtk
19
pygtk.require("2.0")
20
import gtk
21
import pango
399.1.9 by Daniel Schierbeck
Merged with trunk.
22
import gobject
496.1.1 by Sabin Iacob (m0n5t3r)
use webbrowser.open instead of the debian-specific sensible-browser
23
import webbrowser
0.1.1 by Dan Loda
First working version of xannotate.
24
25
from bzrlib.osutils import format_date
412.1.8 by Daniel Schierbeck
Only import the bdecode function from the bzrlib.util.bencode package.
26
from bzrlib.util.bencode import bdecode
511.1.3 by Jelmer Vernooij
Make sure signed testament matches repository data.
27
from bzrlib.testament import Testament
28
29
from bzrlib.plugins.gtk import icon_path
0.1.1 by Dan Loda
First working version of xannotate.
30
399.3.27 by Daniel Schierbeck
Only show Signature tab if DBus and Seahorse are installed.
31
try:
399.3.29 by Daniel Schierbeck
Renamed the crypt module to seahorse.
32
    from bzrlib.plugins.gtk import seahorse
498.1.2 by Elliot Murphy
Trying to fix bug 107169 so that visualize can be used even if there are DBus problems which prevent seahorse from being loaded
33
except ImportError:
399.3.29 by Daniel Schierbeck
Renamed the crypt module to seahorse.
34
    has_seahorse = False
399.3.27 by Daniel Schierbeck
Only show Signature tab if DBus and Seahorse are installed.
35
else:
399.3.29 by Daniel Schierbeck
Renamed the crypt module to seahorse.
36
    has_seahorse = True
399.3.27 by Daniel Schierbeck
Only show Signature tab if DBus and Seahorse are installed.
37
450.1.19 by Daniel Schierbeck
Made sure the Signature page only gets updated when it is selected.
38
PAGE_GENERAL = 0
39
PAGE_RELATIONS = 1
40
PAGE_SIGNATURE = 2
41
PAGE_BUGS = 3
42
496.1.2 by Sabin Iacob (m0n5t3r)
also try xdg-open and sensible-browser
43
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
44
def _open_link(widget, uri):
498.2.1 by Sabin Iacob (m0n5t3r)
fix the browser opening code to work with python 2.4
45
    for cmd in ['sensible-browser', 'xdg-open']:
46
        if webbrowser._iscommand(cmd):
498.2.3 by Sabin Iacob (m0n5t3r)
fix typo, it actually works now
47
            webbrowser._tryorder.insert(0, '%s "%%s"' % cmd)
496.1.1 by Sabin Iacob (m0n5t3r)
use webbrowser.open instead of the debian-specific sensible-browser
48
    webbrowser.open(uri)
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
49
50
gtk.link_button_set_uri_hook(_open_link)
51
450.6.1 by Daniel Schierbeck
Made bug tab prettier.
52
class BugsTab(gtk.VBox):
399.3.1 by Daniel Schierbeck
Made the key id label disappear when the revision is not signed.
53
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
54
    def __init__(self):
450.6.1 by Daniel Schierbeck
Made bug tab prettier.
55
        super(BugsTab, self).__init__(False, 6)
450.6.11 by Daniel Schierbeck
Made Bugs page always visible, but only sensitive when the revision has bug associations.
56
    
450.6.1 by Daniel Schierbeck
Made bug tab prettier.
57
        table = gtk.Table(rows=2, columns=2)
58
59
        table.set_row_spacings(6)
450.6.7 by Daniel Schierbeck
Improved spacing in the bugs page.
60
        table.set_col_spacing(0, 16)
450.6.1 by Daniel Schierbeck
Made bug tab prettier.
61
62
        image = gtk.Image()
63
        image.set_from_file(icon_path("bug.png"))
64
        table.attach(image, 0, 1, 0, 1, gtk.FILL)
65
450.6.2 by Daniel Schierbeck
Further improved the look of the bug tab.
66
        align = gtk.Alignment(0.0, 0.1)
450.6.12 by Daniel Schierbeck
Changed Bugs page labels.
67
        self.label = gtk.Label()
68
        align.add(self.label)
450.6.1 by Daniel Schierbeck
Made bug tab prettier.
69
        table.attach(align, 1, 2, 0, 1, gtk.FILL)
70
71
        treeview = self.construct_treeview()
72
        table.attach(treeview, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND)
73
74
        self.set_border_width(6)
75
        self.pack_start(table, expand=False)
76
450.6.12 by Daniel Schierbeck
Changed Bugs page labels.
77
        self.clear()
450.6.11 by Daniel Schierbeck
Made Bugs page always visible, but only sensitive when the revision has bug associations.
78
        self.show_all()
450.6.1 by Daniel Schierbeck
Made bug tab prettier.
79
450.6.4 by Daniel Schierbeck
Moved bug parsing code into the bug page itself.
80
    def set_revision(self, revision):
81
        if revision is None:
82
            return
83
84
        self.clear()
450.6.5 by Daniel Schierbeck
Simplified bug parsing.
85
        bugs_text = revision.properties.get('bugs', '')
86
        for bugline in bugs_text.splitlines():
450.6.4 by Daniel Schierbeck
Moved bug parsing code into the bug page itself.
87
                (url, status) = bugline.split(" ")
450.6.10 by Daniel Schierbeck
Only show fixed bugs in Bugs page.
88
                if status == "fixed":
89
                    self.add_bug(url, status)
450.6.12 by Daniel Schierbeck
Changed Bugs page labels.
90
        
91
        if self.num_bugs == 0:
92
            return
93
        elif self.num_bugs == 1:
94
            label = "bug"
95
        else:
96
            label = "bugs"
97
98
        self.label.set_markup("<b>Bugs fixed</b>\n" +
99
                              "This revision claims to fix " +
100
                              "%d %s." % (self.num_bugs, label))
450.6.4 by Daniel Schierbeck
Moved bug parsing code into the bug page itself.
101
450.6.1 by Daniel Schierbeck
Made bug tab prettier.
102
    def construct_treeview(self):
103
        self.bugs = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
104
        self.treeview = gtk.TreeView(self.bugs)
450.6.8 by Daniel Schierbeck
Removed status column from bug table.
105
        self.treeview.set_headers_visible(False)
450.6.1 by Daniel Schierbeck
Made bug tab prettier.
106
107
        uri_column = gtk.TreeViewColumn('Bug URI', gtk.CellRendererText(), text=0)
108
        self.treeview.append_column(uri_column)
109
450.6.9 by Daniel Schierbeck
Made it possible to open bugs in the browser.
110
        self.treeview.connect('row-activated', self.on_row_activated)
111
450.6.1 by Daniel Schierbeck
Made bug tab prettier.
112
        win = gtk.ScrolledWindow()
113
        win.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
114
        win.set_shadow_type(gtk.SHADOW_IN)
115
        win.add(self.treeview)
116
117
        return win
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
118
119
    def clear(self):
450.6.11 by Daniel Schierbeck
Made Bugs page always visible, but only sensitive when the revision has bug associations.
120
        self.num_bugs = 0
450.6.1 by Daniel Schierbeck
Made bug tab prettier.
121
        self.bugs.clear()
450.6.11 by Daniel Schierbeck
Made Bugs page always visible, but only sensitive when the revision has bug associations.
122
        self.set_sensitive(False)
450.6.12 by Daniel Schierbeck
Changed Bugs page labels.
123
        self.label.set_markup("<b>No bugs fixed</b>\n" +
124
                              "This revision does not claim to fix any bugs.")
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
125
126
    def add_bug(self, url, status):
450.6.11 by Daniel Schierbeck
Made Bugs page always visible, but only sensitive when the revision has bug associations.
127
        self.num_bugs += 1
450.6.1 by Daniel Schierbeck
Made bug tab prettier.
128
        self.bugs.append([url, status])
450.6.11 by Daniel Schierbeck
Made Bugs page always visible, but only sensitive when the revision has bug associations.
129
        self.set_sensitive(True)
130
131
    def get_num_bugs(self):
132
        return self.num_bugs
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
133
450.6.9 by Daniel Schierbeck
Made it possible to open bugs in the browser.
134
    def on_row_activated(self, treeview, path, column):
135
        uri = self.bugs.get_value(self.bugs.get_iter(path), 0)
136
        _open_link(self, uri)
137
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
138
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
139
class SignatureTab(gtk.VBox):
399.3.1 by Daniel Schierbeck
Made the key id label disappear when the revision is not signed.
140
399.3.17 by Daniel Schierbeck
Moved signature handling into signature widget.
141
    def __init__(self, repository):
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
142
        self.key = None
399.3.23 by Daniel Schierbeck
Added comparison with revision committer.
143
        self.revision = None
399.3.17 by Daniel Schierbeck
Moved signature handling into signature widget.
144
        self.repository = repository
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
145
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
146
        super(SignatureTab, self).__init__(False, 6)
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
147
        signature_box = gtk.Table(rows=3, columns=3)
399.3.21 by Daniel Schierbeck
Played a bit with the spacings.
148
        signature_box.set_col_spacing(0, 16)
149
        signature_box.set_col_spacing(1, 12)
399.3.19 by Daniel Schierbeck
Increased row spacing in signature tab.
150
        signature_box.set_row_spacings(6)
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
151
152
        self.signature_image = gtk.Image()
153
        signature_box.attach(self.signature_image, 0, 1, 0, 1, gtk.FILL)
154
399.3.21 by Daniel Schierbeck
Played a bit with the spacings.
155
        align = gtk.Alignment(0.0, 0.1)
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
156
        self.signature_label = gtk.Label()
399.3.2 by Daniel Schierbeck
Moved key id label to the right.
157
        align.add(self.signature_label)
158
        signature_box.attach(align, 1, 3, 0, 1, gtk.FILL)
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
159
399.3.21 by Daniel Schierbeck
Played a bit with the spacings.
160
        align = gtk.Alignment(0.0, 0.5)
399.3.1 by Daniel Schierbeck
Made the key id label disappear when the revision is not signed.
161
        self.signature_key_id_label = gtk.Label()
162
        self.signature_key_id_label.set_markup("<b>Key Id:</b>")
163
        align.add(self.signature_key_id_label)
399.3.2 by Daniel Schierbeck
Moved key id label to the right.
164
        signature_box.attach(align, 1, 2, 1, 2, gtk.FILL, gtk.FILL)
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
165
166
        align = gtk.Alignment(0.0, 0.5)
167
        self.signature_key_id = gtk.Label()
168
        self.signature_key_id.set_selectable(True)
169
        align.add(self.signature_key_id)
399.3.2 by Daniel Schierbeck
Moved key id label to the right.
170
        signature_box.attach(align, 2, 3, 1, 2, gtk.EXPAND | gtk.FILL, gtk.FILL)
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
171
399.3.21 by Daniel Schierbeck
Played a bit with the spacings.
172
        align = gtk.Alignment(0.0, 0.5)
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
173
        self.signature_fingerprint_label = gtk.Label()
174
        self.signature_fingerprint_label.set_markup("<b>Fingerprint:</b>")
175
        align.add(self.signature_fingerprint_label)
176
        signature_box.attach(align, 1, 2, 2, 3, gtk.FILL, gtk.FILL)
177
178
        align = gtk.Alignment(0.0, 0.5)
179
        self.signature_fingerprint = gtk.Label()
180
        self.signature_fingerprint.set_selectable(True)
181
        align.add(self.signature_fingerprint)
182
        signature_box.attach(align, 2, 3, 2, 3, gtk.EXPAND | gtk.FILL, gtk.FILL)
183
399.3.6 by Daniel Schierbeck
Added support for key trust.
184
        align = gtk.Alignment(0.0, 0.5)
399.3.21 by Daniel Schierbeck
Played a bit with the spacings.
185
        self.signature_trust_label = gtk.Label()
186
        self.signature_trust_label.set_markup("<b>Trust:</b>")
187
        align.add(self.signature_trust_label)
188
        signature_box.attach(align, 1, 2, 3, 4, gtk.FILL, gtk.FILL)
189
190
        align = gtk.Alignment(0.0, 0.5)
399.3.6 by Daniel Schierbeck
Added support for key trust.
191
        self.signature_trust = gtk.Label()
192
        self.signature_trust.set_selectable(True)
193
        align.add(self.signature_trust)
194
        signature_box.attach(align, 2, 3, 3, 4, gtk.EXPAND | gtk.FILL, gtk.FILL)
195
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
196
        self.set_border_width(6)
197
        self.pack_start(signature_box, expand=False)
198
        self.show_all()
199
399.3.17 by Daniel Schierbeck
Moved signature handling into signature widget.
200
    def set_revision(self, revision):
201
        self.revision = revision
202
        revid = revision.revision_id
203
204
        if self.repository.has_signature_for_revision_id(revid):
399.3.30 by Daniel Schierbeck
Fixed some naming issues.
205
            crypttext = self.repository.get_signature_text(revid)
206
            self.show_signature(crypttext)
399.3.17 by Daniel Schierbeck
Moved signature handling into signature widget.
207
        else:
208
            self.show_no_signature()
209
399.1.16 by Jelmer Vernooij
Move logic showing images to the SignatureTab widget.
210
    def show_no_signature(self):
399.3.1 by Daniel Schierbeck
Made the key id label disappear when the revision is not signed.
211
        self.signature_key_id_label.hide()
399.1.16 by Jelmer Vernooij
Move logic showing images to the SignatureTab widget.
212
        self.signature_key_id.set_text("")
399.3.6 by Daniel Schierbeck
Added support for key trust.
213
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
214
        self.signature_fingerprint_label.hide()
215
        self.signature_fingerprint.set_text("")
399.3.6 by Daniel Schierbeck
Added support for key trust.
216
217
        self.signature_trust_label.hide()
218
        self.signature_trust.set_text("")
219
399.1.19 by Jelmer Vernooij
Add utility function for finding icon paths.
220
        self.signature_image.set_from_file(icon_path("sign-unknown.png"))
399.3.9 by Daniel Schierbeck
Added headings.
221
        self.signature_label.set_markup("<b>Authenticity unknown</b>\n" +
222
                                        "This revision has not been signed.")
399.1.16 by Jelmer Vernooij
Move logic showing images to the SignatureTab widget.
223
399.3.30 by Daniel Schierbeck
Fixed some naming issues.
224
    def show_signature(self, crypttext):
511.1.2 by Jelmer Vernooij
Return cleartext from seahorse module
225
        (cleartext, key) = seahorse.verify(crypttext)
399.3.3 by Daniel Schierbeck
Made the signature code use the Seahorse D-Bus service.
226
511.1.3 by Jelmer Vernooij
Make sure signed testament matches repository data.
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
236
450.5.3 by Daniel Schierbeck
Made the signature checking code not try to discover the signature key.
237
        if key and key.is_available():
399.3.23 by Daniel Schierbeck
Added comparison with revision committer.
238
            if key.is_trusted():
239
                if key.get_display_name() == self.revision.committer:
240
                    self.signature_image.set_from_file(icon_path("sign-ok.png"))
241
                    self.signature_label.set_markup("<b>Authenticity confirmed</b>\n" +
242
                                                    "This revision has been signed with " +
243
                                                    "a trusted key.")
244
                else:
245
                    self.signature_image.set_from_file(icon_path("sign-bad.png"))
246
                    self.signature_label.set_markup("<b>Authenticity cannot be confirmed</b>\n" +
247
                                                    "Revision committer is not the same as signer.")
248
            else:
249
                self.signature_image.set_from_file(icon_path("sign-bad.png"))
250
                self.signature_label.set_markup("<b>Authenticity cannot be confirmed</b>\n" +
251
                                                "This revision has been signed, but the " +
252
                                                "key is not trusted.")
253
        else:
399.3.11 by Daniel Schierbeck
Fixed error with unavailable keys.
254
            self.show_no_signature()
255
            self.signature_image.set_from_file(icon_path("sign-bad.png"))
399.3.13 by Daniel Schierbeck
Changed wording of authenticity heading.
256
            self.signature_label.set_markup("<b>Authenticity cannot be confirmed</b>\n" +
399.3.12 by Daniel Schierbeck
Fixed typo.
257
                                            "Signature key not available.")
399.3.11 by Daniel Schierbeck
Fixed error with unavailable keys.
258
            return
259
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
260
        trust = key.get_trust()
399.3.6 by Daniel Schierbeck
Added support for key trust.
261
399.3.29 by Daniel Schierbeck
Renamed the crypt module to seahorse.
262
        if trust <= seahorse.TRUST_NEVER:
399.3.6 by Daniel Schierbeck
Added support for key trust.
263
            trust_text = 'never trusted'
399.3.29 by Daniel Schierbeck
Renamed the crypt module to seahorse.
264
        elif trust == seahorse.TRUST_UNKNOWN:
399.3.6 by Daniel Schierbeck
Added support for key trust.
265
            trust_text = 'not trusted'
399.3.29 by Daniel Schierbeck
Renamed the crypt module to seahorse.
266
        elif trust == seahorse.TRUST_MARGINAL:
399.3.6 by Daniel Schierbeck
Added support for key trust.
267
            trust_text = 'marginally trusted'
399.3.29 by Daniel Schierbeck
Renamed the crypt module to seahorse.
268
        elif trust == seahorse.TRUST_FULL:
399.3.6 by Daniel Schierbeck
Added support for key trust.
269
            trust_text = 'fully trusted'
399.3.29 by Daniel Schierbeck
Renamed the crypt module to seahorse.
270
        elif trust == seahorse.TRUST_ULTIMATE:
399.3.6 by Daniel Schierbeck
Added support for key trust.
271
            trust_text = 'ultimately trusted'
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
272
399.3.1 by Daniel Schierbeck
Made the key id label disappear when the revision is not signed.
273
        self.signature_key_id_label.show()
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
274
        self.signature_key_id.set_text(key.get_id())
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
275
399.3.15 by Daniel Schierbeck
Made the fingerprint label read N/A when no fingerprint is available.
276
        fingerprint = key.get_fingerprint()
277
        if fingerprint == "":
399.3.18 by Daniel Schierbeck
Made empty fingerprint text grey.
278
            fingerprint = '<span foreground="dim grey">N/A</span>'
399.3.15 by Daniel Schierbeck
Made the fingerprint label read N/A when no fingerprint is available.
279
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
280
        self.signature_fingerprint_label.show()
399.3.18 by Daniel Schierbeck
Made empty fingerprint text grey.
281
        self.signature_fingerprint.set_markup(fingerprint)
399.3.3 by Daniel Schierbeck
Made the signature code use the Seahorse D-Bus service.
282
399.3.6 by Daniel Schierbeck
Added support for key trust.
283
        self.signature_trust_label.show()
284
        self.signature_trust.set_text('This key is ' + trust_text)
399.3.17 by Daniel Schierbeck
Moved signature handling into signature widget.
285
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
286
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
287
class RevisionView(gtk.Notebook):
0.1.1 by Dan Loda
First working version of xannotate.
288
    """ Custom widget for commit log details.
289
290
    A variety of bzr tools may need to implement such a thing. This is a
291
    start.
292
    """
293
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
294
    __gproperties__ = {
295
        'branch': (
296
            gobject.TYPE_PYOBJECT,
297
            'Branch',
298
            'The branch holding the revision being displayed',
299
            gobject.PARAM_CONSTRUCT_ONLY | gobject.PARAM_WRITABLE
300
        ),
301
302
        'revision': (
303
            gobject.TYPE_PYOBJECT,
304
            'Revision',
305
            'The revision being displayed',
412.1.2 by Daniel Schierbeck
Moved retrieval of tags into the revisionview itself.
306
            gobject.PARAM_READWRITE
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
307
        ),
308
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
309
        'children': (
310
            gobject.TYPE_PYOBJECT,
311
            'Children',
312
            'Child revisions',
313
            gobject.PARAM_READWRITE
314
        ),
315
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
316
        'file-id': (
317
            gobject.TYPE_PYOBJECT,
318
            'File Id',
319
            'The file id',
320
            gobject.PARAM_READWRITE
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
321
        )
322
    }
323
471.2.1 by Jelmer Vernooij
Fix gannotate.
324
    def __init__(self, branch=None, repository=None):
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
325
        gtk.Notebook.__init__(self)
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
326
399.3.17 by Daniel Schierbeck
Moved signature handling into signature widget.
327
        self._revision = None
328
        self._branch = branch
471.2.1 by Jelmer Vernooij
Fix gannotate.
329
        if branch is not None:
330
            self._repository = branch.repository
331
        else:
332
            self._repository = repository
399.3.17 by Daniel Schierbeck
Moved signature handling into signature widget.
333
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
334
        self._create_general()
335
        self._create_relations()
485 by Jelmer Vernooij
Disable signature tab until we actually start verifying the testament.
336
        # Disabled because testaments aren't verified yet:
511.1.1 by Jelmer Vernooij
Re-enable signature showing.
337
        if has_seahorse:
338
            self._create_signature()
278.1.45 by John Arbash Meinel
Switch to a new tab for per-file messages.
339
        self._create_file_info_view()
423.14.1 by Jelmer Vernooij
Add bugs tab to display bug status change metadata.
340
        self._create_bugs()
324.2.9 by Daniel Schierbeck
Made 'General' the default page of the logview.
341
450.1.19 by Daniel Schierbeck
Made sure the Signature page only gets updated when it is selected.
342
        self.set_current_page(PAGE_GENERAL)
450.1.20 by Daniel Schierbeck
Removed usage of lambda expressions as callbacks.
343
        self.connect_after('switch-page', self._switch_page_cb)
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
344
        
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
345
        self._show_callback = None
346
        self._clicked_callback = None
0.1.1 by Dan Loda
First working version of xannotate.
347
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
348
        self._revision = None
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
349
        self._branch = branch
350
423.7.4 by Daniel Schierbeck
Made revisionview and branchview update when a tag is added.
351
        self.update_tags()
412.1.2 by Daniel Schierbeck
Moved retrieval of tags into the revisionview itself.
352
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
353
        self.set_file_id(None)
0.1.1 by Dan Loda
First working version of xannotate.
354
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
355
    def do_get_property(self, property):
356
        if property.name == 'branch':
357
            return self._branch
358
        elif property.name == 'revision':
359
            return self._revision
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
360
        elif property.name == 'children':
361
            return self._children
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
362
        elif property.name == 'file-id':
363
            return self._file_id
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
364
        else:
365
            raise AttributeError, 'unknown property %s' % property.name
366
367
    def do_set_property(self, property, value):
368
        if property.name == 'branch':
369
            self._branch = value
370
        elif property.name == 'revision':
371
            self._set_revision(value)
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
372
        elif property.name == 'children':
373
            self.set_children(value)
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
374
        elif property.name == 'file-id':
375
            self._file_id = value
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
376
        else:
377
            raise AttributeError, 'unknown property %s' % property.name
378
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
379
    def set_show_callback(self, callback):
380
        self._show_callback = callback
381
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
382
    def set_file_id(self, file_id):
383
        """Set a specific file id that we want to track.
384
385
        This just effects the display of a per-file commit message.
386
        If it is set to None, then all commit messages will be shown.
387
        """
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
388
        self.set_property('file-id', file_id)
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
389
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
390
    def set_revision(self, revision):
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
391
        if revision != self._revision:
392
            self.set_property('revision', revision)
393
394
    def get_revision(self):
395
        return self.get_property('revision')
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
396
412.1.15 by Daniel Schierbeck
Removed redundant method argument.
397
    def _set_revision(self, revision):
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
398
        if revision is None: return
399
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
400
        self._revision = revision
192 by Jelmer Vernooij
Allow committer to be None.
401
        if revision.committer is not None:
402
            self.committer.set_text(revision.committer)
403
        else:
404
            self.committer.set_text("")
259 by Aaron Bentley
Add author support to gannotate and log viewer
405
        author = revision.properties.get('author', '')
406
        if author != '':
407
            self.author.set_text(author)
408
            self.author.show()
409
            self.author_label.show()
410
        else:
411
            self.author.hide()
412
            self.author_label.hide()
413
197 by Jelmer Vernooij
Fix some warnings when displaying ghost revisions. Reported by John.
414
        if revision.timestamp is not None:
415
            self.timestamp.set_text(format_date(revision.timestamp,
416
                                                revision.timezone))
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
417
        try:
418
            self.branchnick_label.set_text(revision.properties['branch-nick'])
419
        except KeyError:
420
            self.branchnick_label.set_text("")
421
256.2.23 by Gary van der Merwe
Show Children
422
        self._add_parents_or_children(revision.parent_ids,
423
                                      self.parents_widgets,
424
                                      self.parents_table)
425
        
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
426
        file_info = revision.properties.get('file-info', None)
278.1.2 by John Arbash Meinel
Add an extra box that pops up when we have per-file information.
427
        if file_info is not None:
412.1.8 by Daniel Schierbeck
Only import the bdecode function from the bzrlib.util.bencode package.
428
            file_info = bdecode(file_info.encode('UTF-8'))
278.1.2 by John Arbash Meinel
Add an extra box that pops up when we have per-file information.
429
430
        if file_info:
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
431
            if self._file_id is None:
432
                text = []
433
                for fi in file_info:
434
                    text.append('%(path)s\n%(message)s' % fi)
435
                self.file_info_buffer.set_text('\n'.join(text))
436
                self.file_info_box.show()
437
            else:
438
                text = []
439
                for fi in file_info:
440
                    if fi['file_id'] == self._file_id:
441
                        text.append(fi['message'])
442
                if text:
443
                    self.file_info_buffer.set_text('\n'.join(text))
444
                    self.file_info_box.show()
445
                else:
446
                    self.file_info_box.hide()
278.1.2 by John Arbash Meinel
Add an extra box that pops up when we have per-file information.
447
        else:
448
            self.file_info_box.hide()
449
423.7.4 by Daniel Schierbeck
Made revisionview and branchview update when a tag is added.
450
    def update_tags(self):
451
        if self._branch is not None and self._branch.supports_tags():
452
            self._tagdict = self._branch.tags.get_reverse_tag_dict()
453
        else:
454
            self._tagdict = {}
455
456
        self._add_tags()
457
450.1.20 by Daniel Schierbeck
Removed usage of lambda expressions as callbacks.
458
    def _update_signature(self, widget, param):
450.1.19 by Daniel Schierbeck
Made sure the Signature page only gets updated when it is selected.
459
        if self.get_current_page() == PAGE_SIGNATURE:
460
            self.signature_table.set_revision(self._revision)
399.1.13 by Daniel Schierbeck
Merged with mainline.
461
450.6.4 by Daniel Schierbeck
Moved bug parsing code into the bug page itself.
462
    def _update_bugs(self, widget, param):
463
        self.bugs_page.set_revision(self._revision)
450.6.11 by Daniel Schierbeck
Made Bugs page always visible, but only sensitive when the revision has bug associations.
464
        label = self.get_tab_label(self.bugs_page)
461.1.1 by Daniel Schierbeck
Merged bug page improvements.
465
        label.set_sensitive(self.bugs_page.get_num_bugs() != 0)
450.6.4 by Daniel Schierbeck
Moved bug parsing code into the bug page itself.
466
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
467
    def set_children(self, children):
468
        self._add_parents_or_children(children,
469
                                      self.children_widgets,
470
                                      self.children_table)
471
450.1.20 by Daniel Schierbeck
Removed usage of lambda expressions as callbacks.
472
    def _switch_page_cb(self, notebook, page, page_num):
473
        if page_num == PAGE_SIGNATURE:
474
            self.signature_table.set_revision(self._revision)
475
476
477
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
478
    def _show_clicked_cb(self, widget, revid, parentid):
479
        """Callback for when the show button for a parent is clicked."""
480
        self._show_callback(revid, parentid)
481
482
    def _go_clicked_cb(self, widget, revid):
483
        """Callback for when the go button for a parent is clicked."""
484
412.1.4 by Daniel Schierbeck
Made tag list smarter.
485
    def _add_tags(self, *args):
399.1.13 by Daniel Schierbeck
Merged with mainline.
486
        if self._revision is None:
487
            return
423.7.4 by Daniel Schierbeck
Made revisionview and branchview update when a tag is added.
488
412.1.4 by Daniel Schierbeck
Made tag list smarter.
489
        if self._tagdict.has_key(self._revision.revision_id):
490
            tags = self._tagdict[self._revision.revision_id]
491
        else:
492
            tags = []
493
            
241 by Jelmer Vernooij
Show tags in bzr viz.
494
        if tags == []:
495
            self.tags_list.hide()
496
            self.tags_label.hide()
497
            return
498
423.3.1 by Daniel Schierbeck
Made the tag list be a comma-separated line instead of a vertically stacked box.
499
        self.tags_list.set_text(", ".join(tags))
500
241 by Jelmer Vernooij
Show tags in bzr viz.
501
        self.tags_list.show_all()
502
        self.tags_label.show_all()
503
        
256.2.23 by Gary van der Merwe
Show Children
504
    def _add_parents_or_children(self, revids, widgets, table):
505
        while len(widgets) > 0:
506
            widget = widgets.pop()
507
            table.remove(widget)
508
        
509
        table.resize(max(len(revids), 1), 2)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
510
256.2.23 by Gary van der Merwe
Show Children
511
        for idx, revid in enumerate(revids):
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
512
            align = gtk.Alignment(0.0, 0.0)
256.2.23 by Gary van der Merwe
Show Children
513
            widgets.append(align)
514
            table.attach(align, 1, 2, idx, idx + 1,
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
515
                                      gtk.EXPAND | gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
516
            align.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
517
518
            hbox = gtk.HBox(False, spacing=6)
519
            align.add(hbox)
520
            hbox.show()
521
522
            image = gtk.Image()
523
            image.set_from_stock(
524
                gtk.STOCK_FIND, gtk.ICON_SIZE_SMALL_TOOLBAR)
525
            image.show()
526
148 by Jelmer Vernooij
Clean up interface a bit: don't show diff button when no diff can be accessed, use label instead of button when there is no callback set.
527
            if self._show_callback is not None:
528
                button = gtk.Button()
529
                button.add(image)
530
                button.connect("clicked", self._show_clicked_cb,
256.2.23 by Gary van der Merwe
Show Children
531
                               self._revision.revision_id, revid)
148 by Jelmer Vernooij
Clean up interface a bit: don't show diff button when no diff can be accessed, use label instead of button when there is no callback set.
532
                hbox.pack_start(button, expand=False, fill=True)
533
                button.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
534
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
535
            button = gtk.Button(revid)
536
            button.connect("clicked",
471.2.1 by Jelmer Vernooij
Fix gannotate.
537
                    lambda w, r: self.set_revision(self._repository.get_revision(r)), revid)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
538
            button.set_use_underline(False)
539
            hbox.pack_start(button, expand=False, fill=True)
540
            button.show()
0.1.1 by Dan Loda
First working version of xannotate.
541
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
542
    def _create_general(self):
0.1.1 by Dan Loda
First working version of xannotate.
543
        vbox = gtk.VBox(False, 6)
544
        vbox.set_border_width(6)
545
        vbox.pack_start(self._create_headers(), expand=False, fill=True)
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
546
        vbox.pack_start(self._create_message_view())
547
        self.append_page(vbox, tab_label=gtk.Label("General"))
548
        vbox.show()
549
550
    def _create_relations(self):
551
        vbox = gtk.VBox(False, 6)
552
        vbox.set_border_width(6)
291 by Jelmer Vernooij
Put children widget on a new line.
553
        vbox.pack_start(self._create_parents(), expand=False, fill=True)
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
554
        vbox.pack_start(self._create_children(), expand=False, fill=True)
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
555
        self.append_page(vbox, tab_label=gtk.Label("Relations"))
0.1.1 by Dan Loda
First working version of xannotate.
556
        vbox.show()
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
557
399.1.10 by Daniel Schierbeck
Improved implementation of the Signature page.
558
    def _create_signature(self):
471.2.1 by Jelmer Vernooij
Fix gannotate.
559
        self.signature_table = SignatureTab(self._repository)
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
560
        self.append_page(self.signature_table, tab_label=gtk.Label('Signature'))
450.1.20 by Daniel Schierbeck
Removed usage of lambda expressions as callbacks.
561
        self.connect_after('notify::revision', self._update_signature)
399.1.10 by Daniel Schierbeck
Improved implementation of the Signature page.
562
0.1.1 by Dan Loda
First working version of xannotate.
563
    def _create_headers(self):
241 by Jelmer Vernooij
Show tags in bzr viz.
564
        self.table = gtk.Table(rows=5, columns=2)
0.1.1 by Dan Loda
First working version of xannotate.
565
        self.table.set_row_spacings(6)
566
        self.table.set_col_spacings(6)
567
        self.table.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
568
569
        align = gtk.Alignment(1.0, 0.5)
570
        label = gtk.Label()
571
        label.set_markup("<b>Revision Id:</b>")
572
        align.add(label)
573
        self.table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
574
        align.show()
575
        label.show()
576
577
        align = gtk.Alignment(0.0, 0.5)
412.1.5 by Daniel Schierbeck
Made the revision id label use signals when updating.
578
        revision_id = gtk.Label()
579
        revision_id.set_selectable(True)
580
        self.connect('notify::revision', 
581
                lambda w, p: revision_id.set_text(self._revision.revision_id))
582
        align.add(revision_id)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
583
        self.table.attach(align, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.FILL)
584
        align.show()
412.1.5 by Daniel Schierbeck
Made the revision id label use signals when updating.
585
        revision_id.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
586
0.1.1 by Dan Loda
First working version of xannotate.
587
        align = gtk.Alignment(1.0, 0.5)
259 by Aaron Bentley
Add author support to gannotate and log viewer
588
        self.author_label = gtk.Label()
589
        self.author_label.set_markup("<b>Author:</b>")
590
        align.add(self.author_label)
591
        self.table.attach(align, 0, 1, 1, 2, gtk.FILL, gtk.FILL)
592
        align.show()
593
        self.author_label.show()
594
595
        align = gtk.Alignment(0.0, 0.5)
596
        self.author = gtk.Label()
597
        self.author.set_selectable(True)
598
        align.add(self.author)
599
        self.table.attach(align, 1, 2, 1, 2, gtk.EXPAND | gtk.FILL, gtk.FILL)
600
        align.show()
601
        self.author.show()
602
        self.author.hide()
603
604
        align = gtk.Alignment(1.0, 0.5)
0.1.1 by Dan Loda
First working version of xannotate.
605
        label = gtk.Label()
606
        label.set_markup("<b>Committer:</b>")
607
        align.add(label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
608
        self.table.attach(align, 0, 1, 2, 3, gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
609
        align.show()
610
        label.show()
611
612
        align = gtk.Alignment(0.0, 0.5)
613
        self.committer = gtk.Label()
614
        self.committer.set_selectable(True)
615
        align.add(self.committer)
259 by Aaron Bentley
Add author support to gannotate and log viewer
616
        self.table.attach(align, 1, 2, 2, 3, gtk.EXPAND | gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
617
        align.show()
618
        self.committer.show()
619
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
620
        align = gtk.Alignment(0.0, 0.5)
621
        label = gtk.Label()
622
        label.set_markup("<b>Branch nick:</b>")
623
        align.add(label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
624
        self.table.attach(align, 0, 1, 3, 4, gtk.FILL, gtk.FILL)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
625
        label.show()
626
        align.show()
627
628
        align = gtk.Alignment(0.0, 0.5)
629
        self.branchnick_label = gtk.Label()
630
        self.branchnick_label.set_selectable(True)
631
        align.add(self.branchnick_label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
632
        self.table.attach(align, 1, 2, 3, 4, gtk.EXPAND | gtk.FILL, gtk.FILL)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
633
        self.branchnick_label.show()
634
        align.show()
635
0.1.1 by Dan Loda
First working version of xannotate.
636
        align = gtk.Alignment(1.0, 0.5)
637
        label = gtk.Label()
638
        label.set_markup("<b>Timestamp:</b>")
639
        align.add(label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
640
        self.table.attach(align, 0, 1, 4, 5, gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
641
        align.show()
642
        label.show()
643
644
        align = gtk.Alignment(0.0, 0.5)
645
        self.timestamp = gtk.Label()
646
        self.timestamp.set_selectable(True)
647
        align.add(self.timestamp)
259 by Aaron Bentley
Add author support to gannotate and log viewer
648
        self.table.attach(align, 1, 2, 4, 5, gtk.EXPAND | gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
649
        align.show()
650
        self.timestamp.show()
651
241 by Jelmer Vernooij
Show tags in bzr viz.
652
        align = gtk.Alignment(1.0, 0.5)
653
        self.tags_label = gtk.Label()
654
        self.tags_label.set_markup("<b>Tags:</b>")
655
        align.add(self.tags_label)
656
        align.show()
261 by Aaron Bentley
Fix tags formatting
657
        self.table.attach(align, 0, 1, 5, 6, gtk.FILL, gtk.FILL)
241 by Jelmer Vernooij
Show tags in bzr viz.
658
        self.tags_label.show()
659
660
        align = gtk.Alignment(0.0, 0.5)
423.3.1 by Daniel Schierbeck
Made the tag list be a comma-separated line instead of a vertically stacked box.
661
        self.tags_list = gtk.Label()
241 by Jelmer Vernooij
Show tags in bzr viz.
662
        align.add(self.tags_list)
261 by Aaron Bentley
Fix tags formatting
663
        self.table.attach(align, 1, 2, 5, 6, gtk.EXPAND | gtk.FILL, gtk.FILL)
241 by Jelmer Vernooij
Show tags in bzr viz.
664
        align.show()
665
        self.tags_list.show()
666
412.1.4 by Daniel Schierbeck
Made tag list smarter.
667
        self.connect('notify::revision', self._add_tags)
668
0.1.1 by Dan Loda
First working version of xannotate.
669
        return self.table
256.2.23 by Gary van der Merwe
Show Children
670
    
291 by Jelmer Vernooij
Put children widget on a new line.
671
    def _create_parents(self):
672
        hbox = gtk.HBox(True, 3)
256.2.23 by Gary van der Merwe
Show Children
673
        
674
        self.parents_table = self._create_parents_or_children_table(
675
            "<b>Parents:</b>")
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
676
        self.parents_widgets = []
256.2.23 by Gary van der Merwe
Show Children
677
        hbox.pack_start(self.parents_table)
291 by Jelmer Vernooij
Put children widget on a new line.
678
679
        hbox.show()
680
        return hbox
681
682
    def _create_children(self):
683
        hbox = gtk.HBox(True, 3)
684
        self.children_table = self._create_parents_or_children_table(
685
            "<b>Children:</b>")
686
        self.children_widgets = []
687
        hbox.pack_start(self.children_table)
256.2.23 by Gary van der Merwe
Show Children
688
        hbox.show()
689
        return hbox
690
        
691
    def _create_parents_or_children_table(self, text):
692
        table = gtk.Table(rows=1, columns=2)
693
        table.set_row_spacings(3)
694
        table.set_col_spacings(6)
695
        table.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
696
697
        label = gtk.Label()
256.2.23 by Gary van der Merwe
Show Children
698
        label.set_markup(text)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
699
        align = gtk.Alignment(0.0, 0.5)
700
        align.add(label)
256.2.23 by Gary van der Merwe
Show Children
701
        table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
702
        label.show()
703
        align.show()
704
256.2.23 by Gary van der Merwe
Show Children
705
        return table
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
706
0.1.1 by Dan Loda
First working version of xannotate.
707
    def _create_message_view(self):
412.1.6 by Daniel Schierbeck
Made the message buffer use signals when updating.
708
        msg_buffer = gtk.TextBuffer()
709
        self.connect('notify::revision',
710
                lambda w, p: msg_buffer.set_text(self._revision.message))
324.2.2 by Daniel Schierbeck
Surrounded the commit message textview with a scrolled window and added a shadow.
711
        window = gtk.ScrolledWindow()
712
        window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
713
        window.set_shadow_type(gtk.SHADOW_IN)
412.1.6 by Daniel Schierbeck
Made the message buffer use signals when updating.
714
        tv = gtk.TextView(msg_buffer)
0.1.1 by Dan Loda
First working version of xannotate.
715
        tv.set_editable(False)
716
        tv.set_wrap_mode(gtk.WRAP_WORD)
399.1.13 by Daniel Schierbeck
Merged with mainline.
717
0.1.1 by Dan Loda
First working version of xannotate.
718
        tv.modify_font(pango.FontDescription("Monospace"))
719
        tv.show()
324.2.2 by Daniel Schierbeck
Surrounded the commit message textview with a scrolled window and added a shadow.
720
        window.add(tv)
721
        window.show()
722
        return window
0.1.1 by Dan Loda
First working version of xannotate.
723
423.14.1 by Jelmer Vernooij
Add bugs tab to display bug status change metadata.
724
    def _create_bugs(self):
450.6.4 by Daniel Schierbeck
Moved bug parsing code into the bug page itself.
725
        self.bugs_page = BugsTab()
726
        self.connect_after('notify::revision', self._update_bugs) 
727
        self.append_page(self.bugs_page, tab_label=gtk.Label('Bugs'))
423.14.1 by Jelmer Vernooij
Add bugs tab to display bug status change metadata.
728
278.1.2 by John Arbash Meinel
Add an extra box that pops up when we have per-file information.
729
    def _create_file_info_view(self):
278.1.45 by John Arbash Meinel
Switch to a new tab for per-file messages.
730
        self.file_info_box = gtk.VBox(False, 6)
731
        self.file_info_box.set_border_width(6)
278.1.2 by John Arbash Meinel
Add an extra box that pops up when we have per-file information.
732
        self.file_info_buffer = gtk.TextBuffer()
278.1.44 by John Arbash Meinel
Merge in trunk, and update logview per-file commit messages.
733
        window = gtk.ScrolledWindow()
734
        window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
735
        window.set_shadow_type(gtk.SHADOW_IN)
278.1.2 by John Arbash Meinel
Add an extra box that pops up when we have per-file information.
736
        tv = gtk.TextView(self.file_info_buffer)
737
        tv.set_editable(False)
738
        tv.set_wrap_mode(gtk.WRAP_WORD)
739
        tv.modify_font(pango.FontDescription("Monospace"))
740
        tv.show()
278.1.44 by John Arbash Meinel
Merge in trunk, and update logview per-file commit messages.
741
        window.add(tv)
742
        window.show()
743
        self.file_info_box.pack_start(window)
278.1.2 by John Arbash Meinel
Add an extra box that pops up when we have per-file information.
744
        self.file_info_box.hide() # Only shown when there are per-file messages
278.1.45 by John Arbash Meinel
Switch to a new tab for per-file messages.
745
        self.append_page(self.file_info_box, tab_label=gtk.Label('Per-file'))
278.1.2 by John Arbash Meinel
Add an extra box that pops up when we have per-file information.
746