/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: Daniel Schierbeck
  • Date: 2007-11-02 14:49:57 UTC
  • mto: (330.6.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 341.
  • Revision ID: daniel.schierbeck@gmail.com-20071102144957-8r4lp70ma5bpk8r8
Renamed logview 'revisionview'.

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.
18
19
gannotate         GTK+ annotate. 
19
20
gbranch           GTK+ branching. 
20
21
gcheckout         GTK+ checkout. 
22
23
gconflicts        GTK+ conflicts. 
23
24
gdiff             Show differences in working tree in a GTK+ Window. 
24
25
ginit             Initialise a new branch.
25
 
gmerge            GTK+ merge dialog
26
26
gmissing          GTK+ missing revisions dialog. 
27
27
gpreferences      GTK+ preferences dialog. 
28
28
gpush             GTK+ push.
32
32
visualise         Graphically visualise this branch. 
33
33
"""
34
34
 
35
 
import sys
36
 
 
37
35
import bzrlib
38
36
 
39
 
version_info = (0, 95, 0, 'dev', 1)
 
37
version_info = (0, 92, 0, 'dev', 0)
40
38
 
41
39
if version_info[3] == 'final':
42
40
    version_string = '%d.%d.%d' % version_info[:3]
44
42
    version_string = '%d.%d.%d%s%d' % version_info
45
43
__version__ = version_string
46
44
 
47
 
required_bzrlib = (1, 3)
48
 
 
49
45
def check_bzrlib_version(desired):
50
46
    """Check that bzrlib is compatible.
51
47
 
52
48
    If version is < bzr-gtk version, assume incompatible.
 
49
    If version == bzr-gtk version, assume completely compatible
 
50
    If version == bzr-gtk version + 1, assume compatible, with deprecations
 
51
    Otherwise, assume incompatible.
53
52
    """
 
53
    desired_plus = (desired[0], desired[1]+1)
54
54
    bzrlib_version = bzrlib.version_info[:2]
 
55
    if bzrlib_version == desired or (bzrlib_version == desired_plus and
 
56
                                     bzrlib.version_info[3] == 'dev'):
 
57
        return
55
58
    try:
56
59
        from bzrlib.trace import warning
57
60
    except ImportError:
62
65
        warning('Installed Bazaar version %s is too old to be used with bzr-gtk'
63
66
                ' %s.' % (bzrlib.__version__, __version__))
64
67
        raise BzrError('Version mismatch: %r, %r' % (version_info, bzrlib.version_info) )
 
68
    else:
 
69
        warning('bzr-gtk is not up to date with installed bzr version %s.'
 
70
                ' \nThere should be a newer version available, e.g. %i.%i.' 
 
71
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
65
72
 
66
73
 
67
74
if version_info[2] == "final":
68
 
    check_bzrlib_version(required_bzrlib)
 
75
    check_bzrlib_version(version_info[:2])
69
76
 
70
77
from bzrlib.trace import warning
71
78
if __name__ != 'bzrlib.plugins.gtk':
77
84
    branch,
78
85
    builtins,
79
86
    errors,
80
 
    merge_directive,
81
87
    workingtree,
82
88
    )
83
89
""")
104
110
    bzrlib.ui.ui_factory = GtkUIFactory()
105
111
 
106
112
 
107
 
def data_basedirs():
108
 
    return [os.path.dirname(__file__),
109
 
             "/usr/share/bzr-gtk", 
110
 
             "/usr/local/share/bzr-gtk"]
111
 
 
112
 
 
113
 
def data_path(*args):
114
 
    for basedir in data_basedirs():
115
 
        path = os.path.join(basedir, *args)
116
 
        if os.path.exists(path):
117
 
            return path
118
 
    return None
119
 
 
120
 
 
121
 
def icon_path(*args):
122
 
    return data_path(os.path.join('icons', *args))
123
 
 
124
 
 
125
 
def open_display():
126
 
    pygtk = import_pygtk()
127
 
    try:
128
 
        import gtk
129
 
    except RuntimeError, e:
130
 
        if str(e) == "could not open display":
131
 
            raise NoDisplayError
132
 
    set_ui_factory()
133
 
    return gtk
134
 
 
 
113
def data_path():
 
114
    return os.path.dirname(__file__)
 
115
 
135
116
 
136
117
class GTKCommand(Command):
137
118
    """Abstract class providing GTK specific run commands."""
