/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to nautilus-bzr.py

  • Committer: Jelmer Vernooij
  • Date: 2011-02-18 13:01:03 UTC
  • Revision ID: jelmer@samba.org-20110218130103-fiyk203auk28thpn
Remove some unused imports, fix some formatting.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
#
3
3
# Copyright (C) 2006 Jeff Bailey
4
4
# Copyright (C) 2006 Wouter van Heyst
5
 
# Copyright (C) 2006-2011 Jelmer Vernooij <jelmer@samba.org>
6
 
#
7
 
# This program is free software; you can redistribute it and/or modify
8
 
# it under the terms of the GNU General Public License as published by
9
 
# the Free Software Foundation; either version 3 of the License, or
10
 
# (at your option) any later version.
11
 
 
12
 
# This program is distributed in the hope that it will be useful,
13
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
# GNU General Public License for more details.
16
 
 
17
 
# You should have received a copy of the GNU General Public License
18
 
# along with this program; if not, write to the Free Software
19
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 
 
21
 
# Installation:
22
 
# setup.py can install nautilus-bzr to the right system folder, if pkg-config
23
 
# is present.
24
 
#
25
 
# You can also install nautilus-bzr manually by copying it (or linking it from)
26
 
# ~/.local/share/nautilus-python/extensions/nautilus-bzr.py
27
 
 
28
 
from gi.repository import Gtk, GObject, Nautilus
29
 
from bzrlib.controldir import ControlDir
30
 
from bzrlib.errors import (
31
 
    NotBranchError,
32
 
    NoWorkingTree,
33
 
    )
34
 
from bzrlib.ignores import tree_ignores_add_patterns
35
 
from bzrlib.tree import InterTree
 
5
# Copyright (C) 2006-2008 Jelmer Vernooij <jelmer@samba.org>
 
6
#
 
7
# Published under the GNU GPL
 
8
 
 
9
import gtk
 
10
import nautilus
 
11
import bzrlib
 
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
36
17
 
37
18
from bzrlib.plugin import load_plugins
38
19
load_plugins()
39
20
 
40
 
 
41
 
class BazaarExtension(Nautilus.MenuProvider, Nautilus.ColumnProvider,
42
 
        Nautilus.InfoProvider, Nautilus.PropertyPageProvider, GObject.GObject):
43
 
    """Nautilus extension providing Bazaar integration."""
44
 
 
 
21
from bzrlib.plugins.gtk.commands import cmd_gannotate, start_viz_window
 
22
 
 
23
print "Bazaar nautilus module initialized"
 
24
 
 
25
 
 
26
class BzrExtension(nautilus.MenuProvider, nautilus.ColumnProvider, nautilus.InfoProvider):
45
27
    def __init__(self):
46
28
        pass
47
29
 
48
 
    @classmethod
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
 
    @classmethod
55
 
    def _open_tree(cls, vfs_file):
56
 
        controldir, path = cls._open_bzrdir(vfs_file)
57
 
        return controldir.open_workingtree(), path
58
 
 
59
 
    def add_cb(self, menu, tree, path):
 
30
    def add_cb(self, menu, vfs_file):
 
31
        # We can only cope with local files
 
32
        if vfs_file.get_uri_scheme() != 'file':
 
33
            return
 
34
 
 
35
        file = vfs_file.get_uri()
 
36
        try:
 
37
            tree, path = WorkingTree.open_containing(file)
 
38
        except NotBranchError:
 
39
            return
 
40
 
60
41
        tree.add(path)
61
42
 
62
 
    def ignore_cb(self, menu, tree, path):
63
 
        # We can only cope with local files
64
 
        tree_ignores_add_patterns(tree, [path])
65
 
        #FIXME: Add path to ignore file
66
 
 
67
 
    def unignore_cb(self, menu, tree, path):
68
 
        pass
69
 
        # We can only cope with local files
70
 
        #FIXME
71
 
 
72
 
    def diff_cb(self, menu, tree, path=None):
 
43
        return
 
44
 
 
45
    def ignore_cb(self, menu, vfs_file):
 
46
        # We can only cope with local files
 
47
        if vfs_file.get_uri_scheme() != 'file':
 
48
            return
 
