/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
399.1.9 by Daniel Schierbeck
Merged with trunk.
21
import gobject
0.1.1 by Dan Loda
First working version of xannotate.
22
import pango
399.1.10 by Daniel Schierbeck
Improved implementation of the Signature page.
23
from gpg import GPGSubprocess
0.1.1 by Dan Loda
First working version of xannotate.
24
25
from bzrlib.osutils import format_date
412.1.8 by Daniel Schierbeck
Only import the bdecode function from the bzrlib.util.bencode package.
26
from bzrlib.util.bencode import bdecode
0.1.1 by Dan Loda
First working version of xannotate.
27
399.1.10 by Daniel Schierbeck
Improved implementation of the Signature page.
28
gpg = GPGSubprocess()
29
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
30
class RevisionView(gtk.Notebook):
0.1.1 by Dan Loda
First working version of xannotate.
31
    """ Custom widget for commit log details.
32
33
    A variety of bzr tools may need to implement such a thing. This is a
34
    start.
35
    """
36
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
37
    __gproperties__ = {
38
        'branch': (
39
            gobject.TYPE_PYOBJECT,
40
            'Branch',
41
            'The branch holding the revision being displayed',
42
            gobject.PARAM_CONSTRUCT_ONLY | gobject.PARAM_WRITABLE
43
        ),
44
45
        'revision': (
46
            gobject.TYPE_PYOBJECT,
47
            'Revision',
48
            'The revision being displayed',
412.1.2 by Daniel Schierbeck
Moved retrieval of tags into the revisionview itself.
49
            gobject.PARAM_READWRITE
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
50
        ),
51
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
52
        'children': (
53
            gobject.TYPE_PYOBJECT,
54
            'Children',
55
            'Child revisions',
56
            gobject.PARAM_READWRITE
57
        ),
58
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
59
        'file-id': (
60
            gobject.TYPE_PYOBJECT,
61
            'File Id',
62
            'The file id',
63
            gobject.PARAM_READWRITE
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
64
        )
65
    }
66
67
412.1.2 by Daniel Schierbeck
Moved retrieval of tags into the revisionview itself.
68
    def __init__(self, branch=None):
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
69
        gtk.Notebook.__init__(self)
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
70
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
71
        self._create_general()
72
        self._create_relations()
399.1.6 by Daniel Schierbeck
Made signature page label singular.
73
        self._create_signature()
278.1.45 by John Arbash Meinel
Switch to a new tab for per-file messages.
74
        self._create_file_info_view()
324.2.9 by Daniel Schierbeck
Made 'General' the default page of the logview.
75
76
        self.set_current_page(0)
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
77
        
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
78
        self._show_callback = None
79
        self._clicked_callback = None
0.1.1 by Dan Loda
First working version of xannotate.
80
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
81
        self._revision = None
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
82
        self._branch = branch
399.1.10 by Daniel Schierbeck
Improved implementation of the Signature page.
83
        self._repository = branch.repository
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
84
412.1.12 by Daniel Schierbeck
Fixed bug in gmissing.
85
        if self._branch is not None and self._branch.supports_tags():
412.1.2 by Daniel Schierbeck
Moved retrieval of tags into the revisionview itself.
86
            self._tagdict = self._branch.tags.get_reverse_tag_dict()
412.1.3 by Daniel Schierbeck
Fixed problem with branches that do not support tags.
87
        else:
88
            self._tagdict = {}
412.1.2 by Daniel Schierbeck
Moved retrieval of tags into the revisionview itself.
89
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
90
        self.set_file_id(None)
0.1.1 by Dan Loda
First working version of xannotate.
91
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
92
    def do_get_property(self, property):
93
        if property.name == 'branch':
94
            return self._branch
95
        elif property.name == 'revision':
96
            return self._revision
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
97
        elif property.name == 'children':
98
            return self._children
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
99
        elif property.name == 'file-id':
100
            return self._file_id
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
101
        else:
102
            raise AttributeError, 'unknown property %s' % property.name
103
104
    def do_set_property(self, property, value):
105
        if property.name == 'branch':
106
            self._branch = value
107
        elif property.name == 'revision':
108
            self._set_revision(value)
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
109
        elif property.name == 'children':
110
            self.set_children(value)
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
111
        elif property.name == 'file-id':
112
            self._file_id = value
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
113
        else:
114
            raise AttributeError, 'unknown property %s' % property.name
115
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
116
    def set_show_callback(self, callback):
117
        self._show_callback = callback
118
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
119
    def set_file_id(self, file_id):
120
        """Set a specific file id that we want to track.
121
122
        This just effects the display of a per-file commit message.
123
        If it is set to None, then all commit messages will be shown.
124
        """
412.1.7 by Daniel Schierbeck
Added file-id property to the revisionview.
125
        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.
126
412.1.13 by Daniel Schierbeck
Re-added support for displaying the children of a revision.
127
    def set_revision(self, revision):
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
128
        if revision != self._revision:
129
            self.set_property('revision', revision)
130
131
    def get_revision(self):
132
        return self.get_property('revision')
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
133
399.1.9 by Daniel Schierbeck
Merged with trunk.
134
    def set_children(self, children):
135
        self._add_parents_or_children(children,
136
                                      self.children_widgets,
137
                                      self.children_table)
138
412.1.15 by Daniel Schierbeck
Removed redundant method argument.
139
    def _set_revision(self, revision):
412.1.1 by Daniel Schierbeck
Added branch and revision properties to the revisionview widget.
140
        if revision is None: return
141
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
142
        self._revision = revision
192 by Jelmer Vernooij
Allow committer to be None.
143
        if revision.committer is not None:
144
            self.committer.set_text(revision.committer)
145
        else:
146
            self.committer.set_text("")
259 by Aaron Bentley
Add author support to gannotate and log viewer
147
        author = revision.properties.get('author', '')
148
        if author != '':
149
            self.author.set_text(author)
150
            self.author.show()
151
            self.author_label.show()
152
        else:
153
            self.author.hide()
154
            self.author_label.hide()
155
197 by Jelmer Vernooij
Fix some warnings when displaying ghost revisions. Reported by John.
156
        if revision.timestamp is not None:
157
            self.timestamp.set_text(format_date(revision.timestamp,
158
                                                revision.timezone))
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
159
        try:
160
            self.branchnick_label.set_text(revision.properties['branch-nick'])
161
        except KeyError:
162
            self.branchnick_label.set_text("")
163
256.2.23 by Gary van der Merwe
Show Children
164
        self._add_parents_or_children(revision.parent_ids,
165
                                      self.parents_widgets,
166
                                      self.parents_table)
167
        
278.1.3 by John Arbash Meinel
Have the ability to tell the log view that we only care about a specific file_id.
168
        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.
169
        if file_info is not None:
412.1.8 by Daniel Schierbeck
Only import the bdecode function from the bzrlib.util.bencode package.
170
            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.
171
172
        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.
173
            if self._file_id is None:
174
                text = []
175
                for fi in file_info:
176
                    text.append('%(path)s\n%(message)s' % fi)
177
                self.file_info_buffer.set_text('\n'.join(text))
178
                self.file_info_box.show()
179
            else:
180
                text = []
181
                for fi in file_info:
182
                    if fi['file_id'] == self._file_id:
183
                        text.append(fi['message'])
184
                if text:
185
                    self.file_info_buffer.set_text('\n'.join(text))
186
                    self.file_info_box.show()
187
                else:
188
                    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.
189
        else:
190
            self.file_info_box.hide()
191
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
192
    def _show_clicked_cb(self, widget, revid, parentid):
193
        """Callback for when the show button for a parent is clicked."""
194
        self._show_callback(revid, parentid)
195
196
    def _go_clicked_cb(self, widget, revid):
