First pass for GTK 3 and Python 3.

Still some bugs to fix but we can diff files.
Need tests with non-utf8 files.
This commit is contained in:
Romain Failliot 2016-07-03 20:22:54 -04:00
parent 4d54a00041
commit 18328c98c3
1 changed files with 139 additions and 118 deletions

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2006-2014 Derrick Moser <derrick_moser@yahoo.com>
@ -69,22 +69,15 @@ VERSION = '0.4.8'
COPYRIGHT = _('Copyright © 2006-2014 Derrick Moser')
WEBSITE = 'http://diffuse.sourceforge.net/'
# print a UTF-8 string using the host's native encoding
def printMessage(s):
try:
print(codecs.encode(unicode(s, 'utf_8'), sys.getfilesystemencoding()))
except UnicodeEncodeError:
pass
# process help options
if __name__ == '__main__':
args = sys.argv
argc = len(args)
if argc == 2 and args[1] in [ '-v', '--version' ]:
printMessage('%s %s\n%s' % (APP_NAME, VERSION, COPYRIGHT))
print('%s %s\n%s' % (APP_NAME, VERSION, COPYRIGHT))
sys.exit(0)
if argc == 2 and args[1] in [ '-h', '-?', '--help' ]:
printMessage(_('''Usage:
print(_('''Usage:
diffuse [ [OPTION...] [FILE...] ]...
diffuse ( -h | -? | --help | -v | --version )
@ -123,8 +116,15 @@ Display Options:
( -w | --ignore-all-space ) Ignore white space differences'''))
sys.exit(0)
import pygtk
pygtk.require('2.0')
import gi
from gi import pygtkcompat
pygtkcompat.enable()
pygtkcompat.enable_gtk(version='3.0')
from gi.repository import PangoCairo
gi.require_version('PangoCairo', '1.0')
import gtk
import difflib
@ -279,7 +279,7 @@ def readlines(fd):
return strip_eols(splitlines(fd.read()))
def readconfiglines(fd):
return unicode(fd.read(), 'utf_8').replace(u'\r', u'').split(u'\n')
return fd.read().replace(u'\r', u'').split(u'\n')
# This class to hold all customisable behaviour not exposed in the preferences
# dialogue: hotkey assignment, colours, syntax highlighting, etc.
@ -464,7 +464,7 @@ class Resources:
# keyboard action processing
def setKeyBinding(self, ctx, s, v):
action_tuple = (ctx, s)
modifiers = 0
modifiers = gtk.gdk.ModifierType(0)
key = None
for token in v.split('+'):
if token == 'Shift':
@ -559,7 +559,7 @@ class Resources:
# syntax highlighting
def getSyntaxNames(self):
return self.syntaxes.keys()
return list(self.syntaxes.keys())
def getSyntax(self, name):
return self.syntaxes.get(name, None)
@ -758,7 +758,7 @@ class FileEntry(gtk.HBox):
# action performed when the pick file button is pressed
def chooseFile(self, widget):
dialog = gtk.FileChooserDialog(self.title, self.toplevel, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
dialog.set_current_folder(unicode(os.path.realpath(os.curdir), sys.getfilesystemencoding()))
dialog.set_current_folder(os.path.realpath(os.curdir))
if dialog.run() == gtk.RESPONSE_OK:
self.entry.set_text(dialog.get_filename())
dialog.destroy()
@ -1118,11 +1118,11 @@ class Preferences:
for encoding in self._getDefaultEncodings():
try:
for m in magic.get(encoding.lower().replace('-', '').replace('_', ''), [ '' ]):
if s.startswith(m):
if str(s).startswith(m):
break
else:
continue
return unicode(s, encoding), encoding
return str(s, encoding=encoding), encoding
except (UnicodeDecodeError, LookupError):
pass
return u''.join([ unichr(ord(c)) for c in s ]), None
@ -1130,7 +1130,6 @@ class Preferences:
# cygwin and native applications can be used on windows, use this method
# to convert a path to the usual form expected on sys.platform
def convertToNativePath(self, s):
s = unicode(s, sys.getfilesystemencoding())
if isWindows() and s.find('/') >= 0:
# treat as a cygwin path
s = s.replace(os.sep, '/')
@ -1185,10 +1184,11 @@ def createMenu(specs, radio=None, accel_group=None):
item.set_sensitive(spec[5])
if len(spec) > 6 and spec[6] is not None:
item.set_submenu(createMenu(spec[6], radio, accel_group))
item.set_use_underline(True)
else:
item = gtk.SeparatorMenuItem()
menu.append(item)
item.show()
menu.append(item)
return menu
# convenience method for creating a menu bar according to a template
@ -1197,8 +1197,9 @@ def createMenuBar(specs, radio, accel_group):
for label, spec in specs:
menu = gtk.MenuItem(label)
menu.set_submenu(createMenu(spec, radio, accel_group))
menu_bar.append(menu)
menu.set_use_underline(True)
menu.show()
menu_bar.append(menu)
return menu_bar
# convenience method to set a widget's tooltip
@ -1218,7 +1219,7 @@ def appendButtons(box, size, specs):
if len(spec) > 0:
button = gtk.Button()
button.set_relief(gtk.RELIEF_NONE)
button.unset_flags(gtk.CAN_FOCUS)
button.set_can_focus(False)
image = gtk.Image()
image.set_from_stock(spec[0], size)
button.add(image)
@ -2675,8 +2676,8 @@ theVCSs = VCSs()
def step_adjustment(adj, delta):
v = adj.get_value() + delta
# clamp to the allowed range
v = max(v, int(adj.lower))
v = min(v, int(adj.upper - adj.page_size))
v = max(v, int(adj.get_lower()))
v = min(v, int(adj.get_upper() - adj.get_page_size()))
adj.set_value(v)
# This is a replacement for gtk.ScrolledWindow as it forced expose events to be
@ -2694,6 +2695,7 @@ class ScrolledWindow(gtk.Table):
self.hadj, self.vadj = hadj, vadj
vport = gtk.Viewport()
darea = gtk.DrawingArea()
darea.add_events(gtk.gdk.SCROLL_MASK)
self.darea = darea
# replace darea's queue_draw_area with our own so we can tell when
# to disable/enable our scrolling optimisation
@ -2717,17 +2719,17 @@ class ScrolledWindow(gtk.Table):
vadj.connect('value-changed', self.value_changed_cb)
darea.connect('configure-event', self.configure_cb)
darea.connect('scroll-event', self.scroll_cb)
darea.connect('expose-event', self.expose_cb)
darea.connect('draw', self.draw_cb)
# updates the adjustments to match the new widget size
def configure_cb(self, widget, event):
w, h = event.width, event.height
for adj, d in (self.hadj, w), (self.vadj, h):
v = adj.get_value()
if v + d > adj.upper:
adj.set_value(max(0, adj.upper - d))
adj.page_size = d
adj.page_increment = d
if v + d > adj.get_upper():
adj.set_value(max(0, adj.get_upper() - d))
adj.set_page_size(d)
adj.set_page_increment(d)
# update the vertical adjustment when the mouse's scroll wheel is used
def scroll_cb(self, widget, event):
@ -2760,7 +2762,7 @@ class ScrolledWindow(gtk.Table):
self.partial_redraw = False
self.darea.queue_draw()
def expose_cb(self, widget, event):
def draw_cb(self, widget, cr):
self.scroll_count = 0
# replacement for darea.queue_draw_area that notifies us when a partial
@ -3222,7 +3224,7 @@ class FileDiffViewer(gtk.Table):
raise ValueError('Invalid number of panes')
gtk.Table.__init__(self, 3, n + 1)
self.set_flags(gtk.CAN_FOCUS)
self.set_can_focus(True)
self.prefs = prefs
self.string_width_cache = {}
self.options = {}
@ -3345,10 +3347,11 @@ class FileDiffViewer(gtk.Table):
# pane contents
sw = ScrolledWindow(self.hadj, self.vadj)
darea = sw.darea
darea.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON1_MOTION_MASK)
darea.add_events(gtk.gdk.BUTTON_PRESS_MASK |
gtk.gdk.BUTTON1_MOTION_MASK)
darea.connect('button-press-event', self.darea_button_press_cb, i)
darea.connect('motion-notify-event', self.darea_motion_notify_cb, i)
darea.connect('expose-event', self.darea_expose_cb, i)
darea.connect('draw', self.darea_draw_cb, i)
self.dareas.append(darea)
self.attach(sw, i, i + 1, 1, 2)
sw.show()
@ -3358,11 +3361,13 @@ class FileDiffViewer(gtk.Table):
# add diff map
self.map = map = gtk.DrawingArea()
map.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON1_MOTION_MASK)
map.add_events(gtk.gdk.BUTTON_PRESS_MASK |
gtk.gdk.BUTTON1_MOTION_MASK |
gtk.gdk.SCROLL_MASK)
map.connect('button-press-event', self.map_button_press_cb)
map.connect('motion-notify-event', self.map_button_press_cb)
map.connect('scroll-event', self.map_scroll_cb)
map.connect('expose-event', self.map_expose_cb)
map.connect('draw', self.map_draw_cb)
self.attach(map, n, n + 1, 1, 2, gtk.FILL, gtk.FILL)
map.show()
map.set_size_request(16 * n, 0)
@ -3386,6 +3391,12 @@ class FileDiffViewer(gtk.Table):
self.setFont(pango.FontDescription(prefs.getString('display_font')))
self.cursor_pos = (0, 0)
# Contextual menu
self.ctxMenu = gtk.Menu()
menuItem = gtk.MenuItem("Test")
menuItem.show()
self.ctxMenu.append(menuItem)
# scroll to first difference when realised
darea.connect_after('realize', self._realise_cb)
@ -3693,9 +3704,9 @@ class FileDiffViewer(gtk.Table):
width = pixels(width)
height = self.font_height * num_lines
# update the adjustments
self.hadj.upper = width
self.hadj.set_upper(width)
self.hadj.step_increment = self.font_height
self.vadj.upper = height
self.vadj.set_upper(height)
self.vadj.step_increment = self.font_height
# returns a line from the specified pane and offset
@ -4511,7 +4522,7 @@ class FileDiffViewer(gtk.Table):
upper = lower + h
vadj = self.vadj
v = vadj.get_value()
ps = vadj.page_size
ps = vadj.get_page_size()
if lower < v:
vadj.set_value(lower)
elif upper > v + ps:
@ -4574,7 +4585,13 @@ class FileDiffViewer(gtk.Table):
x, y = self.dareas[self.current_pane].translate_coordinates(self.get_toplevel(), x, y)
# input methods support widgets are centred horizontally about the
# cursor, a width of 50 seems to give a better widget positions
self.im_context.set_cursor_location((x, y, 50, h))
rect = gtk.gdk.Rectangle()
rect.x = x
rect.y = y
rect.width = 50
rect.height = h
self.im_context.set_cursor_location(rect)
# get the position of the cursor in pango units
def _get_cursor_x_offset(self):
@ -4599,7 +4616,7 @@ class FileDiffViewer(gtk.Table):
# scroll horizontally
hadj = self.hadj
v = hadj.get_value()
ps = hadj.page_size
ps = hadj.get_page_size()
if lower < v:
hadj.set_value(lower)
elif upper > v + ps:
@ -4736,7 +4753,7 @@ class FileDiffViewer(gtk.Table):
i = min(y // self.font_height, nlines)
if event.button == 1:
# left mouse button
if event.type == gtk.gdk._2BUTTON_PRESS:
if event.type == gtk.gdk.EventType._2BUTTON_PRESS:
# double click
if self.mode == ALIGN_MODE:
self.setLineMode()
@ -4763,7 +4780,7 @@ class FileDiffViewer(gtk.Table):
while j < n and getCharacterClass(text[j]) == c:
j += 1
self.setCurrentChar(i, j, i, k)
elif event.type == gtk.gdk._3BUTTON_PRESS:
elif event.type == gtk.gdk.EventType._3BUTTON_PRESS:
# triple click, select a whole line
if self.mode == CHAR_MODE and self.current_pane == f:
i2 = min(i + 1, nlines)
@ -4801,7 +4818,8 @@ class FileDiffViewer(gtk.Table):
[_('Clear Edits'), self.button_cb, 'clear_edits', gtk.STOCK_CLEAR, None, can_isolate],
[],
[_('Swap with Selected Pane'), self.swap_panes_cb, f, None, None, can_swap] ])
menu.popup(None, None, None, event.button, event.time)
menu.attach_to_widget(self)
menu.popup(None, None, None, None, event.button, event.time)
# callback used to notify us about click and drag motion
def darea_motion_notify_cb(self, widget, event, f):
@ -4931,22 +4949,23 @@ class FileDiffViewer(gtk.Table):
return s
# draw the text viewport
def darea_expose_cb(self, widget, event, f):
def darea_draw_cb(self, widget, cr, f):
pane = self.panes[f]
syntax = theResources.getSyntax(self.syntax)
offset_x, offset_y, width, height = event.area
x = offset_x + int(self.hadj.get_value())
y = offset_y + int(self.vadj.get_value())
#offset_x, offset_y, width, height = widget.get_allocation()
rect = widget.get_allocation()
x = rect.x + int(self.hadj.get_value())
y = rect.y + int(self.vadj.get_value())
# draw to a pixmap to avoid screen flicker
pixmap = gtk.gdk.Pixmap(widget.window, width, height)
#pixmap = gtk.gdk.Pixmap(widget.window, width, height)
cr = pixmap.cairo_create()
#cr = pixmap.cairo_create()
cr.translate(-x, -y)
maxx = x + width
maxy = y + height
maxx = x + rect.width
maxy = y + rect.height
line_number_width = pixels(self.getLineNumberWidth())
h = self.font_height
@ -4976,7 +4995,8 @@ class FileDiffViewer(gtk.Table):
layout.set_font_description(self.font)
w = pixels(layout.get_size()[0] + self.digit_width)
cr.move_to(line_number_width - w, y_start)
cr.show_layout(layout)
#cr.show_layout(layout)
PangoCairo.show_layout(cr, layout)
cr.restore()
x_start = line_number_width
@ -5218,12 +5238,14 @@ class FileDiffViewer(gtk.Table):
layout = self.create_pango_layout(''.join(ss[starti:self.current_char]))
layout.set_font_description(self.font)
cr.move_to(x_start + pixels(start), y_start)
cr.show_layout(layout)
#cr.show_layout(layout)
PangoCairo.show_layout(cr, layout)
start += layout.get_size()[0] + preeditwidth
layout = self.create_pango_layout(''.join(ss[self.current_char:endi]))
layout.set_font_description(self.font)
cr.move_to(x_start + pixels(start), y_start)
cr.show_layout(layout)
#cr.show_layout(layout)
PangoCairo.show_layout(cr, layout)
if self.current_pane == f and self.current_line == i:
# draw the cursor and preedit text
@ -5243,7 +5265,8 @@ class FileDiffViewer(gtk.Table):
colour = theResources.getColour('preedit')
cr.set_source_rgb(colour.red, colour.green, colour.blue)
cr.move_to(x_pos, y_start)
cr.show_layout(layout)
#cr.show_layout(layout)
PangoCairo.show_layout(cr, layout)
# advance to the preedit's cursor position
x_pos += pixels(self._preedit_layout(True).get_size()[0])
# draw the character editing cursor
@ -5269,8 +5292,8 @@ class FileDiffViewer(gtk.Table):
y_start += h
# draw the pixmap to window
gc = pixmap.new_gc()
widget.window.draw_drawable(gc, pixmap, 0, 0, offset_x, offset_y, width, height)
#gc = pixmap.new_gc()
#widget.window.draw_drawable(gc, pixmap, 0, 0, offset_x, offset_y, width, height)
# callback used when panes are scrolled horizontally
def hadj_changed_cb(self, adj):
@ -5286,13 +5309,13 @@ class FileDiffViewer(gtk.Table):
vadj = self.vadj
h = widget.get_allocation().height
hmax = max(int(vadj.upper), h)
hmax = max(int(vadj.get_upper()), h)
# centre view about picked location
y = event.y * hmax // h
v = y - int(vadj.page_size / 2)
v = max(v, int(vadj.lower))
v = min(v, int(vadj.upper - vadj.page_size))
v = y - int(vadj.get_page_size() / 2)
v = max(v, int(vadj.get_lower()))
v = min(v, int(vadj.get_upper() - vadj.get_page_size()))
vadj.set_value(v)
# callback to handle mouse scrollwheel events
@ -5304,7 +5327,7 @@ class FileDiffViewer(gtk.Table):
step_adjustment(self.vadj, delta)
# redraws the overview map when a portion is exposed
def map_expose_cb(self, widget, event):
def map_draw_cb(self, widget, cr):
n = len(self.panes)
# compute map if it hasn't already been cached
@ -5352,10 +5375,10 @@ class FileDiffViewer(gtk.Table):
self.map_cache[f].append([start[f], nlines, flags[f]])
# draw to a pixmap to avoid screen flicker
x, y, width, height = event.area
pixmap = gtk.gdk.Pixmap(widget.window, width, height)
cr = pixmap.cairo_create()
cr.translate(-x, -y)
#x, y, width, height = event.area
#pixmap = gtk.gdk.Pixmap(widget.window, width, height)
#cr = pixmap.cairo_create()
#cr.translate(-rect.x, -rect.y)
# clear
colour = theResources.getColour('map_background')
@ -5364,14 +5387,14 @@ class FileDiffViewer(gtk.Table):
bg_colour = theResources.getColour('text_background')
edited_colour = theResources.getColour('edited')
rect = widget.get_allocation()
# get scroll position and total size
r = widget.get_allocation()
w, h = r.width, r.height
vadj = self.vadj
hmax = max(vadj.upper, h)
hmax = max(vadj.get_upper(), rect.height)
# draw diff blocks
wn = w / n
wn = rect.width / n
pad = 1
for f in range(n):
diffcolours = [ theResources.getDifferenceColour(f), theResources.getDifferenceColour(f + 1) ]
@ -5393,12 +5416,13 @@ class FileDiffViewer(gtk.Table):
continue
# ensure the line is visible in the map
ymin = h * self.font_height * start // hmax
if ymin >= y + height:
ymin = rect.height * self.font_height * start // hmax
if ymin >= rect.y + rect.height:
break
yh = max(h * self.font_height * end // hmax - ymin, 1)
if ymin + yh <= y:
continue
yh = max(rect.height * self.font_height * end // hmax - ymin, 1)
#if ymin + yh <= rect.y:
# continue
cr.set_source_rgb(colour.red, colour.green, colour.blue)
cr.rectangle(wx + pad, ymin, wn - 2 * pad, yh)
@ -5406,28 +5430,28 @@ class FileDiffViewer(gtk.Table):
# draw cursor
vmin = int(vadj.get_value())
vmax = vmin + vadj.page_size
ymin = h * vmin // hmax
if ymin < y + height:
yh = h * vmax // hmax - ymin
vmax = vmin + vadj.get_page_size()
ymin = rect.height * vmin // hmax
if ymin < rect.y + rect.height:
yh = rect.height * vmax // hmax - ymin
if yh > 1:
yh -= 1
if ymin + yh > y:
#if ymin + yh > rect.y:
colour = theResources.getColour('line_selection')
alpha = theResources.getFloat('line_selection_opacity')
cr.set_source_rgba(colour.red, colour.green, colour.blue, alpha)
cr.rectangle(0.5, ymin + 0.5, w - 1, yh - 1)
cr.rectangle(0.5, ymin + 0.5, rect.width - 1, yh - 1)
cr.fill()
colour = theResources.getColour('cursor')
cr.set_source_rgb(colour.red, colour.green, colour.blue)
cr.set_line_width(1)
cr.rectangle(0.5, ymin + 0.5, w - 1, yh - 1)
cr.rectangle(0.5, ymin + 0.5, rect.width - 1, yh - 1)
cr.stroke()
# draw the pixmap to the window
gc = pixmap.new_gc()
widget.window.draw_drawable(gc, pixmap, 0, 0, x, y, width, height)
#gc = pixmap.new_gc()
#widget.window.draw_drawable(gc, pixmap, 0, 0, x, y, width, height)
# returns the maximum valid offset for a cursor position
# cursors cannot be moved to the right of line ending characters
@ -5499,7 +5523,7 @@ class FileDiffViewer(gtk.Table):
# 'page_up' keybinding action
def _line_mode_page_up(self, selection=None):
delta = int(self.vadj.page_size // self.font_height)
delta = int(self.vadj.get_page_size() // self.font_height)
self.setCurrentLine(self.current_pane, self.current_line - delta, selection)
# 'extend_page_up' keybinding action
@ -5508,7 +5532,7 @@ class FileDiffViewer(gtk.Table):
# 'page_down' keybinding action
def _line_mode_page_down(self, selection=None):
delta = int(self.vadj.page_size // self.font_height)
delta = int(self.vadj.get_page_size() // self.font_height)
self.setCurrentLine(self.current_pane, self.current_line + delta, selection)
# 'extend_page_down' keybinding action
@ -5550,7 +5574,7 @@ class FileDiffViewer(gtk.Table):
def im_commit_cb(self, im, s):
if self.mode == CHAR_MODE:
self.openUndoBlock()
self.replaceText(unicode(s, 'utf_8'))
self.replaceText(s)
self.closeUndoBlock()
# update the cached preedit text
@ -5571,7 +5595,6 @@ class FileDiffViewer(gtk.Table):
s, a, c = self.im_context.get_preedit_string()
if len(s) > 0:
# we have preedit text, draw that instead
s = unicode(s, 'utf_8')
p = (s, a, c)
else:
p = None
@ -5646,7 +5669,7 @@ class FileDiffViewer(gtk.Table):
if event.keyval in [ gtk.keysyms.Up, gtk.keysyms.Down ]:
delta = 1
else:
delta = int(self.vadj.page_size // self.font_height)
delta = int(self.vadj.get_page_size() // self.font_height)
if event.keyval in [ gtk.keysyms.Up, gtk.keysyms.Page_Up ]:
delta = -delta
i += delta
@ -5776,7 +5799,7 @@ class FileDiffViewer(gtk.Table):
self.replaceText('')
# return key, add the platform specific end of line characters
elif event.keyval in [ gtk.keysyms.Return, gtk.keysyms.KP_Enter ]:
s = unicode(os.linesep)
s = os.linesep
if self.prefs.getBool('editor_auto_indent'):
start_i, start_j = self.selection_line, self.selection_char
end_i, end_j = self.current_line, self.current_char
@ -5789,12 +5812,12 @@ class FileDiffViewer(gtk.Table):
w = self.stringWidth(text[:j])
if self.prefs.getBool('editor_expand_tabs'):
# convert to spaces
s += u' ' * w
s += ' ' * w
else:
tab_width = self.prefs.getInt('display_tab_width')
# replace with tab characters where possible
s += u'\t' * (w // tab_width)
s += u' ' * (w % tab_width)
s += '\t' * (w // tab_width)
s += ' ' * (w % tab_width)
self.replaceText(s)
# insert key
elif event.keyval in [ gtk.keysyms.Tab, gtk.keysyms.ISO_Left_Tab ]:
@ -5896,7 +5919,7 @@ class FileDiffViewer(gtk.Table):
needs_block = (self.undoblock is None)
if needs_block:
self.openUndoBlock()
self.replaceText(unicode(nullToEmpty(text), 'utf_8'))
self.replaceText(nullToEmpty(text))
if needs_block:
self.closeUndoBlock()
@ -6124,7 +6147,7 @@ class FileDiffViewer(gtk.Table):
# scroll the viewport so pixels at position 'y' are centred
def centre_view_about_y(self, y):
vadj = self.vadj
y = min(max(0, y - vadj.page_size / 2), vadj.upper - vadj.page_size)
y = min(max(0, y - vadj.get_page_size() / 2), vadj.get_upper() - vadj.get_page_size())
vadj.set_value(y)
# move the cursor from line 'i' to the next difference in direction 'delta'
@ -6734,7 +6757,7 @@ class FileChooserDialog(gtk.FileChooserDialog):
self.vbox.pack_start(hbox, False, False, 0)
hbox.show()
self.set_current_folder(unicode(self.last_chosen_folder, sys.getfilesystemencoding()))
self.set_current_folder(self.last_chosen_folder)
self.connect('current-folder-changed', self.__current_folder_changed_cb)
def set_encoding(self, encoding):
@ -6748,9 +6771,7 @@ class FileChooserDialog(gtk.FileChooserDialog):
def get_filename(self):
# convert from UTF-8 string to unicode
s = gtk.FileChooserDialog.get_filename(self)
if s is not None:
return unicode(s, 'utf_8')
return gtk.FileChooserDialog.get_filename(self)
# dialogue used to search for text
class NumericDialog(gtk.Dialog):
@ -6783,7 +6804,7 @@ class NumericDialog(gtk.Dialog):
def url_hook(dialog, link, userdata):
webbrowser.open(link)
gtk.about_dialog_set_url_hook(url_hook, None)
#gtk.about_dialog_set_url_hook(url_hook, None)
# the about dialogue
class AboutDialog(gtk.AboutDialog):
@ -7028,7 +7049,7 @@ class Diffuse(gtk.Window):
self.connect('format-changed', self.format_changed_cb)
for i, darea in enumerate(self.dareas):
darea.drag_dest_set(gtk.DEST_DEFAULT_ALL, [ ('text/uri-list', 0, 0) ], gtk.gdk.ACTION_COPY)
darea.drag_dest_set(gtk.DEST_DEFAULT_ALL, [ gtk.TargetEntry.new('text/uri-list', 0, 0) ], gtk.gdk.ACTION_COPY)
darea.connect('drag-data-received', self.drag_data_received_cb, i)
# initialise status
self.updateStatus()
@ -7082,7 +7103,7 @@ class Diffuse(gtk.Window):
if i > start:
p = url2path(s[start:i])
if p is not None:
ss.append(unicode(p, 'utf_8'))
ss.append(p)
# load the first valid file
for s in ss:
if os.path.isfile(s):
@ -7161,7 +7182,7 @@ class Diffuse(gtk.Window):
if encoding is None:
s, encoding = self.prefs.convertToUnicode(s)
else:
s = unicode(s, encoding)
s = str(s, encoding=encoding)
ss = splitlines(s)
except (IOError, OSError, UnicodeDecodeError, WindowsError, LookupError):
# FIXME: this can occur before the toplevel window is drawn
@ -7456,7 +7477,7 @@ class Diffuse(gtk.Window):
s = 0.8
sw, sh = int(s * w), int(s * h)
w1, h1 = w - sw, h - sh
p = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
p = gtk.gdk.Pixbuf.new(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
p.fill(0)
p0.composite(p, 0, 0, sw, sh, 0, 0, s, s, gtk.gdk.INTERP_BILINEAR, 255)
p0.composite(p, w1, h1, sw, sh, w1, h1, s, s, gtk.gdk.INTERP_BILINEAR, 255)
@ -7467,7 +7488,7 @@ class Diffuse(gtk.Window):
sw, sh = int(s * w), int(s * h)
w1, h1 = (w - sw) / 2, (h - sh) / 2
w2, h2 = w - sw, h - sh
p = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
p = gtk.gdk.Pixbuf.new(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
p.fill(0)
p0.composite(p, 0, 0, sw, sh, 0, 0, s, s, gtk.gdk.INTERP_BILINEAR, 255)
p0.composite(p, w1, h1, sw, sh, w1, h1, s, s, gtk.gdk.INTERP_BILINEAR, 255)
@ -7482,14 +7503,14 @@ class Diffuse(gtk.Window):
w1, h1 = w - sw, h - sh
# create merge from left then right icon
p = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
p = gtk.gdk.Pixbuf.new(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
p.fill(0)
p1.composite(p, w1, h1, sw, sh, w1, h1, s, s, gtk.gdk.INTERP_BILINEAR, 255)
p0.composite(p, 0, 0, sw, sh, 0, 0, s, s, gtk.gdk.INTERP_BILINEAR, 255)
factory.add(DIFFUSE_STOCK_LEFT_RIGHT, gtk.IconSet(p))
# create merge from right then left icon
p = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
p = gtk.gdk.Pixbuf.new(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
p.fill(0)
p0.composite(p, 0, h1, sw, sh, 0, h1, s, s, gtk.gdk.INTERP_BILINEAR, 255)
p1.composite(p, w1, 0, sw, sh, w1, 0, s, s, gtk.gdk.INTERP_BILINEAR, 255)
@ -8423,7 +8444,7 @@ if __name__ == '__main__':
elif i + 1 < argc and arg in [ '-r', '--revision' ]:
# specified revision
i += 1
revs.append((unicode(args[i], sys.getfilesystemencoding()), encoding))
revs.append((args[i], encoding))
elif arg in [ '-s', '--separate' ]:
funcs[mode](specs, labels, options)
specs, labels, options = [], [], {}
@ -8436,7 +8457,7 @@ if __name__ == '__main__':
mode = 'single'
elif i + 1 < argc and arg in [ '-V', '--vcs-order' ]:
i += 1
diff.prefs.setString('vcs_search_order', unicode(args[i], sys.getfilesystemencoding()))
diff.prefs.setString('vcs_search_order', args[i])
diff.preferences_updated()
elif arg in [ '-b', '--ignore-space-change' ]:
diff.prefs.setBool('display_ignore_whitespace_changes', True)
@ -8460,7 +8481,7 @@ if __name__ == '__main__':
diff.preferences_updated()
elif i + 1 < argc and arg == '-L':
i += 1
labels.append(unicode(args[i], sys.getfilesystemencoding()))
labels.append(args[i])
elif i + 1 < argc and arg == '--line':
i += 1
try: