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