Commit 21690b1d authored by steve9000's avatar steve9000

*** empty log message ***

parent 3bf2e643
......@@ -13,7 +13,8 @@ rundiff:
#$(PROG) ../old/meld-2003-03-01 . #../old/meld-2002-12-21
#$(PROG) test/lao test/tzu test/tao
#$(PROG) hkBaseSystem.cpp hkBaseSystem.cpp
$(PROG) ntest/file$(TESTNUM)*
#$(PROG) ntest/file$(TESTNUM)*
$(PROG) ntest/file$(TESTNUM)a ntest/file$(TESTNUM)a
#$(PROG) ../old/meld-2002-11-12 .
#$(PROG) {../old/oldmeld,../svnrepository/meld}/GNUmakefile
#$(PROG) test/1 test/2
......
......@@ -223,7 +223,7 @@ class CvsView(gnomeglade.Component):
lambda x: 1,
lambda x: x.cvs in [CVS_NONE,CVS_MODIFIED,CVS_MISSING] or x.isdir ]
def __init__(self, statusbar, location=None):
def __init__(self, statusbar):
gnomeglade.Component.__init__(self, misc.appdir("glade2/cvsview.glade"), "cvsview")
self.statusbar = statusbar
self.tempfiles = []
......@@ -279,9 +279,7 @@ class CvsView(gnomeglade.Component):
self.colors = ["#888888", "#000000", "#ff0000", "#0000ff"]
self.status = ["", "", "modified", "missing"]
self.location = None
self.set_location(location)
def on_quit_event(self):
for f in self.tempfiles:
......@@ -386,25 +384,20 @@ class CvsView(gnomeglade.Component):
return 0
def set_location(self, location):
location = os.path.abspath(location)
self.treemodel.clear()
if location:
self.location = location
self.fileentry.gtk_entry().set_text(location)
root = self.treemodel.append(None)
self.treemodel.set_value( root, MODEL_PIXMAP, self.image_dir )
self.treemodel.set_value( root, MODEL_NAME, location )
self.treemodel.set_value( root, MODEL_COLOR, self.colors[1])
self.treemodel.set_value( root, MODEL_STATUS, "")
self.treemodel.set_value( root, MODEL_ENTRY, Dir(location,location, CVS_NORMAL) )
child = self.treemodel.append(root)
self.treemodel.set_value(child, MODEL_NAME, "<empty>" )
self.treeview.expand_row(self.treemodel.get_path(root), 0)
else: #not location:
self.location = location
self.location = location = os.path.abspath(location or ".")
self.fileentry.gtk_entry().set_text(location)
root = self.treemodel.append(None)
self.treemodel.set_value( root, MODEL_PIXMAP, self.image_dir )
self.treemodel.set_value( root, MODEL_NAME, location )
self.treemodel.set_value( root, MODEL_COLOR, self.colors[1])
self.treemodel.set_value( root, MODEL_STATUS, "")
self.treemodel.set_value( root, MODEL_ENTRY, Dir(location, location, CVS_NORMAL) )
child = self.treemodel.append(root)
self.treemodel.set_value(child, MODEL_NAME, "<empty>" )
self.treeview.expand_row(self.treemodel.get_path(root), 0)
self.label_changed()
def on_button_recurse_toggled(self, button):
self.treeview_column_location.set_visible( self.button_recurse.get_active() )
self.refresh()
......@@ -427,6 +420,8 @@ class CvsView(gnomeglade.Component):
return map(lambda x: x[-1]!="/" and x or x[:-1], filter(lambda x: x!=None, ret))
def _command(self, command, files, refresh=1):
"""Run 'command' on 'files'. Return a tuple of the directory the
command was executed in and the output of the command."""
def progress():
self.emit("working-hard", 1)
self.flushevents()
......
......@@ -2,9 +2,49 @@
from __future__ import generators
import difflib
import misc
def _null_or_space(s):
return len(s) == 0 or s.isspace()
return len(s.strip()) == 0
if 0:
def _not_equal(s):
return filter( lambda x: x[0]!="equal", s )
else:
def _not_equal(s):
return s
################################################################################
#
# Differ
#
################################################################################
class IncrementalSequenceMatcher(difflib.SequenceMatcher):
def __init__(self, isjunk=None, a="", b=""):
difflib.SequenceMatcher.__init__(self, isjunk, a, b)
def initialise(self):
la, lb = len(self.a), len(self.b)
todo = [(0, la, 0, lb)]
done = []
while len(todo):
alo, ahi, blo, bhi = todo.pop(0)
i, j, k = x = self.find_longest_match(alo, ahi, blo, bhi)
if k:
yield None
done.append( (i,x) )
if alo < i and blo < j:
todo.append( (alo, i, blo, j) )
if i+k < ahi and j+k < bhi:
todo.append( (i+k, ahi, j+k, bhi) )
done.append( (la, (la, lb, 0)) )
done.sort()
self.matching_blocks = [x[1] for x in done]
yield 1
def get_difference_opcodes(self):
return filter(lambda x: x[0]!="equal", self.get_opcodes())
#return self.get_opcodes()
################################################################################
#
......@@ -13,101 +53,123 @@ def _null_or_space(s):
################################################################################
class Differ:
"""Utility class to hold diff2 or diff3 chunks"""
reverse = {
reversemap = {
"replace":"replace",
"insert":"delete",
"delete":"insert",
"conflict":"conflict",
"equal":"equal"}
"insert":"delete",
"delete":"insert",
"conflict":"conflict",
"equal":"equal"}
def __init__(self, *sequences):
"""Initialise with 1,2 or 3 sequences to compare"""
# Internally, diffs are stored from text1 -> text0 and text1 -> text2 for consistency
# Internally, diffs are stored from text1 -> text0 and text1 -> text2.
self.num_sequences = len(sequences)
self.seqlength = [0,0,0]
for i,s in misc.enumerate(sequences):
self.seqlength[i] = len(s)
if len(sequences)==0 or len(sequences)==1:
self.diffs = [[], []]
elif len(sequences)==2:
seq0 = difflib.SequenceMatcher(None, sequences[1], sequences[0]).get_opcodes()
seq0 = IncrementalSequenceMatcher(None, sequences[1], sequences[0]).get_difference_opcodes()
self.diffs = [seq0, []]
elif len(sequences)==3:
seq0 = difflib.SequenceMatcher(None, sequences[1], sequences[0]).get_opcodes()
seq1 = difflib.SequenceMatcher(None, sequences[1], sequences[2]).get_opcodes()
seq0 = IncrementalSequenceMatcher(None, sequences[1], sequences[0]).get_difference_opcodes()
seq1 = IncrementalSequenceMatcher(None, sequences[1], sequences[2]).get_difference_opcodes()
self.diffs = self._merge_diffs(seq0, seq1, sequences)
else:
raise "Bad number of arguments to Differ constructor (%i)" % len(sequences)
def _locate_chunk(self, fromindex, toindex, line):
def change_sequence(self, sequence, startidx, sizechange, getlines ):
"""getlines(sequence, lo, hi)"""
assert sequence in (0,1,2)
if sequence != 1: #0 or 2
self._change_sequence(sequence/2, sequence, startidx, sizechange, getlines)
else:# sequence==1:
self._change_sequence( 0, sequence, startidx, sizechange, getlines)
if self.num_sequences == 3:
self._change_sequence( 1, sequence, startidx, sizechange, getlines)
if self.num_sequences == 3: # conflict update
class Lazytext:
def __init__(self, get):
self.get = get
def __getslice__(self, lo, hi):
return self.get(lo,hi)
text = [Lazytext(lambda l,h:getlines(i,l,h)) for i in range(3)]
self.diffs = self._merge_diffs(self.diffs[0], self.diffs[1], text)
def _locate_chunk(self, whichdiffs, sequence, line):
"""Find the index of the chunk which contains line."""
#XXX 3way
idx = 1 + 2*(1-fromindex)
line_in_chunk = lambda x: x[idx] <= line and line < c[idx+1]
idx = 1 + 2*(sequence != 1)
line_in_chunk = lambda x: line < c[idx+1]
i = 0
for c in self.diffs[0]:
for c in self.diffs[whichdiffs]:
if line_in_chunk(c):
break
else:
i += 1
return i
def change_sequence(self, sequence, startidx, sizechange, getlines ):
"""gettext(sequence, lo, hi)"""
diffs = self.diffs[0]
def _change_sequence(self, which, sequence, startidx, sizechange, getlines ):
diffs = self.diffs[which]
lines_added = [0,0,0]
lines_added[sequence] = sizechange
if len(diffs) == 0:
assert min(lines_added) >= 0
self.diffs[0] = [("replace", 0, 1+lines_added[1], 0, 1+lines_added[0])]
return
# clamp range!!!
endidx = startidx + sizechange
loidx = self._locate_chunk(sequence, 1-sequence, startidx)
hiidx = min(self._locate_chunk(sequence, 1-sequence, endidx) + 1, len(diffs))
while loidx > 0:
loidx = self._locate_chunk(which, sequence, startidx)
if sizechange < 0:
hiidx = self._locate_chunk(which, sequence, startidx-sizechange)
else:
hiidx = loidx
if loidx > 0:
loidx -= 1
if diffs[loidx][0] == "equal":
break
while hiidx < len(diffs):
lorange = diffs[loidx][3], diffs[loidx][1]
else:
lorange = (0,0)
x = which*2
if hiidx < len(diffs):
hiidx += 1
if diffs[hiidx-1][0] == "equal":
break
range0 = diffs[loidx][3], diffs[hiidx-1][4] + lines_added[0]
assert range0[0] <= range0[1]
range1 = diffs[loidx][1], diffs[hiidx-1][2] + lines_added[1]
assert range1[0] <= range1[1]
lines0 = getlines(0, range0[0], range0[1])
hirange = diffs[hiidx-1][4], diffs[hiidx-1][2]
else:
hirange = self.seqlength[x], self.seqlength[1]
print "diffs", loidx, hiidx, len(diffs), lorange, hirange #diffs[loidx], diffs[hiidx-1]
rangex = lorange[0], hirange[0] + lines_added[x]
range1 = lorange[1], hirange[1] + lines_added[1]
assert rangex[0] <= rangex[1] and range1[0] <= range1[1]
linesx = getlines(x, rangex[0], rangex[1])
lines1 = getlines(1, range1[0], range1[1])
newdiffs = difflib.SequenceMatcher( None, lines1, lines0).get_opcodes()
newdiffs = [ (c[0], c[1]+range1[0],c[2]+range1[0], c[3]+range0[0],c[4]+range0[0]) for c in newdiffs]
if hiidx < len(self.diffs[0]):
self.diffs[0][hiidx:] = [ (c[0],
c[1] + lines_added[1], c[2] + lines_added[1],
c[3] + lines_added[0], c[4] + lines_added[0])
for c in self.diffs[0][hiidx:] ]
self.diffs[0][loidx:hiidx] = newdiffs
print "<<<\n%s\n===\n%s\n>>>" % ("\n".join(linesx),"\n".join(lines1))
newdiffs = IncrementalSequenceMatcher( None, lines1, linesx).get_difference_opcodes()
newdiffs = [ (c[0], c[1]+range1[0],c[2]+range1[0], c[3]+rangex[0],c[4]+rangex[0]) for c in newdiffs]
if hiidx < len(self.diffs[which]):
self.diffs[which][hiidx:] = [ (c[0],
c[1] + lines_added[1], c[2] + lines_added[1],
c[3] + lines_added[x], c[4] + lines_added[x])
for c in self.diffs[which][hiidx:] ]
self.diffs[which][loidx:hiidx] = newdiffs
self.seqlength[sequence] += sizechange
def reverse(self, c):
return self.reversemap[c[0]], c[3],c[4], c[1],c[2]
def pair_changes(self, fromindex, toindex):
"""give all changes between specified files"""
assert(fromindex != toindex)
assert(fromindex == 1 or toindex == 1)
if 0 in (fromindex, toindex):
whichdiff = 0
else:
whichdiff = 1
if fromindex == 1: # always diff from file 1 to file x
for c in self.diffs[whichdiff]:
assert abs(fromindex - toindex) == 1
assert 1 in (fromindex, toindex)
whichdiff = 2 in (fromindex, toindex)
if fromindex == 1:
for c in _not_equal(self.diffs[whichdiff]):
yield c
else: # diff hunks are reversed
for c in self.diffs[whichdiff]:
yield self.reverse[c[0]], c[3],c[4], c[1],c[2]
for c in _not_equal(self.diffs[whichdiff]):
yield self.reverse(c)
def single_changes(self, textindex):
"""give changes for single file only. do not return 'equal' hunks"""
if textindex == 0 or textindex == 2:
for c in self.diffs[textindex/2]:
yield c[0], c[3], c[4], c[1], c[2], 1
if textindex in (0,2):
for c in _not_equal(self.diffs[textindex/2]):
yield self.reversemap[c[0]], c[3], c[4], c[1], c[2], 1
else:
thread0 = self.diffs[0]
thread1 = self.diffs[1]
thread0 = _not_equal(self.diffs[0])
thread1 = _not_equal(self.diffs[1])
i0 = 0
i1 = 0
while i0 < len(thread0) and i1 < len(thread1):
......@@ -197,13 +259,40 @@ class Differ:
return [out0, out1]
def set_sequences_iter(self, *sequences):
if len(sequences)==0 or len(sequences)==1:
diffs = [[], []]
elif len(sequences)==2:
matcher = IncrementalSequenceMatcher(None, sequences[1], sequences[0])
work = matcher.initialise()
while work.next() == None:
yield None
diffs = [matcher.get_difference_opcodes(), []]
elif len(sequences)==3:
diffs = [[], []]
for i in range(2):
matcher = IncrementalSequenceMatcher(None, sequences[1], sequences[i*2])
work = matcher.initialise()
while work.next() == None:
yield None
diffs[i] = matcher.get_difference_opcodes()
diffs = self._merge_diffs(diffs[0], diffs[1], sequences)
else:
raise "Bad number of arguments to Differ constructor (%i)" % len(sequences)
self.diffs = diffs
self.num_sequences = len(sequences)
self.seqlength = [0] * self.num_sequences
for i,s in misc.enumerate(sequences):
self.seqlength[i] = len(s)
yield 1
def main():
t0 = open("test/lao").readlines()
tc = open("test/tzu").readlines()
t1 = open("test/tao").readlines()
thread0 = filter(lambda x: x[0]!="equal", difflib.SequenceMatcher(None, tc, t0).get_opcodes())
thread1 = filter(lambda x: x[0]!="equal", difflib.SequenceMatcher(None, tc, t1).get_opcodes())
thread0 = IncrementalSequenceMatcher(None, tc, t0).get_difference_opcodes()
thread1 = IncrementalSequenceMatcher(None, tc, t1).get_difference_opcodes()
texts = (t0,tc,t1)
......
......@@ -153,8 +153,6 @@ class DirDiff(gnomeglade.Component):
def __init__(self, num_panes, statusbar):
gnomeglade.Component.__init__(self, misc.appdir("glade2/dirdiff.glade"), "dirdiff")
self._map_widgets_into_lists( ["treeview", "fileentry", "diffmap", "scrolledwindow", "linkmap"] )
self.num_panes = 0
self.set_num_panes(num_panes)
self.statusbar = statusbar
self.undosequence = undo.UndoSequence()
self.lock = 0
......@@ -183,6 +181,8 @@ class DirDiff(gnomeglade.Component):
self.scrolledwindow[i].get_vadjustment().connect("value-changed", self._sync_vscroll )
self.scrolledwindow[i].get_hadjustment().connect("value-changed", self._sync_hscroll )
#self.linediffs = [DiffMap(),DiffMap()]
self.num_panes = 0
self.set_num_panes(num_panes)
def _do_to_others(self, master, objects, methodname, args):
for o in filter(lambda x:x!=master, objects):
......@@ -222,24 +222,24 @@ class DirDiff(gnomeglade.Component):
return self.fileentry[pane].get_full_path(0) or ""
def on_fileentry_activate(self, entry):
pane = self.fileentry.index(entry)
loc = entry.get_full_path(0)
self.set_location(loc, pane)
def set_location(self, loc, pane):
loc = os.path.abspath(loc or ".")
self.fileentry[pane].set_filename(loc)
self.statusbar.add_status( "Set location %i %s" % (pane, loc) )
locs = [ e.get_full_path(0) for e in self.fileentry[:self.num_panes] ]
self.set_locations(locs)
def set_locations(self, locations):
self.set_num_panes(len(locations))
for pane, loc in misc.enumerate(locations):
loc = os.path.abspath(loc or ".")
self.fileentry[pane].set_filename(loc)
self.statusbar.add_status( "Set location %i %s" % (pane, loc) )
self.model.clear()
root = self.model.append(None)
child = self.model.append(root)
self.model.set_value( root, PATH, "")
self.model.set_value(child, PATH, "")
l = self.fileentry[pane].get_full_path(0) or ""
self.model.set_value( root, pane+TEXT, os.path.basename(l))
self.model.set_value( root, pane+ICON, self.pixbuf_folder)
self.label_changed()
self.model.clear()
root = self.model.append(None)
child = self.model.append(root)
self.model.set_value( root, PATH, "")
self.model.set_value(child, PATH, "")
for i in range(self.num_panes):
l = self.fileentry[i].get_full_path(0) or ""
self.model.set_value( root, i+TEXT, os.path.basename(l))
self.model.set_value( root, i+ICON, self.pixbuf_folder)
self.treeview[pane].expand_row(self.model.get_path(root), 0)
def launch_comparison(self, file):
......@@ -429,15 +429,17 @@ class DirDiff(gnomeglade.Component):
def set_num_panes(self, n):
if n != self.num_panes and n in (1,2,3):
self.num_panes = n
toshow = self.scrolledwindow[:n] + self.fileentry[:n]
toshow += self.linkmap[:n-1] + self.diffmap[:n]
map( lambda x: x.show(), toshow )
tohide = self.scrolledwindow[n:] + self.fileentry[n:]
tohide += self.linkmap[n-1:] + self.diffmap[n:]
map( lambda x: x.hide(), tohide )
self.label_changed()
if self.num_panes != 0: # not first time through
self.num_panes = n
self.on_fileentry_activate(None)
else:
self.num_panes = n
def refresh(self):
pass
......
......@@ -3,7 +3,6 @@
from __future__ import generators
import codecs
import difflib
import math
import os
import pango
......@@ -21,9 +20,6 @@ import undo
gdk = gtk.gdk
def _enumerate(s):
return zip(range(len(s)),s)
################################################################################
#
# Local Functions
......@@ -110,9 +106,9 @@ class FileDiff(gnomeglade.Component):
keylookup = {65505 : MASK_SHIFT, 65507 : MASK_CTRL, 65513: MASK_ALT}
def __init__(self, num_panes, statusbar, prefs):
"""Start up an filediff with num_panes empty contents"""
gnomeglade.Component.__init__(self, misc.appdir("glade2/filediff.glade"), "filediff")
self._map_widgets_into_lists( ["textview", "fileentry", "diffmap", "scrolledwindow", "linkmap", "statusimage"] )
self.refresh_timer_id = -1
self.statusbar = statusbar
self.undosequence = undo.UndoSequence()
self.undosequence_busy = 0
......@@ -128,7 +124,7 @@ class FileDiff(gnomeglade.Component):
w.get_hadjustment().connect("value-changed", self._sync_hscroll )
self._connect_buffer_handlers()
self.linediffs = diffutil.Differ()
self.linediffer = diffutil.Differ()
load = lambda x: gnomeglade.load_pixbuf(misc.appdir("glade2/pixmaps/"+x), self.pixels_per_line)
self.pixbuf_apply0 = load("button_apply0.xpm")
self.pixbuf_apply1 = load("button_apply1.xpm")
......@@ -141,17 +137,21 @@ class FileDiff(gnomeglade.Component):
self.num_panes = 0
self.set_num_panes(num_panes)
for t in self.textview:
_ensure_fresh_tag_exists("edited line", t.get_buffer(), {"background": self.prefs.color_edited} )
def _disconnect_buffer_handlers(self):
for textview in self.textview:
buf = textview.get_buffer()
assert hasattr(buf,"handlers")
textview.set_editable(0)
for h in buf.handlers:
buf.disconnect(h)
def _connect_buffer_handlers(self):
for textview in self.textview:
buf = textview.get_buffer()
textview.set_editable(1)
id0 = buf.connect("insert-text", self.on_text_insert_text)
id1 = buf.connect("delete-range", self.on_text_delete_range)
id2 = buf.connect_after("insert-text", self.after_text_insert_text)
......@@ -164,8 +164,12 @@ class FileDiff(gnomeglade.Component):
pane = buffers.index(buffer)
def getlines(pane,lo,hi):
b = buffers[pane]
return b.get_text(b.get_iter_at_line(lo), b.get_iter_at_line(hi), 0).split("\n")[:-1]
self.linediffs.change_sequence( pane, startline, sizechange, getlines )
text = b.get_text(b.get_iter_at_line(lo), b.get_iter_at_line(hi), 0)
lines = text.split("\n")
if len(text) and text[-1]=='\n':
del lines[-1]
return lines
self.linediffer.change_sequence( pane, startline, sizechange, getlines )
self.refresh()
def after_text_insert_text(self, buffer, iter, newtext, textlen):
......@@ -175,7 +179,8 @@ class FileDiff(gnomeglade.Component):
def after_text_delete_range(self, buffer, iter0, iter1):
starting_at = iter0.get_line()
self._after_text_modified(buffer, starting_at, self.deleted_lines_pending)
assert self.deleted_lines_pending != -1
self._after_text_modified(buffer, starting_at, -self.deleted_lines_pending)
self.deleted_lines_pending = -1
def load_font(self):
......@@ -218,6 +223,7 @@ class FileDiff(gnomeglade.Component):
w = self.pixbuf_copy0.get_width()
l.queue_draw_area(0, 0, w, a[3])
l.queue_draw_area(a[2]-w, 0, w, a[3])
def on_key_release_event(self, object, event):
x = self.keylookup.get(event.keyval, 0)
if self.keymask & ~x != self.keymask:
......@@ -264,6 +270,7 @@ class FileDiff(gnomeglade.Component):
#
def on_text_begin_user_action(self, *buffer):
self.undosequence.begin_group()
def on_text_end_user_action(self, *buffer):
self.undosequence.end_group()
......@@ -294,6 +301,7 @@ class FileDiff(gnomeglade.Component):
self.undosequence.undo()
finally:
self.undosequence_busy = 0
def redo(self):
if self.undosequence.can_redo():
self.undosequence_busy = 1
......@@ -306,30 +314,16 @@ class FileDiff(gnomeglade.Component):
#
# text buffer loading/saving
#
def set_text(self, text, filename, pane, writable=1):
raise "FOO"
view = self.textview[pane]
buffer = view.get_buffer()
if self.prefs.supply_newline and len(text) and text[-1] != '\n':
def _set_text(self, text, filename, pane, writable=1):
"""Set the contents of 'pane' to utf8 'text'"""
self.fileentry[pane].set_filename(filename)
buffer = self.textview[pane].get_buffer()
if self.prefs.supply_newline and (len(text)==0 or text[-1] != '\n'):
text += "\n"
buffer.set_text( text )
gettext = buffer.get_text( buffer.get_start_iter(), buffer.get_end_iter(), 0 )
if text == gettext:
buffer.meld_encoding = None
else:
assert self.prefs.fallback_encoding
encoding = self.prefs.fallback_encoding
text = unicode(text, encoding)
buffer.set_text( text )
gettext = buffer.get_text( buffer.get_start_iter(), buffer.get_end_iter(), 0 )
buffer.meld_encoding = encoding
_ensure_fresh_tag_exists("edited line", buffer, {"background": self.prefs.color_edited} )
entry = self.fileentry[pane]
entry.set_filename(filename)
self.undosequence.clear()
self.set_buffer_modified(buffer, 0)
self.set_buffer_writable(buffer, writable)
self.flushevents()
def label_changed(self):
filenames = []
......@@ -360,17 +354,23 @@ class FileDiff(gnomeglade.Component):
d.destroy()
def set_files(self, files):
"""Set num panes to len(files) and load each file given.
If an element is None, the text of a pane is left"""
gtk.idle_add( self._set_files_internal(files).next )
def _set_files_internal(self, files):
self.set_num_panes( len(files) )
self._disconnect_buffer_handlers()
self.linediffer.diffs = [[],[]]
self.refresh()
buffers = [t.get_buffer() for t in self.textview][:self.num_panes]
[b.delete( b.get_start_iter(), b.get_end_iter() ) for b in buffers]
try_codecs = ["utf8", "latin1"]
yield "Opening files"
panetext = ["\n"] * self.num_panes
tasks = []
for i,f in _enumerate(files):
for i,f in misc.enumerate(files):
if f:
buffers[i].delete( buffers[i].get_start_iter(), buffers[i].get_end_iter() )
self.fileentry[i].set_filename(f)
try:
task = misc.struct(filename = f,
......@@ -378,43 +378,46 @@ class FileDiff(gnomeglade.Component):
buf = buffers[i],
codec = try_codecs[:],
text = [],
done = 0)
pane = i)
tasks.append(task)
except IOError, e:
self.set_text( "", filename, pane)
self._set_text( "", filename, pane)
self._dialog("Could not open '%s' for reading.\n\nThe error was:\n%s" % (filename, str(e)) )
else:
panetext[i] = buffers[i].get_text( buffers[i].get_start_iter(), buffers[i].get_end_iter() )
self.label_changed()
yield "Reading files"
while 0 in map(lambda x: x.done, tasks):
for t in tasks:
while len(tasks):
for t in tasks[:]:
try:
nextbit = t.file.read(4096)
except ValueError, err:
t.codec.pop(0)
if len(t.codec):
#print "codec error reset", err
t.file = codecs.open(t.filename, "r", t.codec[0])
t.buf.delete( t.buf.get_start_iter(), t.buf.get_end_iter() )
t.text = []
else:
print "codec error fallback", err
t.buf.delete( t.buf.get_start_iter(), t.buf.get_end_iter() )
t.text = []
self._dialog("Could not read from '%s'.\n\nI tried encodings %s."
% (t.filename, try_codecs))
t.done = 1
tasks.remove(t)
else:
if len(nextbit):
t.buf.insert( t.buf.get_end_iter(), nextbit )
t.text.append(nextbit)
else:
t.done = 1
tasks.remove(t)
panetext[t.pane] = "".join(t.text)
yield 1
yield "Computing differences"
text = ["".join(t.text) for t in tasks]
lines = map(lambda x: x.split("\n"), text)
print lines
lines = map(lambda x: x.split("\n"), panetext)
step = self.linediffer.set_sequences_iter(*lines)
while step.next() == None:
yield 1
self._connect_buffer_handlers()
self.refresh()
yield 0
def save_file(self, pane):
......@@ -429,6 +432,7 @@ class FileDiff(gnomeglade.Component):
self.fileentry[pane].set_filename(name)
buf = self.textview[pane].get_buffer()
text = buf.get_text(buf.get_start_iter(), buf.get_end_iter(), 0)
buf.meld_encoding = None
if buf.meld_encoding:
text = text.encode(buf.meld_encoding)
try:
......@@ -473,9 +477,9 @@ class FileDiff(gnomeglade.Component):
self.save_file(i)
def on_fileentry_activate(self, entry):
pane = self.fileentry.index(entry)
file = entry.get_full_path(0)
self.set_file(file, pane)
files = [None] * self.num_panes
files[ self.fileentry.index(entry) ] = entry.get_full_path(0)
self.set_files(files)
#
# refresh, _queue_refresh
......@@ -535,7 +539,7 @@ class FileDiff(gnomeglade.Component):
for (i,adj) in others:
mbegin,mend, obegin,oend = 0, self._get_line_count(master), 0, self._get_line_count(i)
# look for the chunk containing 'line'
for c in self.linediffs.pair_changes(master, i):
for c in self.linediffer.pair_changes(master, i):
c = c[1:]
if c[0] >= line:
mend = c[0]
......@@ -592,8 +596,8 @@ class FileDiff(gnomeglade.Component):
self._setup_gcs(area)
gc = area.meldgc.get_gc
for c in self.linediffs.single_changes(textindex):
if c[0] == "equal": continue
for c in self.linediffer.single_changes(textindex):
assert c[0] != "equal"
s,e = ( scaleit(c[1]), scaleit(c[2]+(c[1]==c[2])) )
s,e = math.floor(s), math.ceil(e)
window.draw_rectangle( gc(c[0]), 1, x0, s, x1, e-s)
......@@ -623,7 +627,7 @@ class FileDiff(gnomeglade.Component):
tag_conflict_line = _ensure_fresh_tag_exists("conflict line", buffer,