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

  • Committer: Jelmer Vernooij
  • Date: 2007-01-29 23:53:29 UTC
  • Revision ID: jelmer@samba.org-20070129235329-okuy0ap5pipcebd0
Throw out the old CommitDialog code and use the new code instead, also for 'gcommit'.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
from errors import show_bzr_error
33
33
from guifiles import GLADEFILENAME
34
34
 
35
 
 
36
 
class CommitDialog:
37
 
    """ Display Commit dialog and perform the needed actions. """
38
 
    def __init__(self, wt, wtpath, notbranch):
39
 
        """ Initialize the Commit dialog.
40
 
        :param  wt:         bzr working tree object
41
 
        :param  wtpath:     path to working tree root
42
 
        :param  notbranch:  flag that path is not a brach
43
 
        :type   notbranch:  bool
44
 
        """
45
 
        self.glade = gtk.glade.XML(GLADEFILENAME, 'window_commit', 'olive-gtk')
46
 
        
47
 
        self.wt = wt
48
 
        self.wtpath = wtpath
49
 
        self.notbranch = notbranch
50
 
 
51
 
        # Get some important widgets
52
 
        self.window = self.glade.get_widget('window_commit')
53
 
        self.checkbutton_local = self.glade.get_widget('checkbutton_commit_local')
54
 
        self.textview = self.glade.get_widget('textview_commit')
55
 
        self.file_expander = self.glade.get_widget('expander_commit_select')
56
 
        self.file_view = self.glade.get_widget('treeview_commit_select')
57
 
        self.pending_expander = self.glade.get_widget('expander_commit_pending')
58
 
        self.pending_label = self.glade.get_widget('label_commit_pending')
59
 
        self.pending_view = self.glade.get_widget('treeview_commit_pending')
60
 
 
61
 
        if wt is None or notbranch:
62
 
            return
63
 
        
64
 
        # Set the delta
65
 
        self.old_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
66
 
        self.delta = self.wt.changes_from(self.old_tree)
67
 
        
68
 
        # Get pending merges
69
 
        self.pending = self._pending_merges(self.wt)
70
 
        
71
 
        # Dictionary for signal_autoconnect
72
 
        dic = { "on_button_commit_commit_clicked": self.commit,
73
 
                "on_button_commit_cancel_clicked": self.close }
74
 
 
75
 
        # Connect the signals to the handlers
76
 
        self.glade.signal_autoconnect(dic)
77
 
        
78
 
        # Create the file list
79
 
        self._create_file_view()
80
 
        # Create the pending merges
81
 
        self._create_pending_merges()
82
 
    
83
 
    def display(self):
84
 
        """ Display the Push dialog.
85
 
        @return:    True if dialog is shown.
86
 
        """
87
 
        if self.wt is None and not self.notbranch:
88
 
            error_dialog(_('Directory does not have a working tree'),
89
 
                         _('Operation aborted.'))
90
 
            self.close()
91
 
            return False
92
 
        if self.notbranch:
93
 
            error_dialog(_('Directory is not a branch'),
94
 
                         _('You can perform this action only in a branch.'))
95
 
            self.close()
96
 
            return False
97
 
        else:
98
 
            if self.wt.branch.get_bound_location() is not None:
99
 
                # we have a checkout, so the local commit checkbox must appear
100
 
                self.checkbutton_local.show()
101
 
            
102
 
            if self.pending:
103
 
                # There are pending merges, file selection not supported
104
 
                self.file_expander.set_expanded(False)
105
 
                self.file_view.set_sensitive(False)
106
 
            else:
107
 
                # No pending merges
108
 
                self.pending_expander.hide()
109
 
            
110
 
            self.textview.modify_font(pango.FontDescription("Monospace"))
111
 
            self.window.show()
112
 
            return True
113
 
    
114
 
    def _create_file_view(self):
115
 
        self.file_store = gtk.ListStore(gobject.TYPE_BOOLEAN,   # [0] checkbox
116
 
                                        gobject.TYPE_STRING,    # [1] path to display
117
 
                                        gobject.TYPE_STRING,    # [2] changes type
118
 
                                        gobject.TYPE_STRING)    # [3] real path
119
 
        self.file_view.set_model(self.file_store)
120
 
        crt = gtk.CellRendererToggle()
121
 
        crt.set_property("activatable", True)
122
 
        crt.connect("toggled", self._toggle_commit, self.file_store)
123
 
        self.file_view.append_column(gtk.TreeViewColumn(_('Commit'),
124
 
                                     crt, active=0))
125
 
        self.file_view.append_column(gtk.TreeViewColumn(_('Path'),
126
 
                                     gtk.CellRendererText(), text=1))
127
 
        self.file_view.append_column(gtk.TreeViewColumn(_('Type'),
128
 
                                     gtk.CellRendererText(), text=2))
129
 
 
130
 
        for path, id, kind in self.delta.added:
131
 
            marker = osutils.kind_marker(kind)
132
 
            self.file_store.append([ True, path+marker, _('added'), path ])
133
 
 
134
 
        for path, id, kind in self.delta.removed:
135
 
            marker = osutils.kind_marker(kind)
136
 
            self.file_store.append([ True, path+marker, _('removed'), path ])
137
 
 
138
 
        for oldpath, newpath, id, kind, text_modified, meta_modified in self.delta.renamed:
139
 
            marker = osutils.kind_marker(kind)
140
 
            if text_modified or meta_modified:
141
 
                changes = _('renamed and modified')
142
 
            else:
143
 
                changes = _('renamed')
144
 
            self.file_store.append([ True,
145
 
                                     oldpath+marker + '  =>  ' + newpath+marker,
146
 
                                     changes,
147
 
                                     newpath
148
 
                                   ])
149
 
 
150
 
        for path, id, kind, text_modified, meta_modified in self.delta.modified:
151
 
            marker = osutils.kind_marker(kind)
152
 
            self.file_store.append([ True, path+marker, _('modified'), path ])
153
 
    
154
 
    def _create_pending_merges(self):
155
 
        if not self.pending:
156
 
            # hide unused pending merge part
157
 
            scrolled_window = self.glade.get_widget('scrolledwindow_commit_pending')
158
 
            parent = scrolled_window.get_parent()
159
 
            parent.remove(scrolled_window)
160
 
            parent = self.pending_label.get_parent()
161
 
            parent.remove(self.pending_label)
162
 
            return
163
 
        
164
 
        liststore = gtk.ListStore(gobject.TYPE_STRING,
165
 
                                  gobject.TYPE_STRING,
166
 
                                  gobject.TYPE_STRING)
167
 
        self.pending_view.set_model(liststore)
168
 
        
169
 
        self.pending_view.append_column(gtk.TreeViewColumn(_('Date'),
170
 
                                        gtk.CellRendererText(), text=0))
171
 
        self.pending_view.append_column(gtk.TreeViewColumn(_('Committer'),
172
 
                                        gtk.CellRendererText(), text=1))
173
 
        self.pending_view.append_column(gtk.TreeViewColumn(_('Summary'),
174
 
                                        gtk.CellRendererText(), text=2))
175
 
        
176
 
        for item in self.pending:
177
 
            liststore.append([ item['date'],
178
 
                               item['committer'],
179
 
                               item['summary'] ])
180
 
    
181
 
    def _get_specific_files(self):
182
 
        ret = []
183
 
        it = self.file_store.get_iter_first()
184
 
        while it:
185
 
            if self.file_store.get_value(it, 0):
186
 
                # get real path from hidden column 3
187
 
                ret.append(self.file_store.get_value(it, 3))
188
 
            it = self.file_store.iter_next(it)
189
 
 
190
 
        return ret
191
 
    
192
 
    def _toggle_commit(self, cell, path, model):
193
 
        model[path][0] = not model[path][0]
194
 
        return
195
 
    
196
 
    def _pending_merges(self, wt):
197
 
        """ Return a list of pending merges or None if there are none of them. """
198
 
        parents = wt.get_parent_ids()
199
 
        if len(parents) < 2:
200
 
            return None
201
 
        
202
 
        import re
203
 
        from bzrlib.osutils import format_date
204
 
        
205
 
        pending = parents[1:]
206
 
        branch = wt.branch
207
 
        last_revision = parents[0]
208
 
        
209
 
        if last_revision is not None:
210
 
            try:
211
 
                ignore = set(branch.repository.get_ancestry(last_revision))
212
 
            except errors.NoSuchRevision:
213
 
                # the last revision is a ghost : assume everything is new 
214
 
                # except for it
215
 
                ignore = set([None, last_revision])
216
 
        else:
217
 
            ignore = set([None])
218
 
        
219
 
        pm = []
220
 
        for merge in pending:
221
 
            ignore.add(merge)
222
 
            try:
223
 
                m_revision = branch.repository.get_revision(merge)
224
 
                
225
 
                rev = {}
226
 
                rev['committer'] = re.sub('<.*@.*>', '', m_revision.committer).strip(' ')
227
 
                rev['summary'] = m_revision.get_summary()
