/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:
184
                    if (tree1.inventory.path2id(tree_filename) is None and 
185
                        tree2.inventory.path2id(tree_filename) is None):
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 NotBranchError, e:
327
            path = e.path
328
        except NoWorkingTree, e:
329
            path = e.base
330
            try:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
331
                (br, path) = branch.Branch.open_containing(path)
93.1.17 by Alexander Belchenko
gcommit reworked again.
332
            except NotBranchError, e:
333
                path = e.path
334
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
335
        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'.
336
        commit.run()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
337
338
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
339
340
class cmd_gstatus(GTKCommand):
157 by Jelmer Vernooij
Add gstatus command.
341
    """GTK+ status dialog
342
343
    Graphical user interface for showing status 
344
    information."""
345
    
346
    aliases = [ "gst" ]
347
    takes_args = ['PATH?']
348
    takes_options = []
349
350
    def run(self, path='.'):
351
        import os
184 by Jelmer Vernooij
Fix gstatus
352
        gtk = self.open_display()
157 by Jelmer Vernooij
Add gstatus command.
353
        from status import StatusDialog
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
354
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
157 by Jelmer Vernooij
Add gstatus command.
355
        status = StatusDialog(wt, wt_path)
356
        status.connect("destroy", gtk.main_quit)
357
        status.run()
358
359
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
360
361
class cmd_gconflicts(GTKCommand):
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
362
    """ GTK+ push.
363
    
364
    """
365
    def run(self):
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
366
        (wt, path) = workingtree.WorkingTree.open_containing('.')
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
367
        self.open_display()
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
368
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
369
        dialog = ConflictsDialog(wt)
370
        dialog.run()
371
157 by Jelmer Vernooij
Add gstatus command.
372
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
373
374
class cmd_gpreferences(GTKCommand):
171 by Jelmer Vernooij
Initial work on a preferences dialog in GTK+, including a list of plugins with metadata browser.
375
    """ GTK+ preferences dialog.
376
377
    """
378
    def run(self):
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
379
        self.open_display()
171 by Jelmer Vernooij
Initial work on a preferences dialog in GTK+, including a list of plugins with metadata browser.
380
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
381
        dialog = PreferencesWindow()
382
        dialog.run()
383
384
175 by Jelmer Vernooij
Add very simple gmissing command.
385
386
class cmd_gmissing(Command):
387
    """ GTK+ missing revisions dialog.
388
389
    """
390
    takes_args = ["other_branch?"]
391
    def run(self, other_branch=None):
392
        pygtk = import_pygtk()
393
        try:
394
            import gtk
395
        except RuntimeError, e:
396
            if str(e) == "could not open display":
397
                raise NoDisplayError
398
399
        from bzrlib.plugins.gtk.missing import MissingWindow
400
        from bzrlib.branch import Branch
401
402
        local_branch = Branch.open_containing(".")[0]
403
        if other_branch is None:
404
            other_branch = local_branch.get_parent()
405
            
406
            if other_branch is None:
407
                raise errors.BzrCommandError("No peer location known or specified.")
408
        remote_branch = Branch.open_containing(other_branch)[0]
409
        set_ui_factory()
410
        local_branch.lock_read()
411
        try:
412
            remote_branch.lock_read()
413
            try:
414
                dialog = MissingWindow(local_branch, remote_branch)
415
                dialog.run()
416
            finally:
417
                remote_branch.unlock()
418
        finally:
419
            local_branch.unlock()
420
177 by Jelmer Vernooij
Register commands all at once.
421
188.1.1 by Szilveszter Farkas (Phanatic)
Inital implementation of the Initialize dialog. Not fully functional yet.
422
class cmd_ginit(GTKCommand):
423
    def run(self):
424
        self.open_display()
425
        from initialize import InitDialog
426
        dialog = InitDialog(os.path.abspath(os.path.curdir))
427
        dialog.run()
428
429
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
430
class cmd_gtags(GTKCommand):
431
    def run(self):
432
        br = branch.Branch.open_containing('.')[0]
433
        
434
        gtk = self.open_display()
435
        from tags import TagsWindow
436
        window = TagsWindow(br)
437
        window.show()
438
        gtk.main()
439
440
177 by Jelmer Vernooij
Register commands all at once.
441
commands = [
442
    cmd_gmissing, 
443
    cmd_gpreferences, 
444
    cmd_gconflicts, 
445
    cmd_gstatus,
446
    cmd_gcommit, 
447
    cmd_gannotate, 
448
    cmd_visualise, 
449
    cmd_gdiff,
450
    cmd_gpush, 
451
    cmd_gcheckout, 
188.1.1 by Szilveszter Farkas (Phanatic)
Inital implementation of the Initialize dialog. Not fully functional yet.
452
    cmd_gbranch,
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
453
    cmd_ginit,
454
    cmd_gtags
177 by Jelmer Vernooij
Register commands all at once.
455
    ]
456
457
for cmd in commands:
458
    register_command(cmd)
175 by Jelmer Vernooij
Add very simple gmissing command.
459
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
460
173.1.3 by Robert Collins
Add new command 'commit-notify' to listen for commits on dbus and show them via pynotify.
461
class cmd_commit_notify(GTKCommand):
462
    """Run the bzr commit notifier.
463
464
    This is a background program which will pop up a notification on the users
465
    screen when a commit occurs.
466
    """
467
468
    def run(self):
469
        gtk = self.open_display()
470
        import cgi
471
        import dbus
472
        import dbus.service
473
        import pynotify
474
        from bzrlib.bzrdir import BzrDir
475
        from bzrlib import errors
476
        from bzrlib.osutils import format_date
477
        from bzrlib.transport import get_transport
478
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
479
            import dbus.glib
480
        from bzrlib.plugins.dbus import activity
481
        bus = dbus.SessionBus()
482
        # get the object so we can subscribe to callbacks from it.
483
        broadcast_service = bus.get_object(
484
            activity.Broadcast.DBUS_NAME,
485
            activity.Broadcast.DBUS_PATH)
182.1.1 by Robert Collins
Update commit-notify to use new dbus api, and show remote URL's.
486
        def catch_branch(revision_id, urls):
487
            # TODO: show all the urls, or perhaps choose the 'best'.
488
            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.
489
            try:
490
                if isinstance(revision_id, unicode):
491
                    revision_id = revision_id.encode('utf8')
492
                transport = get_transport(url)
493
                a_dir = BzrDir.open_from_transport(transport)
494
                branch = a_dir.open_branch()
495
                revno = branch.revision_id_to_revno(revision_id)
496
                revision = branch.repository.get_revision(revision_id)
497
                summary = 'New revision %d in %s' % (revno, url)
498
                body  = 'Committer: %s\n' % revision.committer
499
                body += 'Date: %s\n' % format_date(revision.timestamp,
500
                    revision.timezone)
501
                body += '\n'
502
                body += revision.message
503
                body = cgi.escape(body)
504
                nw = pynotify.Notification(summary, body)
505
                nw.set_timeout(5000)
506
                nw.show()
507
            except Exception, e:
508
                print e
509
                raise
510
        broadcast_service.connect_to_signal("Revision", catch_branch,
511
            dbus_interface=activity.Broadcast.DBUS_INTERFACE)
512
        pynotify.init("bzr commit-notify")
513
        gtk.main()
514
515
register_command(cmd_commit_notify)
516
517
152 by Jelmer Vernooij
Cleanup some more code.
518
import gettext
519
gettext.install('olive-gtk')
520
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
521
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
522
class NoDisplayError(BzrCommandError):
523
    """gtk could not find a proper display"""
524
525
    def __str__(self):
133 by Jelmer Vernooij
Actually use the ui factory.
526
        return "No DISPLAY. Unable to run GTK+ application."
527
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
528
140 by Jelmer Vernooij
add framework for tests.
529
def test_suite():
530
    from unittest import TestSuite
531
    import tests
163 by Aaron Bentley
Prevent test suite from causing default-encoding changes
532
    import sys
533
    default_encoding = sys.getdefaultencoding()
534
    try:
535
        result = TestSuite()
536
        result.addTest(tests.test_suite())
537
    finally:
170.1.2 by Aaron Bentley
Test suite only fixes encoding if it's changed. Fixes test_selftest bug.
538
        if sys.getdefaultencoding() != default_encoding:
539
            reload(sys)
540
            sys.setdefaultencoding(default_encoding)
140 by Jelmer Vernooij
add framework for tests.
541
    return result