/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
0.1.1 by Dan Loda
First working version of xannotate.
1
# Copyright (C) 2005 Dan Loda <danloda@gmail.com>
175 by Jelmer Vernooij
Add very simple gmissing command.
2
# Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
0.1.1 by Dan Loda
First working version of xannotate.
3
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
18
import pygtk
19
pygtk.require("2.0")
20
import gtk
21
import pango
399.1.9 by Daniel Schierbeck
Merged with trunk.
22
import gobject
423.14.1 by Jelmer Vernooij
Add bugs tab to display bug status change metadata.
23
import subprocess
399.3.3 by Daniel Schierbeck
Made the signature code use the Seahorse D-Bus service.
24
import dbus
0.1.1 by Dan Loda
First working version of xannotate.
25
399.1.19 by Jelmer Vernooij
Add utility function for finding icon paths.
26
from bzrlib.plugins.gtk import icon_path
399.3.4 by Daniel Schierbeck
Moved crypt code to crypt.py.
27
from bzrlib.plugins.gtk import crypt
0.1.1 by Dan Loda
First working version of xannotate.
28
from bzrlib.osutils import format_date
412.1.8 by Daniel Schierbeck
Only import the bdecode function from the bzrlib.util.bencode package.
29
from bzrlib.util.bencode import bdecode
0.1.1 by Dan Loda
First working version of xannotate.
30
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
31
def _open_link(widget, uri):
32
    subprocess.Popen(['sensible-browser', uri], close_fds=True)
33
34
gtk.link_button_set_uri_hook(_open_link)
35
36
class BugsTab(gtk.Table):
399.3.1 by Daniel Schierbeck
Made the key id label disappear when the revision is not signed.
37
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
38
    def __init__(self):
39
        super(BugsTab, self).__init__(rows=5, columns=2)
40
        self.set_row_spacings(6)
41
        self.set_col_spacings(6)
448 by Jelmer Vernooij
Add bugs tab in branch view.
42
        self.clear()
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
43
44
    def clear(self):
45
        for c in self.get_children():
46
            self.remove(c)
47
        self.count = 0
448 by Jelmer Vernooij
Add bugs tab in branch view.
48
        self.hide_all() # Only shown when there are bugs
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
49
50
    def add_bug(self, url, status):
51
        button = gtk.LinkButton(url, url)
52
        self.attach(button, 0, 1, self.count, self.count + 1,
53
                              gtk.EXPAND | gtk.FILL, gtk.FILL)
54
        status_label = gtk.Label(status)
55
        self.attach(status_label, 1, 2, self.count, self.count + 1,
56
                              gtk.EXPAND | gtk.FILL, gtk.FILL)
57
        self.count += 1
448 by Jelmer Vernooij
Add bugs tab in branch view.
58
        self.show_all()
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
59
60
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
61
class SignatureTab(gtk.VBox):
399.3.1 by Daniel Schierbeck
Made the key id label disappear when the revision is not signed.
62
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
63
    def __init__(self):
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
64
        self.key = None
65
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
66
        super(SignatureTab, self).__init__(False, 6)
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
67
        signature_box = gtk.Table(rows=3, columns=3)
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
68
        signature_box.set_col_spacing(0, 12)
399.3.2 by Daniel Schierbeck
Moved key id label to the right.
69
        signature_box.set_col_spacing(1, 6)
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
70
71
        self.signature_image = gtk.Image()
72
        signature_box.attach(self.signature_image, 0, 1, 0, 1, gtk.FILL)
73
74
        self.signature_label = gtk.Label()
399.3.2 by Daniel Schierbeck
Moved key id label to the right.
75
        align = gtk.Alignment(0.0, 0.5)
76
        align.add(self.signature_label)
77
        signature_box.attach(align, 1, 3, 0, 1, gtk.FILL)
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
78
79
        align = gtk.Alignment(1.0, 0.5)
399.3.1 by Daniel Schierbeck
Made the key id label disappear when the revision is not signed.
80
        self.signature_key_id_label = gtk.Label()
