/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
49 by Jelmer Vernooij
Merge in Dan Loda's gannotate plugin and put it in annotate/
1
# This program is free software; you can redistribute it and/or modify
2
# it under the terms of the GNU General Public License as published by
3
# the Free Software Foundation; either version 2 of the License, or
4
# (at your option) any later version.
5
6
# This program is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9
# GNU General Public License for more details.
10
11
# You should have received a copy of the GNU General Public License
12
# along with this program; if not, write to the Free Software
13
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14
15
"""GTK+ frontends to Bazaar commands """
73 by Jelmer Vernooij
Release 0.9, list myself as maintainer.
16
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
17
import bzrlib
18
162 by Aaron Bentley
Update version to 0.16.0
19
__version__ = '0.16.0'
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
20
version_info = tuple(int(n) for n in __version__.split('.'))
21
22
23
def check_bzrlib_version(desired):
24
    """Check that bzrlib is compatible.
25
26
    If version is < bzr-gtk version, assume incompatible.
27
    If version == bzr-gtk version, assume completely compatible
28
    If version == bzr-gtk version + 1, assume compatible, with deprecations
29
    Otherwise, assume incompatible.
30
    """
31
    desired_plus = (desired[0], desired[1]+1)
32
    bzrlib_version = bzrlib.version_info[:2]
33
    if bzrlib_version == desired:
34
        return
35
    try:
36
        from bzrlib.trace import warning
37
    except ImportError:
38
        # get the message out any way we can
39
        from warnings import warn as warning
40
    if bzrlib_version < desired:
41
        warning('Installed bzr version %s is too old to be used with bzr-gtk'
42
                ' %s.' % (bzrlib.__version__, __version__))
43
        # Not using BzrNewError, because it may not exist.
44
        raise Exception, ('Version mismatch', version_info)
45
    else:
