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