/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: Vincent Ladeuil
  • Date: 2008-05-05 18:16:46 UTC
  • mto: (487.1.1 gtk)
  • mto: This revision was merged to the branch mainline in revision 490.
  • Revision ID: v.ladeuil+lp@free.fr-20080505181646-n95l8ltw2u6jtr26
Fix bug #187283 fix replacing _() by _i18n().

* genpot.sh 
Remove duplication. Add the ability to specify the genrated pot
file on command-line for debugging purposes.

* po/olive-gtk.pot:
Regenerated.

* __init__.py, branch.py, branchview/treeview.py, checkout.py,
commit.py, conflicts.py, diff.py, errors.py, initialize.py,
merge.py, nautilus-bzr.py, olive/__init__.py, olive/add.py,
olive/bookmark.py, olive/guifiles.py, olive/info.py,
olive/menu.py, olive/mkdir.py, olive/move.py, olive/remove.py,
olive/rename.py, push.py, revbrowser.py, status.py, tags.py:
Replace all calls to _() by calls to _i18n(), the latter being
defined in __init__.py and imported in the other modules from
there. This fix the problem encountered countless times when
running bzr selftest and getting silly error messages about
boolean not being callables.

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.tree import file_status
 
16
from bzrlib.workingtree import WorkingTree
 
17
from bzrlib.config import GlobalConfig
36
18
 
37
19
from bzrlib.plugin import load_plugins
38
20
load_plugins()
39
21
 
40
 
from bzrlib.plugins.gtk.i18n import _i18n
41
 
 
42
 
 
43
 
class BazaarExtension(Nautilus.MenuProvider, Nautilus.ColumnProvider,
44
 
        Nautilus.InfoProvider, Nautilus.PropertyPageProvider,
45
 
        Nautilus.LocationWidgetProvider, GObject.GObject):
46
 
    """Nautilus extension providing Bazaar integration."""
47
 
 
 
22
from bzrlib.plugins.gtk import _i18n, cmd_visualise, cmd_gannotate
 
23
 
 
24
class BzrExtension(nautilus.MenuProvider, nautilus.ColumnProvider, nautilus.InfoProvider):
48
25
    def __init__(self):
49
26
        pass
50
27
 
51
 
    @classmethod
52
 
    def _open_bzrdir(cls, vfs_file):
53
 
        uri = vfs_file.get_uri()
54
 
        controldir, path = ControlDir.open_containing(uri)
55
 
        return controldir, path
56
 
 
57
 
    @classmethod
58
 
    def _open_tree(cls, vfs_file):
59
 
        controldir, path = cls._open_bzrdir(vfs_file)
60
 
        return controldir.open_workingtree(), path
61
 
 
62
 
    def add_cb(self, menu, tree, path):
 
28
    def add_cb(self, menu, vfs_file):
 
29
        # We can only cope with local files
 
30
        if vfs_file.get_uri_scheme() != 'file':
 
31
            return
 
32
 
 
33
        file = vfs_file.get_uri()
 
34
        try:
 
35
            tree, path = WorkingTree.open_containing(file)
 
36
        except NotBranchError:
 
37
            return
 
38
 
63
39
        tree.add(path)
64
40
 
65
 
    def ignore_cb(self, menu, tree, path):
66
 
        # We can only cope with local files
67
 
        tree_ignores_add_patterns(tree, [path])
68
 
        #FIXME: Add path to ignore file
69
 
 
70
 
    def unignore_cb(self, menu, tree, path):
71
 
        pass
72
 
        # We can only cope with local files
73
 
        #FIXME
74
 
 
75
 
    def diff_cb(self, menu, tree, path=None):
 
41
        return
 
42
 
 
43
    def ignore_cb(self, menu, vfs_file):
 
44
        # We can only cope with local files
 
45
        if vfs_file.get_uri_scheme() != 'file':
 
46
            return
 
47
 
 
48
        file = vfs_file.get_uri()
 
49
        try:
 
50
            tree, path = WorkingTree.open_containing(file)
 
51
        except NotBranchError:
 
52
            return
 
53
 
 
54
        #FIXME
 
55
 
 
56
        return
 
57
 
 
58
    def unignore_cb(self, menu, vfs_file):
 
59
        # We can only cope with local files
 
60
        if vfs_file.get_uri_scheme() != 'file':
 
61
            return
 
62
 
 
63
        file = vfs_file.get_uri()
 
64
        try:
 
65
            tree, path = WorkingTree.open_containing(file)
 
66
        except NotBranchError:
 
67
            return
 
68
 
 
69
        #FIXME
 
70
 
 
71
        return
 
72
 
 
73
    def diff_cb(self, menu, vfs_file):
 
74
        # We can only cope with local files
 
75
        if vfs_file.get_uri_scheme() != 'file':
 
76
            return
 
77
 
 
78
        file = vfs_file.get_uri()
 
79
        try:
 
80
            tree, path = WorkingTree.open_containing(file)
 
81
        except NotBranchError:
 
82
            return
 
83
 
76
84
        from bzrlib.plugins.gtk.diff import DiffWindow
77
85
        window = DiffWindow()
78
 
        window.set_diff(tree.branch._get_nick(local=True), tree, 
79
 
                        tree.branch.basis_tree())
 
86
        window.set_diff(tree.branch.nick, tree, tree.branch.basis_tree())
80
87
        window.show()
81
88
 
 
89
        return
 
90
 
82
91
    def newtree_cb(self, menu, vfs_file):
83
 
        controldir, path = self._open_bzrdir(vfs_file)
84
 
        controldir.create_workingtree()
85
 
 
86
 
    def remove_cb(self, menu, tree, path):
 
92
        # We can only cope with local files
 
93
        if vfs_file.get_uri_scheme() != 'file':
 
94
            return
 
95
 
 
96
        file = vfs_file.get_uri()
 
97
 
 
98
        # We only want to continue here if we get a NotBranchError
 
99
        try:
 
100
            tree, path = WorkingTree.open_containing(file)
 
101
        except NotBranchError:
 
102
            BzrDir.create_standalone_workingtree(file)
 
103
 
 
104
    def remove_cb(self, menu, vfs_file):
 
105
        # We can only cope with local files
 
106
        if vfs_file.get_uri_scheme() != 'file':
 
107
            return
 
108
 
 
109
        file = vfs_file.get_uri()
 
110
        try:
 
111
            tree, path = WorkingTree.open_containing(file)
 
112
        except NotBranchError:
 
113
            return
 
114
 
87
115
        tree.remove(path)
88
116
 
89
 
    def annotate_cb(self, menu, tree, path, file_id):
90
 
        from bzrlib.plugins.gtk.annotate.gannotate import GAnnotateWindow
91
 
        win = GAnnotateWindow()
92
 
        win.show()
93
 
        win.annotate(tree, tree.branch, file_id)
94
 
        Gtk.main()
 
117
    def annotate_cb(self, menu, vfs_file):
 
118
        # We can only cope with local files
 
119
        if vfs_file.get_uri_scheme() != 'file':
 
120
            return
 
121
 
 
122
        file = vfs_file.get_uri()
 
123
 
 
124
        vis = cmd_gannotate()
 
125
        vis.run(file)
95
126
 
96
127
    def clone_cb(self, menu, vfs_file=None):
 
128
        # We can only cope with local files
 
129
        if vfs_file.get_uri_scheme() != 'file':
 
130
            return
 
131
 
97
132
        from bzrlib.plugins.gtk.branch import BranchDialog
98
 
        controldir, path = self._open_bzrdir(vfs_file)
99
 
 
 
133
        
100
134
        dialog = BranchDialog(vfs_file.get_name())
101
135
        response = dialog.run()
102
 
        if response != Gtk.ResponseType.NONE:
 
136
        if response != gtk.RESPONSE_NONE:
103
137
            dialog.hide()
104
138
            dialog.destroy()
105
 
 
106
 
    def commit_cb(self, menu, tree, path=None):
 
139
 
 
140
    def commit_cb(self, menu, vfs_file=None):
 
141
        # We can only cope with local files
 
142
        if vfs_file.get_uri_scheme() != 'file':
 
143
            return
 
144
 
 
145
        file = vfs_file.get_uri()
 
146
        tree = None
 
147
        branch = None
 
148
        try:
 
149
            tree, path = WorkingTree.open_containing(file)
 
150
            branch = tree.branch
 
151
        except NotBranchError, e:
 
152
            path = e.path
 
153
            #return
 
154
        except NoWorkingTree, e:
 
155
            path = e.base
 
156
            try:
 
157
                (branch, path) = Branch.open_containing(path)
 
158
            except NotBranchError, e:
 
159
                path = e.path
 
160
 
107
161
        from bzrlib.plugins.gtk.commit import CommitDialog
108
162
        dialog = CommitDialog(tree, path)
109
163
        response = dialog.run()
110
 
        if response != Gtk.ResponseType.NONE:
 
164
        if response != gtk.RESPONSE_NONE:
111
165
            dialog.hide()
112
166
            dialog.destroy()
113
167
 
114
 
    def log_cb(self, menu, controldir, path=None):
115
 
        from bzrlib.plugins.gtk.viz import BranchWindow
116
 
        branch = controldir.open_branch()
117
 
        pp = BranchWindow(branch, [branch.last_revision()], None)
118
 
        pp.show()
119
 
        Gtk.main()
120
 
 
121
 
    def pull_cb(self, menu, controldir, path=None):
 
168
    def log_cb(self, menu, vfs_file):
 
169
        # We can only cope with local files
 
