/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to __init__.py

  • Committer: Mateusz Korniak
  • Date: 2007-09-02 15:42:18 UTC
  • mto: This revision was merged to the branch mainline in revision 274.
  • Revision ID: matkor@laptop-hp-20070902154218-nba0woaqjsn20f9n
Ignoring eric3 project files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python
2
 
 
3
1
# This program is free software; you can redistribute it and/or modify
4
2
# it under the terms of the GNU General Public License as published by
5
3
# the Free Software Foundation; either version 2 of the License, or
14
12
# along with this program; if not, write to the Free Software
15
13
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
14
 
17
 
"""GTK+ frontends to Bazaar commands """
 
15
"""Graphical support for Bazaar using GTK.
 
16
 
 
17
This plugin includes:
 
18
commit-notify     Start the graphical notifier of commits.
 
19
gannotate         GTK+ annotate. 
 
20
gbranch           GTK+ branching. 
 
21
gcheckout         GTK+ checkout. 
 
22
gcommit           GTK+ commit dialog 
 
23
gconflicts        GTK+ conflicts. 
 
24
gdiff             Show differences in working tree in a GTK+ Window. 
 
25
ginit             Initialise a new branch.
 
26
gmissing          GTK+ missing revisions dialog. 
 
27
gpreferences      GTK+ preferences dialog. 
 
28
gpush             GTK+ push. 
 
29
gstatus           GTK+ status dialog 
 
30
gtags             Manage branch tags.
 
31
visualise         Graphically visualise this branch. 
 
32
"""
 
33
 
 
34
import bzrlib
 
35
 
 
36
__version__ = '0.91.0'
 
37
version_info = tuple(int(n) for n in __version__.split('.'))
 
38
 
 
39
 
 
40
def check_bzrlib_version(desired):
 
41
    """Check that bzrlib is compatible.
 
42
 
 
43
    If version is < bzr-gtk version, assume incompatible.
 
44
    If version == bzr-gtk version, assume completely compatible
 
45
    If version == bzr-gtk version + 1, assume compatible, with deprecations
 
46
    Otherwise, assume incompatible.
 
47
    """
 
48
    desired_plus = (desired[0], desired[1]+1)
 
49
    bzrlib_version = bzrlib.version_info[:2]
 
50
    if bzrlib_version == desired or (bzrlib_version == desired_plus and
 
51
                                     bzrlib.version_info[3] == 'dev'):
 
52
        return
 
53
    try:
 
54
        from bzrlib.trace import warning
 
55
    except ImportError:
 
56
        # get the message out any way we can
 
57
        from warnings import warn as warning
 
58
    if bzrlib_version < desired:
 
59
        from bzrlib.errors import BzrError
 
60
        warning('Installed Bazaar version %s is too old to be used with bzr-gtk'
 
61
                ' %s.' % (bzrlib.__version__, __version__))
 
62
        raise BzrError('Version mismatch: %r' % (version_info,) )
 
63
    else:
 
