/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: 2008-03-28 19:26:53 UTC
  • mto: (450.1.13 trunk)
  • mto: This revision was merged to the branch mainline in revision 458.
  • Revision ID: jelmer@samba.org-20080328192653-trzptkwahx1tulz9
Add module for preferences code.

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. 
21
22
gcommit           GTK+ commit dialog.
22
23
gconflicts        GTK+ conflicts. 
23
24
gdiff             Show differences in working tree in a GTK+ Window. 
 
25
ghandle-patch     Display and optionally merge a merge directive or patch.
24
26
ginit             Initialise a new branch.
25
27
gmissing          GTK+ missing revisions dialog. 
26
28
gpreferences      GTK+ preferences dialog. 
35
37
 
36
38
import bzrlib
37
39
 
38
 
version_info = (0, 95, 0, 'dev', 1)
 
40
version_info = (0, 94, 0, 'dev', 0)
39
41
 
40
42
if version_info[3] == 'final':
41
43
    version_string = '%d.%d.%d' % version_info[:3]
103
105
    bzrlib.ui.ui_factory = GtkUIFactory()
104
106
 
105
107
 
106
 
def data_basedirs():
107
 
    return [os.path.dirname(__file__),
108
 
             "/usr/share/bzr-gtk", 
109
 
             "/usr/local/share/bzr-gtk"]
110
 
 
111
 
 
112
 
def data_path(*args):
113
 
    for basedir in data_basedirs():
114
 
        path = os.path.join(basedir, *args)
115
 
        if os.path.exists(path):
116
 
            return path
117
 
    return None
118
 
 
119
 
 
120
 
def icon_path(*args):
121
 
    return data_path(os.path.join('icons', *args))
122
 
 
123
 
 
124
 
def open_display():
125
 
    pygtk = import_pygtk()
126
 
    try:
127
 
        import gtk
128
 
    except RuntimeError, e:
129
 
        if str(e) == "could not open display":
130
 
            raise NoDisplayError
131
 
    set_ui_factory()
132
 
    return gtk
133
 
 
 
108
def data_path():
 
109
    return os.path.dirname(__file__)
 
110
 
134
111
 
135
112
class GTKCommand(Command):
136
113
    """Abstract class providing GTK specific run commands."""
137
114
 
 
115
    def open_display(self):
 
116
        pygtk = import_pygtk()
 
117
        try:
 
118
            import gtk
 
119
        except RuntimeError, e:
 
120
            if str(e) == "could not open display":
 
121
                raise NoDisplayError
 
122
        set_ui_factory()
 
123
        return gtk
 
124
 
138
125
    def run(self):
139
 
        open_display()
 
126
        self.open_display()
140
127
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
141
128
        dialog.run()
142
129
 
170
157
 
171
158
    def run(self, location="."):
172
159
        (br, path) = branch.Branch.open_containing(location)
173
 
        open_display()
 
160
        self.open_display()
174
161
        from push import PushDialog
175
162
        dialog = PushDialog(br.repository, br.last_revision(), br)
176
163
        dialog.run()
195
182
            if revision is not None:
196
183
                if len(revision) == 1:
197
184
                    tree1 = wt
198
 
                    revision_id = revision[0].as_revision_id(tree1.branch)
 
185
                    revision_id = revision[0].in_history(branch).rev_id
199
186
                    tree2 = branch.repository.revision_tree(revision_id)
200
187
                elif len(revision) == 2:
201
 
                    revision_id_0 = revision[0].as_revision_id(branch)
 
188
                    revision_id_0 = revision[0].in_history(branch).rev_id
202
189
                    tree2 = branch.repository.revision_tree(revision_id_0)
203
 
                    revision_id_1 = revision[1].as_revision_id(branch)
 
190
                    revision_id_1 = revision[1].in_history(branch).rev_id
204
191
                    tree1 = branch.repository.revision_tree(revision_id_1)
205
192
            else:
206
193
                tree1 = wt
228
215
            wt.unlock()
229
216
 
230
217
 
231
 
def start_viz_window(branch, revisions, limit=None):
 
218
def start_viz_window(branch, revision, limit=None):
232
219
    """Start viz on branch with revision revision.
233
220
    
234
221
    :return: The viz window object.
235
222
    """
236
223
    from viz import BranchWindow
237
 
    return BranchWindow(branch, revisions, limit)
 
224
    return BranchWindow(branch, revision, limit)
238
225
 
239
226
 
240
227
class cmd_visualise(Command):
250
237
        "revision",
251
238
        Option('limit', "Maximum number of revisions to display.",
252
239
               int, 'count')]
253
 
    takes_args = [ "locations*" ]
 
240
    takes_args = [ "location?" ]
254
241
    aliases = [ "visualize", "vis", "viz" ]
255
242
 
256
 
    def run(self, locations_list, revision=None, limit=None):
 
243
    def run(self, location=".", revision=None, limit=None):
257
244
        set_ui_factory()
258
 
        if locations_list is None:
259
 
            locations_list = ["."]
260
 
        revids = []
261
 
        for location in locations_list:
262
 
            (br, path) = branch.Branch.open_containing(location)
263
 
            if revision is None:
264
 
                revids.append(br.last_revision())
265
 
            else:
266
 
                revids.append(revision[0].as_revision_id(br))
 
245
        (br, path) = branch.Branch.open_containing(location)
 
246
        if revision is None:
 
247
            revid = br.last_revision()
 
248
            if revid is None:
 
249
                return
 
250
        else:
 
251
            (revno, revid) = revision[0].in_history(br)
 
252
 
267
253
        import gtk
268
 
        pp = start_viz_window(br, revids, limit)
 
254
        pp = start_viz_window(br, revid, limit)
269
255
        pp.connect("destroy", lambda w: gtk.main_quit())
270
256
        pp.show()
271
257
        gtk.main()
288
274
    aliases = ["gblame", "gpraise"]
289
275
    
290
276
    def run(self, filename, all=False, plain=False, line='1', revision=None):
291
 
        gtk = open_display()
 
277
        gtk = self.open_display()
292
278
 
293
279
        try:
294
280
            line = int(line)
313
299
        if revision is not None:
314
300
            if len(revision) != 1:
315
301
                raise BzrCommandError("Only 1 revion may be specified.")
316
 
            revision_id = revision[0].as_revision_id(br)
 
302
            revision_id = revision[0].in_history(br).rev_id
317
303
            tree = br.repository.revision_tree(revision_id)
318
304
        else:
319
305
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
320
306
 
321
 
        window = GAnnotateWindow(all, plain, branch=br)
 
307
        window = GAnnotateWindow(all, plain)
322
308
        window.connect("destroy", lambda w: gtk.main_quit())
323
309
        config = GAnnotateConfig(window)
324
310
        window.show()
347
333
 
348
334
    def run(self, filename=None):
349
335
        import os
350
 
        open_display()
 
336
        self.open_display()
351
337
        from commit import CommitDialog
