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