/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
49 by Jelmer Vernooij
Merge in Dan Loda's gannotate plugin and put it in annotate/
1
# This program is free software; you can redistribute it and/or modify
2
# it under the terms of the GNU General Public License as published by
3
# the Free Software Foundation; either version 2 of the License, or
4
# (at your option) any later version.
5
6
# This program is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9
# GNU General Public License for more details.
10
11
# You should have received a copy of the GNU General Public License
12
# along with this program; if not, write to the Free Software
13
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14
15
"""GTK+ frontends to Bazaar commands """
73 by Jelmer Vernooij
Release 0.9, list myself as maintainer.
16
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
17
import bzrlib
18
188 by Jelmer Vernooij
merge 0.15.2 NEWS update.
19
__version__ = '0.16.0'
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
20
version_info = tuple(int(n) for n in __version__.split('.'))
21
22
23
def check_bzrlib_version(desired):
24
    """Check that bzrlib is compatible.
25
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.
30
    """
31
    desired_plus = (desired[0], desired[1]+1)
32
    bzrlib_version = bzrlib.version_info[:2]
33
    if bzrlib_version == desired:
34
        return
35
    try:
36
        from bzrlib.trace import warning
37
    except ImportError:
38
        # get the message out any way we can
39
        from warnings import warn as warning
40
    if bzrlib_version < desired:
41
        warning('Installed bzr version %s is too old to be used with bzr-gtk'
42
                ' %s.' % (bzrlib.__version__, __version__))
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])
54
146 by Jelmer Vernooij
Move more code to top-level directory.
55
from bzrlib.trace import warning
56
if __name__ != 'bzrlib.plugins.gtk':
57
    warning("Not running as bzrlib.plugins.gtk, things may break.")
