/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: Szilveszter Farkas (Phanatic)
  • Date: 2007-02-03 17:19:29 UTC
  • mto: (157.1.2 trunk) (170.1.3 trunk)
  • mto: This revision was merged to the branch mainline in revision 160.
  • Revision ID: szilveszter.farkas@gmail.com-20070203171929-6egi16ulzmkg9g1g
Implemented Conflicts dialog. Added gconflicts command.

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
 
"""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
 
gsend             GTK+ send merge directive.
30
 
gstatus           GTK+ status dialog.
31
 
gtags             Manage branch tags.
32
 
visualise         Graphically visualise this branch. 
33
 
"""
34
 
 
35
 
import sys
 
15
"""GTK+ frontends to Bazaar commands """
36
16
 
37
17
import bzrlib
38
18
 
39
 
version_info = (0, 95, 0, 'dev', 1)
40
 
 
41
 
if version_info[3] == 'final':
42
 
    version_string = '%d.%d.%d' % version_info[:3]
43
 
else:
44
 
    version_string = '%d.%d.%d%s%d' % version_info
45
 
__version__ = version_string
46
 
 
47
 
required_bzrlib = (1, 3)
 
19
__version__ = '0.15.0'
 
20
version_info = tuple(int(n) for n in __version__.split('.'))
 
21
 
48
22
 
49
23
def check_bzrlib_version(desired):
50
24
    """Check that bzrlib is compatible.
51
25
 
52
26
    If version is < bzr-gtk version, assume incompatible.
 
27
    If version == bzr-gtk version, assume completely compatible
 
28
    If version == bzr-gtk version + 1, assume compatible, with deprecations
 
29
    Otherwise, assume incompatible.
53
30
    """
 
31
    desired_plus = (desired[0], desired[1]+1)
54
32
    bzrlib_version = bzrlib.version_info[:2]
 
33
    if bzrlib_version == desired:
 
34
        return
55
35
    try:
56
36
        from bzrlib.trace import warning
57
37
    except ImportError:
58
38
        # get the message out any way we can
59
39
        from warnings import warn as warning
60
40
    if bzrlib_version < desired:
61
 
        from bzrlib.errors import BzrError
