/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: Curtis Hovey
  • Date: 2011-09-04 20:04:03 UTC
  • mto: This revision was merged to the branch mainline in revision 741.
  • Revision ID: sinzui.is@verizon.net-20110904200403-t38t3o2q1j600dho
Added missing tests for BranchTreeModel and CellRendererGraph.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
"""Graphical support for Bazaar using GTK.
16
16
 
17
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. 
 
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.
25
24
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 
 
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.
30
32
gtags             Manage branch tags.
31
 
visualise         Graphically visualise this branch. 
 
33
visualise         Graphically visualise this branch.
32
34
"""
33
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
 
34
52
import bzrlib
35
 
 
36
 
__version__ = '0.90.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 bzr 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(), """
 
53
import bzrlib.api
77
54
from bzrlib import (
78
55
    branch,
79
 
    builtins,
 
56
    config,
80
57
    errors,
81
 
    workingtree,
82
 
    )
83
 
""")
84
 
 
85
 
from bzrlib.commands import Command, register_command, display_command
86
 
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
87
 
from bzrlib.option import Option
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
 
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.")
98
77
 
99
78
 
100
79
def set_ui_factory():
101
 
    import_pygtk()
102
80
    from ui import GtkUIFactory
103
81
    import bzrlib.ui
104
82
    bzrlib.ui.ui_factory = GtkUIFactory()
105
83
 
106
84
 
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):
131
 
    """GTK+ branching.
132
 
    
133
 
    """
134
 
 
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):
167
 
    """Show differences in working tree in a GTK+ Window.
168
 
    
169
 
    Otherwise, all changes for the tree are listed.
170
 
    """
171
 
    takes_args = ['filename?']
172
 
    takes_options = ['revision']
173
 
 
174
 
    @display_command
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:
192
 
                tree1 = wt
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
 
 
230
 
 
231
 
class cmd_visualise(Command):
232
 
    """Graphically visualise this branch.
233
 
 
234
 
    Opens a graphical window to allow you to see the history of the branch
235
 
    and relationships between revisions in a visual manner,
236
 
 
237
 
    The default starting point is latest revision on the branch, you can
238
 
    specify a starting point with -r revision.
239
 
    """
240
 
    takes_options = [
241
 
        "revision",
242
 
        Option('limit', "Maximum number of revisions to display.",
243
 
               int, 'count')]
244
 
    takes_args = [ "location?" ]
245
 
    aliases = [ "visualize", "vis", "viz" ]
246
 
 
247
 
    def run(self, location=".", revision=None, limit=None):
248
 
        set_ui_factory()
249
 
        (br, path) = branch.Branch.open_containing(location)
250
 
        br.lock_read()
251
 
        try:
252
 
            if revision is None:
253
 
                revid = br.last_revision()
254
 
                if revid is None:
255
 
                    return
256
 
            else:
257
 
                (revno, revid) = revision[0].in_history(br)
258
 
 
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()
264
 
        finally:
265
 
            br.unlock()
266
 
 
267
 
 
268
 
class cmd_gannotate(GTKCommand):
269
 
    """GTK+ annotate.
270
 
    
271
 
    Browse changes to FILENAME line by line in a GTK+ window.
272
 
    """
273
 
 
274
 
    takes_args = ["filename", "line?"]
275
 
    takes_options = [
276
 
        Option("all", help="Show annotations on all lines."),
277
 
        Option("plain", help="Don't highlight annotation lines."),
278
 
        Option("line", type=int, argname="lineno",
279
 
               help="Jump to specified line number."),
280
 
        "revision",
281
 
    ]
282
 
    aliases = ["gblame", "gpraise"]
283
 
    
284
 
    def run(self, filename, all=False, plain=False, line='1', revision=None):
285
 
        gtk = self.open_display()
286
 
 
287
 
        try:
288
 
            line = int(line)
289
 
        except ValueError:
290
 
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
291
 
                                  line)
292
 
 
293
 
        from annotate.gannotate import GAnnotateWindow
294
 
        from annotate.config import GAnnotateConfig
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)
304
 
 
305
 
        if file_id is None:
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)()
314
 
 
315
 
        window = GAnnotateWindow(all, plain)
316
 
        window.connect("destroy", lambda w: gtk.main_quit())
317
 
        window.set_title(path + " - gannotate")
318
 
        config = GAnnotateConfig(window)
319
 
        window.show()
320
 
        br.lock_read()
321
 
        if wt is not None:
322
 
            wt.lock_read()
323
 
        try:
324
 
            window.annotate(tree, br, file_id)
325
 
            window.jump_to_line(line)
326
 
            gtk.main()
327
 
        finally:
328
 
            br.unlock()
329
 
            if wt is not None:
330
 
                wt.unlock()
331
 
 
332
 
 
333
 
 
334
 
class cmd_gcommit(GTKCommand):
335
 
    """GTK+ commit dialog
