3 from rox
import processes
, g
4 from rox
.options
import Option
7 processes
.PipeThroughCommand
9 rox
.croak('Edit requires ROX-Lib 1.9.11 or later. Sorry!\n'
10 '\nhttp://rox.sourceforge.net/rox_lib.html')
12 header_fg
= Option('headers_fg', '#000')
13 header_bg
= Option('headers_bg', '#ddd')
15 static_fg
= Option('static_fg', '#000')
16 static_bg
= Option('static_bg', '#fff')
18 additions_fg
= Option('additions_fg', '#000')
19 additions_bg
= Option('additions_bg', '#8f8')
21 deletions_fg
= Option('deletions_fg', '#000')
22 deletions_bg
= Option('deletions_bg', '#f88')
24 tags
= g
.TextTagTable()
26 header
= g
.TextTag('header')
29 static
= g
.TextTag('static')
32 add
= g
.TextTag('add')
34 remove
= g
.TextTag('remove')
37 def options_changed():
38 header
.set_property('foreground', header_fg
.value
)
39 header
.set_property('background', header_bg
.value
)
40 static
.set_property('foreground', static_fg
.value
)
41 static
.set_property('background', static_bg
.value
)
42 add
.set_property('foreground', additions_fg
.value
)
43 add
.set_property('background', additions_bg
.value
)
44 remove
.set_property('foreground', deletions_fg
.value
)
45 remove
.set_property('background', deletions_bg
.value
)
47 rox
.app_options
.add_notify(options_changed
)
49 class Diff(processes
.PipeThroughCommand
):
50 def __init__(self
, uri
, src
, dst
):
51 processes
.PipeThroughCommand
.__init
__(self
, ('diff', '-u', '--', uri
, '-'), src
, dst
)
54 def check_errors(self
, errors
, status
):
56 raise Exception(errors
)
58 def Tmp(mode
= 'w+b', suffix
= '-tmp'):
59 "Create a seekable, randomly named temp file (deleted automatically after use)."
62 return tempfile
.NamedTemporaryFile(mode
, suffix
= suffix
)
64 # python2.2 doesn't have NamedTemporaryFile...
68 name
= tempfile
.mktemp(`random
.randint(1, 1000000)`
+ suffix
)
70 fd
= os
.open(name
, os
.O_RDWR|os
.O_CREAT|os
.O_EXCL
, 0700)
71 tmp
= tempfile
.TemporaryFileWrapper(os
.fdopen(fd
, mode
), name
)
75 class DiffWindow(rox
.Dialog
):
76 def __init__(self
, uri
, diff
):
77 rox
.Dialog
.__init
__(self
)
78 self
.set_title(_('Changes to %s') % uri
)
79 self
.set_has_separator(False)
81 buffer = g
.TextBuffer(tags
)
82 text
= g
.TextView(buffer)
83 text
.set_editable(False)
84 text
.set_cursor_visible(False)
85 text
.modify_base(g
.STATE_NORMAL
, g
.gdk
.color_parse(static_bg
.value
))
87 swin
= g
.ScrolledWindow()
88 swin
.set_shadow_type(g
.SHADOW_IN
)
89 swin
.set_policy(g
.POLICY_AUTOMATIC
, g
.POLICY_ALWAYS
)
90 self
.vbox
.pack_start(swin
)
94 self
.add_button(g
.STOCK_CLOSE
, g
.RESPONSE_OK
)
95 self
.connect('response', lambda b
, r
: self
.destroy())
97 iter = buffer.get_start_iter()
98 for line
in diff
.split('\n'):
100 if line
[:4] in ('--- ', '+++ ', '@@ -'):
102 elif line
.startswith('-'):
104 if len(line
) < 3: line
= ' \n'
105 elif line
.startswith('+'):
107 if len(line
) < 3: line
= ' \n'
110 buffer.insert_with_tags(iter, line
, tag
)
112 width
= g
.gdk
.screen_width() * 3 / 4
113 height
= g
.gdk
.screen_height() * 1 / 2
114 self
.set_default_size(width
, height
)
117 def show_diff(uri
, writer
):
118 from cStringIO
import StringIO
119 src
= Tmp(suffix
= '-diff')
125 diff
= dst
.getvalue()
128 rox
.info(_('There is no difference between this version and the saved one.'))
130 DiffWindow(uri
, diff
).show()