197
        """Callback for when the go button for a parent is clicked."""
198
412.1.4 by Daniel Schierbeck
Made tag list smarter.
199
    def _add_tags(self, *args):
200
        if self._tagdict.has_key(self._revision.revision_id):
201
            tags = self._tagdict[self._revision.revision_id]
202
        else:
203
            tags = []
204
            
241 by Jelmer Vernooij
Show tags in bzr viz.
205
        if tags == []:
206
            self.tags_list.hide()
207
            self.tags_label.hide()
208
            return
209
423.3.1 by Daniel Schierbeck
Made the tag list be a comma-separated line instead of a vertically stacked box.
210
        self.tags_list.set_text(", ".join(tags))
211
241 by Jelmer Vernooij
Show tags in bzr viz.
212
        self.tags_list.show_all()
213
        self.tags_label.show_all()
214
        
256.2.23 by Gary van der Merwe
Show Children
215
    def _add_parents_or_children(self, revids, widgets, table):
216
        while len(widgets) > 0:
217
            widget = widgets.pop()
218
            table.remove(widget)
219
        
220
        table.resize(max(len(revids), 1), 2)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
221
256.2.23 by Gary van der Merwe
Show Children
222
        for idx, revid in enumerate(revids):
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
223
            align = gtk.Alignment(0.0, 0.0)
256.2.23 by Gary van der Merwe
Show Children
224
            widgets.append(align)
