/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
471.2.1 by Jelmer Vernooij
Fix gannotate.
308
    def __init__(self, branch=None, repository=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
471.2.1 by Jelmer Vernooij
Fix gannotate.
313
        if branch is not None:
314
            self._repository = branch.repository
315
        else:
316
            self._repository = repository
399.3.17 by Daniel Schierbeck
Moved signature handling into signature widget.
317
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
318
        self._create_general()
319
        self._create_relations()
399.3.29 by Daniel Schierbeck
Renamed the crypt module to seahorse.
320
        if has_seahorse:
399.3.27 by Daniel Schierbeck
Only show Signature tab if DBus and Seahorse are installed.
321
            self._create_signature()
278.1.45 by John Arbash Meinel
Switch to a new tab for per-file messages.
322
        self._create_file_info_view()
423.14.1 by Jelmer Vernooij
Add bugs tab to display bug status change metadata.
323
        self._create_bugs()
324.2.9 by Daniel Schierbeck
Made 'General' the default page of the logview.
324
450.1.19 by Daniel Schierbeck
Made sure the Signature page only gets updated when it is selected.
325
        self.set_current_page(PAGE_GENERAL)
450.1.20 by Daniel Schierbeck
Removed usage of lambda expressions as callbacks.
326
        self.connect_after('switch-page', self._switch_page_cb)
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
327
        
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
328
        self._show_callback = None
329
        self._clicked_callback = None
0.1.1 by Dan Loda
First working version of xannotate.
330
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
331
        self._revision = None
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
332
        self._branch = branch
333
423.7.4 by Daniel Schierbeck
Made revisionview and branchview update when a tag is added.
334
        self.update_tags()
412.1.2 by Daniel Schierbeck
Moved retrieval of tags into the revisionview itself.
335
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
336
        self.set_file_id(None)
0.1.1 by Dan Loda
First working version of xannotate.
337
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
338
    def do_get_property(self, property):
339
        if property.name == 'branch':
340
            return self._branch
341
        elif property.name == 'revision':
342
            return self._revision
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
343
        elif property.name == 'children':
344
            return self._children
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
345
        elif property.name == 'file-id':
346
            return self._file_id
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
347
        else:
348
            raise AttributeError, 'unknown property %s' % property.name
349
350
    def do_set_property(self, property, value):
351
        if property.name == 'branch':
352
            self._branch = value
353
        elif property.name == 'revision':
354
            self._set_revision(value)
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
355
        elif property.name == 'children':
356
            self.set_children(value)
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
357
        elif property.name == 'file-id':
358
            self._file_id = value
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
359
        else:
360
            raise AttributeError, 'unknown property %s' % property.name
361
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
362
    def set_show_callback(self, callback):
363
        self._show_callback = callback
364
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
365
    def set_file_id(self, file_id):
366
        """Set a specific file id that we want to track.
367
368
        This just effects the display of a per-file commit message.
369
        If it is set to None, then all commit messages will be shown.
370
        """
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
371
        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.
372
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
373
    def set_revision(self, revision):
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
374
        if revision != self._revision:
375
            self.set_property('revision', revision)
376
377
    def get_revision(self):
378
        return self.get_property('revision')
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
379
412.1.15 by Daniel Schierbeck
Removed redundant method argument.
380
    def _set_revision(self, revision):
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
381
        if revision is None: return
382
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
383
        self._revision = revision
192 by Jelmer Vernooij
Allow committer to be None.
384
        if revision.committer is not None:
385
            self.committer.set_text(revision.committer)
386
        else:
387
            self.committer.set_text("")
259 by Aaron Bentley
Add author support to gannotate and log viewer
388
        author = revision.properties.get('author', '')
389
        if author != '':
390
            self.author.set_text(author)
391
            self.author.show()
392
            self.author_label.show()
393
        else:
394
            self.author.hide()
395
            self.author_label.hide()
396
197 by Jelmer Vernooij
Fix some warnings when displaying ghost revisions. Reported by John.
397
        if revision.timestamp is not None:
398
            self.timestamp.set_text(format_date(revision.timestamp,
399
                                                revision.timezone))
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
400
        try:
401
            self.branchnick_label.set_text(revision.properties['branch-nick'])
402
        except KeyError:
403
            self.branchnick_label.set_text("")
404
256.2.23 by Gary van der Merwe
Show Children
405
        self._add_parents_or_children(revision.parent_ids,
406
                                      self.parents_widgets,
407
                                      self.parents_table)
408
        
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
409
        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.
410
        if file_info is not None:
412.1.8 by Daniel Schierbeck
Only import the bdecode function from the bzrlib.util.bencode package.
411
            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.
412
413
        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.
414
            if self._file_id is None:
415
                text = []
416
                for fi in file_info:
417
                    text.append('%(path)s\n%(message)s' % fi)
418
                self.file_info_buffer.set_text('\n'.join(text))
419
                self.file_info_box.show()
420
            else:
421
                text = []
422
                for fi in file_info:
423
                    if fi['file_id'] == self._file_id:
424
                        text.append(fi['message'])
425
                if text:
426
                    self.file_info_buffer.set_text('\n'.join(text))
427
                    self.file_info_box.show()
428
                else:
429
                    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.
430
        else:
431
            self.file_info_box.hide()
432
423.7.4 by Daniel Schierbeck
Made revisionview and branchview update when a tag is added.
433
    def update_tags(self):
434
        if self._branch is not None and self._branch.supports_tags():
435
            self._tagdict = self._branch.tags.get_reverse_tag_dict()
436
        else:
437
            self._tagdict = {}
438
439
        self._add_tags()
440
450.1.20 by Daniel Schierbeck
Removed usage of lambda expressions as callbacks.
441
    def _update_signature(self, widget, param):
450.1.19 by Daniel Schierbeck
Made sure the Signature page only gets updated when it is selected.
442
        if self.get_current_page() == PAGE_SIGNATURE:
443
            self.signature_table.set_revision(self._revision)
399.1.13 by Daniel Schierbeck
Merged with mainline.
444
450.6.4 by Daniel Schierbeck
Moved bug parsing code into the bug page itself.
445
    def _update_bugs(self, widget, param):
446
        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.
447
        label = self.get_tab_label(self.bugs_page)
461.1.1 by Daniel Schierbeck
Merged bug page improvements.
448
        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.
449
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
450
    def set_children(self, children):
451
        self._add_parents_or_children(children,
452
                                      self.children_widgets,
453
                                      self.children_table)
454
450.1.20 by Daniel Schierbeck
Removed usage of lambda expressions as callbacks.
455
    def _switch_page_cb(self, notebook, page, page_num):
456
        if page_num == PAGE_SIGNATURE:
457
            self.signature_table.set_revision(self._revision)
458
459
460
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
461
    def _show_clicked_cb(self, widget, revid, parentid):
462
        """Callback for when the show button for a parent is clicked."""
463
        self._show_callback(revid, parentid)
464
465
    def _go_clicked_cb(self, widget, revid):
466
        """Callback for when the go button for a parent is clicked."""
467
412.1.4 by Daniel Schierbeck
Made tag list smarter.
468
    def _add_tags(self, *args):
399.1.13 by Daniel Schierbeck
Merged with mainline.
469
        if self._revision is None:
470
            return
423.7.4 by Daniel Schierbeck
Made revisionview and branchview update when a tag is added.
471
412.1.4 by Daniel Schierbeck
Made tag list smarter.
472
        if self._tagdict.has_key(self._revision.revision_id):
473
            tags = self._tagdict[self._revision.revision_id]
474
        else:
475
            tags = []
476
            
241 by Jelmer Vernooij
Show tags in bzr viz.
477
        if tags == []:
478
            self.tags_list.hide()
479
            self.tags_label.hide()
480
            return
481
423.3.1 by Daniel Schierbeck
Made the tag list be a comma-separated line instead of a vertically stacked box.
482
        self.tags_list.set_text(", ".join(tags))
483
241 by Jelmer Vernooij
Show tags in bzr viz.
484
        self.tags_list.show_all()
485
        self.tags_label.show_all()
486
        
256.2.23 by Gary van der Merwe
Show Children
487
    def _add_parents_or_children(self, revids, widgets, table):
488
        while len(widgets) > 0:
489
            widget = widgets.pop()
490
            table.remove(widget)
491
        
492
        table.resize(max(len(revids), 1), 2)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
493
256.2.23 by Gary van der Merwe
Show Children
494
        for idx, revid in enumerate(revids):
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
495
            align = gtk.Alignment(0.0, 0.0)
256.2.23 by Gary van der Merwe
Show Children
496
            widgets.append(align)
497
            table.attach(align, 1, 2, idx, idx + 1,
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
498
                                      gtk.EXPAND | gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
499
            align.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
500
501
            hbox = gtk.HBox(False, spacing=6)
502
            align.add(hbox)
503
            hbox.show()
504
505
            image = gtk.Image()
506
            image.set_from_stock(
507
                gtk.STOCK_FIND, gtk.ICON_SIZE_SMALL_TOOLBAR)
508
            image.show()
509
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.
510
            if self._show_callback is not None:
511
                button = gtk.Button()
512
                button.add(image)
513
                button.connect("clicked", self._show_clicked_cb,
256.2.23 by Gary van der Merwe
Show Children
514
                               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.
515
                hbox.pack_start(button, expand=False, fill=True)
516
                button.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
517
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
518
            button = gtk.Button(revid)
519
            button.connect("clicked",
471.2.1 by Jelmer Vernooij
Fix gannotate.
520
                    lambda w, r: self.set_revision(self._repository.get_revision(r)), revid)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
521
            button.set_use_underline(False)
522
            hbox.pack_start(button, expand=False, fill=True)
523
            button.show()
0.1.1 by Dan Loda
First working version of xannotate.
524
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
525
    def _create_general(self):
0.1.1 by Dan Loda
First working version of xannotate.
526
        vbox = gtk.VBox(False, 6)
527
        vbox.set_border_width(6)
528
        vbox.pack_start(self._create_headers(), expand=False, fill=True)
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
529
        vbox.pack_start(self._create_message_view())
530
        self.append_page(vbox, tab_label=gtk.Label("General"))
531
        vbox.show()
532
533
    def _create_relations(self):
534
        vbox = gtk.VBox(False, 6)
535
        vbox.set_border_width(6)
291 by Jelmer Vernooij
Put children widget on a new line.
536
        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.
537
        vbox.pack_start(self._create_children(), expand=False, fill=True)
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
538
        self.append_page(vbox, tab_label=gtk.Label("Relations"))
0.1.1 by Dan Loda
First working version of xannotate.
539
        vbox.show()
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
540
399.1.10 by Daniel Schierbeck
Improved implementation of the Signature page.
541
    def _create_signature(self):
471.2.1 by Jelmer Vernooij
Fix gannotate.
542
        self.signature_table = SignatureTab(self._repository)
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
543
        self.append_page(self.signature_table, tab_label=gtk.Label('Signature'))
450.1.20 by Daniel Schierbeck
Removed usage of lambda expressions as callbacks.
544
        self.connect_after('notify::revision', self._update_signature)
399.1.10 by Daniel Schierbeck
Improved implementation of the Signature page.
545
0.1.1 by Dan Loda
First working version of xannotate.
546
    def _create_headers(self):
241 by Jelmer Vernooij
Show tags in bzr viz.
547
        self.table = gtk.Table(rows=5, columns=2)
0.1.1 by Dan Loda
First working version of xannotate.
548
        self.table.set_row_spacings(6)
549
        self.table.set_col_spacings(6)
550
        self.table.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
551
552
        align = gtk.Alignment(1.0, 0.5)
553
        label = gtk.Label()
554
        label.set_markup("<b>Revision Id:</b>")
555
        align.add(label)
556
        self.table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
557
        align.show()
558
        label.show()
559
560
        align = gtk.Alignment(0.0, 0.5)
412.1.5 by Daniel Schierbeck
Made the revision id label use signals when updating.
561
        revision_id = gtk.Label()
562
        revision_id.set_selectable(True)
563
        self.connect('notify::revision', 
564
                lambda w, p: revision_id.set_text(self._revision.revision_id))
565
        align.add(revision_id)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
566
        self.table.attach(align, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.FILL)
567
        align.show()
412.1.5 by Daniel Schierbeck
Made the revision id label use signals when updating.
568
        revision_id.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
569
0.1.1 by Dan Loda
First working version of xannotate.
570
        align = gtk.Alignment(1.0, 0.5)
259 by Aaron Bentley
Add author support to gannotate and log viewer
571
        self.author_label = gtk.Label()
572
        self.author_label.set_markup("<b>Author:</b>")
573
        align.add(self.author_label)
574
        self.table.attach(align, 0, 1, 1, 2, gtk.FILL, gtk.FILL)
575
        align.show()
576
        self.author_label.show()
577
578
        align = gtk.Alignment(0.0, 0.5)
579
        self.author = gtk.Label()
580
        self.author.set_selectable(True)
581
        align.add(self.author)
582
        self.table.attach(align, 1, 2, 1, 2, gtk.EXPAND | gtk.FILL, gtk.FILL)
583
        align.show()
584
        self.author.show()
585
        self.author.hide()
586
587
        align = gtk.Alignment(1.0, 0.5)
0.1.1 by Dan Loda
First working version of xannotate.
588
        label = gtk.Label()
589
        label.set_markup("<b>Committer:</b>")
590
        align.add(label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
591
        self.table.attach(align, 0, 1, 2, 3, gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
592
        align.show()
593
        label.show()
594
595
        align = gtk.Alignment(0.0, 0.5)
596
        self.committer = gtk.Label()
597
        self.committer.set_selectable(True)
598
        align.add(self.committer)
259 by Aaron Bentley
Add author support to gannotate and log viewer
599
        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.
600
        align.show()
601
        self.committer.show()
602
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
603
        align = gtk.Alignment(0.0, 0.5)
604
        label = gtk.Label()
605
        label.set_markup("<b>Branch nick:</b>")
606
        align.add(label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
607
        self.table.attach(align, 0, 1, 3, 4, gtk.FILL, gtk.FILL)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
608
        label.show()
609
        align.show()
610
611
        align = gtk.Alignment(0.0, 0.5)
612
        self.branchnick_label = gtk.Label()
613
        self.branchnick_label.set_selectable(True)
614
        align.add(self.branchnick_label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
615
        self.table.attach(align, 1, 2, 3, 4, gtk.EXPAND | gtk.FILL, gtk.FILL)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
616
        self.branchnick_label.show()
617
        align.show()
618
0.1.1 by Dan Loda
First working version of xannotate.
619
        align = gtk.Alignment(1.0, 0.5)
620
        label = gtk.Label()
621
        label.set_markup("<b>Timestamp:</b>")
622
        align.add(label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
623
        self.table.attach(align, 0, 1, 4, 5, gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
624
        align.show()
625
        label.show()
626
627
        align = gtk.Alignment(0.0, 0.5)
628
        self.timestamp = gtk.Label()
629
        self.timestamp.set_selectable(True)
630
        align.add(self.timestamp)
259 by Aaron Bentley
Add author support to gannotate and log viewer
631
        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.
632
        align.show()
633
        self.timestamp.show()
634
241 by Jelmer Vernooij
Show tags in bzr viz.
635
        align = gtk.Alignment(1.0, 0.5)
636
        self.tags_label = gtk.Label()
637
        self.tags_label.set_markup("<b>Tags:</b>")
638
        align.add(self.tags_label)
639
        align.show()
261 by Aaron Bentley
Fix tags formatting
640
        self.table.attach(align, 0, 1, 5, 6, gtk.FILL, gtk.FILL)
241 by Jelmer Vernooij
Show tags in bzr viz.
641
        self.tags_label.show()
642
643
        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.
644
        self.tags_list = gtk.Label()
241 by Jelmer Vernooij
Show tags in bzr viz.
645
        align.add(self.tags_list)
261 by Aaron Bentley
Fix tags formatting
646
        self.table.attach(align, 1, 2, 5, 6, gtk.EXPAND | gtk.FILL, gtk.FILL)
241 by Jelmer Vernooij
Show tags in bzr viz.
647
        align.show()
648
        self.tags_list.show()
649
412.1.4 by Daniel Schierbeck
Made tag list smarter.
650
        self.connect('notify::revision', self._add_tags)
651
0.1.1 by Dan Loda
First working version of xannotate.
652
        return self.table
256.2.23 by Gary van der Merwe
Show Children
653
    
291 by Jelmer Vernooij
Put children widget on a new line.
654
    def _create_parents(self):
655
        hbox = gtk.HBox(True, 3)
256.2.23 by Gary van der Merwe
Show Children
656
        
657
        self.parents_table = self._create_parents_or_children_table(
658
            "<b>Parents:</b>")
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
659
        self.parents_widgets = []
256.2.23 by Gary van der Merwe
Show Children
660
        hbox.pack_start(self.parents_table)
291 by Jelmer Vernooij
Put children widget on a new line.
661
662
        hbox.show()
663
        return hbox
664
665
    def _create_children(self):
666
        hbox = gtk.HBox(True, 3)
667
        self.children_table = self._create_parents_or_children_table(
668
            "<b>Children:</b>")
669
        self.children_widgets = []
670
        hbox.pack_start(self.children_table)
256.2.23 by Gary van der Merwe
Show Children
671
        hbox.show()
672
        return hbox
673
        
674
    def _create_parents_or_children_table(self, text):
675
        table = gtk.Table(rows=1, columns=2)
676
        table.set_row_spacings(3)
677
        table.set_col_spacings(6)
678
        table.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
679
680
        label = gtk.Label()
256.2.23 by Gary van der Merwe
Show Children
681
        label.set_markup(text)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
682
        align = gtk.Alignment(0.0, 0.5)
683
        align.add(label)
256.2.23 by Gary van der Merwe
Show Children
684
        table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
685
        label.show()
686
        align.show()
687
256.2.23 by Gary van der Merwe
Show Children
688
        return table
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
689
0.1.1 by Dan Loda
First working version of xannotate.
690
    def _create_message_view(self):
412.1.6 by Daniel Schierbeck
Made the message buffer use signals when updating.
691
        msg_buffer = gtk.TextBuffer()
692
        self.connect('notify::revision',
693
                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.
694
        window = gtk.ScrolledWindow()
695
        window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
696
        window.set_shadow_type(gtk.SHADOW_IN)
412.1.6 by Daniel Schierbeck
Made the message buffer use signals when updating.
697
        tv = gtk.TextView(msg_buffer)
0.1.1 by Dan Loda
First working version of xannotate.
698
        tv.set_editable(False)
699
        tv.set_wrap_mode(gtk.WRAP_WORD)
399.1.13 by Daniel Schierbeck
Merged with mainline.
700
0.1.1 by Dan Loda
First working version of xannotate.
701
        tv.modify_font(pango.FontDescription("Monospace"))
702
        tv.show()
324.2.2 by Daniel Schierbeck
Surrounded the commit message textview with a scrolled window and added a shadow.
703
        window.add(tv)
704
        window.show()
705
        return window
0.1.1 by Dan Loda
First working version of xannotate.
706
423.14.1 by Jelmer Vernooij
Add bugs tab to display bug status change metadata.
707
    def _create_bugs(self):
450.6.4 by Daniel Schierbeck
Moved bug parsing code into the bug page itself.
708
        self.bugs_page = BugsTab()
709
        self.connect_after('notify::revision', self._update_bugs) 
710
        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.
711
278.1.2 by John Arbash Meinel
Add an extra box that pops up when we have per-file information.
712
    def _create_file_info_view(self):
278.1.45 by John Arbash Meinel
Switch to a new tab for per-file messages.
713
        self.file_info_box = gtk.VBox(False, 6)
714
        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.
715
        self.file_info_buffer = gtk.TextBuffer()
278.1.44 by John Arbash Meinel
Merge in trunk, and update logview per-file commit messages.
716
        window = gtk.ScrolledWindow()
717
        window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
718
        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.
719
        tv = gtk.TextView(self.file_info_buffer)
720
        tv.set_editable(False)
721
        tv.set_wrap_mode(gtk.WRAP_WORD)
722
        tv.modify_font(pango.FontDescription("Monospace"))
723
        tv.show()
278.1.44 by John Arbash Meinel
Merge in trunk, and update logview per-file commit messages.
724
        window.add(tv)
725
        window.show()
726
        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.
727
        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.
728
        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.
729