170
        if vfs_file.get_uri_scheme() != 'file':
 
171
            return
 
172
 
 
173
        file = vfs_file.get_uri()
 
174
 
 
175
        # We only want to continue here if we get a NotBranchError
 
176
        try:
 
177
            tree, path = WorkingTree.open_containing(file)
 
178
        except NotBranchError:
 
179
            return
 
180
 
 
181
        vis = cmd_visualise()
 
182
        vis.run(file)
 
183
 
 
184
        return
 
185
 
 
186
    def pull_cb(self, menu, vfs_file):
 
187
        # We can only cope with local files
 
188
        if vfs_file.get_uri_scheme() != 'file':
 
189
            return
 
190
 
 
191
        file = vfs_file.get_uri()
 
192
 
 
193
        # We only want to continue here if we get a NotBranchError
 
194
        try:
 
195
            tree, path = WorkingTree.open_containing(file)
 
196
        except NotBranchError:
 
197
            return
 
198
 
122
199
        from bzrlib.plugins.gtk.pull import PullDialog
123
 
        dialog = PullDialog(controldir.open_workingtree(), path)
124
 
        dialog.display()
125
 
        Gtk.main()
126
 
 
127
 
    def push_cb(self, menu, controldir, path=None):
128
 
        from bzrlib.plugins.gtk.push import PushDialog
129
 
        dialog = PushDialog(branch=controldir.open_workingtree().branch)
130
 
        dialog.display()
131
 
        Gtk.main()
132
 
 
133
 
    def merge_cb(self, menu, tree, path=None):
 
200
        dialog = PullDialog(tree, path)
 
201
        dialog.display()
 
202
        gtk.main()
 
203
 
 
204
    def merge_cb(self, menu, vfs_file):
 
205
        # We can only cope with local files
 
206
        if vfs_file.get_uri_scheme() != 'file':
 
207
            return
 
208
 
 
209
        file = vfs_file.get_uri()
 
210
 
 
211
        # We only want to continue here if we get a NotBranchError
 
212
        try:
 
213
            tree, path = WorkingTree.open_containing(file)
 
214
        except NotBranchError:
 
215
            return
 
216
 
134
217
        from bzrlib.plugins.gtk.merge import MergeDialog
135
218
        dialog = MergeDialog(tree, path)
136
 
        dialog.run()
137
 
        dialog.destroy()
138
 
 
139
 
    def create_tree_cb(self, menu, controldir):
140
 
        controldir.create_workingtree()
 
219
        dialog.display()
 
220
        gtk.main()
141
221
 
142
222
    def get_background_items(self, window, vfs_file):
 
223
        items = []
 
224
        file = vfs_file.get_uri()
 
225
 
143
226
        try:
144
 
            controldir, path = self._open_bzrdir(vfs_file)
145
 
        except NotBranchError:
 
227
            tree, path = WorkingTree.open_containing(file)
 
228
            disabled_flag = self.check_branch_enabled(tree.branch)
 
229
        except UnsupportedProtocol:
146
230
            return
147
 
        try:
148
 
            branch = controldir.open_branch()
149
231
        except NotBranchError:
150
 
            items = []
151
 
            item = Nautilus.MenuItem(name='BzrNautilus::newtree',
152
 
                                 label='Make directory versioned',
153
 
                                 tip='Create new Bazaar tree in this folder',
154
 
                                 icon='')
 
232
            disabled_flag = self.check_branch_enabled()
 
233
            item = nautilus.MenuItem('BzrNautilus::newtree',
 
234
                                 'Make directory versioned',
 
235
                                 'Create new Bazaar tree in this folder')
155
236
            item.connect('activate', self.newtree_cb, vfs_file)
156
237
            items.append(item)
157
238
 
158
 
            item = Nautilus.MenuItem(name='BzrNautilus::clone',
159
 
                                 label='Checkout Bazaar branch ...',
160
 
                                 tip='Checkout Existing Bazaar Branch',
161
 
                                 icon='')
 
239
            item = nautilus.MenuItem('BzrNautilus::clone',
 
240
                                 'Checkout Bazaar branch',
 
241
                                 'Checkout Existing Bazaar Branch')
162
242
            item.connect('activate', self.clone_cb, vfs_file)
163
243
            items.append(item)
 
244
 
164
245
            return items
165
 
 
166
 
        items = []
167
 
 
168
 
        nautilus_integration = self.check_branch_enabled(branch)
169
 
        if not nautilus_integration:
170
 
            item = Nautilus.MenuItem(name='BzrNautilus::enable',
171
 
                                     label='Enable Bazaar Plugin for this Branch',
172
 
                                     tip='Enable Bazaar plugin for nautilus',
173
 
                                     icon='')
174
 
            item.connect('activate', self.toggle_integration, True, branch)
175
 
            return [item]
176
 
        else:
177
 
            item = Nautilus.MenuItem(name='BzrNautilus::disable',
178
 
                                     label='Disable Bazaar Plugin this Branch',
179
 
                                     tip='Disable Bazaar plugin for nautilus',
180
 
                                     icon='')
181
 
            item.connect('activate', self.toggle_integration, False, branch)
182
 
            items.append(item)
183
 
 
184
 
        item = Nautilus.MenuItem(name='BzrNautilus::log',
185
 
                             label='History ...',
186
 
                             tip='Show Bazaar history',
187
 
                             icon='')
188
 
        item.connect('activate', self.log_cb, controldir)
189
 
        items.append(item)
190
 
 
191
 
        item = Nautilus.MenuItem(name='BzrNautilus::pull',
192
 
                             label='Pull ...',
193
 
                             tip='Pull from another branch',
194
 
                             icon='')
195
 
        item.connect('activate', self.pull_cb, controldir)
196
 
        items.append(item)
197
 
 
198
 
        try:
199
 
            tree = controldir.open_workingtree()
200
246
        except NoWorkingTree:
201
 
            item = Nautilus.MenuItem(name='BzrNautilus::create_tree',
202
 
                                 label='Create working tree...',
203
 
                                 tip='Create a working tree for this branch',
204
 
                                 icon='')
205
 
            item.connect('activate', self.create_tree_cb, controldir)
206
 
            items.append(item)
 
247
            return
 
248
        
 
249
        if disabled_flag == 'False':
 
250
            item = nautilus.MenuItem('BzrNautilus::enable',
 
251
                                     'Enable Bazaar Plugin for this Branch',
 
252
                                     'Enable Bazaar plugin for nautilus')
 
253
            item.connect('activate', self.toggle_integration, 'True', vfs_file)
 
254
            return item,
207
255
        else:
208
 
            item = Nautilus.MenuItem(name='BzrNautilus::merge',
209
 
                                 label='Merge ...',
210
 
                                 tip='Merge from another branch',
211
 
                                 icon='')
212
 
            item.connect('activate', self.merge_cb, tree, path)
213
 
            items.append(item)
214
 
 
215
 
            item = Nautilus.MenuItem(name='BzrNautilus::commit',
216
 
                                 label='Commit ...',
217
 
                                 tip='Commit Changes',
218
 
                                 icon='')
219
 
            item.connect('activate', self.commit_cb, tree, path)
220
 
            items.append(item)
 
256
            item = nautilus.MenuItem('BzrNautilus::disable',
 
257
                                      'Disable Bazaar Plugin for the Branch',
 
258
                                      'Disable Bazaar plugin for nautilus')
 
259
            item.connect('activate', self.toggle_integration, 'False', vfs_file)
 
260
            items.append(item)
 
261
 
 
262
        item = nautilus.MenuItem('BzrNautilus::log',
 
263
                             'Log',
 
264
                             'Show Bazaar history')
 
265
        item.connect('activate', self.log_cb, vfs_file)
 
266
        items.append(item)
 
267
 
 
268
        item = nautilus.MenuItem('BzrNautilus::pull',
 
269
                             'Pull',
 
270
                             'Pull from another branch')
 
271
        item.connect('activate', self.pull_cb, vfs_file)
 
272
        items.append(item)
 
273
 
 
274
        item = nautilus.MenuItem('BzrNautilus::merge',
 
275
                             'Merge',
 
276
                             'Merge from another branch')
 
277
        item.connect('activate', self.merge_cb, vfs_file)
 
278
        items.append(item)
 
279
 
 
280
        item = nautilus.MenuItem('BzrNautilus::commit',
 
281
                             'Commit',
 
282
                             'Commit Changes')
 
283
        item.connect('activate', self.commit_cb, vfs_file)
 
284
        items.append(item)
221
285
 
222
286
        return items
223
287
 
224
 
    def _get_file_menuitems(self, tree, intertree, path):
225
 
        file_id = tree.path2id(path)
226
 
        if file_id is None:
227
 
            item = Nautilus.MenuItem(name='BzrNautilus::add',
228
 
                                 label='Add',
229
 
                                 tip='Add as versioned file',
230
 
                                 icon='')
231
 
            item.connect('activate', self.add_cb, tree, path)
232
 
            yield item
233
 
 
234
 
            item = Nautilus.MenuItem(name='BzrNautilus::ignore',
235
 
                                 label='Ignore',
236
 
                                 tip='Ignore file for versioning',
237
 
                                 icon='')
238
 
            item.connect('activate', self.ignore_cb, tree, path)
239
 
            yield item
240
 
        elif tree.is_ignored(path):
241
 
            item = Nautilus.MenuItem(name='BzrNautilus::unignore',
242
 
                                 label='Unignore',
243
 
                                 tip='Unignore file for versioning',
244
 
                                 icon='')