81
        self.signature_key_id_label.set_markup("<b>Key Id:</b>")
82
        align.add(self.signature_key_id_label)
399.3.2 by Daniel Schierbeck
Moved key id label to the right.
83
        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.
84
85
        align = gtk.Alignment(0.0, 0.5)
86
        self.signature_key_id = gtk.Label()
87
        self.signature_key_id.set_selectable(True)
88
        align.add(self.signature_key_id)
399.3.2 by Daniel Schierbeck
Moved key id label to the right.
89
        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.
90
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
91
        align = gtk.Alignment(1.0, 0.5)
92
        self.signature_fingerprint_label = gtk.Label()
93
        self.signature_fingerprint_label.set_markup("<b>Fingerprint:</b>")
94
        align.add(self.signature_fingerprint_label)
95
        signature_box.attach(align, 1, 2, 2, 3, gtk.FILL, gtk.FILL)
96
97
        align = gtk.Alignment(0.0, 0.5)
98
        self.signature_fingerprint = gtk.Label()
99
        self.signature_fingerprint.set_selectable(True)
100
        align.add(self.signature_fingerprint)
101
        signature_box.attach(align, 2, 3, 2, 3, gtk.EXPAND | gtk.FILL, gtk.FILL)
102
399.3.6 by Daniel Schierbeck
Added support for key trust.
103
        align = gtk.Alignment(0.0, 0.5)
104
        self.signature_trust = gtk.Label()
105
        self.signature_trust.set_selectable(True)
106
        align.add(self.signature_trust)
107
        signature_box.attach(align, 2, 3, 3, 4, gtk.EXPAND | gtk.FILL, gtk.FILL)
108
109
        align = gtk.Alignment(1.0, 0.5)
110
        self.signature_trust_label = gtk.Label()
111
        self.signature_trust_label.set_markup("<b>Trust:</b>")
112
        align.add(self.signature_trust_label)
113
        signature_box.attach(align, 1, 2, 3, 4, gtk.FILL, gtk.FILL)
114
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
115
        self.set_border_width(6)
116
        self.pack_start(signature_box, expand=False)
117
        self.show_all()
118
399.1.16 by Jelmer Vernooij
Move logic showing images to the SignatureTab widget.
119
    def show_no_signature(self):
399.3.1 by Daniel Schierbeck
Made the key id label disappear when the revision is not signed.
120
        self.signature_key_id_label.hide()
399.1.16 by Jelmer Vernooij
Move logic showing images to the SignatureTab widget.
121
        self.signature_key_id.set_text("")
399.3.6 by Daniel Schierbeck
Added support for key trust.
122
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
123
        self.signature_fingerprint_label.hide()
124
        self.signature_fingerprint.set_text("")
399.3.6 by Daniel Schierbeck
Added support for key trust.
125
126
        self.signature_trust_label.hide()
127
        self.signature_trust.set_text("")
128
399.1.19 by Jelmer Vernooij
Add utility function for finding icon paths.
129
        self.signature_image.set_from_file(icon_path("sign-unknown.png"))
399.3.9 by Daniel Schierbeck
Added headings.
130
        self.signature_label.set_markup("<b>Authenticity unknown</b>\n" +
131
                                        "This revision has not been signed.")
399.1.16 by Jelmer Vernooij
Move logic showing images to the SignatureTab widget.
132
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
133
    def show_signature(self, crypttext):
134
        key = crypt.verify(crypttext)
399.3.3 by Daniel Schierbeck
Made the signature code use the Seahorse D-Bus service.
135
399.3.11 by Daniel Schierbeck
Fixed error with unavailable keys.
136
        if not key.is_available():
137
            self.show_no_signature()
138
            self.signature_image.set_from_file(icon_path("sign-bad.png"))
139
            self.signature_label.set_markup("<b>Authentication error</b>\n" +
140
                                            "Signature key not available")
141
            return
142
143
        if key.is_trusted():
144
            self.signature_image.set_from_file(icon_path("sign-ok.png"))