64
        warning('bzr-gtk is not up to date with installed bzr version %s.'
 
65
                ' \nThere should be a newer version available, e.g. %i.%i.' 
 
66
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
 
67
 
 
68
 
 
69
check_bzrlib_version(version_info[:2])
 
70
 
 
71
from bzrlib.trace import warning
 
72
if __name__ != 'bzrlib.plugins.gtk':
 
73
    warning("Not running as bzrlib.plugins.gtk, things may break.")
 
74
 
 
75
from bzrlib.lazy_import import lazy_import
 
76
lazy_import(globals(), """
 
77
from bzrlib import (
 
78
    branch,
 
79
    builtins,
 
80
    errors,
 
81
    workingtree,
 
82
    )
 
83
""")
 
84
 
18
85
from bzrlib.commands import Command, register_command, display_command
19
 
from bzrlib.errors import NotVersionedError, BzrCommandError
20
 
from bzrlib.commands import Command, register_command
 
86
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
21
87
from bzrlib.option import Option
22
 
from bzrlib.branch import Branch
23
 
from bzrlib.workingtree import WorkingTree
24
 
from bzrlib.bzrdir import BzrDir
25
 
 
26
 
class cmd_gbranch(Command):
 
88
 
 
89
import os.path
 
90
 
 
91
def import_pygtk():
 
92
    try:
 
93
        import pygtk
 
94
    except ImportError:
 
95
        raise errors.BzrCommandError("PyGTK not installed.")
 
96
    pygtk.require('2.0')
 
97
    return pygtk
 
98
 
 
99
 
 
100
def set_ui_factory():
 
101
    import_pygtk()
 
102
    from ui import GtkUIFactory
 
103
    import bzrlib.ui
 
104
    bzrlib.ui.ui_factory = GtkUIFactory()
 
105
 
 
106
 
 
107
def data_path():
 
108
    return os.path.dirname(__file__)
 
109
 
 
110
 
 
111
class GTKCommand(Command):
 
112
    """Abstract class providing GTK specific run commands."""
 
113
 
 
114
    def open_display(self):
 
115
        pygtk = import_pygtk()
 
116
        try:
 
117
            import gtk
 
118
        except RuntimeError, e:
 
119
            if str(e) == "could not open display":
 
120
                raise NoDisplayError
 
121
        set_ui_factory()
 
122
        return gtk
 
123
 
 
124
    def run(self):
 
125
        self.open_display()
 
126
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
 
127
        dialog.run()
 
128
 
 
129
 
 
130
class cmd_gbranch(GTKCommand):
27
131
    """GTK+ branching.
28
132
    
29
133
    """
30
134
 
31
 
    def run(self):
32
 
        import pygtk
33
 
        pygtk.require("2.0")
34
 
        try:
35
 
            import gtk
36
 
        except RuntimeError, e:
37
 
            if str(e) == "could not open display":
38
 
                raise NoDisplayError
39
 
 
40
 
        from clone import CloneDialog
41
 
 
42
 
        window = CloneDialog()
43
 
        if window.run() == gtk.RESPONSE_OK:
44
 
            bzrdir = BzrDir.open(window.url)
45
 
            bzrdir.sprout(window.dest_path)
46
 
 
47
 
register_command(cmd_gbranch)
48
 
 
49
 
class cmd_gdiff(Command):
 
135
    def get_gtk_dialog(self, path):
 
136
        from bzrlib.plugins.gtk.branch import BranchDialog
 
137
        return BranchDialog(path)
 
138
 
 
139
 
 
140
class cmd_gcheckout(GTKCommand):
 
141
    """ GTK+ checkout.
 
142
    
 
143
    """
 
144
    
 
145
    def get_gtk_dialog(self, path):
 
146
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
 
147
        return CheckoutDialog(path)
 
148
 
 
149
 
 
150
 
 
151
class cmd_gpush(GTKCommand):
 
152
    """ GTK+ push.
 
153
    
 
154
    """
 
155
    takes_args = [ "location?" ]
 
156
 
 
157
    def run(self, location="."):
 
158
        (br, path) = branch.Branch.open_containing(location)
 
159
        self.open_display()
 
160
        from push import PushDialog
 
161
        dialog = PushDialog(br.repository, br.last_revision(), br)
 
162
        dialog.run()
 
163
 
 
164
 
 
165
 
 
166
class cmd_gdiff(GTKCommand):
50
167
    """Show differences in working tree in a GTK+ Window.
51
168
    
52
169
    Otherwise, all changes for the tree are listed.
53
170
    """
54
 
    takes_args = []
 
171
    takes_args = ['filename?']
55
172
    takes_options = ['revision']
56
173
 
57
174
    @display_command
58
 
    def run(self, revision=None, file_list=None):
59
 
        wt = WorkingTree.open_containing(".")[0]
60
 
        branch = wt.branch
61
 
        if revision is not None:
62
 
            if len(revision) == 1:
 
175
    def run(self, revision=None, filename=None):
 
176
        set_ui_factory()
 
177
        wt = workingtree.WorkingTree.open_containing(".")[0]
 
178
        wt.lock_read()
 
179
        try:
 
180
            branch = wt.branch
 
181
            if revision is not None:
 
182
                if len(revision) == 1:
 
183
                    tree1 = wt
 
184
                    revision_id = revision[0].in_history(branch).rev_id
 
185
                    tree2 = branch.repository.revision_tree(revision_id)
 
186
                elif len(revision) == 2:
 
187
                    revision_id_0 = revision[0].in_history(branch).rev_id
 
188
                    tree2 = branch.repository.revision_tree(revision_id_0)
 
189
                    revision_id_1 = revision[1].in_history(branch).rev_id
 
190
                    tree1 = branch.repository.revision_tree(revision_id_1)
 
191
            else:
63
192
                tree1 = wt
64
 
                revision_id = revision[0].in_history(branch).rev_id
65
 
                tree2 = branch.repository.revision_tree(revision_id)
66
 
            elif len(revision) == 2:
67
 
                revision_id_0 = revision[0].in_history(branch).rev_id
68
 
                tree2 = branch.repository.revision_tree(revision_id_0)
69
 
                revision_id_1 = revision[1].in_history(branch).rev_id
70
 
                tree1 = branch.repository.revision_tree(revision_id_1)
71
 
        else:
72
 
            tree1 = wt
73
 
            tree2 = tree1.basis_tree()
74
 
 
75
 
        from bzrlib.plugins.gtk.viz.diffwin import DiffWindow
76
 
        import gtk
77
 
        window = DiffWindow()
78
 
        window.connect("destroy", lambda w: gtk.main_quit())
79
 
        window.set_diff("Working Tree", tree1, tree2)
80
 
        window.show()
81
 
 
82
 
        gtk.main()
83
 
 
84
 
register_command(cmd_gdiff)
 
193
                tree2 = tree1.basis_tree()
 
194
 
 
195
            from diff import DiffWindow
 
196
            import gtk
 
197
            window = DiffWindow()
 
198
            window.connect("destroy", gtk.main_quit)
 
199
            window.set_diff("Working Tree", tree1, tree2)
 
200
            if filename is not None:
 
201
                tree_filename = wt.relpath(filename)
 
202
                try:
 
203
                    window.set_file(tree_filename)
 
204
                except NoSuchFile:
 
205
                    if (tree1.path2id(tree_filename) is None and 
 
206
                        tree2.path2id(tree_filename) is None):
 
207
                        raise NotVersionedError(filename)
 
208
                    raise BzrCommandError('No changes found for file "%s"' % 
 
209
                                          filename)
 
210
            window.show()
 
211
 
 
212
            gtk.main()
 
213
        finally:
 
214
            wt.unlock()
 
215
 
 
216
 
 
217
def start_viz_window(branch, revision, limit=None):
 
218
    """Start viz on branch with revision revision.
 
219
    
 
220
    :return: The viz window object.
 
221
    """
 
222
    from viz.branchwin import BranchWindow
 
223
    branch.lock_read()
 
224
    pp = BranchWindow()
 
225
    pp.set_branch(branch, revision, limit)
 
226
    # cleanup locks when the window is closed
 
227
    pp.connect("destroy", lambda w: branch.unlock())
 
228
    return pp
 
229
 
85
230
 
86
231
class cmd_visualise(Command):
87
232
    """Graphically visualise this branch.
94
239
    """
95
240
    takes_options = [
96
241
        "revision",
97
 
        Option('limit', "maximum number of revisions to display",
 
242
        Option('limit', "Maximum number of revisions to display.",
98
243
               int, 'count')]
99
244
    takes_args = [ "location?" ]
100
245
    aliases = [ "visualize", "vis", "viz" ]
101
246
 
102
247
    def run(self, location=".", revision=None, limit=None):
103
 
        (branch, path) = Branch.open_containing(location)
104
 
        branch.lock_read()
105
 
        branch.repository.lock_read()
 
248
        set_ui_factory()
 
249
        (br, path) = branch.Branch.open_containing(location)
 
250
        br.lock_read()
106
251
        try:
107
252
            if revision is None:
108
 
                revid = branch.last_revision()
 
253
                revid = br.last_revision()
109
254
                if revid is None:
110
255
                    return
111
256
            else:
112
 
                (revno, revid) = revision[0].in_history(branch)
 
257
                (revno, revid) = revision[0].in_history(br)
113
258
 
114
 
            from viz.bzrkapp import BzrkApp
115
 
                
116
 
            app = BzrkApp()
117
 
            app.show(branch, revid, limit)
 
259
            import gtk
 
260
            pp = start_viz_window(br, revid, limit)
 
261
            pp.connect("destroy", lambda w: gtk.main_quit())
 
262
            pp.show()
 
263
            gtk.main()
118
264
        finally:
119
 
            branch.repository.unlock()
120
 
            branch.unlock()
121
 
        app.main()
122
 
 
123
 
 
124
 
register_command(cmd_visualise)
125
 
 
126
 
class cmd_gannotate(Command):
 
265
            br.unlock()
 
266
 
 
267
 
 
268
class cmd_gannotate(GTKCommand):
127
269
    """GTK+ annotate.
128
270
    
129
271
    Browse changes to FILENAME line by line in a GTK+ window.
130
272
    """
131
273
 
132
 
    takes_args = ["filename"]
 
274
    takes_args = ["filename", "line?"]
133
275
    takes_options = [
134
 
        Option("all", help="show annotations on all lines"),
135
 
        Option("plain", help="don't highlight annotation lines"),
 
276
        Option("all", help="Show annotations on all lines."),
 
277
        Option("plain", help="Don't highlight annotation lines."),
136
278
        Option("line", type=int, argname="lineno",
137
 
               help="jump to specified line number")
 
279
               help="Jump to specified line number."),
 
280
        "revision",
138
281
    ]
139
282
    aliases = ["gblame", "gpraise"]
140
283
    
141
 
    def run(self, filename, all=False, plain=False, line=1):
142
 
        import pygtk
143
 
        pygtk.require("2.0")
 
284
    def run(self, filename, all=False, plain=False, line='1', revision=None):
 
285
        gtk = self.open_display()
144
286
 
145
287
        try:
146
 
            import gtk
147
 
        except RuntimeError, e:
148
 
            if str(e) == "could not open display":
149
 
                raise NoDisplayError
 
288
            line = int(line)
 
289
        except ValueError:
 
290
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
 
291
                                  line)
