/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
15
"""GTK+ frontends to Bazaar commands """
73 by Jelmer Vernooij
Release 0.9, list myself as maintainer.
16
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
17
import bzrlib
18
139 by Jelmer Vernooij
Update for use with current bzr.dev
19
__version__ = '0.15.0'
137 by Jelmer Vernooij
Warn about incompatible versions (taken from bzrtools, thanks Aaron).
20
version_info = tuple(int(n) for n in __version__.split('.'))
21
22
23
def check_bzrlib_version(desired):
24
    """Check that bzrlib is compatible.
25
26
    If version is < bzr-gtk version, assume incompatible.
27
    If version == bzr-gtk version, assume completely compatible
28
    If version == bzr-gtk version + 1, assume compatible, with deprecations
29
    Otherwise, assume incompatible.
30
    """
31
    desired_plus = (desired[0], desired[1]+1)
32
    bzrlib_version = bzrlib.version_info[:2]
33
    if bzrlib_version == desired:
34
        return
35
    try:
36
        from bzrlib.trace import warning
37
    except ImportError:
38
        # get the message out any way we can
39
        from warnings import warn as warning
40
    if bzrlib_version < desired:
41
        warning('Installed bzr version %s is too old to be used with bzr-gtk'
42
                ' %s.' % (bzrlib.__version__, __version__))
43
        # Not using BzrNewError, because it may not exist.
44
        raise Exception, ('Version mismatch', version_info)
45
    else:
46
        warning('bzr-gtk is not up to date with installed bzr version %s.'
47
                ' \nThere should be a newer version available, e.g. %i.%i.' 
48
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
49
        if bzrlib_version != desired_plus:
50
            raise Exception, 'Version mismatch'
51
52
53
check_bzrlib_version(version_info[:2])
54
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
55
from bzrlib import errors
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
56
from bzrlib.commands import Command, register_command, display_command
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
57
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
58
from bzrlib.commands import Command, register_command
59
from bzrlib.option import Option
60
from bzrlib.branch import Branch
61
from bzrlib.workingtree import WorkingTree
62
from bzrlib.bzrdir import BzrDir
63
126.1.5 by Szilveszter Farkas (Phanatic)
bzr gbranch should work now (Fixed: #77751)
64
import os.path
65
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
66
def import_pygtk():
67
    try:
68
        import pygtk
69
    except ImportError:
70
        raise errors.BzrCommandError("PyGTK not installed.")
71
    pygtk.require('2.0')
72
    return pygtk
73
74
133 by Jelmer Vernooij
Actually use the ui factory.
75
def set_ui_factory():
76
    pygtk = import_pygtk()
77
    from olive.ui import GtkUIFactory
78
    import bzrlib.ui
79
    bzrlib.ui.ui_factory = GtkUIFactory()
80
81
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
82
class cmd_gbranch(Command):
83
    """GTK+ branching.
84
    
85
    """
86
87
    def run(self):
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
88
        pygtk = import_pygtk()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
89
        try:
90
            import gtk
91
        except RuntimeError, e:
92
            if str(e) == "could not open display":
93
                raise NoDisplayError
94
90 by Jelmer Vernooij
Use Olive's clone dialog in nautilus-bzr; remove the old Clone dialog
95
        from bzrlib.plugins.gtk.olive.branch import BranchDialog
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
96
133 by Jelmer Vernooij
Actually use the ui factory.
97
        set_ui_factory()
126.1.5 by Szilveszter Farkas (Phanatic)
bzr gbranch should work now (Fixed: #77751)
98
        dialog = BranchDialog(os.path.abspath('.'))
126.1.15 by Szilveszter Farkas (Phanatic)
Refactoring the Branch dialog. We also have a Revision Browser now.
99
        dialog.run()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
100
101
register_command(cmd_gbranch)
102
103
class cmd_gdiff(Command):
104
    """Show differences in working tree in a GTK+ Window.
105
    
106
    Otherwise, all changes for the tree are listed.
107
    """
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
108
    takes_args = ['filename?']
58.1.1 by Aaron Bentley
gdiff takes -r arguments
109
    takes_options = ['revision']
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
110
111
    @display_command
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
112
    def run(self, revision=None, filename=None):
133 by Jelmer Vernooij
Actually use the ui factory.
113
        set_ui_factory()
58.1.1 by Aaron Bentley
gdiff takes -r arguments
114
        wt = WorkingTree.open_containing(".")[0]
115
        branch = wt.branch
116
        if revision is not None:
117
            if len(revision) == 1:
118
                tree1 = wt
119
                revision_id = revision[0].in_history(branch).rev_id
120
                tree2 = branch.repository.revision_tree(revision_id)
121
            elif len(revision) == 2:
122
                revision_id_0 = revision[0].in_history(branch).rev_id
123
                tree2 = branch.repository.revision_tree(revision_id_0)
124
                revision_id_1 = revision[1].in_history(branch).rev_id
125
                tree1 = branch.repository.revision_tree(revision_id_1)
126
        else:
127
            tree1 = wt
128
            tree2 = tree1.basis_tree()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
129
93.1.8 by Alexander Belchenko
Fix absolute import in gdiff command.
130
        from viz.diffwin import DiffWindow
58 by Jelmer Vernooij
[merge] Home
131
        import gtk
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
132
        window = DiffWindow()
133
        window.connect("destroy", lambda w: gtk.main_quit())
134
        window.set_diff("Working Tree", tree1, tree2)
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
135
        if filename is not None:
93.1.16 by Alexander Belchenko
Partial fix for problem with encodings in diff window
136
            tree_filename = wt.relpath(filename)
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
137
            try:
138
                window.set_file(tree_filename)
139
            except NoSuchFile:
140
                if (tree1.inventory.path2id(tree_filename) is None and 
141
                    tree2.inventory.path2id(tree_filename) is None):
142
                    raise NotVersionedError(filename)
143
                raise BzrCommandError('No changes found for file "%s"' % 
144
                                      filename)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
145
        window.show()
146
147
        gtk.main()
148
149
register_command(cmd_gdiff)
150
151
class cmd_visualise(Command):
152
    """Graphically visualise this branch.
153
154
    Opens a graphical window to allow you to see the history of the branch
155
    and relationships between revisions in a visual manner,
156
157
    The default starting point is latest revision on the branch, you can
158
    specify a starting point with -r revision.
159
    """
160
    takes_options = [
161
        "revision",
162
        Option('limit', "maximum number of revisions to display",
163
               int, 'count')]
164
    takes_args = [ "location?" ]
165
    aliases = [ "visualize", "vis", "viz" ]
166
167
    def run(self, location=".", revision=None, limit=None):
133 by Jelmer Vernooij
Actually use the ui factory.
168
        set_ui_factory()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
169
        (branch, path) = Branch.open_containing(location)
170
        branch.lock_read()
171
        branch.repository.lock_read()
172
        try:
173
            if revision is None:
174
                revid = branch.last_revision()
175
                if revid is None:
176
                    return
177
            else:
178
                (revno, revid) = revision[0].in_history(branch)
179
180
            from viz.bzrkapp import BzrkApp
181
                
182
            app = BzrkApp()
183
            app.show(branch, revid, limit)
184
        finally:
185
            branch.repository.unlock()
186
            branch.unlock()
187
        app.main()
188
189
190
register_command(cmd_visualise)
191
192
class cmd_gannotate(Command):
193
    """GTK+ annotate.
194
    
195
    Browse changes to FILENAME line by line in a GTK+ window.
196
    """
197
59.2.1 by Aaron Bentley
Gannotate takes a line number
198
    takes_args = ["filename", "line?"]
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
199
    takes_options = [
200
        Option("all", help="show annotations on all lines"),
201
        Option("plain", help="don't highlight annotation lines"),
202
        Option("line", type=int, argname="lineno",
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
203
               help="jump to specified line number"),
204
        "revision",
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
205
    ]
206
    aliases = ["gblame", "gpraise"]
207
    
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
208
    def run(self, filename, all=False, plain=False, line='1', revision=None):
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
209
        pygtk = import_pygtk()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
210
211
        try:
212
            import gtk
213
        except RuntimeError, e:
214
            if str(e) == "could not open display":
215
                raise NoDisplayError
133 by Jelmer Vernooij
Actually use the ui factory.
216
        set_ui_factory()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
217
59.2.1 by Aaron Bentley
Gannotate takes a line number
218
        try:
219
            line = int(line)
220
        except ValueError:
221
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
222
                                  line)
223
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
224
        from annotate.gannotate import GAnnotateWindow
225
        from annotate.config import GAnnotateConfig
226
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
227
        try:
228
            (tree, path) = WorkingTree.open_containing(filename)
229
            branch = tree.branch
230
        except errors.NoWorkingTree:
231
            (branch, path) = Branch.open_containing(filename)
232
            tree = branch.basis_tree()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
233
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
234
        file_id = tree.path2id(path)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
235
236
        if file_id is None:
237
            raise NotVersionedError(filename)
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
238
        if revision is not None:
239
            if len(revision) != 1:
240
                raise BzrCommandError("Only 1 revion may be specified.")
241
            revision_id = revision[0].in_history(branch).rev_id
66.2.14 by Aaron Bentley
Annotate showing uncommitted changes
242
            tree = branch.repository.revision_tree(revision_id)
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
243
        else:
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
244
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
245
246
        window = GAnnotateWindow(all, plain)
247
        window.connect("destroy", lambda w: gtk.main_quit())
248
        window.set_title(path + " - gannotate")
249
        config = GAnnotateConfig(window)
250
        window.show()
251
        branch.lock_read()
252
        try:
66.2.14 by Aaron Bentley
Annotate showing uncommitted changes
253
            window.annotate(tree, branch, file_id)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
254
        finally:
255
            branch.unlock()
256
        window.jump_to_line(line)
257
        
258
        gtk.main()
259
260
register_command(cmd_gannotate)
261
262
class cmd_gcommit(Command):
263
    """GTK+ commit dialog
264
265
    Graphical user interface for committing revisions"""
266
    
267
    takes_args = []
268
    takes_options = []
269
270
    def run(self, filename=None):
93.1.17 by Alexander Belchenko
gcommit reworked again.
271
        import os
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
272
        pygtk = import_pygtk()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
273
274
        try:
275
            import gtk
276
        except RuntimeError, e:
277
            if str(e) == "could not open display":
278
                raise NoDisplayError
279
133 by Jelmer Vernooij
Actually use the ui factory.
280
        set_ui_factory()
90 by Jelmer Vernooij
Use Olive's clone dialog in nautilus-bzr; remove the old Clone dialog
281
        from olive.commit import CommitDialog
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
282
        from bzrlib.commit import Commit
93.1.17 by Alexander Belchenko
gcommit reworked again.
283
        from bzrlib.errors import (BzrCommandError,
284
                                   NotBranchError,
285
                                   NoWorkingTree,
286
                                   PointlessCommit,
287
                                   ConflictsInTree,
288
                                   StrictCommitFailed)
289
290
        wt = None
291
        branch = None
292
        try:
293
            (wt, path) = WorkingTree.open_containing(filename)
294
            branch = wt.branch
295
        except NotBranchError, e:
296
            path = e.path
297
        except NoWorkingTree, e:
298
            path = e.base
299
            try:
300
                (branch, path) = Branch.open_containing(path)
301
            except NotBranchError, e:
302
                path = e.path
303
135 by Jelmer Vernooij
Throw out the old CommitDialog code and use the new code instead, also for 'gcommit'.
304
305
        commit = CommitDialog(wt, path, not branch)
306
        commit.run()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
307
308
register_command(cmd_gcommit)
309
310
class NoDisplayError(BzrCommandError):
311
    """gtk could not find a proper display"""
312
313
    def __str__(self):
133 by Jelmer Vernooij
Actually use the ui factory.
314
        return "No DISPLAY. Unable to run GTK+ application."
315
316