/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
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
28
import re
126.1.10 by Szilveszter Farkas (Phanatic)
Allow to commit single files from the context menu (Fixed: #54983)
29
248 by Jelmer Vernooij
Merge fixes for #127392 and #127381)
30
from bzrlib import errors, osutils
235.1.5 by Mateusz Korniak
Missing mutter import added.
31
from bzrlib.trace import mutter
0.8.20 by Szilveszter Farkas (Phanatic)
2006-07-24 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
32
153 by Jelmer Vernooij
Fix references to dialog.
33
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.
34
from errors import show_bzr_error
93.1.6 by Alexander Belchenko
detecting name of glade file doing in separate module (olive.gladefile)
35
158 by Jelmer Vernooij
If available, use NetworkManager to find out whether a commit should be local or not.
36
try:
37
    import dbus
38
    import dbus.glib
180 by Jelmer Vernooij
Don't obtain handle to network manager until it's actually needed.
39
    have_dbus = True
158 by Jelmer Vernooij
If available, use NetworkManager to find out whether a commit should be local or not.
40
except ImportError:
180 by Jelmer Vernooij
Don't obtain handle to network manager until it's actually needed.
41
    have_dbus = False
158 by Jelmer Vernooij
If available, use NetworkManager to find out whether a commit should be local or not.
42
278.1.4 by John Arbash Meinel
Just playing around.
43
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
44
def pending_revisions(wt):
45
    """Return a list of pending merges or None if there are none of them.
46
47
    Arguably this should be a core function, and
48
    ``bzrlib.status.show_pending_merges`` should be built on top of it.
49
50
    :return: [(rev, [children])]
51
    """
52
    parents = wt.get_parent_ids()
53
    if len(parents) < 2:
54
        return None
55
56
    # The basic pending merge algorithm uses the same algorithm as
57
    # bzrlib.status.show_pending_merges
58
    pending = parents[1:]
59
    branch = wt.branch
60
    last_revision = parents[0]
61
62
    if last_revision is not None:
63
        try:
64
            ignore = set(branch.repository.get_ancestry(last_revision,
65
                                                        topo_sorted=False))
66
        except errors.NoSuchRevision:
67
            # the last revision is a ghost : assume everything is new
68
            # except for it
69
            ignore = set([None, last_revision])
70
    else:
71
        ignore = set([None])
72
73
    pm = []
74
    for merge in pending:
75
        ignore.add(merge)
76
        try:
77
            rev = branch.repository.get_revision(merge)
78
            children = []
79
            pm.append((rev, children))
80
81
            # This does need to be topo sorted, so we search backwards
82
            inner_merges = branch.repository.get_ancestry(merge)
83
            assert inner_merges[0] is None
84
            inner_merges.pop(0)
85
            for mmerge in reversed(inner_merges):
86
                if mmerge in ignore:
87
                    continue
88
                rev = branch.repository.get_revision(mmerge)
89
                children.append(rev)
90
91
                ignore.add(mmerge)
92
        except errors.NoSuchRevision:
93
            print "DEBUG: NoSuchRevision:", merge
94
95
    return pm
96
97
135 by Jelmer Vernooij
Throw out the old CommitDialog code and use the new code instead, also for 'gcommit'.
98
class CommitDialog(gtk.Dialog):
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
99
    """Implementation of Commit."""
100
101
    def __init__(self, wt, selected=None, parent=None):
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
102
        gtk.Dialog.__init__(self, title="Commit - Olive",
103
                                  parent=parent,
104
                                  flags=0,
105
                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
278.1.24 by John Arbash Meinel
Actually show the commit button.
106
        self._question_dialog = question_dialog
107
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
108
        self._wt = wt
109
        self._selected = selected
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
110
        self.committed_revision_id = None # Nothing has been committed yet
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
111
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
112
        self.setup_params()
113
        self.construct()
114
        self.fill_in_data()
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
115
116
    def setup_params(self):
117
        """Setup the member variables for state."""
118
        self._basis_tree = self._wt.basis_tree()
278.1.12 by John Arbash Meinel
Delay computing the delta, and clean up some of the diff view names.
119
        self._delta = None
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
120
        self._pending = pending_revisions(self._wt)
121
122
        self._is_checkout = (self._wt.branch.get_bound_location() is not None)
123
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
124
    def fill_in_data(self):
125
        # Now that we are built, handle changes to the view based on the state
126
        self._fill_in_pending()
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
127
        self._fill_in_diff()
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
128
        self._fill_in_files()
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
129
130
    def _fill_in_pending(self):
131
        if not self._pending:
132
            self._pending_box.hide()
133
            return
134
135
        # TODO: We'd really prefer this to be a nested list
136
        for rev, children in self._pending:
137
            rev_info = self._rev_to_pending_info(rev)
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
138
            self._pending_store.append([
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
139
                rev_info['revision_id'],
140
                rev_info['date'],
141
                rev_info['committer'],
142
                rev_info['summary'],
143
                ])
144
            for child in children:
145
                rev_info = self._rev_to_pending_info(child)
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
146
                self._pending_store.append([
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
147
                    rev_info['revision_id'],
148
                    rev_info['date'],
149
                    rev_info['committer'],
150
                    rev_info['summary'],
151
                    ])
152
        self._pending_box.show()
153
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
154
    def _fill_in_files(self):
155
        # We should really use _iter_changes, and then add a progress bar of
156
        # some kind.
157
        # While we fill in the view, hide the store
158
        store = self._files_store
159
        self._treeview_files.set_model(None)
160
161
        added = _('added')
162
        removed = _('removed')
163
        renamed = _('renamed')
164
        renamed_and_modified = _('renamed and modified')
165
        modified = _('modified')
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
166
        kind_changed = _('kind changed')
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
167
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
168
        # The store holds:
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
169
        # [file_id, real path, checkbox, display path, changes type, message]
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
170
        # _iter_changes returns:
171
        # (file_id, (path_in_source, path_in_target),
172
        #  changed_content, versioned, parent, name, kind,
173
        #  executable)
174
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
175
        # The first entry is always the 'whole tree'
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
176
        store.append([None, None, True, 'All Files', '', ''])
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
177
        # should we pass specific_files?
178
        self._wt.lock_read()
179
        self._basis_tree.lock_read()
180
        try:
181
            for (file_id, paths, changed_content, versioned, parent_ids, names,
182
                 kinds, executables) in self._wt._iter_changes(self._basis_tree):
183
184
                # Skip the root entry.
185
                if parent_ids == (None, None):
186
                    continue
187
188
                change_type = None
189
                if kinds[0] is None:
190
                    source_marker = ''
191
                else:
192
                    source_marker = osutils.kind_marker(kinds[0])
193
                if kinds[1] is None:
194
                    assert kinds[0] is not None
195
                    marker = osutils.kind_marker(kinds[0])
196
                else:
197
                    marker = osutils.kind_marker(kinds[1])
198
199
                real_path = paths[1]
200
                if real_path is None:
201
                    real_path = paths[0]
202
                assert real_path is not None
203
                display_path = real_path + marker
204
205
                present_source = versioned[0] and kinds[0] is not None
206
                present_target = versioned[1] and kinds[1] is not None
207
208
                if present_source != present_target:
209
                    if present_target:
210
                        change_type = added
211
                    else:
212
                        change_type = removed
213
                elif names[0] != names[1] or parent_ids[0] != parent_ids[1]:
214
                    # Renamed
215
                    if changed_content or executables[0] != executables[1]:
216
                        # and modified
217
                        change_type = renamed_and_modified
218
                    else:
219
                        change_type = renamed
220
                    display_path = (paths[0] + source_marker
221
                                    + ' => ' + paths[1] + marker)
222
                elif kinds[0] != kinds[1]:
223
                    change_type = kind_changed
224
                    display_path = (paths[0] + source_marker
225
                                    + ' => ' + paths[1] + marker)
226
                elif changed_content is True or executables[0] != executables[1]:
227
                    change_type = modified
228
                else:
229
                    assert False, "How did we get here?"
230
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
231
                store.append([file_id, real_path, True, display_path,
232
                              change_type, ''])
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
233
        finally:
234
            self._basis_tree.unlock()
235
            self._wt.unlock()
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
236
237
        self._treeview_files.set_model(store)
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
238
        self._last_selected_file = None
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
239
        self._treeview_files.set_cursor(0)
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
240
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
241
    def _fill_in_diff(self):
242
        self._diff_view.set_trees(self._wt, self._basis_tree)
243
278.1.12 by John Arbash Meinel
Delay computing the delta, and clean up some of the diff view names.
244
    def _compute_delta(self):
245
        self._delta = self._wt.changes_from(self._basis_tree)
246
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
247
    def construct(self):
248
        """Build up the dialog widgets."""
249
        # The primary pane which splits it into left and right (adjustable)
250
        # sections.
278.1.4 by John Arbash Meinel
Just playing around.
251
        self._hpane = gtk.HPaned()
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
252
253
        self._construct_left_pane()
254
        self._construct_right_pane()
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
255
        self._construct_action_pane()
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
256
257
        self.vbox.pack_start(self._hpane)
258
        self._hpane.show()
259
        self.set_focus(self._global_message_text_view)
260
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
261
        # This seems like a reasonable default, we might like it to
262
        # be a bit wider, so that by default we can fit an 80-line diff in the
263
        # diff window.
264
        # Alternatively, we should be saving the last position/size rather than
265
        # setting it to a fixed value every time we start up.
266
        screen = self.get_screen()
267
        monitor = 0 # We would like it to be the monitor we are going to
268
                    # display on, but I don't know how to figure that out
269
                    # Only really useful for freaks like me that run dual
270
                    # monitor, with different sizes on the monitors
271
        monitor_rect = screen.get_monitor_geometry(monitor)
272
        width = int(monitor_rect.width * 0.66)
273
        height = int(monitor_rect.height * 0.66)
274
        self.set_default_size(width, height)
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
275
        self._hpane.set_position(300)
276
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
277
    def _construct_left_pane(self):
278.1.11 by John Arbash Meinel
Worked out the rest of the spacing.
278
        self._left_pane_box = gtk.VBox(homogeneous=False, spacing=5)
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
279
        self._construct_file_list()
280
        self._construct_pending_list()
281
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
282
        self._hpane.pack1(self._left_pane_box, resize=False, shrink=False)
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
283
        self._left_pane_box.show()
284
285
    def _construct_right_pane(self):
286
        # TODO: I really want to make it so the diff view gets more space than
287
        # the global commit message, and the per-file commit message gets even
288
        # less. When I did it with wxGlade, I set it to 4 for diff, 2 for
289
        # commit, and 1 for file commit, and it looked good. But I don't seem
290
        # to have a way to do that with the gtk boxes... :( (Which is extra
291
        # weird since wx uses gtk on Linux...)
278.1.10 by John Arbash Meinel
To get the space weighting I wanted, I turned to a Table.
292
        self._right_pane_table = gtk.Table(rows=10, columns=1, homogeneous=False)
278.1.11 by John Arbash Meinel
Worked out the rest of the spacing.
293
        self._right_pane_table.set_row_spacings(5)
294
        self._right_pane_table.set_col_spacings(5)
278.1.10 by John Arbash Meinel
To get the space weighting I wanted, I turned to a Table.
295
        self._right_pane_table_row = 0
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
296
        self._construct_diff_view()
297
        self._construct_file_message()
298
        self._construct_global_message()
299
278.1.10 by John Arbash Meinel
To get the space weighting I wanted, I turned to a Table.
300
        self._right_pane_table.show()
301
        self._hpane.pack2(self._right_pane_table, resize=True, shrink=True)
302
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
303
    def _construct_action_pane(self):
304
        self._button_commit = gtk.Button(_("Comm_it"), use_underline=True)
305
        self._button_commit.connect('clicked', self._on_commit_clicked)
306
        self._button_commit.set_flags(gtk.CAN_DEFAULT)
278.1.24 by John Arbash Meinel
Actually show the commit button.
307
        self._button_commit.show()
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
308
        self.action_area.pack_end(self._button_commit)
278.1.24 by John Arbash Meinel
Actually show the commit button.
309
        self._button_commit.grab_default()
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
310
278.1.10 by John Arbash Meinel
To get the space weighting I wanted, I turned to a Table.
311
    def _add_to_right_table(self, widget, weight, expanding=False):
312
        """Add another widget to the table
313
314
        :param widget: The object to add
315
        :param weight: How many rows does this widget get to request
316
        :param expanding: Should expand|fill|shrink be set?
317
        """
318
        end_row = self._right_pane_table_row + weight
319
        options = 0
320
        expand_opts = gtk.EXPAND | gtk.FILL | gtk.SHRINK
321
        if expanding:
322
            options = expand_opts
323
        self._right_pane_table.attach(widget, 0, 1,
324
                                      self._right_pane_table_row, end_row,
325
                                      xoptions=expand_opts, yoptions=options)
326
        self._right_pane_table_row = end_row
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
327
328
    def _construct_file_list(self):
278.1.11 by John Arbash Meinel
Worked out the rest of the spacing.
329
        self._files_box = gtk.VBox(homogeneous=False, spacing=0)
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
330
        file_label = gtk.Label(_('Files'))
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
331
        file_label.show()
332
        self._files_box.pack_start(file_label, expand=False)
333
334
        scroller = gtk.ScrolledWindow()
335
        scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
336
        self._treeview_files = gtk.TreeView()
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
337
        self._treeview_files.show()
338
        scroller.add(self._treeview_files)
339
        scroller.show()
340
        scroller.set_shadow_type(gtk.SHADOW_IN)
341
        self._files_box.pack_start(scroller,
342
                                   expand=True, fill=True)
343
        self._files_box.show()
344
        self._left_pane_box.pack_start(self._files_box)
345
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
346
        liststore = gtk.ListStore(
347
            gobject.TYPE_STRING,  # [0] file_id
348
            gobject.TYPE_STRING,  # [1] real path
349
            gobject.TYPE_BOOLEAN, # [2] checkbox
350
            gobject.TYPE_STRING,  # [3] display path
351
            gobject.TYPE_STRING,  # [4] changes type
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
352
            gobject.TYPE_STRING,  # [5] commit message
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
353
            )
354
        self._files_store = liststore
355
        self._treeview_files.set_model(liststore)
356
        crt = gtk.CellRendererToggle()
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
357
        crt.set_active(not bool(self._pending))
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
358
        crt.connect("toggled", self._toggle_commit, self._files_store)
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
359
        if self._pending:
360
            name = _('Commit*')
361
        else:
362
            name = _('Commit')
363
        self._treeview_files.append_column(gtk.TreeViewColumn(name,
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
364
                                           crt, active=2))
365
        self._treeview_files.append_column(gtk.TreeViewColumn(_('Path'),
366
                                           gtk.CellRendererText(), text=3))
367
        self._treeview_files.append_column(gtk.TreeViewColumn(_('Type'),
368
                                           gtk.CellRendererText(), text=4))
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
369
        self._treeview_files.connect('cursor-changed',
370
                                     self._on_treeview_files_cursor_changed)
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
371
372
    def _toggle_commit(self, cell, path, model):
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
373
        if model[path][0] is None: # No file_id means 'All Files'
374
            new_val = not model[path][2]
375
            for node in model:
376
                node[2] = new_val
377
        else:
378
            model[path][2] = not model[path][2]
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
379
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
380
    def _construct_pending_list(self):
381
        # Pending information defaults to hidden, we put it all in 1 box, so
382
        # that we can show/hide all of them at once
383
        self._pending_box = gtk.VBox()
384
        self._pending_box.hide()
385
386
        pending_message = gtk.Label()
387
        pending_message.set_markup(
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
388
            _('<i>* Cannot select specific files when merging</i>'))
278.1.11 by John Arbash Meinel
Worked out the rest of the spacing.
389
        self._pending_box.pack_start(pending_message, expand=False, padding=5)
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
390
        pending_message.show()
391
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
392
        pending_label = gtk.Label(_('Pending Revisions'))
278.1.11 by John Arbash Meinel
Worked out the rest of the spacing.
393
        self._pending_box.pack_start(pending_label, expand=False, padding=0)
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
394
        pending_label.show()
395
396
        scroller = gtk.ScrolledWindow()
397
        scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
398
        self._treeview_pending = gtk.TreeView()
399
        scroller.add(self._treeview_pending)
400
        scroller.show()
401
        scroller.set_shadow_type(gtk.SHADOW_IN)
402
        self._pending_box.pack_start(scroller,
278.1.11 by John Arbash Meinel
Worked out the rest of the spacing.
403
                                     expand=True, fill=True, padding=5)
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
404
        self._treeview_pending.show()
405
        self._left_pane_box.pack_start(self._pending_box)
406
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
407
        liststore = gtk.ListStore(gobject.TYPE_STRING, # revision_id
408
                                  gobject.TYPE_STRING, # date
409
                                  gobject.TYPE_STRING, # committer
410
                                  gobject.TYPE_STRING, # summary
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
411
                                 )
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
412
        self._pending_store = liststore
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
413
        self._treeview_pending.set_model(liststore)
414
        self._treeview_pending.append_column(gtk.TreeViewColumn(_('Date'),
415
                                             gtk.CellRendererText(), text=1))
416
        self._treeview_pending.append_column(gtk.TreeViewColumn(_('Committer'),
417
                                             gtk.CellRendererText(), text=2))
418
        self._treeview_pending.append_column(gtk.TreeViewColumn(_('Summary'),
419
                                             gtk.CellRendererText(), text=3))
420
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
421
    def _construct_diff_view(self):
278.1.12 by John Arbash Meinel
Delay computing the delta, and clean up some of the diff view names.
422
        from diff import DiffView
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
423
424
        self._diff_label = gtk.Label(_('Diff for whole tree'))
278.1.11 by John Arbash Meinel
Worked out the rest of the spacing.
425
        self._diff_label.set_alignment(0, 0)
426
        self._right_pane_table.set_row_spacing(self._right_pane_table_row, 0)
278.1.10 by John Arbash Meinel
To get the space weighting I wanted, I turned to a Table.
427
        self._add_to_right_table(self._diff_label, 1, False)
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
428
        self._diff_label.show()
429
278.1.12 by John Arbash Meinel
Delay computing the delta, and clean up some of the diff view names.
430
        self._diff_view = DiffView()
278.1.10 by John Arbash Meinel
To get the space weighting I wanted, I turned to a Table.
431
        self._add_to_right_table(self._diff_view, 4, True)
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
432
        self._diff_view.show()
433
434
    def _construct_file_message(self):
435
        file_message_box = gtk.VBox()
278.1.9 by John Arbash Meinel
Move all text entry boxes into a ScrolledWindow, so that they don't change size constantly.
436
        scroller = gtk.ScrolledWindow()
437
        scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
438
439
        self._file_message_text_view = gtk.TextView()
440
        scroller.add(self._file_message_text_view)
441
        scroller.show()
442
        scroller.set_shadow_type(gtk.SHADOW_IN)
443
        file_message_box.pack_start(scroller, expand=True, fill=True)
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
444
445
        self._file_message_text_view.modify_font(pango.FontDescription("Monospace"))
446
        self._file_message_text_view.set_wrap_mode(gtk.WRAP_WORD)
447
        self._file_message_text_view.set_accepts_tab(False)
448
        self._file_message_text_view.show()
449
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
450
        self._file_message_expander = gtk.Expander(_('File commit message'))
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
451
        self._file_message_expander.add(file_message_box)
452
        file_message_box.show()
278.1.10 by John Arbash Meinel
To get the space weighting I wanted, I turned to a Table.
453
        self._add_to_right_table(self._file_message_expander, 1, False)
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
454
        self._file_message_expander.show()
455
456
    def _construct_global_message(self):
457
        self._global_message_label = gtk.Label(_('Global Commit Message'))
278.1.11 by John Arbash Meinel
Worked out the rest of the spacing.
458
        self._global_message_label.set_alignment(0, 0)
459
        self._right_pane_table.set_row_spacing(self._right_pane_table_row, 0)
278.1.10 by John Arbash Meinel
To get the space weighting I wanted, I turned to a Table.
460
        self._add_to_right_table(self._global_message_label, 1, False)
278.1.11 by John Arbash Meinel
Worked out the rest of the spacing.
461
        # Can we remove the spacing between the label and the box?
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
462
        self._global_message_label.show()
463
278.1.9 by John Arbash Meinel
Move all text entry boxes into a ScrolledWindow, so that they don't change size constantly.
464
        scroller = gtk.ScrolledWindow()
465
        scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
466
467
        self._global_message_text_view = gtk.TextView()
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
468
        self._global_message_text_view.modify_font(pango.FontDescription("Monospace"))
278.1.9 by John Arbash Meinel
Move all text entry boxes into a ScrolledWindow, so that they don't change size constantly.
469
        scroller.add(self._global_message_text_view)
470
        scroller.show()
471
        scroller.set_shadow_type(gtk.SHADOW_IN)
278.1.10 by John Arbash Meinel
To get the space weighting I wanted, I turned to a Table.
472
        self._add_to_right_table(scroller, 2, True)
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
473
        self._file_message_text_view.set_wrap_mode(gtk.WRAP_WORD)
474
        self._file_message_text_view.set_accepts_tab(False)
475
        self._global_message_text_view.show()
476
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
477
    def _on_treeview_files_cursor_changed(self, treeview):
278.1.18 by John Arbash Meinel
Start checking the diff view is correct.
478
        treeselection = treeview.get_selection()
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
479
        (model, selection) = treeselection.get_selected()
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
480
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
481
        if selection is not None:
482
            path, display_path = model.get(selection, 1, 3)
278.1.18 by John Arbash Meinel
Start checking the diff view is correct.
483
            self._diff_label.set_text(_('Diff for ') + display_path)
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
484
            if path is None:
485
                self._diff_view.show_diff(None)
486
            else:
487
                self._diff_view.show_diff([path])
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
488
            self._update_per_file_info(selection)
489
490
    def _save_current_file_message(self):
491
        if self._last_selected_file is None:
492
            return # Nothing to save
493
        text_buffer = self._file_message_text_view.get_buffer()
494
        cur_text = text_buffer.get_text(text_buffer.get_start_iter(),
495
                                        text_buffer.get_end_iter())
496
        last_selected = self._files_store.get_iter(self._last_selected_file)
497
        self._files_store.set_value(last_selected, 5, cur_text)
498
499
    def _update_per_file_info(self, selection):
500
        # The node is changing, so cache the current message
501
        self._save_current_file_message()
502
        text_buffer = self._file_message_text_view.get_buffer()
503
        file_id, display_path, message = self._files_store.get(selection, 0, 3, 5)
504
        if file_id is None: # Whole tree
505
            self._file_message_expander.set_label(_('File commit message'))
506
            self._file_message_expander.set_expanded(False)
507
            self._file_message_expander.set_sensitive(False)
508
            text_buffer.set_text('')
509
            self._last_selected_file = None
510
        else:
511
            self._file_message_expander.set_label(_('Commit message for ')
512
                                                  + display_path)
513
            self._file_message_expander.set_expanded(True)
514
            self._file_message_expander.set_sensitive(True)
515
            text_buffer.set_text(message)
516
            self._last_selected_file = self._files_store.get_path(selection)
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
517
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
518
    @show_bzr_error
519
    def _on_commit_clicked(self, button):
520
        """ Commit button clicked handler. """
521
        self._do_commit()
522
523
    def _do_commit(self):
524
        buf = self._global_message_text_view.get_buffer()
525
        start, end = buf.get_bounds()
526
        message = buf.get_text(start, end).decode('utf-8')
527
528
        if message == '':
529
            response = self._question_dialog(
530
                            _('Commit with an empty message?'),
531
                            _('You can describe your commit intent in the message.'))
532
            if response == gtk.RESPONSE_NO:
533
                # Kindly give focus to message area
534
                self._global_message_text_view.grab_focus()
535
                return
536
537
        # if not self.pending:
538
        #     specific_files = self._get_specific_files()
539
        # else:
540
        #     specific_files = None
541
542
        # if self._is_checkout:
543
        #     local = self._check_local.get_active()
544
        # else:
545
        #     local = False
546
547
        # if list(self._wt.unknowns()) != []:
548
        #     response = question_dialog(_("Commit with unknowns?"),
549
        #        _("Unknown files exist in the working tree. Commit anyway?"))
550
        #     if response == gtk.RESPONSE_NO:
551
        #         return
552
553
        local = False
554
        specific_files = None
555
        try:
556
            rev_id = self._wt.commit(message,
557
                       allow_pointless=False,
558
                       strict=False,
559
                       local=local,
560
                       specific_files=specific_files)
561
        except errors.PointlessCommit:
562
            response = question_dialog(_('Commit with no changes?'),
563
                                       _('There are no changes in the working tree.'))
564
            if response == gtk.RESPONSE_YES:
565
                rev_id = self._wt.commit(message,
566
                               allow_pointless=True,
567
                               strict=False,
568
                               local=local,
569
                               specific_files=specific_files)
570
        self.committed_revision_id = rev_id
571
        self.response(gtk.RESPONSE_OK)
572
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
573
    @staticmethod
574
    def _rev_to_pending_info(rev):
575
        """Get the information from a pending merge."""
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
576
        from bzrlib.osutils import format_date
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
577
578
        rev_dict = {}
579
        rev_dict['committer'] = re.sub('<.*@.*>', '', rev.committer).strip(' ')
580
        rev_dict['summary'] = rev.get_summary()
581
        rev_dict['date'] = format_date(rev.timestamp,
582
                                       rev.timezone or 0,
583
                                       'original', date_fmt="%Y-%m-%d",
584
                                       show_offset=False)
585
        rev_dict['revision_id'] = rev.revision_id
586
        return rev_dict
587
588
589
# class CommitDialog(gtk.Dialog):
590
#     """ New implementation of the Commit dialog. """
591
#     def __init__(self, wt, wtpath, notbranch, selected=None, parent=None):
592
#         """ Initialize the Commit Dialog. """
593
#         gtk.Dialog.__init__(self, title="Commit - Olive",
594
#                                   parent=parent,
595
#                                   flags=0,
596
#                                   buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
597
#         
598
#         # Get arguments
599
#         self.wt = wt
600
#         self.wtpath = wtpath
601
#         self.notbranch = notbranch
602
#         self.selected = selected
603
#         
604
#         # Set the delta
605
#         self.old_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
606
#         self.delta = self.wt.changes_from(self.old_tree)
607
#         
608
#         # Get pending merges
609
#         self.pending = self._pending_merges(self.wt)
610
#         
611
#         # Do some preliminary checks
612
#         self._is_checkout = False
613
#         self._is_pending = False
614
#         if self.wt is None and not self.notbranch:
615
#             error_dialog(_('Directory does not have a working tree'),
616
#                          _('Operation aborted.'))
617
#             self.close()
618
#             return
619
# 
620
#         if self.notbranch:
621
#             error_dialog(_('Directory is not a branch'),
622
#                          _('You can perform this action only in a branch.'))
623
#             self.close()
624
#             return
625
#         else:
626
#             if self.wt.branch.get_bound_location() is not None:
627
#                 # we have a checkout, so the local commit checkbox must appear
628
#                 self._is_checkout = True
629
#             
630
#             if self.pending:
631
#                 # There are pending merges, file selection not supported
632
#                 self._is_pending = True
633
#         
634
#         # Create the widgets
635
#         # This is the main horizontal box, which is used to separate the commit
636
#         # info from the diff window.
637
#         self._hpane = gtk.HPaned()
638
#         self._button_commit = gtk.Button(_("Comm_it"), use_underline=True)
639
#         self._expander_files = gtk.Expander(_("File(s) to commit"))
640
#         self._vpaned_main = gtk.VPaned()
641
#         self._scrolledwindow_files = gtk.ScrolledWindow()
642
#         self._scrolledwindow_message = gtk.ScrolledWindow()
643
#         self._treeview_files = gtk.TreeView()
644
#         self._vbox_message = gtk.VBox()
645
#         self._label_message = gtk.Label(_("Commit message:"))
646
#         self._textview_message = gtk.TextView()
647
#         
648
#         if self._is_pending:
649
#             self._expander_merges = gtk.Expander(_("Pending merges"))
650
#             self._vpaned_list = gtk.VPaned()
651
#             self._scrolledwindow_merges = gtk.ScrolledWindow()
652
#             self._treeview_merges = gtk.TreeView()
653
# 
654
#         # Set callbacks
655
#         self._button_commit.connect('clicked', self._on_commit_clicked)
656
#         self._treeview_files.connect('cursor-changed', self._on_treeview_files_cursor_changed)
657
#         self._treeview_files.connect('row-activated', self._on_treeview_files_row_activated)
658
#         
659
#         # Set properties
660
#         self._scrolledwindow_files.set_policy(gtk.POLICY_AUTOMATIC,
661
#                                               gtk.POLICY_AUTOMATIC)
662
#         self._scrolledwindow_message.set_policy(gtk.POLICY_AUTOMATIC,
663
#                                                 gtk.POLICY_AUTOMATIC)
664
#         self._textview_message.modify_font(pango.FontDescription("Monospace"))
665
#         self.set_default_size(500, 500)
666
#         self._vpaned_main.set_position(200)
667
#         self._button_commit.set_flags(gtk.CAN_DEFAULT)
668
# 
669
#         if self._is_pending:
670
#             self._scrolledwindow_merges.set_policy(gtk.POLICY_AUTOMATIC,
671
#                                                    gtk.POLICY_AUTOMATIC)
672
#             self._treeview_files.set_sensitive(False)
673
#         
674
#         # Construct the dialog
675
#         self.action_area.pack_end(self._button_commit)
676
#         
677
#         self._scrolledwindow_files.add(self._treeview_files)
678
#         self._scrolledwindow_message.add(self._textview_message)
679
#         
680
#         self._expander_files.add(self._scrolledwindow_files)
681
#         
682
#         self._vbox_message.pack_start(self._label_message, False, False)
683
#         self._vbox_message.pack_start(self._scrolledwindow_message, True, True)
684
#         
685
#         if self._is_pending:        
686
#             self._expander_merges.add(self._scrolledwindow_merges)
687
#             self._scrolledwindow_merges.add(self._treeview_merges)
688
#             self._vpaned_list.add1(self._expander_files)
689
#             self._vpaned_list.add2(self._expander_merges)
690
#             self._vpaned_main.add1(self._vpaned_list)
691
#         else:
692
#             self._vpaned_main.add1(self._expander_files)
693
# 
694
#         self._vpaned_main.add2(self._vbox_message)
695
#         
696
#         self._hpane.pack1(self._vpaned_main)
697
#         self.vbox.pack_start(self._hpane, expand=True, fill=True)
698
#         if self._is_checkout: 
699
#             self._check_local = gtk.CheckButton(_("_Only commit locally"),
700
#                                                 use_underline=True)
701
#             self.vbox.pack_start(self._check_local, False, False)
702
#             if have_dbus:
703
#                 bus = dbus.SystemBus()
704
#                 proxy_obj = bus.get_object('org.freedesktop.NetworkManager', 
705
#                               '/org/freedesktop/NetworkManager')
706
#                 dbus_iface = dbus.Interface(
707
#                         proxy_obj, 'org.freedesktop.NetworkManager')
708
#                 try:
709
#                     # 3 is the enum value for STATE_CONNECTED
710
#                     self._check_local.set_active(dbus_iface.state() != 3)
711
#                 except dbus.DBusException, e:
712
#                     # Silently drop errors. While DBus may be 
713
#                     # available, NetworkManager doesn't necessarily have to be
714
#                     mutter("unable to get networkmanager state: %r" % e)
715
#                 
716
#         # Create the file list
717
#         self._create_file_view()
718
#         # Create the pending merges
719
#         self._create_pending_merges()
720
#         self._create_diff_view()
721
#         
722
#         # Expand the corresponding expander
723
#         if self._is_pending:
724
#             self._expander_merges.set_expanded(True)
725
#         else:
726
#             self._expander_files.set_expanded(True)
727
#         
728
#         # Display dialog
729
#         self.vbox.show_all()
730
#         
731
#         # Default to Commit button
732
#         self._button_commit.grab_default()
733
#     
734
#     def _show_diff_view(self, treeview):
735
#         # FIXME: the diff window freezes for some reason
736
#         treeselection = treeview.get_selection()
737
#         (model, iter) = treeselection.get_selected()
738
# 
739
#         if iter is not None:
740
#             selected = model.get_value(iter, 3) # Get the real_path attribute
741
#             self._diff_display.show_diff([selected])
742
# 
743
#     def _on_treeview_files_cursor_changed(self, treeview):
744
#         self._show_diff_view(treeview)
745
#         
746
#     def _on_treeview_files_row_activated(self, treeview, path, view_column):
747
#         self._show_diff_view(treeview)
748
#     
749
#     @show_bzr_error
750
#     def _on_commit_clicked(self, button):
751
#         """ Commit button clicked handler. """
752
#         textbuffer = self._textview_message.get_buffer()
753
#         start, end = textbuffer.get_bounds()
754
#         message = textbuffer.get_text(start, end).decode('utf-8')
755
#         
756
#         if not self.pending:
757
#             specific_files = self._get_specific_files()
758
#         else:
759
#             specific_files = None
760
# 
761
#         if message == '':
762
#             response = question_dialog(_('Commit with an empty message?'),
763
#                                        _('You can describe your commit intent in the message.'))
764
#             if response == gtk.RESPONSE_NO:
765
#                 # Kindly give focus to message area
766
#                 self._textview_message.grab_focus()
767
#                 return
768
# 
769
#         if self._is_checkout:
770
#             local = self._check_local.get_active()
771
#         else:
772
#             local = False
773
# 
774
#         if list(self.wt.unknowns()) != []:
775
#             response = question_dialog(_("Commit with unknowns?"),
776
#                _("Unknown files exist in the working tree. Commit anyway?"))
777
#             if response == gtk.RESPONSE_NO:
778
#                 return
779
#         
780
#         try:
781
#             self.wt.commit(message,
782
#                        allow_pointless=False,
783
#                        strict=False,
784
#                        local=local,
785
#                        specific_files=specific_files)
786
#         except errors.PointlessCommit:
787
#             response = question_dialog(_('Commit with no changes?'),
788
#                                        _('There are no changes in the working tree.'))
789
#             if response == gtk.RESPONSE_YES:
790
#                 self.wt.commit(message,
791
#                                allow_pointless=True,
792
#                                strict=False,
793
#                                local=local,
794
#                                specific_files=specific_files)
795
#         self.response(gtk.RESPONSE_OK)
796
# 
797
#     def _pending_merges(self, wt):
798
#         """ Return a list of pending merges or None if there are none of them. """
799
#         parents = wt.get_parent_ids()
800
#         if len(parents) < 2:
801
#             return None
802
#         
803
#         import re
804
#         from bzrlib.osutils import format_date
805
#         
806
#         pending = parents[1:]
807
#         branch = wt.branch
808
#         last_revision = parents[0]
809
#         
810
#         if last_revision is not None:
811
#             try:
812
#                 ignore = set(branch.repository.get_ancestry(last_revision))
813
#             except errors.NoSuchRevision:
814
#                 # the last revision is a ghost : assume everything is new 
815
#                 # except for it
816
#                 ignore = set([None, last_revision])
817
#         else:
818
#             ignore = set([None])
819
#         
820
#         pm = []
821
#         for merge in pending:
822
#             ignore.add(merge)
823
#             try:
824
#                 m_revision = branch.repository.get_revision(merge)
825
#                 
826
#                 rev = {}
827
#                 rev['committer'] = re.sub('<.*@.*>', '', m_revision.committer).strip(' ')
828
#                 rev['summary'] = m_revision.get_summary()
829
#                 rev['date'] = format_date(m_revision.timestamp,
830
#                                           m_revision.timezone or 0, 
831
#                                           'original', date_fmt="%Y-%m-%d",
832
#                                           show_offset=False)
833
#                 
834
#                 pm.append(rev)
835
#                 
836
#                 inner_merges = branch.repository.get_ancestry(merge)
837
#                 assert inner_merges[0] is None
838
#                 inner_merges.pop(0)
839
#                 inner_merges.reverse()
840
#                 for mmerge in inner_merges:
841
#                     if mmerge in ignore:
842
#                         continue
843
#                     mm_revision = branch.repository.get_revision(mmerge)
844
#                     
845
#                     rev = {}
846
#                     rev['committer'] = re.sub('<.*@.*>', '', mm_revision.committer).strip(' ')
847
#                     rev['summary'] = mm_revision.get_summary()
848
#                     rev['date'] = format_date(mm_revision.timestamp,
849
#                                               mm_revision.timezone or 0, 
850
#                                               'original', date_fmt="%Y-%m-%d",
851
#                                               show_offset=False)
852
#                 
853
#                     pm.append(rev)
854
#                     
855
#                     ignore.add(mmerge)
856
#             except errors.NoSuchRevision:
857
#                 print "DEBUG: NoSuchRevision:", merge
858
#         
859
#         return pm
860
# 
861
#     def _create_file_view(self):
862
#         self._file_store = gtk.ListStore(gobject.TYPE_BOOLEAN,   # [0] checkbox
863
#                                          gobject.TYPE_STRING,    # [1] path to display
864
#                                          gobject.TYPE_STRING,    # [2] changes type
865
#                                          gobject.TYPE_STRING)    # [3] real path
866
#         self._treeview_files.set_model(self._file_store)
867
#         crt = gtk.CellRendererToggle()
868
#         crt.set_property("activatable", True)
869
#         crt.connect("toggled", self._toggle_commit, self._file_store)
870
#         self._treeview_files.append_column(gtk.TreeViewColumn(_('Commit'),
871
#                                      crt, active=0))
872
#         self._treeview_files.append_column(gtk.TreeViewColumn(_('Path'),
873
#                                      gtk.CellRendererText(), text=1))
874
#         self._treeview_files.append_column(gtk.TreeViewColumn(_('Type'),
875
#                                      gtk.CellRendererText(), text=2))
876
# 
877
#         for path, id, kind in self.delta.added:
878
#             marker = osutils.kind_marker(kind)
879
#             if self.selected is not None:
880
#                 if path == os.path.join(self.wtpath, self.selected):
881
#                     self._file_store.append([ True, path+marker, _('added'), path ])
882
#                 else:
883
#                     self._file_store.append([ False, path+marker, _('added'), path ])
884
#             else:
885
#                 self._file_store.append([ True, path+marker, _('added'), path ])
886
# 
887
#         for path, id, kind in self.delta.removed:
888
#             marker = osutils.kind_marker(kind)
889
#             if self.selected is not None:
890
#                 if path == os.path.join(self.wtpath, self.selected):
891
#                     self._file_store.append([ True, path+marker, _('removed'), path ])
892
#                 else:
893
#                     self._file_store.append([ False, path+marker, _('removed'), path ])
894
#             else:
895
#                 self._file_store.append([ True, path+marker, _('removed'), path ])
896
# 
897
#         for oldpath, newpath, id, kind, text_modified, meta_modified in self.delta.renamed:
898
#             marker = osutils.kind_marker(kind)
899
#             if text_modified or meta_modified:
900
#                 changes = _('renamed and modified')
901
#             else:
902
#                 changes = _('renamed')
903
#             if self.selected is not None:
904
#                 if newpath == os.path.join(self.wtpath, self.selected):
905
#                     self._file_store.append([ True,
906
#                                               oldpath+marker + '  =>  ' + newpath+marker,
907
#                                               changes,
908
#                                               newpath
909
#                                             ])
910
#                 else:
911
#                     self._file_store.append([ False,
912
#                                               oldpath+marker + '  =>  ' + newpath+marker,
913
#                                               changes,
914
#                                               newpath
915
#                                             ])
916
#             else:
917
#                 self._file_store.append([ True,
918
#                                           oldpath+marker + '  =>  ' + newpath+marker,
919
#                                           changes,
920
#                                           newpath
921
#                                         ])
922
# 
923
#         for path, id, kind, text_modified, meta_modified in self.delta.modified:
924
#             marker = osutils.kind_marker(kind)
925
#             if self.selected is not None:
926
#                 if path == os.path.join(self.wtpath, self.selected):
927
#                     self._file_store.append([ True, path+marker, _('modified'), path ])
928
#                 else:
929
#                     self._file_store.append([ False, path+marker, _('modified'), path ])
930
#             else:
931
#                 self._file_store.append([ True, path+marker, _('modified'), path ])
932
#     
933
#     def _create_pending_merges(self):
934
#         if not self.pending:
935
#             return
936
#         
937
#         liststore = gtk.ListStore(gobject.TYPE_STRING,
938
#                                   gobject.TYPE_STRING,
939
#                                   gobject.TYPE_STRING)
940
#         self._treeview_merges.set_model(liststore)
941
#         
942
#         self._treeview_merges.append_column(gtk.TreeViewColumn(_('Date'),
943
#                                             gtk.CellRendererText(), text=0))
944
#         self._treeview_merges.append_column(gtk.TreeViewColumn(_('Committer'),
945
#                                             gtk.CellRendererText(), text=1))
946
#         self._treeview_merges.append_column(gtk.TreeViewColumn(_('Summary'),
947
#                                             gtk.CellRendererText(), text=2))
948
#         
949
#         for item in self.pending:
950
#             liststore.append([ item['date'],
951
#                                item['committer'],
952
#                                item['summary'] ])
953
#     
954
# 
955
#     def _create_diff_view(self):
278.1.12 by John Arbash Meinel
Delay computing the delta, and clean up some of the diff view names.
956
#         from diff import DiffView
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
957
# 
278.1.12 by John Arbash Meinel
Delay computing the delta, and clean up some of the diff view names.
958
#         self._diff_display = DiffView()
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
959
#         self._diff_display.set_trees(self.wt, self.wt.basis_tree())
960
#         self._diff_display.show_diff(None)
961
#         self._diff_display.show()
962
#         self._hpane.pack2(self._diff_display)
963
# 
964
#     def _get_specific_files(self):
965
#         ret = []
966
#         it = self._file_store.get_iter_first()
967
#         while it:
968
#             if self._file_store.get_value(it, 0):
969
#                 # get real path from hidden column 3
970
#                 ret.append(self._file_store.get_value(it, 3))
971
#             it = self._file_store.iter_next(it)
972
# 
973
#         return ret
974
#     
975
#     def _toggle_commit(self, cell, path, model):
976
#         model[path][0] = not model[path][0]
977
#         return