62
 
        warning('Installed Bazaar version %s is too old to be used with bzr-gtk'
 
41
        warning('Installed bzr version %s is too old to be used with bzr-gtk'
63
42
                ' %s.' % (bzrlib.__version__, __version__))
64
 
        raise BzrError('Version mismatch: %r, %r' % (version_info, bzrlib.version_info) )
65
 
 
66
 
 
67
 
if version_info[2] == "final":
68
 
    check_bzrlib_version(required_bzrlib)
 
43
        # Not using BzrNewError, because it may not exist.
 
44
        raise Exception, ('Version mismatch', version_info)
 
45
    else:
 
46
        warning('bzr-gtk is not up to date with installed bzr version %s.'
 
47
                ' \nThere should be a newer version available, e.g. %i.%i.' 
 
48
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
 
49
        if bzrlib_version != desired_plus:
 
50
            raise Exception, 'Version mismatch'
 
51
 
 
52
 
 
53
check_bzrlib_version(version_info[:2])
69
54
 
70
55
from bzrlib.trace import warning
71
56
if __name__ != 'bzrlib.plugins.gtk':
72
57
    warning("Not running as bzrlib.plugins.gtk, things may break.")
73
58
 
74
 
from bzrlib.lazy_import import lazy_import
75
 
lazy_import(globals(), """
76
 
from bzrlib import (
77
 
    branch,
78
 
    builtins,
79
 
    errors,
80
 
    merge_directive,
81
 
    workingtree,
82
 
    )
83
 
""")
84
 
 
 
59
from bzrlib import errors
85
60
from bzrlib.commands import Command, register_command, display_command
86
61
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
 
62
from bzrlib.commands import Command, register_command
87
63
from bzrlib.option import Option
 
64
from bzrlib.branch import Branch
 
65
from bzrlib.workingtree import WorkingTree
 
66
from bzrlib.bzrdir import BzrDir
88
67
 
89
68
import os.path
90
69
 
98
77
 
99
78
 
100
79
def set_ui_factory():
101
 
    import_pygtk()
 
80
    pygtk = import_pygtk()
102
81
    from ui import GtkUIFactory
103
82
    import bzrlib.ui
104
83
    bzrlib.ui.ui_factory = GtkUIFactory()
105
84
 
106
85
 
107
 
def data_path():
108
 
    return os.path.dirname(__file__)
109
 
 
110
 
 
111
 
def icon_path(*args):
112
 
    basedirs = [os.path.join(data_path()),
113
 
             "/usr/share/bzr-gtk", 
114
 
             "/usr/local/share/bzr-gtk"]
115
 
    for basedir in basedirs:
116
 
        path = os.path.join(basedir, 'icons', *args)
117
 
        if os.path.exists(path):
118
 
            return path
119
 
    return None
120
 
 
121
 
 
122
 
def open_display():
123
 
    pygtk = import_pygtk()
124
 
    try:
125
 
        import gtk
126
 
    except RuntimeError, e:
127
 
        if str(e) == "could not open display":
128
 
            raise NoDisplayError
129
 
    set_ui_factory()
130
 
    return gtk
131
 
 
132
 
 
133
 
class GTKCommand(Command):
134
 
    """Abstract class providing GTK specific run commands."""
135
 
 
136
 
    def run(self):
137
 
        open_display()
138
 
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
139
 
        dialog.run()
140
 
 
141
 
 
142
 
class cmd_gbranch(GTKCommand):
 
86
class cmd_gbranch(Command):
143
87
    """GTK+ branching.
144
88
    
145
89
    """
146
90
 
147
 
    def get_gtk_dialog(self, path):
 
91
    def run(self):
 
92
        pygtk = import_pygtk()
 
93
        try:
 
94
            import gtk
 
95
        except RuntimeError, e:
 
96
            if str(e) == "could not open display":
 
97
                raise NoDisplayError
 
98
 
148
99
        from bzrlib.plugins.gtk.branch import BranchDialog
149
 
        return BranchDialog(path)
150
 
 
151
 
 
152
 
class cmd_gcheckout(GTKCommand):
 
100
 
 
101
        set_ui_factory()
 
102
        dialog = BranchDialog(os.path.abspath('.'))
 
103
        dialog.run()
 
104
 
 
105
register_command(cmd_gbranch)
 
106
 
 
107
class cmd_gcheckout(Command):
153
108
    """ GTK+ checkout.
154
109
    
155
110
    """
156
111
    
157
 
    def get_gtk_dialog(self, path):
 
112
    def run(self):
 
113
        pygtk = import_pygtk()
 
114
        try:
 
115
            import gtk
 
116
        except RuntimeError, e:
 
117
            if str(e) == "could not open display":
 
118
                raise NoDisplayError
 
119
 
158
120
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
159
 
        return CheckoutDialog(path)
160
 
 
161
 
 
162
 
 
163
 
class cmd_gpush(GTKCommand):
 
121
 
 
122
        set_ui_factory()
 
123
        dialog = CheckoutDialog(os.path.abspath('.'))
 
124
        dialog.run()
 
125
 
 
126
register_command(cmd_gcheckout)
 
127
 
 
128
class cmd_gpush(Command):
164
129
    """ GTK+ push.
165
130
    
166
131
    """
167
132
    takes_args = [ "location?" ]
168
 
 
 
133
    
169
134
    def run(self, location="."):
170
 
        (br, path) = branch.Branch.open_containing(location)
171
 
        open_display()
 
135
        (branch, path) = Branch.open_containing(location)
 
136
        
 
137
        pygtk = import_pygtk()
 
138
        try:
 
139
            import gtk
 
140
        except RuntimeError, e:
 
141
            if str(e) == "could not open display":
 
142
                raise NoDisplayError
 
143
 
172
144
        from push import PushDialog
173
 
        dialog = PushDialog(br.repository, br.last_revision(), br)
 
145
 
 
146
        set_ui_factory()
 
147
        dialog = PushDialog(branch)
174
148
        dialog.run()
175
149
 
176
 
 
177
 
 
178
 
class cmd_gdiff(GTKCommand):
 
150
register_command(cmd_gpush)
 
151
 
 
152
class cmd_gdiff(Command):
179
153
    """Show differences in working tree in a GTK+ Window.
180
154
    
181
155
    Otherwise, all changes for the tree are listed.
186
160
    @display_command
187
161
    def run(self, revision=None, filename=None):
188
162
        set_ui_factory()
189
 
        wt = workingtree.WorkingTree.open_containing(".")[0]
190
 
        wt.lock_read()
191
 
        try:
192
 
            branch = wt.branch
193
 
            if revision is not None:
194
 
                if len(revision) == 1:
195
 
                    tree1 = wt
196
 
                    revision_id = revision[0].as_revision_id(tree1.branch)
197
 
                    tree2 = branch.repository.revision_tree(revision_id)
198
 
                elif len(revision) == 2:
199
 
                    revision_id_0 = revision[0].as_revision_id(branch)
200
 
                    tree2 = branch.repository.revision_tree(revision_id_0)
201
 
                    revision_id_1 = revision[1].as_revision_id(branch)
202
 
                    tree1 = branch.repository.revision_tree(revision_id_1)
203
 
            else:
 
163
        wt = WorkingTree.open_containing(".")[0]
 
164
        branch = wt.branch
 
165
        if revision is not None:
 
166
            if len(revision) == 1:
204
167
                tree1 = wt
205
 
                tree2 = tree1.basis_tree()
206
 
 
207
 
            from diff import DiffWindow
208
 
            import gtk
209
 
            window = DiffWindow()
210
 
            window.connect("destroy", gtk.main_quit)
211
 
            window.set_diff("Working Tree", tree1, tree2)
212
 
            if filename is not None:
213
 
                tree_filename = wt.relpath(filename)
214
 
                try:
215
 
                    window.set_file(tree_filename)
216
 
                except NoSuchFile:
217
 
                    if (tree1.path2id(tree_filename) is None and 
218
 
                        tree2.path2id(tree_filename) is None):
219
 
                        raise NotVersionedError(filename)
220
 
                    raise BzrCommandError('No changes found for file "%s"' % 
221
 
                                          filename)
222
 
            window.show()
223
 
 
224
 
            gtk.main()
225
 
        finally:
226
 
            wt.unlock()
227
 
 
228
 
 
229
 
def start_viz_window(branch, revisions, limit=None):
230
 
    """Start viz on branch with revision revision.
231
 
    
232
 
    :return: The viz window object.
233
 
    """
234
 
    from viz import BranchWindow
235
 
    return BranchWindow(branch, revisions, limit)
236
 
 
 
168
                revision_id = revision[0].in_history(branch).rev_id
 
169
                tree2 = branch.repository.revision_tree(revision_id)
 
170
            elif len(revision) == 2:
 
171
                revision_id_0 = revision[0].in_history(branch).rev_id
 
172
                tree2 = branch.repository.revision_tree(revision_id_0)
 
173
                revision_id_1 = revision[1].in_history(branch).rev_id
 
174
                tree1 = branch.repository.revision_tree(revision_id_1)
 
175
        else:
 
176
            tree1 = wt
 
177
            tree2 = tree1.basis_tree()
 
178
 
 
179
        from diff import DiffWindow
 
180
        import gtk
 
181
        window = DiffWindow()
 
182
        window.connect("destroy", gtk.main_quit)
 
183
        window.set_diff("Working Tree", tree1, tree2)
 
184
        if filename is not None:
 
185
            tree_filename = wt.relpath(filename)
 
186
            try:
 
187
                window.set_file(tree_filename)
 
188
            except NoSuchFile:
 
189
                if (tree1.inventory.path2id(tree_filename) is None and 
 
190
                    tree2.inventory.path2id(tree_filename) is None):
 
191
                    raise NotVersionedError(filename)
 
192
                raise BzrCommandError('No changes found for file "%s"' % 
 
193
                                      filename)
 
194
        window.show()
 
195
 
 
196
        gtk.main()
 
197
 
 
198
register_command(cmd_gdiff)
237
199
 
238
200
class cmd_visualise(Command):
239
201
    """Graphically visualise this branch.
246
208
    """
247
209
    takes_options = [
248
210
        "revision",
249
 
        Option('limit', "Maximum number of revisions to display.",
 
211
        Option('limit', "maximum number of revisions to display",
250
212
               int, 'count')]
251
 
    takes_args = [ "locations*" ]
 
213
    takes_args = [ "location?" ]
252
214
    aliases = [ "visualize", "vis", "viz" ]
253
215
 
254
 
    def run(self, locations_list, revision=None, limit=None):
 
216
    def run(self, location=".", revision=None, limit=None):
255
217
        set_ui_factory()
256
 
        if locations_list is None:
257
 
            locations_list = ["."]
258
 
        revids = []
259
 
        for location in locations_list:
260
 
            (br, path) = branch.Branch.open_containing(location)
 
218
        (branch, path) = Branch.open_containing(location)
 
219
        branch.lock_read()
 
220
        branch.repository.lock_read()
 
221
        try:
261
222
            if revision is None:
262
 
                revids.append(br.last_revision())
 
223
                revid = branch.last_revision()
 
224
                if revid is None:
 
225
                    return
263
226
            else:
264
 
                revids.append(revision[0].as_revision_id(br))
265
 
        import gtk
266
 
        pp = start_viz_window(br, revids, limit)
267
 
        pp.connect("destroy", lambda w: gtk.main_quit())
268
 
        pp.show()
269
 
        gtk.main()
270
 
 
271
 
 
272
 
class cmd_gannotate(GTKCommand):
 
227
                (revno, revid) = revision[0].in_history(branch)
 
228
 
 
229
            from viz.branchwin import BranchWindow
 
230
            import gtk
 
231
                
 
232
            pp = BranchWindow()
 
233
            pp.set_branch(branch, revid, limit)
 
234
            pp.connect("destroy", lambda w: gtk.main_quit())
 
235
            pp.show()
 
236
            gtk.main()
 
237
        finally:
 
238
            branch.repository.unlock()
 
239
            branch.unlock()
 
240
 
 
241
 
 
242
register_command(cmd_visualise)
 
243
 
 
244
class cmd_gannotate(Command):
273
245
    """GTK+ annotate.
274
246
    
275
247
    Browse changes to FILENAME line by line in a GTK+ window.
277
249
 
278
250
    takes_args = ["filename", "line?"]
279
251
    takes_options = [
280
 
        Option("all", help="Show annotations on all lines."),
281
 
        Option("plain", help="Don't highlight annotation lines."),
 
252
        Option("all", help="show annotations on all lines"),
 
253
        Option("plain", help="don't highlight annotation lines"),
282
254
        Option("line", type=int, argname="lineno",
283
 
               help="Jump to specified line number."),
 
255
               help="jump to specified line number"),
284
256
        "revision",
285
257
    ]
286
258
    aliases = ["gblame", "gpraise"]
287
259
    
288
260
    def run(self, filename, all=False, plain=False, line='1', revision=None):
289
 
        gtk = open_display()
 
261
        pygtk = import_pygtk()
 
262
 
 
263
        try:
 
264
            import gtk
 
265
        except RuntimeError, e:
 
266
            if str(e) == "could not open display":
 
267
                raise NoDisplayError
 
268
        set_ui_factory()
290
269
 
291
270
        try:
292
271
            line = int(line)
296
275
 
297
276
        from annotate.gannotate import GAnnotateWindow
298
277
        from annotate.config import GAnnotateConfig
299
 
        from bzrlib.bzrdir import BzrDir
300
278
 
301
 
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
302
 
        if wt is not None:
303
 
            tree = wt
304
 
        else:
305
 
            tree = br.basis_tree()
 
279
        try:
 
280
            (tree, path) = WorkingTree.open_containing(filename)
 
281
            branch = tree.branch
 
282
        except errors.NoWorkingTree:
 
283
            (branch, path) = Branch.open_containing(filename)
 
284
            tree = branch.basis_tree()
306
285
 
307
286
        file_id = tree.path2id(path)
308
287
 
311
290
        if revision is not None:
312
291
            if len(revision) != 1:
313
292
                raise BzrCommandError("Only 1 revion may be specified.")
314
 
            revision_id = revision[0].as_revision_id(br)
315
 
            tree = br.repository.revision_tree(revision_id)
 
293
            revision_id = revision[0].in_history(branch).rev_id
 
294
            tree = branch.repository.revision_tree(revision_id)
316
295
        else:
317
296
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
318
297
 
319
 
        window = GAnnotateWindow(all, plain, branch=br)
 
298
        window = GAnnotateWindow(all, plain)
320
299
        window.connect("destroy", lambda w: gtk.main_quit())
 
300
        window.set_title(path + " - gannotate")
321
301
        config = GAnnotateConfig(window)
322
302
        window.show()
323
 
        br.lock_read()
324
 
        if wt is not None:
325
 
            wt.lock_read()
 
303
        branch.lock_read()
326
304
        try:
327
 
            window.annotate(tree, br, file_id)
328
 
            window.jump_to_line(line)
329
 
            gtk.main()
 
305
            window.annotate(tree, branch, file_id)
330
306
        finally:
331
 
            br.unlock()
332
 
            if wt is not None:
333
 
                wt.unlock()
334
 
 
335
 
 
336
 
 
337
 
class cmd_gcommit(GTKCommand):
 
307
            branch.unlock()
 
308
        window.jump_to_line(line)
 
309
        
 
310
        gtk.main()
 
311
 
 
312
register_command(cmd_gannotate)
 
313
 
 
314
class cmd_gcommit(Command):
338
315
    """GTK+ commit dialog
339
316
 
340
317
    Graphical user interface for committing revisions"""
341
 
 
 
318
    
342
319
    aliases = [ "gci" ]
343
320
    takes_args = []
344
321
    takes_options = []
345
322
 
346
323
    def run(self, filename=None):
347
324
        import os
348
 
        open_display()
 
325
        pygtk = import_pygtk()
 
326
 
 
327
        try:
 
328
            import gtk
 
329
        except RuntimeError, e:
 
330
            if str(e) == "could not open display":
 
331
                raise NoDisplayError
 
332
 
 
333
        set_ui_factory()
349
334
        from commit import CommitDialog
 
335
        from bzrlib.commit import Commit
350
336
        from bzrlib.errors import (BzrCommandError,
351
337
                                   NotBranchError,
352
 
                                   NoWorkingTree)
 
338
                                   NoWorkingTree,
 
339
                                   PointlessCommit,
 
340
                                   ConflictsInTree,
 
341
                                   StrictCommitFailed)
353
342
 
354
343
        wt = None
355
 
        br = None
 
344
        branch = None
356
345
        try:
357
 
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
358
 
            br = wt.branch
 
346
            (wt, path) = WorkingTree.open_containing(filename)
 
347
            branch = wt.branch
 
348
        except NotBranchError, e:
 
349
            path = e.path
359
350
        except NoWorkingTree, e:
360
 
            from dialog import error_dialog
361
 
            error_dialog(_i18n('Directory does not have a working tree'),
362
 
                         _i18n('Operation aborted.'))
363
 
            return 1 # should this be retval=3?
364
 
 
365
 
        # It is a good habit to keep things locked for the duration, but it
366
 
        # could cause difficulties if someone wants to do things in another
367
 
        # window... We could lock_read() until we actually go to commit
368
 
        # changes... Just a thought.
369
 
        wt.lock_write()
370
 
        try:
371
 
            dlg = CommitDialog(wt)
372
 
            return dlg.run()
373
 
        finally:
374
 
            wt.unlock()
375
 
 
376
 
 
377
 
class cmd_gstatus(GTKCommand):
 
351
            path = e.base
 
352
            try:
 
353
                (branch, path) = Branch.open_containing(path)
 
354
            except NotBranchError, e:
 
355
                path = e.path
 
356
 
 
357
 
 
358
        commit = CommitDialog(wt, path, not branch)
 
359
        commit.run()
 
360
 
 
361
register_command(cmd_gcommit)
 
362
 
 
363
class cmd_gstatus(Command):
378
364
    """GTK+ status dialog
379
365
 
380
366
    Graphical user interface for showing status 
382
368
    
383
369
    aliases = [ "gst" ]
384
370
    takes_args = ['PATH?']
385
 
    takes_options = ['revision']
 
371
    takes_options = []
386
372
 
387
 
    def run(self, path='.', revision=None):
 
373
    def run(self, path='.'):
388
374
        import os
389
 
        gtk = open_display()
 
375
        pygtk = import_pygtk()
 
376
 
 
377
        try:
 
378
            import gtk
 
379
        except RuntimeError, e:
 
380
            if str(e) == "could not open display":
 
381
                raise NoDisplayError
 
382
 
 
383
        set_ui_factory()
390
384
        from status import StatusDialog
391
 
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
392
 
        
393
 
        if revision is not None:
394
 
            try:
395
 
                revision_id = revision[0].as_revision_id(wt.branch)
396
 
            except:
397
 
                from bzrlib.errors import BzrError
398
 
                raise BzrError('Revision %r doesn\'t exist' % revision[0].user_spec )
399
 
        else:
400
 
            revision_id = None
401
 
 
402
 
        status = StatusDialog(wt, wt_path, revision_id)
 
385
        (wt, wt_path) = WorkingTree.open_containing(path)
 
386
        status = StatusDialog(wt, wt_path)
403
387
        status.connect("destroy", gtk.main_quit)
404
388
        status.run()
405
389
 
406
 
 
407
 
class cmd_gsend(GTKCommand):
408
 
    """GTK+ send merge directive.
409
 
 
410
 
    """
411
 
    def run(self):
412
 
        (br, path) = branch.Branch.open_containing(".")
413
 
        gtk = open_display()
414
 
        from bzrlib.plugins.gtk.mergedirective import SendMergeDirectiveDialog
415
 
        from StringIO import StringIO
416
 
        dialog = SendMergeDirectiveDialog(br)
417
 
        if dialog.run() == gtk.RESPONSE_OK:
418
 
            outf = StringIO()
419
 
            outf.writelines(dialog.get_merge_directive().to_lines())
420
 
            mail_client = br.get_config().get_mail_client()
421
 
            mail_client.compose_merge_request(dialog.get_mail_to(), "[MERGE]", 
422
 
                outf.getvalue())
423
 
 
424
 
            
425
 
 
426
 
 
427
 
class cmd_gconflicts(GTKCommand):
428
 
    """GTK+ conflicts.
 
390
register_command(cmd_gstatus)
 
391
 
 
392
class cmd_gconflicts(Command):
 
393
    """ GTK+ push.
429
394
    
430
 
    Select files from the list of conflicts and run an external utility to
431
 
    resolve them.
432
395
    """
433
396
    def run(self):
434
 
        (wt, path) = workingtree.WorkingTree.open_containing('.')
435
 
        open_display()
 