145
            self.signature_label.set_markup("<b>Authenticity confirmed</b>\n" +
146
                                            "This revision has been signed by " +
147
                                            "a trusted party.")
148
        else:
149
            self.signature_image.set_from_file(icon_path("sign-bad.png"))
150
            self.signature_label.set_markup("<b>Authenticity cannot be confirmed</b>\n" +
151
                                            "This revision has been signed by " +
152
                                            "an untrusted party.")
153
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
154
        trust = key.get_trust()
399.3.6 by Daniel Schierbeck
Added support for key trust.
155
156
        if trust <= crypt.TRUST_NEVER:
157
            trust_text = 'never trusted'
158
        elif trust == crypt.TRUST_UNKNOWN:
159
            trust_text = 'not trusted'
160
        elif trust == crypt.TRUST_MARGINAL:
161
            trust_text = 'marginally trusted'
162
        elif trust == crypt.TRUST_FULL:
163
            trust_text = 'fully trusted'
164
        elif trust == crypt.TRUST_ULTIMATE:
165
            trust_text = 'ultimately trusted'
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
166
399.3.1 by Daniel Schierbeck
Made the key id label disappear when the revision is not signed.
167
        self.signature_key_id_label.show()
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
168
        self.signature_key_id.set_text(key.get_id())
399.3.5 by Daniel Schierbeck
Added support for key fingerprints.
169
170
        self.signature_fingerprint_label.show()
399.3.8 by Daniel Schierbeck
Moved crypt code into a Key class.
171
        self.signature_fingerprint.set_text(key.get_fingerprint())
399.3.3 by Daniel Schierbeck
Made the signature code use the Seahorse D-Bus service.
172
399.3.6 by Daniel Schierbeck
Added support for key trust.
173
        self.signature_trust_label.show()
174
        self.signature_trust.set_text('This key is ' + trust_text)
399.3.11 by Daniel Schierbeck
Fixed error with unavailable keys.
175
        
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
176
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
177
class RevisionView(gtk.Notebook):
0.1.1 by Dan Loda
First working version of xannotate.
178
    """ Custom widget for commit log details.
179
180
    A variety of bzr tools may need to implement such a thing. This is a
181
    start.
182
    """
183
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
184
    __gproperties__ = {
185
        'branch': (
186
            gobject.TYPE_PYOBJECT,
187
            'Branch',
188
            'The branch holding the revision being displayed',
189
            gobject.PARAM_CONSTRUCT_ONLY | gobject.PARAM_WRITABLE
190
        ),
191
192
        'revision': (
193
            gobject.TYPE_PYOBJECT,
194
            'Revision',
195
            'The revision being displayed',
412.1.2 by Daniel Schierbeck
Moved retrieval of tags into the revisionview itself.
196
            gobject.PARAM_READWRITE
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
197
        ),
198
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
199
        'children': (
200
            gobject.TYPE_PYOBJECT,
201
            'Children',
202
            'Child revisions',
203
            gobject.PARAM_READWRITE
204
        ),
205
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
206
        'file-id': (
207
            gobject.TYPE_PYOBJECT,
208
            'File Id',
209
            'The file id',
210
            gobject.PARAM_READWRITE
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
211
        )
212
    }
213
214
412.1.2 by Daniel Schierbeck
Moved retrieval of tags into the revisionview itself.
215
    def __init__(self, branch=None):
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
216
        gtk.Notebook.__init__(self)
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
217
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
218
        self._create_general()
219
        self._create_relations()
399.1.6 by Daniel Schierbeck
Made signature page label singular.
220
        self._create_signature()
278.1.45 by John Arbash Meinel
Switch to a new tab for per-file messages.
221
        self._create_file_info_view()
423.14.1 by Jelmer Vernooij
Add bugs tab to display bug status change metadata.
222
        self._create_bugs()
324.2.9 by Daniel Schierbeck
Made 'General' the default page of the logview.
223
224
        self.set_current_page(0)
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
225
        
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
226
        self._show_callback = None
227
        self._clicked_callback = None