49
 
 
50
        file = vfs_file.get_uri()
 
51
        try:
 
52
            tree, path = WorkingTree.open_containing(file)
 
53
        except NotBranchError:
 
54
            return
 
55
 
 
56
        #FIXME
 
57
 
 
58
        return
 
59
 
 
60
    def unignore_cb(self, menu, vfs_file):
 
61
        # We can only cope with local files
 
62
        if vfs_file.get_uri_scheme() != 'file':
 
63
            return
 
64
 
 
65
        file = vfs_file.get_uri()
 
66
        try:
 
67
            tree, path = WorkingTree.open_containing(file)
 
68
        except NotBranchError:
 
69
            return
 
70
 
 
71
        #FIXME
 
72
 
 
73
        return
 
74
 
 
75
    def diff_cb(self, menu, vfs_file):
 
76
        # We can only cope with local files
 
77
        if vfs_file.get_uri_scheme() != 'file':
 
78
            return
 
79
 
 
80
        file = vfs_file.get_uri()
 
81
        try:
 
82
            tree, path = WorkingTree.open_containing(file)
 
83
        except NotBranchError:
 
84
            return
 
85
 
73
86
        from bzrlib.plugins.gtk.diff import DiffWindow
74
87
        window = DiffWindow()
75
88
        window.set_diff(tree.branch._get_nick(local=True), tree, 
76
89
                        tree.branch.basis_tree())
77
90
        window.show()
78
91
 
 
92
        return
 
93
 
79
94
    def newtree_cb(self, menu, vfs_file):
80
 
        controldir, path = self._open_bzrdir(vfs_file)
81
 
        controldir.create_workingtree()
82
 
 
83
 
    def remove_cb(self, menu, tree, path):
 
95
        # We can only cope with local files
 
96
        if vfs_file.get_uri_scheme() != 'file':
 
97
            return
 
98
 
 
99
        file = vfs_file.get_uri()
 
100
 
 
101
        # We only want to continue here if we get a NotBranchError
 
102
        try:
 
103
            tree, path = WorkingTree.open_containing(file)
 
104
        except NotBranchError:
 
105
            BzrDir.create_standalone_workingtree(file)
 
106
 
 
107
    def remove_cb(self, menu, vfs_file):
 
108
        # We can only cope with local files
 
109
        if vfs_file.get_uri_scheme() != 'file':
 
110
            return
 
111
 
 
112
        file = vfs_file.get_uri()
 
113
        try:
 
114
            tree, path = WorkingTree.open_containing(file)
 
115
        except NotBranchError:
 
116
            return
 
117
 
84
118
        tree.remove(path)
85
119
 
86
 
    def annotate_cb(self, menu, tree, path, file_id):
87
 
        from bzrlib.plugins.gtk.annotate.gannotate import GAnnotateWindow
88
 
        win = GAnnotateWindow()
89
 
        win.show()
90
 
        win.annotate(tree, tree.branch, file_id)
91
 
        Gtk.main()
 
120
    def annotate_cb(self, menu, vfs_file):
 
121
        # We can only cope with local files
 
122
        if vfs_file.get_uri_scheme() != 'file':
 
123
            return
 
124
 
 
125
        file = vfs_file.get_uri()
 
126
 
 
127
        vis = cmd_gannotate()
 
128
        vis.run(file)
92
129
 
93
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':
 
133
            return
 
134
 
94
135
        from bzrlib.plugins.gtk.branch import BranchDialog
95
 
        controldir, path = self._open_bzrdir(vfs_file)
96
 
 
 
136
        
97
137
        dialog = BranchDialog(vfs_file.get_name())
98
138
        response = dialog.run()
99
 
        if response != Gtk.ResponseType.NONE:
 
139
        if response != gtk.RESPONSE_NONE:
100
140
            dialog.hide()
101
141
            dialog.destroy()
102
 
 
103
 
    def commit_cb(self, menu, tree, path=None):
 
142
 
 
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':
 
146
            return
 
147
 
 
148
        file = vfs_file.get_uri()
 
149
        tree = None
 
150
        branch = None
 
151
        try:
 
152
            tree, path = WorkingTree.open_containing(file)
 
153
            branch = tree.branch
 
