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