150
292
 
151
293
        from annotate.gannotate import GAnnotateWindow
152
294
        from annotate.config import GAnnotateConfig
153
 
 
154
 
        (wt, path) = WorkingTree.open_containing(filename)
155
 
        branch = wt.branch
156
 
 
157
 
        file_id = wt.path2id(path)
 
295
        from bzrlib.bzrdir import BzrDir
 
296
 
 
297
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
 
298
        if wt is not None:
 
299
            tree = wt
 
300
        else:
 
301
            tree = br.basis_tree()
 
302
 
 
303
        file_id = tree.path2id(path)
158
304
 
159
305
        if file_id is None:
160
306
            raise NotVersionedError(filename)
 
307
        if revision is not None:
 
308
            if len(revision) != 1:
 
309
                raise BzrCommandError("Only 1 revion may be specified.")
 
310
            revision_id = revision[0].in_history(br).rev_id
 
311
            tree = br.repository.revision_tree(revision_id)
 
312
        else:
 
313
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
161
314
 
162
315
        window = GAnnotateWindow(all, plain)
163
316
        window.connect("destroy", lambda w: gtk.main_quit())
164
317
        window.set_title(path + " - gannotate")
165
318
        config = GAnnotateConfig(window)
166
319
        window.show()
167
 
        branch.lock_read()
 
