/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

Merge lazy commands.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
visualise         Graphically visualise this branch. 
35
35
"""
36
36
 
37
 
import sys
38
 
 
39
37
import bzrlib
40
38
import bzrlib.api
 
39
from bzrlib import errors
 
40
from bzrlib.commands import plugin_cmds
 
41
 
 
42
import os.path
41
43
 
42
44
version_info = (0, 96, 0, 'dev', 1)
43
45
 
52
54
 
53
55
bzrlib.api.require_any_api(bzrlib, COMPATIBLE_BZR_VERSIONS)
54
56
 
55
 
from bzrlib.trace import warning
56
57
if __name__ != 'bzrlib.plugins.gtk':
 
58
    from bzrlib.trace import warning
57
59
    warning("Not running as bzrlib.plugins.gtk, things may break.")
58
60
 
59
 
from bzrlib.lazy_import import lazy_import
60
 
lazy_import(globals(), """
61
 
from bzrlib import (
62
 
    branch,
63
 
    builtins,
64
 
    errors,
65
 
    merge_directive,
66
 
    workingtree,
67
 
    )
68
 
""")
69
 
 
70
 
from bzrlib.commands import Command, register_command, display_command
71
 
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
72
 
from bzrlib.option import Option
73
 
 
74
 
import os.path
75
 
 
76
61
def import_pygtk():
77
62
    try:
78
63
        import pygtk
118
103
    return gtk
119
104
 
120
105
 
121
 
class GTKCommand(Command):
122
 
    """Abstract class providing GTK specific run commands."""
123
 
 
124
 
    def run(self):
125
 
        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
 
        open_display()
160
 
        from bzrlib.plugins.gtk.push import PushDialog
161
 
        dialog = PushDialog(br.repository, br.last_revision(), br)
162
 
        dialog.run()
163
 
 
164
 
 
165
 
class cmd_gloom(GTKCommand):
166
 
    """ GTK+ loom.
167
 
    
168
 
    """
169
 
    takes_args = [ "location?" ]
170
 
 
171
 
    def run(self, location="."):
172
 
        try:
173
 
            (tree, path) = workingtree.WorkingTree.open_containing(location)
174
 
            br = tree.branch
175
 
        except NoWorkingTree, e:
176
 
            (br, path) = branch.Branch.open_containing(location)
177
 
            tree = None
178
 
        open_display()
179
 
        from bzrlib.plugins.gtk.loom import LoomDialog
180
 
        dialog = LoomDialog(br, tree)
181
 
        dialog.run()
182
 
 
183
 
 
184
 
class cmd_gdiff(GTKCommand):
185
 
    """Show differences in working tree in a GTK+ Window.
186
 
    
187
 
    Otherwise, all changes for the tree are listed.
188
 
    """
189
 
    takes_args = ['filename?']
190
 
    takes_options = ['revision']
191
 
 
192
 
    @display_command
193
 
    def run(self, revision=None, filename=None):
194
 
        set_ui_factory()
195
 
        wt = workingtree.WorkingTree.open_containing(".")[0]
196
 
        wt.lock_read()
197
 
        try:
198
 
            branch = wt.branch
199
 
            if revision is not None:
200
 
                if len(revision) == 1:
201
 
                    tree1 = wt
202
 
                    revision_id = revision[0].as_revision_id(tree1.branch)
203
 
                    tree2 = branch.repository.revision_tree(revision_id)
204
 
                elif len(revision) == 2:
205
 
                    revision_id_0 = revision[0].as_revision_id(branch)
206
 
                    tree2 = branch.repository.revision_tree(revision_id_0)
207
 
                    revision_id_1 = revision[1].as_revision_id(branch)
208
 
                    tree1 = branch.repository.revision_tree(revision_id_1)
209
 
            else:
210
 
                tree1 = wt
211
 
                tree2 = tree1.basis_tree()
212
 
 
213
 
            from diff import DiffWindow
214
 
            import gtk
215
 
            window = DiffWindow()
216
 
            window.connect("destroy", gtk.main_quit)
217
 
            window.set_diff("Working Tree", tree1, tree2)
218
 
            if filename is not None:
219
 
                tree_filename = wt.relpath(filename)
220
 
                try:
221
 
                    window.set_file(tree_filename)
222
 
                except NoSuchFile:
223
 
                    if (tree1.path2id(tree_filename) is None and 
224
 
                        tree2.path2id(tree_filename) is None):
225
 
                        raise NotVersionedError(filename)
226
 
                    raise BzrCommandError('No changes found for file "%s"' % 
227
 
                                          filename)
228
 
            window.show()
229
 
 
230
 
            gtk.main()
231
 
        finally:
232
 
            wt.unlock()
233
 
 
234
 
 
235
 
def start_viz_window(branch, revisions, limit=None):
236
 
    """Start viz on branch with revision revision.
