/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: Jelmer Vernooij
  • Date: 2007-07-15 15:22:29 UTC
  • Revision ID: jelmer@samba.org-20070715152229-clmlen0vpd8d2pzx
Add docstrings, remove unused code.

Show diffs side-by-side

added added

removed removed

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