320
        br.lock_read()
 
321
        if wt is not None:
 
322
            wt.lock_read()
168
323
        try:
169
 
            window.annotate(branch, file_id)
 
324
            window.annotate(tree, br, file_id)
 
325
            window.jump_to_line(line)
 
326
            gtk.main()
170
327
        finally:
171
 
            branch.unlock()
172
 
        window.jump_to_line(line)
173
 
        
174
 
        gtk.main()
175
 
 
176
 
register_command(cmd_gannotate)
177
 
 
178
 
class cmd_gcommit(Command):
 
328
            br.unlock()
 
329
            if wt is not None:
 
330
                wt.unlock()
 
331
 
 
332
 
 
333
 
 
334
class cmd_gcommit(GTKCommand):
179
335
    """GTK+ commit dialog
180
336
 
181
337
    Graphical user interface for committing revisions"""
182
338
    
 
339
    aliases = [ "gci" ]
183
340
    takes_args = []
184
341
    takes_options = []
185
342
 
186
343
    def run(self, filename=None):
187
 
        import pygtk
188
 
        pygtk.require("2.0")
189
 
 
 
344
        import os
 
345
        self.open_display()
 
346
        from commit import CommitDialog
 
347
        from bzrlib.errors import (BzrCommandError,
 
348
                                   NotBranchError,
 
349
                                   NoWorkingTree)
 