397
        (wt, path) = WorkingTree.open_containing('.')
 
398
        
 
399
        pygtk = import_pygtk()
 
400
        try:
 
401
            import gtk
 
402
        except RuntimeError, e:
 
403
            if str(e) == "could not open display":
 
404
                raise NoDisplayError
 
405
 
436
406
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
 
407
 
 
408
        set_ui_factory()
437
409
        dialog = ConflictsDialog(wt)
438
410
        dialog.run()
439
411
 
440
 
 
441
 
class cmd_gpreferences(GTKCommand):
442
 
    """ GTK+ preferences dialog.
443
 
 
444
 
    """
445
 
    def run(self):
446
 
        open_display()
447
 
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
448
 
        dialog = PreferencesWindow()
449
 
        dialog.run()
450
 
 
451
 
 
452
 
class cmd_gmissing(Command):
453
 
    """ GTK+ missing revisions dialog.
454
 
 
455
 
    """
456
 
    takes_args = ["other_branch?"]
457
 
    def run(self, other_branch=None):
458
 
        pygtk = import_pygtk()
459
 
        try:
460
 
            import gtk
461
 
        except RuntimeError, e:
462
 
            if str(e) == "could not open display":
463
 
                raise NoDisplayError
464
 
 
465
 
        from bzrlib.plugins.gtk.missing import MissingWindow
466
 
        from bzrlib.branch import Branch
467
 
 
468
 
        local_branch = Branch.open_containing(".")[0]
469
 
        if other_branch is None:
470
 
            other_branch = local_branch.get_parent()
471
 
            
472
 
            if other_branch is None:
473
 
                raise errors.BzrCommandError("No peer location known or specified.")
474
 
        remote_branch = Branch.open_containing(other_branch)[0]
475
 
        set_ui_factory()
476
 
        local_branch.lock_read()
477
 
        try:
478
 
            remote_branch.lock_read()
479
 
            try:
480
 
                dialog = MissingWindow(local_branch, remote_branch)
481
 
                dialog.run()
482
 
            finally:
483
 
                remote_branch.unlock()
484
 
        finally:
485
 
            local_branch.unlock()
486
 
 
487
 
 
488
 
class cmd_ginit(GTKCommand):
489
 
    def run(self):
490
 
        open_display()
491
 
        from initialize import InitDialog
492
 
        dialog = InitDialog(os.path.abspath(os.path.curdir))
493
 
        dialog.run()
494
 
 
495
 
 
496
 
class cmd_gtags(GTKCommand):
497
 
    def run(self):
498
 
        br = branch.Branch.open_containing('.')[0]
499
 
        
500
 
        gtk = open_display()
501
 
        from tags import TagsWindow
502
 
        window = TagsWindow(br)
503
 
        window.show()
504
 
        gtk.main()
505
 
 
506
 
 
507
 
commands = [
508
 
    cmd_gannotate, 
509
 
    cmd_gbranch,
510
 
    cmd_gcheckout, 
511
 
    cmd_gcommit, 
512
 
    cmd_gconflicts, 
513
 
    cmd_gdiff,
514
 
    cmd_ginit,
515
 
    cmd_gmissing, 
516
 
    cmd_gpreferences, 
517
 
    cmd_gpush, 
518
 
    cmd_gsend,
519
 
    cmd_gstatus,
520
 
    cmd_gtags,
521
 
    cmd_visualise
522
 
    ]
523
 
 
524
 
for cmd in commands:
525
 
    register_command(cmd)
526
 
 
527
 
 
528
 
class cmd_commit_notify(GTKCommand):
529
 
    """Run the bzr commit notifier.
530
 
 
531
 
    This is a background program which will pop up a notification on the users
532
 
    screen when a commit occurs.
533
 
    """
534
 
 
535
 
    def run(self):
536
 
        from notify import NotifyPopupMenu
537
 
        gtk = open_display()
538
 
        menu = NotifyPopupMenu()
539
 
        icon = gtk.status_icon_new_from_file(icon_path("bzr-icon-64.png"))
540
 
        icon.connect('popup-menu', menu.display)
541
 
 
542
 
        import cgi
543
 
        import dbus
544
 
        import dbus.service
545
 
        import pynotify
546
 
        from bzrlib.bzrdir import BzrDir
547
 
        from bzrlib import errors
548
 
        from bzrlib.osutils import format_date
549
 
        from bzrlib.transport import get_transport
550
 
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
551
 
            import dbus.glib
552
 
        BROADCAST_INTERFACE = "org.bazaarvcs.plugins.dbus.Broadcast"
553
 
        bus = dbus.SessionBus()
554
 
 
555
 
        def catch_branch(revision_id, urls):
556
 
            # TODO: show all the urls, or perhaps choose the 'best'.
557
 
            url = urls[0]
558
 
            try:
559
 
                if isinstance(revision_id, unicode):
560
 
                    revision_id = revision_id.encode('utf8')
561
 
                transport = get_transport(url)
562
 
                a_dir = BzrDir.open_from_transport(transport)
563
 
                branch = a_dir.open_branch()
564
 
                revno = branch.revision_id_to_revno(revision_id)
565
 
                revision = branch.repository.get_revision(revision_id)
566
 
                summary = 'New revision %d in %s' % (revno, url)
567
 
                body  = 'Committer: %s\n' % revision.committer
568
 
                body += 'Date: %s\n' % format_date(revision.timestamp,
569
 
                    revision.timezone)
570
 
                body += '\n'
571
 
                body += revision.message
572
 
                body = cgi.escape(body)
573
 
                nw = pynotify.Notification(summary, body)
574
 
                def start_viz(notification=None, action=None, data=None):
575
 
                    """Start the viz program."""
576
 
                    pp = start_viz_window(branch, revision_id)
577
 
                    pp.show()
578
 
                def start_branch(notification=None, action=None, data=None):
579
 
                    """Start a Branch dialog"""
580
 
                    from bzrlib.plugins.gtk.branch import BranchDialog
581
 
                    bd = BranchDialog(remote_path=url)
582
 
                    bd.run()
583
 
                nw.add_action("inspect", "Inspect", start_viz, None)
584
 
                nw.add_action("branch", "Branch", start_branch, None)
585
 
                nw.set_timeout(5000)
586
 
                nw.show()
587
 
            except Exception, e:
588
 
                print e
589
 
                raise
590
 
        bus.add_signal_receiver(catch_branch,
591
 
                                dbus_interface=BROADCAST_INTERFACE,
592
 
                                signal_name="Revision")
593
 
        pynotify.init("bzr commit-notify")
594
 
        gtk.main()
595
 
 
596
 
register_command(cmd_commit_notify)
597
 
 
598
 
 
599
 
class cmd_gselftest(GTKCommand):
600
 
    """Version of selftest that displays a notification at the end"""
601
 
 
602
 
    takes_args = builtins.cmd_selftest.takes_args
603
 
    takes_options = builtins.cmd_selftest.takes_options
604
 
    _see_also = ['selftest']
605
 
 
606
 
    def run(self, *args, **kwargs):
607
 
        import cgi
608
 
        import sys
609
 
        default_encoding = sys.getdefaultencoding()
610
 
        # prevent gtk from blowing up later
611
 
        gtk = import_pygtk()
612
 
        # prevent gtk from messing with default encoding
613
 
        import pynotify
614
 
        if sys.getdefaultencoding() != default_encoding:
615
 
            reload(sys)
616
 
            sys.setdefaultencoding(default_encoding)
