1
# Trivial Bazaar plugin for Nautilus
 
 
3
# Copyright (C) 2006 Jeff Bailey
 
 
4
# Copyright (C) 2006 Wouter van Heyst
 
 
5
# Copyright (C) 2006 Jelmer Vernooij
 
 
7
# Published under the GNU GPL
 
 
11
from bzrlib.bzrdir import BzrDir
 
 
12
from bzrlib.errors import NotBranchError
 
 
13
from bzrlib.workingtree import WorkingTree
 
 
14
from bzrlib.tree import file_status
 
 
16
from bzrlib.plugin import load_plugins
 
 
19
from bzrlib.plugins.gtk import cmd_visualise, cmd_gannotate
 
 
21
class BzrExtension(nautilus.MenuProvider, nautilus.ColumnProvider, nautilus.InfoProvider):
 
 
25
    def add_cb(self, menu, vfs_file):
 
 
26
        # We can only cope with local files
 
 
27
        if vfs_file.get_uri_scheme() != 'file':
 
 
30
        file = vfs_file.get_uri()
 
 
32
            tree, path = WorkingTree.open_containing(file)
 
 
33
        except NotBranchError:
 
 
40
    def ignore_cb(self, menu, vfs_file):
 
 
41
        # We can only cope with local files
 
 
42
        if vfs_file.get_uri_scheme() != 'file':
 
 
45
        file = vfs_file.get_uri()
 
 
47
            tree, path = WorkingTree.open_containing(file)
 
 
48
        except NotBranchError:
 
 
55
    def unignore_cb(self, menu, vfs_file):
 
 
56
        # We can only cope with local files
 
 
57
        if vfs_file.get_uri_scheme() != 'file':
 
 
60
        file = vfs_file.get_uri()
 
 
62
            tree, path = WorkingTree.open_containing(file)
 
 
63
        except NotBranchError:
 
 
70
    def diff_cb(self, menu, vfs_file):
 
 
71
        # We can only cope with local files
 
 
72
        if vfs_file.get_uri_scheme() != 'file':
 
 
75
        file = vfs_file.get_uri()
 
 
77
            tree, path = WorkingTree.open_containing(file)
 
 
78
        except NotBranchError:
 
 
81
        from bzrlib.plugins.gtk.viz.diff import DiffWindow
 
 
83
        window.set_diff(tree.branch.nick, tree, tree.branch.basis_tree())
 
 
88
    def newtree_cb(self, menu, vfs_file):
 
 
89
        # We can only cope with local files
 
 
90
        if vfs_file.get_uri_scheme() != 'file':
 
 
93
        file = vfs_file.get_uri()
 
 
95
        # We only want to continue here if we get a NotBranchError
 
 
97
            tree, path = WorkingTree.open_containing(file)
 
 
98
        except NotBranchError:
 
 
99
            BzrDir.create_branch_and_repo(file)
 
 
101
    def remove_cb(self, menu, vfs_file):
 
 
102
        # We can only cope with local files
 
 
103
        if vfs_file.get_uri_scheme() != 'file':
 
 
106
        file = vfs_file.get_uri()
 
 
108
            tree, path = WorkingTree.open_containing(file)
 
 
109
        except NotBranchError:
 
 
114
    def annotate_cb(self, menu, vfs_file):
 
 
115
        # We can only cope with local files
 
 
116
        if vfs_file.get_uri_scheme() != 'file':
 
 
119
        file = vfs_file.get_uri()
 
 
121
        vis = cmd_gannotate()
 
 
124
    def clone_cb(self, menu, vfs_file=None):
 
 
125
        # We can only cope with local files
 
 
126
        if vfs_file.get_uri_scheme() != 'file':
 
 
129
        from bzrlib.plugins.gtk.branch import BranchDialog
 
 
131
        dialog = BranchDialog(vfs_file.get_name())
 
 
134
    def commit_cb(self, menu, vfs_file=None):
 
 
135
        # We can only cope with local files
 
 
136
        if vfs_file.get_uri_scheme() != 'file':
 
 
139
        file = vfs_file.get_uri()
 
 
141
            tree, path = WorkingTree.open_containing(file)
 
 
142
        except NotBranchError:
 
 
145
        from bzrlib.plugins.gtk.commit import CommitDialog
 
 
146
        dialog = CommitDialog(tree, path)
 
 
150
    def log_cb(self, menu, vfs_file):
 
 
151
        # We can only cope with local files
 
 
152
        if vfs_file.get_uri_scheme() != 'file':
 
 
155
        file = vfs_file.get_uri()
 
 
157
        # We only want to continue here if we get a NotBranchError
 
 
159
            tree, path = WorkingTree.open_containing(file)
 
 
160
        except NotBranchError:
 
 
163
        vis = cmd_visualise()
 
 
168
    def pull_cb(self, menu, vfs_file):
 
 
169
        # We can only cope with local files
 
 
170
        if vfs_file.get_uri_scheme() != 'file':
 
 
173
        file = vfs_file.get_uri()
 
 
175
        # We only want to continue here if we get a NotBranchError
 
 
177
            tree, path = WorkingTree.open_containing(file)
 
 
178
        except NotBranchError:
 
 
181
        from bzrlib.plugins.gtk.pull import PullDialog
 
 
182
        dialog = PullDialog(tree, path)
 
 
186
    def merge_cb(self, menu, vfs_file):
 
 
187
        # We can only cope with local files
 
 
188
        if vfs_file.get_uri_scheme() != 'file':
 
 
191
        file = vfs_file.get_uri()
 
 
193
        # We only want to continue here if we get a NotBranchError
 
 
195
            tree, path = WorkingTree.open_containing(file)
 
 
196
        except NotBranchError:
 
 
199
        from bzrlib.plugins.gtk.merge import MergeDialog
 
 
200
        dialog = MergeDialog(tree, path)
 
 
204
    def get_background_items(self, window, vfs_file):
 
 
206
        file = vfs_file.get_uri()
 
 
208
            tree, path = WorkingTree.open_containing(file)
 
 
209
        except NotBranchError:
 
 
210
            item = nautilus.MenuItem('BzrNautilus::newtree',
 
 
211
                                 'Make directory versioned',
 
 
212
                                 'Create new Bazaar tree in this folder')
 
 
213
            item.connect('activate', self.newtree_cb, vfs_file)
 
 
216
            item = nautilus.MenuItem('BzrNautilus::clone',
 
 
217
                                 'Checkout Bazaar branch',
 
 
218
                                 'Checkout Existing Bazaar Branch')
 
 
219
            item.connect('activate', self.clone_cb, vfs_file)
 
 
224
        item = nautilus.MenuItem('BzrNautilus::log',
 
 
226
                             'Show Bazaar history')
 
 
227
        item.connect('activate', self.log_cb, vfs_file)
 
 
230
        item = nautilus.MenuItem('BzrNautilus::pull',
 
 
232
                             'Pull from another branch')
 
 
233
        item.connect('activate', self.pull_cb, vfs_file)
 
 
236
        item = nautilus.MenuItem('BzrNautilus::merge',
 
 
238
                             'Merge from another branch')
 
 
239
        item.connect('activate', self.merge_cb, vfs_file)
 
 
242
        item = nautilus.MenuItem('BzrNautilus::commit',
 
 
245
        item.connect('activate', self.commit_cb, vfs_file)
 
 
251
    def get_file_items(self, window, files):
 
 
254
        for vfs_file in files:
 
 
255
            # We can only cope with local files
 
 
256
            if vfs_file.get_uri_scheme() != 'file':
 
 
259
            file = vfs_file.get_uri()
 
 
261
                tree, path = WorkingTree.open_containing(file)
 
 
262
            except NotBranchError:
 
 
263
                if not vfs_file.is_directory():
 
 
265
                item = nautilus.MenuItem('BzrNautilus::newtree',
 
 
266
                                     'Make directory versioned',
 
 
267
                                     'Create new Bazaar tree in %s' % vfs_file.get_name())
 
 
268
                item.connect('activate', self.newtree_cb, vfs_file)
 
 
271
            file_class = tree.file_class(path)
 
 
273
            if file_class == '?':
 
 
274
                item = nautilus.MenuItem('BzrNautilus::add',
 
 
276
                                     'Add as versioned file')
 
 
277
                item.connect('activate', self.add_cb, vfs_file)
 
 
280
                item = nautilus.MenuItem('BzrNautilus::ignore',
 
 
282
                                     'Ignore file for versioning')
 
 
283
                item.connect('activate', self.ignore_cb, vfs_file)
 
 
285
            elif file_class == 'I':
 
 
286
                item = nautilus.MenuItem('BzrNautilus::unignore',
 
 
288
                                     'Unignore file for versioning')
 
 
289
                item.connect('activate', self.unignore_cb, vfs_file)
 
 
291
            elif file_class == 'V':
 
 
292
                item = nautilus.MenuItem('BzrNautilus::log',
 
 
295
                item.connect('activate', self.log_cb, vfs_file)
 
 
298
                item = nautilus.MenuItem('BzrNautilus::diff',
 
 
301
                item.connect('activate', self.diff_cb, vfs_file)
 
 
304
                item = nautilus.MenuItem('BzrNautilus::remove',
 
 
306
                                     'Remove this file from versioning')
 
 
307
                item.connect('activate', self.remove_cb, vfs_file)
 
 
310
                item = nautilus.MenuItem('BzrNautilus::annotate',
 
 
312
                             'Annotate File Data')
 
 
313
                item.connect('activate', self.annotate_cb, vfs_file)
 
 
316
                item = nautilus.MenuItem('BzrNautilus::commit',
 
 
319
                item.connect('activate', self.commit_cb, vfs_file)
 
 
324
    def get_columns(self):
 
 
325
        return nautilus.Column("BzrNautilus::bzr_status",
 
 
328
                               "Version control status"),
 
 
330
    def update_file_info(self, file):
 
 
331
        if file.get_uri_scheme() != 'file':
 
 
335
            tree, path = WorkingTree.open_containing(file.get_uri())
 
 
336
        except NotBranchError:
 
 
342
        if tree.has_filename(path):
 
 
343
            emblem = 'cvs-controlled'
 
 
345
            id = tree.path2id(path)
 
 
347
            delta = tree.changes_from(tree.branch.basis_tree())
 
 
348
            if delta.touches_file_id(id):
 
 
349
                emblem = 'cvs-modified'
 
 
351
            for f, _, _ in delta.added:
 
 
356
            for of, f, _, _, _, _ in delta.renamed:
 
 
358
                    status = 'renamed from %s' % f
 
 
360
        elif tree.branch.basis_tree().has_filename(path):
 
 
361
            emblem = 'cvs-removed'
 
 
364
            # FIXME: Check for ignored files
 
 
365
            status = 'unversioned'
 
 
367
        if emblem is not None:
 
 
368
            file.add_emblem(emblem)
 
 
369
        file.add_string_attribute('bzr_status', status)