237
 
    
238
 
    :return: The viz window object.
239
 
    """
240
 
    from bzrlib.plugins.gtk.viz import BranchWindow
241
 
    return BranchWindow(branch, revisions, limit)
242
 
 
243
 
 
244
 
class cmd_visualise(Command):
245
 
    """Graphically visualise this branch.
246
 
 
247
 
    Opens a graphical window to allow you to see the history of the branch
248
 
    and relationships between revisions in a visual manner,
249
 
 
250
 
    The default starting point is latest revision on the branch, you can
251
 
    specify a starting point with -r revision.
252
 
    """
253
 
    takes_options = [
254
 
        "revision",
255
 
        Option('limit', "Maximum number of revisions to display.",
256
 
               int, 'count')]
257
 
    takes_args = [ "locations*" ]
258
 
    aliases = [ "visualize", "vis", "viz" ]
259
 
 
260
 
    def run(self, locations_list, revision=None, limit=None):
261
 
        set_ui_factory()
262
 
        if locations_list is None:
263
 
            locations_list = ["."]
264
 
        revids = []
265
 
        for location in locations_list:
266
 
            (br, path) = branch.Branch.open_containing(location)
267
 
            if revision is None:
268
 
                revids.append(br.last_revision())
269
 
            else:
270
 
                revids.append(revision[0].as_revision_id(br))
271
 
        import gtk
272
 
        pp = start_viz_window(br, revids, limit)
273
 
        pp.connect("destroy", lambda w: gtk.main_quit())
274
 
        pp.show()
275
 
        gtk.main()
276
 
 
277
 
 
278
 
class cmd_gannotate(GTKCommand):
279
 
    """GTK+ annotate.
280
 
    
281
 
    Browse changes to FILENAME line by line in a GTK+ window.
282
 
    """
283
 
 
284
 
    takes_args = ["filename", "line?"]
285
 
    takes_options = [
286
 
        Option("all", help="Show annotations on all lines."),
287
 
        Option("plain", help="Don't highlight annotation lines."),
288
 
        Option("line", type=int, argname="lineno",
289
 
               help="Jump to specified line number."),
290
 
        "revision",
291
 
    ]
292
 
    aliases = ["gblame", "gpraise"]
293
 
    
294
 
    def run(self, filename, all=False, plain=False, line='1', revision=None):
295
 
        gtk = open_display()
296
 
 
297
 
        try:
298
 
            line = int(line)
299
 
        except ValueError:
300
 
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
301
 
                                  line)
302
 
 
303
 
        from annotate.gannotate import GAnnotateWindow
304
 
        from annotate.config import GAnnotateConfig
305
 
        from bzrlib.bzrdir import BzrDir
306
 
 
307
 
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
308
 
        if wt is not None:
309
 
            tree = wt
310
 
        else:
311
 
            tree = br.basis_tree()
312
 
 
313
 
        file_id = tree.path2id(path)
314
 
 
315
 
        if file_id is None:
316
 
            raise NotVersionedError(filename)
317
 
        if revision is not None:
318
 
            if len(revision) != 1:
319
 
                raise BzrCommandError("Only 1 revion may be specified.")
320
 
            revision_id = revision[0].as_revision_id(br)
321
 
            tree = br.repository.revision_tree(revision_id)
322
 
        else:
323
 
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
324
 
 
325
 
        window = GAnnotateWindow(all, plain, branch=br)
326
 
        window.connect("destroy", lambda w: gtk.main_quit())
327
 
        config = GAnnotateConfig(window)
328
 
        window.show()
329
 
        br.lock_read()
330
 
        if wt is not None:
331
 
            wt.lock_read()
332
 
        try:
333
 
            window.annotate(tree, br, file_id)
334
 
            window.jump_to_line(line)
335
 
            gtk.main()
336
 
        finally:
337
 
            br.unlock()
338
 
            if wt is not None:
339
 
                wt.unlock()
340
 
 
341
 
 
342
 
 
343
 
class cmd_gcommit(GTKCommand):
344
 
    """GTK+ commit dialog