245
 
            item.connect('activate', self.unignore_cb, tree, path)
246
 
            yield item
247
 
        else:
248
 
            kind = tree.kind(file_id)
249
 
            item = Nautilus.MenuItem(name='BzrNautilus::log',
250
 
                             label='History ...',
251
 
                             tip='List changes',
252
 
                             icon='')
253
 
            item.connect('activate', self.log_cb, tree.bzrdir, path)
254
 
            yield item
255
 
 
256
 
            if not intertree.file_content_matches(file_id, file_id):
257
 
                item = Nautilus.MenuItem(name='BzrNautilus::diff',
258
 
                                 label='View Changes ...',
259
 
                                 tip='Show differences',
260
 
                                 icon='')
261
 
                item.connect('activate', self.diff_cb, tree, path)
262
 
                yield item
263
 
 
264
 
                item = Nautilus.MenuItem(name='BzrNautilus::commit',
265
 
                             label='Commit ...',
266
 
                             tip='Commit Changes',
267
 
                             icon='')
268
 
                item.connect('activate', self.commit_cb, tree, path)
269
 
                yield item
270
 
 
271
 
            item = Nautilus.MenuItem(name='BzrNautilus::remove',
272
 
                                 label='Remove',
273
 
                                 tip='Remove this file from versioning',
274
 
                                 icon='')
275
 
            item.connect('activate', self.remove_cb, tree, path)
276
 
            yield item
277
 
 
278
 
            if kind == 'file':
279
 
                item = Nautilus.MenuItem(name='BzrNautilus::annotate',
280
 
                             label='Annotate ...',
281
 
                             tip='Annotate File Data',
282
 
                             icon='')
283
 
                item.connect('activate', self.annotate_cb, tree, path, file_id)
284
 
                yield item
285
 
 
286
288
    def get_file_items(self, window, files):
287
289
        items = []
288
 
        trees = {}
289
 
 
290
 
        try:
291
 
            for vfs_file in files:
292
 
                controldir, path = self._open_bzrdir(vfs_file)
293
 
 
294
 
                try:
295
 
                    tree = trees[controldir.user_url]
296
 
                except KeyError:
297
 
                    try:
298
 
                        tree = controldir.open_workingtree()
299
 
                    except NoWorkingTree:
300
 
                        continue
301
 
                    trees[controldir.user_url] = tree
302
 
                    tree.lock_read()
303
 
 
304
 
                nautilus_integration = self.check_branch_enabled(tree.branch)
305
 
                if not nautilus_integration:
 
290
        
 
291
        wtfiles = {}
 
292
        for vfs_file in files:
 
293
            # We can only cope with local files
 
294
            if vfs_file.get_uri_scheme() != 'file':
 
295
                continue
 
296
 
 
297
            file = vfs_file.get_uri()
 
298
            try:
 
299
                tree, path = WorkingTree.open_containing(file)
 
300
                disabled_flag = self.check_branch_enabled(tree.branch)
 
301
            except NotBranchError:
 
302
                disabled_flag = self.check_branch_enabled()
 
303
                if not vfs_file.is_directory():
306
304
                    continue
307
305
 
308
 
                intertree = InterTree.get(tree.basis_tree(), tree)
309
 
                items.extend(list(self._get_file_menuitems(tree, intertree, path)))
310
 
        finally:
311
 
            for tree in trees.itervalues():
 
306
                if disabled_flag == 'False':
 
307
                    return
 
308
 
 
309
                item = nautilus.MenuItem('BzrNautilus::newtree',
 
310
                                     'Make directory versioned',
 
311
                                     'Create new Bazaar tree in %s' % vfs_file.get_name())
 
312
                item.connect('activate', self.newtree_cb, vfs_file)
 
313
                return item,
 
314
            except NoWorkingTree:
 
315
                continue
 
316
            # Refresh the list of filestatuses in the working tree
 
317
            if path not in wtfiles.keys():
 
318
                tree.lock_read()
 
319
                for rpath, file_class, kind, id, entry in tree.list_files():
 
320
                    wtfiles[rpath] = file_class
312
321
                tree.unlock()
 
322
                wtfiles[u''] = 'V'
 
323
 
 
324
            if wtfiles[path] == '?':
 
325
                item = nautilus.MenuItem('BzrNautilus::add',
 
326
                                     'Add',
 
327
                                     'Add as versioned file')
 
328
                item.connect('activate', self.add_cb, vfs_file)
 
329
                items.append(item)
 
330
 
 
331
                item = nautilus.MenuItem('BzrNautilus::ignore',
 
332
                                     'Ignore',
 
333
                                     'Ignore file for versioning')
 
334
                item.connect('activate', self.ignore_cb, vfs_file)
 
335
                items.append(item)
 
336
            elif wtfiles[path] == 'I':
 
