/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: Vincent Ladeuil
  • Date: 2008-05-05 18:16:46 UTC
  • mto: (487.1.1 gtk)
  • mto: This revision was merged to the branch mainline in revision 490.
  • Revision ID: v.ladeuil+lp@free.fr-20080505181646-n95l8ltw2u6jtr26
Fix bug #187283 fix replacing _() by _i18n().

* genpot.sh 
Remove duplication. Add the ability to specify the genrated pot
file on command-line for debugging purposes.

* po/olive-gtk.pot:
Regenerated.

* __init__.py, branch.py, branchview/treeview.py, checkout.py,
commit.py, conflicts.py, diff.py, errors.py, initialize.py,
merge.py, nautilus-bzr.py, olive/__init__.py, olive/add.py,
olive/bookmark.py, olive/guifiles.py, olive/info.py,
olive/menu.py, olive/mkdir.py, olive/move.py, olive/remove.py,
olive/rename.py, push.py, revbrowser.py, status.py, tags.py:
Replace all calls to _() by calls to _i18n(), the latter being
defined in __init__.py and imported in the other modules from
there. This fix the problem encountered countless times when
running bzr selftest and getting silly error messages about
boolean not being callables.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
# along with this program; if not, write to the Free Software
13
13
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14
14
 
15
 
"""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
ghandle-patch     Display and optionally merge a merge directive or patch.
 
26
ginit             Initialise a new branch.
 
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.
 
32
gtags             Manage branch tags.
 
33
visualise         Graphically visualise this branch. 
 
34
"""
 
35
 
 
36
import sys
 
37
 
 
38
import bzrlib
 
39
 
 
40
version_info = (0, 94, 0, 'rc', 1)
 
41
 
 
42
if version_info[3] == 'final':
 
43
    version_string = '%d.%d.%d' % version_info[:3]
 
44
else:
 
45
    version_string = '%d.%d.%d%s%d' % version_info
 
46
__version__ = version_string
 
47
 
 
48
required_bzrlib = (1, 3)
 
49
 
 
50
def check_bzrlib_version(desired):
 
51
    """Check that bzrlib is compatible.
 
52
 
 
53
    If version is < bzr-gtk version, assume incompatible.
 
54
    """
 
55
    bzrlib_version = bzrlib.version_info[:2]
 
56
    try:
 
57
        from bzrlib.trace import warning
 
58
    except ImportError:
 
59
        # get the message out any way we can
 
60
        from warnings import warn as warning
 
61
    if bzrlib_version < desired:
 
62
        from bzrlib.errors import BzrError
 
63
        warning('Installed Bazaar version %s is too old to be used with bzr-gtk'
 
64
                ' %s.' % (bzrlib.__version__, __version__))
 
65
        raise BzrError('Version mismatch: %r, %r' % (version_info, bzrlib.version_info) )
 
66
 
 
67
 
 
68
if version_info[2] == "final":
 
69
    check_bzrlib_version(required_bzrlib)
 
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
    merge_directive,
 
82
    workingtree,
 
83
    )
 
84
""")
16
85
 
17
86
from bzrlib.commands import Command, register_command, display_command
18
87
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
19
 
from bzrlib.commands import Command, register_command
20
88
from bzrlib.option import Option
21
 
from bzrlib.branch import Branch
22
 
from bzrlib.workingtree import WorkingTree
23
 
from bzrlib.bzrdir import BzrDir
24
 
 
25
 
__version__ = '0.11.0'
26
 
 
27
 
class cmd_gbranch(Command):
 
89
 
 
90
import os.path
 
91
 
 
92
def import_pygtk():
 
93
    try:
 
94
        import pygtk
 
95
    except ImportError:
 
96
        raise errors.BzrCommandError("PyGTK not installed.")
 
97
    pygtk.require('2.0')
 
98
    return pygtk
 
99
 
 
100
 
 
101
def set_ui_factory():
 
102
    import_pygtk()
 
103
    from ui import GtkUIFactory
 
104
    import bzrlib.ui
 
105
    bzrlib.ui.ui_factory = GtkUIFactory()
 
106
 
 
107
 
 
108
def data_path():
 
109
    return os.path.dirname(__file__)
 
110
 
 
111
 
 
112
def icon_path(*args):
 
113
    basedirs = [os.path.join(data_path()),
 
114
             "/usr/share/bzr-gtk", 
 
115
             "/usr/local/share/bzr-gtk"]
 
116
    for basedir in basedirs:
 
117
        path = os.path.join(basedir, 'icons', *args)
 
118
        if os.path.exists(path):
 
119
            return path
 
120
    return None
 
121
 
 
122
 
 
123
class GTKCommand(Command):
 
124
    """Abstract class providing GTK specific run commands."""
 
125
 
 
126
    def open_display(self):
 
127
        pygtk = import_pygtk()
 
128
        try:
 
129
            import gtk
 
130
        except RuntimeError, e:
 
131
            if str(e) == "could not open display":
 
132
                raise NoDisplayError
 
133
        set_ui_factory()
 
134
        return gtk
 
135
 
 
136
    def run(self):
 
137
        self.open_display()
 
138
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
 
139
        dialog.run()
 
140
 
 
141
 
 
142
class cmd_gbranch(GTKCommand):
28
143
    """GTK+ branching.
