125
113
# XXX I don't know what other cases we need to handle
126
114
return 'Unknown tree'
129
class DiffItem(object):
132
def create(klass, trees, file_id, paths, changed_content, versioned,
133
parent, name, kind, executable, filter = None):
135
if parent == (None, None): # filter out TREE_ROOT (?)
138
# check for manually deleted files (w/o using bzr rm commands)
140
if versioned == (False, True):
143
if versioned == (True, True):
144
versioned = (True, False)
145
paths = (paths[0], None)
147
renamed = (parent[0], name[0]) != (parent[1], name[1])
153
dates[ix] = trees[ix].get_file_mtime(file_id, paths[ix])
155
if not renamed or e.errno != errno.ENOENT:
157
# If we get ENOENT error then probably we trigger
158
# bug #251532 in bzrlib. Take current time instead
159
dates[ix] = time.time()
160
except FileTimestampUnavailable:
161
# ghosts around us (see Bug #513096)
162
dates[ix] = 0 # using 1970/1/1 instead
164
properties_changed = []
165
if bool(executable[0]) != bool(executable[1]):
166
descr = {True: "+x", False: "-x", None: None}
167
properties_changed.append((descr[executable[0]],
168
descr[executable[1]]))
170
if versioned == (True, False):
171
status = N_('removed')
172
elif versioned == (False, True):
174
elif renamed and changed_content:
175
status = N_('renamed and modified')
177
status = N_('renamed')
179
status = N_('modified')
180
# check filter options
181
if filter and not filter(status):
184
return klass(trees, file_id, paths, changed_content, versioned, kind,
185
properties_changed, dates, status)
187
def __init__(self, trees, file_id, paths, changed_content, versioned, kind,
188
properties_changed, dates, status):
190
self.file_id = file_id
192
self.changed_content = changed_content
193
self.versioned = versioned
195
self.properties_changed = properties_changed
201
self._group_cache = {}
202
self._encodings = [None, None]
203
self._ulines = [None, None]
206
if self._lines is None:
209
def _load_lines(self):
210
if ((self.versioned[0] != self.versioned[1] or self.changed_content)
211
and (self.kind[0] == 'file' or self.kind[1] == 'file')):
214
for ix, tree in enumerate(self.trees):
216
if self.versioned[ix] and self.kind[ix] == 'file':
217
content = get_file_lines_from_tree(tree, self.file_id)
218
lines.append(content)
219
binary = binary or is_binary_content(content)
221
self._binary = binary
223
self._lines = ((),())
228
if self._lines is None:
234
if self._binary is None:
238
def groups(self, complete, ignore_whitespace):
239
key = (complete, ignore_whitespace)
240
groups = self._group_cache.get(key)
241
if groups is not None:
247
if self.versioned == (True, False):
248
groups = [[('delete', 0, len(lines[0]), 0, 0)]]
249
elif self.versioned == (False, True):
250
groups = [[('insert', 0, 0, 0, len(lines[1]))]]
252
groups = self.difference_groups(lines, complete, ignore_whitespace)
256
self._group_cache[key] = groups
259
def difference_groups(self, lines, complete, ignore_whitespace):
261
if ignore_whitespace:
262
re_whitespaces = re.compile("\s+")
263
left = (re_whitespaces.sub(" ", line) for line in left)
264
right = (re_whitespaces.sub(" ", line) for line in right)
265
matcher = SequenceMatcher(None, left, right)
267
groups = list([matcher.get_opcodes()])
269
groups = list(matcher.get_grouped_opcodes())
273
def encode(self, encodings):
275
ulines = self._ulines
277
if encodings[i] != self._encodings[i]:
278
self._encodings[i] = encodings[i]
280
ulines[i] = lines[i][:]
283
ulines[i] = [l.decode(encodings[i]) for l in lines[i]]
284
except UnicodeDecodeError, e:
285
trace.note('Failed to decode using %s, falling back to latin1', e.encoding)
286
ulines[i] = [l.decode('latin1') for l in lines[i]]
290
116
class DiffWindow(QBzrWindow):
292
118
def __init__(self, arg_provider, parent=None,
652
484
QtGui.QMessageBox.information(self, gettext('Diff'),
653
485
gettext('No changes found.'),
487
for t in self.views[0].browsers + (self.views[1],):
488
t.emit(QtCore.SIGNAL("documentChangeFinished()"))
655
489
self.view_refresh.setEnabled(self.can_refresh())
657
491
def click_toggle_view_mode(self, checked):
659
493
view = self.sdiffview
660
self.find_toolbar.text_edit = view
494
self.find_toolbar.set_text_edits([view.view])
661
495
self.tab_width_selector_left.menuAction().setVisible(False)
662
496
self.tab_width_selector_right.menuAction().setVisible(False)
663
497
self.tab_width_selector_unidiff.menuAction().setVisible(True)
665
499
view = self.diffview
666
self.find_toolbar.text_edit = view.browsers[0]
500
self.find_toolbar.set_text_edits(view.browsers)
667
501
self.tab_width_selector_left.menuAction().setVisible(True)
668
502
self.tab_width_selector_right.menuAction().setVisible(True)
669
503
self.tab_width_selector_unidiff.menuAction().setVisible(False)