350
 
 
351
        wt = None
 
352
        br = None
 
353
        try:
 
354
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
 
355
            br = wt.branch
 
356
        except NoWorkingTree, e:
 
357
            path = e.base
 
358
            (br, path) = branch.Branch.open_containing(path)
 
359
 
 
360
        commit = CommitDialog(wt, path, not br)
 
361
        commit.run()
 
362
 
 
363
 
 
364
 
 
365
class cmd_gstatus(GTKCommand):
 
366
    """GTK+ status dialog
 
367
 
 
368
    Graphical user interface for showing status 
 
369
    information."""
 
370
    
 
371
    aliases = [ "gst" ]
 
372
    takes_args = ['PATH?']
 
373
    takes_options = []
 
374
 
 
375
    def run(self, path='.'):
 
376
        import os
 
377
        gtk = self.open_display()
 
378
        from status import StatusDialog
 
379
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
 
380
        status = StatusDialog(wt, wt_path)
 
381
        status.connect("destroy", gtk.main_quit)
 
382
        status.run()
 
383
 
 
384
 
 
385
 
 
386
class cmd_gconflicts(GTKCommand):
 
387
    """ GTK+ conflicts.
 
388
    
 
389
    Select files from the list of conflicts and run an external utility to
 
390
    resolve them.
 
391
    """
 
392
    def run(self):
 
393
        (wt, path) = workingtree.WorkingTree.open_containing('.')
 
394
        self.open_display()
 
395
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
 
396
        dialog = ConflictsDialog(wt)
 
397
        dialog.run()
 
398
 
 
399
 
 
400
 
 
401
class cmd_gpreferences(GTKCommand):
 
402
    """ GTK+ preferences dialog.
 
403
 
 
404
    """
 
405
    def run(self):
 
406
        self.open_display()
 
407
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
 
408
        dialog = PreferencesWindow()
 
409
        dialog.run()
 
410
 
 
411
 
 
412
 
 
413
class cmd_gmissing(Command):
 
414
    """ GTK+ missing revisions dialog.
 
415
 
 
416
    """
 
417
    takes_args = ["other_branch?"]
 
418
    def run(self, other_branch=None):
 
419
        pygtk = import_pygtk()
190
420
        try:
191
421
            import gtk
192
422
        except RuntimeError, e:
193
423
            if str(e) == "could not open display":
194
424
                raise NoDisplayError
195
425
 
196
 
        from commit import GCommitDialog
197
 
        from bzrlib.commit import Commit
198
 
        from bzrlib.errors import (BzrCommandError, PointlessCommit, ConflictsInTree, 
199
 
           StrictCommitFailed)
200
 
 
201
 
        (wt, path) = WorkingTree.open_containing(filename)
202
 
        branch = wt.branch
203
 
 
204
 
        file_id = wt.path2id(path)
205
 
 
206
 
        if file_id is None:
207
 
            raise NotVersionedError(filename)
208
 
 
209
 
        dialog = GCommitDialog(wt)
210
 
        dialog.set_title(path + " - Commit")
211
 
        if dialog.run() != gtk.RESPONSE_CANCEL:
