/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 commit.py

  • Committer: Mateusz Korniak
  • Date: 2007-07-21 13:16:33 UTC
  • mto: This revision was merged to the branch mainline in revision 248.
  • Revision ID: matkor@laptop-hp-20070721131633-t40kxs20j1q2fvvc
Context menu "Remove and delete added"
Acts like "Remove" but also deletes file locally.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
2
 
 
 
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
 
 
7
#
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
# GNU General Public License for more details.
12
 
 
 
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
import sys
18
 
 
19
17
try:
20
18
    import pygtk
21
19
    pygtk.require("2.0")
22
20
except:
23
21
    pass
24
 
try:
25
 
    import gtk
26
 
    import gtk.glade
27
 
    import gobject
28
 
except:
29
 
    sys.exit(1)
30
 
 
31
 
from bzrlib.delta import compare_trees
 
22
 
 
23
import gtk
 
24
import gobject
 
25
import pango
 
26
 
 
27
import os.path
 
28
 
32
29
import bzrlib.errors as errors
33
 
from bzrlib.workingtree import WorkingTree
34
 
 
35
 
from dialog import OliveDialog
36
 
 
37
 
class OliveCommit:
38
 
    """ Display Commit dialog and perform the needed actions. """
39
 
    def __init__(self, gladefile, comm):
40
 
        """ Initialize the Commit dialog. """
41
 
        import bzrlib
42
 
        
43
 
        self.gladefile = gladefile
44
 
        self.glade = gtk.glade.XML(self.gladefile, 'window_commit')
45
 
        
46
 
        self.comm = comm
47
 
        
48
 
        self.dialog = OliveDialog(self.gladefile)
49
 
        
50
 
        # Check if current location is a branch
51
 
        try:
52
 
            (self.wt, path) = WorkingTree.open_containing(self.comm.get_path())
53
 
            branch = self.wt.branch
54
 
        except errors.NotBranchError:
55
 
            self.notbranch = True
56
 
            return
57
 
        except:
58
 
            raise
59
 
 
60
 
        file_id = self.wt.path2id(path)
61
 
 
62
 
        self.notbranch = False
63
 
        if file_id is None:
64
 
            self.notbranch = True
65
 
            return
 
30
from bzrlib import osutils
 
31
 
 
32
from dialog import error_dialog, question_dialog
 
33
from errors import show_bzr_error
 
34
 
 
35
try:
 
36
    import dbus
 
37
    import dbus.glib
 
38
    have_dbus = True
 
39
except ImportError:
 
40
    have_dbus = False
 
41
 
 
42
class CommitDialog(gtk.Dialog):
 
43
    """ New implementation of the Commit dialog. """
 
44
    def __init__(self, wt, wtpath, notbranch, selected=None, parent=None):
 
45
        """ Initialize the Commit Dialog. """
 
