/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
208.2.1 by Robert Collins
Better module docstring.
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 
242.1.2 by Adeodato Simó
Fix gconflicts docstring.
23
gconflicts        GTK+ conflicts. 
208.2.1 by Robert Collins
Better module docstring.
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
gstatus           GTK+ status dialog 
30
gtags             Manage branch tags.
31
visualise         Graphically visualise this branch. 
32
"""
73 by Jelmer Vernooij
Release 0.9, list myself as maintainer.
33
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
34
import bzrlib
35
287 by Jelmer Vernooij
Use standard version tuple.
36
version_info = (0, 92, 0, 'dev', 0)
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
37
287 by Jelmer Vernooij
Use standard version tuple.
38
if version_info[3] == 'final':
39
    version_string = '%d.%d.%d' % version_info[:3]
40
else:
41
    version_string = '%d.%d.%d%s%d' % version_info
42
__version__ = version_string
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
43
44
def check_bzrlib_version(desired):
45
    """Check that bzrlib is compatible.
46
47
    If version is < bzr-gtk version, assume incompatible.
48
    If version == bzr-gtk version, assume completely compatible
49
    If version == bzr-gtk version + 1, assume compatible, with deprecations
50
    Otherwise, assume incompatible.
51
    """
52
    desired_plus = (desired[0], desired[1]+1)
53
    bzrlib_version = bzrlib.version_info[:2]
203 by Aaron Bentley
Don't warn if bzrlib is dev version of next release
54
    if bzrlib_version == desired or (bzrlib_version == desired_plus and
55
                                     bzrlib.version_info[3] == 'dev'):
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
56
        return
57
    try:
58
        from bzrlib.trace import warning
59
    except ImportError:
60
        # get the message out any way we can
61
        from warnings import warn as warning
62
    if bzrlib_version < desired:
207 by Aaron Bentley
Import BzrError before using it
63
        from bzrlib.errors import BzrError
271 by Jelmer Vernooij
Add common widget for selecting branches.
64
        warning('Installed Bazaar version %s is too old to be used with bzr-gtk'
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
65
                ' %s.' % (bzrlib.__version__, __version__))
287 by Jelmer Vernooij
Use standard version tuple.
66
        raise BzrError('Version mismatch: %r, %r' % (version_info, bzrlib.version_info) )
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
67
    else:
68
        warning('bzr-gtk is not up to date with installed bzr version %s.'
69
                ' \nThere should be a newer version available, e.g. %i.%i.' 
70
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
71
72
287 by Jelmer Vernooij
Use standard version tuple.
73
if version_info[2] == "final":
74
    check_bzrlib_version(version_info[:2])
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
75
146 by Jelmer Vernooij
Move more code to top-level directory.
76
from bzrlib.trace import warning
77
if __name__ != 'bzrlib.plugins.gtk':
78
    warning("Not running as bzrlib.plugins.gtk, things may break.")
79
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
80
from bzrlib.lazy_import import lazy_import
81
lazy_import(globals(), """
82
from bzrlib import (
83
    branch,
249 by Aaron Bentley
Add gselftest command
84
    builtins,
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
85
    errors,
86
    workingtree,
87
    )
88
""")
89
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
90
from bzrlib.commands import Command, register_command, display_command
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
91
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
92
from bzrlib.option import Option
93
126.1.5 by Szilveszter Farkas (Phanatic)
bzr gbranch should work now (Fixed: #77751)
94
import os.path
95
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
96
def import_pygtk():
97
    try:
98
        import pygtk
99
    except ImportError:
100
        raise errors.BzrCommandError("PyGTK not installed.")
101
    pygtk.require('2.0')
102
    return pygtk
103
104
133 by Jelmer Vernooij
Actually use the ui factory.
105
def set_ui_factory():
177 by Jelmer Vernooij
Register commands all at once.
106
    import_pygtk()
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
107
    from ui import GtkUIFactory
133 by Jelmer Vernooij
Actually use the ui factory.
108
    import bzrlib.ui
109
    bzrlib.ui.ui_factory = GtkUIFactory()
110
111
247 by Jelmer Vernooij
Use application path to find icons.
112
def data_path():
113
    return os.path.dirname(__file__)
114
115
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
116
class GTKCommand(Command):
117
    """Abstract class providing GTK specific run commands."""
118
119
    def open_display(self):
120
        pygtk = import_pygtk()
121
        try:
122
            import gtk
123
        except RuntimeError, e:
124
            if str(e) == "could not open display":
125
                raise NoDisplayError
126
        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.
127
        return gtk
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
128
129
    def run(self):
130
        self.open_display()
131
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
132
        dialog.run()
133
134
135
class cmd_gbranch(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
136
    """GTK+ branching.