352
338
        from bzrlib.errors import (BzrCommandError,
353
339
                                   NotBranchError,
360
346
            br = wt.branch
361
347
        except NoWorkingTree, e:
362
348
            from dialog import error_dialog
363
 
            error_dialog(_i18n('Directory does not have a working tree'),
364
 
                         _i18n('Operation aborted.'))
 
349
            error_dialog(_('Directory does not have a working tree'),
 
350
                         _('Operation aborted.'))
365
351
            return 1 # should this be retval=3?
366
352
 
367
353
        # It is a good habit to keep things locked for the duration, but it
384
370
    
385
371
    aliases = [ "gst" ]
386
372
    takes_args = ['PATH?']
387
 
    takes_options = ['revision']
 
373
    takes_options = []
388
374
 
389
 
    def run(self, path='.', revision=None):
 
375
    def run(self, path='.'):
390
376
        import os
391
 
        gtk = open_display()
 
377
        gtk = self.open_display()
392
378
        from status import StatusDialog
393
379
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
394
 
        
395
 
        if revision is not None:
396
 
            try:
397
 
                revision_id = revision[0].as_revision_id(wt.branch)
398
 
            except:
399
 
                from bzrlib.errors import BzrError
400
 
                raise BzrError('Revision %r doesn\'t exist' % revision[0].user_spec )
401
 
        else:
402
 
            revision_id = None
403
 
 
404
 
        status = StatusDialog(wt, wt_path, revision_id)
 
380
        status = StatusDialog(wt, wt_path)
405
381
        status.connect("destroy", gtk.main_quit)
406
382
        status.run()
407
383
 
412
388
    """
413
389
    def run(self):
414
390
        (br, path) = branch.Branch.open_containing(".")
415
 
        gtk = open_display()
 
391
        gtk = self.open_display()
416
392
        from bzrlib.plugins.gtk.mergedirective import SendMergeDirectiveDialog
417
393
        from StringIO import StringIO
418
394
        dialog = SendMergeDirectiveDialog(br)
434
410
    """
435
411
    def run(self):
436
412
        (wt, path) = workingtree.WorkingTree.open_containing('.')
437
 
        open_display()
 
413
        self.open_display()
438
414
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
439
415
        dialog = ConflictsDialog(wt)
440
416
        dialog.run()
445
421
 
446
422
    """
447
423
    def run(self):
448
 
        open_display()
 
424
        self.open_display()
449
425
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
450
426
        dialog = PreferencesWindow()
451
427
        dialog.run()
489
465
 
490
466
class cmd_ginit(GTKCommand):
491
467
    def run(self):
492
 
        open_display()
 
468
        self.open_display()
493
469
        from initialize import InitDialog
494
470
        dialog = InitDialog(os.path.abspath(os.path.curdir))
495
471
        dialog.run()
499
475
    def run(self):
500
476
        br = branch.Branch.open_containing('.')[0]
501
477
        
502
 
        gtk = open_display()
 
478
        gtk = self.open_display()
503
479
        from tags import TagsWindow
504
480
        window = TagsWindow(br)
505
481
        window.show()
527
503
    register_command(cmd)
528
504
 
529
505
 
 
506
class cmd_commit_notify(GTKCommand):
 
507
    """Run the bzr commit notifier.
 
508
 
 
509
    This is a background program which will pop up a notification on the users
 
510
    screen when a commit occurs.
 
511
    """
 
512
 
 
513
    def run(self):
 
514
        from notify import NotifyPopupMenu
 
515
        gtk = self.open_display()
 
516
        menu = NotifyPopupMenu()
 
517
        icon = gtk.status_icon_new_from_file(os.path.join(data_path(), "bzr-icon-64.png"))
 
518
        icon.connect('popup-menu', menu.display)
 
519
 
 
520
        import cgi
 
521
        import dbus
 
522
        import dbus.service
 
523
        import pynotify
 
524
        from bzrlib.bzrdir import BzrDir
 
525
        from bzrlib import errors
 
526
        from bzrlib.osutils import format_date
 
527
        from bzrlib.transport import get_transport
 
528
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
 
529
            import dbus.glib
 
530
        from bzrlib.plugins.dbus import activity
 
531
        bus = dbus.SessionBus()
 
532
        # get the object so we can subscribe to callbacks from it.
 
533
        broadcast_service = bus.get_object(
 
534
            activity.Broadcast.DBUS_NAME,
 
535
            activity.Broadcast.DBUS_PATH)
 
536
 
 
537
        def catch_branch(revision_id, urls):
 
538
            # TODO: show all the urls, or perhaps choose the 'best'.
 
539
            url = urls[0]
 
540
            try:
 
541
                if isinstance(revision_id, unicode):
 
542
                    revision_id = revision_id.encode('utf8')
 
543
                transport = get_transport(url)
 
544
                a_dir = BzrDir.open_from_transport(transport)
 
545
                branch = a_dir.open_branch()
 
546
                revno = branch.revision_id_to_revno(revision_id)
 
547
                revision = branch.repository.get_revision(revision_id)
 
548
                summary = 'New revision %d in %s' % (revno, url)
 
549
                body  = 'Committer: %s\n' % revision.committer
 
550
                body += 'Date: %s\n' % format_date(revision.timestamp,
 
551
                    revision.timezone)
 
552
                body += '\n'
 
553
                body += revision.message
 
554
                body = cgi.escape(body)
 
555
                nw = pynotify.Notification(summary, body)
 
556
                def start_viz(notification=None, action=None, data=None):
 
557
                    """Start the viz program."""
 
558
                    pp = start_viz_window(branch, revision_id)
 
559
                    pp.show()
 
560
                def start_branch(notification=None, action=None, data=None):
 
561
                    """Start a Branch dialog"""
 
562
                    from bzrlib.plugins.gtk.branch import BranchDialog
 
563
                    bd = BranchDialog(remote_path=url)
 
564
                    bd.run()
 
565
                nw.add_action("inspect", "Inspect", start_viz, None)
 
566
                nw.add_action("branch", "Branch", start_branch, None)
 
567
                nw.set_timeout(5000)
 
568
                nw.show()
 
569
            except Exception, e:
 
570
                print e
 
571
                raise
 
572
        broadcast_service.connect_to_signal("Revision", catch_branch,
 
573
            dbus_interface=activity.Broadcast.DBUS_INTERFACE)
 
574
        pynotify.init("bzr commit-notify")
 
575
        gtk.main()
 
576
 
 
577
register_command(cmd_commit_notify)
 
578
 
 
579
 
530
580
class cmd_gselftest(GTKCommand):
531
581
    """Version of selftest that displays a notification at the end"""
532
582
 
623
673
register_command(cmd_test_gtk)
624
674
 
625
675
 
 
676
class cmd_ghandle_patch(GTKCommand):
 
677
    """Display a patch or merge directive, possibly merging.
 
678
 
 
679
    This is a helper, meant to be launched from other programs like browsers
 
680
    or email clients.  Since these programs often do not allow parameters to
 
681
    be provided, a "handle-patch" script is included.
 
682
    """
 
683
 
 
684
    takes_args = ['path']
 
685
 
 
686
    def run(self, path):
 
687
        try:
 
688
            from bzrlib.plugins.gtk.diff import (DiffWindow,
 
689
                                                 MergeDirectiveWindow)
 
690
            lines = open(path, 'rb').readlines()
 
691
            lines = [l.replace('\r\n', '\n') for l in lines]
 
692
            try:
 
693
                directive = merge_directive.MergeDirective.from_lines(lines)
 
694
            except errors.NotAMergeDirective:
 
695
                window = DiffWindow()
 
696
                window.set_diff_text(path, lines)
 
697
            else:
 
698
                window = MergeDirectiveWindow(directive, path)
 
699
                window.set_diff_text(path, directive.patch.splitlines(True))
 
700
            window.show()
 
701
            gtk = self.open_display()
 
702
            window.connect("destroy", gtk.main_quit)
 
703
        except Exception, e:
 
704
            from dialog import error_dialog
 
705
            error_dialog('Error', str(e))
 
706
            raise
 
707
        gtk.main()
 
708
 
 
709
 
 
710
register_command(cmd_ghandle_patch)
 
711
 
626
712
 
627
713
import gettext
628
714
gettext.install('olive-gtk')
629
715
 
630
 
# Let's create a specialized alias to protect '_' from being erased by other
631
 
# uses of '_' as an anonymous variable (think pdb for one).
632
 
_i18n = gettext.gettext
633
716
 
634
717
class NoDisplayError(BzrCommandError):
635
718
    """gtk could not find a proper display"""