46
        gtk.Dialog.__init__(self, title="Commit - Olive",
 
47
                                  parent=parent,
 
48
                                  flags=0,
 
49
                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
 
50
        
 
51
        # Get arguments
 
52
        self.wt = wt
 
53
        self.wtpath = wtpath
 
54
        self.notbranch = notbranch
 
55
        self.selected = selected
66
56
        
67
57
        # Set the delta
68
58
        self.old_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
69
 
        if bzrlib.version_info[1] < 9:
70
 
            self.delta = compare_trees(self.old_tree, self.wt)
71
 
        else:
72
 
            self.delta = self.wt.changes_from(self.old_tree)
73
 
        
74
 
        # Get the Commit dialog widget
75
 
        self.window = self.glade.get_widget('window_commit')
76
 
        
77
 
        # Dictionary for signal_autoconnect
78
 
        dic = { "on_button_commit_commit_clicked": self.commit,
79
 
                "on_button_commit_cancel_clicked": self.close }
80
 
        
81
 
        # Connect the signals to the handlers
82
 
        self.glade.signal_autoconnect(dic)
83
 
        
 
59
        self.delta = self.wt.changes_from(self.old_tree)
 
60
        
 
61
        # Get pending merges
 
62
        self.pending = self._pending_merges(self.wt)
 
63
        
 
64
        # Do some preliminary checks
 
65
        self._is_checkout = False
 
66
        self._is_pending = False
 
67
        if self.wt is None and not self.notbranch:
 
68
            error_dialog(_('Directory does not have a working tree'),
 
69
                         _('Operation aborted.'))
 
70
            self.close()
 
71
            return
 
72
 
 
73
        if self.notbranch:
 
74
            error_dialog(_('Directory is not a branch'),
 
75
                         _('You can perform this action only in a branch.'))
 
76
            self.close()
 
77
            return
 
78
        else:
 
79
            if self.wt.branch.get_bound_location() is not None:
 
80
                # we have a checkout, so the local commit checkbox must appear
 
81
                self._is_checkout = True
 
82
            
 
83
            if self.pending:
 
84
                # There are pending merges, file selection not supported
 
85
                self._is_pending = True
 
86
        
 
87
        # Create the widgets
 
88
        self._button_commit = gtk.Button(_("Comm_it"), use_underline=True)
 
89
        self._expander_files = gtk.Expander(_("File(s) to commit"))
 
90
        self._vpaned_main = gtk.VPaned()
 
91
        self._scrolledwindow_files = gtk.ScrolledWindow()
 
92
        self._scrolledwindow_message = gtk.ScrolledWindow()
 
93
        self._treeview_files = gtk.TreeView()
 
94
        self._vbox_message = gtk.VBox()
 
95
        self._label_message = gtk.Label(_("Commit message:"))
 
96
        self._textview_message = gtk.TextView()
 
97
        
 
98
        if self._is_pending:
 
99
            self._expander_merges = gtk.Expander(_("Pending merges"))
 
100
            self._vpaned_list = gtk.VPaned()
 
101
            self._scrolledwindow_merges = gtk.ScrolledWindow()
 
102
            self._treeview_merges = gtk.TreeView()
 
103
 
 
104
        # Set callbacks
 
105
        self._button_commit.connect('clicked', self._on_commit_clicked)
 
106
        self._treeview_files.connect('row_activated', self._on_treeview_files_row_activated)
 
107
        
 
108
        # Set properties
 
109
        self._scrolledwindow_files.set_policy(gtk.POLICY_AUTOMATIC,
 
110
                                              gtk.POLICY_AUTOMATIC)
 
111
        self._scrolledwindow_message.set_policy(gtk.POLICY_AUTOMATIC,
 
112
                                                gtk.POLICY_AUTOMATIC)
 
113
        self._textview_message.modify_font(pango.FontDescription("Monospace"))
 
114
        self.set_default_size(500, 500)
 
115
        self._vpaned_main.set_position(200)
 
116
        self._button_commit.set_flags(gtk.CAN_DEFAULT)
 
117
 
 
118
        if self._is_pending:
 
119
            self._scrolledwindow_merges.set_policy(gtk.POLICY_AUTOMATIC,
 
120
                                                   gtk.POLICY_AUTOMATIC)
 
121
            self._treeview_files.set_sensitive(False)
 
122
        
 
123
        # Construct the dialog
 
124
        self.action_area.pack_end(self._button_commit)
 
125
        
 
126
        self._scrolledwindow_files.add(self._treeview_files)
 
127
        self._scrolledwindow_message.add(self._textview_message)
 
128
        
 
129
        self._expander_files.add(self._scrolledwindow_files)
 
130
        
 
131
        self._vbox_message.pack_start(self._label_message, False, False)
 
132
        self._vbox_message.pack_start(self._scrolledwindow_message, True, True)
 
133
        
 
134
        if self._is_pending:        
 
135
            self._expander_merges.add(self._scrolledwindow_merges)
 
136
            self._scrolledwindow_merges.add(self._treeview_merges)
 
137
            self._vpaned_list.add1(self._expander_files)
 
138
            self._vpaned_list.add2(self._expander_merges)
 
139
            self._vpaned_main.add1(self._vpaned_list)
 
140
        else:
 
141
            self._vpaned_main.add1(self._expander_files)
 
142
 
 
143
        self._vpaned_main.add2(self._vbox_message)
 
144
        
 
145
        self.vbox.pack_start(self._vpaned_main, True, True)
 
146
        if self._is_checkout: 
 
147
            self._check_local = gtk.CheckButton(_("_Only commit locally"),
 
148
                                                use_underline=True)
 
149
            self.vbox.pack_start(self._check_local, False, False)
 
150
            if have_dbus:
 
151
                bus = dbus.SystemBus()
 
152
                proxy_obj = bus.get_object('org.freedesktop.NetworkManager', 
 
153
                              '/org/freedesktop/NetworkManager')
 
154
                dbus_iface = dbus.Interface(
 
155
                        proxy_obj, 'org.freedesktop.NetworkManager')
 
156
                try:
 
157
                    # 3 is the enum value for STATE_CONNECTED
 
158
                    self._check_local.set_active(dbus_iface.state() != 3)
 
159
                except dbus.DBusException, e:
 
160
                    # Silently drop errors. While DBus may be 
 
161
                    # available, NetworkManager doesn't necessarily have to be
 
162
                    mutter("unable to get networkmanager state: %r" % e)
 
163
                
84
164
        # Create the file list
85
165
        self._create_file_view()
86
 
        
87
 
        # Some additional widgets
88
 
        self.checkbutton_local = self.glade.get_widget('checkbutton_commit_local')
89
 
    
90
 
    def display(self):
91
 
        """ Display the Push dialog. """
92
 
        if self.notbranch:
93
 
            self.dialog.error_dialog('Directory is not a branch.')
94
 
        else:
95
 
            from olive.backend.info import is_checkout
96
 
            if is_checkout(self.comm.get_path()):
97
 
                # we have a checkout, so the local commit checkbox must appear
98
 
                self.checkbutton_local.show()
99
 
            
100
 
            self.window.show()
101
 
            
102
 
    
103
 
    # This code is from Jelmer Vernooij's bzr-gtk branch
 
166
        # Create the pending merges
 
167
        self._create_pending_merges()
 
168
        
 
169
        # Expand the corresponding expander
 
170
        if self._is_pending:
 
171
            self._expander_merges.set_expanded(True)
 
172
        else:
 
173
            self._expander_files.set_expanded(True)
 
174
        
 
175
        # Display dialog
 
176
        self.vbox.show_all()
 
177
        
 
178
        # Default to Commit button
 
179
        self._button_commit.grab_default()
 
180
    
 
181
    def _on_treeview_files_row_activated(self, treeview, path, view_column):
 
182
        # FIXME: the diff window freezes for some reason
 
183
        treeselection = treeview.get_selection()
 
184
        (model, iter) = treeselection.get_selected()
 
185
        
 
186
        if iter is not None:
 
187
            from diff import DiffWindow
 
188
            
 
189
            _selected = model.get_value(iter, 1)
 
190
            
 
191
            diff = DiffWindow()
 
192
            diff.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
 
193
            diff.set_modal(True)
 
194
            parent_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
 
195
            diff.set_diff(self.wt.branch.nick, self.wt, parent_tree)
 
196
            try:
 
197
                diff.set_file(_selected)
 
198
            except errors.NoSuchFile:
 
199
                pass
 
200
            diff.show()
 
201
    
 
202
    @show_bzr_error
 
203
    def _on_commit_clicked(self, button):
 
204
        """ Commit button clicked handler. """
 
205
        textbuffer = self._textview_message.get_buffer()
 
206
        start, end = textbuffer.get_bounds()
 
207
        message = textbuffer.get_text(start, end).decode('utf-8')
 
208
        
 
209
        if not self.pending:
 
210
            specific_files = self._get_specific_files()
 
211
        else:
 
212
            specific_files = None
 
213
 
 
214
        if message == '':
 
215
            response = question_dialog(_('Commit with an empty message?'),
 
216
                                       _('You can describe your commit intent in the message.'))
 
217
            if response == gtk.RESPONSE_NO:
 
218
                # Kindly give focus to message area
 
219
                self._textview_message.grab_focus()
 
220
                return
 
221
 
 
222
        if self._is_checkout:
 
223
            local = self._check_local.get_active()
 
224
        else:
 
225
            local = False
 
226
 
 
227
        if list(self.wt.unknowns()) != []:
 
228
            response = question_dialog(_("Commit with unknowns?"),
 
229
               _("Unknown files exist in the working tree. Commit anyway?"))
 
230
            if response == gtk.RESPONSE_NO:
 
231
                return
 
232
        
 
233
        try:
 
234
            self.wt.commit(message,
 
235
                       allow_pointless=False,
 
236
                       strict=False,
 
237
                       local=local,
 
238
                       specific_files=specific_files)
 
239
        except errors.PointlessCommit:
 
240
            response = question_dialog(_('Commit with no changes?'),
 
241
                                       _('There are no changes in the working tree.'))
 
242
            if response == gtk.RESPONSE_YES:
 
243
                self.wt.commit(message,
 
244
                               allow_pointless=True,
 
245
                               strict=False,
 
246
                               local=local,
 
247
                               specific_files=specific_files)
 
248
        self.response(gtk.RESPONSE_OK)
 
249
 
 
250
    def _pending_merges(self, wt):
 
251
        """ Return a list of pending merges or None if there are none of them. """
 
252
        parents = wt.get_parent_ids()
 
253
        if len(parents) < 2:
 
254
            return None
 
255
        
 
256
        import re
 
257
        from bzrlib.osutils import format_date
 
258
        
 
259
        pending = parents[1:]
 
260
        branch = wt.branch
 
261
        last_revision = parents[0]
 
262
        
 
263
        if last_revision is not None:
 
264
            try:
 
265
                ignore = set(branch.repository.get_ancestry(last_revision))
 
266
            except errors.NoSuchRevision:
 
267
                # the last revision is a ghost : assume everything is new 
 
268
                # except for it
 
269
                ignore = set([None, last_revision])
 
270
        else:
 
271
            ignore = set([None])
 
272
        
 
273
        pm = []
 
274
        for merge in pending:
 
275
            ignore.add(merge)
 
276
            try:
 
277
                m_revision = branch.repository.get_revision(merge)
 
278
                
 
279
                rev = {}
 
280
                rev['committer'] = re.sub('<.*@.*>', '', m_revision.committer).strip(' ')
 
281
                rev['summary'] = m_revision.get_summary()
 
282
                rev['date'] = format_date(m_revision.timestamp,
 
283
                                          m_revision.timezone or 0, 
 
284
                                          'original', date_fmt="%Y-%m-%d",
 
285
                                          show_offset=False)
 
286
                
 
287
                pm.append(rev)
 
288
                
 
289
                inner_merges = branch.repository.get_ancestry(merge)
 
290
                assert inner_merges[0] is None
 
291
                inner_merges.pop(0)
 
292
                inner_merges.reverse()
 
293
                for mmerge in inner_merges:
 
294
                    if mmerge in ignore:
 
295
                        continue
 
296
                    mm_revision = branch.repository.get_revision(mmerge)
 
297
                    
 
298
                    rev = {}
 
299
                    rev['committer'] = re.sub('<.*@.*>', '', mm_revision.committer).strip(' ')
 
300
                    rev['summary'] = mm_revision.get_summary()
 
301
                    rev['date'] = format_date(mm_revision.timestamp,
 
302
                                              mm_revision.timezone or 0, 
 
303
                                              'original', date_fmt="%Y-%m-%d",
 
304
                                              show_offset=False)
 
305
                
 
306
                    pm.append(rev)
 
307
                    
 
308
                    ignore.add(mmerge)
 
309
            except errors.NoSuchRevision:
 
310
                print "DEBUG: NoSuchRevision:", merge
 
311
        
 
312
        return pm
 
313
 
104
314
    def _create_file_view(self):
105
 
        self.file_store = gtk.ListStore(gobject.TYPE_BOOLEAN,
106
 
                                        gobject.TYPE_STRING,
107
 
                                        gobject.TYPE_STRING)
108
 
        self.file_view = self.glade.get_widget('treeview_commit_select')
109
 
        self.file_view.set_model(self.file_store)
 
315
        self._file_store = gtk.ListStore(gobject.TYPE_BOOLEAN,   # [0] checkbox
 
316
                                         gobject.TYPE_STRING,    # [1] path to display
 
317
                                         gobject.TYPE_STRING,    # [2] changes type
 
318
                                         gobject.TYPE_STRING)    # [3] real path
 
319
        self._treeview_files.set_model(self._file_store)
110
320
        crt = gtk.CellRendererToggle()
111
321
        crt.set_property("activatable", True)
112
 
        crt.connect("toggled", self._toggle_commit, self.file_store)
113
 
        self.file_view.append_column(gtk.TreeViewColumn("Commit",
 
322
        crt.connect("toggled", self._toggle_commit, self._file_store)
 
323
        self._treeview_files.append_column(gtk.TreeViewColumn(_('Commit'),
114
324
                                     crt, active=0))
115
 
        self.file_view.append_column(gtk.TreeViewColumn("Path",
 
325
        self._treeview_files.append_column(gtk.TreeViewColumn(_('Path'),
116
326
                                     gtk.CellRendererText(), text=1))
117
 
        self.file_view.append_column(gtk.TreeViewColumn("Type",
 
327
        self._treeview_files.append_column(gtk.TreeViewColumn(_('Type'),
118
328
                                     gtk.CellRendererText(), text=2))
119
329
 
120
 
        for path, _, _ in self.delta.added:
121
 
            self.file_store.append([ True, path, "added" ])
122
 
 
123
 
        for path, _, _ in self.delta.removed:
124
 
            self.file_store.append([ True, path, "removed" ])
125
 
 
126
 
        for oldpath, _, _, _, _, _ in self.delta.renamed:
127
 
            self.file_store.append([ True, oldpath, "renamed"])
128
 
 
129
 
        for path, _, _, _, _ in self.delta.modified:
130
 
            self.file_store.append([ True, path, "modified"])
 
330
        for path, id, kind in self.delta.added:
 
331
            marker = osutils.kind_marker(kind)
 
332
            if self.selected is not None:
 
333
                if path == os.path.join(self.wtpath, self.selected):
 
334
                    self._file_store.append([ True, path+marker, _('added'), path ])
 
335
                else:
 
336
                    self._file_store.append([ False, path+marker, _('added'), path ])
 
337
            else:
 
338
                self._file_store.append([ True, path+marker, _('added'), path ])
 
339
 
 
340
        for path, id, kind in self.delta.removed:
 
341
            marker = osutils.kind_marker(kind)
 
342
            if self.selected is not None:
 
343
                if path == os.path.join(self.wtpath, self.selected):
 
344
                    self._file_store.append([ True, path+marker, _('removed'), path ])
 
345
                else:
 
346
                    self._file_store.append([ False, path+marker, _('removed'), path ])
 
347
            else:
 
348
                self._file_store.append([ True, path+marker, _('removed'), path ])
 
349
 
 
350
        for oldpath, newpath, id, kind, text_modified, meta_modified in self.delta.renamed:
 
351
            marker = osutils.kind_marker(kind)
 
352
            if text_modified or meta_modified:
 
353
                changes = _('renamed and modified')
 
354
            else:
 
355
                changes = _('renamed')
 
356
            if self.selected is not None:
 
357
                if newpath == os.path.join(self.wtpath, self.selected):
 
358
                    self._file_store.append([ True,
 
359
                                              oldpath+marker + '  =>  ' + newpath+marker,
 
360
                                              changes,
 
361
                                              newpath
 
362
                                            ])
 
363
                else:
 
364
                    self._file_store.append([ False,
 
365
                                              oldpath+marker + '  =>  ' + newpath+marker,
 
366
                                              changes,
 
367
                                              newpath
 
368
                                            ])
 
369
            else:
 
370
                self._file_store.append([ True,
 
371
                                          oldpath+marker + '  =>  ' + newpath+marker,
 
372
                                          changes,
 
373
                                          newpath
 
374
                                        ])
 
375
 
 
376
        for path, id, kind, text_modified, meta_modified in self.delta.modified:
 
377
            marker = osutils.kind_marker(kind)
 
378
            if self.selected is not None:
 
379
                if path == os.path.join(self.wtpath, self.selected):
 
380
                    self._file_store.append([ True, path+marker, _('modified'), path ])
 
381
                else:
 
382
                    self._file_store.append([ False, path+marker, _('modified'), path ])
 
383
            else:
 
384
                self._file_store.append([ True, path+marker, _('modified'), path ])
 
385
    
 
386
    def _create_pending_merges(self):
 
387
        if not self.pending:
 
388
            return
 
389
        
 
390
        liststore = gtk.ListStore(gobject.TYPE_STRING,
 
391
                                  gobject.TYPE_STRING,
 
392
                                  gobject.TYPE_STRING)
 
393
        self._treeview_merges.set_model(liststore)
 
394
        
 
395
        self._treeview_merges.append_column(gtk.TreeViewColumn(_('Date'),
 
396
                                            gtk.CellRendererText(), text=0))
 
397
        self._treeview_merges.append_column(gtk.TreeViewColumn(_('Committer'),
 
398
                                            gtk.CellRendererText(), text=1))
 
399
        self._treeview_merges.append_column(gtk.TreeViewColumn(_('Summary'),
 
400
                                            gtk.CellRendererText(), text=2))
 
401
        
 
402
        for item in self.pending:
 
403
            liststore.append([ item['date'],
 
404
                               item['committer'],
 
405
                               item['summary'] ])
131
406
    
132
407
    def _get_specific_files(self):
133
408
        ret = []
134
 
        it = self.file_store.get_iter_first()
 
409
        it = self._file_store.get_iter_first()
135
410
        while it:
136
 
            if self.file_store.get_value(it, 0):
137
 
                ret.append(self.file_store.get_value(it, 1))
138
 
            it = self.file_store.iter_next(it)
 
411
            if self._file_store.get_value(it, 0):
 
412
                # get real path from hidden column 3
 
413
                ret.append(self._file_store.get_value(it, 3))
 
414
            it = self._file_store.iter_next(it)
139
415
 
140
416
        return ret
141
 
    # end of bzr-gtk code
142
417
    
143
418
    def _toggle_commit(self, cell, path, model):
144
419
        model[path][0] = not model[path][0]
145
420
        return
146
 
    
147
 
    def commit(self, widget):
148
 
        textview = self.glade.get_widget('textview_commit')
149
 
        textbuffer = textview.get_buffer()
150
 
        start, end = textbuffer.get_bounds()
151
 
        message = textbuffer.get_text(start, end)
152
 
        
153
 
        checkbutton_strict = self.glade.get_widget('checkbutton_commit_strict')
154
 
        checkbutton_force = self.glade.get_widget('checkbutton_commit_force')
155
 
        
156
 
        specific_files = self._get_specific_files()
157
 
        
158
 
        self.comm.set_busy(self.window)
159
 
        # merged from Jelmer Vernooij's olive integration branch
160
 
        try:
161
 
            self.wt.commit(message, 
162
 
                           allow_pointless=checkbutton_force.get_active(),
163
 
                           strict=checkbutton_strict.get_active(),
164
 
                           local=self.checkbutton_local.get_active(),
165
 
                           specific_files=specific_files)
166
 
        except errors.NotBranchError:
167
 
            self.dialog.error_dialog('Directory is not a branch.')
168
 
            self.comm.set_busy(self.window, False)
169
 
            return
170
 
        except errors.LocalRequiresBoundBranch:
171
 
            self.dialog.error_dialog('Local commit requires a bound branch.')
172
 
            self.comm.set_busy(self.window, False)
173
 
            return
174
 
        except errors.PointlessCommit:
175
 
            self.dialog.error_dialog('No changes to commit. Try force commit.')
176
 
            self.comm.set_busy(self.window, False)
177
 
            return
178
 
        except errors.ConflictsInTree:
179
 
            self.dialog.error_dialog('Conflicts in tree. Please resolve them first.')
180
 
            self.comm.set_busy(self.window, False)
181
 
            return
182
 
        except errors.StrictCommitFailed:
183
 
            self.dialog.error_dialog('Strict commit failed. There are unknown files.')
184
 
            self.comm.set_busy(self.window, False)
185
 
            return
186
 
        except errors.BoundBranchOutOfDate, errmsg:
187
 
            self.dialog.error_dialog('Bound branch is out of date: %s' % errmsg)
188
 
            self.comm.set_busy(self.window, False)
189
 
            return
190
 
        except:
191
 
            raise
192
 
        
193
 
        self.close()
194
 
        self.comm.refresh_right()
195
 
        
196
 
    def close(self, widget=None):
197
 
        self.window.destroy()