336
 
 
337
 
    Graphical user interface for committing revisions"""
338
 
    
339
 
    aliases = [ "gci" ]
340
 
    takes_args = []
341
 
    takes_options = []
342
 
 
343
 
    def run(self, filename=None):
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()
420
 
        try:
421
 
            import gtk
422
 
        except RuntimeError, e:
423
 
            if str(e) == "could not open display":
424
 
                raise NoDisplayError
425
 
 
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
 
 
599
 
 
600
 
class NoDisplayError(BzrCommandError):
601
 
    """gtk could not find a proper display"""
602
 
 
603
 
    def __str__(self):
604
 
        return "No DISPLAY. Unable to run GTK+ application."
605
 
 
606
 
 
607
 
def test_suite():
608
 
    from unittest import TestSuite
609
 
    import tests
 
85
def data_basedirs():
 
86
    return [os.path.dirname(__file__),
 
87
             "/usr/share/bzr-gtk", 
 
88
             "/usr/local/share/bzr-gtk"]
 
89
 
 
90
 
 
91
def data_path(*args):
 
92
    for basedir in data_basedirs():
 
93
        path = os.path.join(basedir, *args)
 
94
        if os.path.exists(path):
 
95
            return path
 
96
    return None
 
97
 
 
98
 
 
99
def icon_path(*args):
 
100
    return data_path(os.path.join('icons', *args))
 
101
 
 
102
 
 
103
commands = {
 
104
    "gannotate": ["gblame", "gpraise"],
 
105
    "gbranch": [],
 
106
    "gcheckout": [],
 
107
    "gcommit": ["gci"],
 
108
    "gconflicts": [],
 
109
    "gdiff": [],
 
110
    "ginit": [],
 
111
    "gmerge": [],
 
112
    "gmissing": [],
 
113
    "gpreferences": [],
 
114
    "gpush": [],
 
115
    "gsend": [],
 
116
    "gstatus": ["gst"],
 
117
    "gtags": [],
 
118
    "visualise": ["visualize", "vis", "viz", 'glog'],
 
119
    }
 
120
 
 
121
try:
 
122
    from bzrlib.plugins import loom
 
123
except ImportError:
 
124
    pass # Loom plugin doesn't appear to be present
 
125
else:
 
126
    commands["gloom"] = []
 
127
 
 
128
for cmd, aliases in commands.iteritems():
 
129
    plugin_cmds.register_lazy("cmd_%s" % cmd, aliases,
 
130
                              "bzrlib.plugins.gtk.commands")
 
131
 
 
132
def save_commit_messages(*args):
 
133
    from bzrlib.plugins.gtk import commit
 
134
    commit.save_commit_messages(*args)
 
135
 
 
136
branch.Branch.hooks.install_named_hook('post_uncommit',
 
137
                                       save_commit_messages,
 
138
                                       "Saving commit messages for gcommit")
 
139
 
 
140
credential_store_registry = getattr(config, "credential_store_registry", None)
 
141
if credential_store_registry is not None:
 
142
    try:
 
143
        credential_store_registry.register_lazy(
 
144
            "gnome-keyring", "bzrlib.plugins.gtk.keyring", "GnomeKeyringCredentialStore",
 
145
            help="The GNOME Keyring.", fallback=True)
 
146
    except TypeError:
 
147
    # Fallback credentials stores were introduced in Bazaar 1.15
 
148
        credential_store_registry.register_lazy(
 
149
            "gnome-keyring", "bzrlib.plugins.gtk.keyring", "GnomeKeyringCredentialStore",
 
150
            help="The GNOME Keyring.")
 
151
 
 
152
 
 
153
def load_tests(basic_tests, module, loader):
 
154
    testmod_names = [
 
155
        'tests',
 
156
        ]
610
157
    import sys
611
158
    default_encoding = sys.getdefaultencoding()
612
159
    try:
613
 
        result = TestSuite()
614
 
        result.addTest(tests.test_suite())
 
160
        result = basic_tests
 
161
        try:
 
162
            import gi.repository.Gtk
 
163
        except ImportError:
 
164
            return basic_tests
 
165
        basic_tests.addTest(loader.loadTestsFromModuleNames(
 
166
                ["%s.%s" % (__name__, tmn) for tmn in testmod_names]))
615
167
    finally:
616
168
        if sys.getdefaultencoding() != default_encoding:
617
169
            reload(sys)
618
170
            sys.setdefaultencoding(default_encoding)
619
 
    return result
 
171
    return basic_tests
 
172