58
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
59
from bzrlib.lazy_import import lazy_import
60
lazy_import(globals(), """
61
from bzrlib import (
62
    branch,
63
    errors,
64
    workingtree,
65
    )
66
""")
67
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
68
from bzrlib.commands import Command, register_command, display_command
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
69
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
70
from bzrlib.option import Option
71
126.1.5 by Szilveszter Farkas (Phanatic)
bzr gbranch should work now (Fixed: #77751)
72
import os.path
73
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
74
def import_pygtk():
75
    try:
76
        import pygtk
77
    except ImportError:
78
        raise errors.BzrCommandError("PyGTK not installed.")
79
    pygtk.require('2.0')
80
    return pygtk
81
82
133 by Jelmer Vernooij
Actually use the ui factory.
83
def set_ui_factory():
177 by Jelmer Vernooij
Register commands all at once.
84
    import_pygtk()
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
85
    from ui import GtkUIFactory
133 by Jelmer Vernooij
Actually use the ui factory.
86
    import bzrlib.ui
87
    bzrlib.ui.ui_factory = GtkUIFactory()
88
89
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
90
class GTKCommand(Command):
91
    """Abstract class providing GTK specific run commands."""
92
93
    def open_display(self):
94
        pygtk = import_pygtk()
95
        try:
96
            import gtk
97
        except RuntimeError, e:
98
            if str(e) == "could not open display":
99
                raise NoDisplayError
100
        set_ui_factory()
173.1.3 by Robert Collins
Add new command 'commit-notify' to listen for commits on dbus and show them via pynotify.
101
        return gtk
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
102
103
    def run(self):
104
        self.open_display()
105
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
106
        dialog.run()
107
108
109
class cmd_gbranch(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
110
    """GTK+ branching.
111
    
112
    """
113
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
114
    def get_gtk_dialog(self, path):
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
115
        from bzrlib.plugins.gtk.branch import BranchDialog
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
116
        return BranchDialog(path)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
117
118
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
119
class cmd_gcheckout(GTKCommand):
126.1.18 by Szilveszter Farkas (Phanatic)
Improved Branch dialog. Refactored Checkout dialog.
120
    """ GTK+ checkout.
121
    
122
    """
123
    
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
124
    def get_gtk_dialog(self, path):
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
125
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
126
        return CheckoutDialog(path)
126.1.18 by Szilveszter Farkas (Phanatic)
Improved Branch dialog. Refactored Checkout dialog.
127
128
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
129
130
class cmd_gpush(GTKCommand):
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
131
    """ GTK+ push.
132
    
133
    """
134
    takes_args = [ "location?" ]
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
135
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
136
    def run(self, location="."):
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
137
        (br, path) = branch.Branch.open_containing(location)
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
138
        self.open_display()
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
139
        from push import PushDialog
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
140
        dialog = PushDialog(br)
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
141
        dialog.run()
142
143
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
144
145
class cmd_gdiff(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
146
    """Show differences in working tree in a GTK+ Window.
147
    
148
    Otherwise, all changes for the tree are listed.
149
    """
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
150
    takes_args = ['filename?']
58.1.1 by Aaron Bentley
gdiff takes -r arguments
151
    takes_options = ['revision']
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
152
153
    @display_command
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
154
    def run(self, revision=None, filename=None):
133 by Jelmer Vernooij
Actually use the ui factory.
155
        set_ui_factory()
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
156
        wt = workingtree.WorkingTree.open_containing(".")[0]
161 by Aaron Bentley
Fix gannotate interaction with dirstate
157
        wt.lock_read()
158
        try:
159
            branch = wt.branch
160
            if revision is not None:
161
                if len(revision) == 1:
162
                    tree1 = wt
163
                    revision_id = revision[0].in_history(branch).rev_id
164
                    tree2 = branch.repository.revision_tree(revision_id)
165
                elif len(revision) == 2:
166
                    revision_id_0 = revision[0].in_history(branch).rev_id
167
                    tree2 = branch.repository.revision_tree(revision_id_0)
168
                    revision_id_1 = revision[1].in_history(branch).rev_id
169
                    tree1 = branch.repository.revision_tree(revision_id_1)
170
            else:
58.1.1 by Aaron Bentley
gdiff takes -r arguments
171
                tree1 = wt
161 by Aaron Bentley
Fix gannotate interaction with dirstate
172
                tree2 = tree1.basis_tree()
173
174
            from diff import DiffWindow
175
            import gtk
176
            window = DiffWindow()
177
            window.connect("destroy", gtk.main_quit)
178
            window.set_diff("Working Tree", tree1, tree2)
179
            if filename is not None:
180
                tree_filename = wt.relpath(filename)
181
                try:
182
                    window.set_file(tree_filename)
183
                except NoSuchFile:
188.3.1 by John Arbash Meinel
Use tree.path2id to avoid getting 'Object Not Locked' errors.
184
                    if (tree1.path2id(tree_filename) is None and 
185
                        tree2.path2id(tree_filename) is None):
161 by Aaron Bentley
Fix gannotate interaction with dirstate
186
                        raise NotVersionedError(filename)
187
                    raise BzrCommandError('No changes found for file "%s"' % 
188
                                          filename)
189
            window.show()
190
191
            gtk.main()
192
        finally:
193
            wt.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
194
195
196
class cmd_visualise(Command):
197
    """Graphically visualise this branch.
198
199
    Opens a graphical window to allow you to see the history of the branch
200
    and relationships between revisions in a visual manner,
201
202
    The default starting point is latest revision on the branch, you can
203
    specify a starting point with -r revision.
204
    """
205
    takes_options = [
206
        "revision",
207
        Option('limit', "maximum number of revisions to display",
208
               int, 'count')]
209
    takes_args = [ "location?" ]
210
    aliases = [ "visualize", "vis", "viz" ]
211
212
    def run(self, location=".", revision=None, limit=None):
133 by Jelmer Vernooij
Actually use the ui factory.
213
        set_ui_factory()
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
214
        (br, path) = branch.Branch.open_containing(location)
215
        br.lock_read()
216
        br.repository.lock_read()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
217
        try:
218
            if revision is None:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
219
                revid = br.last_revision()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
220
                if revid is None:
221
                    return
222
            else:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
223
                (revno, revid) = revision[0].in_history(br)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
224
152 by Jelmer Vernooij
Cleanup some more code.
225
            from viz.branchwin import BranchWindow
226
            import gtk
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
227
                
152 by Jelmer Vernooij
Cleanup some more code.
228
            pp = BranchWindow()
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
229
            pp.set_branch(br, revid, limit)
152 by Jelmer Vernooij
Cleanup some more code.
230
            pp.connect("destroy", lambda w: gtk.main_quit())
231
            pp.show()
232
            gtk.main()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
233
        finally:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
234
            br.repository.unlock()
235
            br.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
236
237
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
238
class cmd_gannotate(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
239
    """GTK+ annotate.
240
    
241
    Browse changes to FILENAME line by line in a GTK+ window.
242
    """
243
59.2.1 by Aaron Bentley
Gannotate takes a line number
244
    takes_args = ["filename", "line?"]
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
245
    takes_options = [
246
        Option("all", help="show annotations on all lines"),
247
        Option("plain", help="don't highlight annotation lines"),
248
        Option("line", type=int, argname="lineno",
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
249
               help="jump to specified line number"),
250
        "revision",
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
251
    ]
252
    aliases = ["gblame", "gpraise"]
253
    
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
254
    def run(self, filename, all=False, plain=False, line='1', revision=None):
187 by Jelmer Vernooij
Fix gannotate.
255
        gtk = self.open_display()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
256
59.2.1 by Aaron Bentley
Gannotate takes a line number
257
        try:
258
            line = int(line)
259
        except ValueError:
260
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
261
                                  line)
262
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
263
        from annotate.gannotate import GAnnotateWindow
264
        from annotate.config import GAnnotateConfig
177 by Jelmer Vernooij
Register commands all at once.
265
        from bzrlib.bzrdir import BzrDir
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
266
161 by Aaron Bentley
Fix gannotate interaction with dirstate
267
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
268
        if wt is not None:
269
            tree = wt
270
        else:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
271
            tree = br.basis_tree()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
272
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
273
        file_id = tree.path2id(path)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
274
275
        if file_id is None:
276
            raise NotVersionedError(filename)
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
277
        if revision is not None:
278
            if len(revision) != 1:
279
                raise BzrCommandError("Only 1 revion may be specified.")
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
280
            revision_id = revision[0].in_history(br).rev_id
281
            tree = br.repository.revision_tree(revision_id)
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
282
        else:
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
283
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
284
285
        window = GAnnotateWindow(all, plain)
286
        window.connect("destroy", lambda w: gtk.main_quit())
287
        window.set_title(path + " - gannotate")
288
        config = GAnnotateConfig(window)
289
        window.show()
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
290
        br.lock_read()
161 by Aaron Bentley
Fix gannotate interaction with dirstate
291
        if wt is not None:
292
            wt.lock_read()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
293
        try:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
294
            window.annotate(tree, br, file_id)
161 by Aaron Bentley
Fix gannotate interaction with dirstate
295
            window.jump_to_line(line)
296
            gtk.main()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
297
        finally:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
298
            br.unlock()
161 by Aaron Bentley
Fix gannotate interaction with dirstate
299
            if wt is not None:
300
                wt.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
301
302
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
303
304
class cmd_gcommit(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
305
    """GTK+ commit dialog
306
307
    Graphical user interface for committing revisions"""
308
    
145 by Jelmer Vernooij
Fix some strings, import.
309
    aliases = [ "gci" ]
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
310
    takes_args = []
311
    takes_options = []
312
313
    def run(self, filename=None):
93.1.17 by Alexander Belchenko
gcommit reworked again.
314
        import os
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
315
        self.open_display()
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
316
        from commit import CommitDialog
93.1.17 by Alexander Belchenko
gcommit reworked again.
317
        from bzrlib.errors import (BzrCommandError,
318
                                   NotBranchError,
178 by Jelmer Vernooij
Remove unneeded imports.
319
                                   NoWorkingTree)
93.1.17 by Alexander Belchenko
gcommit reworked again.
320
321
        wt = None
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
322
        br = None
93.1.17 by Alexander Belchenko
gcommit reworked again.
323
        try:
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
324
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
325
            br = wt.branch
93.1.17 by Alexander Belchenko
gcommit reworked again.
326
        except NoWorkingTree, e:
327
            path = e.base
195.2.1 by Szilveszter Farkas (Phanatic)
NotBranchError exception shouldn't be handled. (Fixes: #113394)
328
            (br, path) = branch.Branch.open_containing(path)
93.1.17 by Alexander Belchenko
gcommit reworked again.
329
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
330
        commit = CommitDialog(wt, path, not br)
135 by Jelmer Vernooij
Throw out the old CommitDialog code and use the new code instead, also for 'gcommit'.
331
        commit.run()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
332
333
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
334
335
class cmd_gstatus(GTKCommand):
157 by Jelmer Vernooij
Add gstatus command.
336
    """GTK+ status dialog
337
338
    Graphical user interface for showing status 
339
    information."""
340
    
341
    aliases = [ "gst" ]
342
    takes_args = ['PATH?']
343
    takes_options = []
344
345
    def run(self, path='.'):
346
        import os
184 by Jelmer Vernooij
Fix gstatus
347
        gtk = self.open_display()
157 by Jelmer Vernooij
Add gstatus command.
348
        from status import StatusDialog
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
349
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
157 by Jelmer Vernooij
Add gstatus command.
350
        status = StatusDialog(wt, wt_path)
351
        status.connect("destroy", gtk.main_quit)
352
        status.run()
353
354
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
355
356
class cmd_gconflicts(GTKCommand):
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
357
    """ GTK+ push.
358
    
359
    """
360
    def run(self):
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
361
        (wt, path) = workingtree.WorkingTree.open_containing('.')
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
362
        self.open_display()
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
363
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
364
        dialog = ConflictsDialog(wt)
365
        dialog.run()
366
157 by Jelmer Vernooij
Add gstatus command.
367
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
368
369
class cmd_gpreferences(GTKCommand):
171 by Jelmer Vernooij
Initial work on a preferences dialog in GTK+, including a list of plugins with metadata browser.
370
    """ GTK+ preferences dialog.
371
372
    """
373
    def run(self):
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
374
        self.open_display()
171 by Jelmer Vernooij
Initial work on a preferences dialog in GTK+, including a list of plugins with metadata browser.
375
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
376
        dialog = PreferencesWindow()
377
        dialog.run()
378
379
175 by Jelmer Vernooij
Add very simple gmissing command.
380
381
class cmd_gmissing(Command):
382
    """ GTK+ missing revisions dialog.
383
384
    """
385
    takes_args = ["other_branch?"]
386
    def run(self, other_branch=None):
387
        pygtk = import_pygtk()
388
        try:
389
            import gtk
390
        except RuntimeError, e:
391
            if str(e) == "could not open display":
392
                raise NoDisplayError
393
394
        from bzrlib.plugins.gtk.missing import MissingWindow
395
        from bzrlib.branch import Branch
396
397
        local_branch = Branch.open_containing(".")[0]
398
        if other_branch is None:
399
            other_branch = local_branch.get_parent()
400
            
401
            if other_branch is None:
402
                raise errors.BzrCommandError("No peer location known or specified.")
403
        remote_branch = Branch.open_containing(other_branch)[0]
404
        set_ui_factory()
405
        local_branch.lock_read()
406
        try:
407
            remote_branch.lock_read()
408
            try:
409
                dialog = MissingWindow(local_branch, remote_branch)
410
                dialog.run()
411
            finally:
412
                remote_branch.unlock()
413
        finally:
414
            local_branch.unlock()
415
177 by Jelmer Vernooij
Register commands all at once.
416
188.1.1 by Szilveszter Farkas (Phanatic)
Inital implementation of the Initialize dialog. Not fully functional yet.
417
class cmd_ginit(GTKCommand):
418
    def run(self):
419
        self.open_display()
420
        from initialize import InitDialog
421
        dialog = InitDialog(os.path.abspath(os.path.curdir))
422
        dialog.run()
423
424
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
425
class cmd_gtags(GTKCommand):
426
    def run(self):
427
        br = branch.Branch.open_containing('.')[0]
428
        
429
        gtk = self.open_display()
430
        from tags import TagsWindow
431
        window = TagsWindow(br)
432
        window.show()
433
        gtk.main()
434
435
177 by Jelmer Vernooij
Register commands all at once.
436
commands = [
437
    cmd_gmissing, 
438
    cmd_gpreferences, 
439
    cmd_gconflicts, 
440
    cmd_gstatus,
441
    cmd_gcommit, 
442
    cmd_gannotate, 
443
    cmd_visualise, 
444
    cmd_gdiff,
445
    cmd_gpush, 
446
    cmd_gcheckout, 
188.1.1 by Szilveszter Farkas (Phanatic)
Inital implementation of the Initialize dialog. Not fully functional yet.
447
    cmd_gbranch,
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
448
    cmd_ginit,
449
    cmd_gtags
177 by Jelmer Vernooij
Register commands all at once.
450
    ]
451
452
for cmd in commands:
453
    register_command(cmd)
175 by Jelmer Vernooij
Add very simple gmissing command.
454
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
455
173.1.3 by Robert Collins
Add new command 'commit-notify' to listen for commits on dbus and show them via pynotify.
456
class cmd_commit_notify(GTKCommand):
457
    """Run the bzr commit notifier.
458
459
    This is a background program which will pop up a notification on the users
460
    screen when a commit occurs.
461
    """
462
463
    def run(self):
464
        gtk = self.open_display()
465
        import cgi
466
        import dbus
467
        import dbus.service
468
        import pynotify
469
        from bzrlib.bzrdir import BzrDir
470
        from bzrlib import errors
471
        from bzrlib.osutils import format_date
472
        from bzrlib.transport import get_transport
473
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
474
            import dbus.glib
475
        from bzrlib.plugins.dbus import activity
476
        bus = dbus.SessionBus()
477
        # get the object so we can subscribe to callbacks from it.
478
        broadcast_service = bus.get_object(
479
            activity.Broadcast.DBUS_NAME,
480
            activity.Broadcast.DBUS_PATH)
182.1.1 by Robert Collins
Update commit-notify to use new dbus api, and show remote URL's.
481
        def catch_branch(revision_id, urls):
482
            # TODO: show all the urls, or perhaps choose the 'best'.
483
            url = urls[0]
173.1.3 by Robert Collins
Add new command 'commit-notify' to listen for commits on dbus and show them via pynotify.
484
            try:
485
                if isinstance(revision_id, unicode):
486
                    revision_id = revision_id.encode('utf8')
487
                transport = get_transport(url)
488
                a_dir = BzrDir.open_from_transport(transport)
489
                branch = a_dir.open_branch()
490
                revno = branch.revision_id_to_revno(revision_id)
491
                revision = branch.repository.get_revision(revision_id)
492
                summary = 'New revision %d in %s' % (revno, url)
493
                body  = 'Committer: %s\n' % revision.committer
494
                body += 'Date: %s\n' % format_date(revision.timestamp,
495
                    revision.timezone)
496
                body += '\n'
497
                body += revision.message
498
                body = cgi.escape(body)
499
                nw = pynotify.Notification(summary, body)
500
                nw.set_timeout(5000)
501
                nw.show()
502
            except Exception, e:
503
                print e
504
                raise
505
        broadcast_service.connect_to_signal("Revision", catch_branch,
506
            dbus_interface=activity.Broadcast.DBUS_INTERFACE)
507
        pynotify.init("bzr commit-notify")
508
        gtk.main()
509
510
register_command(cmd_commit_notify)
511
512
152 by Jelmer Vernooij
Cleanup some more code.
513
import gettext
514
gettext.install('olive-gtk')
515
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
516
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
517
class NoDisplayError(BzrCommandError):
518
    """gtk could not find a proper display"""
519
520
    def __str__(self):
133 by Jelmer Vernooij
Actually use the ui factory.
521
        return "No DISPLAY. Unable to run GTK+ application."
522
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
523
140 by Jelmer Vernooij
add framework for tests.
524
def test_suite():
525
    from unittest import TestSuite
526
    import tests
163 by Aaron Bentley
Prevent test suite from causing default-encoding changes
527
    import sys
528
    default_encoding = sys.getdefaultencoding()
529
    try:
530
        result = TestSuite()
531
        result.addTest(tests.test_suite())
532
    finally:
170.1.2 by Aaron Bentley
Test suite only fixes encoding if it's changed. Fixes test_selftest bug.
533
        if sys.getdefaultencoding() != default_encoding:
534
            reload(sys)
535
            sys.setdefaultencoding(default_encoding)
140 by Jelmer Vernooij
add framework for tests.
536
    return result