/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
0.8.46 by Szilveszter Farkas (Phanatic)
Modified OliveDialog class interface; huge cleanups.
2
#
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
0.8.46 by Szilveszter Farkas (Phanatic)
Modified OliveDialog class interface; huge cleanups.
7
#
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
0.8.46 by Szilveszter Farkas (Phanatic)
Modified OliveDialog class interface; huge cleanups.
12
#
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
try:
18
    import pygtk
19
    pygtk.require("2.0")
20
except:
21
    pass
0.8.98 by Szilveszter Farkas (Phanatic)
Loads of fixes. Pyflakes cleanup.
22
0.13.11 by Jelmer Vernooij
Bunch of small fixes, cleanups and simplifications.
23
import gtk
24
import gobject
25
import pango
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
26
126.1.10 by Szilveszter Farkas (Phanatic)
Allow to commit single files from the context menu (Fixed: #54983)
27
import os.path
28
248 by Jelmer Vernooij
Merge fixes for #127392 and #127381)
29
from bzrlib import errors, osutils
235.1.5 by Mateusz Korniak
Missing mutter import added.
30
from bzrlib.trace import mutter
0.8.20 by Szilveszter Farkas (Phanatic)
2006-07-24 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
31
153 by Jelmer Vernooij
Fix references to dialog.
32
from dialog import error_dialog, question_dialog
132 by Jelmer Vernooij
Use decorator for catching and showing bzr-gtk errors graphically. Eventually, this should go away and should be handled by the ui factory.
33
from errors import show_bzr_error
93.1.6 by Alexander Belchenko
detecting name of glade file doing in separate module (olive.gladefile)
34
158 by Jelmer Vernooij
If available, use NetworkManager to find out whether a commit should be local or not.
35
try:
36
    import dbus
37
    import dbus.glib
180 by Jelmer Vernooij
Don't obtain handle to network manager until it's actually needed.
38
    have_dbus = True
158 by Jelmer Vernooij
If available, use NetworkManager to find out whether a commit should be local or not.
39
except ImportError:
180 by Jelmer Vernooij
Don't obtain handle to network manager until it's actually needed.
40
    have_dbus = False
158 by Jelmer Vernooij
If available, use NetworkManager to find out whether a commit should be local or not.
41
278.1.4 by John Arbash Meinel
Just playing around.
42
135 by Jelmer Vernooij
Throw out the old CommitDialog code and use the new code instead, also for 'gcommit'.
43
class CommitDialog(gtk.Dialog):
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
44
    """ New implementation of the Commit dialog. """
45
    def __init__(self, wt, wtpath, notbranch, selected=None, parent=None):
46
        """ Initialize the Commit Dialog. """
47
        gtk.Dialog.__init__(self, title="Commit - Olive",
48
                                  parent=parent,
49
                                  flags=0,
50
                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
51
        
52
        # Get arguments
53
        self.wt = wt
54
        self.wtpath = wtpath
55
        self.notbranch = notbranch
56
        self.selected = selected
57
        
58
        # Set the delta
59
        self.old_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
60
        self.delta = self.wt.changes_from(self.old_tree)
61
        
62
        # Get pending merges
63
        self.pending = self._pending_merges(self.wt)
64
        
65
        # Do some preliminary checks
66
        self._is_checkout = False
67
        self._is_pending = False
68
        if self.wt is None and not self.notbranch:
69
            error_dialog(_('Directory does not have a working tree'),
70
                         _('Operation aborted.'))
71
            self.close()
72
            return
73
74
        if self.notbranch:
75
            error_dialog(_('Directory is not a branch'),
76
                         _('You can perform this action only in a branch.'))
77
            self.close()
78
            return
79
        else:
80
            if self.wt.branch.get_bound_location() is not None:
81
                # we have a checkout, so the local commit checkbox must appear
82
                self._is_checkout = True
83
            
84
            if self.pending:
85
                # There are pending merges, file selection not supported
86
                self._is_pending = True
87
        
88
        # Create the widgets
278.1.4 by John Arbash Meinel
Just playing around.
89
        # This is the main horizontal box, which is used to separate the commit
90
        # info from the diff window.
91
        self._hpane = gtk.HPaned()
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
92
        self._button_commit = gtk.Button(_("Comm_it"), use_underline=True)
145 by Jelmer Vernooij
Fix some strings, import.
93
        self._expander_files = gtk.Expander(_("File(s) to commit"))
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
94
        self._vpaned_main = gtk.VPaned()
95
        self._scrolledwindow_files = gtk.ScrolledWindow()
96
        self._scrolledwindow_message = gtk.ScrolledWindow()
97
        self._treeview_files = gtk.TreeView()
98
        self._vbox_message = gtk.VBox()
145 by Jelmer Vernooij
Fix some strings, import.
99
        self._label_message = gtk.Label(_("Commit message:"))
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
100
        self._textview_message = gtk.TextView()
101
        
102
        if self._is_pending:
103
            self._expander_merges = gtk.Expander(_("Pending merges"))
104
            self._vpaned_list = gtk.VPaned()
105
            self._scrolledwindow_merges = gtk.ScrolledWindow()
106
            self._treeview_merges = gtk.TreeView()
107
108
        # Set callbacks
109
        self._button_commit.connect('clicked', self._on_commit_clicked)
278.1.4 by John Arbash Meinel
Just playing around.
110
        self._treeview_files.connect('cursor-changed', self._on_treeview_files_cursor_changed)
111
        self._treeview_files.connect('row-activated', self._on_treeview_files_row_activated)
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
112
        
113
        # Set properties
114
        self._scrolledwindow_files.set_policy(gtk.POLICY_AUTOMATIC,
115
                                              gtk.POLICY_AUTOMATIC)
116
        self._scrolledwindow_message.set_policy(gtk.POLICY_AUTOMATIC,
117
                                                gtk.POLICY_AUTOMATIC)
118
        self._textview_message.modify_font(pango.FontDescription("Monospace"))
119
        self.set_default_size(500, 500)
120
        self._vpaned_main.set_position(200)
126.1.29 by Szilveszter Farkas (Phanatic)
Default button set on Commit dialog (Fixed: #83030)
121
        self._button_commit.set_flags(gtk.CAN_DEFAULT)
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
122
123
        if self._is_pending:
124
            self._scrolledwindow_merges.set_policy(gtk.POLICY_AUTOMATIC,
125
                                                   gtk.POLICY_AUTOMATIC)
126
            self._treeview_files.set_sensitive(False)
127
        
128
        # Construct the dialog
129
        self.action_area.pack_end(self._button_commit)
130
        
131
        self._scrolledwindow_files.add(self._treeview_files)
132
        self._scrolledwindow_message.add(self._textview_message)
133
        
134
        self._expander_files.add(self._scrolledwindow_files)
135
        
136
        self._vbox_message.pack_start(self._label_message, False, False)
137
        self._vbox_message.pack_start(self._scrolledwindow_message, True, True)
138
        
139
        if self._is_pending:        
140
            self._expander_merges.add(self._scrolledwindow_merges)
141
            self._scrolledwindow_merges.add(self._treeview_merges)
142
            self._vpaned_list.add1(self._expander_files)
143
            self._vpaned_list.add2(self._expander_merges)
144
            self._vpaned_main.add1(self._vpaned_list)
145
        else:
146
            self._vpaned_main.add1(self._expander_files)
147
148
        self._vpaned_main.add2(self._vbox_message)
149
        
278.1.4 by John Arbash Meinel
Just playing around.
150
        self._hpane.pack1(self._vpaned_main)
151
        self.vbox.pack_start(self._hpane, expand=True, fill=True)
159 by Jelmer Vernooij
Use network manager for checking default of "Local Commit" setting rather than hiding the option completely.
152
        if self._is_checkout: 
158 by Jelmer Vernooij
If available, use NetworkManager to find out whether a commit should be local or not.
153
            self._check_local = gtk.CheckButton(_("_Only commit locally"),
154
                                                use_underline=True)
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
155
            self.vbox.pack_start(self._check_local, False, False)
180 by Jelmer Vernooij
Don't obtain handle to network manager until it's actually needed.
156
            if have_dbus:
157
                bus = dbus.SystemBus()
158
                proxy_obj = bus.get_object('org.freedesktop.NetworkManager', 
159
                              '/org/freedesktop/NetworkManager')
160
                dbus_iface = dbus.Interface(
161
                        proxy_obj, 'org.freedesktop.NetworkManager')
235.1.1 by Mateusz Korniak
Fix for broken dbus detection if network is avaiable.
162
                try:
163
                    # 3 is the enum value for STATE_CONNECTED
240 by Jelmer Vernooij
Merge fix for local commits when network manager isn't available.
164
                    self._check_local.set_active(dbus_iface.state() != 3)
165
                except dbus.DBusException, e:
166
                    # Silently drop errors. While DBus may be 
167
                    # available, NetworkManager doesn't necessarily have to be
168
                    mutter("unable to get networkmanager state: %r" % e)
235.1.1 by Mateusz Korniak
Fix for broken dbus detection if network is avaiable.
169
                
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
170
        # Create the file list
171
        self._create_file_view()
172
        # Create the pending merges
173
        self._create_pending_merges()
278.1.4 by John Arbash Meinel
Just playing around.
174
        self._create_diff_view()
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
175
        
176
        # Expand the corresponding expander
177
        if self._is_pending:
178
            self._expander_merges.set_expanded(True)
179
        else:
180
            self._expander_files.set_expanded(True)
181
        
182
        # Display dialog
183
        self.vbox.show_all()
126.1.29 by Szilveszter Farkas (Phanatic)
Default button set on Commit dialog (Fixed: #83030)
184
        
185
        # Default to Commit button
186
        self._button_commit.grab_default()
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
187
    
278.1.4 by John Arbash Meinel
Just playing around.
188
    def _show_diff_view(self, treeview):
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
189
        # FIXME: the diff window freezes for some reason
190
        treeselection = treeview.get_selection()
191
        (model, iter) = treeselection.get_selected()
278.1.4 by John Arbash Meinel
Just playing around.
192
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
193
        if iter is not None:
278.1.4 by John Arbash Meinel
Just playing around.
194
            selected = model.get_value(iter, 3) # Get the real_path attribute
195
            self._diff_display.show_diff([selected])
196
197
    def _on_treeview_files_cursor_changed(self, treeview):
198
        self._show_diff_view(treeview)
199
        
200
    def _on_treeview_files_row_activated(self, treeview, path, view_column):
201
        self._show_diff_view(treeview)
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
202
    
132 by Jelmer Vernooij
Use decorator for catching and showing bzr-gtk errors graphically. Eventually, this should go away and should be handled by the ui factory.
203
    @show_bzr_error
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
204
    def _on_commit_clicked(self, button):
205
        """ Commit button clicked handler. """
206
        textbuffer = self._textview_message.get_buffer()
207
        start, end = textbuffer.get_bounds()
208
        message = textbuffer.get_text(start, end).decode('utf-8')
209
        
210
        if not self.pending:
211
            specific_files = self._get_specific_files()
212
        else:
213
            specific_files = None
214
215
        if message == '':
216
            response = question_dialog(_('Commit with an empty message?'),
217
                                       _('You can describe your commit intent in the message.'))
218
            if response == gtk.RESPONSE_NO:
219
                # Kindly give focus to message area
220
                self._textview_message.grab_focus()
221
                return
222
223
        if self._is_checkout:
159 by Jelmer Vernooij
Use network manager for checking default of "Local Commit" setting rather than hiding the option completely.
224
            local = self._check_local.get_active()
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
225
        else:
226
            local = False
176 by Jelmer Vernooij
Don't make the user worry about strict commit unless we actually find unknown files.
227
228
        if list(self.wt.unknowns()) != []:
229
            response = question_dialog(_("Commit with unknowns?"),
230
               _("Unknown files exist in the working tree. Commit anyway?"))
231
            if response == gtk.RESPONSE_NO:
232
                return
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
233
        
234
        try:
235
            self.wt.commit(message,
132 by Jelmer Vernooij
Use decorator for catching and showing bzr-gtk errors graphically. Eventually, this should go away and should be handled by the ui factory.
236
                       allow_pointless=False,
176 by Jelmer Vernooij
Don't make the user worry about strict commit unless we actually find unknown files.
237
                       strict=False,
132 by Jelmer Vernooij
Use decorator for catching and showing bzr-gtk errors graphically. Eventually, this should go away and should be handled by the ui factory.
238
                       local=local,
239
                       specific_files=specific_files)
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
240
        except errors.PointlessCommit:
241
            response = question_dialog(_('Commit with no changes?'),
242
                                       _('There are no changes in the working tree.'))
243
            if response == gtk.RESPONSE_YES:
132 by Jelmer Vernooij
Use decorator for catching and showing bzr-gtk errors graphically. Eventually, this should go away and should be handled by the ui factory.
244
                self.wt.commit(message,
245
                               allow_pointless=True,
176 by Jelmer Vernooij
Don't make the user worry about strict commit unless we actually find unknown files.
246
                               strict=False,
132 by Jelmer Vernooij
Use decorator for catching and showing bzr-gtk errors graphically. Eventually, this should go away and should be handled by the ui factory.
247
                               local=local,
248
                               specific_files=specific_files)
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
249
        self.response(gtk.RESPONSE_OK)
250
251
    def _pending_merges(self, wt):
252
        """ Return a list of pending merges or None if there are none of them. """
253
        parents = wt.get_parent_ids()
254
        if len(parents) < 2:
255
            return None
256
        
257
        import re
258
        from bzrlib.osutils import format_date
259
        
260
        pending = parents[1:]
261
        branch = wt.branch
262
        last_revision = parents[0]
263
        
264
        if last_revision is not None:
265
            try:
266
                ignore = set(branch.repository.get_ancestry(last_revision))
267
            except errors.NoSuchRevision:
268
                # the last revision is a ghost : assume everything is new 
269
                # except for it
270
                ignore = set([None, last_revision])
271
        else:
272
            ignore = set([None])
273
        
274
        pm = []
275
        for merge in pending:
276
            ignore.add(merge)
277
            try:
278
                m_revision = branch.repository.get_revision(merge)
279
                
280
                rev = {}
281
                rev['committer'] = re.sub('<.*@.*>', '', m_revision.committer).strip(' ')
282
                rev['summary'] = m_revision.get_summary()
283
                rev['date'] = format_date(m_revision.timestamp,
284
                                          m_revision.timezone or 0, 
285
                                          'original', date_fmt="%Y-%m-%d",
286
                                          show_offset=False)
287
                
288
                pm.append(rev)
289
                
290
                inner_merges = branch.repository.get_ancestry(merge)
291
                assert inner_merges[0] is None
292
                inner_merges.pop(0)
293
                inner_merges.reverse()
294
                for mmerge in inner_merges:
295
                    if mmerge in ignore:
296
                        continue
297
                    mm_revision = branch.repository.get_revision(mmerge)
298
                    
299
                    rev = {}
300
                    rev['committer'] = re.sub('<.*@.*>', '', mm_revision.committer).strip(' ')
301
                    rev['summary'] = mm_revision.get_summary()
302
                    rev['date'] = format_date(mm_revision.timestamp,
303
                                              mm_revision.timezone or 0, 
304
                                              'original', date_fmt="%Y-%m-%d",
305
                                              show_offset=False)
306
                
307
                    pm.append(rev)
308
                    
309
                    ignore.add(mmerge)
310
            except errors.NoSuchRevision:
311
                print "DEBUG: NoSuchRevision:", merge
312
        
313
        return pm
314
315
    def _create_file_view(self):
316
        self._file_store = gtk.ListStore(gobject.TYPE_BOOLEAN,   # [0] checkbox
317
                                         gobject.TYPE_STRING,    # [1] path to display
318
                                         gobject.TYPE_STRING,    # [2] changes type
319
                                         gobject.TYPE_STRING)    # [3] real path
320
        self._treeview_files.set_model(self._file_store)
321
        crt = gtk.CellRendererToggle()
322
        crt.set_property("activatable", True)
323
        crt.connect("toggled", self._toggle_commit, self._file_store)
324
        self._treeview_files.append_column(gtk.TreeViewColumn(_('Commit'),
325
                                     crt, active=0))
326
        self._treeview_files.append_column(gtk.TreeViewColumn(_('Path'),
327
                                     gtk.CellRendererText(), text=1))
328
        self._treeview_files.append_column(gtk.TreeViewColumn(_('Type'),
329
                                     gtk.CellRendererText(), text=2))
330
331
        for path, id, kind in self.delta.added:
332
            marker = osutils.kind_marker(kind)
126.1.10 by Szilveszter Farkas (Phanatic)
Allow to commit single files from the context menu (Fixed: #54983)
333
            if self.selected is not None:
334
                if path == os.path.join(self.wtpath, self.selected):
335
                    self._file_store.append([ True, path+marker, _('added'), path ])
336
                else:
337
                    self._file_store.append([ False, path+marker, _('added'), path ])
338
            else:
339
                self._file_store.append([ True, path+marker, _('added'), path ])
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
340
341
        for path, id, kind in self.delta.removed:
342
            marker = osutils.kind_marker(kind)
126.1.10 by Szilveszter Farkas (Phanatic)
Allow to commit single files from the context menu (Fixed: #54983)
343
            if self.selected is not None:
344
                if path == os.path.join(self.wtpath, self.selected):
345
                    self._file_store.append([ True, path+marker, _('removed'), path ])
346
                else:
347
                    self._file_store.append([ False, path+marker, _('removed'), path ])
348
            else:
349
                self._file_store.append([ True, path+marker, _('removed'), path ])
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
350
351
        for oldpath, newpath, id, kind, text_modified, meta_modified in self.delta.renamed:
352
            marker = osutils.kind_marker(kind)
353
            if text_modified or meta_modified:
354
                changes = _('renamed and modified')
355
            else:
356
                changes = _('renamed')
126.1.10 by Szilveszter Farkas (Phanatic)
Allow to commit single files from the context menu (Fixed: #54983)
357
            if self.selected is not None:
358
                if newpath == os.path.join(self.wtpath, self.selected):
359
                    self._file_store.append([ True,
360
                                              oldpath+marker + '  =>  ' + newpath+marker,
361
                                              changes,
362
                                              newpath
363
                                            ])
364
                else:
365
                    self._file_store.append([ False,
366
                                              oldpath+marker + '  =>  ' + newpath+marker,
367
                                              changes,
368
                                              newpath
369
                                            ])
370
            else:
371
                self._file_store.append([ True,
372
                                          oldpath+marker + '  =>  ' + newpath+marker,
373
                                          changes,
374
                                          newpath
375
                                        ])
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
376
377
        for path, id, kind, text_modified, meta_modified in self.delta.modified:
378
            marker = osutils.kind_marker(kind)
126.1.10 by Szilveszter Farkas (Phanatic)
Allow to commit single files from the context menu (Fixed: #54983)
379
            if self.selected is not None:
380
                if path == os.path.join(self.wtpath, self.selected):
381
                    self._file_store.append([ True, path+marker, _('modified'), path ])
382
                else:
383
                    self._file_store.append([ False, path+marker, _('modified'), path ])
384
            else:
385
                self._file_store.append([ True, path+marker, _('modified'), path ])
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
386
    
387
    def _create_pending_merges(self):
388
        if not self.pending:
389
            return
390
        
391
        liststore = gtk.ListStore(gobject.TYPE_STRING,
392
                                  gobject.TYPE_STRING,
393
                                  gobject.TYPE_STRING)
394
        self._treeview_merges.set_model(liststore)
395
        
396
        self._treeview_merges.append_column(gtk.TreeViewColumn(_('Date'),
397
                                            gtk.CellRendererText(), text=0))
398
        self._treeview_merges.append_column(gtk.TreeViewColumn(_('Committer'),
399
                                            gtk.CellRendererText(), text=1))
400
        self._treeview_merges.append_column(gtk.TreeViewColumn(_('Summary'),
401
                                            gtk.CellRendererText(), text=2))
402
        
403
        for item in self.pending:
404
            liststore.append([ item['date'],
405
                               item['committer'],
406
                               item['summary'] ])
407
    
278.1.4 by John Arbash Meinel
Just playing around.
408
409
    def _create_diff_view(self):
410
        from diff import DiffDisplay
411
412
        self._diff_display = DiffDisplay()
413
        self._diff_display.set_trees(self.wt, self.wt.basis_tree())
414
        self._diff_display.show_diff(None)
415
        self._diff_display.show()
416
        self._hpane.pack2(self._diff_display)
417
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
418
    def _get_specific_files(self):
419
        ret = []
420
        it = self._file_store.get_iter_first()
421
        while it:
422
            if self._file_store.get_value(it, 0):
423
                # get real path from hidden column 3
424
                ret.append(self._file_store.get_value(it, 3))
425
            it = self._file_store.iter_next(it)
426
427
        return ret
428
    
429
    def _toggle_commit(self, cell, path, model):
430
        model[path][0] = not model[path][0]
431
        return