345
 
 
346
 
    Graphical user interface for committing revisions"""
347
 
 
348
 
    aliases = [ "gci" ]
349
 
    takes_args = []
350
 
    takes_options = []
351
 
 
352
 
    def run(self, filename=None):
353
 
        import os
354
 
        open_display()
355
 
        from commit import CommitDialog
356
 
        from bzrlib.errors import (BzrCommandError,
357
 
                                   NotBranchError,
358
 
                                   NoWorkingTree)
359
 
 
360
 
        wt = None
361
 
        br = None
362
 
        try:
363
 
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
364
 
            br = wt.branch
365
 
        except NoWorkingTree, e:
366
 
            from dialog import error_dialog
367
 
            error_dialog(_i18n('Directory does not have a working tree'),
368
 
                         _i18n('Operation aborted.'))
369
 
            return 1 # should this be retval=3?
370
 
 
371
 
        # It is a good habit to keep things locked for the duration, but it
372
 
        # could cause difficulties if someone wants to do things in another
373
 
        # window... We could lock_read() until we actually go to commit
374
 
        # changes... Just a thought.
375
 
        wt.lock_write()
376
 
        try:
377
 
            dlg = CommitDialog(wt)
378
 
            return dlg.run()
379
 
        finally:
380
 
            wt.unlock()
381
 
 
382
 
 
383
 
class cmd_gstatus(GTKCommand):
384
 
    """GTK+ status dialog
385
 
 
386
 
    Graphical user interface for showing status 
387
 
    information."""
388
 
 
389
 
    aliases = [ "gst" ]
390
 
    takes_args = ['PATH?']
391
 
    takes_options = ['revision']
392
 
 
393
 
    def run(self, path='.', revision=None):
394
 
        import os
395
 
        gtk = open_display()
396
 
        from bzrlib.plugins.gtk.status import StatusWindow
397
 
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
398
 
 
399
 
        if revision is not None:
400
 
            try:
401
 
                revision_id = revision[0].as_revision_id(wt.branch)
402
 
            except:
403
 
                from bzrlib.errors import BzrError
404
 
                raise BzrError('Revision %r doesn\'t exist'
405
 
                               % revision[0].user_spec )
406
 
        else:
407
 
            revision_id = None
408
 
 
409
 
        status = StatusWindow(wt, wt_path, revision_id)
410
 
        status.connect("destroy", gtk.main_quit)
411
 
        status.show()
412
 
        gtk.main()
413
 
 
414
 
 
415
 
class cmd_gsend(GTKCommand):
416
 
    """GTK+ send merge directive.
417
 
 
418
 
    """
419
 
    def run(self):
420
 
        (br, path) = branch.Branch.open_containing(".")
421
 
        gtk = open_display()
422
 
        from bzrlib.plugins.gtk.mergedirective import SendMergeDirectiveDialog
423
 
        from StringIO import StringIO
424
 
        dialog = SendMergeDirectiveDialog(br)
425
 
        if dialog.run() == gtk.RESPONSE_OK:
426
 
            outf = StringIO()
427
 
            outf.writelines(dialog.get_merge_directive().to_lines())
428
 
            mail_client = br.get_config().get_mail_client()
429
 
            mail_client.compose_merge_request(dialog.get_mail_to(), "[MERGE]", 
430
 
                outf.getvalue())
431
 
 
432
 
            
433
 
 
434
 
 
435
 
class cmd_gconflicts(GTKCommand):
436
 
    """GTK+ conflicts.