212
 
            Commit().commit(working_tree=wt,message=dialog.message,
213
 
                specific_files=dialog.specific_files)
214
 
 
215
 
register_command(cmd_gcommit)
 
426
        from bzrlib.plugins.gtk.missing import MissingWindow
 
427
        from bzrlib.branch import Branch
 
428
 
 
429
        local_branch = Branch.open_containing(".")[0]
 
430
        if other_branch is None:
 
431
            other_branch = local_branch.get_parent()
 
432
            
 
433
            if other_branch is None:
 
434
                raise errors.BzrCommandError("No peer location known or specified.")
 
435
        remote_branch = Branch.open_containing(other_branch)[0]
 
436
        set_ui_factory()
 
437
        local_branch.lock_read()
 
438
        try:
 
439
            remote_branch.lock_read()
 
440
            try:
 
441
                dialog = MissingWindow(local_branch, remote_branch)
 
442
                dialog.run()
 
443
            finally:
 
444
                remote_branch.unlock()
 
445
        finally:
 
446
            local_branch.unlock()
 
447
 
 
448
 
 
449
class cmd_ginit(GTKCommand):
 
450
    def run(self):
 
451
        self.open_display()
 
452
        from initialize import InitDialog
 
453
        dialog = InitDialog(os.path.abspath(os.path.curdir))
 
454
        dialog.run()
 
455
 
 
456
 
 
457
class cmd_gtags(GTKCommand):
 
458
    def run(self):
 
459
        br = branch.Branch.open_containing('.')[0]
 
460
        
 
461
        gtk = self.open_display()
 
462
        from tags import TagsWindow
 
463
        window = TagsWindow(br)
 
464
        window.show()
 
465
        gtk.main()
 
466
 
 
467
 
 
468
commands = [
 
469
    cmd_gmissing, 
 
470
    cmd_gpreferences, 
 
471
    cmd_gconflicts, 
 
472
    cmd_gstatus,
 
473
    cmd_gcommit, 
 
474
    cmd_gannotate, 
 
475
    cmd_visualise, 
 
476
    cmd_gdiff,
 
477
    cmd_gpush, 
 
478
    cmd_gcheckout, 
 
479
    cmd_gbranch,
 
480
    cmd_ginit,
 
481
    cmd_gtags
 
482
    ]
 
483
 
 
484
for cmd in commands:
 
485
    register_command(cmd)
 
486
 
 
487
 
 
488
class cmd_commit_notify(GTKCommand):
 
489
    """Run the bzr commit notifier.
 
490
 
 
491
    This is a background program which will pop up a notification on the users
 
492
    screen when a commit occurs.
 
493
    """
 
494
 
 
495
    def run(self):
 
496
        from notify import NotifyPopupMenu
 
497
        gtk = self.open_display()
 
498
        menu = NotifyPopupMenu()
 
499
        icon = gtk.status_icon_new_from_file(os.path.join(data_path(), "bzr-icon-64.png"))
 
500
        icon.connect('popup-menu', menu.display)
 
501
 
 
502
        import cgi
 
503
        import dbus
 
504
        import dbus.service
 
505
        import pynotify
 
506
        from bzrlib.bzrdir import BzrDir
 
507
        from bzrlib import errors
 
508
        from bzrlib.osutils import format_date
 
509
        from bzrlib.transport import get_transport
 
510
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
 
511
            import dbus.glib
 
512
        from bzrlib.plugins.dbus import activity
 
513
        bus = dbus.SessionBus()
 
514
        # get the object so we can subscribe to callbacks from it.
 
515
        broadcast_service = bus.get_object(
 
516
            activity.Broadcast.DBUS_NAME,
 
517
            activity.Broadcast.DBUS_PATH)
 
518
 
 
519
        def catch_branch(revision_id, urls):
 
520
            # TODO: show all the urls, or perhaps choose the 'best'.
 
521
            url = urls[0]
 
522
            try:
 
523
                if isinstance(revision_id, unicode):
 
524
                    revision_id = revision_id.encode('utf8')
 
525
                transport = get_transport(url)
 
526
                a_dir = BzrDir.open_from_transport(transport)
 