154
        except NotBranchError, e:
 
155
            path = e.path
 
156
            #return
 
157
        except NoWorkingTree, e:
 
158
            path = e.base
 
159
            try:
 
160
                (branch, path) = Branch.open_containing(path)
 
161
            except NotBranchError, e:
 
162
                path = e.path
 
163
 
104
164
        from bzrlib.plugins.gtk.commit import CommitDialog
105
165
        dialog = CommitDialog(tree, path)
106
166
        response = dialog.run()
107
 
        if response != Gtk.ResponseType.NONE:
 
167
        if response != gtk.RESPONSE_NONE:
108
168
            dialog.hide()
109
169
            dialog.destroy()
110
170
 
111
 
    def log_cb(self, menu, controldir, path=None):
112
 
        from bzrlib.plugins.gtk.viz import BranchWindow
113
 
        branch = controldir.open_branch()
114
 
        pp = BranchWindow(branch, [branch.last_revision()], 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':
 
174
            return
 
175
 
 
176
        file = vfs_file.get_uri()
 
177
 
 
178
        # We only want to continue here if we get a NotBranchError
 
179
        try:
 
180
            branch, path = Branch.open_containing(file)
 
181
        except NotBranchError:
 
182
            return
 
183
 
 
184
        pp = start_viz_window(branch, [branch.last_revision()])
115
185
        pp.show()
116
 
        Gtk.main()
117
 
 
118
 
    def pull_cb(self, menu, controldir, path=None):
 
186
        gtk.main()
 
187
 
 
188
    def pull_cb(self, menu, vfs_file):
 
189
        # We can only cope with local files
 
190
        if vfs_file.get_uri_scheme() != 'file':
 
191
            return
 
192
 
 
193
        file = vfs_file.get_uri()
 
194
 
 
195
        # We only want to continue here if we get a NotBranchError
 
196
        try:
 
197
            tree, path = WorkingTree.open_containing(file)
 
198
        except NotBranchError:
 
199
            return
 
200
 
119
201
        from bzrlib.plugins.gtk.pull import PullDialog
120
 
        dialog = PullDialog(controldir.open_workingtree(), path)
 
202
        dialog = PullDialog(tree, path)
121
203
        dialog.display()
122
 
        Gtk.main()
123
 
 
124
 
    def merge_cb(self, menu, tree, path=None):
 
204
        gtk.main()
 
205
 
 
206
    def merge_cb(self, menu, vfs_file):
 
207
        # We can only cope with local files
 
208
        if vfs_file.get_uri_scheme() != 'file':
 
209
            return
 
210
 
 
211
        file = vfs_file.get_uri()
 
212
 
 
213
        # We only want to continue here if we get a NotBranchError
 
214
        try:
 
215
            tree, path = WorkingTree.open_containing(file)
 
216
        except NotBranchError:
 
217
            return
 
218
 
125
219
        from bzrlib.plugins.gtk.merge import MergeDialog
126
220
        dialog = MergeDialog(tree, path)
127
221
        dialog.run()
128
222
        dialog.destroy()
129
223
 
130
 
    def create_tree_cb(self, menu, controldir):
131
 
        controldir.create_workingtree()
132
 
 
133
224
    def get_background_items(self, window, vfs_file):
 
225
        items = []
 
226
        file = vfs_file.get_uri()
 
227
 
134
228
        try:
135
 
            controldir, path = self._open_bzrdir(vfs_file)
136
 
        except NotBranchError:
 
229
            tree, path = WorkingTree.open_containing(file)
 
230
            disabled_flag = self.check_branch_enabled(tree.branch)
 
231
        except UnsupportedProtocol:
137
232
            return
138
 
        try:
139
 
            branch = controldir.open_branch()
140
233
        except NotBranchError:
141
 
            items = []
142
 
            item = Nautilus.MenuItem(name='BzrNautilus::newtree',
143
 
                                 label='Make directory versioned',
144
 
                                 tip='Create new Bazaar tree in this folder',
145
 
                                 icon='')
 
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')
146
238
            item.connect('activate', self.newtree_cb, vfs_file)
147
239
            items.append(item)
148
240
 
149
 
            item = Nautilus.MenuItem(name='BzrNautilus::clone',
150
 
                                 label='Checkout Bazaar branch ...',
151
 
                                 tip='Checkout Existing Bazaar Branch',
152
 
                                 icon='')
 
241
            item = nautilus.MenuItem('BzrNautilus::clone',
 
242
                                 'Checkout Bazaar branch ...',
 
243
                                 'Checkout Existing Bazaar Branch')
153
244
            item.connect('activate', self.clone_cb, vfs_file)
154
245
            items.append(item)
 
246
 
155
247
            return items
156
 
 
157
 
        items = []
158
 
 
159
 
        nautilus_integration = self.check_branch_enabled(branch)
160
 
        if not nautilus_integration:
161
 
            item = Nautilus.MenuItem(name='BzrNautilus::enable',
162
 
                                     label='Enable Bazaar Plugin for this Branch',
163
 
                                     tip='Enable Bazaar plugin for nautilus',
164
 
                                     icon='')
165
 
            item.connect('activate', self.toggle_integration, True, branch)
166
 
            return [item]
167
 
        else:
168
 
            item = Nautilus.MenuItem(name='BzrNautilus::disable',
169
 
                                     label='Disable Bazaar Plugin this Branch',
170
 
                                     tip='Disable Bazaar plugin for nautilus',
171
 
                                     icon='')
172
 
            item.connect('activate', self.toggle_integration, False, branch)
173
 
            items.append(item)
174
 
 
175
 
        item = Nautilus.MenuItem(name='BzrNautilus::log',
176
 
                             label='History ...',
177
 
                             tip='Show Bazaar history',
178
 
                             icon='')
179
 
        item.connect('activate', self.log_cb, controldir)
180
 
        items.append(item)
181
 
 
182
 
        item = Nautilus.MenuItem(name='BzrNautilus::pull',
183
 
                             label='Pull ...',
184
 
                             tip='Pull from another branch',
185
 
                             icon='')
186
 
        item.connect('activate', self.pull_cb, controldir)
187
 
        items.append(item)
188
 
 
189
 
        try:
190
 
            tree = controldir.open_workingtree()
191
248
        except NoWorkingTree:
192
 
            item = Nautilus.MenuItem(name='BzrNautilus::create_tree',
193
 
                                 label='Create working tree...',
194
 
                                 tip='Create a working tree for this branch',
195
 
                                 icon='')
196
 
            item.connect('activate', self.create_tree_cb, controldir)
197
 
            items.append(item)
 
249
            return
 
250
        
 
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)
 
256
            return item,
198
257
        else:
199
 
            item = Nautilus.MenuItem(name='BzrNautilus::merge',
200
 
                                 label='Merge ...',
201
 
                                 tip='Merge from another branch',
202
 
                                 icon='')
203
 
            item.connect('activate', self.merge_cb, tree, path)
204
 
            items.append(item)
205
 
 
206
 
            item = Nautilus.MenuItem(name='BzrNautilus::commit',
207
 
                                 label='Commit ...',
208
 
                                 tip='Commit Changes',
209
 
                                 icon='')
210
 
            item.connect('activate', self.commit_cb, tree, path)
211
 
            items.append(item)
 
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)
 
262
            items.append(item)
 
263
 
 
264
        item = nautilus.MenuItem('BzrNautilus::log',
 
265
                             'History ...',
 
266
                             'Show Bazaar history')
 
267
        item.connect('activate', self.log_cb, vfs_file)
 
268
        items.append(item)
 
269
 
 
270
        item = nautilus.MenuItem('BzrNautilus::pull',
 
271
                             'Pull ...',
 
272
                             'Pull from another branch')
 
273
        item.connect('activate', self.pull_cb, vfs_file)
 
274
        items.append(item)
 
275
 
 
276
        item = nautilus.MenuItem('BzrNautilus::merge',
 
277
                             'Merge ...',
 
278
                             'Merge from another branch')
 
279
        item.connect('activate', self.merge_cb, vfs_file)
 
280
        items.append(item)
 
281
 
 
282
        item = nautilus.MenuItem('BzrNautilus::commit',
 
283
                             'Commit ...',
 
284
                             'Commit Changes')
 