46
        warning('bzr-gtk is not up to date with installed bzr version %s.'
47
                ' \nThere should be a newer version available, e.g. %i.%i.' 
48
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
49
        if bzrlib_version != desired_plus:
50
            raise Exception, 'Version mismatch'
51
52
53
check_bzrlib_version(version_info[:2])
54
146 by Jelmer Vernooij
Move more code to top-level directory.
55
from bzrlib.trace import warning
56
if __name__ != 'bzrlib.plugins.gtk':
57
    warning("Not running as bzrlib.plugins.gtk, things may break.")
58
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
59
from bzrlib.lazy_import import lazy_import
60
lazy_import(globals(), """
61
from bzrlib import (
62
    branch,
63
    errors,
64
    workingtree,
65
    )
66
""")
67
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
68
from bzrlib.commands import Command, register_command, display_command
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
69
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
70
from bzrlib.option import Option
71
126.1.5 by Szilveszter Farkas (Phanatic)
bzr gbranch should work now (Fixed: #77751)
72
import os.path
73
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
74
def import_pygtk():
75
    try:
76
        import pygtk
77
    except ImportError:
78
        raise errors.BzrCommandError("PyGTK not installed.")
79
    pygtk.require('2.0')
80
    return pygtk
81
82
133 by Jelmer Vernooij
Actually use the ui factory.
83
def set_ui_factory():
177 by Jelmer Vernooij
Register commands all at once.
84
    import_pygtk()
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
85
    from ui import GtkUIFactory
133 by Jelmer Vernooij
Actually use the ui factory.
86
    import bzrlib.ui
87
    bzrlib.ui.ui_factory = GtkUIFactory()
88
89
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
90
class cmd_gbranch(Command):
91
    """GTK+ branching.
92
    
93
    """
94
95
    def run(self):
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
96
        pygtk = import_pygtk()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
97
        try:
98
            import gtk
99
        except RuntimeError, e:
100
            if str(e) == "could not open display":
101
                raise NoDisplayError
102
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
103
        from bzrlib.plugins.gtk.branch import BranchDialog
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
104
133 by Jelmer Vernooij
Actually use the ui factory.
105
        set_ui_factory()
126.1.5 by Szilveszter Farkas (Phanatic)
bzr gbranch should work now (Fixed: #77751)
106
        dialog = BranchDialog(os.path.abspath('.'))
126.1.15 by Szilveszter Farkas (Phanatic)
Refactoring the Branch dialog. We also have a Revision Browser now.
107
        dialog.run()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
108
126.1.18 by Szilveszter Farkas (Phanatic)
Improved Branch dialog. Refactored Checkout dialog.
109
class cmd_gcheckout(Command):
110
    """ GTK+ checkout.
111
    
112
    """
113
    
114
    def run(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
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
122
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
126.1.18 by Szilveszter Farkas (Phanatic)
Improved Branch dialog. Refactored Checkout dialog.
123
124
        set_ui_factory()
125
        dialog = CheckoutDialog(os.path.abspath('.'))
126
        dialog.run()
127
128
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
129
class cmd_gpush(Command):
130
    """ GTK+ push.
131
    
132
    """
133
    takes_args = [ "location?" ]
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
134
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
135
    def run(self, location="."):
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
136
        (br, path) = branch.Branch.open_containing(location)
137
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
138
        pygtk = import_pygtk()
139
        try:
140
            import gtk
141
        except RuntimeError, e:
142
            if str(e) == "could not open display":
143
                raise NoDisplayError
144
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
145
        from push import PushDialog
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
146
147
        set_ui_factory()
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
148
        dialog = PushDialog(br)
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
149
        dialog.run()
150
151
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
152
class cmd_gdiff(Command):
153
    """Show differences in working tree in a GTK+ Window.
154
    
155
    Otherwise, all changes for the tree are listed.
156
    """
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
157
    takes_args = ['filename?']
58.1.1 by Aaron Bentley
gdiff takes -r arguments
158
    takes_options = ['revision']
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
159
160
    @display_command
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
161
    def run(self, revision=None, filename=None):
133 by Jelmer Vernooij
Actually use the ui factory.
162
        set_ui_factory()
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
163
        wt = workingtree.WorkingTree.open_containing(".")[0]
161 by Aaron Bentley
Fix gannotate interaction with dirstate
164
        wt.lock_read()
165
        try:
166
            branch = wt.branch
167
            if revision is not None:
168
                if len(revision) == 1:
169
                    tree1 = wt
170
                    revision_id = revision[0].in_history(branch).rev_id
171
                    tree2 = branch.repository.revision_tree(revision_id)
172
                elif len(revision) == 2:
173
                    revision_id_0 = revision[0].in_history(branch).rev_id
174
                    tree2 = branch.repository.revision_tree(revision_id_0)
175
                    revision_id_1 = revision[1].in_history(branch).rev_id
176
                    tree1 = branch.repository.revision_tree(revision_id_1)
177
            else:
58.1.1 by Aaron Bentley
gdiff takes -r arguments
178
                tree1 = wt
161 by Aaron Bentley
Fix gannotate interaction with dirstate
179
                tree2 = tree1.basis_tree()
180
181
            from diff import DiffWindow
182
            import gtk
183
            window = DiffWindow()
184
            window.connect("destroy", gtk.main_quit)
185
            window.set_diff("Working Tree", tree1, tree2)
186
            if filename is not None:
187
                tree_filename = wt.relpath(filename)
188
                try:
189
                    window.set_file(tree_filename)
190
                except NoSuchFile:
191
                    if (tree1.inventory.path2id(tree_filename) is None and 
192
                        tree2.inventory.path2id(tree_filename) is None):
193
                        raise NotVersionedError(filename)
194
                    raise BzrCommandError('No changes found for file "%s"' % 
195
                                          filename)
196
            window.show()
197
198
            gtk.main()
199
        finally:
200
            wt.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
201
202
203
class cmd_visualise(Command):
204
    """Graphically visualise this branch.
205
206
    Opens a graphical window to allow you to see the history of the branch
207
    and relationships between revisions in a visual manner,
208
209
    The default starting point is latest revision on the branch, you can
210
    specify a starting point with -r revision.
211
    """
212
    takes_options = [
213
        "revision",
214
        Option('limit', "maximum number of revisions to display",
215
               int, 'count')]
216
    takes_args = [ "location?" ]
217
    aliases = [ "visualize", "vis", "viz" ]
218
219
    def run(self, location=".", revision=None, limit=None):
133 by Jelmer Vernooij
Actually use the ui factory.
220
        set_ui_factory()
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
221
        (br, path) = branch.Branch.open_containing(location)
222
        br.lock_read()
223
        br.repository.lock_read()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
224
        try:
225
            if revision is None:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
226
                revid = br.last_revision()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
227
                if revid is None:
228
                    return
229
            else:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
230
                (revno, revid) = revision[0].in_history(br)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
231
152 by Jelmer Vernooij
Cleanup some more code.
232
            from viz.branchwin import BranchWindow
233
            import gtk
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
234
                
152 by Jelmer Vernooij
Cleanup some more code.
235
            pp = BranchWindow()
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
236
            pp.set_branch(br, revid, limit)
152 by Jelmer Vernooij
Cleanup some more code.
237
            pp.connect("destroy", lambda w: gtk.main_quit())
238
            pp.show()
239
            gtk.main()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
240
        finally:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
241
            br.repository.unlock()
242
            br.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
243
244
245
class cmd_gannotate(Command):
246
    """GTK+ annotate.
247
    
248
    Browse changes to FILENAME line by line in a GTK+ window.
249
    """
250
59.2.1 by Aaron Bentley
Gannotate takes a line number
251
    takes_args = ["filename", "line?"]
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
252
    takes_options = [
253
        Option("all", help="show annotations on all lines"),
254
        Option("plain", help="don't highlight annotation lines"),
255
        Option("line", type=int, argname="lineno",
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
256
               help="jump to specified line number"),
257
        "revision",
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
258
    ]
259
    aliases = ["gblame", "gpraise"]
260
    
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
261
    def run(self, filename, all=False, plain=False, line='1', revision=None):
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
262
        pygtk = import_pygtk()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
263
264
        try:
265
            import gtk
266
        except RuntimeError, e:
267
            if str(e) == "could not open display":
268
                raise NoDisplayError
133 by Jelmer Vernooij
Actually use the ui factory.
269
        set_ui_factory()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
270
59.2.1 by Aaron Bentley
Gannotate takes a line number
271
        try:
272
            line = int(line)
273
        except ValueError:
274
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
275
                                  line)
276
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
277
        from annotate.gannotate import GAnnotateWindow
278
        from annotate.config import GAnnotateConfig
177 by Jelmer Vernooij
Register commands all at once.
279
        from bzrlib.bzrdir import BzrDir
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
280
161 by Aaron Bentley
Fix gannotate interaction with dirstate
281
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
282
        if wt is not None:
283
            tree = wt
284
        else:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
285
            tree = br.basis_tree()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
286
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
287
        file_id = tree.path2id(path)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
288
289
        if file_id is None:
290
            raise NotVersionedError(filename)
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
291
        if revision is not None:
292
            if len(revision) != 1:
293
                raise BzrCommandError("Only 1 revion may be specified.")
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
294
            revision_id = revision[0].in_history(br).rev_id
295
            tree = br.repository.revision_tree(revision_id)
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
296
        else:
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
297
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
298
299
        window = GAnnotateWindow(all, plain)
300
        window.connect("destroy", lambda w: gtk.main_quit())
301
        window.set_title(path + " - gannotate")
302
        config = GAnnotateConfig(window)
303
        window.show()
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
304
        br.lock_read()
161 by Aaron Bentley
Fix gannotate interaction with dirstate
305
        if wt is not None:
306
            wt.lock_read()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
307
        try:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
308
            window.annotate(tree, br, file_id)
161 by Aaron Bentley
Fix gannotate interaction with dirstate
309
            window.jump_to_line(line)
310
            gtk.main()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
311
        finally:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
312
            br.unlock()
161 by Aaron Bentley
Fix gannotate interaction with dirstate
313
            if wt is not None:
314
                wt.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
315
316
317
class cmd_gcommit(Command):
318
    """GTK+ commit dialog
319
320
    Graphical user interface for committing revisions"""
321
    
145 by Jelmer Vernooij
Fix some strings, import.
322
    aliases = [ "gci" ]
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
323
    takes_args = []
324
    takes_options = []
325
326
    def run(self, filename=None):
93.1.17 by Alexander Belchenko
gcommit reworked again.
327
        import os
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
328
        pygtk = import_pygtk()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
329
330
        try:
331
            import gtk
332
        except RuntimeError, e:
333
            if str(e) == "could not open display":
334
                raise NoDisplayError
335
133 by Jelmer Vernooij
Actually use the ui factory.
336
        set_ui_factory()
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
337
        from commit import CommitDialog
93.1.17 by Alexander Belchenko
gcommit reworked again.
338
        from bzrlib.errors import (BzrCommandError,
339
                                   NotBranchError,
178 by Jelmer Vernooij
Remove unneeded imports.
340
                                   NoWorkingTree)
93.1.17 by Alexander Belchenko
gcommit reworked again.
341
342
        wt = None
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
343
        br = None
93.1.17 by Alexander Belchenko
gcommit reworked again.
344
        try:
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
345
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
346
            br = wt.branch
93.1.17 by Alexander Belchenko
gcommit reworked again.
347
        except NotBranchError, e:
348
            path = e.path
349
        except NoWorkingTree, e:
350
            path = e.base
351
            try:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
352
                (br, path) = branch.Branch.open_containing(path)
93.1.17 by Alexander Belchenko
gcommit reworked again.
353
            except NotBranchError, e:
354
                path = e.path
355
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
356
        commit = CommitDialog(wt, path, not br)
135 by Jelmer Vernooij
Throw out the old CommitDialog code and use the new code instead, also for 'gcommit'.
357
        commit.run()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
358
359
157 by Jelmer Vernooij
Add gstatus command.
360
class cmd_gstatus(Command):
361
    """GTK+ status dialog
362
363
    Graphical user interface for showing status 
364
    information."""
365
    
366
    aliases = [ "gst" ]
367
    takes_args = ['PATH?']
368
    takes_options = []
369
370
    def run(self, path='.'):
371
        import os
372
        pygtk = import_pygtk()
373
374
        try:
375
            import gtk
376
        except RuntimeError, e:
377
            if str(e) == "could not open display":
378
                raise NoDisplayError
379
380
        set_ui_factory()
381
        from status import StatusDialog
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
382
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
157 by Jelmer Vernooij
Add gstatus command.
383
        status = StatusDialog(wt, wt_path)
384
        status.connect("destroy", gtk.main_quit)
385
        status.run()
386
387
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
388
class cmd_gconflicts(Command):
389
    """ GTK+ push.
390
    
391
    """
392
    def run(self):
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
393
        (wt, path) = workingtree.WorkingTree.open_containing('.')
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
394
        
395
        pygtk = import_pygtk()
396
        try:
397
            import gtk
398
        except RuntimeError, e:
399
            if str(e) == "could not open display":
400
                raise NoDisplayError
401
402
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
403
404
        set_ui_factory()
405
        dialog = ConflictsDialog(wt)
406
        dialog.run()
407
157 by Jelmer Vernooij
Add gstatus command.
408
171 by Jelmer Vernooij
Initial work on a preferences dialog in GTK+, including a list of plugins with metadata browser.
409
class cmd_gpreferences(Command):
410
    """ GTK+ preferences dialog.
411
412
    """
413
    def run(self):
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.preferences import PreferencesWindow
422
423
        set_ui_factory()
424
        dialog = PreferencesWindow()
425
        dialog.run()
426
427
175 by Jelmer Vernooij
Add very simple gmissing command.
428
429
class cmd_gmissing(Command):
430
    """ GTK+ missing revisions dialog.
431
432
    """
433
    takes_args = ["other_branch?"]
434
    def run(self, other_branch=None):
435
        pygtk = import_pygtk()
436
        try:
437
            import gtk
438
        except RuntimeError, e:
439
            if str(e) == "could not open display":
440
                raise NoDisplayError
441
442
        from bzrlib.plugins.gtk.missing import MissingWindow
443
        from bzrlib.branch import Branch
444
445
        local_branch = Branch.open_containing(".")[0]
446
        if other_branch is None:
447
            other_branch = local_branch.get_parent()
448
            
449
            if other_branch is None:
450
                raise errors.BzrCommandError("No peer location known or specified.")
451
        remote_branch = Branch.open_containing(other_branch)[0]
452
        set_ui_factory()
453
        local_branch.lock_read()
454
        try:
455
            remote_branch.lock_read()
456
            try:
457
                dialog = MissingWindow(local_branch, remote_branch)
458
                dialog.run()
459
            finally:
460
                remote_branch.unlock()
461
        finally:
462
            local_branch.unlock()
463
177 by Jelmer Vernooij
Register commands all at once.
464
465
commands = [
466
    cmd_gmissing, 
467
    cmd_gpreferences, 
468
    cmd_gconflicts, 
469
    cmd_gstatus,
470
    cmd_gcommit, 
471
    cmd_gannotate, 
472
    cmd_visualise, 
473
    cmd_gdiff,
474
    cmd_gpush, 
475
    cmd_gcheckout, 
476
    cmd_gbranch 
477
    ]
478
479
for cmd in commands:
480
    register_command(cmd)
175 by Jelmer Vernooij
Add very simple gmissing command.
481
152 by Jelmer Vernooij
Cleanup some more code.
482
import gettext
483
gettext.install('olive-gtk')
484
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
485
class NoDisplayError(BzrCommandError):
486
    """gtk could not find a proper display"""
487
488
    def __str__(self):
133 by Jelmer Vernooij
Actually use the ui factory.
489
        return "No DISPLAY. Unable to run GTK+ application."
490
140 by Jelmer Vernooij
add framework for tests.
491
def test_suite():
492
    from unittest import TestSuite
493
    import tests
163 by Aaron Bentley
Prevent test suite from causing default-encoding changes
494
    import sys
495
    default_encoding = sys.getdefaultencoding()
496
    try:
497
        result = TestSuite()
498
        result.addTest(tests.test_suite())
499
    finally:
170.1.2 by Aaron Bentley
Test suite only fixes encoding if it's changed. Fixes test_selftest bug.
500
        if sys.getdefaultencoding() != default_encoding:
501
            reload(sys)
502
            sys.setdefaultencoding(default_encoding)
140 by Jelmer Vernooij
add framework for tests.
503
    return result