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