228
 
                rev['date'] = format_date(m_revision.timestamp,
229
 
                                          m_revision.timezone or 0, 
230
 
                                          'original', date_fmt="%Y-%m-%d",
231
 
                                          show_offset=False)
232
 
                
233
 
                pm.append(rev)
234
 
                
235
 
                inner_merges = branch.repository.get_ancestry(merge)
236
 
                assert inner_merges[0] is None
237
 
                inner_merges.pop(0)
238
 
                inner_merges.reverse()
239
 
                for mmerge in inner_merges:
240
 
                    if mmerge in ignore:
241
 
                        continue
242
 
                    mm_revision = branch.repository.get_revision(mmerge)
243
 
                    
244
 
                    rev = {}
245
 
                    rev['committer'] = re.sub('<.*@.*>', '', mm_revision.committer).strip(' ')
246
 
                    rev['summary'] = mm_revision.get_summary()
247
 
                    rev['date'] = format_date(mm_revision.timestamp,
248
 
                                              mm_revision.timezone or 0, 
249
 
                                              'original', date_fmt="%Y-%m-%d",
250
 
                                              show_offset=False)
251
 
                
252
 
                    pm.append(rev)
253
 
                    
254
 
                    ignore.add(mmerge)
255
 
            except errors.NoSuchRevision:
256
 
                print "DEBUG: NoSuchRevision:", merge
257
 
        
258
 
        return pm
259
 
 
260
 
    def commit(self, widget):
261
 
        textbuffer = self.textview.get_buffer()
262
 
        start, end = textbuffer.get_bounds()
263
 
        message = textbuffer.get_text(start, end).decode('utf-8')
264
 
        
265
 
        checkbutton_strict = self.glade.get_widget('checkbutton_commit_strict')
266
 
        checkbutton_force = self.glade.get_widget('checkbutton_commit_force')
267
 
        
268
 
        if not self.pending:
269
 
            specific_files = self._get_specific_files()
270
 
        else:
271
 
            specific_files = None
272
 
 
273
 
        if message == '':
274
 
            response = question_dialog('Commit with an empty message ?',
275
 
                                       'You can describe your commit intent'
276
 
                                       +' in the message')
277
 
            if response == gtk.RESPONSE_NO:
278
 
                # Kindly give focus to message area
279
 
                self.textview.grab_focus()
280
 
                return
281
 
 
282
 
        try:
283
 
            self.wt.commit(message,
284
 
                           allow_pointless=checkbutton_force.get_active(),
285
 
                           strict=checkbutton_strict.get_active(),
286
 
                           local=self.checkbutton_local.get_active(),
287
 
                           specific_files=specific_files)
288
 
        except errors.NotBranchError:
289
 
            error_dialog(_('Directory is not a branch'),
290
 
                         _('You can perform this action only in a branch.'))
291
 
            return
292
 
        except errors.LocalRequiresBoundBranch:
293
 
            error_dialog(_('Directory is not a checkout'),
294
 
                         _('You can perform local commit only on checkouts.'))
295
 
            return
296
 
        except errors.PointlessCommit:
297
 
            error_dialog(_('No changes to commit'),
298
 
                         _('Try force commit if you want to commit anyway.'))
299
 
            return
300
 
        except errors.ConflictsInTree:
301
 
            error_dialog(_('Conflicts in tree'),
302
 
                         _('You need to resolve the conflicts before committing.'))
303
 
            return
304
 
        except errors.StrictCommitFailed:
305
 
            error_dialog(_('Strict commit failed'),
306
 
                         _('There are unknown files in the working tree.\nPlease add or delete them.'))
307
 
            return
308
 
        except errors.BoundBranchOutOfDate, errmsg:
309
 
            error_dialog(_('Bound branch is out of date'),
310
 
                         _('%s') % errmsg)
311
 
            return
312
 
        except errors.BzrError, msg:
313
 
            error_dialog(_('Unknown bzr error'), str(msg))
314
 
            return
315
 
        except Exception, msg:
316
 
            error_dialog(_('Unknown error'), str(msg))
317
 
            return
318
 
 
319
 
        self.close()
320
 
 
321
 
    def close(self, widget=None):
322
 
        self.window.destroy()
323
 
 
324
 
class CommitDialogNew(gtk.Dialog):
 
35
class CommitDialog(gtk.Dialog):
325
36
    """ New implementation of the Commit dialog. """
326
37
    def __init__(self, wt, wtpath, notbranch, selected=None, parent=None):
327
38
        """ Initialize the Commit Dialog. """