Commit 7a56fe43 authored by Kai Willadsen's avatar Kai Willadsen

Fix some handling of unicode file names (closes bgo#168760, bgo#694099)

While in theory we should be using encoding from the file system, this
turns out to usually be incorrect. Typically, the filenames we handle
have already passed through GTK+ (and are thus UTF-8) or have come
from Python, in which case if we pass unicode in, we get unicode out.

This patch basically takes these two factors into account and tries
to make sure we give Python's file system handling unicode objects and
decodes the UTF-8 we get from GTK+. This appears to work on both
Linux (which it already did, assuming a UTF-8 file system...) and on
Windows (UTF-16, probably).
parent 998563a3
......@@ -24,6 +24,7 @@ import os
import re
import shutil
import stat
import sys
import time
import gtk
......@@ -577,10 +578,18 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
def on_fileentry_activate(self, entry):
locs = [e.get_full_path() for e in self.fileentry[:self.num_panes]]
locs = [l.decode('utf8') for l in locs]
self.set_locations(locs)
def set_locations(self, locations):
self.set_num_panes(len(locations))
# This is difficult to trigger, and to test. Most of the time here we
# will actually have had UTF-8 from GTK, which has been unicode-ed by
# the time we get this far. This is a fallback, and may be wrong!
for i, l in enumerate(locations):
if not isinstance(l, unicode):
locations[i] = l.decode(sys.getfilesystemencoding())
# TODO: Support for blank folder comparisons should probably look here
locations = [os.path.abspath(l or ".") for l in locations]
self.current_path = None
self.model.clear()
......@@ -666,7 +675,8 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
for e in entries:
try:
e = e.decode('utf8')
if not isinstance(e, unicode):
e = e.decode('utf8')
except UnicodeDecodeError:
approximate_name = e.decode('utf8', 'replace')
encoding_errors.append((pane, approximate_name))
......
......@@ -992,13 +992,17 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
If an element is None, the text of a pane is left as is.
"""
self._disconnect_buffer_handlers()
for i,f in enumerate(files):
if f:
absfile = os.path.abspath(f)
self.fileentry[i].set_filename(absfile)
self.fileentry[i].prepend_history(absfile)
self.textbuffer[i].reset_buffer(absfile)
self.msgarea_mgr[i].clear()
for i, f in enumerate(files):
if not f:
continue
if not isinstance(f, unicode):
files[i] = f = f.decode('utf8')
absfile = os.path.abspath(f)
self.fileentry[i].set_filename(absfile)
self.fileentry[i].prepend_history(absfile)
self.textbuffer[i].reset_buffer(absfile)
self.msgarea_mgr[i].clear()
self.recompute_label()
self.textview[len(files) >= 2].grab_focus()
self._connect_buffer_handlers()
......@@ -1526,6 +1530,7 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
if self.check_save_modified() != gtk.RESPONSE_CANCEL:
entries = self.fileentry[:self.num_panes]
paths = [e.get_full_path() for e in entries]
paths = [p.decode('utf8') for p in paths]
self.set_files(paths)
return True
......
......@@ -109,6 +109,7 @@ class NewDiffTab(gobject.GObject, gnomeglade.Component):
for chooser in type_choosers[self.diff_type][:num_paths]:
gfile = chooser.get_file()
path = gfile.get_path() if gfile else ""
path = path.decode('utf8')
compare_paths.append(path)
tab = self.diff_methods[self.diff_type](compare_paths)
......
......@@ -104,7 +104,10 @@ class DiffTreeStore(gtk.TreeStore):
return [self.value_path(it, i) for i in range(self.ntree)]
def value_path(self, it, pane):
return self.get_value(it, self.column_index(COL_PATH, pane))
path = self.get_value(it, self.column_index(COL_PATH, pane))
if path is not None:
path = path.decode('utf8')
return path
def column_index(self, col, pane):
return self.ntree * col + pane
......
......@@ -868,7 +868,7 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
def treeview_search_cb(self, model, column, key, it):
"""Callback function for searching in VcView treeview"""
path = model.get_value(it, tree.COL_PATH)
path = model.value_path(it, 0)
# if query text contains slash, search in full path
if key.find('/') >= 0:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment