2 from rox
import processes
, g
3 from rox
.options
import Option
5 header_fg
= Option('headers_fg', '#000')
6 header_bg
= Option('headers_bg', '#ddd')
8 static_fg
= Option('static_fg', '#000')
9 static_bg
= Option('static_bg', '#fff')
11 additions_fg
= Option('additions_fg', '#000')
12 additions_bg
= Option('additions_bg', '#8f8')
14 deletions_fg
= Option('deletions_fg', '#000')
15 deletions_bg
= Option('deletions_bg', '#f88')
17 tags
= g
.TextTagTable()
19 header
= g
.TextTag('header')
22 static
= g
.TextTag('static')
25 add
= g
.TextTag('add')
27 remove
= g
.TextTag('remove')
30 def options_changed():
31 header
.set_property('foreground', header_fg
.value
)
32 header
.set_property('background', header_bg
.value
)
33 static
.set_property('foreground', static_fg
.value
)
34 static
.set_property('background', static_bg
.value
)
35 add
.set_property('foreground', additions_fg
.value
)
36 add
.set_property('background', additions_bg
.value
)
37 remove
.set_property('foreground', deletions_fg
.value
)
38 remove
.set_property('background', deletions_bg
.value
)
40 rox
.app_options
.add_notify(options_changed
)
42 class Diff(processes
.PipeThroughCommand
):
43 def __init__(self
, uri
, src
, dst
):
44 processes
.PipeThroughCommand
.__init
__(self
, ('diff', '-u', uri
, '-'), src
, dst
)
47 def check_errors(self
, errors
, status
):
49 raise Exception(errors
)
51 def Tmp(mode
= 'w+b', suffix
= '-tmp'):
52 "Create a seekable, randomly named temp file (deleted automatically after use)."
55 return tempfile
.NamedTemporaryFile(mode
, suffix
= suffix
)
57 # python2.2 doesn't have NamedTemporaryFile...
61 name
= tempfile
.mktemp(`random
.randint(1, 1000000)`
+ suffix
)
63 fd
= os
.open(name
, os
.O_RDWR|os
.O_CREAT|os
.O_EXCL
, 0700)
64 tmp
= tempfile
.TemporaryFileWrapper(os
.fdopen(fd
, mode
), name
)
68 class DiffWindow(rox
.Dialog
):
69 def __init__(self
, uri
, diff
):
70 rox
.Dialog
.__init
__(self
)
71 self
.set_title('Changes to %s' % uri
)
72 self
.set_has_separator(False)
74 buffer = g
.TextBuffer(tags
)
75 text
= g
.TextView(buffer)
76 text
.set_editable(False)
77 text
.set_cursor_visible(False)
78 text
.modify_base(g
.STATE_NORMAL
, g
.gdk
.color_parse(static_bg
.value
))
80 swin
= g
.ScrolledWindow()
81 swin
.set_shadow_type(g
.SHADOW_IN
)
82 swin
.set_policy(g
.POLICY_AUTOMATIC
, g
.POLICY_ALWAYS
)
83 self
.vbox
.pack_start(swin
)
87 self
.add_button(g
.STOCK_CLOSE
, g
.RESPONSE_OK
)
88 self
.connect('response', lambda b
, r
: self
.destroy())
90 iter = buffer.get_start_iter()
91 for line
in diff
.split('\n'):
93 line
= line
.replace('\t', ' ')
94 if line
[:4] in ('--- ', '+++ ', '@@ -'):
96 elif line
.startswith('-'):
98 if len(line
) < 3: line
= ' \n'
99 elif line
.startswith('+'):
101 if len(line
) < 3: line
= ' \n'
104 buffer.insert_with_tags(iter, line
[1:], tag
)
106 width
= g
.gdk
.screen_width() * 3 / 4
107 height
= g
.gdk
.screen_height() * 1 / 2
108 self
.set_default_size(width
, height
)
111 def show_diff(uri
, writer
):
112 from cStringIO
import StringIO
113 src
= Tmp(suffix
= '-diff')
119 diff
= dst
.getvalue()
122 rox
.info('There is no difference between this version and the saved one.')
124 DiffWindow(uri
, diff
).show()