29
144
    
30
145
    """
31
146
 
32
 
    def run(self):
33
 
        import pygtk
34
 
        pygtk.require("2.0")
35
 
        try:
36
 
            import gtk
37
 
        except RuntimeError, e:
38
 
            if str(e) == "could not open display":
39
 
                raise NoDisplayError
40
 
 
41
 
        from bzrlib.plugins.gtk.olive.branch import BranchDialog
42
 
 
43
 
        window = BranchDialog('.')
44
 
        window.display()
45
 
 
46
 
register_command(cmd_gbranch)
47
 
 
48
 
class cmd_gdiff(Command):
 
147
    def get_gtk_dialog(self, path):
 
148
        from bzrlib.plugins.gtk.branch import BranchDialog
 
149
        return BranchDialog(path)
 
150
 
 
151
 
 
152
class cmd_gcheckout(GTKCommand):
 
153
    """ GTK+ checkout.
 
154
    
 
155
    """
 
156
    
 
157
    def get_gtk_dialog(self, path):
 
158
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
 
159
        return CheckoutDialog(path)
 
160
 
 
161
 
 
162
 
 
163
class cmd_gpush(GTKCommand):
 
164
    """ GTK+ push.
 
165
    
 
166
    """
 
167
    takes_args = [ "location?" ]
 
168
 
 
169
    def run(self, location="."):
 
170
        (br, path) = branch.Branch.open_containing(location)
 
171
        self.open_display()
 
172
        from push import PushDialog
 
173
        dialog = PushDialog(br.repository, br.last_revision(), br)
 
174
        dialog.run()
 
175
 
 
176
 
 
177
 
 
178
class cmd_gdiff(GTKCommand):
49
179
    """Show differences in working tree in a GTK+ Window.
50
180
    
51
181
    Otherwise, all changes for the tree are listed.
55
185
 
56
186
    @display_command
57
187
    def run(self, revision=None, filename=None):
58
 
        wt = WorkingTree.open_containing(".")[0]
59
 
        branch = wt.branch
60
 
        if revision is not None:
61
 
            if len(revision) == 1:
 
188
        set_ui_factory()
 
189
        wt = workingtree.WorkingTree.open_containing(".")[0]
 
190
        wt.lock_read()
 
191
        try:
 
192
            branch = wt.branch
 
193
            if revision is not None:
 
194
                if len(revision) == 1:
 
195
                    tree1 = wt
 
196
                    revision_id = revision[0].in_history(branch).rev_id
 
197
                    tree2 = branch.repository.revision_tree(revision_id)
 
198
                elif len(revision) == 2:
 
199
                    revision_id_0 = revision[0].in_history(branch).rev_id
 
200
                    tree2 = branch.repository.revision_tree(revision_id_0)
 
201
                    revision_id_1 = revision[1].in_history(branch).rev_id
 
202
                    tree1 = branch.repository.revision_tree(revision_id_1)
 
203
            else:
62
204
                tree1 = wt
63
 
                revision_id = revision[0].in_history(branch).rev_id
64
 
                tree2 = branch.repository.revision_tree(revision_id)
65
 
            elif len(revision) == 2:
66
 
                revision_id_0 = revision[0].in_history(branch).rev_id
67
 
                tree2 = branch.repository.revision_tree(revision_id_0)
68
 
                revision_id_1 = revision[1].in_history(branch).rev_id
69
 
                tree1 = branch.repository.revision_tree(revision_id_1)
70
 
        else:
71
 
            tree1 = wt
72
 
            tree2 = tree1.basis_tree()
73
 
 
74
 
        from bzrlib.plugins.gtk.viz.diffwin import DiffWindow
75
 
        import gtk
76
 
        window = DiffWindow()
77
 
        window.connect("destroy", lambda w: gtk.main_quit())
78
 
        window.set_diff("Working Tree", tree1, tree2)
79
 
        if filename is not None:
80
 
            tree_filename = tree1.relpath(filename)
81
 
            try:
82
 
                window.set_file(tree_filename)
83
 
            except NoSuchFile:
84
 
                if (tree1.inventory.path2id(tree_filename) is None and 
85
 
                    tree2.inventory.path2id(tree_filename) is None):
86
 
                    raise NotVersionedError(filename)
87
 
                raise BzrCommandError('No changes found for file "%s"' % 
88
 
                                      filename)
89
 
        window.show()
90
 
 
91
 
        gtk.main()
92
 
 
93
 
register_command(cmd_gdiff)
 
205
                tree2 = tree1.basis_tree()
 
206
 
 
207
            from diff import DiffWindow
 
208
            import gtk
 
209
            window = DiffWindow()
 
210
            window.connect("destroy", gtk.main_quit)
 
211
            window.set_diff("Working Tree", tree1, tree2)
 
212
            if filename is not None:
 
213
                tree_filename = wt.relpath(filename)
 
214
                try:
 
215
                    window.set_file(tree_filename)
 
216
                except NoSuchFile:
 
217
                    if (tree1.path2id(tree_filename) is None and 
 
218
                        tree2.path2id(tree_filename) is None):
 
219
                        raise NotVersionedError(filename)
 
220
                    raise BzrCommandError('No changes found for file "%s"' % 
 
221
                                          filename)
 
222
            window.show()
 
223
 
 
224
            gtk.main()
 
225
        finally:
 
226
            wt.unlock()
 
227
 
 
228
 
 
229
def start_viz_window(branch, revisions, limit=None):
 
230
    """Start viz on branch with revision revision.
 
231
    
 
232
    :return: The viz window object.
 
233
    """
 
234
    from viz import BranchWindow
 
235
    return BranchWindow(branch, revisions, limit)
 
236
 
94
237
 
95
238
class cmd_visualise(Command):
96
239
    """Graphically visualise this branch.
103
246
    """
104
247
    takes_options = [
105
248
        "revision",
106
 
        Option('limit', "maximum number of revisions to display",
 
249
        Option('limit', "Maximum number of revisions to display.",
107
250
               int, 'count')]
108
 
    takes_args = [ "location?" ]
 
251
    takes_args = [ "locations*" ]
109
252
    aliases = [ "visualize", "vis", "viz" ]
110
253
 
111
 
    def run(self, location=".", revision=None, limit=None):
112
 
        (branch, path) = Branch.open_containing(location)
113
 
        branch.lock_read()
114
 
        branch.repository.lock_read()
115
 
        try:
 
254
    def run(self, locations_list, revision=None, limit=None):
 
255
        set_ui_factory()
 
256
        if locations_list is None:
 
257
            locations_list = ["."]
 
258
        revids = []
 
259
        for location in locations_list:
 
260
            (br, path) = branch.Branch.open_containing(location)
116
261
            if revision is None:
117
 
                revid = branch.last_revision()
118
 
                if revid is None:
119
 
                    return
 
262
                revids.append(br.last_revision())
120
263
            else:
121
 
                (revno, revid) = revision[0].in_history(branch)
122
 
 
123
 
            from viz.bzrkapp import BzrkApp
124
 
                
125
 
            app = BzrkApp()
126
 
            app.show(branch, revid, limit)
127
 
        finally:
128
 
            branch.repository.unlock()
129
 
            branch.unlock()
130
 
        app.main()
131
 
 
132
 
 
133
 
register_command(cmd_visualise)
134
 
 
135
 
class cmd_gannotate(Command):
 
264
                (revno, revid) = revision[0].in_history(br)
 
265
                revids.append(revid)
 
266
        import gtk
 
267
        pp = start_viz_window(br, revids, limit)
 
268
        pp.connect("destroy", lambda w: gtk.main_quit())
 
269
        pp.show()
 
270
        gtk.main()
 
271
 
 
272
 
 
273
class cmd_gannotate(GTKCommand):
136
274
    """GTK+ annotate.
137
275
    
138
276
    Browse changes to FILENAME line by line in a GTK+ window.
140
278
 
141
279
    takes_args = ["filename", "line?"]
142
280
    takes_options = [
143
 
        Option("all", help="show annotations on all lines"),
144
 
        Option("plain", help="don't highlight annotation lines"),
 
281
        Option("all", help="Show annotations on all lines."),
 
282
        Option("plain", help="Don't highlight annotation lines."),
145
283
        Option("line", type=int, argname="lineno",
146
 
               help="jump to specified line number")
 
284
               help="Jump to specified line number."),
 
285
        "revision",
147
286
    ]
148
287
    aliases = ["gblame", "gpraise"]
149
288
    
150
 
    def run(self, filename, all=False, plain=False, line='1'):
151
 
        import pygtk
152
 
        pygtk.require("2.0")
153
 
 
154
 
        try:
155
 
            import gtk
156
 
        except RuntimeError, e:
157
 
            if str(e) == "could not open display":
158
 
                raise NoDisplayError
 
289
    def run(self, filename, all=False, plain=False, line='1', revision=None):
 
290
        gtk = self.open_display()
159
291
 
160
292
        try:
161
293
            line = int(line)
165
297
 
166
298
        from annotate.gannotate import GAnnotateWindow
167
299
        from annotate.config import GAnnotateConfig
168
 
 
169
 
        (wt, path) = WorkingTree.open_containing(filename)
170
 
        branch = wt.branch
171
 
 
172
 
        file_id = wt.path2id(path)
 
300
        from bzrlib.bzrdir import BzrDir
 
301
 
 
302
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
 
303
        if wt is not None:
 
304
            tree = wt
 
305
        else:
 
306
            tree = br.basis_tree()
 
307
 
 
308
        file_id = tree.path2id(path)
173
309
 
174
310
        if file_id is None:
175
311
            raise NotVersionedError(filename)
 
312
        if revision is not None:
 
313
            if len(revision) != 1:
 
314
                raise BzrCommandError("Only 1 revion may be specified.")
 
315
            revision_id = revision[0].in_history(br).rev_id
 
316
            tree = br.repository.revision_tree(revision_id)
 
317
        else:
 
318
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
176
319
 
177
320
        window = GAnnotateWindow(all, plain)
178
321
        window.connect("destroy", lambda w: gtk.main_quit())
179
 
        window.set_title(path + " - gannotate")
180
322
        config = GAnnotateConfig(window)
181
323
        window.show()
182
 
        branch.lock_read()
 
324
        br.lock_read()
 
325
        if wt is not None:
 
326
            wt.lock_read()
183
327
        try:
184
 
            window.annotate(branch, file_id)
 
328
            window.annotate(tree, br, file_id)
 
329
            window.jump_to_line(line)
 
330
            gtk.main()
185
331
        finally:
186
 
            branch.unlock()
187
 
        window.jump_to_line(line)
188
 
        
189
 
        gtk.main()
190
 
 
191
 
register_command(cmd_gannotate)
192
 
 
193
 
class cmd_gcommit(Command):
 
332
            br.unlock()
 
333
            if wt is not None:
 
334
                wt.unlock()
 
335
 
 
336
 
 
337
 
 
338
class cmd_gcommit(GTKCommand):
194
339
    """GTK+ commit dialog
195
340
 
196
341
    Graphical user interface for committing revisions"""
197
 
    
 
342
 
 
343
    aliases = [ "gci" ]
198
344
    takes_args = []
199
345
    takes_options = []
200
346
 
201
347
    def run(self, filename=None):
202
 
        import pygtk
203
 
        pygtk.require("2.0")
204
 
 
 
348
        import os
 
349
        self.open_display()
 
350
        from commit import CommitDialog
 
351
        from bzrlib.errors import (BzrCommandError,
 
352
                                   NotBranchError,
 
353
                                   NoWorkingTree)
 
354
 
 
355
        wt = None
 
356
        br = None
 
357
        try:
 
358
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
 
359
            br = wt.branch
 
360
        except NoWorkingTree, e:
 
361
            from dialog import error_dialog
 
362
            error_dialog(_i18n('Directory does not have a working tree'),
 
363
                         _i18n('Operation aborted.'))
 
364
            return 1 # should this be retval=3?
 
365
 
 
366
        # It is a good habit to keep things locked for the duration, but it
 
367
        # could cause difficulties if someone wants to do things in another
 
368
        # window... We could lock_read() until we actually go to commit
 
369
        # changes... Just a thought.
 
370
        wt.lock_write()
 
371
        try:
 
372
            dlg = CommitDialog(wt)
 
373
            return dlg.run()
 
374
        finally:
 
375
            wt.unlock()
 
376
 
 
377
 
 
378
class cmd_gstatus(GTKCommand):
 
379
    """GTK+ status dialog
 
380
 
 
381
    Graphical user interface for showing status 
 
382
    information."""
 
383
    
 
384
    aliases = [ "gst" ]
 
385
    takes_args = ['PATH?']
 
386
    takes_options = ['revision']
 
387
 
 
388
    def run(self, path='.', revision=None):
 
389
        import os
 
390
        gtk = self.open_display()
 
391
        from status import StatusDialog
 
392
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
 
393
        
 
394
        if revision is not None:
 
395
            try:
 
396
                revision_id = revision[0].in_history(wt.branch).rev_id
 
397
            except:
 
398
                from bzrlib.errors import BzrError
 
399
                raise BzrError('Revision %r doesn\'t exist' % revision[0].user_spec )
 
400
        else:
 
401
            revision_id = None
 
402
 
 
403
        status = StatusDialog(wt, wt_path, revision_id)
 
404
        status.connect("destroy", gtk.main_quit)
 
405
        status.run()
 
406
 
 
407
 
 
408
class cmd_gsend(GTKCommand):
 
409
    """GTK+ send merge directive.
 
410
 
 
411
    """
 
412
    def run(self):
 
413
        (br, path) = branch.Branch.open_containing(".")
 
414
        gtk = self.open_display()
 
415
        from bzrlib.plugins.gtk.mergedirective import SendMergeDirectiveDialog
 
416
        from StringIO import StringIO
 
417
        dialog = SendMergeDirectiveDialog(br)
 
418
        if dialog.run() == gtk.RESPONSE_OK:
 
419
            outf = StringIO()
 
420
            outf.writelines(dialog.get_merge_directive().to_lines())
 
421
            mail_client = br.get_config().get_mail_client()
 
422
            mail_client.compose_merge_request(dialog.get_mail_to(), "[MERGE]", 
 
423
                outf.getvalue())
 
424
 
 
425
            
 
426
 
 
427
 
 
428
class cmd_gconflicts(GTKCommand):
 
429
    """GTK+ conflicts.
 
430
    
 
431
    Select files from the list of conflicts and run an external utility to
 
432
    resolve them.
 
433
    """
 
434
    def run(self):
 
435
        (wt, path) = workingtree.WorkingTree.open_containing('.')
 
436
        self.open_display()
 
437
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
 
438
        dialog = ConflictsDialog(wt)
 
439
        dialog.run()
 
440
 
 
441
 
 
442
class cmd_gpreferences(GTKCommand):
 
443
    """ GTK+ preferences dialog.
 
444
 
 
445
    """
 
446
    def run(self):
 
447
        self.open_display()
 
448
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
 
449
        dialog = PreferencesWindow()
 
450
        dialog.run()
 
451
 
 
452
 
 
453
class cmd_gmissing(Command):
 
454
    """ GTK+ missing revisions dialog.
 
455
 
 
456
    """
 
457
    takes_args = ["other_branch?"]
 
458
    def run(self, other_branch=None):
 
459
        pygtk = import_pygtk()
205
460
        try:
206
461
            import gtk
207
462
        except RuntimeError, e:
208
463
            if str(e) == "could not open display":
209
464
                raise NoDisplayError
210
465
 
211
 
        from olive.commit import CommitDialog
212
 
        from bzrlib.commit import Commit
213
 
        from bzrlib.errors import (BzrCommandError, PointlessCommit, ConflictsInTree, 
214
 
           StrictCommitFailed)
215
 
 
216
 
        (wt, path) = WorkingTree.open_containing(filename)
217
 
 
218
 
        dialog = CommitDialog(wt, path)
219
 
        dialog.display()
220
 
        gtk.main()
221
 
 
222
 
register_command(cmd_gcommit)
 
466
        from bzrlib.plugins.gtk.missing import MissingWindow
 
467
        from bzrlib.branch import Branch
 
468
 
 
469
        local_branch = Branch.open_containing(".")[0]
 
470
        if other_branch is None:
 
471
            other_branch = local_branch.get_parent()
 
472
            
 
473
            if other_branch is None:
 
474
                raise errors.BzrCommandError("No peer location known or specified.")
 
475
        remote_branch = Branch.open_containing(other_branch)[0]
 
476
        set_ui_factory()
 
477
        local_branch.lock_read()
 
478
        try:
 
479
            remote_branch.lock_read()
 
480
            try:
 
481
                dialog = MissingWindow(local_branch, remote_branch)
 
482
                dialog.run()
 
483
            finally:
 
484
                remote_branch.unlock()
 
485
        finally:
 
486
            local_branch.unlock()
 
487
 
 
488
 
 
489
class cmd_ginit(GTKCommand):
 
490
    def run(self):
 
491
        self.open_display()
 
492
        from initialize import InitDialog
 
493
        dialog = InitDialog(os.path.abspath(os.path.curdir))
 
494
        dialog.run()
 
495
 
 
496
 
 
497
class cmd_gtags(GTKCommand):
 
498
    def run(self):
 
499
        br = branch.Branch.open_containing('.')[0]
 
500
        
 
501
        gtk = self.open_display()
 
502
        from tags import TagsWindow
 
503
        window = TagsWindow(br)
 
504
        window.show()
 
505
        gtk.main()
 
506
 
 
507
 
 
508
commands = [
 
509
    cmd_gannotate, 
 
510
    cmd_gbranch,
 
511
    cmd_gcheckout, 
 
512
    cmd_gcommit, 
 
513
    cmd_gconflicts, 
 
514
    cmd_gdiff,
 
515
    cmd_ginit,
 
516
    cmd_gmissing, 
 
517
    cmd_gpreferences, 
 
518
    cmd_gpush, 
 
519
    cmd_gsend,
 
520
    cmd_gstatus,
 
521
    cmd_gtags,
 
522
    cmd_visualise
 
523
    ]
 
524
 
 
525
for cmd in commands:
 
526
    register_command(cmd)
 
527
 
 
528
 
 
529
class cmd_commit_notify(GTKCommand):
 
530
    """Run the bzr commit notifier.
 
531
 
 
532
    This is a background program which will pop up a notification on the users
 
533
    screen when a commit occurs.
 
534
    """
 
535
 
 
536
    def run(self):
 
537
        from notify import NotifyPopupMenu
 
538
        gtk = self.open_display()
 
539
        menu = NotifyPopupMenu()
 
540
        icon = gtk.status_icon_new_from_file(icon_path("bzr-icon-64.png"))
 
541
        icon.connect('popup-menu', menu.display)
 
542
 
 
543
        import cgi
 
544
        import dbus
 
545
        import dbus.service
 
546
        import pynotify
 
547
        from bzrlib.bzrdir import BzrDir
 
548
        from bzrlib import errors
 
549
        from bzrlib.osutils import format_date
 
550
        from bzrlib.transport import get_transport
 
551
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
 
552
            import dbus.glib
 
553
        BROADCAST_INTERFACE = "org.bazaarvcs.plugins.dbus.Broadcast"
 
554
        bus = dbus.SessionBus()
 
555
 
 
556
        def catch_branch(revision_id, urls):
 
557
            # TODO: show all the urls, or perhaps choose the 'best'.
 
558
            url = urls[0]
 
559
            try:
 
560
                if isinstance(revision_id, unicode):
 
561
                    revision_id = revision_id.encode('utf8')
 
562
                transport = get_transport(url)
 
563
                a_dir = BzrDir.open_from_transport(transport)
 
564
                branch = a_dir.open_branch()
 
565
                revno = branch.revision_id_to_revno(revision_id)
 
566
                revision = branch.repository.get_revision(revision_id)
 
567
                summary = 'New revision %d in %s' % (revno, url)
 
568
                body  = 'Committer: %s\n' % revision.committer
 
569
                body += 'Date: %s\n' % format_date(revision.timestamp,
 
570
                    revision.timezone)
 
571
                body += '\n'
 
572
                body += revision.message
 
573
                body = cgi.escape(body)
 
574
                nw = pynotify.Notification(summary, body)
 
575
                def start_viz(notification=None, action=None, data=None):
 
576
                    """Start the viz program."""
 
577
                    pp = start_viz_window(branch, revision_id)
 
578
                    pp.show()
 
579
                def start_branch(notification=None, action=None, data=None):
 
580
                    """Start a Branch dialog"""
 
581
                    from bzrlib.plugins.gtk.branch import BranchDialog
 
582
                    bd = BranchDialog(remote_path=url)
 
583
                    bd.run()
 
584
                nw.add_action("inspect", "Inspect", start_viz, None)
 
585
                nw.add_action("branch", "Branch", start_branch, None)
 
586
                nw.set_timeout(5000)
 
587
                nw.show()
 
588
            except Exception, e:
 
589
                print e
 
590
                raise
 
591
        bus.add_signal_receiver(catch_branch,
 
592
                                dbus_interface=BROADCAST_INTERFACE,
 
593
                                signal_name="Revision")
 
594
        pynotify.init("bzr commit-notify")
 
595
        gtk.main()
 
596
 
 
597
register_command(cmd_commit_notify)
 
598
 
 
599
 
 
600
class cmd_gselftest(GTKCommand):
 
601
    """Version of selftest that displays a notification at the end"""
 
602
 
 
603
    takes_args = builtins.cmd_selftest.takes_args
 
604
    takes_options = builtins.cmd_selftest.takes_options
 
605
    _see_also = ['selftest']
 
606
 
 
607
    def run(self, *args, **kwargs):
 
608
        import cgi
 
609
        import sys
 
610
        default_encoding = sys.getdefaultencoding()
 
611
        # prevent gtk from blowing up later
 
612
        gtk = import_pygtk()
 
613
        # prevent gtk from messing with default encoding
 
614
        import pynotify
 
615
        if sys.getdefaultencoding() != default_encoding:
 
616
            reload(sys)
 
617
            sys.setdefaultencoding(default_encoding)
 
618
        result = builtins.cmd_selftest().run(*args, **kwargs)
 
619
        if result == 0:
 
620
            summary = 'Success'
 
621
            body = 'Selftest succeeded in "%s"' % os.getcwd()
 
622
        if result == 1:
 
623
            summary = 'Failure'
 
624
            body = 'Selftest failed in "%s"' % os.getcwd()
 
625
        pynotify.init("bzr gselftest")
 
626
        note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
 
627
        note.set_timeout(pynotify.EXPIRES_NEVER)
 
628
        note.show()
 
629
 
 
630
 
 
631
register_command(cmd_gselftest)
 
632
 
 
633
 
 
634
class cmd_test_gtk(GTKCommand):
 
635
    """Version of selftest that just runs the gtk test suite."""
 
636
 
 
637
    takes_options = ['verbose',
 
638
                     Option('one', short_name='1',
 
639
                            help='Stop when one test fails.'),
 
640
                     Option('benchmark', help='Run the benchmarks.'),
 
641
                     Option('lsprof-timed',
 
642
                     help='Generate lsprof output for benchmarked'
 
643
                          ' sections of code.'),
 
644
                     Option('list-only',
 
645
                     help='List the tests instead of running them.'),
 
646
                     Option('randomize', type=str, argname="SEED",
 
647
                     help='Randomize the order of tests using the given'
 
648
                          ' seed or "now" for the current time.'),
 
649
                    ]
 
650
    takes_args = ['testspecs*']
 
651
 
 
652
    def run(self, verbose=None, one=False, benchmark=None,
 
653
            lsprof_timed=None, list_only=False, randomize=None,
 
654
            testspecs_list=None):
 
655
        from bzrlib import __path__ as bzrlib_path
 
656
        from bzrlib.tests import selftest
 
657
 
 
658
        print '%10s: %s' % ('bzrlib', bzrlib_path[0])
 
659
        if benchmark:
 
660
            print 'No benchmarks yet'
 
661
            return 3
 
662
 
 
663
            test_suite_factory = bench_suite
 
664
            if verbose is None:
 
665
                verbose = True
 
666
            # TODO: should possibly lock the history file...
 
667
            benchfile = open(".perf_history", "at", buffering=1)
 
668
        else:
 
669
            test_suite_factory = test_suite
 
670
            if verbose is None:
 
671
                verbose = False
 
672
            benchfile = None
 
673
 
 
674
        if testspecs_list is not None:
 
675
            pattern = '|'.join(testspecs_list)
 
676
        else:
 
677
            pattern = ".*"
 
678
 
 
679
        try:
 
680
            result = selftest(verbose=verbose,
 
681
                              pattern=pattern,
 
682
                              stop_on_failure=one,
 
683
                              test_suite_factory=test_suite_factory,
 
684
                              lsprof_timed=lsprof_timed,
 
685
                              bench_history=benchfile,
 
686
                              list_only=list_only,
 
687
                              random_seed=randomize,
 
688
                             )
 
689
        finally:
 
690
            if benchfile is not None:
 
691
                benchfile.close()
 
692
 
 
693
register_command(cmd_test_gtk)
 
694
 
 
695
 
 
696
class cmd_ghandle_patch(GTKCommand):
 
697
    """Display a patch or merge directive, possibly merging.
 
698
 
 
699
    This is a helper, meant to be launched from other programs like browsers
 
700
    or email clients.  Since these programs often do not allow parameters to
 
701
    be provided, a "handle-patch" script is included.
 
702
    """
 
703
 
 
704
    takes_args = ['path']
 
705
 
 
706
    def run(self, path):
 
707
        try:
 
708
            from bzrlib.plugins.gtk.diff import (DiffWindow,
 
709
                                                 MergeDirectiveWindow)
 
710
            lines = open(path, 'rb').readlines()
 
711
            lines = [l.replace('\r\n', '\n') for l in lines]
 
712
            try:
 
713
                directive = merge_directive.MergeDirective.from_lines(lines)
 
714
            except errors.NotAMergeDirective:
 
715
                window = DiffWindow()
 
716
                window.set_diff_text(path, lines)
 
717
            else:
 
718
                window = MergeDirectiveWindow(directive, path)
 
719
                window.set_diff_text(path, directive.patch.splitlines(True))
 
720
            window.show()
 
721
            gtk = self.open_display()
 
722
            window.connect("destroy", gtk.main_quit)
 
723
        except Exception, e:
 
724
            from dialog import error_dialog
 
725
            error_dialog('Error', str(e))
 
726
            raise
 
727
        gtk.main()
 
728
 
 
729
 
 
730
register_command(cmd_ghandle_patch)
 
731
 
 
732
 
 
733
import gettext
 
734
gettext.install('olive-gtk')
 
735
 
 
736
# Let's create a specialized alias to protect '_' from being erased by other
 
737
# uses of '_' as an anonymous variable (think pdb for one).
 
738
_i18n = gettext.gettext
223
739
 
224
740
class NoDisplayError(BzrCommandError):
225
741
    """gtk could not find a proper display"""
226
742
 
227
743
    def __str__(self):
228
 
        return "No DISPLAY. gannotate is disabled."
 
744
        return "No DISPLAY. Unable to run GTK+ application."
 
745
 
 
746
 
 
747
def test_suite():
 
748
    from unittest import TestSuite
 
749
    import tests
 
750
    import sys
 
751
    default_encoding = sys.getdefaultencoding()
 
752
    try:
 
753
        result = TestSuite()
 
754
        try:
 
755
            import_pygtk()
 
756
        except errors.BzrCommandError:
 
757
            return result
 
758
        result.addTest(tests.test_suite())
 
759
    finally:
 
760
        if sys.getdefaultencoding() != default_encoding:
 
761
            reload(sys)
 
762
            sys.setdefaultencoding(default_encoding)
 
763
    return result