/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
gannotate         GTK+ annotate. 
19
gbranch           GTK+ branching. 
20
gcheckout         GTK+ checkout. 
323 by Jelmer Vernooij
Add gsend command.
21
gcommit           GTK+ commit dialog.
242.1.2 by Adeodato Simó
Fix gconflicts docstring.
22
gconflicts        GTK+ conflicts. 
208.2.1 by Robert Collins
Better module docstring.
23
gdiff             Show differences in working tree in a GTK+ Window. 
24
ginit             Initialise a new branch.
25
gmissing          GTK+ missing revisions dialog. 
26
gpreferences      GTK+ preferences dialog. 
323 by Jelmer Vernooij
Add gsend command.
27
gpush             GTK+ push.
28
gsend             GTK+ send merge directive.
29
gstatus           GTK+ status dialog.
208.2.1 by Robert Collins
Better module docstring.
30
gtags             Manage branch tags.
31
visualise         Graphically visualise this branch. 
32
"""
73 by Jelmer Vernooij
Release 0.9, list myself as maintainer.
33
278.1.22 by John Arbash Meinel
Add a test-gtk command to make testing faster
34
import sys
35
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
36
import bzrlib
37
487 by Jelmer Vernooij
Start working on 0.95.0.
38
version_info = (0, 95, 0, 'dev', 1)
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
39
287 by Jelmer Vernooij
Use standard version tuple.
40
if version_info[3] == 'final':
41
    version_string = '%d.%d.%d' % version_info[:3]
42
else:
43
    version_string = '%d.%d.%d%s%d' % version_info
44
__version__ = version_string
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
45
451.1.1 by Daniel Schierbeck
Bumped required version of bzrlib to 1.3.
46
required_bzrlib = (1, 3)
423.1.1 by Jelmer Vernooij
Allow bzr-gtk and Bazaar versions to be out of sync. No longer warn about
47
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
48
def check_bzrlib_version(desired):
49
    """Check that bzrlib is compatible.
50
51
    If version is < bzr-gtk version, assume incompatible.
52
    """
53
    bzrlib_version = bzrlib.version_info[:2]
54
    try:
55
        from bzrlib.trace import warning
56
    except ImportError:
57
        # get the message out any way we can
58
        from warnings import warn as warning
59
    if bzrlib_version < desired:
207 by Aaron Bentley
Import BzrError before using it
60
        from bzrlib.errors import BzrError
271 by Jelmer Vernooij
Add common widget for selecting branches.
61
        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).
62
                ' %s.' % (bzrlib.__version__, __version__))
287 by Jelmer Vernooij
Use standard version tuple.
63
        raise BzrError('Version mismatch: %r, %r' % (version_info, bzrlib.version_info) )
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
64
65
287 by Jelmer Vernooij
Use standard version tuple.
66
if version_info[2] == "final":
423.1.1 by Jelmer Vernooij
Allow bzr-gtk and Bazaar versions to be out of sync. No longer warn about
67
    check_bzrlib_version(required_bzrlib)
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
68
146 by Jelmer Vernooij
Move more code to top-level directory.
69
from bzrlib.trace import warning
70
if __name__ != 'bzrlib.plugins.gtk':
71
    warning("Not running as bzrlib.plugins.gtk, things may break.")
72
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
73
from bzrlib.lazy_import import lazy_import
74
lazy_import(globals(), """
75
from bzrlib import (
76
    branch,
249 by Aaron Bentley
Add gselftest command
77
    builtins,
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
78
    errors,
426 by Aaron Bentley
Start support for Merge Directives
79
    merge_directive,
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
80
    workingtree,
81
    )
82
""")
83
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
84
from bzrlib.commands import Command, register_command, display_command
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
85
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
86
from bzrlib.option import Option
87
126.1.5 by Szilveszter Farkas (Phanatic)
bzr gbranch should work now (Fixed: #77751)
88
import os.path
89
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
90
def import_pygtk():
91
    try:
92
        import pygtk
93
    except ImportError:
94
        raise errors.BzrCommandError("PyGTK not installed.")
95
    pygtk.require('2.0')
96
    return pygtk
97
98
133 by Jelmer Vernooij
Actually use the ui factory.
99
def set_ui_factory():
177 by Jelmer Vernooij
Register commands all at once.
100
    import_pygtk()
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
101
    from ui import GtkUIFactory
133 by Jelmer Vernooij
Actually use the ui factory.
102
    import bzrlib.ui
103
    bzrlib.ui.ui_factory = GtkUIFactory()
104
105
247 by Jelmer Vernooij
Use application path to find icons.
106
def data_path():
107
    return os.path.dirname(__file__)
108
109
399.1.19 by Jelmer Vernooij
Add utility function for finding icon paths.
110
def icon_path(*args):
111
    basedirs = [os.path.join(data_path()),
112
             "/usr/share/bzr-gtk", 
113
             "/usr/local/share/bzr-gtk"]
114
    for basedir in basedirs:
115
        path = os.path.join(basedir, 'icons', *args)
116
        if os.path.exists(path):
117
            return path
118
    return None
119
120
505.1.1 by Jelmer Vernooij
Make handle-patch not dependend on the users name being abentley and install it.
121
def open_display():
122
    pygtk = import_pygtk()
123
    try:
124
        import gtk
125
    except RuntimeError, e:
126
        if str(e) == "could not open display":
127
            raise NoDisplayError
128
    set_ui_factory()
129
    return gtk
130
 
131
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
132
class GTKCommand(Command):
133
    """Abstract class providing GTK specific run commands."""
134
135
    def run(self):
505.1.1 by Jelmer Vernooij
Make handle-patch not dependend on the users name being abentley and install it.
136
        open_display()
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
137
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
138
        dialog.run()
139
140
141
class cmd_gbranch(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
142
    """GTK+ branching.
143
    
144
    """
145
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
146
    def get_gtk_dialog(self, path):
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
147
        from bzrlib.plugins.gtk.branch import BranchDialog
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
148
        return BranchDialog(path)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
149
150
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
151
class cmd_gcheckout(GTKCommand):
126.1.18 by Szilveszter Farkas (Phanatic)
Improved Branch dialog. Refactored Checkout dialog.
152
    """ GTK+ checkout.
153
    
154
    """
155
    
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
156
    def get_gtk_dialog(self, path):
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
157
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
158
        return CheckoutDialog(path)
126.1.18 by Szilveszter Farkas (Phanatic)
Improved Branch dialog. Refactored Checkout dialog.
159
160
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
161
162
class cmd_gpush(GTKCommand):
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
163
    """ GTK+ push.
164
    
165
    """
166
    takes_args = [ "location?" ]
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
167
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
168
    def run(self, location="."):
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
169
        (br, path) = branch.Branch.open_containing(location)
505.1.1 by Jelmer Vernooij
Make handle-patch not dependend on the users name being abentley and install it.
170
        open_display()
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
171
        from push import PushDialog
233 by Jelmer Vernooij
Get rid of test button in push.
172
        dialog = PushDialog(br.repository, br.last_revision(), br)
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
173
        dialog.run()
174
175
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
176
177
class cmd_gdiff(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
178
    """Show differences in working tree in a GTK+ Window.
179
    
180
    Otherwise, all changes for the tree are listed.
181
    """
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
182
    takes_args = ['filename?']
58.1.1 by Aaron Bentley
gdiff takes -r arguments
183
    takes_options = ['revision']
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
184
185
    @display_command
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
186
    def run(self, revision=None, filename=None):
133 by Jelmer Vernooij
Actually use the ui factory.
187
        set_ui_factory()
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
188
        wt = workingtree.WorkingTree.open_containing(".")[0]
161 by Aaron Bentley
Fix gannotate interaction with dirstate
189
        wt.lock_read()
190
        try:
191
            branch = wt.branch
192
            if revision is not None:
193
                if len(revision) == 1:
194
                    tree1 = wt
493 by Aaron Bentley
Convert remaining uses of RevisionSpec.in_history to as_revision_id
195
                    revision_id = revision[0].as_revision_id(tree1.branch)
161 by Aaron Bentley
Fix gannotate interaction with dirstate
196
                    tree2 = branch.repository.revision_tree(revision_id)
197
                elif len(revision) == 2:
493 by Aaron Bentley
Convert remaining uses of RevisionSpec.in_history to as_revision_id
198
                    revision_id_0 = revision[0].as_revision_id(branch)
161 by Aaron Bentley
Fix gannotate interaction with dirstate
199
                    tree2 = branch.repository.revision_tree(revision_id_0)
493 by Aaron Bentley
Convert remaining uses of RevisionSpec.in_history to as_revision_id
200
                    revision_id_1 = revision[1].as_revision_id(branch)
161 by Aaron Bentley
Fix gannotate interaction with dirstate
201
                    tree1 = branch.repository.revision_tree(revision_id_1)
202
            else:
58.1.1 by Aaron Bentley
gdiff takes -r arguments
203
                tree1 = wt
161 by Aaron Bentley
Fix gannotate interaction with dirstate
204
                tree2 = tree1.basis_tree()
205
206
            from diff import DiffWindow
207
            import gtk
208
            window = DiffWindow()
209
            window.connect("destroy", gtk.main_quit)
210
            window.set_diff("Working Tree", tree1, tree2)
211
            if filename is not None:
212
                tree_filename = wt.relpath(filename)
213
                try:
214
                    window.set_file(tree_filename)
215
                except NoSuchFile:
188.3.1 by John Arbash Meinel
Use tree.path2id to avoid getting 'Object Not Locked' errors.
216
                    if (tree1.path2id(tree_filename) is None and 
217
                        tree2.path2id(tree_filename) is None):
161 by Aaron Bentley
Fix gannotate interaction with dirstate
218
                        raise NotVersionedError(filename)
219
                    raise BzrCommandError('No changes found for file "%s"' % 
220
                                          filename)
221
            window.show()
222
223
            gtk.main()
224
        finally:
225
            wt.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
226
227
452.4.1 by Jelmer Vernooij
Support displaying multiple tips in viz.
228
def start_viz_window(branch, revisions, limit=None):
208.2.2 by Robert Collins
Add inspect window to bzr commity-notify.
229
    """Start viz on branch with revision revision.
230
    
231
    :return: The viz window object.
232
    """
423.2.2 by Daniel Schierbeck
Moved the branch window class to the viz package.
233
    from viz import BranchWindow
452.4.1 by Jelmer Vernooij
Support displaying multiple tips in viz.
234
    return BranchWindow(branch, revisions, limit)
208.2.2 by Robert Collins
Add inspect window to bzr commity-notify.
235
236
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
237
class cmd_visualise(Command):
238
    """Graphically visualise this branch.
239
240
    Opens a graphical window to allow you to see the history of the branch
241
    and relationships between revisions in a visual manner,
242
243
    The default starting point is latest revision on the branch, you can
244
    specify a starting point with -r revision.
245
    """
246
    takes_options = [
247
        "revision",
208.2.7 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
248
        Option('limit', "Maximum number of revisions to display.",
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
249
               int, 'count')]
452.4.1 by Jelmer Vernooij
Support displaying multiple tips in viz.
250
    takes_args = [ "locations*" ]
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
251
    aliases = [ "visualize", "vis", "viz" ]
252
452.4.1 by Jelmer Vernooij
Support displaying multiple tips in viz.
253
    def run(self, locations_list, revision=None, limit=None):
133 by Jelmer Vernooij
Actually use the ui factory.
254
        set_ui_factory()
452.4.1 by Jelmer Vernooij
Support displaying multiple tips in viz.
255
        if locations_list is None:
256
            locations_list = ["."]
257
        revids = []
258
        for location in locations_list:
259
            (br, path) = branch.Branch.open_containing(location)
260
            if revision is None:
261
                revids.append(br.last_revision())
262
            else:
493 by Aaron Bentley
Convert remaining uses of RevisionSpec.in_history to as_revision_id
263
                revids.append(revision[0].as_revision_id(br))
365 by Daniel Schierbeck
Fixed locks and made tagging work.
264
        import gtk
452.4.1 by Jelmer Vernooij
Support displaying multiple tips in viz.
265
        pp = start_viz_window(br, revids, limit)
365 by Daniel Schierbeck
Fixed locks and made tagging work.
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
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):
505.1.1 by Jelmer Vernooij
Make handle-patch not dependend on the users name being abentley and install it.
288
        gtk = 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.")
493 by Aaron Bentley
Convert remaining uses of RevisionSpec.in_history to as_revision_id
313
            revision_id = revision[0].as_revision_id(br)
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
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
473.1.1 by Andrew Bennetts
Simple hack to fix gannotate.
318
        window = GAnnotateWindow(all, plain, branch=br)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
319
        window.connect("destroy", lambda w: gtk.main_quit())
320
        config = GAnnotateConfig(window)
321
        window.show()
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
322
        br.lock_read()
161 by Aaron Bentley
Fix gannotate interaction with dirstate
323
        if wt is not None:
324
            wt.lock_read()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
325
        try:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
326
            window.annotate(tree, br, file_id)
161 by Aaron Bentley
Fix gannotate interaction with dirstate
327
            window.jump_to_line(line)
328
            gtk.main()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
329
        finally:
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
330
            br.unlock()
161 by Aaron Bentley
Fix gannotate interaction with dirstate
331
            if wt is not None:
332
                wt.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
333
334
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
335
336
class cmd_gcommit(GTKCommand):
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
337
    """GTK+ commit dialog
338
339
    Graphical user interface for committing revisions"""
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
340
145 by Jelmer Vernooij
Fix some strings, import.
341
    aliases = [ "gci" ]
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
342
    takes_args = []
343
    takes_options = []
344
345
    def run(self, filename=None):
93.1.17 by Alexander Belchenko
gcommit reworked again.
346
        import os
505.1.1 by Jelmer Vernooij
Make handle-patch not dependend on the users name being abentley and install it.
347
        open_display()
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
348
        from commit import CommitDialog
93.1.17 by Alexander Belchenko
gcommit reworked again.
349
        from bzrlib.errors import (BzrCommandError,
350
                                   NotBranchError,
178 by Jelmer Vernooij
Remove unneeded imports.
351
                                   NoWorkingTree)
93.1.17 by Alexander Belchenko
gcommit reworked again.
352
353
        wt = None
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
354
        br = None
93.1.17 by Alexander Belchenko
gcommit reworked again.
355
        try:
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
356
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
157.2.1 by Vincent Ladeuil
Rename variable 'branch' to 'br' where it conflicts with 'branch' module
357
            br = wt.branch
93.1.17 by Alexander Belchenko
gcommit reworked again.
358
        except NoWorkingTree, e:
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
359
            from dialog import error_dialog
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
360
            error_dialog(_i18n('Directory does not have a working tree'),
361
                         _i18n('Operation aborted.'))
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
362
            return 1 # should this be retval=3?
363
364
        # It is a good habit to keep things locked for the duration, but it
365
        # could cause difficulties if someone wants to do things in another
366
        # window... We could lock_read() until we actually go to commit
367
        # changes... Just a thought.
368
        wt.lock_write()
369
        try:
370
            dlg = CommitDialog(wt)
371
            return dlg.run()
372
        finally:
373
            wt.unlock()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
374
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
375
250 by Aaron Bentley
oops- revert status change
376
class cmd_gstatus(GTKCommand):
157 by Jelmer Vernooij
Add gstatus command.
377
    """GTK+ status dialog
378
379
    Graphical user interface for showing status 
380
    information."""
381
    
382
    aliases = [ "gst" ]
383
    takes_args = ['PATH?']
463.1.1 by Javier Derderian
Added revision option to gstatus. Bug #136530
384
    takes_options = ['revision']
157 by Jelmer Vernooij
Add gstatus command.
385
463.1.1 by Javier Derderian
Added revision option to gstatus. Bug #136530
386
    def run(self, path='.', revision=None):
157 by Jelmer Vernooij
Add gstatus command.
387
        import os
505.1.1 by Jelmer Vernooij
Make handle-patch not dependend on the users name being abentley and install it.
388
        gtk = open_display()
157 by Jelmer Vernooij
Add gstatus command.
389
        from status import StatusDialog
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
390
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
463.1.1 by Javier Derderian
Added revision option to gstatus. Bug #136530
391
        
392
        if revision is not None:
463.1.2 by Javier Derderian
Added 'Revision # doesn't exist' message
393
            try:
493 by Aaron Bentley
Convert remaining uses of RevisionSpec.in_history to as_revision_id
394
                revision_id = revision[0].as_revision_id(wt.branch)
463.1.2 by Javier Derderian
Added 'Revision # doesn't exist' message
395
            except:
396
                from bzrlib.errors import BzrError
397
                raise BzrError('Revision %r doesn\'t exist' % revision[0].user_spec )
463.1.1 by Javier Derderian
Added revision option to gstatus. Bug #136530
398
        else:
399
            revision_id = None
400
401
        status = StatusDialog(wt, wt_path, revision_id)
157 by Jelmer Vernooij
Add gstatus command.
402
        status.connect("destroy", gtk.main_quit)
403
        status.run()
404
405
323 by Jelmer Vernooij
Add gsend command.
406
class cmd_gsend(GTKCommand):
407
    """GTK+ send merge directive.
408
409
    """
410
    def run(self):
411
        (br, path) = branch.Branch.open_containing(".")
505.1.1 by Jelmer Vernooij
Make handle-patch not dependend on the users name being abentley and install it.
412
        gtk = open_display()
323 by Jelmer Vernooij
Add gsend command.
413
        from bzrlib.plugins.gtk.mergedirective import SendMergeDirectiveDialog
324 by Jelmer Vernooij
Add very simple "Send Merge Directive" window.
414
        from StringIO import StringIO
323 by Jelmer Vernooij
Add gsend command.
415
        dialog = SendMergeDirectiveDialog(br)
324 by Jelmer Vernooij
Add very simple "Send Merge Directive" window.
416
        if dialog.run() == gtk.RESPONSE_OK:
417
            outf = StringIO()
418
            outf.writelines(dialog.get_merge_directive().to_lines())
419
            mail_client = br.get_config().get_mail_client()
420
            mail_client.compose_merge_request(dialog.get_mail_to(), "[MERGE]", 
421
                outf.getvalue())
422
423
            
323 by Jelmer Vernooij
Add gsend command.
424
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
425
426
class cmd_gconflicts(GTKCommand):
323 by Jelmer Vernooij
Add gsend command.
427
    """GTK+ conflicts.
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
428
    
242.1.2 by Adeodato Simó
Fix gconflicts docstring.
429
    Select files from the list of conflicts and run an external utility to
430
    resolve them.
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
431
    """
432
    def run(self):
157.1.5 by Aaron Bentley
Use lazy_import to reduce rocks time by .015s
433
        (wt, path) = workingtree.WorkingTree.open_containing('.')
505.1.1 by Jelmer Vernooij
Make handle-patch not dependend on the users name being abentley and install it.
434
        open_display()
126.1.24 by Szilveszter Farkas (Phanatic)
Implemented Conflicts dialog. Added gconflicts command.
435
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
436
        dialog = ConflictsDialog(wt)
437
        dialog.run()
438
157 by Jelmer Vernooij
Add gstatus command.
439
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
440
class cmd_gpreferences(GTKCommand):
171 by Jelmer Vernooij
Initial work on a preferences dialog in GTK+, including a list of plugins with metadata browser.
441
    """ GTK+ preferences dialog.
442
443
    """
444
    def run(self):
505.1.1 by Jelmer Vernooij
Make handle-patch not dependend on the users name being abentley and install it.
445
        open_display()
171 by Jelmer Vernooij
Initial work on a preferences dialog in GTK+, including a list of plugins with metadata browser.
446
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
447
        dialog = PreferencesWindow()
448
        dialog.run()
449
450
175 by Jelmer Vernooij
Add very simple gmissing command.
451
class cmd_gmissing(Command):
452
    """ GTK+ missing revisions dialog.
453
454
    """
455
    takes_args = ["other_branch?"]
456
    def run(self, other_branch=None):
457
        pygtk = import_pygtk()
458
        try:
459
            import gtk
460
        except RuntimeError, e:
461
            if str(e) == "could not open display":
462
                raise NoDisplayError
463
464
        from bzrlib.plugins.gtk.missing import MissingWindow
465
        from bzrlib.branch import Branch
466
467
        local_branch = Branch.open_containing(".")[0]
468
        if other_branch is None:
469
            other_branch = local_branch.get_parent()
470
            
471
            if other_branch is None:
472
                raise errors.BzrCommandError("No peer location known or specified.")
473
        remote_branch = Branch.open_containing(other_branch)[0]
474
        set_ui_factory()
475
        local_branch.lock_read()
476
        try:
477
            remote_branch.lock_read()
478
            try:
479
                dialog = MissingWindow(local_branch, remote_branch)
480
                dialog.run()
481
            finally:
482
                remote_branch.unlock()
483
        finally:
484
            local_branch.unlock()
485
177 by Jelmer Vernooij
Register commands all at once.
486
188.1.1 by Szilveszter Farkas (Phanatic)
Inital implementation of the Initialize dialog. Not fully functional yet.
487
class cmd_ginit(GTKCommand):
488
    def run(self):
505.1.1 by Jelmer Vernooij
Make handle-patch not dependend on the users name being abentley and install it.
489
        open_display()
188.1.1 by Szilveszter Farkas (Phanatic)
Inital implementation of the Initialize dialog. Not fully functional yet.
490
        from initialize import InitDialog
491
        dialog = InitDialog(os.path.abspath(os.path.curdir))
492
        dialog.run()
493
494
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
495
class cmd_gtags(GTKCommand):
496
    def run(self):
497
        br = branch.Branch.open_containing('.')[0]
498
        
505.1.1 by Jelmer Vernooij
Make handle-patch not dependend on the users name being abentley and install it.
499
        gtk = open_display()
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
500
        from tags import TagsWindow
501
        window = TagsWindow(br)
502
        window.show()
503
        gtk.main()
504
505
177 by Jelmer Vernooij
Register commands all at once.
506
commands = [
323 by Jelmer Vernooij
Add gsend command.
507
    cmd_gannotate, 
508
    cmd_gbranch,
509
    cmd_gcheckout, 
510
    cmd_gcommit, 
511
    cmd_gconflicts, 
512
    cmd_gdiff,
513
    cmd_ginit,
177 by Jelmer Vernooij
Register commands all at once.
514
    cmd_gmissing, 
515
    cmd_gpreferences, 
323 by Jelmer Vernooij
Add gsend command.
516
    cmd_gpush, 
517
    cmd_gsend,
177 by Jelmer Vernooij
Register commands all at once.
518
    cmd_gstatus,
323 by Jelmer Vernooij
Add gsend command.
519
    cmd_gtags,
520
    cmd_visualise
177 by Jelmer Vernooij
Register commands all at once.
521
    ]
522
523
for cmd in commands:
524
    register_command(cmd)
175 by Jelmer Vernooij
Add very simple gmissing command.
525
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
526
249 by Aaron Bentley
Add gselftest command
527
class cmd_gselftest(GTKCommand):
528
    """Version of selftest that displays a notification at the end"""
529
530
    takes_args = builtins.cmd_selftest.takes_args
531
    takes_options = builtins.cmd_selftest.takes_options
532
    _see_also = ['selftest']
533
534
    def run(self, *args, **kwargs):
535
        import cgi
253 by Aaron Bentley
Avoid encoding problems from pygtk
536
        import sys
537
        default_encoding = sys.getdefaultencoding()
249 by Aaron Bentley
Add gselftest command
538
        # prevent gtk from blowing up later
539
        gtk = import_pygtk()
253 by Aaron Bentley
Avoid encoding problems from pygtk
540
        # prevent gtk from messing with default encoding
249 by Aaron Bentley
Add gselftest command
541
        import pynotify
253 by Aaron Bentley
Avoid encoding problems from pygtk
542
        if sys.getdefaultencoding() != default_encoding:
543
            reload(sys)
544
            sys.setdefaultencoding(default_encoding)
249 by Aaron Bentley
Add gselftest command
545
        result = builtins.cmd_selftest().run(*args, **kwargs)
546
        if result == 0:
547
            summary = 'Success'
548
            body = 'Selftest succeeded in "%s"' % os.getcwd()
549
        if result == 1:
550
            summary = 'Failure'
551
            body = 'Selftest failed in "%s"' % os.getcwd()
552
        pynotify.init("bzr gselftest")
553
        note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
554
        note.set_timeout(pynotify.EXPIRES_NEVER)
555
        note.show()
556
557
558
register_command(cmd_gselftest)
559
560
278.1.22 by John Arbash Meinel
Add a test-gtk command to make testing faster
561
class cmd_test_gtk(GTKCommand):
562
    """Version of selftest that just runs the gtk test suite."""
563
564
    takes_options = ['verbose',
565
                     Option('one', short_name='1',
330.6.2 by Aaron Bentley
Fix option grammar
566
                            help='Stop when one test fails.'),
567
                     Option('benchmark', help='Run the benchmarks.'),
278.1.22 by John Arbash Meinel
Add a test-gtk command to make testing faster
568
                     Option('lsprof-timed',
330.6.2 by Aaron Bentley
Fix option grammar
569
                     help='Generate lsprof output for benchmarked'
278.1.22 by John Arbash Meinel
Add a test-gtk command to make testing faster
570
                          ' sections of code.'),
571
                     Option('list-only',
330.6.2 by Aaron Bentley
Fix option grammar
572
                     help='List the tests instead of running them.'),
278.1.22 by John Arbash Meinel
Add a test-gtk command to make testing faster
573
                     Option('randomize', type=str, argname="SEED",
330.6.2 by Aaron Bentley
Fix option grammar
574
                     help='Randomize the order of tests using the given'
575
                          ' seed or "now" for the current time.'),
278.1.22 by John Arbash Meinel
Add a test-gtk command to make testing faster
576
                    ]
577
    takes_args = ['testspecs*']
578
579
    def run(self, verbose=None, one=False, benchmark=None,
580
            lsprof_timed=None, list_only=False, randomize=None,
581
            testspecs_list=None):
582
        from bzrlib import __path__ as bzrlib_path
583
        from bzrlib.tests import selftest
584
585
        print '%10s: %s' % ('bzrlib', bzrlib_path[0])
586
        if benchmark:
587
            print 'No benchmarks yet'
588
            return 3
589
590
            test_suite_factory = bench_suite
591
            if verbose is None:
592
                verbose = True
593
            # TODO: should possibly lock the history file...
594
            benchfile = open(".perf_history", "at", buffering=1)
595
        else:
596
            test_suite_factory = test_suite
597
            if verbose is None:
598
                verbose = False
599
            benchfile = None
600
601
        if testspecs_list is not None:
602
            pattern = '|'.join(testspecs_list)
603
        else:
604
            pattern = ".*"
605
606
        try:
607
            result = selftest(verbose=verbose,
608
                              pattern=pattern,
609
                              stop_on_failure=one,
610
                              test_suite_factory=test_suite_factory,
611
                              lsprof_timed=lsprof_timed,
612
                              bench_history=benchfile,
613
                              list_only=list_only,
614
                              random_seed=randomize,
615
                             )
616
        finally:
617
            if benchfile is not None:
618
                benchfile.close()
619
620
register_command(cmd_test_gtk)
621
622
424 by Aaron Bentley
Add ghandle-patch
623
152 by Jelmer Vernooij
Cleanup some more code.
624
import gettext
625
gettext.install('olive-gtk')
626
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
627
# Let's create a specialized alias to protect '_' from being erased by other
628
# uses of '_' as an anonymous variable (think pdb for one).
629
_i18n = gettext.gettext
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
630
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
631
class NoDisplayError(BzrCommandError):
632
    """gtk could not find a proper display"""
633
634
    def __str__(self):
133 by Jelmer Vernooij
Actually use the ui factory.
635
        return "No DISPLAY. Unable to run GTK+ application."
636
173.1.2 by Robert Collins
Minor refactoring of __init__ to have less duplication.
637
140 by Jelmer Vernooij
add framework for tests.
638
def test_suite():
639
    from unittest import TestSuite
640
    import tests
163 by Aaron Bentley
Prevent test suite from causing default-encoding changes
641
    import sys
642
    default_encoding = sys.getdefaultencoding()
643
    try:
644
        result = TestSuite()
330.6.4 by Aaron Bentley
Allow test suite to run without pygtk
645
        try:
646
            import_pygtk()
647
        except errors.BzrCommandError:
648
            return result
163 by Aaron Bentley
Prevent test suite from causing default-encoding changes
649
        result.addTest(tests.test_suite())
650
    finally:
170.1.2 by Aaron Bentley
Test suite only fixes encoding if it's changed. Fixes test_selftest bug.
651
        if sys.getdefaultencoding() != default_encoding:
652
            reload(sys)
653
            sys.setdefaultencoding(default_encoding)
140 by Jelmer Vernooij
add framework for tests.
654
    return result