527
                branch = a_dir.open_branch()
 
528
                revno = branch.revision_id_to_revno(revision_id)
 
529
                revision = branch.repository.get_revision(revision_id)
 
530
                summary = 'New revision %d in %s' % (revno, url)
 
531
                body  = 'Committer: %s\n' % revision.committer
 
532
                body += 'Date: %s\n' % format_date(revision.timestamp,
 
533
                    revision.timezone)
 
534
                body += '\n'
 
535
                body += revision.message
 
536
                body = cgi.escape(body)
 
537
                nw = pynotify.Notification(summary, body)
 
538
                def start_viz(notification=None, action=None, data=None):
 
539
                    """Start the viz program."""
 
540
                    pp = start_viz_window(branch, revision_id)
 
541
                    pp.show()
 
542
                def start_branch(notification=None, action=None, data=None):
 
543
                    """Start a Branch dialog"""
 
544
                    from bzrlib.plugins.gtk.branch import BranchDialog
 
545
                    bd = BranchDialog(remote_path=url)
 
546
                    bd.run()
 
547
                nw.add_action("inspect", "Inspect", start_viz, None)
 
548
                nw.add_action("branch", "Branch", start_branch, None)
 
549
                nw.set_timeout(5000)
 
550
                nw.show()
 
551
            except Exception, e:
 
552
                print e
 
553
                raise
 
554
        broadcast_service.connect_to_signal("Revision", catch_branch,
 
555
            dbus_interface=activity.Broadcast.DBUS_INTERFACE)
 
556
        pynotify.init("bzr commit-notify")
 
557
        gtk.main()
 
558
 
 
559
register_command(cmd_commit_notify)
 
560
 
 
561
 
 
562
class cmd_gselftest(GTKCommand):
 
563
    """Version of selftest that displays a notification at the end"""
 
564
 
 
565
    takes_args = builtins.cmd_selftest.takes_args
 
566
    takes_options = builtins.cmd_selftest.takes_options
 
567
    _see_also = ['selftest']
 
568
 
 
569
    def run(self, *args, **kwargs):
 
570
        import cgi
 
571
        import sys
 
572
        default_encoding = sys.getdefaultencoding()
 
573
        # prevent gtk from blowing up later
 
574
        gtk = import_pygtk()
 
575
        # prevent gtk from messing with default encoding
 
576
        import pynotify
 
577
        if sys.getdefaultencoding() != default_encoding:
 
578
            reload(sys)
 
579
            sys.setdefaultencoding(default_encoding)
 
580
        result = builtins.cmd_selftest().run(*args, **kwargs)
 
581
        if result == 0:
 
582
            summary = 'Success'
 
583
            body = 'Selftest succeeded in "%s"' % os.getcwd()
 
584
        if result == 1:
 
585
            summary = 'Failure'
 
586
            body = 'Selftest failed in "%s"' % os.getcwd()
 
587
        pynotify.init("bzr gselftest")
 
588
        note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
 
589
        note.set_timeout(pynotify.EXPIRES_NEVER)
 
590
        note.show()
 
591
 
 
592
 
 
593
register_command(cmd_gselftest)
 
594
 
 
595
 
 
596
import gettext
 
597
gettext.install('olive-gtk')
 
598
 
216
599
 
217
600
class NoDisplayError(BzrCommandError):
218
601
    """gtk could not find a proper display"""
219
602
 
220
603
    def __str__(self):
221
 
        return "No DISPLAY. gannotate is disabled."
 
604
        return "No DISPLAY. Unable to run GTK+ application."
 
605
 
 
606
 
 
607
def test_suite():
 
608
    from unittest import TestSuite
 
609
    import tests
 
610
    import sys
 
611
    default_encoding = sys.getdefaultencoding()
 
612
    try:
 
613
        result = TestSuite()
 
614
        result.addTest(tests.test_suite())
 
615
    finally:
 
616
        if sys.getdefaultencoding() != default_encoding:
 
617
            reload(sys)
 
618
            sys.setdefaultencoding(default_encoding)
 
619
    return result