0.1.1 by Dan Loda
First working version of xannotate.
228
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
229
        self._revision = None
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
230
        self._branch = branch
231
423.7.4 by Daniel Schierbeck
Made revisionview and branchview update when a tag is added.
232
        self.update_tags()
412.1.2 by Daniel Schierbeck
Moved retrieval of tags into the revisionview itself.
233
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
234
        self.set_file_id(None)
0.1.1 by Dan Loda
First working version of xannotate.
235
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
236
    def do_get_property(self, property):
237
        if property.name == 'branch':
238
            return self._branch
239
        elif property.name == 'revision':
240
            return self._revision
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
241
        elif property.name == 'children':
242
            return self._children
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
243
        elif property.name == 'file-id':
244
            return self._file_id
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
245
        else:
246
            raise AttributeError, 'unknown property %s' % property.name
247
248
    def do_set_property(self, property, value):
249
        if property.name == 'branch':
250
            self._branch = value
251
        elif property.name == 'revision':
252
            self._set_revision(value)
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
253
        elif property.name == 'children':
254
            self.set_children(value)
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
255
        elif property.name == 'file-id':
256
            self._file_id = value
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
257
        else:
258
            raise AttributeError, 'unknown property %s' % property.name
259
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
260
    def set_show_callback(self, callback):
261
        self._show_callback = callback
262
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
263
    def set_file_id(self, file_id):
264
        """Set a specific file id that we want to track.
265
266
        This just effects the display of a per-file commit message.
267
        If it is set to None, then all commit messages will be shown.
268
        """
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
269
        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.
270
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
271
    def set_revision(self, revision):
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
272
        if revision != self._revision:
273
            self.set_property('revision', revision)
274
275
    def get_revision(self):
276
        return self.get_property('revision')
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
277
412.1.15 by Daniel Schierbeck
Removed redundant method argument.
278
    def _set_revision(self, revision):
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
279
        if revision is None: return
280
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
281
        self._revision = revision
192 by Jelmer Vernooij
Allow committer to be None.
282
        if revision.committer is not None:
283
            self.committer.set_text(revision.committer)
284
        else:
285
            self.committer.set_text("")
259 by Aaron Bentley
Add author support to gannotate and log viewer
286
        author = revision.properties.get('author', '')
287
        if author != '':
288
            self.author.set_text(author)
289
            self.author.show()
290
            self.author_label.show()
291
        else:
292
            self.author.hide()
293
            self.author_label.hide()
294
197 by Jelmer Vernooij
Fix some warnings when displaying ghost revisions. Reported by John.
295
        if revision.timestamp is not None:
296
            self.timestamp.set_text(format_date(revision.timestamp,
297
                                                revision.timezone))
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
298
        try:
299
            self.branchnick_label.set_text(revision.properties['branch-nick'])
300
        except KeyError:
301
            self.branchnick_label.set_text("")
302
256.2.23 by Gary van der Merwe
Show Children
303
        self._add_parents_or_children(revision.parent_ids,
304
                                      self.parents_widgets,
305
                                      self.parents_table)
306
        
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
307
        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.
308
        if file_info is not None:
412.1.8 by Daniel Schierbeck
Only import the bdecode function from the bzrlib.util.bencode package.
309
            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.
310
311
        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.
312
            if self._file_id is None:
313
                text = []
314
                for fi in file_info:
315
                    text.append('%(path)s\n%(message)s' % fi)
316
                self.file_info_buffer.set_text('\n'.join(text))
317
                self.file_info_box.show()
318
            else:
319
                text = []
320
                for fi in file_info:
321
                    if fi['file_id'] == self._file_id:
322
                        text.append(fi['message'])
323
                if text:
324
                    self.file_info_buffer.set_text('\n'.join(text))
325
                    self.file_info_box.show()
326
                else:
327
                    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.
328
        else:
329
            self.file_info_box.hide()
330
423.14.3 by Jelmer Vernooij
Always show bugs tab.
331
        self.bugs_table.clear()
423.14.1 by Jelmer Vernooij
Add bugs tab to display bug status change metadata.
332
        bugs_text = revision.properties.get('bugs', None)
333
        if bugs_text:
334
            for bugline in bugs_text.splitlines():
335
                (url, status) = bugline.split(" ")
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
336
                self.bugs_table.add_bug(url, status)
423.14.1 by Jelmer Vernooij
Add bugs tab to display bug status change metadata.
337
423.7.4 by Daniel Schierbeck
Made revisionview and branchview update when a tag is added.
338
    def update_tags(self):
339
        if self._branch is not None and self._branch.supports_tags():
340
            self._tagdict = self._branch.tags.get_reverse_tag_dict()
341
        else:
342
            self._tagdict = {}
343
344
        self._add_tags()
345
399.1.13 by Daniel Schierbeck
Merged with mainline.
346
    def _update_signature(self, widget, param):
347
        revid = self._revision.revision_id
348
349
        if self._branch.repository.has_signature_for_revision_id(revid):
350
            signature_text = self._branch.repository.get_signature_text(revid)
399.1.16 by Jelmer Vernooij
Move logic showing images to the SignatureTab widget.
351
            self.signature_table.show_signature(signature_text)
399.1.13 by Daniel Schierbeck
Merged with mainline.
352
        else:
399.1.16 by Jelmer Vernooij
Move logic showing images to the SignatureTab widget.
353
            self.signature_table.show_no_signature()
399.1.13 by Daniel Schierbeck
Merged with mainline.
354
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
355
    def set_children(self, children):
356
        self._add_parents_or_children(children,
357
                                      self.children_widgets,
358
                                      self.children_table)
359
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
360
    def _show_clicked_cb(self, widget, revid, parentid):
361
        """Callback for when the show button for a parent is clicked."""
362
        self._show_callback(revid, parentid)
363
364
    def _go_clicked_cb(self, widget, revid):
365
        """Callback for when the go button for a parent is clicked."""
366
412.1.4 by Daniel Schierbeck
Made tag list smarter.
367
    def _add_tags(self, *args):
399.1.13 by Daniel Schierbeck
Merged with mainline.
368
        if self._revision is None:
369
            return
423.7.4 by Daniel Schierbeck
Made revisionview and branchview update when a tag is added.
370
412.1.4 by Daniel Schierbeck
Made tag list smarter.
371
        if self._tagdict.has_key(self._revision.revision_id):
372
            tags = self._tagdict[self._revision.revision_id]
373
        else:
374
            tags = []
375
            
241 by Jelmer Vernooij
Show tags in bzr viz.
376
        if tags == []:
377
            self.tags_list.hide()
378
            self.tags_label.hide()
379
            return
380
423.3.1 by Daniel Schierbeck
Made the tag list be a comma-separated line instead of a vertically stacked box.
381
        self.tags_list.set_text(", ".join(tags))
382
241 by Jelmer Vernooij
Show tags in bzr viz.
383
        self.tags_list.show_all()
384
        self.tags_label.show_all()
385
        
256.2.23 by Gary van der Merwe
Show Children
386
    def _add_parents_or_children(self, revids, widgets, table):
387
        while len(widgets) > 0:
388
            widget = widgets.pop()
389
            table.remove(widget)
390
        
391
        table.resize(max(len(revids), 1), 2)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
392
256.2.23 by Gary van der Merwe
Show Children
393
        for idx, revid in enumerate(revids):
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
394
            align = gtk.Alignment(0.0, 0.0)
256.2.23 by Gary van der Merwe
Show Children
395
            widgets.append(align)
396
            table.attach(align, 1, 2, idx, idx + 1,
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
397
                                      gtk.EXPAND | gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
398
            align.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
399
400
            hbox = gtk.HBox(False, spacing=6)
401
            align.add(hbox)
402
            hbox.show()
403
404
            image = gtk.Image()
405
            image.set_from_stock(
406
                gtk.STOCK_FIND, gtk.ICON_SIZE_SMALL_TOOLBAR)
407
            image.show()
408
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.
409
            if self._show_callback is not None:
410
                button = gtk.Button()
411
                button.add(image)
412
                button.connect("clicked", self._show_clicked_cb,
256.2.23 by Gary van der Merwe
Show Children
413
                               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.
414
                hbox.pack_start(button, expand=False, fill=True)
415
                button.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
416
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
417
            button = gtk.Button(revid)
418
            button.connect("clicked",
412.1.14 by Daniel Schierbeck
Fixed bug in the way the child buttons worked.
419
                    lambda w, r: self.set_revision(self._branch.repository.get_revision(r)), revid)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
420
            button.set_use_underline(False)
421
            hbox.pack_start(button, expand=False, fill=True)
422
            button.show()
0.1.1 by Dan Loda
First working version of xannotate.
423
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
424
    def _create_general(self):
0.1.1 by Dan Loda
First working version of xannotate.
425
        vbox = gtk.VBox(False, 6)
426
        vbox.set_border_width(6)
427
        vbox.pack_start(self._create_headers(), expand=False, fill=True)
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
428
        vbox.pack_start(self._create_message_view())
429
        self.append_page(vbox, tab_label=gtk.Label("General"))
430
        vbox.show()
431
432
    def _create_relations(self):
433
        vbox = gtk.VBox(False, 6)
434
        vbox.set_border_width(6)
291 by Jelmer Vernooij
Put children widget on a new line.
435
        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.
436
        vbox.pack_start(self._create_children(), expand=False, fill=True)
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
437
        self.append_page(vbox, tab_label=gtk.Label("Relations"))
0.1.1 by Dan Loda
First working version of xannotate.
438
        vbox.show()
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
439
399.1.10 by Daniel Schierbeck
Improved implementation of the Signature page.
440
    def _create_signature(self):
399.3.3 by Daniel Schierbeck
Made the signature code use the Seahorse D-Bus service.
441
        self.signature_table = SignatureTab()
399.1.15 by Jelmer Vernooij
Move signature tab to a separate class.
442
        self.append_page(self.signature_table, tab_label=gtk.Label('Signature'))
399.1.10 by Daniel Schierbeck
Improved implementation of the Signature page.
443
        self.connect_after('notify::revision', self._update_signature)
444
0.1.1 by Dan Loda
First working version of xannotate.
445
    def _create_headers(self):
241 by Jelmer Vernooij
Show tags in bzr viz.
446
        self.table = gtk.Table(rows=5, columns=2)
0.1.1 by Dan Loda
First working version of xannotate.
447
        self.table.set_row_spacings(6)
448
        self.table.set_col_spacings(6)
449
        self.table.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
450
451
        align = gtk.Alignment(1.0, 0.5)
452
        label = gtk.Label()
453
        label.set_markup("<b>Revision Id:</b>")
454
        align.add(label)
455
        self.table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
456
        align.show()
457
        label.show()
458
459
        align = gtk.Alignment(0.0, 0.5)
412.1.5 by Daniel Schierbeck
Made the revision id label use signals when updating.
460
        revision_id = gtk.Label()
461
        revision_id.set_selectable(True)
462
        self.connect('notify::revision', 
463
                lambda w, p: revision_id.set_text(self._revision.revision_id))
464
        align.add(revision_id)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
465
        self.table.attach(align, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.FILL)
466
        align.show()
412.1.5 by Daniel Schierbeck
Made the revision id label use signals when updating.
467
        revision_id.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
468
0.1.1 by Dan Loda
First working version of xannotate.
469
        align = gtk.Alignment(1.0, 0.5)
259 by Aaron Bentley
Add author support to gannotate and log viewer
470
        self.author_label = gtk.Label()
471
        self.author_label.set_markup("<b>Author:</b>")
472
        align.add(self.author_label)
473
        self.table.attach(align, 0, 1, 1, 2, gtk.FILL, gtk.FILL)
474
        align.show()
475
        self.author_label.show()
476
477
        align = gtk.Alignment(0.0, 0.5)
478
        self.author = gtk.Label()
479
        self.author.set_selectable(True)
480
        align.add(self.author)
481
        self.table.attach(align, 1, 2, 1, 2, gtk.EXPAND | gtk.FILL, gtk.FILL)
482
        align.show()
483
        self.author.show()
484
        self.author.hide()
485
486
        align = gtk.Alignment(1.0, 0.5)
0.1.1 by Dan Loda
First working version of xannotate.
487
        label = gtk.Label()
488
        label.set_markup("<b>Committer:</b>")
489
        align.add(label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
490
        self.table.attach(align, 0, 1, 2, 3, gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
491
        align.show()
492
        label.show()
493
494
        align = gtk.Alignment(0.0, 0.5)
495
        self.committer = gtk.Label()
496
        self.committer.set_selectable(True)
497
        align.add(self.committer)
259 by Aaron Bentley
Add author support to gannotate and log viewer
498
        self.table.attach(align, 1, 2, 2, 3, gtk.EXPAND | gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
499
        align.show()
500
        self.committer.show()
501
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
502
        align = gtk.Alignment(0.0, 0.5)
503
        label = gtk.Label()
504
        label.set_markup("<b>Branch nick:</b>")
505
        align.add(label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
506
        self.table.attach(align, 0, 1, 3, 4, gtk.FILL, gtk.FILL)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
507
        label.show()
508
        align.show()
509
510
        align = gtk.Alignment(0.0, 0.5)
511
        self.branchnick_label = gtk.Label()
512
        self.branchnick_label.set_selectable(True)
513
        align.add(self.branchnick_label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
514
        self.table.attach(align, 1, 2, 3, 4, gtk.EXPAND | gtk.FILL, gtk.FILL)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
515
        self.branchnick_label.show()
516
        align.show()
517
0.1.1 by Dan Loda
First working version of xannotate.
518
        align = gtk.Alignment(1.0, 0.5)
519
        label = gtk.Label()
520
        label.set_markup("<b>Timestamp:</b>")
521
        align.add(label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
522
        self.table.attach(align, 0, 1, 4, 5, gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
523
        align.show()
524
        label.show()
525
526
        align = gtk.Alignment(0.0, 0.5)
527
        self.timestamp = gtk.Label()
528
        self.timestamp.set_selectable(True)
529
        align.add(self.timestamp)
259 by Aaron Bentley
Add author support to gannotate and log viewer
530
        self.table.attach(align, 1, 2, 4, 5, gtk.EXPAND | gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
531
        align.show()
532
        self.timestamp.show()
533
241 by Jelmer Vernooij
Show tags in bzr viz.
534
        align = gtk.Alignment(1.0, 0.5)
535
        self.tags_label = gtk.Label()
536
        self.tags_label.set_markup("<b>Tags:</b>")
537
        align.add(self.tags_label)
538
        align.show()
261 by Aaron Bentley
Fix tags formatting
539
        self.table.attach(align, 0, 1, 5, 6, gtk.FILL, gtk.FILL)
241 by Jelmer Vernooij
Show tags in bzr viz.
540
        self.tags_label.show()
541
542
        align = gtk.Alignment(0.0, 0.5)
423.3.1 by Daniel Schierbeck
Made the tag list be a comma-separated line instead of a vertically stacked box.
543
        self.tags_list = gtk.Label()
241 by Jelmer Vernooij
Show tags in bzr viz.
544
        align.add(self.tags_list)
261 by Aaron Bentley
Fix tags formatting
545
        self.table.attach(align, 1, 2, 5, 6, gtk.EXPAND | gtk.FILL, gtk.FILL)
241 by Jelmer Vernooij
Show tags in bzr viz.
546
        align.show()
547
        self.tags_list.show()
548
412.1.4 by Daniel Schierbeck
Made tag list smarter.
549
        self.connect('notify::revision', self._add_tags)
550
0.1.1 by Dan Loda
First working version of xannotate.
551
        return self.table
256.2.23 by Gary van der Merwe
Show Children
552
    
291 by Jelmer Vernooij
Put children widget on a new line.
553
    def _create_parents(self):
554
        hbox = gtk.HBox(True, 3)
256.2.23 by Gary van der Merwe
Show Children
555
        
556
        self.parents_table = self._create_parents_or_children_table(
557
            "<b>Parents:</b>")
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
558
        self.parents_widgets = []
256.2.23 by Gary van der Merwe
Show Children
559
        hbox.pack_start(self.parents_table)
291 by Jelmer Vernooij
Put children widget on a new line.
560
561
        hbox.show()
562
        return hbox
563
564
    def _create_children(self):
565
        hbox = gtk.HBox(True, 3)
566
        self.children_table = self._create_parents_or_children_table(
567
            "<b>Children:</b>")
568
        self.children_widgets = []
569
        hbox.pack_start(self.children_table)
256.2.23 by Gary van der Merwe
Show Children
570
        hbox.show()
571
        return hbox
572
        
573
    def _create_parents_or_children_table(self, text):
574
        table = gtk.Table(rows=1, columns=2)
575
        table.set_row_spacings(3)
576
        table.set_col_spacings(6)
577
        table.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
578
579
        label = gtk.Label()
256.2.23 by Gary van der Merwe
Show Children
580
        label.set_markup(text)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
581
        align = gtk.Alignment(0.0, 0.5)
582
        align.add(label)
256.2.23 by Gary van der Merwe
Show Children
583
        table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
584
        label.show()
585
        align.show()
586
256.2.23 by Gary van der Merwe
Show Children
587
        return table
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
588
0.1.1 by Dan Loda
First working version of xannotate.
589
    def _create_message_view(self):
412.1.6 by Daniel Schierbeck
Made the message buffer use signals when updating.
590
        msg_buffer = gtk.TextBuffer()
591
        self.connect('notify::revision',
592
                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.
593
        window = gtk.ScrolledWindow()
594
        window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
595
        window.set_shadow_type(gtk.SHADOW_IN)
412.1.6 by Daniel Schierbeck
Made the message buffer use signals when updating.
596
        tv = gtk.TextView(msg_buffer)
0.1.1 by Dan Loda
First working version of xannotate.
597
        tv.set_editable(False)
598
        tv.set_wrap_mode(gtk.WRAP_WORD)
399.1.13 by Daniel Schierbeck
Merged with mainline.
599
0.1.1 by Dan Loda
First working version of xannotate.
600
        tv.modify_font(pango.FontDescription("Monospace"))
601
        tv.show()
324.2.2 by Daniel Schierbeck
Surrounded the commit message textview with a scrolled window and added a shadow.
602
        window.add(tv)
603
        window.show()
604
        return window
0.1.1 by Dan Loda
First working version of xannotate.
605
423.14.1 by Jelmer Vernooij
Add bugs tab to display bug status change metadata.
606
    def _create_bugs(self):
423.14.2 by Jelmer Vernooij
Move bugs tab to separate widget.
607
        self.bugs_table = BugsTab()
423.14.1 by Jelmer Vernooij
Add bugs tab to display bug status change metadata.
608
        self.append_page(self.bugs_table, tab_label=gtk.Label('Bugs'))
609
278.1.2 by John Arbash Meinel
Add an extra box that pops up when we have per-file information.
610
    def _create_file_info_view(self):
278.1.45 by John Arbash Meinel
Switch to a new tab for per-file messages.
611
        self.file_info_box = gtk.VBox(False, 6)
612
        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.
613
        self.file_info_buffer = gtk.TextBuffer()
278.1.44 by John Arbash Meinel
Merge in trunk, and update logview per-file commit messages.
614
        window = gtk.ScrolledWindow()
615
        window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
616
        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.
617
        tv = gtk.TextView(self.file_info_buffer)
618
        tv.set_editable(False)
619
        tv.set_wrap_mode(gtk.WRAP_WORD)
620
        tv.modify_font(pango.FontDescription("Monospace"))
621
        tv.show()
278.1.44 by John Arbash Meinel
Merge in trunk, and update logview per-file commit messages.
622
        window.add(tv)
623
        window.show()
624
        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.
625
        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.
626
        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.
627