137
    
138
    """
139
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
140
    def get_gtk_dialog(self, path):
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
141
        from bzrlib.plugins.gtk.branch import BranchDialog
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
142
        return BranchDialog(path)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
143
144
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
145
class cmd_gcheckout(GTKCommand):
126.1.18 by Szilveszter Farkas (Phanatic)
Improved Branch dialog. Refactored Checkout dialog.
146
    """ GTK+ checkout.
147
    
148
    """
149
    
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
150
    def get_gtk_dialog(self, path):
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
151
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
152
        return CheckoutDialog(path)
126.1.18 by Szilveszter Farkas (Phanatic)
Improved Branch dialog. Refactored Checkout dialog.
153
154
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
155
156
class cmd_gpush(GTKCommand):
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
157
    """ GTK+ push.
158
    
159
    """
160
    takes_args = [ "location?" ]
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
161
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
162
    def run(self, location="."):
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
163
        (br, path) = branch.Branch.open_containing(location)
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
164
        self.open_display()
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
165
        from push import PushDialog
233 by Jelmer Vernooij
Get rid of test button in push.
166
        dialog = PushDialog(br.repository, br.last_revision(), br)
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
167
        dialog.run()
168
169
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
170
171
class cmd_gdiff(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
172
    """Show differences in working tree in a GTK+ Window.
173
    
174
    Otherwise, all changes for the tree are listed.
175
    """
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
176
    takes_args = ['filename?']
58.1.1 by Aaron Bentley
gdiff takes -r arguments
177
    takes_options = ['revision']
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
178
179
    @display_command
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
180
    def run(self, revision=None, filename=None):
133 by Jelmer Vernooij
Actually use the ui factory.
181
        set_ui_factory()
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
182
        wt = workingtree.WorkingTree.open_containing(".")[0]
161 by Aaron Bentley
Fix gannotate interaction with dirstate
183
        wt.lock_read()
184
        try:
185
            branch = wt.branch
186
            if revision is not None:
187
                if len(revision) == 1:
188
                    tree1 = wt
189
                    revision_id = revision[0].in_history(branch).rev_id
190
                    tree2 = branch.repository.revision_tree(revision_id)
191
                elif len(revision) == 2:
192
                    revision_id_0 = revision[0].in_history(branch).rev_id
193
                    tree2 = branch.repository.revision_tree(revision_id_0)
194
                    revision_id_1 = revision[1].in_history(branch).rev_id
195
                    tree1 = branch.repository.revision_tree(revision_id_1)
196
            else:
58.1.1 by Aaron Bentley
gdiff takes -r arguments
197
                tree1 = wt
161 by Aaron Bentley
Fix gannotate interaction with dirstate
198
                tree2 = tree1.basis_tree()
199
200
            from diff import DiffWindow
201
            import gtk
202
            window = DiffWindow()
203
            window.connect("destroy", gtk.main_quit)
204
            window.set_diff("Working Tree", tree1, tree2)
205
            if filename is not None:
206
                tree_filename = wt.relpath(filename)
207
                try:
208
                    window.set_file(tree_filename)
209
                except NoSuchFile:
188.3.1 by John Arbash Meinel
Use tree.path2id to avoid getting 'Object Not Locked' errors.
210
                    if (tree1.path2id(tree_filename) is None and 
211
                        tree2.path2id(tree_filename) is None):
161 by Aaron Bentley
Fix gannotate interaction with dirstate
212
                        raise NotVersionedError(filename)
213
                    raise BzrCommandError('No changes found for file "%s"' % 
214
                                          filename)
215
            window.show()
216
217
            gtk.main()
218
        finally:
219
            wt.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
220
221
208.2.2 by Robert Collins
Add inspect window to bzr commity-notify.
222
def start_viz_window(branch, revision, limit=None):
223
    """Start viz on branch with revision revision.
224
    
225
    :return: The viz window object.