337
                item = nautilus.MenuItem('BzrNautilus::unignore',
 
338
                                     'Unignore',
 
339
                                     'Unignore file for versioning')
 
340
                item.connect('activate', self.unignore_cb, vfs_file)
 
341
                items.append(item)
 
342
            elif wtfiles[path] == 'V':
 
343
                item = nautilus.MenuItem('BzrNautilus::log',
 
344
                                 'Log',
 
345
                                 'List changes')
 
346
                item.connect('activate', self.log_cb, vfs_file)
 
347
                items.append(item)
 
348
 
 
349
                item = nautilus.MenuItem('BzrNautilus::diff',
 
350
                                 'Diff',
 
351
                                 'Show differences')
 
352
                item.connect('activate', self.diff_cb, vfs_file)
 
353
                items.append(item)
 
354
 
 
355
                item = nautilus.MenuItem('BzrNautilus::remove',
 
356
                                     'Remove',
 
357
                                     'Remove this file from versioning')
 
358
                item.connect('activate', self.remove_cb, vfs_file)
 
359
                items.append(item)
 
360
 
 
361
                item = nautilus.MenuItem('BzrNautilus::annotate',
 
362
                             'Annotate',
 
363
                             'Annotate File Data')
 
364
                item.connect('activate', self.annotate_cb, vfs_file)
 
365
                items.append(item)
 
366
 
 
367
                item = nautilus.MenuItem('BzrNautilus::commit',
 
368
                             'Commit',
 
369
                             'Commit Changes')
 
370
                item.connect('activate', self.commit_cb, vfs_file)
 
371
                items.append(item)
313
372
 
314
373
        return items
315
374
 
316
375
    def get_columns(self):
317
 
        return [
318
 
            Nautilus.Column(name="BzrNautilus::bzr_status",
319
 
                            attribute="bzr_status",
320
 
                            label="Status",
321
 
                            description="Version control status"),
322
 
            Nautilus.Column(name="BzrNautilus::bzr_revision",
323
 
                            attribute="bzr_revision",
324
 
                            label="Revision",
325
 
                            description="Last change revision"),
326
 
            ]
327
 
 
328
 
    def _file_summary(self, tree, basis_tree, intertree, path):
329
 
        file_revision = ""
 
376
        return nautilus.Column("BzrNautilus::bzr_status",
 
377
                               "bzr_status",
 
378
                               "Bzr Status",
 
379
                               "Version control status"),
 
380
 
 
381
    def update_file_info(self, file):
 
382
 
 
383
        if file.get_uri_scheme() != 'file':
 
384
            return
 
385
        
 
386
        try:
 
387
            tree, path = WorkingTree.open_containing(file.get_uri())
 
388
        except NotBranchError:
 
389
            return
 
390
        except NoWorkingTree:
 
391
            return   
 
392
 
 
393
        disabled_flag = self.check_branch_enabled(tree.branch)
 
394
        if disabled_flag == 'False':
 
395
            return
 
396
 
330
397
        emblem = None
331
 
 
332
 
        file_id = tree.path2id(path)
333
 
        if file_id is None:
334
 
            if tree.is_ignored(path):
335
 
                status = 'ignored'
336
 
                emblem = 'bzr-ignored'
337
 
            else:
338
 
                status = 'unversioned'
339
 
            file_revision = "N/A"
340
 
        elif tree.has_filename(path): # Still present
341
 
            if not intertree.file_content_matches(file_id, file_id):
342
 
                if not basis_tree.has_id(file_id):
 
398
        status = None
 
399
 
 
400
        if tree.has_filename(path):
 
401
            emblem = 'bzr-controlled'
 
402
            status = 'unchanged'
 
403
            id = tree.path2id(path)
 
404
 
 
405
            delta = tree.changes_from(tree.branch.basis_tree())
 
406
            if delta.touches_file_id(id):
 
407
                emblem = 'bzr-modified'
 
408
                status = 'modified'
 
409
            for f, _, _ in delta.added:
 
410
                if f == path:
343
411
                    emblem = 'bzr-added'
344
412
                    status = 'added'
345
 
                    file_revision = "new file"
346
 
                elif basis_tree.path2id(file_id) != path:
347
 
                    status = 'bzr-renamed'
348
 
                    status = 'renamed from %s' % basis_tree.path2id(file_id)
349
 
                else:
350
 
                    emblem = 'bzr-modified'
351
 
                    status = 'modified'
352
 
            else:
353
 
                emblem = 'bzr-controlled'
354
 
                status = 'unchanged'
355
 
        elif basis_tree.has_filename(path):
 
413
 
 
414
            for of, f, _, _, _, _ in delta.renamed:
 
415
                if f == path:
 
416
                    status = 'renamed from %s' % f
 
417
 
 
418
        elif tree.branch.basis_tree().has_filename(path):
356
419
            emblem = 'bzr-removed'
