/b-gtk/fix-viz

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