[meld] Fix some handling of unicode file names (closes bgo#168760, bgo#694099)
- From: Kai Willadsen <kaiw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [meld] Fix some handling of unicode file names (closes bgo#168760, bgo#694099)
- Date: Sat, 6 Apr 2013 20:35:54 +0000 (UTC)
commit 7a56fe43c241704813b2285a07f5d56b98162b23
Author: Kai Willadsen <kai willadsen gmail com>
Date: Sun Apr 7 06:26:06 2013 +1000
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).
meld/dirdiff.py | 12 +++++++++++-
meld/filediff.py | 19 ++++++++++++-------
meld/newdifftab.py | 1 +
meld/tree.py | 5 ++++-
meld/vcview.py | 2 +-
5 files changed, 29 insertions(+), 10 deletions(-)
---
diff --git a/meld/dirdiff.py b/meld/dirdiff.py
index e5b022e..c6a5b69 100644
--- a/meld/dirdiff.py
+++ b/meld/dirdiff.py
@@ -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))
diff --git a/meld/filediff.py b/meld/filediff.py
index 49e2aa7..3b73530 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -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
diff --git a/meld/newdifftab.py b/meld/newdifftab.py
index 2e4efd3..a1f5ad1 100644
--- a/meld/newdifftab.py
+++ b/meld/newdifftab.py
@@ -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)
diff --git a/meld/tree.py b/meld/tree.py
index dc8c0b9..2962908 100644
--- a/meld/tree.py
+++ b/meld/tree.py
@@ -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
diff --git a/meld/vcview.py b/meld/vcview.py
index 89cf9ae..f0044e1 100644
--- a/meld/vcview.py
+++ b/meld/vcview.py
@@ -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:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]