437
 
    
438
 
    Select files from the list of conflicts and run an external utility to
439
 
    resolve them.
440
 
    """
441
 
    def run(self):
442
 
        (wt, path) = workingtree.WorkingTree.open_containing('.')
443
 
        open_display()
444
 
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
445
 
        dialog = ConflictsDialog(wt)
446
 
        dialog.run()
447
 
 
448
 
 
449
 
class cmd_gpreferences(GTKCommand):
450
 
    """ GTK+ preferences dialog.
451
 
 
452
 
    """
453
 
    def run(self):
454
 
        open_display()
455
 
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
456
 
        dialog = PreferencesWindow()
457
 
        dialog.run()
458
 
 
459
 
 
460
 
class cmd_ginfo(Command):
461
 
    """ GTK+ info dialog
462
 
    
463
 
    """
464
 
    def run(self):
465
 
        from bzrlib import workingtree
466
 
        from bzrlib.plugins.gtk.olive.info import InfoDialog
467
 
        wt = workingtree.WorkingTree.open_containing('.')[0]
468
 
        info = InfoDialog(wt.branch)
469
 
        info.display()
470
 
        info.window.run()
471
 
 
472
 
 
473
 
class cmd_gmerge(Command):
474
 
    """ GTK+ merge dialog
475
 
    
476
 
    """
477
 
    takes_args = ["merge_from_path?"]
478
 
    def run(self, merge_from_path=None):
479
 
        from bzrlib import workingtree
480
 
        from bzrlib.plugins.gtk.dialog import error_dialog
481
 
        from bzrlib.plugins.gtk.merge import MergeDialog
482
 
        
483
 
        (wt, path) = workingtree.WorkingTree.open_containing('.')
484
 
        old_tree = wt.branch.repository.revision_tree(wt.branch.last_revision())
485
 
        delta = wt.changes_from(old_tree)
486
 
        if len(delta.added) or len(delta.removed) or len(delta.renamed) or len(delta.modified):
487
 
            error_dialog(_i18n('There are local changes in the branch'),
488
 
                         _i18n('Please commit or revert the changes before merging.'))
489
 
        else:
490
 
            parent_branch_path = wt.branch.get_parent()
491
 
            merge = MergeDialog(wt, path, parent_branch_path)
492
 
            response = merge.run()
493
 
            merge.destroy()
494
 
 
495
 
 
496
 
class cmd_gmissing(Command):
497
 
    """ GTK+ missing revisions dialog.
