Added ability to bring up a diff of the changes to the saved version of the
[rox-edit.git] / diff.py
blob1bc4e99db7aa9a36829f3b8eb6cd3212d35df6af
1 import rox
2 from rox import processes, g
4 class Diff(processes.PipeThroughCommand):
5 def __init__(self, uri, src, dst):
6 processes.PipeThroughCommand.__init__(self, ('diff', '-u', uri, '-'), src, dst)
7 self.wait()
9 def check_errors(self, errors, status):
10 if errors:
11 raise Exception(errors)
13 def Tmp(mode = 'w+b', suffix = '-tmp'):
14 "Create a seekable, randomly named temp file (deleted automatically after use)."
15 import tempfile
16 try:
17 return tempfile.NamedTemporaryFile(mode, suffix = suffix)
18 except:
19 # python2.2 doesn't have NamedTemporaryFile...
20 pass
22 import random
23 name = tempfile.mktemp(`random.randint(1, 1000000)` + suffix)
25 fd = os.open(name, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0700)
26 tmp = tempfile.TemporaryFileWrapper(os.fdopen(fd, mode), name)
27 tmp.name = name
28 return tmp
30 class DiffWindow(rox.Dialog):
31 def __init__(self, uri, diff):
32 rox.Dialog.__init__(self)
33 self.set_title('Changes to %s' % uri)
34 self.text = g.TextView()
35 buffer = self.text.get_buffer()
36 self.vbox.pack_start(self.text)
37 self.vbox.show_all()
39 self.add_button(g.STOCK_CLOSE, g.RESPONSE_OK)
40 self.connect('response', lambda b, r: self.destroy())
42 tt = buffer.get_tag_table()
43 header = g.TextTag('header')
44 header.set_property('foreground', 'grey60')
45 tt.add(header)
46 add = g.TextTag('add')
47 add.set_property('foreground', 'dark green')
48 tt.add(add)
49 remove = g.TextTag('remove')
50 remove.set_property('foreground', 'red')
51 tt.add(remove)
53 start_to_tag = {
54 '-': header,
57 iter = buffer.get_start_iter()
58 for line in diff.split('\n'):
59 line += '\n'
60 tag = start_to_tag.get(line[:1], None)
61 if line[:4] in ('--- ', '+++ ', '@@ -'):
62 buffer.insert_with_tags(iter, line, header)
63 elif line.startswith('-'):
64 buffer.insert_with_tags(iter, line, remove)
65 elif line.startswith('+'):
66 buffer.insert_with_tags(iter, line, add)
67 else:
68 buffer.insert(iter, line)
70 def show_diff(uri, writer):
71 from cStringIO import StringIO
72 src = Tmp(suffix = '-diff')
73 dst = StringIO()
74 writer(src)
75 src.seek(0)
76 Diff(uri, src, dst)
77 del src
78 diff = dst.getvalue()
79 del dst
80 if not diff:
81 rox.info('There is no difference between this version and the saved one.')
82 else:
83 DiffWindow(uri, diff).show()