1
# Trivial Bazaar plugin for Nautilus
3
# Copyright (C) 2006 Jeff Bailey
4
# Copyright (C) 2006 Wouter van Heyst
5
# Copyright (C) 2006-2008 Jelmer Vernooij <jelmer@samba.org>
7
# Published under the GNU GPL
12
from bzrlib.branch import Branch
13
from bzrlib.bzrdir import BzrDir
14
from bzrlib.errors import NotBranchError, NoWorkingTree, UnsupportedProtocol
15
from bzrlib.workingtree import WorkingTree
16
from bzrlib.config import GlobalConfig
18
from bzrlib.plugin import load_plugins
21
from bzrlib.plugins.gtk.commands import cmd_gannotate, start_viz_window
23
print "Bazaar nautilus module initialized"
26
class BzrExtension(nautilus.MenuProvider, nautilus.ColumnProvider, nautilus.InfoProvider):
30
def add_cb(self, menu, vfs_file):
31
# We can only cope with local files
32
if vfs_file.get_uri_scheme() != 'file':
35
file = vfs_file.get_uri()
37
tree, path = WorkingTree.open_containing(file)
38
except NotBranchError:
45
def ignore_cb(self, menu, vfs_file):
46
# We can only cope with local files
47
if vfs_file.get_uri_scheme() != 'file':
50
file = vfs_file.get_uri()
52
tree, path = WorkingTree.open_containing(file)
53
except NotBranchError:
60
def unignore_cb(self, menu, vfs_file):
61
# We can only cope with local files
62
if vfs_file.get_uri_scheme() != 'file':
65
file = vfs_file.get_uri()
67
tree, path = WorkingTree.open_containing(file)
68
except NotBranchError:
75
def diff_cb(self, menu, vfs_file):
76
# We can only cope with local files
77
if vfs_file.get_uri_scheme() != 'file':
80
file = vfs_file.get_uri()
82
tree, path = WorkingTree.open_containing(file)
83
except NotBranchError:
86
from bzrlib.plugins.gtk.diff import DiffWindow
88
window.set_diff(tree.branch._get_nick(local=True), tree,
89
tree.branch.basis_tree())
94
def newtree_cb(self, menu, vfs_file):
95
# We can only cope with local files
96
if vfs_file.get_uri_scheme() != 'file':
99
file = vfs_file.get_uri()
101
# We only want to continue here if we get a NotBranchError
103
tree, path = WorkingTree.open_containing(file)
104
except NotBranchError:
105
BzrDir.create_standalone_workingtree(file)
107
def remove_cb(self, menu, vfs_file):
108
# We can only cope with local files
109
if vfs_file.get_uri_scheme() != 'file':
112
file = vfs_file.get_uri()
114
tree, path = WorkingTree.open_containing(file)
115
except NotBranchError:
120
def annotate_cb(self, menu, vfs_file):
121
# We can only cope with local files
122
if vfs_file.get_uri_scheme() != 'file':
125
file = vfs_file.get_uri()
127
vis = cmd_gannotate()
130
def clone_cb(self, menu, vfs_file=None):
131
# We can only cope with local files
132
if vfs_file.get_uri_scheme() != 'file':
135
from bzrlib.plugins.gtk.branch import BranchDialog
137
dialog = BranchDialog(vfs_file.get_name())
138
response = dialog.run()
139
if response != gtk.RESPONSE_NONE:
143
def commit_cb(self, menu, vfs_file=None):
144
# We can only cope with local files
145
if vfs_file.get_uri_scheme() != 'file':
148
file = vfs_file.get_uri()
152
tree, path = WorkingTree.open_containing(file)
154
except NotBranchError, e:
157
except NoWorkingTree, e:
160
(branch, path) = Branch.open_containing(path)
161
except NotBranchError, e:
164
from bzrlib.plugins.gtk.commit import CommitDialog
165
dialog = CommitDialog(tree, path)
166
response = dialog.run()
167
if response != gtk.RESPONSE_NONE:
171
def log_cb(self, menu, vfs_file):
172
# We can only cope with local files
173
if vfs_file.get_uri_scheme() != 'file':
176
file = vfs_file.get_uri()
178
# We only want to continue here if we get a NotBranchError
180
branch, path = Branch.open_containing(file)
181
except NotBranchError:
184
pp = start_viz_window(branch, [branch.last_revision()])
188
def pull_cb(self, menu, vfs_file):
189
# We can only cope with local files
190
if vfs_file.get_uri_scheme() != 'file':
193
file = vfs_file.get_uri()
195
# We only want to continue here if we get a NotBranchError
197
tree, path = WorkingTree.open_containing(file)
198
except NotBranchError:
201
from bzrlib.plugins.gtk.pull import PullDialog
202
dialog = PullDialog(tree, path)
206
def merge_cb(self, menu, vfs_file):
207
# We can only cope with local files
208
if vfs_file.get_uri_scheme() != 'file':
211
file = vfs_file.get_uri()
213
# We only want to continue here if we get a NotBranchError
215
tree, path = WorkingTree.open_containing(file)
216
except NotBranchError:
219
from bzrlib.plugins.gtk.merge import MergeDialog
220
dialog = MergeDialog(tree, path)
224
def get_background_items(self, window, vfs_file):
226
file = vfs_file.get_uri()
229
tree, path = WorkingTree.open_containing(file)
230
disabled_flag = self.check_branch_enabled(tree.branch)
231
except UnsupportedProtocol:
233
except NotBranchError:
234
disabled_flag = self.check_branch_enabled()
235
item = nautilus.MenuItem('BzrNautilus::newtree',
236
'Make directory versioned',
237
'Create new Bazaar tree in this folder')
238
item.connect('activate', self.newtree_cb, vfs_file)
241
item = nautilus.MenuItem('BzrNautilus::clone',
242
'Checkout Bazaar branch ...',
243
'Checkout Existing Bazaar Branch')
244
item.connect('activate', self.clone_cb, vfs_file)
248
except NoWorkingTree:
251
if disabled_flag == 'False':
252
item = nautilus.MenuItem('BzrNautilus::enable',
253
'Enable Bazaar Plugin for this Branch',
254
'Enable Bazaar plugin for nautilus')
255
item.connect('activate', self.toggle_integration, 'True', vfs_file)
258
item = nautilus.MenuItem('BzrNautilus::disable',
259
'Disable Bazaar Plugin this Branch',
260
'Disable Bazaar plugin for nautilus')
261
item.connect('activate', self.toggle_integration, 'False', vfs_file)
264
item = nautilus.MenuItem('BzrNautilus::log',
266
'Show Bazaar history')
267
item.connect('activate', self.log_cb, vfs_file)
270
item = nautilus.MenuItem('BzrNautilus::pull',
272
'Pull from another branch')
273
item.connect('activate', self.pull_cb, vfs_file)
276
item = nautilus.MenuItem('BzrNautilus::merge',
278
'Merge from another branch')
279
item.connect('activate', self.merge_cb, vfs_file)
282
item = nautilus.MenuItem('BzrNautilus::commit',
285
item.connect('activate', self.commit_cb, vfs_file)
290
def get_file_items(self, window, files):
294
for vfs_file in files:
295
# We can only cope with local files
296
if vfs_file.get_uri_scheme() != 'file':
299
file = vfs_file.get_uri()
301
tree, path = WorkingTree.open_containing(file)
302
disabled_flag = self.check_branch_enabled(tree.branch)
303
except NotBranchError:
304
disabled_flag = self.check_branch_enabled()
305
if not vfs_file.is_directory():
308
if disabled_flag == 'False':
311
item = nautilus.MenuItem('BzrNautilus::newtree',
312
'Make directory versioned',
313
'Create new Bazaar tree in %s' % vfs_file.get_name())
314
item.connect('activate', self.newtree_cb, vfs_file)
316
except NoWorkingTree:
318
# Refresh the list of filestatuses in the working tree
319
if path not in wtfiles.keys():
321
for rpath, file_class, kind, id, entry in tree.list_files():
322
wtfiles[rpath] = file_class
326
if wtfiles[path] == '?':
327
item = nautilus.MenuItem('BzrNautilus::add',
329
'Add as versioned file')
330
item.connect('activate', self.add_cb, vfs_file)
333
item = nautilus.MenuItem('BzrNautilus::ignore',
335
'Ignore file for versioning')
336
item.connect('activate', self.ignore_cb, vfs_file)
338
elif wtfiles[path] == 'I':
339
item = nautilus.MenuItem('BzrNautilus::unignore',
341
'Unignore file for versioning')
342
item.connect('activate', self.unignore_cb, vfs_file)
344
elif wtfiles[path] == 'V':
345
item = nautilus.MenuItem('BzrNautilus::log',
348
item.connect('activate', self.log_cb, vfs_file)
351
item = nautilus.MenuItem('BzrNautilus::diff',
354
item.connect('activate', self.diff_cb, vfs_file)
357
item = nautilus.MenuItem('BzrNautilus::remove',
359
'Remove this file from versioning')
360
item.connect('activate', self.remove_cb, vfs_file)
363
item = nautilus.MenuItem('BzrNautilus::annotate',
365
'Annotate File Data')
366
item.connect('activate', self.annotate_cb, vfs_file)
369
item = nautilus.MenuItem('BzrNautilus::commit',
372
item.connect('activate', self.commit_cb, vfs_file)
377
def get_columns(self):
378
return nautilus.Column("BzrNautilus::bzr_status",
381
"Version control status"),
383
def update_file_info(self, file):
385
if file.get_uri_scheme() != 'file':
389
tree, path = WorkingTree.open_containing(file.get_uri())
390
except NotBranchError:
392
except NoWorkingTree:
395
disabled_flag = self.check_branch_enabled(tree.branch)
396
if disabled_flag == 'False':
402
id = tree.path2id(path)
404
if tree.is_ignored(path):
406
emblem = 'bzr-ignored'
408
status = 'unversioned'
410
elif tree.has_filename(path):
411
emblem = 'bzr-controlled'
414
delta = tree.changes_from(tree.branch.basis_tree())
415
if delta.touches_file_id(id):
416
emblem = 'bzr-modified'
418
for f, _, _ in delta.added:
423
for of, f, _, _, _, _ in delta.renamed:
425
status = 'renamed from %s' % f
427
elif tree.branch.basis_tree().has_filename(path):
428
emblem = 'bzr-removed'
431
# FIXME: Check for ignored files
432
status = 'unversioned'
434
if emblem is not None:
435
file.add_emblem(emblem)
436
file.add_string_attribute('bzr_status', status)
438
def check_branch_enabled(self, branch=None):
439
# Supports global disable, but there is currently no UI to do this
440
config = GlobalConfig()
441
disabled_flag = config.get_user_option('nautilus_integration')
442
if disabled_flag != 'False':
443
if branch is not None:
444
config = branch.get_config()
445
disabled_flag = config.get_user_option('nautilus_integration')
448
def toggle_integration(self, menu, action, vfs_file=None):
450
tree, path = WorkingTree.open_containing(vfs_file.get_uri())
451
except NotBranchError:
453
except NoWorkingTree:
457
config = GlobalConfig()
459
config = branch.get_config()
460
config.set_user_option('nautilus_integration', action)