/b-gtk/fix-viz

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