25
25
# You can also install nautilus-bzr manually by copying it (or linking it from)
26
26
# ~/.local/share/nautilus-python/extensions/nautilus-bzr.py
28
from gi.repository import Gtk
30
from bzrlib.branch import Branch
31
from bzrlib.bzrdir import BzrDir
28
from gi.repository import Gtk, Nautilus, GObject
29
from bzrlib.controldir import ControlDir
32
30
from bzrlib.errors import (
34
from bzrlib.tree import InterTree
37
35
from bzrlib.workingtree import WorkingTree
38
from bzrlib.config import GlobalConfig
40
37
from bzrlib.plugin import load_plugins
43
from bzrlib.plugins.gtk.commands import (
48
class BzrExtension(nautilus.MenuProvider, nautilus.ColumnProvider, nautilus.InfoProvider):
41
class BazaarExtension(Nautilus.MenuProvider, Nautilus.ColumnProvider,
42
Nautilus.InfoProvider, Nautilus.PropertyPageProvider, GObject.GObject):
43
"""Nautilus extension providing Bazaar integration."""
50
45
def __init__(self):
49
def _open_bzrdir(cls, vfs_file):
50
uri = vfs_file.get_uri()
51
controldir, path = ControlDir.open_containing(uri)
52
return controldir, path
53
54
def add_cb(self, menu, vfs_file):
54
# We can only cope with local files
55
if vfs_file.get_uri_scheme() != 'file':
58
file = vfs_file.get_uri()
60
tree, path = WorkingTree.open_containing(file)
61
except NotBranchError:
55
controldir, path = self._open_bzrdir(vfs_file)
56
tree = controldir.open_workingtree()
68
59
def ignore_cb(self, menu, vfs_file):
69
60
# We can only cope with local files
70
if vfs_file.get_uri_scheme() != 'file':
73
file = vfs_file.get_uri()
75
tree, path = WorkingTree.open_containing(file)
76
except NotBranchError:
61
controldir, path = self._open_bzrdir(vfs_file)
62
tree = controldir.open_workingtree()
63
#FIXME: Add path to ignore file
83
66
def unignore_cb(self, menu, vfs_file):
84
67
# We can only cope with local files
85
if vfs_file.get_uri_scheme() != 'file':
88
file = vfs_file.get_uri()
90
tree, path = WorkingTree.open_containing(file)
91
except NotBranchError:
68
controldir, path = self._open_bzrdir(vfs_file)
69
tree = controldir.open_workingtree()
98
73
def diff_cb(self, menu, vfs_file):
99
# We can only cope with local files
100
if vfs_file.get_uri_scheme() != 'file':
103
file = vfs_file.get_uri()
105
tree, path = WorkingTree.open_containing(file)
106
except NotBranchError:
74
controldir, path = self._open_bzrdir(vfs_file)
75
tree = controldir.open_workingtree()
109
76
from bzrlib.plugins.gtk.diff import DiffWindow
110
77
window = DiffWindow()
111
78
window.set_diff(tree.branch._get_nick(local=True), tree,
117
84
def newtree_cb(self, menu, vfs_file):
118
# We can only cope with local files
119
if vfs_file.get_uri_scheme() != 'file':
122
file = vfs_file.get_uri()
124
# We only want to continue here if we get a NotBranchError
126
tree, path = WorkingTree.open_containing(file)
127
except NotBranchError:
128
BzrDir.create_standalone_workingtree(file)
85
controldir, path = self._open_bzrdir(vfs_file)
86
controldir.create_workingtree()
130
88
def remove_cb(self, menu, vfs_file):
131
# We can only cope with local files
132
if vfs_file.get_uri_scheme() != 'file':
135
file = vfs_file.get_uri()
137
tree, path = WorkingTree.open_containing(file)
138
except NotBranchError:
89
controldir, path = self._open_bzrdir(vfs_file)
90
tree = controldir.open_workingtree()
143
93
def annotate_cb(self, menu, vfs_file):
144
# We can only cope with local files
145
if vfs_file.get_uri_scheme() != 'file':
148
file = vfs_file.get_uri()
150
vis = cmd_gannotate()
94
from bzrlib.plugins.gtk.annotate.gannotate import GAnnotateWindow
95
controldir, path = self._open_bzrdir(vfs_file)
96
win = GAnnotateWindow()
97
win.annotate(controldir.open_workingtree(), controldir.open_branch(), path)
153
100
def clone_cb(self, menu, vfs_file=None):
154
# We can only cope with local files
155
if vfs_file.get_uri_scheme() != 'file':
158
101
from bzrlib.plugins.gtk.branch import BranchDialog
102
controldir, path = self._open_bzrdir(vfs_file)
160
104
dialog = BranchDialog(vfs_file.get_name())
161
105
response = dialog.run()
162
106
if response != Gtk.ResponseType.NONE:
166
110
def commit_cb(self, menu, vfs_file=None):
167
# We can only cope with local files
168
if vfs_file.get_uri_scheme() != 'file':
171
file = vfs_file.get_uri()
175
tree, path = WorkingTree.open_containing(file)
177
except NotBranchError, e:
180
except NoWorkingTree, e:
183
(branch, path) = Branch.open_containing(path)
184
except NotBranchError, e:
111
controldir, path = self._open_bzrdir(vfs_file)
112
tree = controldir.open_workingtree()
187
114
from bzrlib.plugins.gtk.commit import CommitDialog
188
115
dialog = CommitDialog(tree, path)
194
121
def log_cb(self, menu, vfs_file):
195
# We can only cope with local files
196
if vfs_file.get_uri_scheme() != 'file':
199
file = vfs_file.get_uri()
201
# We only want to continue here if we get a NotBranchError
203
branch, path = Branch.open_containing(file)
204
except NotBranchError:
122
controldir, path = self._open_bzrdir(vfs_file)
123
branch = controldir.open_branch()
207
124
pp = start_viz_window(branch, [branch.last_revision()])
211
128
def pull_cb(self, menu, vfs_file):
212
# We can only cope with local files
213
if vfs_file.get_uri_scheme() != 'file':
216
file = vfs_file.get_uri()
218
# We only want to continue here if we get a NotBranchError
220
tree, path = WorkingTree.open_containing(file)
221
except NotBranchError:
129
controldir, path = self._open_bzrdir(vfs_file)
130
tree = controldir.open_workingtree()
224
131
from bzrlib.plugins.gtk.pull import PullDialog
225
132
dialog = PullDialog(tree, path)
229
136
def merge_cb(self, menu, vfs_file):
230
# We can only cope with local files
231
if vfs_file.get_uri_scheme() != 'file':
234
file = vfs_file.get_uri()
236
# We only want to continue here if we get a NotBranchError
238
tree, path = WorkingTree.open_containing(file)
239
except NotBranchError:
137
controldir, path = self._open_bzrdir(vfs_file)
138
tree = controldir.open_workingtree()
242
139
from bzrlib.plugins.gtk.merge import MergeDialog
243
140
dialog = MergeDialog(tree, path)
247
144
def get_background_items(self, window, vfs_file):
249
file = vfs_file.get_uri()
252
tree, path = WorkingTree.open_containing(file)
253
disabled_flag = self.check_branch_enabled(tree.branch)
254
except UnsupportedProtocol:
146
controldir, path = self._open_bzrdir(vfs_file)
147
except NotBranchError:
150
branch = controldir.open_branch()
256
151
except NotBranchError:
257
disabled_flag = self.check_branch_enabled()
258
item = nautilus.MenuItem('BzrNautilus::newtree',
153
item = Nautilus.MenuItem('BzrNautilus::newtree',
259
154
'Make directory versioned',
260
155
'Create new Bazaar tree in this folder')
261
156
item.connect('activate', self.newtree_cb, vfs_file)
262
157
items.append(item)
264
item = nautilus.MenuItem('BzrNautilus::clone',
159
item = Nautilus.MenuItem('BzrNautilus::clone',
265
160
'Checkout Bazaar branch ...',
266
161
'Checkout Existing Bazaar Branch')
267
162
item.connect('activate', self.clone_cb, vfs_file)
268
163
items.append(item)
271
except NoWorkingTree:
274
if disabled_flag == 'False':
275
item = nautilus.MenuItem('BzrNautilus::enable',
168
nautilus_integration = self.check_branch_enabled(branch)
169
if not nautilus_integration:
170
item = Nautilus.MenuItem('BzrNautilus::enable',
276
171
'Enable Bazaar Plugin for this Branch',
277
172
'Enable Bazaar plugin for nautilus')
278
item.connect('activate', self.toggle_integration, 'True', vfs_file)
173
item.connect('activate', self.toggle_integration, True, vfs_file)
281
item = nautilus.MenuItem('BzrNautilus::disable',
282
'Disable Bazaar Plugin this Branch',
283
'Disable Bazaar plugin for nautilus')
284
item.connect('activate', self.toggle_integration, 'False', vfs_file)
176
item = Nautilus.MenuItem('BzrNautilus::disable',
177
'Disable Bazaar Plugin this Branch',
178
'Disable Bazaar plugin for nautilus')
179
item.connect('activate', self.toggle_integration, False, vfs_file)
285
180
items.append(item)
287
item = nautilus.MenuItem('BzrNautilus::log',
182
item = Nautilus.MenuItem('BzrNautilus::log',
289
184
'Show Bazaar history')
290
185
item.connect('activate', self.log_cb, vfs_file)
291
186
items.append(item)
293
item = nautilus.MenuItem('BzrNautilus::pull',
188
item = Nautilus.MenuItem('BzrNautilus::pull',
295
190
'Pull from another branch')
296
191
item.connect('activate', self.pull_cb, vfs_file)
297
192
items.append(item)
299
item = nautilus.MenuItem('BzrNautilus::merge',
301
'Merge from another branch')
302
item.connect('activate', self.merge_cb, vfs_file)
195
tree = controldir.open_workingtree()
196
except NoWorkingTree:
197
item = Nautilus.MenuItem('BzrNautilus::create_tree',
198
'Create working tree...',
199
'Create a working tree for this branch')
200
item.connect('activate', self.create_tree_cb, vfs_file)
203
item = Nautilus.MenuItem('BzrNautilus::merge',
205
'Merge from another branch')
206
item.connect('activate', self.merge_cb, vfs_file)
305
item = nautilus.MenuItem('BzrNautilus::commit',
308
item.connect('activate', self.commit_cb, vfs_file)
209
item = Nautilus.MenuItem('BzrNautilus::commit',
212
item.connect('activate', self.commit_cb, vfs_file)
313
217
def get_file_items(self, window, files):
317
220
for vfs_file in files:
318
# We can only cope with local files
319
if vfs_file.get_uri_scheme() != 'file':
221
controldir, path = self._open_bzrdir(vfs_file)
322
file = vfs_file.get_uri()
324
tree, path = WorkingTree.open_containing(file)
325
disabled_flag = self.check_branch_enabled(tree.branch)
326
except NotBranchError:
327
disabled_flag = self.check_branch_enabled()
328
if not vfs_file.is_directory():
331
if disabled_flag == 'False':
334
item = nautilus.MenuItem('BzrNautilus::newtree',
335
'Make directory versioned',
336
'Create new Bazaar tree in %s' % vfs_file.get_name())
337
item.connect('activate', self.newtree_cb, vfs_file)
224
tree = controldir.open_workingtree()
339
225
except NoWorkingTree:
341
# Refresh the list of filestatuses in the working tree
342
if path not in wtfiles.keys():
344
for rpath, file_class, kind, id, entry in tree.list_files():
345
wtfiles[rpath] = file_class
349
if wtfiles[path] == '?':
350
item = nautilus.MenuItem('BzrNautilus::add',
228
nautilus_integration = self.check_branch_enabled(tree.branch)
229
if not nautilus_integration:
232
file_id = tree.path2id(path)
234
item = Nautilus.MenuItem('BzrNautilus::add',
352
236
'Add as versioned file')
353
237
item.connect('activate', self.add_cb, vfs_file)
354
238
items.append(item)
356
item = nautilus.MenuItem('BzrNautilus::ignore',
240
item = Nautilus.MenuItem('BzrNautilus::ignore',
358
242
'Ignore file for versioning')
359
243
item.connect('activate', self.ignore_cb, vfs_file)
360
244
items.append(item)
361
elif wtfiles[path] == 'I':
362
item = nautilus.MenuItem('BzrNautilus::unignore',
245
elif tree.is_ignored(path):
246
item = Nautilus.MenuItem('BzrNautilus::unignore',
364
248
'Unignore file for versioning')
365
249
item.connect('activate', self.unignore_cb, vfs_file)
366
250
items.append(item)
367
elif wtfiles[path] == 'V':
368
item = nautilus.MenuItem('BzrNautilus::log',
252
item = Nautilus.MenuItem('BzrNautilus::log',
371
255
item.connect('activate', self.log_cb, vfs_file)
372
256
items.append(item)
374
item = nautilus.MenuItem('BzrNautilus::diff',
377
item.connect('activate', self.diff_cb, vfs_file)
380
item = nautilus.MenuItem('BzrNautilus::remove',
258
intertree = InterTree.get(tree.basis_tree(), tree)
259
if not intertree.file_content_matches(file_id, file_id):
260
item = Nautilus.MenuItem('BzrNautilus::diff',
263
item.connect('activate', self.diff_cb, vfs_file)
266
item = Nautilus.MenuItem('BzrNautilus::commit',
269
item.connect('activate', self.commit_cb, vfs_file)
272
item = Nautilus.MenuItem('BzrNautilus::remove',
382
274
'Remove this file from versioning')
383
275
item.connect('activate', self.remove_cb, vfs_file)
384
276
items.append(item)
386
item = nautilus.MenuItem('BzrNautilus::annotate',
278
item = Nautilus.MenuItem('BzrNautilus::annotate',
388
280
'Annotate File Data')
389
281
item.connect('activate', self.annotate_cb, vfs_file)
390
282
items.append(item)
392
item = nautilus.MenuItem('BzrNautilus::commit',
395
item.connect('activate', self.commit_cb, vfs_file)
400
285
def get_columns(self):
401
return nautilus.Column("BzrNautilus::bzr_status",
404
"Version control status"),
287
Nautilus.Column(name="BzrNautilus::bzr_status",
288
attribute="bzr_status",
290
description="Version control status"),
291
Nautilus.Column(name="BzrNautilus::bzr_revision",
292
attribute="bzr_revision",
294
description="Last change revision"),
406
297
def update_file_info(self, file):