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