/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: Jelmer Vernooij
  • Date: 2007-07-15 18:12:57 UTC
  • Revision ID: jelmer@samba.org-20070715181257-g264qus2zyi3v39z
Add RevisionSelectionBox widget, use in TagDialog.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
#
1
3
# This program is free software; you can redistribute it and/or modify
2
4
# it under the terms of the GNU General Public License as published by
3
5
# the Free Software Foundation; either version 2 of the License, or
12
14
# along with this program; if not, write to the Free Software
13
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14
16
 
15
 
"""GTK+ frontends to Bazaar commands """
 
17
"""Graphical support for Bazaar using GTK.
 
18
 
 
19
This plugin includes:
 
20
commit-notify     Start the graphical notifier of commits.
 
21
gannotate         GTK+ annotate. 
 
22
gbranch           GTK+ branching. 
 
23
gcheckout         GTK+ checkout. 
 
24
gcommit           GTK+ commit dialog 
 
25
gconflicts        GTK+ push. 
 
26
gdiff             Show differences in working tree in a GTK+ Window. 
 
27
ginit             Initialise a new branch.
 
28
gmissing          GTK+ missing revisions dialog. 
 
29
gpreferences      GTK+ preferences dialog. 
 
30
gpush             GTK+ push. 
 
31
gstatus           GTK+ status dialog 
 
32
gtags             Manage branch tags.
 
33
visualise         Graphically visualise this branch. 
 
34
"""
16
35
 
17
36
import bzrlib
18
37
 
19
 
__version__ = '0.16.0'
 
38
__version__ = '0.18.0'
20
39
version_info = tuple(int(n) for n in __version__.split('.'))
21
40
 
22
41
 
30
49
    """
31
50
    desired_plus = (desired[0], desired[1]+1)
32
51
    bzrlib_version = bzrlib.version_info[:2]
33
 
    if bzrlib_version == desired:
 
52
    if bzrlib_version == desired or (bzrlib_version == desired_plus and
 
53
                                     bzrlib.version_info[3] == 'dev'):
34
54
        return
35
55
    try:
36
56
        from bzrlib.trace import warning
38
58
        # get the message out any way we can
39
59
        from warnings import warn as warning
40
60
    if bzrlib_version < desired:
 
61
        from bzrlib.errors import BzrError
41
62
        warning('Installed bzr version %s is too old to be used with bzr-gtk'
42
63
                ' %s.' % (bzrlib.__version__, __version__))
43
 
        # Not using BzrNewError, because it may not exist.
44
 
        raise Exception, ('Version mismatch', version_info)
 
64
        raise BzrError('Version mismatch: %r' % version_info)
45
65
    else:
46
66
        warning('bzr-gtk is not up to date with installed bzr version %s.'
47
67
                ' \nThere should be a newer version available, e.g. %i.%i.' 
48
68
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
49
 
        if bzrlib_version != desired_plus:
50
 
            raise Exception, 'Version mismatch'
51
69
 
52
70
 
53
71
check_bzrlib_version(version_info[:2])
87
105
    bzrlib.ui.ui_factory = GtkUIFactory()
88
106
 
89
107
 
90
 
class cmd_gbranch(Command):
 
108
class GTKCommand(Command):
 
109
    """Abstract class providing GTK specific run commands."""
 
110
 
 
111
    def open_display(self):
 
112
        pygtk = import_pygtk()
 
113
        try:
 
114
            import gtk
 
115
        except RuntimeError, e:
 
116
            if str(e) == "could not open display":
 
117
                raise NoDisplayError
 
118
        set_ui_factory()
 
119
        return gtk
 
120
 
 
121
    def run(self):
 
122
        self.open_display()
 
123
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
 
124
        dialog.run()
 
125
 
 
126
 
 
127
class cmd_gbranch(GTKCommand):
91
128
    """GTK+ branching.
92
129
    
93
130
    """
94
131
 
95
 
    def run(self):
96
 
        pygtk = import_pygtk()
97
 
        try:
98
 
            import gtk
99
 
        except RuntimeError, e:
100
 
            if str(e) == "could not open display":
101
 
                raise NoDisplayError
102
 
 
 
132
    def get_gtk_dialog(self, path):
103
133
        from bzrlib.plugins.gtk.branch import BranchDialog
104
 
 
105
 
        set_ui_factory()
106
 
        dialog = BranchDialog(os.path.abspath('.'))
107
 
        dialog.run()
108
 
 
109
 
class cmd_gcheckout(Command):
 
134
        return BranchDialog(path)
 
135
 
 
136
 
 
137
class cmd_gcheckout(GTKCommand):
110
138
    """ GTK+ checkout.
111
139
    