617
 
        result = builtins.cmd_selftest().run(*args, **kwargs)
618
 
        if result == 0:
619
 
            summary = 'Success'
620
 
            body = 'Selftest succeeded in "%s"' % os.getcwd()
621
 
        if result == 1:
622
 
            summary = 'Failure'
623
 
            body = 'Selftest failed in "%s"' % os.getcwd()
624
 
        pynotify.init("bzr gselftest")
625
 
        note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
626
 
        note.set_timeout(pynotify.EXPIRES_NEVER)
627
 
        note.show()
628
 
 
629
 
 
630
 
register_command(cmd_gselftest)
631
 
 
632
 
 
633
 
class cmd_test_gtk(GTKCommand):
634
 
    """Version of selftest that just runs the gtk test suite."""
635
 
 
636
 
    takes_options = ['verbose',
637
 
                     Option('one', short_name='1',
638
 
                            help='Stop when one test fails.'),
639
 
                     Option('benchmark', help='Run the benchmarks.'),
640
 
                     Option('lsprof-timed',
641
 
                     help='Generate lsprof output for benchmarked'
642
 
                          ' sections of code.'),
643
 
                     Option('list-only',
644
 
                     help='List the tests instead of running them.'),
645
 
                     Option('randomize', type=str, argname="SEED",
646
 
                     help='Randomize the order of tests using the given'
647
 
                          ' seed or "now" for the current time.'),
648
 
                    ]
649
 
    takes_args = ['testspecs*']
650
 
 
651
 
    def run(self, verbose=None, one=False, benchmark=None,
652
 
            lsprof_timed=None, list_only=False, randomize=None,
653
 
            testspecs_list=None):
654
 
        from bzrlib import __path__ as bzrlib_path
655
 
        from bzrlib.tests import selftest
656
 
 
657
 
        print '%10s: %s' % ('bzrlib', bzrlib_path[0])
658
 
        if benchmark:
659
 
            print 'No benchmarks yet'
660
 
            return 3
661
 
 
662
 
            test_suite_factory = bench_suite
663
 
            if verbose is None:
664
 
                verbose = True
665
 
            # TODO: should possibly lock the history file...
666
 
            benchfile = open(".perf_history", "at", buffering=1)
667
 
        else:
668
 
            test_suite_factory = test_suite
669
 
            if verbose is None:
670
 
                verbose = False
671
 
            benchfile = None
672
 
 
673
 
        if testspecs_list is not None:
674
 
            pattern = '|'.join(testspecs_list)
675
 
        else:
676
 
            pattern = ".*"
677
 
 
678
 
        try:
679
 
            result = selftest(verbose=verbose,
680
 
                              pattern=pattern,
681
 
                              stop_on_failure=one,
682
 
                              test_suite_factory=test_suite_factory,
683
 
                              lsprof_timed=lsprof_timed,
684
 
                              bench_history=benchfile,
685
 
                              list_only=list_only,
686
 
                              random_seed=randomize,
687
 
                             )
688
 
        finally:
689
 
            if benchfile is not None:
690
 
                benchfile.close()
691
 
 
692
 
register_command(cmd_test_gtk)
693
 
 
694
 
 
 
412
register_command(cmd_gconflicts)
695
413
 
696
414
import gettext
697
415
gettext.install('olive-gtk')
698
416
 
699
 
# Let's create a specialized alias to protect '_' from being erased by other
700
 
# uses of '_' as an anonymous variable (think pdb for one).
701
 
_i18n = gettext.gettext
702
 
 
703
417
class NoDisplayError(BzrCommandError):
704
418
    """gtk could not find a proper display"""
705
419
 
706
420
    def __str__(self):
707
421
        return "No DISPLAY. Unable to run GTK+ application."
708
422
 
709
 
 
710
423
def test_suite():
711
424
    from unittest import TestSuite
712
425
    import tests
713
 
    import sys
714
 
    default_encoding = sys.getdefaultencoding()
715
 
    try:
716
 
        result = TestSuite()
717
 
        try:
718
 
            import_pygtk()
719
 
        except errors.BzrCommandError:
720
 
            return result
721
 
        result.addTest(tests.test_suite())
722
 
    finally:
723
 
        if sys.getdefaultencoding() != default_encoding:
724
 
            reload(sys)
725
 
            sys.setdefaultencoding(default_encoding)
 
426
    result = TestSuite()
 
427
    result.addTest(tests.test_suite())
726
428
    return result