498
 
 
499
 
    """
500
 
    takes_args = ["other_branch?"]
501
 
    def run(self, other_branch=None):
502
 
        pygtk = import_pygtk()
503
 
        try:
504
 
            import gtk
505
 
        except RuntimeError, e:
506
 
            if str(e) == "could not open display":
507
 
                raise NoDisplayError
508
 
 
509
 
        from bzrlib.plugins.gtk.missing import MissingWindow
510
 
        from bzrlib.branch import Branch
511
 
 
512
 
        local_branch = Branch.open_containing(".")[0]
513
 
        if other_branch is None:
514
 
            other_branch = local_branch.get_parent()
515
 
            
516
 
            if other_branch is None:
517
 
                raise errors.BzrCommandError("No peer location known or specified.")
518
 
        remote_branch = Branch.open_containing(other_branch)[0]
519
 
        set_ui_factory()
520
 
        local_branch.lock_read()
521
 
        try:
522
 
            remote_branch.lock_read()
523
 
            try:
524
 
                dialog = MissingWindow(local_branch, remote_branch)
525
 
                dialog.run()
526
 
            finally:
527
 
                remote_branch.unlock()
528
 
        finally:
529
 
            local_branch.unlock()
530
 
 
531
 
 
532
 
class cmd_ginit(GTKCommand):
533
 
    def run(self):
534
 
        open_display()
535
 
        from initialize import InitDialog
536
 
        dialog = InitDialog(os.path.abspath(os.path.curdir))
537
 
        dialog.run()
538
 
 
539
 
 
540
 
class cmd_gtags(GTKCommand):
541
 
    def run(self):
542
 
        br = branch.Branch.open_containing('.')[0]
543
 
        
544
 
        gtk = open_display()
545
 
        from tags import TagsWindow
546
 
        window = TagsWindow(br)
547
 
        window.show()
548
 
        gtk.main()
549
 
 
550
 
 
551
 
commands = [
552
 
    cmd_gannotate, 
553
 
    cmd_gbranch,
554
 
    cmd_gcheckout, 
555
 
    cmd_gcommit, 
556
 
    cmd_gconflicts, 
557
 
    cmd_gdiff,
558
 
    cmd_ginit,
559
 
    cmd_ginfo,
560
 
    cmd_gmerge,
561
 
    cmd_gmissing, 
562
 
    cmd_gpreferences, 
563
 
    cmd_gpush, 
564
 
    cmd_gsend,
565
 
    cmd_gstatus,
566
 
    cmd_gtags,
567
 
    cmd_visualise
568
 
    ]
 
106
commands = {
 
107
    "gannotate": ["gblame", "gpraise"],
 
108
    "gbranch": [],
 
109
    "gcheckout": [], 
 
110
    "gcommit": ["gci"], 
 
111
    "gconflicts": [], 
 
112
    "gdiff": [],
 
113
    "ginit": [],
 
114
    "ginfo": [],
 
115
    "gmerge": [],
 
116
    "gmissing": [], 
 
117
    "gpreferences": [], 
 
118
    "gpush": [], 
 
119
    "gselftest": [],
 
120
    "gsend": [],
 
121
    "gstatus": ["gst"],
 
122
    "gtags": [],
 
123
    "visualise": ["visualize", "vis", "viz"],
 
124
    }
569
125
 
570
126
try:
571
127
    from bzrlib.plugins import loom
572
128
except ImportError:
573
129
    pass # Loom plugin doesn't appear to be present
574
130
else:
575
 
    commands.append(cmd_gloom)
576
 
 
577
 
for cmd in commands:
578
 
    register_command(cmd)
579
 
 
580
 
 
581
 
class cmd_gselftest(GTKCommand):
582
 
    """Version of selftest that displays a notification at the end"""
583
 
 
584
 
    takes_args = builtins.cmd_selftest.takes_args
585
 
    takes_options = builtins.cmd_selftest.takes_options
586
 
    _see_also = ['selftest']
587
 
 
588
 
    def run(self, *args, **kwargs):
589
 
        import cgi
590
 
        import sys
591
 
        default_encoding = sys.getdefaultencoding()
592
 
        # prevent gtk from blowing up later
593
 
        gtk = import_pygtk()
594
 
        # prevent gtk from messing with default encoding
595
 
        import pynotify
596
 
        if sys.getdefaultencoding() != default_encoding:
597
 
            reload(sys)
598
 
            sys.setdefaultencoding(default_encoding)
599
 
        result = builtins.cmd_selftest().run(*args, **kwargs)
600
 
        if result == 0:
601
 
            summary = 'Success'
602
 
            body = 'Selftest succeeded in "%s"' % os.getcwd()
603
 
        if result == 1:
604
 
            summary = 'Failure'
605
 
            body = 'Selftest failed in "%s"' % os.getcwd()
606
 
        pynotify.init("bzr gselftest")
607
 
        note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
608
 
        note.set_timeout(pynotify.EXPIRES_NEVER)
609
 
        note.show()
610
 
 
611
 
 
612
 
register_command(cmd_gselftest)
 
131
    commands["gloom"] = []
 
132
 
 
133
for cmd, aliases in commands.iteritems():
 
134
    plugin_cmds.register_lazy("cmd_%s" % cmd, aliases, "bzrlib.plugins.gtk.commands")
613
135
 
614
136
 
615
137
import gettext
619
141
# uses of '_' as an anonymous variable (think pdb for one).
620
142
_i18n = gettext.gettext
621
143
 
622
 
class NoDisplayError(BzrCommandError):
 
144
class NoDisplayError(errors.BzrCommandError):
623
145
    """gtk could not find a proper display"""
624
146
 
625
147
    def __str__(self):