226
    """
227
    from viz.branchwin import BranchWindow
228
    pp = BranchWindow()
229
    pp.set_branch(branch, revision, limit)
230
    # cleanup locks when the window is closed
231
    return pp
232
233
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
234
class cmd_visualise(Command):
235
    """Graphically visualise this branch.
236
237
    Opens a graphical window to allow you to see the history of the branch
238
    and relationships between revisions in a visual manner,
239
240
    The default starting point is latest revision on the branch, you can
241
    specify a starting point with -r revision.
242
    """
243
    takes_options = [
244
        "revision",
208.2.7 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
245
        Option('limit', "Maximum number of revisions to display.",
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
246
               int, 'count')]
247
    takes_args = [ "location?" ]
248
    aliases = [ "visualize", "vis", "viz" ]
249
250
    def run(self, location=".", revision=None, limit=None):
133 by Jelmer Vernooij
Actually use the ui factory.
251
        set_ui_factory()
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
252
        (br, path) = branch.Branch.open_containing(location)
253
        br.lock_read()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
254
        try:
255
            if revision is None:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
256
                revid = br.last_revision()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
257
                if revid is None:
258
                    return
259
            else:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
260
                (revno, revid) = revision[0].in_history(br)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
261
152 by Jelmer Vernooij
Cleanup some more code.
262
            import gtk
208.2.2 by Robert Collins
Add inspect window to bzr commity-notify.
263
            pp = start_viz_window(br, revid, limit)
152 by Jelmer Vernooij
Cleanup some more code.
264
            pp.connect("destroy", lambda w: gtk.main_quit())
265
            pp.show()
266
            gtk.main()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
267
        finally:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
268
            br.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
269
270
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
271
class cmd_gannotate(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
272
    """GTK+ annotate.
273
    
274
    Browse changes to FILENAME line by line in a GTK+ window.
275
    """
276
59.2.1 by Aaron Bentley
Gannotate takes a line number
277
    takes_args = ["filename", "line?"]
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
278
    takes_options = [
208.2.7 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
279
        Option("all", help="Show annotations on all lines."),
280
        Option("plain", help="Don't highlight annotation lines."),
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
281
        Option("line", type=int, argname="lineno",
208.2.7 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
282
               help="Jump to specified line number."),
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
283
        "revision",
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
284
    ]
285
    aliases = ["gblame", "gpraise"]
286
    
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
287
    def run(self, filename, all=False, plain=False, line='1', revision=None):
187 by Jelmer Vernooij
Fix gannotate.
288
        gtk = self.open_display()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
289
59.2.1 by Aaron Bentley
Gannotate takes a line number
290
        try:
291
            line = int(line)
292
        except ValueError:
293
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
294
                                  line)
295
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
296
        from annotate.gannotate import GAnnotateWindow
297
        from annotate.config import GAnnotateConfig
177 by Jelmer Vernooij
Register commands all at once.
298
        from bzrlib.bzrdir import BzrDir
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
299
161 by Aaron Bentley
Fix gannotate interaction with dirstate
300
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
301
        if wt is not None:
302
            tree = wt
303
        else:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
304
            tree = br.basis_tree()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
305
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
306
        file_id = tree.path2id(path)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
307
308
        if file_id is None:
309
            raise NotVersionedError(filename)
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
310
        if revision is not None:
311
            if len(revision) != 1:
312
                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
313
            revision_id = revision[0].in_history(br).rev_id
314
            tree = br.repository.revision_tree(revision_id)
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
315
        else:
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
316
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
317
318
        window = GAnnotateWindow(all, plain)
319
        window.connect("destroy", lambda w: gtk.main_quit())
320
        window.set_title(path + " - gannotate")
321
        config = GAnnotateConfig(window)
322
        window.show()
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
323
        br.lock_read()
161 by Aaron Bentley
Fix gannotate interaction with dirstate
324
        if wt is not None:
325
            wt.lock_read()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
326
        try:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
327
            window.annotate(tree, br, file_id)
161 by Aaron Bentley
Fix gannotate interaction with dirstate
328
            window.jump_to_line(line)
329
            gtk.main()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
330
        finally:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
331
            br.unlock()
161 by Aaron Bentley
Fix gannotate interaction with dirstate
332
            if wt is not None:
333
                wt.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
334
335
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
336
337
class cmd_gcommit(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
338
    """GTK+ commit dialog
339
340
    Graphical user interface for committing revisions"""
341
    
145 by Jelmer Vernooij
Fix some strings, import.
342
    aliases = [ "gci" ]
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
343
    takes_args = []
344
    takes_options = []
345
346
    def run(self, filename=None):
93.1.17 by Alexander Belchenko
gcommit reworked again.
347
        import os
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
348
        self.open_display()
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
349
        from commit import CommitDialog
93.1.17 by Alexander Belchenko
gcommit reworked again.
350
        from bzrlib.errors import (BzrCommandError,
351
                                   NotBranchError,
178 by Jelmer Vernooij
Remove unneeded imports.
352
                                   NoWorkingTree)
93.1.17 by Alexander Belchenko
gcommit reworked again.
353
354
        wt = None
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
355
        br = None
93.1.17 by Alexander Belchenko
gcommit reworked again.
356
        try:
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
357
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
358
            br = wt.branch
93.1.17 by Alexander Belchenko
gcommit reworked again.
359
        except NoWorkingTree, e:
360
            path = e.base
195.2.1 by Szilveszter Farkas (Phanatic)
NotBranchError exception shouldn't be handled. (Fixes: #113394)
361
            (br, path) = branch.Branch.open_containing(path)
93.1.17 by Alexander Belchenko
gcommit reworked again.
362
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
363
        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'.
364
        commit.run()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
365
366
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
367
250 by Aaron Bentley
oops- revert status change
368
class cmd_gstatus(GTKCommand):
157 by Jelmer Vernooij
Add gstatus command.
369
    """GTK+ status dialog
370
371
    Graphical user interface for showing status 
372
    information."""
373
    
374
    aliases = [ "gst" ]
375
    takes_args = ['PATH?']
376
    takes_options = []
377
378
    def run(self, path='.'):
379
        import os
184 by Jelmer Vernooij
Fix gstatus
380
        gtk = self.open_display()
157 by Jelmer Vernooij
Add gstatus command.
381
        from status import StatusDialog
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
382
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
157 by Jelmer Vernooij
Add gstatus command.
383
        status = StatusDialog(wt, wt_path)
384
        status.connect("destroy", gtk.main_quit)
385
        status.run()
386
387
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
388
389
class cmd_gconflicts(GTKCommand):
242.1.2 by Adeodato Simó
Fix gconflicts docstring.
390
    """ GTK+ conflicts.
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
391
    
242.1.2 by Adeodato Simó
Fix gconflicts docstring.
392
    Select files from the list of conflicts and run an external utility to
393
    resolve them.
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
394
    """
395
    def run(self):
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
396
        (wt, path) = workingtree.WorkingTree.open_containing('.')
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
397
        self.open_display()
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
398
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
399
        dialog = ConflictsDialog(wt)
400
        dialog.run()
401
157 by Jelmer Vernooij
Add gstatus command.
402
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
403
404
class cmd_gpreferences(GTKCommand):
171 by Jelmer Vernooij
Initial work on a preferences dialog in GTK+, including a list of plugins with metadata browser.
405
    """ GTK+ preferences dialog.
406
407
    """
408
    def run(self):
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
409
        self.open_display()
171 by Jelmer Vernooij
Initial work on a preferences dialog in GTK+, including a list of plugins with metadata browser.
410
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
411
        dialog = PreferencesWindow()
412
        dialog.run()
413
414
175 by Jelmer Vernooij
Add very simple gmissing command.
415
416
class cmd_gmissing(Command):
417
    """ GTK+ missing revisions dialog.
418
419
    """
420
    takes_args = ["other_branch?"]
421
    def run(self, other_branch=None):
422
        pygtk = import_pygtk()
423
        try:
424
            import gtk
425
        except RuntimeError, e:
426
            if str(e) == "could not open display":
427
                raise NoDisplayError
428
429
        from bzrlib.plugins.gtk.missing import MissingWindow
430
        from bzrlib.branch import Branch
431
432
        local_branch = Branch.open_containing(".")[0]
433
        if other_branch is None:
434
            other_branch = local_branch.get_parent()
435
            
436
            if other_branch is None:
437
                raise errors.BzrCommandError("No peer location known or specified.")
438
        remote_branch = Branch.open_containing(other_branch)[0]
439
        set_ui_factory()
440
        local_branch.lock_read()
441
        try:
442
            remote_branch.lock_read()
443
            try:
444
                dialog = MissingWindow(local_branch, remote_branch)
445
                dialog.run()
446
            finally:
447
                remote_branch.unlock()
448
        finally:
449
            local_branch.unlock()
450
177 by Jelmer Vernooij
Register commands all at once.
451
188.1.1 by Szilveszter Farkas (Phanatic)
Inital implementation of the Initialize dialog. Not fully functional yet.
452
class cmd_ginit(GTKCommand):
453
    def run(self):
454
        self.open_display()
455
        from initialize import InitDialog
456
        dialog = InitDialog(os.path.abspath(os.path.curdir))
457
        dialog.run()
458
459
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
460
class cmd_gtags(GTKCommand):
461
    def run(self):
462
        br = branch.Branch.open_containing('.')[0]
463
        
464
        gtk = self.open_display()
465
        from tags import TagsWindow
466
        window = TagsWindow(br)
467
        window.show()
468
        gtk.main()
469
470
177 by Jelmer Vernooij
Register commands all at once.
471
commands = [
472
    cmd_gmissing, 
473
    cmd_gpreferences, 
474
    cmd_gconflicts, 
475
    cmd_gstatus,
476
    cmd_gcommit, 
477
    cmd_gannotate, 
478
    cmd_visualise, 
479
    cmd_gdiff,
480
    cmd_gpush, 
481
    cmd_gcheckout, 
188.1.1 by Szilveszter Farkas (Phanatic)
Inital implementation of the Initialize dialog. Not fully functional yet.
482
    cmd_gbranch,
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
483
    cmd_ginit,
484
    cmd_gtags
177 by Jelmer Vernooij
Register commands all at once.
485
    ]
486
487
for cmd in commands:
488
    register_command(cmd)
175 by Jelmer Vernooij
Add very simple gmissing command.
489
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
490
173.1.3 by Robert Collins
Add new command 'commit-notify' to listen for commits on dbus and show them via pynotify.
491
class cmd_commit_notify(GTKCommand):
492
    """Run the bzr commit notifier.
493
494
    This is a background program which will pop up a notification on the users
495
    screen when a commit occurs.
496
    """
497
498
    def run(self):
211 by Jelmer Vernooij
Move notification area code into separate file.
499
        from notify import NotifyPopupMenu
173.1.3 by Robert Collins
Add new command 'commit-notify' to listen for commits on dbus and show them via pynotify.
500
        gtk = self.open_display()
211 by Jelmer Vernooij
Move notification area code into separate file.
501
        menu = NotifyPopupMenu()
247 by Jelmer Vernooij
Use application path to find icons.
502
        icon = gtk.status_icon_new_from_file(os.path.join(data_path(), "bzr-icon-64.png"))
211 by Jelmer Vernooij
Move notification area code into separate file.
503
        icon.connect('popup-menu', menu.display)
210 by Jelmer Vernooij
Add notification area icon for commit-notify.
504
173.1.3 by Robert Collins
Add new command 'commit-notify' to listen for commits on dbus and show them via pynotify.
505
        import cgi
506
        import dbus
507
        import dbus.service
508
        import pynotify
509
        from bzrlib.bzrdir import BzrDir
510
        from bzrlib import errors
511
        from bzrlib.osutils import format_date
512
        from bzrlib.transport import get_transport
513
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
514
            import dbus.glib
515
        from bzrlib.plugins.dbus import activity
516
        bus = dbus.SessionBus()
517
        # get the object so we can subscribe to callbacks from it.
518
        broadcast_service = bus.get_object(
519
            activity.Broadcast.DBUS_NAME,
520
            activity.Broadcast.DBUS_PATH)
211 by Jelmer Vernooij
Move notification area code into separate file.
521
182.1.1 by Robert Collins
Update commit-notify to use new dbus api, and show remote URL's.
522
        def catch_branch(revision_id, urls):
523
            # TODO: show all the urls, or perhaps choose the 'best'.
524
            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.
525
            try:
526
                if isinstance(revision_id, unicode):
527
                    revision_id = revision_id.encode('utf8')
528
                transport = get_transport(url)
529
                a_dir = BzrDir.open_from_transport(transport)
530
                branch = a_dir.open_branch()
531
                revno = branch.revision_id_to_revno(revision_id)
532
                revision = branch.repository.get_revision(revision_id)
533
                summary = 'New revision %d in %s' % (revno, url)
534
                body  = 'Committer: %s\n' % revision.committer
535
                body += 'Date: %s\n' % format_date(revision.timestamp,
536
                    revision.timezone)
537
                body += '\n'
538
                body += revision.message
539
                body = cgi.escape(body)
540
                nw = pynotify.Notification(summary, body)
208.2.2 by Robert Collins
Add inspect window to bzr commity-notify.
541
                def start_viz(notification=None, action=None, data=None):
542
                    """Start the viz program."""
543
                    pp = start_viz_window(branch, revision_id)
544
                    pp.show()
208.2.3 by Robert Collins
Add a Branch button to commit-notify.
545
                def start_branch(notification=None, action=None, data=None):
546
                    """Start a Branch dialog"""
547
                    from bzrlib.plugins.gtk.branch import BranchDialog
548
                    bd = BranchDialog(remote_path=url)
549
                    bd.run()
208.2.4 by Robert Collins
Unbreak inspect of commits due to misunderstanding of pynotify api.
550
                nw.add_action("inspect", "Inspect", start_viz, None)
551
                nw.add_action("branch", "Branch", start_branch, None)
173.1.3 by Robert Collins
Add new command 'commit-notify' to listen for commits on dbus and show them via pynotify.
552
                nw.set_timeout(5000)
553
                nw.show()
554
            except Exception, e:
555
                print e
556
                raise
557
        broadcast_service.connect_to_signal("Revision", catch_branch,
558
            dbus_interface=activity.Broadcast.DBUS_INTERFACE)
559
        pynotify.init("bzr commit-notify")
560
        gtk.main()
561
562
register_command(cmd_commit_notify)
563
564
249 by Aaron Bentley
Add gselftest command
565
class cmd_gselftest(GTKCommand):
566
    """Version of selftest that displays a notification at the end"""
567
568
    takes_args = builtins.cmd_selftest.takes_args
569
    takes_options = builtins.cmd_selftest.takes_options
570
    _see_also = ['selftest']
571
572
    def run(self, *args, **kwargs):
573
        import cgi
253 by Aaron Bentley
Avoid encoding problems from pygtk
574
        import sys
575
        default_encoding = sys.getdefaultencoding()
249 by Aaron Bentley
Add gselftest command
576
        # prevent gtk from blowing up later
577
        gtk = import_pygtk()
253 by Aaron Bentley
Avoid encoding problems from pygtk
578
        # prevent gtk from messing with default encoding
249 by Aaron Bentley
Add gselftest command
579
        import pynotify
253 by Aaron Bentley
Avoid encoding problems from pygtk
580
        if sys.getdefaultencoding() != default_encoding:
581
            reload(sys)
582
            sys.setdefaultencoding(default_encoding)
249 by Aaron Bentley
Add gselftest command
583
        result = builtins.cmd_selftest().run(*args, **kwargs)
584
        if result == 0:
585
            summary = 'Success'
586
            body = 'Selftest succeeded in "%s"' % os.getcwd()
587
        if result == 1:
588
            summary = 'Failure'
589
            body = 'Selftest failed in "%s"' % os.getcwd()
590
        pynotify.init("bzr gselftest")
591
        note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
592
        note.set_timeout(pynotify.EXPIRES_NEVER)
593
        note.show()
594
595
596
register_command(cmd_gselftest)
597
598
152 by Jelmer Vernooij
Cleanup some more code.
599
import gettext
600
gettext.install('olive-gtk')
601
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
602
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
603
class NoDisplayError(BzrCommandError):
604
    """gtk could not find a proper display"""
605
606
    def __str__(self):
133 by Jelmer Vernooij
Actually use the ui factory.
607
        return "No DISPLAY. Unable to run GTK+ application."
608
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
609
140 by Jelmer Vernooij
add framework for tests.
610
def test_suite():
611
    from unittest import TestSuite
612
    import tests
163 by Aaron Bentley
Prevent test suite from causing default-encoding changes
613
    import sys
614
    default_encoding = sys.getdefaultencoding()
615
    try:
616
        result = TestSuite()
617
        result.addTest(tests.test_suite())
618
    finally:
170.1.2 by Aaron Bentley
Test suite only fixes encoding if it's changed. Fixes test_selftest bug.
619
        if sys.getdefaultencoding() != default_encoding:
620
            reload(sys)
621
            sys.setdefaultencoding(default_encoding)
140 by Jelmer Vernooij
add framework for tests.
622
    return result