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:
parent
4d54a00041
commit
18328c98c3
|
@ -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:
|
||||
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.fill()
|
||||
#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, 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.stroke()
|
||||
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, 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:
|
||||
|
|
Loading…
Reference in New Issue