357
420
            status = 'removed'
358
421
        else:
359
422
            # FIXME: Check for ignored files
360
423
            status = 'unversioned'
361
 
        return (status, emblem, file_revision)
362
 
 
363
 
    def update_file_info(self, vfs_file):
364
 
        try:
365
 
            controldir, path = self._open_bzrdir(vfs_file)
366
 
        except NotBranchError:
367
 
            return
368
 
 
369
 
        try:
370
 
            tree = controldir.open_workingtree()
371
 
        except NoWorkingTree:
372
 
            return
373
 
 
374
 
        tree.lock_read()
375
 
        try:
376
 
            nautilus_integration = self.check_branch_enabled(tree.branch)
377
 
            if not nautilus_integration:
378
 
                return
379
 
 
380
 
            basis_tree = tree.basis_tree()
381
 
            intertree = InterTree.get(basis_tree, tree)
382
 
 
383
 
            basis_tree.lock_read()
384
 
            try:
385
 
                (status, emblem, file_revision) = self._file_summary(tree, basis_tree, intertree, path)
386
 
            finally:
387
 
                basis_tree.unlock()
388
 
            if emblem is not None:
389
 
                vfs_file.add_emblem(emblem)
390
 
            vfs_file.add_string_attribute('bzr_status', status)
391
 
            vfs_file.add_string_attribute('bzr_revision', file_revision)
392
 
        finally:
393
 
            tree.unlock()
394
 
 
395
 
    def check_branch_enabled(self, branch):
 
424
        
 
425
        if emblem is not None:
 
426
            file.add_emblem(emblem)
 
427
        file.add_string_attribute('bzr_status', status)
 
428
 
 
429
    def check_branch_enabled(self, branch=None):
396
430
        # Supports global disable, but there is currently no UI to do this
397
 
        config = branch.get_config_stack()
398
 
        return config.get("nautilus_integration")
399
 
 
400
 
    def toggle_integration(self, menu, action, branch):
401
 
        config = branch.get_config_stack()
402
 
        config.set("nautilus_integration", action)
403
 
 
404
 
    def get_property_pages(self, files):
405
 
        pages = []
406
 
        for vfs_file in files:
407
 
            try:
408
 
                controldir, path = self._open_bzrdir(vfs_file)
409
 
            except NotBranchError:
410
 
                continue
411
 
 
412
 
            try:
413
 
                tree = controldir.open_workingtree()
414
 
            except NoWorkingTree:
415
 
                continue
416
 
 
417
 
            tree.lock_read()
418
 
            try:
419
 
                file_id = tree.path2id(path)
420
 
                pages.append(PropertyPageFile(tree, file_id, path))
421
 
                pages.append(PropertyPageBranch(tree.branch))
422
 
            finally:
423
 
                tree.unlock()
424
 
        return pages
425
 
 
426
 
    def get_widget(self, uri, window):
427
 
        controldir, path = ControlDir.open_containing(uri)
 
431
        config = GlobalConfig()
 
432
        disabled_flag = config.get_user_option('nautilus_integration')
 
433
        if disabled_flag != 'False':
 
434
            if branch is not None:
 
435
                config = branch.get_config()
 
436
                disabled_flag = config.get_user_option('nautilus_integration')
 
437
        return disabled_flag
 
438
 
 
439
    def toggle_integration(self, menu, action, vfs_file=None):
428
440
        try:
429
 
            tree = controldir.open_workingtree()
 
441
            tree, path = WorkingTree.open_containing(vfs_file.get_uri())
 
442
        except NotBranchError:
 
443
            return
430
444
        except NoWorkingTree:
431
445
            return
432
 
        ret = Gtk.HBox(False, 4)
433
 
        text = 'This is a Bazaar working tree. '
434
 
        get_shelf_manager = getattr(tree, 'get_shelf_manager', None)
435
 
        if get_shelf_manager is not None:
436
 
            manager = get_shelf_manager()
437
 
            shelves = manager.active_shelves()
438
 
            if len(shelves) == 0:
439
 
                pass
440
 
            elif len(shelves) == 1:
441
 
                text += '1 shelf exists. '
442
 
            else:
443
 
                text += '%d shelf exists. ' % len(shelves)
444
 
        label = Gtk.Label(text)
445
 
        label.show()
446
 
        ret.pack_start(label, True, True, 0)
447
 
        ret.show_all()
448
 
        return ret
449
 
 
450
 
 
451
 
class PropertyPageFile(Nautilus.PropertyPage):
452
 
 
453
 
    def __init__(self, tree, file_id, path):
454
 
        self.tree = tree
455
 
        self.file_id = file_id
456
 
        self.path = path
457
 
        label = Gtk.Label('File Version')
458
 
        label.show()
459
 
 
460
 
        table = self._create_table()