138
119
 
 
120
    def open_display(self):
 
121
        pygtk = import_pygtk()
 
122
        try:
 
123
            import gtk
 
124
        except RuntimeError, e:
 
125
            if str(e) == "could not open display":
 
126
                raise NoDisplayError
 
127
        set_ui_factory()
 
128
        return gtk
 
129
 
139
130
    def run(self):
140
 
        open_display()
 
131
        self.open_display()
141
132
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
142
133
        dialog.run()
143
134
 
171
162
 
172
163
    def run(self, location="."):
173
164
        (br, path) = branch.Branch.open_containing(location)
174
 
        open_display()
 
165
        self.open_display()
175
166
        from push import PushDialog
176
167
        dialog = PushDialog(br.repository, br.last_revision(), br)
177
168
        dialog.run()
196
187
            if revision is not None:
197
188
                if len(revision) == 1:
198
189
                    tree1 = wt
199
 
                    revision_id = revision[0].as_revision_id(tree1.branch)
 
190
                    revision_id = revision[0].in_history(branch).rev_id
200
191
                    tree2 = branch.repository.revision_tree(revision_id)
201
192
                elif len(revision) == 2:
202
 
                    revision_id_0 = revision[0].as_revision_id(branch)
 
193
                    revision_id_0 = revision[0].in_history(branch).rev_id
203
194
                    tree2 = branch.repository.revision_tree(revision_id_0)
204
 
                    revision_id_1 = revision[1].as_revision_id(branch)
 
195
                    revision_id_1 = revision[1].in_history(branch).rev_id
205
196
                    tree1 = branch.repository.revision_tree(revision_id_1)
206
197
            else:
207
198
                tree1 = wt
229
220
            wt.unlock()
230
221
 
231
222
 
232
 
def start_viz_window(branch, revisions, limit=None):
 
223
def start_viz_window(branch, revision, limit=None):
233
224
    """Start viz on branch with revision revision.
234
225
    
235
226
    :return: The viz window object.
236
227
    """
237
 
    from viz import BranchWindow
238
 
    return BranchWindow(branch, revisions, limit)
 
228
    from viz.branchwin import BranchWindow
 
229
    return BranchWindow(branch, revision, limit)
239
230
 
240
231
 
241
232
class cmd_visualise(Command):
251
242
        "revision",
252
243
        Option('limit', "Maximum number of revisions to display.",
253
244
               int, 'count')]
254
 
    takes_args = [ "locations*" ]
 
245
    takes_args = [ "location?" ]
255
246
    aliases = [ "visualize", "vis", "viz" ]
256
247
 
257
 
    def run(self, locations_list, revision=None, limit=None):
 
248
    def run(self, location=".", revision=None, limit=None):
258
249
        set_ui_factory()
259
 
        if locations_list is None:
260
 
            locations_list = ["."]
261
 
        revids = []
262
 
        for location in locations_list:
263
 
            (br, path) = branch.Branch.open_containing(location)
 
250
        (br, path) = branch.Branch.open_containing(location)
 
251
        br.lock_read()
 
252
        try:
264
253
            if revision is None:
265
 
                revids.append(br.last_revision())
 
254
                revid = br.last_revision()
 
255
                if revid is None:
 
256
                    return
266
257
            else:
267
 
                revids.append(revision[0].as_revision_id(br))
268
 
        import gtk
269
 
        pp = start_viz_window(br, revids, limit)
270
 
        pp.connect("destroy", lambda w: gtk.main_quit())
271
 
        pp.show()
272
 
        gtk.main()
 
258
                (revno, revid) = revision[0].in_history(br)
 
259
 
 
260
            import gtk
 
261
            pp = start_viz_window(br, revid, limit)
 
262
            pp.connect("destroy", lambda w: gtk.main_quit())
 
263
            pp.show()
 
264
            gtk.main()
 
265
        finally:
 
266
            br.unlock()
273
267
 
274
268
 
275
269
class cmd_gannotate(GTKCommand):
289
283
    aliases = ["gblame", "gpraise"]
290
284
    
291
285
    def run(self, filename, all=False, plain=False, line='1', revision=None):
292
 
        gtk = open_display()
 
286
        gtk = self.open_display()
293
287
 
294
288
        try:
295
289
            line = int(line)
314
308
        if revision is not None:
315
309
            if len(revision) != 1:
316
310
                raise BzrCommandError("Only 1 revion may be specified.")
