/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: Gary van der Merwe
  • Date: 2007-08-10 10:45:06 UTC
  • mto: This revision was merged to the branch mainline in revision 256.
  • Revision ID: garyvdm@gmail.com-20070810104506-wo2mp9zfkh338axe
Make icon locations consistant between source and installed version. Let glade nkow where to find the icons with a project file.

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
ginit             Initialise a new branch.
 
26
gmissing          GTK+ missing revisions dialog. 
 
27
gpreferences      GTK+ preferences dialog. 
 
28
gpush             GTK+ push. 
 
29
gstatus           GTK+ status dialog 
 
30
gtags             Manage branch tags.
 
31
visualise         Graphically visualise this branch. 
 
32
"""
16
33
 
17
34
import bzrlib
18
35
 
19
 
__version__ = '0.16.0'
 
36
__version__ = '0.19.0'
20
37
version_info = tuple(int(n) for n in __version__.split('.'))
21
38
 
22
39
 
30
47
    """
31
48
    desired_plus = (desired[0], desired[1]+1)
32
49
    bzrlib_version = bzrlib.version_info[:2]
33
 
    if bzrlib_version == desired:
 
50
    if bzrlib_version == desired or (bzrlib_version == desired_plus and
 
51
                                     bzrlib.version_info[3] == 'dev'):
34
52
        return
35
53
    try:
36
54
        from bzrlib.trace import warning
38
56
        # get the message out any way we can
39
57
        from warnings import warn as warning
40
58
    if bzrlib_version < desired:
 
59
        from bzrlib.errors import BzrError
41
60
        warning('Installed bzr version %s is too old to be used with bzr-gtk'
42
61
                ' %s.' % (bzrlib.__version__, __version__))
43
 
        # Not using BzrNewError, because it may not exist.
44
 
        raise Exception, ('Version mismatch', version_info)
 
62
        raise BzrError('Version mismatch: %r' % version_info)
45
63
    else:
46
64
        warning('bzr-gtk is not up to date with installed bzr version %s.'
47
65
                ' \nThere should be a newer version available, e.g. %i.%i.' 
48
66
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
49
 
        if bzrlib_version != desired_plus:
50
 
            raise Exception, 'Version mismatch'
51
67
 
52
68
 
53
69
check_bzrlib_version(version_info[:2])
60
76
lazy_import(globals(), """
61
77
from bzrlib import (
62
78
    branch,
 
79
    builtins,
63
80
    errors,
64
81
    workingtree,
65
82
    )
67
84
 
68
85
from bzrlib.commands import Command, register_command, display_command
69
86
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
70
 
from bzrlib.commands import Command, register_command
71
87
from bzrlib.option import Option
72
 
from bzrlib.bzrdir import BzrDir
73
88
 
74
89
import os.path
75
90
 
83
98
 
84
99
 
85
100
def set_ui_factory():
86
 
    pygtk = import_pygtk()
 
101
    import_pygtk()
87
102
    from ui import GtkUIFactory
88
103
    import bzrlib.ui
89
104
    bzrlib.ui.ui_factory = GtkUIFactory()
90
105
 
91
106
 
92
 
class cmd_gbranch(Command):
 
107
def data_path():
 
108
    return os.path.dirname(__file__)
 
109
 
 
110
 
 
111
class GTKCommand(Command):
 
112
    """Abstract class providing GTK specific run commands."""
 
113
 
 
114
    def open_display(self):
 
115
        pygtk = import_pygtk()
 
116
        try:
 
117
            import gtk
 
118
        except RuntimeError, e:
 
119
            if str(e) == "could not open display":
 
120
                raise NoDisplayError
 
121
        set_ui_factory()
 
122
        return gtk
 
123
 
 
124
    def run(self):
 
125
        self.open_display()
 
126
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
 
127
        dialog.run()
 
128
 
 
129
 
 
130
class cmd_gbranch(GTKCommand):
93
131
    """GTK+ branching.
94
132
    
95
133
    """
96
134
 
97
 
    def run(self):
98
 
        pygtk = import_pygtk()
99
 
        try:
100
 
            import gtk
101
 
        except RuntimeError, e:
102
 
            if str(e) == "could not open display":
103
 
                raise NoDisplayError
104
 
 
 
135
    def get_gtk_dialog(self, path):
105
136
        from bzrlib.plugins.gtk.branch import BranchDialog
106
 
 
107
 
        set_ui_factory()
108
 
        dialog = BranchDialog(os.path.abspath('.'))
109
 
        dialog.run()
110
 
 
111
 
register_command(cmd_gbranch)
112
 
 
113
 
class cmd_gcheckout(Command):
 
137
        return BranchDialog(path)
 
138
 
 
139
 
 
140
class cmd_gcheckout(GTKCommand):
114
141
    """ GTK+ checkout.
115
142
    
116
143
    """
117
144
    
118
 
    def run(self):
119
 
        pygtk = import_pygtk()
120
 
        try:
121
 
            import gtk
122
 
        except RuntimeError, e:
123
 
            if str(e) == "could not open display":
124
 
                raise NoDisplayError
125
 
 
 
145
    def get_gtk_dialog(self, path):
126
146
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
127
 
 
128
 
        set_ui_factory()
129
 
        dialog = CheckoutDialog(os.path.abspath('.'))
130
 
        dialog.run()
131
 
 
132
 
register_command(cmd_gcheckout)
133
 
 
134
 
class cmd_gpush(Command):
 
147
        return CheckoutDialog(path)
 
148
 
 
149
 
 
150
 
 
151
class cmd_gpush(GTKCommand):
135
152
    """ GTK+ push.
136
153
    
137
154
    """
139
156
 
140
157
    def run(self, location="."):
141
158
        (br, path) = branch.Branch.open_containing(location)
142
 
 
143
 
        pygtk = import_pygtk()
144
 
        try:
145
 
            import gtk
146
 
        except RuntimeError, e:
147
 
            if str(e) == "could not open display":
148
 
                raise NoDisplayError
149
 
 
 
159
        self.open_display()
150
160
        from push import PushDialog
151
 
 
152
 
        set_ui_factory()
153
 
        dialog = PushDialog(br)
 
161
        dialog = PushDialog(br.repository, br.last_revision(), br)
154
162
        dialog.run()
155
163
 
156
 
register_command(cmd_gpush)
157
 
 
158
 
class cmd_gdiff(Command):
 
164
 
 
165
 
 
166
class cmd_gdiff(GTKCommand):
159
167
    """Show differences in working tree in a GTK+ Window.
160
168
    
161
169
    Otherwise, all changes for the tree are listed.
194
202
                try:
195
203
                    window.set_file(tree_filename)
196
204
                except NoSuchFile:
197
 
                    if (tree1.inventory.path2id(tree_filename) is None and 
198
 
                        tree2.inventory.path2id(tree_filename) is None):
 
205
                    if (tree1.path2id(tree_filename) is None and 
 
206
                        tree2.path2id(tree_filename) is None):
199
207
                        raise NotVersionedError(filename)
200
208
                    raise BzrCommandError('No changes found for file "%s"' % 
201
209
                                          filename)
205
213
        finally:
206
214
            wt.unlock()
207
215
 
208
 
register_command(cmd_gdiff)
 
216
 
 
217
def start_viz_window(branch, revision, limit=None):
 
218
    """Start viz on branch with revision revision.
 
219
    
 
220
    :return: The viz window object.
 
221
    """
 
222
    from viz.branchwin import BranchWindow
 
223
    branch.lock_read()
 
224
    pp = BranchWindow()
 
225
    pp.set_branch(branch, revision, limit)
 
226
    # cleanup locks when the window is closed
 
227
    pp.connect("destroy", lambda w: branch.unlock())
 
228
    return pp
 
229
 
209
230
 
210
231
class cmd_visualise(Command):
211
232
    """Graphically visualise this branch.
218
239
    """
219
240
    takes_options = [
220
241
        "revision",
221
 
        Option('limit', "maximum number of revisions to display",
 
242
        Option('limit', "Maximum number of revisions to display.",
222
243
               int, 'count')]
223
244
    takes_args = [ "location?" ]
224
245
    aliases = [ "visualize", "vis", "viz" ]
227
248
        set_ui_factory()
228
249
        (br, path) = branch.Branch.open_containing(location)
229
250
        br.lock_read()
230
 
        br.repository.lock_read()
231
251
        try:
232
252
            if revision is None:
233
253
                revid = br.last_revision()
236
256
            else:
237
257
                (revno, revid) = revision[0].in_history(br)
238
258
 
239
 
            from viz.branchwin import BranchWindow
240
259
            import gtk
241
 
                
242
 
            pp = BranchWindow()
243
 
            pp.set_branch(br, revid, limit)
 
260
            pp = start_viz_window(br, revid, limit)
244
261
            pp.connect("destroy", lambda w: gtk.main_quit())
245
262
            pp.show()
246
263
            gtk.main()
247
264
        finally:
248
 
            br.repository.unlock()
249
265
            br.unlock()
250
266
 
251
267
 
252
 
register_command(cmd_visualise)
253
 
 
254
 
class cmd_gannotate(Command):
 
268
class cmd_gannotate(GTKCommand):
255
269
    """GTK+ annotate.
256
270
    
257
271
    Browse changes to FILENAME line by line in a GTK+ window.
259
273
 
260
274
    takes_args = ["filename", "line?"]
261
275
    takes_options = [
262
 
        Option("all", help="show annotations on all lines"),
263
 
        Option("plain", help="don't highlight annotation lines"),
 
276
        Option("all", help="Show annotations on all lines."),
 
277
        Option("plain", help="Don't highlight annotation lines."),
264
278
        Option("line", type=int, argname="lineno",
265
 
               help="jump to specified line number"),
 
279
               help="Jump to specified line number."),
266
280
        "revision",
267
281
    ]
268
282
    aliases = ["gblame", "gpraise"]
269
283
    
270
284
    def run(self, filename, all=False, plain=False, line='1', revision=None):
271
 
        pygtk = import_pygtk()
272
 
 
273
 
        try:
274
 
            import gtk
275
 
        except RuntimeError, e:
276
 
            if str(e) == "could not open display":
277
 
                raise NoDisplayError
278
 
        set_ui_factory()
 
285
        gtk = self.open_display()
279
286
 
280
287
        try:
281
288
            line = int(line)
285
292
 
286
293
        from annotate.gannotate import GAnnotateWindow
287
294
        from annotate.config import GAnnotateConfig
 
295
        from bzrlib.bzrdir import BzrDir
288
296
 
289
297
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
290
298
        if wt is not None:
321
329
            if wt is not None:
322
330
                wt.unlock()
323
331
 
324
 
register_command(cmd_gannotate)
325
 
 
326
 
class cmd_gcommit(Command):
 
332
 
 
333
 
 
334
class cmd_gcommit(GTKCommand):
327
335
    """GTK+ commit dialog
328
336
 
329
337
    Graphical user interface for committing revisions"""
334
342
 
335
343
    def run(self, filename=None):
336
344
        import os
337
 
        pygtk = import_pygtk()
338
 
 
339
 
        try:
340
 
            import gtk
341
 
        except RuntimeError, e:
342
 
            if str(e) == "could not open display":
343
 
                raise NoDisplayError
344
 
 
345
 
        set_ui_factory()
 
345
        self.open_display()
346
346
        from commit import CommitDialog
347
 
        from bzrlib.commit import Commit
348
347
        from bzrlib.errors import (BzrCommandError,
349
348
                                   NotBranchError,
350
 
                                   NoWorkingTree,
351
 
                                   PointlessCommit,
352
 
                                   ConflictsInTree,
353
 
                                   StrictCommitFailed)
 
349
                                   NoWorkingTree)
354
350
 
355
351
        wt = None
356
352
        br = None
357
353
        try:
358
354
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
359
355
            br = wt.branch
360
 
        except NotBranchError, e:
361
 
            path = e.path
362
356
        except NoWorkingTree, e:
363
357
            path = e.base
364
 
            try:
365
 
                (br, path) = branch.Branch.open_containing(path)
366
 
            except NotBranchError, e:
367
 
                path = e.path
368
 
 
 
358
            (br, path) = branch.Branch.open_containing(path)
369
359
 
370
360
        commit = CommitDialog(wt, path, not br)
371
361
        commit.run()
372
362
 
373
 
register_command(cmd_gcommit)
374
 
 
375
 
class cmd_gstatus(Command):
 
363
 
 
364
 
 
365
class cmd_gstatus(GTKCommand):
376
366
    """GTK+ status dialog
377
367
 
378
368
    Graphical user interface for showing status 
384
374
 
385
375
    def run(self, path='.'):
386
376
        import os
387
 
        pygtk = import_pygtk()
388
 
 
389
 
        try:
390
 
            import gtk
391
 
        except RuntimeError, e:
392
 
            if str(e) == "could not open display":
393
 
                raise NoDisplayError
394
 
 
395
 
        set_ui_factory()
 
377
        gtk = self.open_display()
396
378
        from status import StatusDialog
397
379
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
398
380
        status = StatusDialog(wt, wt_path)
399
381
        status.connect("destroy", gtk.main_quit)
400
382
        status.run()
401
383
 
402
 
register_command(cmd_gstatus)
403
 
 
404
 
class cmd_gconflicts(Command):
405
 
    """ GTK+ push.
 
384
 
 
385
 
 
386
class cmd_gconflicts(GTKCommand):
 
387
    """ GTK+ conflicts.
406
388
    
 
389
    Select files from the list of conflicts and run an external utility to
 
390
    resolve them.
407
391
    """
408
392
    def run(self):
409
393
        (wt, path) = workingtree.WorkingTree.open_containing('.')
410
 
        
411
 
        pygtk = import_pygtk()
412
 
        try:
413
 
            import gtk
414
 
        except RuntimeError, e:
415
 
            if str(e) == "could not open display":
416
 
                raise NoDisplayError
417
 
 
 
394
        self.open_display()
418
395
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
419
 
 
420
 
        set_ui_factory()
421
396
        dialog = ConflictsDialog(wt)
422
397
        dialog.run()
423
398
 
424
 
register_command(cmd_gconflicts)
 
399
 
 
400
 
 
401
class cmd_gpreferences(GTKCommand):
 
402
    """ GTK+ preferences dialog.
 
403
 
 
404
    """
 
405
    def run(self):
 
406
        self.open_display()
 
407
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
 
408
        dialog = PreferencesWindow()
 
409
        dialog.run()
 
410
 
 
411
 
 
412
 
 
413
class cmd_gmissing(Command):
 
414
    """ GTK+ missing revisions dialog.
 
415
 
 
416
    """
 
417
    takes_args = ["other_branch?"]
 
418
    def run(self, other_branch=None):
 
419
        pygtk = import_pygtk()
 
420
        try:
 
421
            import gtk
 
422
        except RuntimeError, e:
 
423
            if str(e) == "could not open display":
 
424
                raise NoDisplayError
 
425
 
 
426
        from bzrlib.plugins.gtk.missing import MissingWindow
 
427
        from bzrlib.branch import Branch
 
428
 
 
429
        local_branch = Branch.open_containing(".")[0]
 
430
        if other_branch is None:
 
431
            other_branch = local_branch.get_parent()
 
432
            
 
433
            if other_branch is None:
 
434
                raise errors.BzrCommandError("No peer location known or specified.")
 
435
        remote_branch = Branch.open_containing(other_branch)[0]
 
436
        set_ui_factory()
 
437
        local_branch.lock_read()
 
438
        try:
 
439
            remote_branch.lock_read()
 
440
            try:
 
441
                dialog = MissingWindow(local_branch, remote_branch)
 
442
                dialog.run()
 
443
            finally:
 
444
                remote_branch.unlock()
 
445
        finally:
 
446
            local_branch.unlock()
 
447
 
 
448
 
 
449
class cmd_ginit(GTKCommand):
 
450
    def run(self):
 
451
        self.open_display()
 
452
        from initialize import InitDialog
 
453
        dialog = InitDialog(os.path.abspath(os.path.curdir))
 
454
        dialog.run()
 
455
 
 
456
 
 
457
class cmd_gtags(GTKCommand):
 
458
    def run(self):
 
459
        br = branch.Branch.open_containing('.')[0]
 
460
        
 
461
        gtk = self.open_display()
 
462
        from tags import TagsWindow
 
463
        window = TagsWindow(br)
 
464
        window.show()
 
465
        gtk.main()
 
466
 
 
467
 
 
468
commands = [
 
469
    cmd_gmissing, 
 
470
    cmd_gpreferences, 
 
471
    cmd_gconflicts, 
 
472
    cmd_gstatus,
 
473
    cmd_gcommit, 
 
474
    cmd_gannotate, 
 
475
    cmd_visualise, 
 
476
    cmd_gdiff,
 
477
    cmd_gpush, 
 
478
    cmd_gcheckout, 
 
479
    cmd_gbranch,
 
480
    cmd_ginit,
 
481
    cmd_gtags
 
482
    ]
 
483
 
 
484
for cmd in commands:
 
485
    register_command(cmd)
 
486
 
 
487
 
 
488
class cmd_commit_notify(GTKCommand):
 
489
    """Run the bzr commit notifier.
 
490
 
 
491
    This is a background program which will pop up a notification on the users
 
492
    screen when a commit occurs.
 
493
    """
 
494
 
 
495
    def run(self):
 
496
        from notify import NotifyPopupMenu
 
497
        gtk = self.open_display()
 
498
        menu = NotifyPopupMenu()
 
499
        icon = gtk.status_icon_new_from_file(os.path.join(data_path(), "bzr-icon-64.png"))
 
500
        icon.connect('popup-menu', menu.display)
 
501
 
 
502
        import cgi
 
503
        import dbus
 
504
        import dbus.service
 
505
        import pynotify
 
506
        from bzrlib.bzrdir import BzrDir
 
507
        from bzrlib import errors
 
508
        from bzrlib.osutils import format_date
 
509
        from bzrlib.transport import get_transport
 
510
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
 
511
            import dbus.glib
 
512
        from bzrlib.plugins.dbus import activity
 
513
        bus = dbus.SessionBus()
 
514
        # get the object so we can subscribe to callbacks from it.
 
515
        broadcast_service = bus.get_object(
 
516
            activity.Broadcast.DBUS_NAME,
 
517
            activity.Broadcast.DBUS_PATH)
 
518
 
 
519
        def catch_branch(revision_id, urls):
 
520
            # TODO: show all the urls, or perhaps choose the 'best'.
 
521
            url = urls[0]
 
522
            try:
 
523
                if isinstance(revision_id, unicode):
 
524
                    revision_id = revision_id.encode('utf8')
 
525
                transport = get_transport(url)
 
526
                a_dir = BzrDir.open_from_transport(transport)
 
527
                branch = a_dir.open_branch()
 
528
                revno = branch.revision_id_to_revno(revision_id)
 
529
                revision = branch.repository.get_revision(revision_id)
 
530
                summary = 'New revision %d in %s' % (revno, url)
 
531
                body  = 'Committer: %s\n' % revision.committer
 
532
                body += 'Date: %s\n' % format_date(revision.timestamp,
 
533
                    revision.timezone)
 
534
                body += '\n'
 
535
                body += revision.message
 
536
                body = cgi.escape(body)
 
537
                nw = pynotify.Notification(summary, body)
 
538
                def start_viz(notification=None, action=None, data=None):
 
539
                    """Start the viz program."""
 
540
                    pp = start_viz_window(branch, revision_id)
 
541
                    pp.show()
 
542
                def start_branch(notification=None, action=None, data=None):
 
543
                    """Start a Branch dialog"""
 
544
                    from bzrlib.plugins.gtk.branch import BranchDialog
 
545
                    bd = BranchDialog(remote_path=url)
 
546
                    bd.run()
 
547
                nw.add_action("inspect", "Inspect", start_viz, None)
 
548
                nw.add_action("branch", "Branch", start_branch, None)
 
549
                nw.set_timeout(5000)
 
550
                nw.show()
 
551
            except Exception, e:
 
552
                print e
 
553
                raise
 
554
        broadcast_service.connect_to_signal("Revision", catch_branch,
 
555
            dbus_interface=activity.Broadcast.DBUS_INTERFACE)
 
556
        pynotify.init("bzr commit-notify")
 
557
        gtk.main()
 
558
 
 
559
register_command(cmd_commit_notify)
 
560
 
 
561
 
 
562
class cmd_gselftest(GTKCommand):
 
563
    """Version of selftest that displays a notification at the end"""
 
564
 
 
565
    takes_args = builtins.cmd_selftest.takes_args
 
566
    takes_options = builtins.cmd_selftest.takes_options
 
567
    _see_also = ['selftest']
 
568
 
 
569
    def run(self, *args, **kwargs):
 
570
        import cgi
 
571
        import sys
 
572
        default_encoding = sys.getdefaultencoding()
 
573
        # prevent gtk from blowing up later
 
574
        gtk = import_pygtk()
 
575
        # prevent gtk from messing with default encoding
 
576
        import pynotify
 
577
        if sys.getdefaultencoding() != default_encoding:
 
578
            reload(sys)
 
579
            sys.setdefaultencoding(default_encoding)
 
580
        result = builtins.cmd_selftest().run(*args, **kwargs)
 
581
        if result == 0:
 
582
            summary = 'Success'
 
583
            body = 'Selftest succeeded in "%s"' % os.getcwd()
 
584
        if result == 1:
 
585
            summary = 'Failure'
 
586
            body = 'Selftest failed in "%s"' % os.getcwd()
 
587
        pynotify.init("bzr gselftest")
 
588
        note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
 
589
        note.set_timeout(pynotify.EXPIRES_NEVER)
 
590
        note.show()
 
591
 
 
592
 
 
593
register_command(cmd_gselftest)
 
594
 
425
595
 
426
596
import gettext
427
597
gettext.install('olive-gtk')
428
598
 
 
599
 
429
600
class NoDisplayError(BzrCommandError):
430
601
    """gtk could not find a proper display"""
431
602
 
432
603
    def __str__(self):
433
604
        return "No DISPLAY. Unable to run GTK+ application."
434
605
 
 
606
 
435
607
def test_suite():
436
608
    from unittest import TestSuite
437
609
    import tests
441
613
        result = TestSuite()
442
614
        result.addTest(tests.test_suite())
443
615
    finally:
444
 
        reload(sys)
445
 
        sys.setdefaultencoding(default_encoding)
 
616
        if sys.getdefaultencoding() != default_encoding:
 
617
            reload(sys)
 
618
            sys.setdefaultencoding(default_encoding)
446
619
    return result