461
 
 
462
 
        super(PropertyPageFile, self).__init__(label=label,
463
 
            name="BzrNautilus::file_page", page=table)
464
 
 
465
 
    def _create_table(self):
466
 
        table = Gtk.Table(homogeneous=False, columns=2, rows=3)
467
 
 
468
 
        table.attach(Gtk.Label(_i18n('File id:')), 0, 1, 0, 1)
469
 
        table.attach(Gtk.Label(self.file_id), 1, 2, 0, 1)
470
 
 
471
 
        table.attach(Gtk.Label(_i18n('SHA1Sum:')), 0, 1, 1, 2)
472
 
        table.attach(Gtk.Label(self.tree.get_file_sha1(self.file_id, self.path)), 1, 1, 1, 2)
473
 
 
474
 
        basis_tree = self.tree.revision_tree(self.tree.last_revision())
475
 
        last_revision = basis_tree.get_file_revision(self.file_id)
476
 
 
477
 
        table.attach(Gtk.Label(_i18n('Last Change Revision:')), 0, 1, 2, 3)
478
 
        revno = ".".join([str(x) for x in
479
 
            self.tree.branch.revision_id_to_dotted_revno(last_revision)])
480
 
        table.attach(Gtk.Label(revno), 1, 1, 2, 3)
481
 
 
482
 
        table.attach(Gtk.Label(_i18n('Last Change Author:')), 0, 1, 3, 4)
483
 
        rev = self.tree.branch.repository.get_revision(last_revision)
484
 
        table.attach(Gtk.Label("\n".join(rev.get_apparent_authors())), 1, 1, 3, 4)
485
 
 
486
 
        table.show_all()
487
 
        return table
488
 
 
489
 
 
490
 
class PropertyPageBranch(Nautilus.PropertyPage):
491
 
 
492
 
    def __init__(self, branch):
493
 
        self.branch = branch
494
 
        label = Gtk.Label('Branch')
495
 
        label.show()
496
 
 
497
 
        table = self._create_table()
498
 
 
499
 
        super(PropertyPageBranch, self).__init__(label=label,
500
 
            name="BzrNautilus::branch_page", page=table)
501
 
 
502
 
    def _create_location_entry(self, get_location, set_location):
503
 
        location = get_location()
504
 
        ret = Gtk.Entry()
505
 
        if location is not None:
506
 
            ret.set_text(location)
507
 
        return ret
508
 
 
509
 
    def _create_table(self):
510
 
        table = Gtk.Table(homogeneous=False, columns=2, rows=6)
511
 
 
512
 
        self._push_location_entry = self._create_location_entry(
513
 
            self.branch.get_push_location, self.branch.set_push_location)
514
 
        self._parent_location_entry = self._create_location_entry(
515
 
            self.branch.get_parent, self.branch.set_parent)
516
 
        self._bound_location_entry = self._create_location_entry(
517
 
            self.branch.get_bound_location, self.branch.set_bound_location)
518
 
        self._public_location_entry = self._create_location_entry(
519
 
            self.branch.get_public_branch, self.branch.set_public_branch)
520
 
        self._submit_location_entry = self._create_location_entry(
521
 
            self.branch.get_submit_branch, self.branch.set_submit_branch)
522
 
 
523
 
        table.attach(Gtk.Label(_i18n('Push location:')), 0, 1, 0, 1)
524
 
        table.attach(self._push_location_entry, 1, 2, 0, 1)
525
 
 
526
 
        table.attach(Gtk.Label(_i18n('Parent location:')), 0, 1, 1, 2)
527
 
        table.attach(self._parent_location_entry, 1, 1, 1, 2)
528
 
 
529
 
        table.attach(Gtk.Label(_i18n('Bound location:')), 0, 1, 2, 3)
530
 
        table.attach(self._bound_location_entry, 1, 1, 2, 3)
531
 
 
532
 
        table.attach(Gtk.Label(_i18n('Public location:')), 0, 1, 3, 4)
533
 
        table.attach(self._public_location_entry, 1, 1, 3, 4)
534
 
 
535
 
        table.attach(Gtk.Label(_i18n('Submit location:')), 0, 1, 4, 5)
536
 
        table.attach(self._submit_location_entry, 1, 1, 4, 5)
537
 
 
538
 
        self._append_revisions_only = Gtk.CheckButton(_i18n('Append revisions only'))
539
 
        value = self.branch.get_append_revisions_only()
540
 
        if value is None:
541
 
            value = False
542
 
        self._append_revisions_only.set_active(value)
543
 
        table.attach(self._append_revisions_only, 0, 2, 5, 6)
544
 
 
545
 
        table.show_all()
546
 
        return table
 
446
        branch = tree.branch
 
447
        if branch is None:
 
448
            config = GlobalConfig()
 
449
        else:
 
450
            config = branch.get_config()
 
451
        config.set_user_option('nautilus_integration', action)
 
452