317
 
            revision_id = revision[0].as_revision_id(br)
 
311
            revision_id = revision[0].in_history(br).rev_id
318
312
            tree = br.repository.revision_tree(revision_id)
319
313
        else:
320
314
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
321
315
 
322
 
        window = GAnnotateWindow(all, plain, branch=br)
 
316
        window = GAnnotateWindow(all, plain)
323
317
        window.connect("destroy", lambda w: gtk.main_quit())
 
318
        window.set_title(path + " - gannotate")
324
319
        config = GAnnotateConfig(window)
325
320
        window.show()
326
321
        br.lock_read()
341
336
    """GTK+ commit dialog
342
337
 
343
338
    Graphical user interface for committing revisions"""
344
 
 
 
339
    
345
340
    aliases = [ "gci" ]
346
341
    takes_args = []
347
342
    takes_options = []
348
343
 
349
344
    def run(self, filename=None):
350
345
        import os
351
 
        open_display()
 
346
        self.open_display()
352
347
        from commit import CommitDialog
353
348
        from bzrlib.errors import (BzrCommandError,
354
349
                                   NotBranchError,
360
355
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
361
356
            br = wt.branch
362
357
        except NoWorkingTree, e:
363
 
            from dialog import error_dialog
364
 
            error_dialog(_i18n('Directory does not have a working tree'),
365
 
                         _i18n('Operation aborted.'))
366
 
            return 1 # should this be retval=3?
367
 
 
368
 
        # It is a good habit to keep things locked for the duration, but it
369
 
        # could cause difficulties if someone wants to do things in another
370
 
        # window... We could lock_read() until we actually go to commit
371
 
        # changes... Just a thought.
372
 
        wt.lock_write()
373
 
        try:
374
 
            dlg = CommitDialog(wt)
375
 
            return dlg.run()
376
 
        finally:
377
 
            wt.unlock()
 
358
            path = e.base
 
359
            (br, path) = branch.Branch.open_containing(path)
 
360
 
 
361
        commit = CommitDialog(wt, path, not br)
 
362
        commit.run()
 
363
 
378
364
 
379
365
 
380
366
class cmd_gstatus(GTKCommand):
385
371
    
386
372
    aliases = [ "gst" ]
387
373
    takes_args = ['PATH?']
388
 
    takes_options = ['revision']
 
374
    takes_options = []
389
375
 
390
 
    def run(self, path='.', revision=None):
 
376
    def run(self, path='.'):
391
377
        import os
392
 
        gtk = open_display()
 
378
        gtk = self.open_display()
393
379
        from status import StatusDialog
394
380
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
395
 
        
396
 
        if revision is not None:
397
 
            try:
398
 
                revision_id = revision[0].as_revision_id(wt.branch)
399
 
            except:
400
 
                from bzrlib.errors import BzrError
401
 
                raise BzrError('Revision %r doesn\'t exist' % revision[0].user_spec )
402
 
        else:
403
 
            revision_id = None
404
 
 
405
 
        status = StatusDialog(wt, wt_path, revision_id)
 
381
        status = StatusDialog(wt, wt_path)
406
382
        status.connect("destroy", gtk.main_quit)
407
383
        status.run()
408
384
 
413
389
    """
414
390
    def run(self):
415
391
        (br, path) = branch.Branch.open_containing(".")
416
 
        gtk = open_display()
 
392
        gtk = self.open_display()
417
393
        from bzrlib.plugins.gtk.mergedirective import SendMergeDirectiveDialog
418
394
        from StringIO import StringIO
419
395
        dialog = SendMergeDirectiveDialog(br)
435
411
    """
436
412
    def run(self):
437
413
        (wt, path) = workingtree.WorkingTree.open_containing('.')
438
 
        open_display()
 
414
        self.open_display()
439
415
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
440
416
        dialog = ConflictsDialog(wt)
441
417
        dialog.run()
446
422
 
447
423
    """
448
424
    def run(self):
449
 
        open_display()
 
425
        self.open_display()
450
426
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
451
427
        dialog = PreferencesWindow()
452
428
        dialog.run()
453
429
 
454
430
 
455
 
class cmd_gmerge(Command):
456
 
    """ GTK+ merge dialog
457
 
    
458
 
    """
459
 
    takes_args = ["merge_from_path?"]
460
 
    def run(self, merge_from_path=None):
461
 
        from bzrlib import workingtree
462
 
        from bzrlib.plugins.gtk.dialog import error_dialog
463
 
        from bzrlib.plugins.gtk.merge import MergeDialog
464
 
        
465
 
        (wt, path) = workingtree.WorkingTree.open_containing('.')
466
 
        old_tree = wt.branch.repository.revision_tree(wt.branch.last_revision())
467
 
        delta = wt.changes_from(old_tree)
468
 
        if len(delta.added) or len(delta.removed) or len(delta.renamed) or len(delta.modified):
469
 
            error_dialog(_i18n('There are local changes in the branch'),
470
 
                         _i18n('Please commit or revert the changes before merging.'))
471
 
        else:
472
 
            parent_branch_path = wt.branch.get_parent()
473
 
            merge = MergeDialog(wt, path, parent_branch_path)
474
 
            response = merge.run()
475
 
            merge.destroy()
476
 
 
477
 
 
478
431
class cmd_gmissing(Command):
479
432
    """ GTK+ missing revisions dialog.
480
433
 
513
466
 
514
467
class cmd_ginit(GTKCommand):
515
468
    def run(self):
516
 
        open_display()
 
469
        self.open_display()
517
470
        from initialize import InitDialog
518
471
        dialog = InitDialog(os.path.abspath(os.path.curdir))
519
472
        dialog.run()
523
476
    def run(self):
524
477
        br = branch.Branch.open_containing('.')[0]
525
478
        
526
 
        gtk = open_display()
 
479
        gtk = self.open_display()
527
480
        from tags import TagsWindow
528
481
        window = TagsWindow(br)
529
482
        window.show()
538
491
    cmd_gconflicts, 
539
492
    cmd_gdiff,
540
493
    cmd_ginit,
541
 
    cmd_gmerge,
542
494
    cmd_gmissing, 
543
495
    cmd_gpreferences, 
544
496
    cmd_gpush, 
552
504
    register_command(cmd)
553
505
 
554
506
 
 
507
class cmd_commit_notify(GTKCommand):
 
508
    """Run the bzr commit notifier.
 
509
 
 
510
    This is a background program which will pop up a notification on the users
 
511
    screen when a commit occurs.
 
512
    """
 
513
 
 
514
    def run(self):
 
515
        from notify import NotifyPopupMenu
 
516
        gtk = self.open_display()
 
517
        menu = NotifyPopupMenu()
 
518
        icon = gtk.status_icon_new_from_file(os.path.join(data_path(), "bzr-icon-64.png"))
 
519
        icon.connect('popup-menu', menu.display)
 
520
 
 
521
        import cgi
 
522
        import dbus
 
523
        import dbus.service
 
524
        import pynotify
 
525
        from bzrlib.bzrdir import BzrDir
 
526
        from bzrlib import errors
 
527
        from bzrlib.osutils import format_date
 
528
        from bzrlib.transport import get_transport
 
529
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
 
530
            import dbus.glib
 
531
        from bzrlib.plugins.dbus import activity
 
532
        bus = dbus.SessionBus()
 
533
        # get the object so we can subscribe to callbacks from it.
 
534
        broadcast_service = bus.get_object(
 
535
            activity.Broadcast.DBUS_NAME,
 
536
            activity.Broadcast.DBUS_PATH)
 
537
 
 
538
        def catch_branch(revision_id, urls):
 
539
            # TODO: show all the urls, or perhaps choose the 'best'.
 
540
            url = urls[0]
 
541
            try:
 
542
                if isinstance(revision_id, unicode):
 
543
                    revision_id = revision_id.encode('utf8')
 
544
                transport = get_transport(url)
 
545
                a_dir = BzrDir.open_from_transport(transport)
 
546
                branch = a_dir.open_branch()
 
547
                revno = branch.revision_id_to_revno(revision_id)
 
548
                revision = branch.repository.get_revision(revision_id)
 
549
                summary = 'New revision %d in %s' % (revno, url)
 
550
                body  = 'Committer: %s\n' % revision.committer
 
551
                body += 'Date: %s\n' % format_date(revision.timestamp,
 
552
                    revision.timezone)
 
553
                body += '\n'
 
554
                body += revision.message
 
555
                body = cgi.escape(body)
 
556
                nw = pynotify.Notification(summary, body)
 
557
                def start_viz(notification=None, action=None, data=None):
 
558
                    """Start the viz program."""
 
559
                    pp = start_viz_window(branch, revision_id)
 
560
                    pp.show()
 
561
                def start_branch(notification=None, action=None, data=None):
 
562
                    """Start a Branch dialog"""
 
563
                    from bzrlib.plugins.gtk.branch import BranchDialog
 
564
                    bd = BranchDialog(remote_path=url)
 
565
                    bd.run()
 
566
                nw.add_action("inspect", "Inspect", start_viz, None)
 
567
                nw.add_action("branch", "Branch", start_branch, None)
 
568
                nw.set_timeout(5000)
 
569
                nw.show()
 
570
            except Exception, e:
 
571
                print e
 
572
                raise
 
573
        broadcast_service.connect_to_signal("Revision", catch_branch,
 
574
            dbus_interface=activity.Broadcast.DBUS_INTERFACE)
 
575
        pynotify.init("bzr commit-notify")
 
576
        gtk.main()
 
577
 
 
578
register_command(cmd_commit_notify)
 
579
 
 
580
 
555
581
class cmd_gselftest(GTKCommand):
556
582
    """Version of selftest that displays a notification at the end"""
557
583
 
586
612
register_command(cmd_gselftest)
587
613
 
588
614
 
589
 
class cmd_test_gtk(GTKCommand):
590
 
    """Version of selftest that just runs the gtk test suite."""
591
 
 
592
 
    takes_options = ['verbose',
593
 
                     Option('one', short_name='1',
594
 
                            help='Stop when one test fails.'),
595
 
                     Option('benchmark', help='Run the benchmarks.'),
596
 
                     Option('lsprof-timed',
597
 
                     help='Generate lsprof output for benchmarked'
598
 
                          ' sections of code.'),
599
 
                     Option('list-only',
600
 
                     help='List the tests instead of running them.'),
601
 
                     Option('randomize', type=str, argname="SEED",
602
 
                     help='Randomize the order of tests using the given'
603
 
                          ' seed or "now" for the current time.'),
604
 
                    ]
605
 
    takes_args = ['testspecs*']
606
 
 
607
 
    def run(self, verbose=None, one=False, benchmark=None,
608
 
            lsprof_timed=None, list_only=False, randomize=None,
609
 
            testspecs_list=None):
610
 
        from bzrlib import __path__ as bzrlib_path
611
 
        from bzrlib.tests import selftest
612
 
 
613
 
        print '%10s: %s' % ('bzrlib', bzrlib_path[0])
614
 
        if benchmark:
615
 
            print 'No benchmarks yet'
616
 
            return 3
617
 
 
618
 
            test_suite_factory = bench_suite
619
 
            if verbose is None:
620
 
                verbose = True
621
 
            # TODO: should possibly lock the history file...
622
 
            benchfile = open(".perf_history", "at", buffering=1)
623
 
        else:
624
 
            test_suite_factory = test_suite
625
 
            if verbose is None:
626
 
                verbose = False
627
 
            benchfile = None
628
 
 
629
 
        if testspecs_list is not None:
630
 
            pattern = '|'.join(testspecs_list)
631
 
        else:
632
 
            pattern = ".*"
633
 
 
634
 
        try:
635
 
            result = selftest(verbose=verbose,
636
 
                              pattern=pattern,
637
 
                              stop_on_failure=one,
638
 
                              test_suite_factory=test_suite_factory,
639
 
                              lsprof_timed=lsprof_timed,
640
 
                              bench_history=benchfile,
641
 
                              list_only=list_only,
642
 
                              random_seed=randomize,
643
 
                             )
644
 
        finally:
645
 
            if benchfile is not None:
646
 
                benchfile.close()
647
 
 
648
 
register_command(cmd_test_gtk)
649
 
 
650
 
 
651
 
 
652
615
import gettext
653
616
gettext.install('olive-gtk')
654
617
 
655
 
# Let's create a specialized alias to protect '_' from being erased by other
656
 
# uses of '_' as an anonymous variable (think pdb for one).
657
 
_i18n = gettext.gettext
658
618
 
659
619
class NoDisplayError(BzrCommandError):
660
620
    """gtk could not find a proper display"""
670
630
    default_encoding = sys.getdefaultencoding()
671
631
    try:
672
632
        result = TestSuite()
673
 
        try:
674
 
            import_pygtk()
675
 
        except errors.BzrCommandError:
676
 
            return result
677
633
        result.addTest(tests.test_suite())
678
634
    finally:
679
635
        if sys.getdefaultencoding() != default_encoding: