/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
    branch.lock_read()
229
    pp = BranchWindow()
230
    pp.set_branch(branch, revision, limit)
231
    # cleanup locks when the window is closed
232
    pp.connect("destroy", lambda w: branch.unlock())
233
    return pp
234
235
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
236
class cmd_visualise(Command):
237
    """Graphically visualise this branch.
238
239
    Opens a graphical window to allow you to see the history of the branch
240
    and relationships between revisions in a visual manner,
241
242
    The default starting point is latest revision on the branch, you can
243
    specify a starting point with -r revision.
244
    """
245
    takes_options = [
246
        "revision",
208.2.7 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
247
        Option('limit', "Maximum number of revisions to display.",
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
248
               int, 'count')]
249
    takes_args = [ "location?" ]
250
    aliases = [ "visualize", "vis", "viz" ]
251
252
    def run(self, location=".", revision=None, limit=None):
133 by Jelmer Vernooij
Actually use the ui factory.
253
        set_ui_factory()
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
254
        (br, path) = branch.Branch.open_containing(location)
255
        br.lock_read()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
256
        try:
257
            if revision is None:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
258
                revid = br.last_revision()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
259
                if revid is None:
260
                    return
261
            else:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
262
                (revno, revid) = revision[0].in_history(br)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
263
152 by Jelmer Vernooij
Cleanup some more code.
264
            import gtk
208.2.2 by Robert Collins
Add inspect window to bzr commity-notify.
265
            pp = start_viz_window(br, revid, limit)
152 by Jelmer Vernooij
Cleanup some more code.
266
            pp.connect("destroy", lambda w: gtk.main_quit())
267
            pp.show()
268
            gtk.main()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
269
        finally:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
270
            br.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
271
272
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
273
class cmd_gannotate(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
274
    """GTK+ annotate.
275
    
276
    Browse changes to FILENAME line by line in a GTK+ window.
277
    """
278
59.2.1 by Aaron Bentley
Gannotate takes a line number
279
    takes_args = ["filename", "line?"]
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
280
    takes_options = [
208.2.7 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
281
        Option("all", help="Show annotations on all lines."),
282
        Option("plain", help="Don't highlight annotation lines."),
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
283
        Option("line", type=int, argname="lineno",
208.2.7 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
284
               help="Jump to specified line number."),
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
285
        "revision",
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
286
    ]
287
    aliases = ["gblame", "gpraise"]
288
    
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
289
    def run(self, filename, all=False, plain=False, line='1', revision=None):
187 by Jelmer Vernooij
Fix gannotate.
290
        gtk = self.open_display()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
291
59.2.1 by Aaron Bentley
Gannotate takes a line number
292
        try:
293
            line = int(line)
294
        except ValueError:
295
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
296
                                  line)
297
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
298
        from annotate.gannotate import GAnnotateWindow
299
        from annotate.config import GAnnotateConfig
177 by Jelmer Vernooij
Register commands all at once.
300
        from bzrlib.bzrdir import BzrDir
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
301
161 by Aaron Bentley
Fix gannotate interaction with dirstate
302
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
303
        if wt is not None:
304
            tree = wt
305
        else:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
306
            tree = br.basis_tree()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
307
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
308
        file_id = tree.path2id(path)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
309
310
        if file_id is None:
311
            raise NotVersionedError(filename)
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
312
        if revision is not None:
313
            if len(revision) != 1:
314
                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
315
            revision_id = revision[0].in_history(br).rev_id
316
            tree = br.repository.revision_tree(revision_id)
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
317
        else:
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
318
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
319
320
        window = GAnnotateWindow(all, plain)
321
        window.connect("destroy", lambda w: gtk.main_quit())
322
        window.set_title(path + " - gannotate")
323
        config = GAnnotateConfig(window)
324
        window.show()
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
325
        br.lock_read()
161 by Aaron Bentley
Fix gannotate interaction with dirstate
326
        if wt is not None:
327
            wt.lock_read()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
328
        try:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
329
            window.annotate(tree, br, file_id)
161 by Aaron Bentley
Fix gannotate interaction with dirstate
330
            window.jump_to_line(line)
331
            gtk.main()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
332
        finally:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
333
            br.unlock()
161 by Aaron Bentley
Fix gannotate interaction with dirstate
334
            if wt is not None:
335
                wt.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
336
337
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
338
339
class cmd_gcommit(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
340
    """GTK+ commit dialog
341
342
    Graphical user interface for committing revisions"""
343
    
145 by Jelmer Vernooij
Fix some strings, import.
344
    aliases = [ "gci" ]
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
345
    takes_args = []
346
    takes_options = []
347
348
    def run(self, filename=None):
93.1.17 by Alexander Belchenko
gcommit reworked again.
349
        import os
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
350
        self.open_display()
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
351
        from commit import CommitDialog
93.1.17 by Alexander Belchenko
gcommit reworked again.
352
        from bzrlib.errors import (BzrCommandError,
353
                                   NotBranchError,
178 by Jelmer Vernooij
Remove unneeded imports.
354
                                   NoWorkingTree)
93.1.17 by Alexander Belchenko
gcommit reworked again.
355
356
        wt = None
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
357
        br = None
93.1.17 by Alexander Belchenko
gcommit reworked again.
358
        try:
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
359
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
360
            br = wt.branch
93.1.17 by Alexander Belchenko
gcommit reworked again.
361
        except NoWorkingTree, e:
362
            path = e.base
195.2.1 by Szilveszter Farkas (Phanatic)
NotBranchError exception shouldn't be handled. (Fixes: #113394)
363
            (br, path) = branch.Branch.open_containing(path)
93.1.17 by Alexander Belchenko
gcommit reworked again.
364
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
365
        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'.
366
        commit.run()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
367
368
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
369
250 by Aaron Bentley
oops- revert status change
370
class cmd_gstatus(GTKCommand):
157 by Jelmer Vernooij
Add gstatus command.
371
    """GTK+ status dialog
372
373
    Graphical user interface for showing status 
374
    information."""
375
    
376
    aliases = [ "gst" ]
377
    takes_args = ['PATH?']
378
    takes_options = []
379
380
    def run(self, path='.'):
381
        import os
184 by Jelmer Vernooij
Fix gstatus
382
        gtk = self.open_display()
157 by Jelmer Vernooij
Add gstatus command.
383
        from status import StatusDialog
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
384
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
157 by Jelmer Vernooij
Add gstatus command.
385
        status = StatusDialog(wt, wt_path)
386
        status.connect("destroy", gtk.main_quit)
387
        status.run()
388
389
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
390
391
class cmd_gconflicts(GTKCommand):
242.1.2 by Adeodato Simó
Fix gconflicts docstring.
392
    """ GTK+ conflicts.
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
393
    
242.1.2 by Adeodato Simó
Fix gconflicts docstring.
394
    Select files from the list of conflicts and run an external utility to
395
    resolve them.
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
396
    """
397
    def run(self):
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
398
        (wt, path) = workingtree.WorkingTree.open_containing('.')
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
399
        self.open_display()
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
400
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
401
        dialog = ConflictsDialog(wt)
402
        dialog.run()
403
157 by Jelmer Vernooij
Add gstatus command.
404
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
405
406
class cmd_gpreferences(GTKCommand):
171 by Jelmer Vernooij
Initial work on a preferences dialog in GTK+, including a list of plugins with metadata browser.
407
    """ GTK+ preferences dialog.
408
409
    """
410
    def run(self):
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
411
        self.open_display()
171 by Jelmer Vernooij
Initial work on a preferences dialog in GTK+, including a list of plugins with metadata browser.
412
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
413
        dialog = PreferencesWindow()
414
        dialog.run()
415
416
175 by Jelmer Vernooij
Add very simple gmissing command.
417
418
class cmd_gmissing(Command):
419
    """ GTK+ missing revisions dialog.
420
421
    """
422
    takes_args = ["other_branch?"]
423
    def run(self, other_branch=None):
424
        pygtk = import_pygtk()
425
        try:
426
            import gtk
427
        except RuntimeError, e:
428
            if str(e) == "could not open display":
429
                raise NoDisplayError
430
431
        from bzrlib.plugins.gtk.missing import MissingWindow
432
        from bzrlib.branch import Branch
433
434
        local_branch = Branch.open_containing(".")[0]
435
        if other_branch is None:
436
            other_branch = local_branch.get_parent()
437
            
438
            if other_branch is None:
439
                raise errors.BzrCommandError("No peer location known or specified.")
440
        remote_branch = Branch.open_containing(other_branch)[0]
441
        set_ui_factory()
442
        local_branch.lock_read()
443
        try:
444
            remote_branch.lock_read()
445
            try:
446
                dialog = MissingWindow(local_branch, remote_branch)
447
                dialog.run()
448
            finally:
449
                remote_branch.unlock()
450
        finally:
451
            local_branch.unlock()
452
177 by Jelmer Vernooij
Register commands all at once.
453
188.1.1 by Szilveszter Farkas (Phanatic)
Inital implementation of the Initialize dialog. Not fully functional yet.
454
class cmd_ginit(GTKCommand):
455
    def run(self):
456
        self.open_display()
457
        from initialize import InitDialog
458
        dialog = InitDialog(os.path.abspath(os.path.curdir))
459
        dialog.run()
460
461
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
462
class cmd_gtags(GTKCommand):
463
    def run(self):
464
        br = branch.Branch.open_containing('.')[0]
465
        
466
        gtk = self.open_display()
467
        from tags import TagsWindow
468
        window = TagsWindow(br)
469
        window.show()
470
        gtk.main()
471
472
177 by Jelmer Vernooij
Register commands all at once.
473
commands = [
474
    cmd_gmissing, 
475
    cmd_gpreferences, 
476
    cmd_gconflicts, 
477
    cmd_gstatus,
478
    cmd_gcommit, 
479
    cmd_gannotate, 
480
    cmd_visualise, 
481
    cmd_gdiff,
482
    cmd_gpush, 
483
    cmd_gcheckout, 
188.1.1 by Szilveszter Farkas (Phanatic)
Inital implementation of the Initialize dialog. Not fully functional yet.
484
    cmd_gbranch,
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
485
    cmd_ginit,
486
    cmd_gtags
177 by Jelmer Vernooij
Register commands all at once.
487
    ]
488
489
for cmd in commands:
490
    register_command(cmd)
175 by Jelmer Vernooij
Add very simple gmissing command.
491
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
492
173.1.3 by Robert Collins
Add new command 'commit-notify' to listen for commits on dbus and show them via pynotify.
493
class cmd_commit_notify(GTKCommand):
494
    """Run the bzr commit notifier.
495
496
    This is a background program which will pop up a notification on the users
497
    screen when a commit occurs.
498
    """
499
500
    def run(self):
211 by Jelmer Vernooij
Move notification area code into separate file.
501
        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.
502
        gtk = self.open_display()
211 by Jelmer Vernooij
Move notification area code into separate file.
503
        menu = NotifyPopupMenu()
247 by Jelmer Vernooij
Use application path to find icons.
504
        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.
505
        icon.connect('popup-menu', menu.display)
210 by Jelmer Vernooij
Add notification area icon for commit-notify.
506
173.1.3 by Robert Collins
Add new command 'commit-notify' to listen for commits on dbus and show them via pynotify.
507
        import cgi
508
        import dbus
509
        import dbus.service
510
        import pynotify
511
        from bzrlib.bzrdir import BzrDir
512
        from bzrlib import errors
513
        from bzrlib.osutils import format_date
514
        from bzrlib.transport import get_transport
515
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
516
            import dbus.glib
517
        from bzrlib.plugins.dbus import activity
518
        bus = dbus.SessionBus()
519
        # get the object so we can subscribe to callbacks from it.
520
        broadcast_service = bus.get_object(
521
            activity.Broadcast.DBUS_NAME,
522
            activity.Broadcast.DBUS_PATH)
211 by Jelmer Vernooij
Move notification area code into separate file.
523
182.1.1 by Robert Collins
Update commit-notify to use new dbus api, and show remote URL's.
524
        def catch_branch(revision_id, urls):
525
            # TODO: show all the urls, or perhaps choose the 'best'.
526
            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.
527
            try:
528
                if isinstance(revision_id, unicode):
529
                    revision_id = revision_id.encode('utf8')
530
                transport = get_transport(url)
531
                a_dir = BzrDir.open_from_transport(transport)
532
                branch = a_dir.open_branch()
533
                revno = branch.revision_id_to_revno(revision_id)
534
                revision = branch.repository.get_revision(revision_id)
535
                summary = 'New revision %d in %s' % (revno, url)
536
                body  = 'Committer: %s\n' % revision.committer
537
                body += 'Date: %s\n' % format_date(revision.timestamp,
538
                    revision.timezone)
539
                body += '\n'
540
                body += revision.message
541
                body = cgi.escape(body)
542
                nw = pynotify.Notification(summary, body)
208.2.2 by Robert Collins
Add inspect window to bzr commity-notify.
543
                def start_viz(notification=None, action=None, data=None):
544
                    """Start the viz program."""
545
                    pp = start_viz_window(branch, revision_id)
546
                    pp.show()
208.2.3 by Robert Collins
Add a Branch button to commit-notify.
547
                def start_branch(notification=None, action=None, data=None):
548
                    """Start a Branch dialog"""
549
                    from bzrlib.plugins.gtk.branch import BranchDialog
550
                    bd = BranchDialog(remote_path=url)
551
                    bd.run()
208.2.4 by Robert Collins
Unbreak inspect of commits due to misunderstanding of pynotify api.
552
                nw.add_action("inspect", "Inspect", start_viz, None)
553
                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.
554
                nw.set_timeout(5000)
555
                nw.show()
556
            except Exception, e:
557
                print e
558
                raise
559
        broadcast_service.connect_to_signal("Revision", catch_branch,
560
            dbus_interface=activity.Broadcast.DBUS_INTERFACE)
561
        pynotify.init("bzr commit-notify")
562
        gtk.main()
563
564
register_command(cmd_commit_notify)
565
566
249 by Aaron Bentley
Add gselftest command
567
class cmd_gselftest(GTKCommand):
568
    """Version of selftest that displays a notification at the end"""
569
570
    takes_args = builtins.cmd_selftest.takes_args
571
    takes_options = builtins.cmd_selftest.takes_options
572
    _see_also = ['selftest']
573
574
    def run(self, *args, **kwargs):
575
        import cgi
253 by Aaron Bentley
Avoid encoding problems from pygtk
576
        import sys
577
        default_encoding = sys.getdefaultencoding()
249 by Aaron Bentley
Add gselftest command
578
        # prevent gtk from blowing up later
579
        gtk = import_pygtk()
253 by Aaron Bentley
Avoid encoding problems from pygtk
580
        # prevent gtk from messing with default encoding
249 by Aaron Bentley
Add gselftest command
581
        import pynotify
253 by Aaron Bentley
Avoid encoding problems from pygtk
582
        if sys.getdefaultencoding() != default_encoding:
583
            reload(sys)
584
            sys.setdefaultencoding(default_encoding)
249 by Aaron Bentley
Add gselftest command
585
        result = builtins.cmd_selftest().run(*args, **kwargs)
586
        if result == 0:
587
            summary = 'Success'
588
            body = 'Selftest succeeded in "%s"' % os.getcwd()
589
        if result == 1:
590
            summary = 'Failure'
591
            body = 'Selftest failed in "%s"' % os.getcwd()
592
        pynotify.init("bzr gselftest")
593
        note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
594
        note.set_timeout(pynotify.EXPIRES_NEVER)
595
        note.show()
596
597
598
register_command(cmd_gselftest)
599
600
152 by Jelmer Vernooij
Cleanup some more code.
601
import gettext
602
gettext.install('olive-gtk')
603
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
604
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
605
class NoDisplayError(BzrCommandError):
606
    """gtk could not find a proper display"""
607
608
    def __str__(self):
133 by Jelmer Vernooij
Actually use the ui factory.
609
        return "No DISPLAY. Unable to run GTK+ application."
610
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
611
140 by Jelmer Vernooij
add framework for tests.
612
def test_suite():
613
    from unittest import TestSuite
614
    import tests
163 by Aaron Bentley
Prevent test suite from causing default-encoding changes
615
    import sys
616
    default_encoding = sys.getdefaultencoding()
617
    try:
618
        result = TestSuite()
619
        result.addTest(tests.test_suite())
620
    finally:
170.1.2 by Aaron Bentley
Test suite only fixes encoding if it's changed. Fixes test_selftest bug.
621
        if sys.getdefaultencoding() != default_encoding:
622
            reload(sys)
623
            sys.setdefaultencoding(default_encoding)
140 by Jelmer Vernooij
add framework for tests.
624
    return result