285
        item.connect('activate', self.commit_cb, vfs_file)
 
286
        items.append(item)
212
287
 
213
288
        return items
214
289
 
215
 
    def _get_file_menuitems(self, tree, intertree, path):
216
 
        file_id = tree.path2id(path)
217
 
        if file_id is None:
218
 
            item = Nautilus.MenuItem(name='BzrNautilus::add',
219
 
                                 label='Add',
220
 
                                 tip='Add as versioned file',
221
 
                                 icon='')
222
 
            item.connect('activate', self.add_cb, tree, path)
223
 
            yield item
224
 
 
225
 
            item = Nautilus.MenuItem(name='BzrNautilus::ignore',
226
 
                                 label='Ignore',
227
 
                                 tip='Ignore file for versioning',
228
 
                                 icon='')
229
 
            item.connect('activate', self.ignore_cb, tree, path)
230
 
            yield item
231
 
        elif tree.is_ignored(path):
232
 
            item = Nautilus.MenuItem(name='BzrNautilus::unignore',
233
 
                                 label='Unignore',
234
 
                                 tip='Unignore file for versioning',
235
 
                                 icon='')
236
 
            item.connect('activate', self.unignore_cb, tree, path)
237
 
            yield item
238
 
        else:
239
 
            item = Nautilus.MenuItem(name='BzrNautilus::log',
240
 
                             label='History ...',
241
 
                             tip='List changes',
242
 
                             icon='')
243
 
            item.connect('activate', self.log_cb, tree.bzrdir, path)
244
 
            yield item
245
 
 
246
 
            if not intertree.file_content_matches(file_id, file_id):
247
 
                item = Nautilus.MenuItem(name='BzrNautilus::diff',
248
 
                                 label='View Changes ...',
249
 
                                 tip='Show differences',
250
 
                                 icon='')
251
 
                item.connect('activate', self.diff_cb, tree, path)
252
 
                yield item
253
 
 
254
 
                item = Nautilus.MenuItem(name='BzrNautilus::commit',
255
 
                             label='Commit ...',
256
 
                             tip='Commit Changes',
257
 
                             icon='')
258
 
                item.connect('activate', self.commit_cb, tree, path)
259
 
                yield item
260
 
 
261
 
            item = Nautilus.MenuItem(name='BzrNautilus::remove',
262
 
                                 label='Remove',
263
 
                                 tip='Remove this file from versioning',
264
 
                                 icon='')
265
 
            item.connect('activate', self.remove_cb, tree, path)
266
 
            yield item
267
 
 
268
 
            item = Nautilus.MenuItem(name='BzrNautilus::annotate',
269
 
                         label='Annotate ...',
270
 
                         tip='Annotate File Data',
271
 
                         icon='')
272
 
            item.connect('activate', self.annotate_cb, tree, path, file_id)
273
 
            yield item
274
 
 
275
290
    def get_file_items(self, window, files):
276
291
        items = []
277
 
        trees = {}
278
 
 
279
 
        try:
280
 
            for vfs_file in files:
281
 
                controldir, path = self._open_bzrdir(vfs_file)
282
 
 
283
 
                try:
284
 
                    tree = trees[controldir.user_url]
285
 
                except KeyError:
286
 
                    try:
287
 
                        tree = controldir.open_workingtree()
288
 
                    except NoWorkingTree:
289
 
                        continue
290
 
                    trees[controldir.user_url] = tree
291
 
                    tree.lock_read()
292
 
 
293
 
                nautilus_integration = self.check_branch_enabled(tree.branch)
294
 
                if not nautilus_integration:
 
292
        
 
293
        wtfiles = {}
 
294
        for vfs_file in files:
 
295
            # We can only cope with local files
 
296
            if vfs_file.get_uri_scheme() != 'file':
 
297
                continue
 
298
 
 
299
            file = vfs_file.get_uri()
 
300
            try:
 
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():
295
306
                    continue
296
307
 
297
 
                intertree = InterTree.get(tree.basis_tree(), tree)
298
 
                items.extend(list(self._get_file_menuitems(tree, intertree, path)))
299
 
        finally:
300
 
            for tree in trees.itervalues():
 
308
                if disabled_flag == 'False':
 
309
                    return
 
310
 
 
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)
 
315
                return item,
 
316
            except NoWorkingTree:
 
317
                continue
 
318
            # Refresh the list of filestatuses in the working tree
 
319
            if path not in wtfiles.keys():
 
320
                tree.lock_read()
 
321
                for rpath, file_class, kind, id, entry in tree.list_files():
 
322
                    wtfiles[rpath] = file_class
301
323
                tree.unlock()
 
324
                wtfiles[u''] = 'V'
 
325
 
 
326
            if wtfiles[path] == '?':
 
327
                item = nautilus.MenuItem('BzrNautilus::add',
 
328
                                     'Add',
 
329
                                     'Add as versioned file')
 
330
                item.connect('activate', self.add_cb, vfs_file)
 
331
                items.append(item)
 
332
 
 
333
                item = nautilus.MenuItem('BzrNautilus::ignore',
 
334
                                     'Ignore',
 
335
                                     'Ignore file for versioning')
 
336
                item.connect('activate', self.ignore_cb, vfs_file)
 
337
                items.append(item)
 
338
            elif wtfiles[path] == 'I':
 
339
                item = nautilus.MenuItem('BzrNautilus::unignore',
 
340
                                     'Unignore',
 
341
                                     'Unignore file for versioning')
 
342
                item.connect('activate', self.unignore_cb, vfs_file)
 
343
                items.append(item)
 
344
            elif wtfiles[path] == 'V':
 
345
                item = nautilus.MenuItem('BzrNautilus::log',
 
346
                                 'History ...',
 
347
                                 'List changes')
 
348
                item.connect('activate', self.log_cb, vfs_file)
 
349
                items.append(item)
 
350
 
 
351
                item = nautilus.MenuItem('BzrNautilus::diff',
 
352
                                 'View Changes ...',
 
353
                                 'Show differences')
 
354
                item.connect('activate', self.diff_cb, vfs_file)
 
355
                items.append(item)
 
356
 
 
357
                item = nautilus.MenuItem('BzrNautilus::remove',
 
358
                                     'Remove',
 
359
                                     'Remove this file from versioning')
 
360
                item.connect('activate', self.remove_cb, vfs_file)
 
361
                items.append(item)
 
362
 
 
363
                item = nautilus.MenuItem('BzrNautilus::annotate',
 
364
                             'Annotate ...',
 
365
                             'Annotate File Data')
 
366
                item.connect('activate', self.annotate_cb, vfs_file)
 
367
                items.append(item)
 
368
 
 
369
                item = nautilus.MenuItem('BzrNautilus::commit',
 
370
                             'Commit ...',
 
371
                             'Commit Changes')
 
372
                item.connect('activate', self.commit_cb, vfs_file)
 
373
                items.append(item)
302
374
 
303
375
        return items
304
376
 
305
377
    def get_columns(self):
306
 
        return [
307
 
            Nautilus.Column(name="BzrNautilus::bzr_status",
308
 
                            attribute="bzr_status",
309
 
                            label="Status",
310
 
                            description="Version control status"),
311
 
            Nautilus.Column(name="BzrNautilus::bzr_revision",
312
 
                            attribute="bzr_revision",
313
 
                            label="Revision",
314
 
                            description="Last change revision"),
315
 
            ]
316
 
 
317
 
    def _file_summary(self, tree, basis_tree, intertree, path):
318
 
        file_revision = ""
 
378
        return nautilus.Column("BzrNautilus::bzr_status",
 
379
                               "bzr_status",
 
380
                               "Bzr Status",
 
381
                               "Version control status"),
 
382
 
 
383
    def update_file_info(self, file):
 
384
 
 
385
        if file.get_uri_scheme() != 'file':
 
386
            return
 
387
        
 
388
        try:
 
389
            tree, path = WorkingTree.open_containing(file.get_uri())
 
390
        except NotBranchError:
 
391
            return
 
392
        except NoWorkingTree:
 
393
            return   
 
394
 
 
395
        disabled_flag = self.check_branch_enabled(tree.branch)
 
396
        if disabled_flag == 'False':
 
397
            return
 
398
 
319
399
        emblem = None
 
400
        status = None
320
401
 
321
 
        file_id = tree.path2id(path)
322
 
        if file_id is None:
 
402
        id = tree.path2id(path)
 
403
        if id == None:
323
404
            if tree.is_ignored(path):
324
405
                status = 'ignored'
325
406
                emblem = 'bzr-ignored'
326
407
            else:
327
408
                status = 'unversioned'
328
 
            file_revision = "N/A"
329
 
        elif tree.has_filename(path): # Still present
330
 
            if not intertree.file_content_matches(file_id, file_id):
331
 
                if not basis_tree.has_id(file_id):
 
409
                        
 
410
        elif tree.has_filename(path):
 
411
            emblem = 'bzr-controlled'
 
412
            status = 'unchanged'
 
413
 
 
414
            delta = tree.changes_from(tree.branch.basis_tree())
 
415
            if delta.touches_file_id(id):
 
416
                emblem = 'bzr-modified'
 
417
                status = 'modified'
 
418
            for f, _, _ in delta.added:
 
419
                if f == path:
332
420
                    emblem = 'bzr-added'
333
421
                    status = 'added'
334
 
                    file_revision = "new file"
335
 
                elif basis_tree.path2id(file_id) != path:
336
 
                    status = 'bzr-renamed'
337
 
                    status = 'renamed from %s' % basis_tree.path2id(file_id)
338
 
                else:
339
 
                    emblem = 'bzr-modified'
340
 
                    status = 'modified'
341
 
            else:
342
 
                emblem = 'bzr-controlled'
343
 
                status = 'unchanged'
344
 
        elif basis_tree.has_filename(path):
 
422
 
 
423
            for of, f, _, _, _, _ in delta.renamed:
 
424
                if f == path:
 
425
                    status = 'renamed from %s' % f
 
426
 
 
427
        elif tree.branch.basis_tree().has_filename(path):
345
428
            emblem = 'bzr-removed'
346
429
            status = 'removed'
347
430
        else:
348
431
            # FIXME: Check for ignored files
349
432
            status = 'unversioned'
350
 
        return (status, emblem, file_revision)
351
 
 
352
 
    def update_file_info(self, vfs_file):
353
 
        try:
354
 
            controldir, path = self._open_bzrdir(vfs_file)
355
 
        except NotBranchError:
356
 
            return
357
 
 
358
 
        try:
359
 
            tree = controldir.open_workingtree()
360
 
        except NoWorkingTree:
361
 
            return
362
 
 
363
 
        tree.lock_read()
364
 
        try:
365
 
            nautilus_integration = self.check_branch_enabled(tree.branch)
366
 
            if not nautilus_integration:
367
 
                return
368
 
 
369
 
            basis_tree = tree.basis_tree()
370
 
            intertree = InterTree.get(basis_tree, tree)
371
 
 
372
 
            basis_tree.lock_read()
373
 
            try:
374
 
                (status, emblem, file_revision) = self._file_summary(tree, basis_tree, intertree, path)
375
 
            finally:
376
 
                basis_tree.unlock()
377
 
            if emblem is not None:
378
 
                vfs_file.add_emblem(emblem)
379
 
            vfs_file.add_string_attribute('bzr_status', status)
380
 
            vfs_file.add_string_attribute('bzr_revision', file_revision)
381
 
        finally:
382
 
            tree.unlock()
383
 
 
384
 
    def check_branch_enabled(self, branch):
 
433
        
 
434
        if emblem is not None:
 
435
            file.add_emblem(emblem)
 
436
        file.add_string_attribute('bzr_status', status)
 
437
 
 
438
    def check_branch_enabled(self, branch=None):
385
439
        # Supports global disable, but there is currently no UI to do this
386
 
        config = branch.get_config_stack()
387
 
        return config.get("nautilus_integration")
388
 
 
389
 
    def toggle_integration(self, menu, action, branch):
390
 
        config = branch.get_config_stack()
391
 
        config.set("nautilus_integration", action)
392
 
 
393
 
    def get_property_pages(self, files):
394
 
        pages = []
395
 
        for vfs_file in files:
396
 
            try:
397
 
                controldir, path = self._open_bzrdir(vfs_file)
398
 
            except NotBranchError:
399
 
                continue