112
140
    """
113
141
    
114
 
    def run(self):
115
 
        pygtk = import_pygtk()
116
 
        try:
117
 
            import gtk
118
 
        except RuntimeError, e:
119
 
            if str(e) == "could not open display":
120
 
                raise NoDisplayError
121
 
 
 
142
    def get_gtk_dialog(self, path):
122
143
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
123
 
 
124
 
        set_ui_factory()
125
 
        dialog = CheckoutDialog(os.path.abspath('.'))
126
 
        dialog.run()
127
 
 
128
 
 
129
 
class cmd_gpush(Command):
 
144
        return CheckoutDialog(path)
 
145
 
 
146
 
 
147
 
 
148
class cmd_gpush(GTKCommand):
130
149
    """ GTK+ push.
131
150
    
132
151
    """
134
153
 
135
154
    def run(self, location="."):
136
155
        (br, path) = branch.Branch.open_containing(location)
137
 
 
138
 
        pygtk = import_pygtk()
139
 
        try:
140
 
            import gtk
141
 
        except RuntimeError, e:
142
 
            if str(e) == "could not open display":
143
 
                raise NoDisplayError
144
 
 
 
156
        self.open_display()
145
157
        from push import PushDialog
146
 
 
147
 
        set_ui_factory()
148
158
        dialog = PushDialog(br)
149
159
        dialog.run()
150
160
 
151
161
 
152
 
class cmd_gdiff(Command):
 
162
 
 
163
class cmd_gdiff(GTKCommand):
153
164
    """Show differences in working tree in a GTK+ Window.
154
165
    
155
166
    Otherwise, all changes for the tree are listed.
188
199
                try:
189
200
                    window.set_file(tree_filename)
190
201
                except NoSuchFile:
191
 
                    if (tree1.inventory.path2id(tree_filename) is None and 
192
 
                        tree2.inventory.path2id(tree_filename) is None):
 
202
                    if (tree1.path2id(tree_filename) is None and 
 
203
                        tree2.path2id(tree_filename) is None):
193
204
                        raise NotVersionedError(filename)
194
205
                    raise BzrCommandError('No changes found for file "%s"' % 
195
206
                                          filename)
200
211
            wt.unlock()
201
212
 
202
213
 
 
214
def start_viz_window(branch, revision, limit=None):
 
215
    """Start viz on branch with revision revision.
 
216
    
 
217
    :return: The viz window object.
 
218
    """
 
219
    from viz.branchwin import BranchWindow
 
220
    branch.lock_read()
 
221
    pp = BranchWindow()
 
222
    pp.set_branch(branch, revision, limit)
 
223
    # cleanup locks when the window is closed
 
224
    pp.connect("destroy", lambda w: branch.unlock())
 
225
    return pp
 
226
 
 
227
 
203
228
class cmd_visualise(Command):
204
229
    """Graphically visualise this branch.
205
230
 
211
236
    """