225
            table.attach(align, 1, 2, idx, idx + 1,
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
226
                                      gtk.EXPAND | gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
227
            align.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
228
229
            hbox = gtk.HBox(False, spacing=6)
230
            align.add(hbox)
231
            hbox.show()
232
233
            image = gtk.Image()
234
            image.set_from_stock(
235
                gtk.STOCK_FIND, gtk.ICON_SIZE_SMALL_TOOLBAR)
236
            image.show()
237
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.
238
            if self._show_callback is not None:
239
                button = gtk.Button()
240
                button.add(image)
241
                button.connect("clicked", self._show_clicked_cb,
256.2.23 by Gary van der Merwe
Show Children
242
                               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.
243
                hbox.pack_start(button, expand=False, fill=True)
244
                button.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
245
412.1.9 by Daniel Schierbeck
Removed the use of RevisionView.set_go_callback().
246
            button = gtk.Button(revid)
247
            button.connect("clicked",
412.1.14 by Daniel Schierbeck
Fixed bug in the way the child buttons worked.
248
                    lambda w, r: self.set_revision(self._branch.repository.get_revision(r)), revid)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
249
            button.set_use_underline(False)
250
            hbox.pack_start(button, expand=False, fill=True)
251
            button.show()
0.1.1 by Dan Loda
First working version of xannotate.
252
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
253
    def _create_general(self):
0.1.1 by Dan Loda
First working version of xannotate.
254
        vbox = gtk.VBox(False, 6)
255
        vbox.set_border_width(6)
256
        vbox.pack_start(self._create_headers(), expand=False, fill=True)
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
257
        vbox.pack_start(self._create_message_view())
258
        self.append_page(vbox, tab_label=gtk.Label("General"))
259
        vbox.show()
260
261
    def _create_relations(self):
262
        vbox = gtk.VBox(False, 6)
263
        vbox.set_border_width(6)
291 by Jelmer Vernooij
Put children widget on a new line.
264
        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.
265
        vbox.pack_start(self._create_children(), expand=False, fill=True)
324.2.1 by Daniel Schierbeck
Turned the logview into a notebook.
266
        self.append_page(vbox, tab_label=gtk.Label("Relations"))
0.1.1 by Dan Loda
First working version of xannotate.
267
        vbox.show()
324.2.4 by Daniel Schierbeck
Added 'Changes' page to logview.
268
399.1.10 by Daniel Schierbeck
Improved implementation of the Signature page.
269
    def _create_signature(self):
270
        signature_box = gtk.Table(rows=1, columns=2)
271
        signature_box.set_col_spacing(0, 12)
272
273
        self.signature_image = gtk.Image()
274
        signature_box.attach(self.signature_image, 0, 1, 0, 1, gtk.FILL)
275
276
        self.signature_label = gtk.Label()
277
        signature_box.attach(self.signature_label, 1, 2, 0, 1, gtk.FILL)
278
279
        signature_info = gtk.Table(rows=1, columns=2)
280
        signature_info.set_row_spacings(6)
281
        signature_info.set_col_spacings(6)
282
283
        align = gtk.Alignment(1.0, 0.5)
284
        label = gtk.Label()
285
        label.set_markup("<b>Key Id:</b>")
286
        align.add(label)
287
        signature_info.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
288
289
        align = gtk.Alignment(0.0, 0.5)
290
        self.signature_key_id = gtk.Label()
291
        self.signature_key_id.set_selectable(True)
292
        align.add(self.signature_key_id)
293
        signature_info.attach(align, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.FILL)
294
295
        box = gtk.VBox(False, 6)
296
        box.set_border_width(6)
297
        box.pack_start(signature_box, expand=False)
298
        box.pack_start(signature_info, expand=False)
299
        box.show_all()
300
        self.append_page(box, tab_label=gtk.Label("Signature"))
301
302
        self.connect_after('notify::revision', self._update_signature)
303
0.1.1 by Dan Loda
First working version of xannotate.
304
    def _create_headers(self):
241 by Jelmer Vernooij
Show tags in bzr viz.
305
        self.table = gtk.Table(rows=5, columns=2)
0.1.1 by Dan Loda
First working version of xannotate.
306
        self.table.set_row_spacings(6)
307
        self.table.set_col_spacings(6)
308
        self.table.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
309
310
        align = gtk.Alignment(1.0, 0.5)
311
        label = gtk.Label()
312
        label.set_markup("<b>Revision Id:</b>")
313
        align.add(label)
314
        self.table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
315
        align.show()
316
        label.show()
317
318
        align = gtk.Alignment(0.0, 0.5)
412.1.5 by Daniel Schierbeck
Made the revision id label use signals when updating.
319
        revision_id = gtk.Label()
320
        revision_id.set_selectable(True)
321
        self.connect('notify::revision', 
322
                lambda w, p: revision_id.set_text(self._revision.revision_id))
323
        align.add(revision_id)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
324
        self.table.attach(align, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.FILL)
325
        align.show()
412.1.5 by Daniel Schierbeck
Made the revision id label use signals when updating.
326
        revision_id.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
327
0.1.1 by Dan Loda
First working version of xannotate.
328
        align = gtk.Alignment(1.0, 0.5)
259 by Aaron Bentley
Add author support to gannotate and log viewer
329
        self.author_label = gtk.Label()
330
        self.author_label.set_markup("<b>Author:</b>")
331
        align.add(self.author_label)
332
        self.table.attach(align, 0, 1, 1, 2, gtk.FILL, gtk.FILL)
333
        align.show()
334
        self.author_label.show()
335
336
        align = gtk.Alignment(0.0, 0.5)
337
        self.author = gtk.Label()
338
        self.author.set_selectable(True)
339
        align.add(self.author)
340
        self.table.attach(align, 1, 2, 1, 2, gtk.EXPAND | gtk.FILL, gtk.FILL)
341
        align.show()
342
        self.author.show()
343
        self.author.hide()
344
345
        align = gtk.Alignment(1.0, 0.5)
0.1.1 by Dan Loda
First working version of xannotate.
346
        label = gtk.Label()
347
        label.set_markup("<b>Committer:</b>")
348
        align.add(label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
349
        self.table.attach(align, 0, 1, 2, 3, gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
350
        align.show()
351
        label.show()
352
353
        align = gtk.Alignment(0.0, 0.5)
354
        self.committer = gtk.Label()
355
        self.committer.set_selectable(True)
356
        align.add(self.committer)
259 by Aaron Bentley
Add author support to gannotate and log viewer
357
        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.
358
        align.show()
359
        self.committer.show()
360
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
361
        align = gtk.Alignment(0.0, 0.5)
362
        label = gtk.Label()
363
        label.set_markup("<b>Branch nick:</b>")
364
        align.add(label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
365
        self.table.attach(align, 0, 1, 3, 4, gtk.FILL, gtk.FILL)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
366
        label.show()
367
        align.show()
368
369
        align = gtk.Alignment(0.0, 0.5)
370
        self.branchnick_label = gtk.Label()
371
        self.branchnick_label.set_selectable(True)
372
        align.add(self.branchnick_label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
373
        self.table.attach(align, 1, 2, 3, 4, gtk.EXPAND | gtk.FILL, gtk.FILL)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
374
        self.branchnick_label.show()
375
        align.show()
376
0.1.1 by Dan Loda
First working version of xannotate.
377
        align = gtk.Alignment(1.0, 0.5)
378
        label = gtk.Label()
379
        label.set_markup("<b>Timestamp:</b>")
380
        align.add(label)
259 by Aaron Bentley
Add author support to gannotate and log viewer
381
        self.table.attach(align, 0, 1, 4, 5, gtk.FILL, gtk.FILL)
0.1.1 by Dan Loda
First working version of xannotate.
382
        align.show()
383
        label.show()
384
385
        align = gtk.Alignment(0.0, 0.5)
386
        self.timestamp = gtk.Label()
387
        self.timestamp.set_selectable(True)
388
        align.add(self.timestamp)
259 by Aaron Bentley
Add author support to gannotate and log viewer
389
        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.
390
        align.show()
391
        self.timestamp.show()
392
241 by Jelmer Vernooij
Show tags in bzr viz.
393
        align = gtk.Alignment(1.0, 0.5)
394
        self.tags_label = gtk.Label()
395
        self.tags_label.set_markup("<b>Tags:</b>")
396
        align.add(self.tags_label)
397
        align.show()
261 by Aaron Bentley
Fix tags formatting
398
        self.table.attach(align, 0, 1, 5, 6, gtk.FILL, gtk.FILL)
241 by Jelmer Vernooij
Show tags in bzr viz.
399
        self.tags_label.show()
400
401
        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.
402
        self.tags_list = gtk.Label()
241 by Jelmer Vernooij
Show tags in bzr viz.
403
        align.add(self.tags_list)
261 by Aaron Bentley
Fix tags formatting
404
        self.table.attach(align, 1, 2, 5, 6, gtk.EXPAND | gtk.FILL, gtk.FILL)
241 by Jelmer Vernooij
Show tags in bzr viz.
405
        align.show()
406
        self.tags_list.show()
407
412.1.4 by Daniel Schierbeck
Made tag list smarter.
408
        self.connect('notify::revision', self._add_tags)
409
0.1.1 by Dan Loda
First working version of xannotate.
410
        return self.table
256.2.23 by Gary van der Merwe
Show Children
411
    
291 by Jelmer Vernooij
Put children widget on a new line.
412
    def _create_parents(self):
413
        hbox = gtk.HBox(True, 3)
256.2.23 by Gary van der Merwe
Show Children
414
        
415
        self.parents_table = self._create_parents_or_children_table(
416
            "<b>Parents:</b>")
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
417
        self.parents_widgets = []
256.2.23 by Gary van der Merwe
Show Children
418
        hbox.pack_start(self.parents_table)
291 by Jelmer Vernooij
Put children widget on a new line.
419
420
        hbox.show()
421
        return hbox
422
423
    def _create_children(self):
424
        hbox = gtk.HBox(True, 3)
425
        self.children_table = self._create_parents_or_children_table(
426
            "<b>Children:</b>")
427
        self.children_widgets = []
428
        hbox.pack_start(self.children_table)
256.2.23 by Gary van der Merwe
Show Children
429
        hbox.show()
430
        return hbox
431
        
432
    def _create_parents_or_children_table(self, text):
433
        table = gtk.Table(rows=1, columns=2)
434
        table.set_row_spacings(3)
435
        table.set_col_spacings(6)
436
        table.show()
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
437
438
        label = gtk.Label()
256.2.23 by Gary van der Merwe
Show Children
439
        label.set_markup(text)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
440
        align = gtk.Alignment(0.0, 0.5)
441
        align.add(label)
256.2.23 by Gary van der Merwe
Show Children
442
        table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
443
        label.show()
444
        align.show()
445
256.2.23 by Gary van der Merwe
Show Children
446
        return table
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
447
0.1.1 by Dan Loda
First working version of xannotate.
448
    def _create_message_view(self):
412.1.6 by Daniel Schierbeck
Made the message buffer use signals when updating.
449
        msg_buffer = gtk.TextBuffer()
450
        self.connect('notify::revision',
451
                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.
452
        window = gtk.ScrolledWindow()
453
        window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
454
        window.set_shadow_type(gtk.SHADOW_IN)
412.1.6 by Daniel Schierbeck
Made the message buffer use signals when updating.
455
        tv = gtk.TextView(msg_buffer)
0.1.1 by Dan Loda
First working version of xannotate.
456
        tv.set_editable(False)
457
        tv.set_wrap_mode(gtk.WRAP_WORD)
458
        tv.modify_font(pango.FontDescription("Monospace"))
459
        tv.show()
324.2.2 by Daniel Schierbeck
Surrounded the commit message textview with a scrolled window and added a shadow.
460
        window.add(tv)
461
        window.show()
462
        return window
0.1.1 by Dan Loda
First working version of xannotate.
463
278.1.2 by John Arbash Meinel
Add an extra box that pops up when we have per-file information.
464
    def _create_file_info_view(self):
278.1.45 by John Arbash Meinel
Switch to a new tab for per-file messages.
465
        self.file_info_box = gtk.VBox(False, 6)
466
        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.
467
        self.file_info_buffer = gtk.TextBuffer()
278.1.44 by John Arbash Meinel
Merge in trunk, and update logview per-file commit messages.
468
        window = gtk.ScrolledWindow()
469
        window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
470
        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.
471
        tv = gtk.TextView(self.file_info_buffer)
472
        tv.set_editable(False)
473
        tv.set_wrap_mode(gtk.WRAP_WORD)
474
        tv.modify_font(pango.FontDescription("Monospace"))
475
        tv.show()
278.1.44 by John Arbash Meinel
Merge in trunk, and update logview per-file commit messages.
476
        window.add(tv)
477
        window.show()
478
        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.
479
        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.
480
        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.
481
399.1.10 by Daniel Schierbeck
Improved implementation of the Signature page.
482
    def _update_signature(self, widget, param):
483
        revid = self._revision.revision_id
484
485
        if self._repository.has_signature_for_revision_id(revid):
486
            signature_text = self._repository.get_signature_text(revid)
487
            signature = gpg.verify(signature_text)
488
489
            if signature.key_id is not None:
490
                self.signature_key_id.set_text(signature.key_id)
491
492
            if signature.is_valid():
493
                self.signature_image.set_from_file("icons/sign-ok.png")
494
                self.signature_label.set_text("This revision has been signed.")
495
            else:
496
                self.signature_image.set_from_file("icons/sign-bad.png")
399.1.11 by Daniel Schierbeck
Split long line.
497
                self.signature_label.set_text("This revision has been signed, " + 
498
                        "but the authenticity of the signature cannot be verified.")
399.1.10 by Daniel Schierbeck
Improved implementation of the Signature page.
499
        else:
500
            self.signature_key_id.set_text("")
501
            self.signature_image.set_from_file("icons/sign-unknown.png")
502
            self.signature_label.set_text("This revision has not been signed.")
503
504