400
 
 
401
 
            try:
402
 
                tree = controldir.open_workingtree()
403
 
            except NoWorkingTree:
404
 
                continue
405
 
 
406
 
            tree.lock_read()
407
 
            try:
408
 
                file_id = tree.path2id(path)
409
 
                pages.append(PropertyPageFile(tree, file_id, path))
410
 
                pages.append(PropertyPageBranch(tree.branch))
411
 
            finally:
412
 
                tree.unlock()
413
 
        return pages
414
 
 
415
 
 
416
 
class PropertyPageFile(Nautilus.PropertyPage):
417
 
 
418
 
    def __init__(self, tree, file_id, path):
419
 
        self.tree = tree
420
 
        self.file_id = file_id
421
 
        self.path = path
422
 
        label = Gtk.Label('File Version')
423
 
        label.show()
424
 
 
425
 
        table = self._create_table()
426
 
 
427
 
        super(PropertyPageFile, self).__init__(label=label,
428
 
            name="BzrNautilus::file_page", page=table)
429
 
 
430
 
    def _create_table(self):
431
 
        table = Gtk.Table(homogeneous=False, columns=2, rows=3)
432
 
 
433
 
        table.attach(Gtk.Label('File id:'), 0, 1, 0, 1)
434
 
        table.attach(Gtk.Label(self.file_id), 1, 2, 0, 1)
435
 
 
436
 
        table.attach(Gtk.Label('SHA1Sum:'), 0, 1, 1, 2)
437
 
        table.attach(Gtk.Label(self.tree.get_file_sha1(self.file_id, self.path)), 1, 1, 1, 2)
438
 
 
439
 
        basis_tree = self.tree.revision_tree(self.tree.last_revision())
440
 
        last_revision = basis_tree.get_file_revision(self.file_id)
441
 
 
442
 
        table.attach(Gtk.Label('Last Change Revision:'), 0, 1, 2, 3)
443
 
        revno = ".".join([str(x) for x in
444
 
            self.tree.branch.revision_id_to_dotted_revno(last_revision)])
445
 
        table.attach(Gtk.Label(revno), 1, 1, 2, 3)
446
 
 
447
 
        table.attach(Gtk.Label('Last Change Author:'), 0, 1, 3, 4)
448
 
        rev = self.tree.branch.repository.get_revision(last_revision)
449
 
        table.attach(Gtk.Label("\n".join(rev.get_apparent_authors())), 1, 1, 3, 4)
450
 
 
451
 
        table.show_all()
452
 
        return table
453
 
 
454
 
 
455
 
class PropertyPageBranch(Nautilus.PropertyPage):
456
 
 
457
 
    def __init__(self, branch):
458
 
        self.branch = branch
459
 
        label = Gtk.Label('Branch')
460
 
        label.show()
461
 
 
462
 
        table = self._create_table()
463
 
 
464
 
        super(PropertyPageBranch, self).__init__(label=label,
465
 
            name="BzrNautilus::branch_page", page=table)
466
 
 
467
 
    def _create_table(self):
468
 
        table = Gtk.Table(homogeneous=False, columns=2, rows=3)
469
 
 
470
 
        table.attach(Gtk.Label('Push location:'), 0, 1, 0, 1)
471
 
        table.attach(Gtk.Label(self.branch.get_push_location()), 1, 2, 0, 1)
472
 
 
473
 
        table.attach(Gtk.Label('Parent location:'), 0, 1, 1, 2)
474
 
        table.attach(Gtk.Label(self.branch.get_parent()), 1, 1, 1, 2)
475
 
 
476
 
        table.show_all()
477
 
        return table
 
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')
 
446
        return disabled_flag
 
447
 
 
448
    def toggle_integration(self, menu, action, vfs_file=None):
 
449
        try:
 
450
            tree, path = WorkingTree.open_containing(vfs_file.get_uri())
 
451
        except NotBranchError:
 
452
            return
 
453
        except NoWorkingTree:
 
454
            return
 
455
        branch = tree.branch
 
456
        if branch is None:
 
457
            config = GlobalConfig()
 
458
        else:
 
459
            config = branch.get_config()
 
460
        config.set_user_option('nautilus_integration', action)
 
461