212
237
    takes_options = [
213
238
        "revision",
214
 
        Option('limit', "maximum number of revisions to display",
 
239
        Option('limit', "Maximum number of revisions to display.",
215
240
               int, 'count')]
216
241
    takes_args = [ "location?" ]
217
242
    aliases = [ "visualize", "vis", "viz" ]
220
245
        set_ui_factory()
221
246
        (br, path) = branch.Branch.open_containing(location)
222
247
        br.lock_read()
223
 
        br.repository.lock_read()
224
248
        try:
225
249
            if revision is None:
226
250
                revid = br.last_revision()
229
253
            else:
230
254
                (revno, revid) = revision[0].in_history(br)
231
255
 
232
 
            from viz.branchwin import BranchWindow
233
256
            import gtk
234
 
                
235
 
            pp = BranchWindow()
236
 
            pp.set_branch(br, revid, limit)
 
257
            pp = start_viz_window(br, revid, limit)
237
258
            pp.connect("destroy", lambda w: gtk.main_quit())
238
259
            pp.show()
239
260
            gtk.main()
240
261
        finally:
241
 
            br.repository.unlock()
242
262
            br.unlock()
243
263
 
244
264
 
245
 
class cmd_gannotate(Command):
 
265
class cmd_gannotate(GTKCommand):
246
266
    """GTK+ annotate.
247
267
    
248
268
    Browse changes to FILENAME line by line in a GTK+ window.
250
270
 
251
271
    takes_args = ["filename", "line?"]
252
272
    takes_options = [
253
 
        Option("all", help="show annotations on all lines"),
254
 
        Option("plain", help="don't highlight annotation lines"),
 
273
        Option("all", help="Show annotations on all lines."),
 
274
        Option("plain", help="Don't highlight annotation lines."),
255
275
        Option("line", type=int, argname="lineno",
256
 
               help="jump to specified line number"),
 
276
               help="Jump to specified line number."),
257
277
        "revision",
258
278
    ]
259
279
    aliases = ["gblame", "gpraise"]
260
280
    
261
281
    def run(self, filename, all=False, plain=False, line='1', revision=None):
262
 
        pygtk = import_pygtk()
263
 
 
264
 
        try:
265
 
            import gtk
266
 
        except RuntimeError, e:
267
 
            if str(e) == "could not open display":
268
 
                raise NoDisplayError
269
 
        set_ui_factory()
 
282
        gtk = self.open_display()
270
283
 
271
284
        try:
272
285
            line = int(line)
314
327
                wt.unlock()
315
328
 
316
329
 
317
 
class cmd_gcommit(Command):
 
330
 
 
331
class cmd_gcommit(GTKCommand):
318
332
    """GTK+ commit dialog
319
333
 
320
334
    Graphical user interface for committing revisions"""
325
339
 
326
340
    def run(self, filename=None):
327
341
        import os
328
 
        pygtk = import_pygtk()
329
 
 
330
 
        try:
331
 
            import gtk
332
 
        except RuntimeError, e:
333
 
            if str(e) == "could not open display":
334
 
                raise NoDisplayError
335
 
 
336
 
        set_ui_factory()
 
342
        self.open_display()
337
343
        from commit import CommitDialog
338
344
        from bzrlib.errors import (BzrCommandError,
339
345
                                   NotBranchError,
344
350
        try:
345
351
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
346
352
            br = wt.branch
347
 
        except NotBranchError, e:
348
 
            path = e.path
349
353
        except NoWorkingTree, e:
350
354
            path = e.base
351
 
            try:
352
 
                (br, path) = branch.Branch.open_containing(path)
353
 
            except NotBranchError, e:
354
 
                path = e.path
 
355
            (br, path) = branch.Branch.open_containing(path)
355
356
 
356
357
        commit = CommitDialog(wt, path, not br)
357
358
        commit.run()
358
359
 
359
360
 
360
 
class cmd_gstatus(Command):
 
361
 
 
362
class cmd_gstatus(GTKCommand):
361
363
    """GTK+ status dialog
362
364
 
363
365
    Graphical user interface for showing status 
369
371
 
370
372
    def run(self, path='.'):
371
373
        import os
372
 
        pygtk = import_pygtk()
373
 
 
374
 
        try:
375
 
            import gtk
376
 
        except RuntimeError, e:
377
 
            if str(e) == "could not open display":
378
 
                raise NoDisplayError
379
 
 
380
 
        set_ui_factory()
 
374
        gtk = self.open_display()
381
375
        from status import StatusDialog
382
376
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
383
377
        status = StatusDialog(wt, wt_path)
385
379
        status.run()
386
380
 
387
381
 
388
 
class cmd_gconflicts(Command):
 
382
 
 
383
class cmd_gconflicts(GTKCommand):
389
384
    """ GTK+ push.
390
385
    
391
386
    """
392
387
    def run(self):
393
388
        (wt, path) = workingtree.WorkingTree.open_containing('.')
394
 
        
395
 
        pygtk = import_pygtk()
396
 
        try:
397
 
            import gtk
398
 
        except RuntimeError, e:
399
 
            if str(e) == "could not open display":
400
 
                raise NoDisplayError
401
 
 
 
389
        self.open_display()
402
390
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
403
 
 
404
 
        set_ui_factory()
405
391
        dialog = ConflictsDialog(wt)
406
392
        dialog.run()
407
393
 
408
394
 
409
 
class cmd_gpreferences(Command):
 
395
 
 
396
class cmd_gpreferences(GTKCommand):
410
397
    """ GTK+ preferences dialog.
411
398
 
412
399
    """
413
400
    def run(self):
414
 
        pygtk = import_pygtk()
415
 
        try:
416
 
            import gtk
417
 
        except RuntimeError, e:
418
 
            if str(e) == "could not open display":
419
 
                raise NoDisplayError
420
 
 
 
401
        self.open_display()
421
402
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
422
 
 
423
 
        set_ui_factory()
424
403
        dialog = PreferencesWindow()
425
404
        dialog.run()
426
405
 
462
441
            local_branch.unlock()
463
442
 
464
443
 
 
444
class cmd_ginit(GTKCommand):
 
445
    def run(self):
 
446
        self.open_display()
 
447
        from initialize import InitDialog
 
448
        dialog = InitDialog(os.path.abspath(os.path.curdir))
 
449
        dialog.run()
 
450
 
 
451
 
 
452
class cmd_gtags(GTKCommand):
 
453
    def run(self):
 
454
        br = branch.Branch.open_containing('.')[0]
 
455
        
 
456
        gtk = self.open_display()
 
457
        from tags import TagsWindow
 
458
        window = TagsWindow(br)
 
459
        window.show()
 
460
        gtk.main()
 
461
 
 
462
 
465
463
commands = [
466
464
    cmd_gmissing, 
467
465
    cmd_gpreferences, 
473
471
    cmd_gdiff,
474
472
    cmd_gpush, 
475
473
    cmd_gcheckout, 
476
 
    cmd_gbranch 
 
474
    cmd_gbranch,
 
475
    cmd_ginit,
 
476
    cmd_gtags
477
477
    ]
478
478
 
479
479
for cmd in commands:
480
480
    register_command(cmd)
481
481
 
 
482
 
 
483
class cmd_commit_notify(GTKCommand):
 
484
    """Run the bzr commit notifier.
 
485
 
 
486
    This is a background program which will pop up a notification on the users
 
487
    screen when a commit occurs.
 
488
    """
 
489
 
 
490
    def run(self):
 
491
        from notify import NotifyPopupMenu
 
492
        gtk = self.open_display()
 
493
        menu = NotifyPopupMenu()
 
494
        icon = gtk.status_icon_new_from_file("bzr-icon-64.png")
 
495
        icon.connect('popup-menu', menu.display)
 
496
 
 
497
        import cgi
 
498
        import dbus
 
499
        import dbus.service
 
500
        import pynotify
 
501
        from bzrlib.bzrdir import BzrDir
 
502
        from bzrlib import errors
 
503
        from bzrlib.osutils import format_date
 
504
        from bzrlib.transport import get_transport
 
505
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
 
506
            import dbus.glib
 
507
        from bzrlib.plugins.dbus import activity
 
508
        bus = dbus.SessionBus()
 
509
        # get the object so we can subscribe to callbacks from it.
 
510
        broadcast_service = bus.get_object(
 
511
            activity.Broadcast.DBUS_NAME,
 
512
            activity.Broadcast.DBUS_PATH)
 
513
 
 
514
        def catch_branch(revision_id, urls):
 
515
            # TODO: show all the urls, or perhaps choose the 'best'.
 
516
            url = urls[0]
 
517
            try:
 
518
                if isinstance(revision_id, unicode):
 
519
                    revision_id = revision_id.encode('utf8')
 
520
                transport = get_transport(url)
 
521
                a_dir = BzrDir.open_from_transport(transport)
 
522
                branch = a_dir.open_branch()
 
523
                revno = branch.revision_id_to_revno(revision_id)
 
524
                revision = branch.repository.get_revision(revision_id)
 
525
                summary = 'New revision %d in %s' % (revno, url)
 
526
                body  = 'Committer: %s\n' % revision.committer
 
527
                body += 'Date: %s\n' % format_date(revision.timestamp,
 
528
                    revision.timezone)
 
529
                body += '\n'
 
530
                body += revision.message
 
531
                body = cgi.escape(body)
 
532
                nw = pynotify.Notification(summary, body)
 
533
                def start_viz(notification=None, action=None, data=None):
 
534
                    """Start the viz program."""
 
535
                    pp = start_viz_window(branch, revision_id)
 
536
                    pp.show()
 
537
                def start_branch(notification=None, action=None, data=None):
 
538
                    """Start a Branch dialog"""
 
539
                    from bzrlib.plugins.gtk.branch import BranchDialog
 
540
                    bd = BranchDialog(remote_path=url)
 
541
                    bd.run()
 
542
                nw.add_action("inspect", "Inspect", start_viz, None)
 
543
                nw.add_action("branch", "Branch", start_branch, None)
 
544
                nw.set_timeout(5000)
 
545
                nw.show()
 
546
            except Exception, e:
 
547
                print e
 
548
                raise
 
549
        broadcast_service.connect_to_signal("Revision", catch_branch,
 
550
            dbus_interface=activity.Broadcast.DBUS_INTERFACE)
 
551
        pynotify.init("bzr commit-notify")
 
552
        gtk.main()
 
553
 
 
554
register_command(cmd_commit_notify)
 
555
 
 
556
 
482
557
import gettext
483
558
gettext.install('olive-gtk')
484
559
 
 
560
 
485
561
class NoDisplayError(BzrCommandError):
486
562
    """gtk could not find a proper display"""
487
563
 
488
564
    def __str__(self):
489
565
        return "No DISPLAY. Unable to run GTK+ application."
490
566
 
 
567
 
491
568
def test_suite():
492
569
    from unittest import TestSuite
493
570
    import tests