/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('.'))
99
        dialog.window.connect("destroy", lambda w: gtk.main_quit())
100
        dialog.display()
101
        
102
        gtk.main()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
103
104
register_command(cmd_gbranch)
105
106
class cmd_gdiff(Command):
107
    """Show differences in working tree in a GTK+ Window.
108
    
109
    Otherwise, all changes for the tree are listed.
110
    """
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
111
    takes_args = ['filename?']
58.1.1 by Aaron Bentley
gdiff takes -r arguments
112
    takes_options = ['revision']
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
113
114
    @display_command
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
115
    def run(self, revision=None, filename=None):
133 by Jelmer Vernooij
Actually use the ui factory.
116
        set_ui_factory()
58.1.1 by Aaron Bentley
gdiff takes -r arguments
117
        wt = WorkingTree.open_containing(".")[0]
118
        branch = wt.branch
119
        if revision is not None:
120
            if len(revision) == 1:
121
                tree1 = wt
122
                revision_id = revision[0].in_history(branch).rev_id
123
                tree2 = branch.repository.revision_tree(revision_id)
124
            elif len(revision) == 2:
125
                revision_id_0 = revision[0].in_history(branch).rev_id
126
                tree2 = branch.repository.revision_tree(revision_id_0)
127
                revision_id_1 = revision[1].in_history(branch).rev_id
128
                tree1 = branch.repository.revision_tree(revision_id_1)
129
        else:
130
            tree1 = wt
131
            tree2 = tree1.basis_tree()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
132
93.1.8 by Alexander Belchenko
Fix absolute import in gdiff command.
133
        from viz.diffwin import DiffWindow
58 by Jelmer Vernooij
[merge] Home
134
        import gtk
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
135
        window = DiffWindow()
136
        window.connect("destroy", lambda w: gtk.main_quit())
137
        window.set_diff("Working Tree", tree1, tree2)
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
138
        if filename is not None:
93.1.16 by Alexander Belchenko
Partial fix for problem with encodings in diff window
139
            tree_filename = wt.relpath(filename)
59.2.4 by Aaron Bentley
Teach gdiff to accept a single file argument
140
            try:
141
                window.set_file(tree_filename)
142
            except NoSuchFile:
143
                if (tree1.inventory.path2id(tree_filename) is None and 
144
                    tree2.inventory.path2id(tree_filename) is None):
145
                    raise NotVersionedError(filename)
146
                raise BzrCommandError('No changes found for file "%s"' % 
147
                                      filename)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
148
        window.show()
149
150
        gtk.main()
151
152
register_command(cmd_gdiff)
153
154
class cmd_visualise(Command):
155
    """Graphically visualise this branch.
156
157
    Opens a graphical window to allow you to see the history of the branch
158
    and relationships between revisions in a visual manner,
159
160
    The default starting point is latest revision on the branch, you can
161
    specify a starting point with -r revision.
162
    """
163
    takes_options = [
164
        "revision",
165
        Option('limit', "maximum number of revisions to display",
166
               int, 'count')]
167
    takes_args = [ "location?" ]
168
    aliases = [ "visualize", "vis", "viz" ]
169
170
    def run(self, location=".", revision=None, limit=None):
133 by Jelmer Vernooij
Actually use the ui factory.
171
        set_ui_factory()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
172
        (branch, path) = Branch.open_containing(location)
173
        branch.lock_read()
174
        branch.repository.lock_read()
175
        try:
176
            if revision is None:
177
                revid = branch.last_revision()
178
                if revid is None:
179
                    return
180
            else:
181
                (revno, revid) = revision[0].in_history(branch)
182
183
            from viz.bzrkapp import BzrkApp
184
                
185
            app = BzrkApp()
186
            app.show(branch, revid, limit)
187
        finally:
188
            branch.repository.unlock()
189
            branch.unlock()
190
        app.main()
191
192
193
register_command(cmd_visualise)
194
195
class cmd_gannotate(Command):
196
    """GTK+ annotate.
197
    
198
    Browse changes to FILENAME line by line in a GTK+ window.
199
    """
200
59.2.1 by Aaron Bentley
Gannotate takes a line number
201
    takes_args = ["filename", "line?"]
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
202
    takes_options = [
203
        Option("all", help="show annotations on all lines"),
204
        Option("plain", help="don't highlight annotation lines"),
205
        Option("line", type=int, argname="lineno",
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
206
               help="jump to specified line number"),
207
        "revision",
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
208
    ]
209
    aliases = ["gblame", "gpraise"]
210
    
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
211
    def run(self, filename, all=False, plain=False, line='1', revision=None):
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
212
        pygtk = import_pygtk()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
213
214
        try:
215
            import gtk
216
        except RuntimeError, e:
217
            if str(e) == "could not open display":
218
                raise NoDisplayError
133 by Jelmer Vernooij
Actually use the ui factory.
219
        set_ui_factory()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
220
59.2.1 by Aaron Bentley
Gannotate takes a line number
221
        try:
222
            line = int(line)
223
        except ValueError:
224
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
225
                                  line)
226
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
227
        from annotate.gannotate import GAnnotateWindow
228
        from annotate.config import GAnnotateConfig
229
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
230
        try:
231
            (tree, path) = WorkingTree.open_containing(filename)
232
            branch = tree.branch
233
        except errors.NoWorkingTree:
234
            (branch, path) = Branch.open_containing(filename)
235
            tree = branch.basis_tree()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
236
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
237
        file_id = tree.path2id(path)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
238
239
        if file_id is None:
240
            raise NotVersionedError(filename)
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
241
        if revision is not None:
242
            if len(revision) != 1:
243
                raise BzrCommandError("Only 1 revion may be specified.")
244
            revision_id = revision[0].in_history(branch).rev_id
66.2.14 by Aaron Bentley
Annotate showing uncommitted changes
245
            tree = branch.repository.revision_tree(revision_id)
66.2.1 by Aaron Bentley
Gannotate takes a revision argument
246
        else:
66.2.18 by Aaron Bentley
Gannotate works with branches, not just trees
247
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
248
249
        window = GAnnotateWindow(all, plain)
250
        window.connect("destroy", lambda w: gtk.main_quit())
251
        window.set_title(path + " - gannotate")
252
        config = GAnnotateConfig(window)
253
        window.show()
254
        branch.lock_read()
255
        try:
66.2.14 by Aaron Bentley
Annotate showing uncommitted changes
256
            window.annotate(tree, branch, file_id)
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
257
        finally:
258
            branch.unlock()
259
        window.jump_to_line(line)
260
        
261
        gtk.main()
262
263
register_command(cmd_gannotate)
264
265
class cmd_gcommit(Command):
266
    """GTK+ commit dialog
267
268
    Graphical user interface for committing revisions"""
269
    
270
    takes_args = []
271
    takes_options = []
272
273
    def run(self, filename=None):
93.1.17 by Alexander Belchenko
gcommit reworked again.
274
        import os
66.2.20 by Aaron Bentley
Nicer error when PyGTK not installed
275
        pygtk = import_pygtk()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
276
277
        try:
278
            import gtk
279
        except RuntimeError, e:
280
            if str(e) == "could not open display":
281
                raise NoDisplayError
282
133 by Jelmer Vernooij
Actually use the ui factory.
283
        set_ui_factory()
90 by Jelmer Vernooij
Use Olive's clone dialog in nautilus-bzr; remove the old Clone dialog
284
        from olive.commit import CommitDialog
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
285
        from bzrlib.commit import Commit
93.1.17 by Alexander Belchenko
gcommit reworked again.
286
        from bzrlib.errors import (BzrCommandError,
287
                                   NotBranchError,
288
                                   NoWorkingTree,
289
                                   PointlessCommit,
290
                                   ConflictsInTree,
291
                                   StrictCommitFailed)
292
293
        wt = None
294
        branch = None
295
        try:
296
            (wt, path) = WorkingTree.open_containing(filename)
297
            branch = wt.branch
298
        except NotBranchError, e:
299
            path = e.path
300
        except NoWorkingTree, e:
301
            path = e.base
302
            try:
303
                (branch, path) = Branch.open_containing(path)
304
            except NotBranchError, e:
305
                path = e.path
306
135 by Jelmer Vernooij
Throw out the old CommitDialog code and use the new code instead, also for 'gcommit'.
307
308
        commit = CommitDialog(wt, path, not branch)
309
        commit.run()
55.1.2 by Jelmer Vernooij
Move commands to top-level __init__
310
311
register_command(cmd_gcommit)
312
313
class NoDisplayError(BzrCommandError):
314
    """gtk could not find a proper display"""
315
316
    def __str__(self):
133 by Jelmer Vernooij
Actually use the ui factory.
317
        return "No DISPLAY. Unable to run GTK+ application."
318
140 by Jelmer Vernooij
add framework for tests.
319
def test_suite():
320
    from unittest import TestSuite
321
    import tests
322
    result = TestSuite()
323
    result.addTest(tests.test_suite())
324
    return result
133 by Jelmer Vernooij
Actually use the ui factory.
325