44
def pending_revisions(wt):
45
"""Return a list of pending merges or None if there are none of them.
47
Arguably this should be a core function, and
48
``bzrlib.status.show_pending_merges`` should be built on top of it.
50
:return: [(rev, [children])]
52
parents = wt.get_parent_ids()
56
# The basic pending merge algorithm uses the same algorithm as
57
# bzrlib.status.show_pending_merges
60
last_revision = parents[0]
62
if last_revision is not None:
64
ignore = set(branch.repository.get_ancestry(last_revision,
66
except errors.NoSuchRevision:
67
# the last revision is a ghost : assume everything is new
69
ignore = set([None, last_revision])
77
rev = branch.repository.get_revision(merge)
79
pm.append((rev, children))
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
85
for mmerge in reversed(inner_merges):
88
rev = branch.repository.get_revision(mmerge)
92
except errors.NoSuchRevision:
93
print "DEBUG: NoSuchRevision:", merge
43
98
class CommitDialog(gtk.Dialog):
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",
50
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
55
self.notbranch = notbranch
56
self.selected = selected
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)
63
self.pending = self._pending_merges(self.wt)
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.'))
75
error_dialog(_('Directory is not a branch'),
76
_('You can perform this action only in a branch.'))
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
85
# There are pending merges, file selection not supported
86
self._is_pending = True
89
# This is the main horizontal box, which is used to separate the commit
90
# info from the diff window.
99
"""Implementation of Commit."""
101
def __init__(self, wt, selected=None, parent=None):
102
gtk.Dialog.__init__(self, title="Commit - Olive",
105
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
107
self._selected = selected
111
self.set_default_size(800, 600)
113
def setup_params(self):
114
"""Setup the member variables for state."""
115
self._basis_tree = self._wt.basis_tree()
116
self._delta = self._wt.changes_from(self._basis_tree)
118
self._pending = pending_revisions(self._wt)
120
self._is_checkout = (self._wt.branch.get_bound_location() is not None)
123
"""Build up the dialog widgets."""
124
# The primary pane which splits it into left and right (adjustable)
91
126
self._hpane = gtk.HPaned()
92
self._button_commit = gtk.Button(_("Comm_it"), use_underline=True)
93
self._expander_files = gtk.Expander(_("File(s) to commit"))
94
self._vpaned_main = gtk.VPaned()
95
self._scrolledwindow_files = gtk.ScrolledWindow()
96
self._scrolledwindow_message = gtk.ScrolledWindow()
128
self._construct_left_pane()
129
self._construct_right_pane()
131
self.vbox.pack_start(self._hpane)
133
self.set_focus(self._global_message_text_view)
135
def _construct_left_pane(self):
136
self._left_pane_box = gtk.VBox(homogeneous=False, spacing=3)
137
self._construct_file_list()
138
self._construct_pending_list()
140
self._pending_box.show()
141
self._hpane.pack1(self._left_pane_box, resize=False, shrink=True)
142
self._left_pane_box.show()
144
def _construct_right_pane(self):
145
# TODO: I really want to make it so the diff view gets more space than
146
# the global commit message, and the per-file commit message gets even
147
# less. When I did it with wxGlade, I set it to 4 for diff, 2 for
148
# commit, and 1 for file commit, and it looked good. But I don't seem
149
# to have a way to do that with the gtk boxes... :( (Which is extra
150
# weird since wx uses gtk on Linux...)
151
self._right_pane_box = gtk.VBox(homogeneous=False, spacing=3)
152
self._construct_diff_view()
153
self._construct_file_message()
154
self._construct_global_message()
156
self._right_pane_box.show()
157
self._hpane.pack2(self._right_pane_box, resize=True, shrink=True)
159
def _construct_file_list(self):
160
self._files_box = gtk.VBox()
161
file_label = gtk.Label()
162
file_label.set_markup(_('<b>Files</b>'))
164
self._files_box.pack_start(file_label, expand=False)
166
scroller = gtk.ScrolledWindow()
167
scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
97
168
self._treeview_files = gtk.TreeView()
98
self._vbox_message = gtk.VBox()
99
self._label_message = gtk.Label(_("Commit message:"))
100
self._textview_message = gtk.TextView()
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()
109
self._button_commit.connect('clicked', self._on_commit_clicked)
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)
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)
121
self._button_commit.set_flags(gtk.CAN_DEFAULT)
124
self._scrolledwindow_merges.set_policy(gtk.POLICY_AUTOMATIC,
125
gtk.POLICY_AUTOMATIC)
126
self._treeview_files.set_sensitive(False)
128
# Construct the dialog
129
self.action_area.pack_end(self._button_commit)
131
self._scrolledwindow_files.add(self._treeview_files)
132
self._scrolledwindow_message.add(self._textview_message)
134
self._expander_files.add(self._scrolledwindow_files)
136
self._vbox_message.pack_start(self._label_message, False, False)
137
self._vbox_message.pack_start(self._scrolledwindow_message, True, True)
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)
146
self._vpaned_main.add1(self._expander_files)
148
self._vpaned_main.add2(self._vbox_message)
150
self._hpane.pack1(self._vpaned_main)
151
self.vbox.pack_start(self._hpane, expand=True, fill=True)
152
if self._is_checkout:
153
self._check_local = gtk.CheckButton(_("_Only commit locally"),
155
self.vbox.pack_start(self._check_local, False, False)
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')
163
# 3 is the enum value for STATE_CONNECTED
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)
170
# Create the file list
171
self._create_file_view()
172
# Create the pending merges
173
self._create_pending_merges()
174
self._create_diff_view()
176
# Expand the corresponding expander
178
self._expander_merges.set_expanded(True)
180
self._expander_files.set_expanded(True)
185
# Default to Commit button
186
self._button_commit.grab_default()
188
def _show_diff_view(self, treeview):
189
# FIXME: the diff window freezes for some reason
190
treeselection = treeview.get_selection()
191
(model, iter) = treeselection.get_selected()
194
selected = model.get_value(iter, 3) # Get the real_path attribute
195
self._diff_display.show_diff([selected])
197
def _on_treeview_files_cursor_changed(self, treeview):
198
self._show_diff_view(treeview)
200
def _on_treeview_files_row_activated(self, treeview, path, view_column):
201
self._show_diff_view(treeview)
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')
211
specific_files = self._get_specific_files()
213
specific_files = None
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()
223
if self._is_checkout:
224
local = self._check_local.get_active()
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:
235
self.wt.commit(message,
236
allow_pointless=False,
239
specific_files=specific_files)
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:
244
self.wt.commit(message,
245
allow_pointless=True,
248
specific_files=specific_files)
249
self.response(gtk.RESPONSE_OK)
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()
169
self._treeview_files.show()
170
scroller.add(self._treeview_files)
172
scroller.set_shadow_type(gtk.SHADOW_IN)
173
self._files_box.pack_start(scroller,
174
expand=True, fill=True)
175
self._files_box.show()
176
self._left_pane_box.pack_start(self._files_box)
178
def _construct_pending_list(self):
179
# Pending information defaults to hidden, we put it all in 1 box, so
180
# that we can show/hide all of them at once
181
self._pending_box = gtk.VBox()
182
self._pending_box.hide()
184
# TODO: This message should be centered
185
pending_message = gtk.Label()
186
pending_message.set_markup(
187
_('<i>Cannot select specific files when merging</i>'))
188
self._pending_box.pack_start(pending_message, expand=False)
189
pending_message.show()
191
pending_label = gtk.Label()
192
pending_label.set_markup(_('<b>Pending Revisions</b>'))
193
self._pending_box.pack_start(pending_label, expand=False)
196
scroller = gtk.ScrolledWindow()
197
scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
198
self._treeview_pending = gtk.TreeView()
199
scroller.add(self._treeview_pending)
201
scroller.set_shadow_type(gtk.SHADOW_IN)
202
self._pending_box.pack_start(scroller,
203
expand=True, fill=True)
204
self._treeview_pending.show()
205
self._left_pane_box.pack_start(self._pending_box)
207
def _construct_diff_view(self):
208
from diff import DiffDisplay
210
self._diff_label = gtk.Label(_('Diff for whole tree'))
211
self._right_pane_box.pack_start(self._diff_label, expand=False)
212
self._diff_label.show()
214
self._diff_view = DiffDisplay()
215
# self._diff_display.set_trees(self.wt, self.wt.basis_tree())
216
# self._diff_display.show_diff(None)
217
self._right_pane_box.pack_start(self._diff_view,
218
expand=True, fill=True)
219
self._diff_view.show()
221
def _construct_file_message(self):
222
file_message_box = gtk.VBox()
223
self._file_message_text_view = gtk.TextView()
224
# There should be some way to get at the TextView's ScrolledWindow
225
file_message_box.pack_start(self._file_message_text_view, expand=True, fill=True)
227
self._file_message_text_view.modify_font(pango.FontDescription("Monospace"))
228
self._file_message_text_view.set_wrap_mode(gtk.WRAP_WORD)
229
self._file_message_text_view.set_accepts_tab(False)
230
self._file_message_text_view.show()
232
self._file_message_expander = gtk.Expander(_('Message for XXX'))
233
self._file_message_expander.add(file_message_box)
234
file_message_box.show()
235
# TODO: When expanded, we want to change expand=True
236
self._right_pane_box.pack_start(self._file_message_expander,
237
expand=False, fill=True)
238
self._file_message_expander.connect('notify::expanded',
239
self._expand_file_message_callback)
240
self._file_message_expander.show()
242
def _expand_file_message_callback(self, expander, param_spec):
243
if expander.get_expanded():
244
self._right_pane_box.set_child_packing(expander,
245
expand=True, fill=True, padding=0, pack_type=gtk.PACK_START)
247
self._right_pane_box.set_child_packing(expander,
248
expand=False, fill=True, padding=0, pack_type=gtk.PACK_START)
250
def _construct_global_message(self):
251
self._global_message_label = gtk.Label(_('Global Commit Message'))
252
self._right_pane_box.pack_start(self._global_message_label, expand=False)
253
self._global_message_label.show()
255
self._global_message_text_view = gtk.TextView()
256
self._global_message_text_view.modify_font(pango.FontDescription("Monospace"))
257
self._right_pane_box.pack_start(self._global_message_text_view,
258
expand=True, fill=True)
259
self._file_message_text_view.set_wrap_mode(gtk.WRAP_WORD)
260
self._file_message_text_view.set_accepts_tab(False)
261
self._global_message_text_view.show()
264
def _rev_to_pending_info(rev):
265
"""Get the information from a pending merge."""
258
266
from bzrlib.osutils import format_date
260
pending = parents[1:]
262
last_revision = parents[0]
264
if last_revision is not None:
266
ignore = set(branch.repository.get_ancestry(last_revision))
267
except errors.NoSuchRevision:
268
# the last revision is a ghost : assume everything is new
270
ignore = set([None, last_revision])
275
for merge in pending:
278
m_revision = branch.repository.get_revision(merge)
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",
290
inner_merges = branch.repository.get_ancestry(merge)
291
assert inner_merges[0] is None
293
inner_merges.reverse()
294
for mmerge in inner_merges:
297
mm_revision = branch.repository.get_revision(mmerge)
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",
310
except errors.NoSuchRevision:
311
print "DEBUG: NoSuchRevision:", merge
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'),
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))
331
for path, id, kind in self.delta.added:
332
marker = osutils.kind_marker(kind)
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 ])
337
self._file_store.append([ False, path+marker, _('added'), path ])
339
self._file_store.append([ True, path+marker, _('added'), path ])
341
for path, id, kind in self.delta.removed:
342
marker = osutils.kind_marker(kind)
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 ])
347
self._file_store.append([ False, path+marker, _('removed'), path ])
349
self._file_store.append([ True, path+marker, _('removed'), path ])
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')
356
changes = _('renamed')
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,
365
self._file_store.append([ False,
366
oldpath+marker + ' => ' + newpath+marker,
371
self._file_store.append([ True,
372
oldpath+marker + ' => ' + newpath+marker,
377
for path, id, kind, text_modified, meta_modified in self.delta.modified:
378
marker = osutils.kind_marker(kind)
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 ])
383
self._file_store.append([ False, path+marker, _('modified'), path ])
385
self._file_store.append([ True, path+marker, _('modified'), path ])
387
def _create_pending_merges(self):
391
liststore = gtk.ListStore(gobject.TYPE_STRING,
394
self._treeview_merges.set_model(liststore)
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))
403
for item in self.pending:
404
liststore.append([ item['date'],
409
def _create_diff_view(self):
410
from diff import DiffDisplay
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)
418
def _get_specific_files(self):
420
it = self._file_store.get_iter_first()
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)
429
def _toggle_commit(self, cell, path, model):
430
model[path][0] = not model[path][0]
269
rev_dict['committer'] = re.sub('<.*@.*>', '', rev.committer).strip(' ')
270
rev_dict['summary'] = rev.get_summary()
271
rev_dict['date'] = format_date(rev.timestamp,
273
'original', date_fmt="%Y-%m-%d",
275
rev_dict['revision_id'] = rev.revision_id
279
# class CommitDialog(gtk.Dialog):
280
# """ New implementation of the Commit dialog. """
281
# def __init__(self, wt, wtpath, notbranch, selected=None, parent=None):
282
# """ Initialize the Commit Dialog. """
283
# gtk.Dialog.__init__(self, title="Commit - Olive",
286
# buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
290
# self.wtpath = wtpath
291
# self.notbranch = notbranch
292
# self.selected = selected
295
# self.old_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
296
# self.delta = self.wt.changes_from(self.old_tree)
298
# # Get pending merges
299
# self.pending = self._pending_merges(self.wt)
301
# # Do some preliminary checks
302
# self._is_checkout = False
303
# self._is_pending = False
304
# if self.wt is None and not self.notbranch:
305
# error_dialog(_('Directory does not have a working tree'),
306
# _('Operation aborted.'))
311
# error_dialog(_('Directory is not a branch'),
312
# _('You can perform this action only in a branch.'))
316
# if self.wt.branch.get_bound_location() is not None:
317
# # we have a checkout, so the local commit checkbox must appear
318
# self._is_checkout = True
321
# # There are pending merges, file selection not supported
322
# self._is_pending = True
324
# # Create the widgets
325
# # This is the main horizontal box, which is used to separate the commit
326
# # info from the diff window.
327
# self._hpane = gtk.HPaned()
328
# self._button_commit = gtk.Button(_("Comm_it"), use_underline=True)
329
# self._expander_files = gtk.Expander(_("File(s) to commit"))
330
# self._vpaned_main = gtk.VPaned()
331
# self._scrolledwindow_files = gtk.ScrolledWindow()
332
# self._scrolledwindow_message = gtk.ScrolledWindow()
333
# self._treeview_files = gtk.TreeView()
334
# self._vbox_message = gtk.VBox()
335
# self._label_message = gtk.Label(_("Commit message:"))
336
# self._textview_message = gtk.TextView()
338
# if self._is_pending:
339
# self._expander_merges = gtk.Expander(_("Pending merges"))
340
# self._vpaned_list = gtk.VPaned()
341
# self._scrolledwindow_merges = gtk.ScrolledWindow()
342
# self._treeview_merges = gtk.TreeView()
345
# self._button_commit.connect('clicked', self._on_commit_clicked)
346
# self._treeview_files.connect('cursor-changed', self._on_treeview_files_cursor_changed)
347
# self._treeview_files.connect('row-activated', self._on_treeview_files_row_activated)
350
# self._scrolledwindow_files.set_policy(gtk.POLICY_AUTOMATIC,
351
# gtk.POLICY_AUTOMATIC)
352
# self._scrolledwindow_message.set_policy(gtk.POLICY_AUTOMATIC,
353
# gtk.POLICY_AUTOMATIC)
354
# self._textview_message.modify_font(pango.FontDescription("Monospace"))
355
# self.set_default_size(500, 500)
356
# self._vpaned_main.set_position(200)
357
# self._button_commit.set_flags(gtk.CAN_DEFAULT)
359
# if self._is_pending:
360
# self._scrolledwindow_merges.set_policy(gtk.POLICY_AUTOMATIC,
361
# gtk.POLICY_AUTOMATIC)
362
# self._treeview_files.set_sensitive(False)
364
# # Construct the dialog
365
# self.action_area.pack_end(self._button_commit)
367
# self._scrolledwindow_files.add(self._treeview_files)
368
# self._scrolledwindow_message.add(self._textview_message)
370
# self._expander_files.add(self._scrolledwindow_files)
372
# self._vbox_message.pack_start(self._label_message, False, False)
373
# self._vbox_message.pack_start(self._scrolledwindow_message, True, True)
375
# if self._is_pending:
376
# self._expander_merges.add(self._scrolledwindow_merges)
377
# self._scrolledwindow_merges.add(self._treeview_merges)
378
# self._vpaned_list.add1(self._expander_files)
379
# self._vpaned_list.add2(self._expander_merges)
380
# self._vpaned_main.add1(self._vpaned_list)
382
# self._vpaned_main.add1(self._expander_files)
384
# self._vpaned_main.add2(self._vbox_message)
386
# self._hpane.pack1(self._vpaned_main)
387
# self.vbox.pack_start(self._hpane, expand=True, fill=True)
388
# if self._is_checkout:
389
# self._check_local = gtk.CheckButton(_("_Only commit locally"),
390
# use_underline=True)
391
# self.vbox.pack_start(self._check_local, False, False)
393
# bus = dbus.SystemBus()
394
# proxy_obj = bus.get_object('org.freedesktop.NetworkManager',
395
# '/org/freedesktop/NetworkManager')
396
# dbus_iface = dbus.Interface(
397
# proxy_obj, 'org.freedesktop.NetworkManager')
399
# # 3 is the enum value for STATE_CONNECTED
400
# self._check_local.set_active(dbus_iface.state() != 3)
401
# except dbus.DBusException, e:
402
# # Silently drop errors. While DBus may be
403
# # available, NetworkManager doesn't necessarily have to be
404
# mutter("unable to get networkmanager state: %r" % e)
406
# # Create the file list
407
# self._create_file_view()
408
# # Create the pending merges
409
# self._create_pending_merges()
410
# self._create_diff_view()
412
# # Expand the corresponding expander
413
# if self._is_pending:
414
# self._expander_merges.set_expanded(True)
416
# self._expander_files.set_expanded(True)
419
# self.vbox.show_all()
421
# # Default to Commit button
422
# self._button_commit.grab_default()
424
# def _show_diff_view(self, treeview):
425
# # FIXME: the diff window freezes for some reason
426
# treeselection = treeview.get_selection()
427
# (model, iter) = treeselection.get_selected()
429
# if iter is not None:
430
# selected = model.get_value(iter, 3) # Get the real_path attribute
431
# self._diff_display.show_diff([selected])
433
# def _on_treeview_files_cursor_changed(self, treeview):
434
# self._show_diff_view(treeview)
436
# def _on_treeview_files_row_activated(self, treeview, path, view_column):
437
# self._show_diff_view(treeview)
440
# def _on_commit_clicked(self, button):
441
# """ Commit button clicked handler. """
442
# textbuffer = self._textview_message.get_buffer()
443
# start, end = textbuffer.get_bounds()
444
# message = textbuffer.get_text(start, end).decode('utf-8')
446
# if not self.pending:
447
# specific_files = self._get_specific_files()
449
# specific_files = None
452
# response = question_dialog(_('Commit with an empty message?'),
453
# _('You can describe your commit intent in the message.'))
454
# if response == gtk.RESPONSE_NO:
455
# # Kindly give focus to message area
456
# self._textview_message.grab_focus()
459
# if self._is_checkout:
460
# local = self._check_local.get_active()
464
# if list(self.wt.unknowns()) != []:
465
# response = question_dialog(_("Commit with unknowns?"),
466
# _("Unknown files exist in the working tree. Commit anyway?"))
467
# if response == gtk.RESPONSE_NO:
471
# self.wt.commit(message,
472
# allow_pointless=False,
475
# specific_files=specific_files)
476
# except errors.PointlessCommit:
477
# response = question_dialog(_('Commit with no changes?'),
478
# _('There are no changes in the working tree.'))
479
# if response == gtk.RESPONSE_YES:
480
# self.wt.commit(message,
481
# allow_pointless=True,
484
# specific_files=specific_files)
485
# self.response(gtk.RESPONSE_OK)
487
# def _pending_merges(self, wt):
488
# """ Return a list of pending merges or None if there are none of them. """
489
# parents = wt.get_parent_ids()
490
# if len(parents) < 2:
494
# from bzrlib.osutils import format_date
496
# pending = parents[1:]
498
# last_revision = parents[0]
500
# if last_revision is not None:
502
# ignore = set(branch.repository.get_ancestry(last_revision))
503
# except errors.NoSuchRevision:
504
# # the last revision is a ghost : assume everything is new
506
# ignore = set([None, last_revision])
508
# ignore = set([None])
511
# for merge in pending:
514
# m_revision = branch.repository.get_revision(merge)
517
# rev['committer'] = re.sub('<.*@.*>', '', m_revision.committer).strip(' ')
518
# rev['summary'] = m_revision.get_summary()
519
# rev['date'] = format_date(m_revision.timestamp,
520
# m_revision.timezone or 0,
521
# 'original', date_fmt="%Y-%m-%d",
526
# inner_merges = branch.repository.get_ancestry(merge)
527
# assert inner_merges[0] is None
528
# inner_merges.pop(0)
529
# inner_merges.reverse()
530
# for mmerge in inner_merges:
531
# if mmerge in ignore:
533
# mm_revision = branch.repository.get_revision(mmerge)
536
# rev['committer'] = re.sub('<.*@.*>', '', mm_revision.committer).strip(' ')
537
# rev['summary'] = mm_revision.get_summary()
538
# rev['date'] = format_date(mm_revision.timestamp,
539
# mm_revision.timezone or 0,
540
# 'original', date_fmt="%Y-%m-%d",
546
# except errors.NoSuchRevision:
547
# print "DEBUG: NoSuchRevision:", merge
551
# def _create_file_view(self):
552
# self._file_store = gtk.ListStore(gobject.TYPE_BOOLEAN, # [0] checkbox
553
# gobject.TYPE_STRING, # [1] path to display
554
# gobject.TYPE_STRING, # [2] changes type
555
# gobject.TYPE_STRING) # [3] real path
556
# self._treeview_files.set_model(self._file_store)
557
# crt = gtk.CellRendererToggle()
558
# crt.set_property("activatable", True)
559
# crt.connect("toggled", self._toggle_commit, self._file_store)
560
# self._treeview_files.append_column(gtk.TreeViewColumn(_('Commit'),
562
# self._treeview_files.append_column(gtk.TreeViewColumn(_('Path'),
563
# gtk.CellRendererText(), text=1))
564
# self._treeview_files.append_column(gtk.TreeViewColumn(_('Type'),
565
# gtk.CellRendererText(), text=2))
567
# for path, id, kind in self.delta.added:
568
# marker = osutils.kind_marker(kind)
569
# if self.selected is not None:
570
# if path == os.path.join(self.wtpath, self.selected):
571
# self._file_store.append([ True, path+marker, _('added'), path ])
573
# self._file_store.append([ False, path+marker, _('added'), path ])
575
# self._file_store.append([ True, path+marker, _('added'), path ])
577
# for path, id, kind in self.delta.removed:
578
# marker = osutils.kind_marker(kind)
579
# if self.selected is not None:
580
# if path == os.path.join(self.wtpath, self.selected):
581
# self._file_store.append([ True, path+marker, _('removed'), path ])
583
# self._file_store.append([ False, path+marker, _('removed'), path ])
585
# self._file_store.append([ True, path+marker, _('removed'), path ])
587
# for oldpath, newpath, id, kind, text_modified, meta_modified in self.delta.renamed:
588
# marker = osutils.kind_marker(kind)
589
# if text_modified or meta_modified:
590
# changes = _('renamed and modified')
592
# changes = _('renamed')
593
# if self.selected is not None:
594
# if newpath == os.path.join(self.wtpath, self.selected):
595
# self._file_store.append([ True,
596
# oldpath+marker + ' => ' + newpath+marker,
601
# self._file_store.append([ False,
602
# oldpath+marker + ' => ' + newpath+marker,
607
# self._file_store.append([ True,
608
# oldpath+marker + ' => ' + newpath+marker,
613
# for path, id, kind, text_modified, meta_modified in self.delta.modified:
614
# marker = osutils.kind_marker(kind)
615
# if self.selected is not None:
616
# if path == os.path.join(self.wtpath, self.selected):
617
# self._file_store.append([ True, path+marker, _('modified'), path ])
619
# self._file_store.append([ False, path+marker, _('modified'), path ])
621
# self._file_store.append([ True, path+marker, _('modified'), path ])
623
# def _create_pending_merges(self):
624
# if not self.pending:
627
# liststore = gtk.ListStore(gobject.TYPE_STRING,
628
# gobject.TYPE_STRING,
629
# gobject.TYPE_STRING)
630
# self._treeview_merges.set_model(liststore)
632
# self._treeview_merges.append_column(gtk.TreeViewColumn(_('Date'),
633
# gtk.CellRendererText(), text=0))
634
# self._treeview_merges.append_column(gtk.TreeViewColumn(_('Committer'),
635
# gtk.CellRendererText(), text=1))
636
# self._treeview_merges.append_column(gtk.TreeViewColumn(_('Summary'),
637
# gtk.CellRendererText(), text=2))
639
# for item in self.pending:
640
# liststore.append([ item['date'],
645
# def _create_diff_view(self):
646
# from diff import DiffDisplay
648
# self._diff_display = DiffDisplay()
649
# self._diff_display.set_trees(self.wt, self.wt.basis_tree())
650
# self._diff_display.show_diff(None)
651
# self._diff_display.show()
652
# self._hpane.pack2(self._diff_display)
654
# def _get_specific_files(self):
656
# it = self._file_store.get_iter_first()
658
# if self._file_store.get_value(it, 0):
659
# # get real path from hidden column 3
660
# ret.append(self._file_store.get_value(it, 3))
661
# it = self._file_store.iter_next(it)
665
# def _toggle_commit(self, cell, path, model):
666
# model[path][0] = not model[path][0]