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.tree import file_status
16
from bzrlib.workingtree import WorkingTree
17
from bzrlib.config import GlobalConfig
19
from bzrlib.plugin import load_plugins
22
from bzrlib.plugins.gtk import _i18n, cmd_gannotate, start_viz_window
24
print "Bazaar nautilus module initialized"
27
class BzrExtension(nautilus.MenuProvider, nautilus.ColumnProvider, nautilus.InfoProvider):
31
def add_cb(self, menu, vfs_file):
32
# We can only cope with local files
33
if vfs_file.get_uri_scheme() != 'file':
36
file = vfs_file.get_uri()
38
tree, path = WorkingTree.open_containing(file)
39
except NotBranchError:
46
def ignore_cb(self, menu, vfs_file):
47
# We can only cope with local files
48
if vfs_file.get_uri_scheme() != 'file':
51
file = vfs_file.get_uri()
53
tree, path = WorkingTree.open_containing(file)
54
except NotBranchError:
61
def unignore_cb(self, menu, vfs_file):
62
# We can only cope with local files
63
if vfs_file.get_uri_scheme() != 'file':
66
file = vfs_file.get_uri()
68
tree, path = WorkingTree.open_containing(file)
69
except NotBranchError:
76
def diff_cb(self, menu, vfs_file):
77
# We can only cope with local files
78
if vfs_file.get_uri_scheme() != 'file':
81
file = vfs_file.get_uri()
83
tree, path = WorkingTree.open_containing(file)
84
except NotBranchError:
87
from bzrlib.plugins.gtk.diff import DiffWindow
89
window.set_diff(tree.branch._get_nick(local=True), tree,
90
tree.branch.basis_tree())
95
def newtree_cb(self, menu, vfs_file):
96
# We can only cope with local files
97
if vfs_file.get_uri_scheme() != 'file':
100
file = vfs_file.get_uri()
102
# We only want to continue here if we get a NotBranchError
104
tree, path = WorkingTree.open_containing(file)
105
except NotBranchError:
106
BzrDir.create_standalone_workingtree(file)
108
def remove_cb(self, menu, vfs_file):
109
# We can only cope with local files
110
if vfs_file.get_uri_scheme() != 'file':
113
file = vfs_file.get_uri()
115
tree, path = WorkingTree.open_containing(file)
116
except NotBranchError:
121
def annotate_cb(self, menu, vfs_file):
122
# We can only cope with local files
123
if vfs_file.get_uri_scheme() != 'file':
126
file = vfs_file.get_uri()
128
vis = cmd_gannotate()
131
def clone_cb(self, menu, vfs_file=None):
132
# We can only cope with local files
133
if vfs_file.get_uri_scheme() != 'file':
136
from bzrlib.plugins.gtk.branch import BranchDialog
138
dialog = BranchDialog(vfs_file.get_name())
139
response = dialog.run()
140
if response != gtk.RESPONSE_NONE:
144
def commit_cb(self, menu, vfs_file=None):
145
# We can only cope with local files
146
if vfs_file.get_uri_scheme() != 'file':
149
file = vfs_file.get_uri()
153
tree, path = WorkingTree.open_containing(file)
155
except NotBranchError, e:
158
except NoWorkingTree, e:
161
(branch, path) = Branch.open_containing(path)
162
except NotBranchError, e:
165
from bzrlib.plugins.gtk.commit import CommitDialog
166
dialog = CommitDialog(tree, path)
167
response = dialog.run()
168
if response != gtk.RESPONSE_NONE:
172
def log_cb(self, menu, vfs_file):
173
# We can only cope with local files
174
if vfs_file.get_uri_scheme() != 'file':
177
file = vfs_file.get_uri()
179
# We only want to continue here if we get a NotBranchError
181
branch, path = Branch.open_containing(file)
182
except NotBranchError:
185
pp = start_viz_window(branch, [branch.last_revision()])
189
def pull_cb(self, menu, vfs_file):
190
# We can only cope with local files
191
if vfs_file.get_uri_scheme() != 'file':
194
file = vfs_file.get_uri()
196
# We only want to continue here if we get a NotBranchError
198
tree, path = WorkingTree.open_containing(file)
199
except NotBranchError:
202
from bzrlib.plugins.gtk.pull import PullDialog
203
dialog = PullDialog(tree, path)
207
def merge_cb(self, menu, vfs_file):
208
# We can only cope with local files
209
if vfs_file.get_uri_scheme() != 'file':
212
file = vfs_file.get_uri()
214
# We only want to continue here if we get a NotBranchError
216
tree, path = WorkingTree.open_containing(file)
217
except NotBranchError:
220
from bzrlib.plugins.gtk.merge import MergeDialog
221
dialog = MergeDialog(tree, path)
225
def get_background_items(self, window, vfs_file):
227
file = vfs_file.get_uri()
230
tree, path = WorkingTree.open_containing(file)
231
disabled_flag = self.check_branch_enabled(tree.branch)
232
except UnsupportedProtocol:
234
except NotBranchError:
235
disabled_flag = self.check_branch_enabled()
236
item = nautilus.MenuItem('BzrNautilus::newtree',
237
'Make directory versioned',
238
'Create new Bazaar tree in this folder')
239
item.connect('activate', self.newtree_cb, vfs_file)
242
item = nautilus.MenuItem('BzrNautilus::clone',
243
'Checkout Bazaar branch ...',
244
'Checkout Existing Bazaar Branch')
245
item.connect('activate', self.clone_cb, vfs_file)
249
except NoWorkingTree:
252
if disabled_flag == 'False':
253
item = nautilus.MenuItem('BzrNautilus::enable',
254
'Enable Bazaar Plugin for this Branch',
255
'Enable Bazaar plugin for nautilus')
256
item.connect('activate', self.toggle_integration, 'True', vfs_file)
259
item = nautilus.MenuItem('BzrNautilus::disable',
260
'Disable Bazaar Plugin this Branch',
261
'Disable Bazaar plugin for nautilus')
262
item.connect('activate', self.toggle_integration, 'False', vfs_file)
265
item = nautilus.MenuItem('BzrNautilus::log',
267
'Show Bazaar history')
268
item.connect('activate', self.log_cb, vfs_file)
271
item = nautilus.MenuItem('BzrNautilus::pull',
273
'Pull from another branch')
274
item.connect('activate', self.pull_cb, vfs_file)
277
item = nautilus.MenuItem('BzrNautilus::merge',
279
'Merge from another branch')
280
item.connect('activate', self.merge_cb, vfs_file)
283
item = nautilus.MenuItem('BzrNautilus::commit',
286
item.connect('activate', self.commit_cb, vfs_file)
291
def get_file_items(self, window, files):
295
for vfs_file in files:
296
# We can only cope with local files
297
if vfs_file.get_uri_scheme() != 'file':
300
file = vfs_file.get_uri()
302
tree, path = WorkingTree.open_containing(file)
303
disabled_flag = self.check_branch_enabled(tree.branch)
304
except NotBranchError:
305
disabled_flag = self.check_branch_enabled()
306
if not vfs_file.is_directory():
309
if disabled_flag == 'False':
312
item = nautilus.MenuItem('BzrNautilus::newtree',
313
'Make directory versioned',
314
'Create new Bazaar tree in %s' % vfs_file.get_name())
315
item.connect('activate', self.newtree_cb, vfs_file)
317
except NoWorkingTree:
319
# Refresh the list of filestatuses in the working tree
320
if path not in wtfiles.keys():
322
for rpath, file_class, kind, id, entry in tree.list_files():
323
wtfiles[rpath] = file_class
327
if wtfiles[path] == '?':
328
item = nautilus.MenuItem('BzrNautilus::add',
330
'Add as versioned file')
331
item.connect('activate', self.add_cb, vfs_file)
334
item = nautilus.MenuItem('BzrNautilus::ignore',
336
'Ignore file for versioning')
337
item.connect('activate', self.ignore_cb, vfs_file)
339
elif wtfiles[path] == 'I':
340
item = nautilus.MenuItem('BzrNautilus::unignore',
342
'Unignore file for versioning')
343
item.connect('activate', self.unignore_cb, vfs_file)
345
elif wtfiles[path] == 'V':
346
item = nautilus.MenuItem('BzrNautilus::log',
349
item.connect('activate', self.log_cb, vfs_file)
352
item = nautilus.MenuItem('BzrNautilus::diff',
355
item.connect('activate', self.diff_cb, vfs_file)
358
item = nautilus.MenuItem('BzrNautilus::remove',
360
'Remove this file from versioning')
361
item.connect('activate', self.remove_cb, vfs_file)
364
item = nautilus.MenuItem('BzrNautilus::annotate',
366
'Annotate File Data')
367
item.connect('activate', self.annotate_cb, vfs_file)
370
item = nautilus.MenuItem('BzrNautilus::commit',
373
item.connect('activate', self.commit_cb, vfs_file)
378
def get_columns(self):
379
return nautilus.Column("BzrNautilus::bzr_status",
382
"Version control status"),
384
def update_file_info(self, file):
386
if file.get_uri_scheme() != 'file':
390
tree, path = WorkingTree.open_containing(file.get_uri())
391
except NotBranchError:
393
except NoWorkingTree:
396
disabled_flag = self.check_branch_enabled(tree.branch)
397
if disabled_flag == 'False':
403
if tree.has_filename(path):
404
emblem = 'bzr-controlled'
406
id = tree.path2id(path)
408
delta = tree.changes_from(tree.branch.basis_tree())
409
if delta.touches_file_id(id):
410
emblem = 'bzr-modified'
412
for f, _, _ in delta.added:
417
for of, f, _, _, _, _ in delta.renamed:
419
status = 'renamed from %s' % f
421
elif tree.branch.basis_tree().has_filename(path):
422
emblem = 'bzr-removed'
425
# FIXME: Check for ignored files
426
status = 'unversioned'
428
if emblem is not None:
429
file.add_emblem(emblem)
430
file.add_string_attribute('bzr_status', status)
432
def check_branch_enabled(self, branch=None):
433
# Supports global disable, but there is currently no UI to do this
434
config = GlobalConfig()
435
disabled_flag = config.get_user_option('nautilus_integration')
436
if disabled_flag != 'False':
437
if branch is not None:
438
config = branch.get_config()
439
disabled_flag = config.get_user_option('nautilus_integration')
442
def toggle_integration(self, menu, action, vfs_file=None):
444
tree, path = WorkingTree.open_containing(vfs_file.get_uri())
445
except NotBranchError:
447
except NoWorkingTree:
451
config = GlobalConfig()
453
config = branch.get_config()
454
config.set_user_option('nautilus_integration', action)