From e031599c0a14c5fd6efc174d9ce431d32c57cb55 Mon Sep 17 00:00:00 2001 From: Hans-Werner Hilse Date: Sun, 16 Nov 2014 19:10:37 +0100 Subject: [PATCH 1/2] fix strcoll() workaround The strcoll() workaround we had in place for Kobo devices was (or has become) ineffective. We had set self.strcoll to nil on Kobo devices - but this was the instance variable. Setting it to nil effectively makes the instance variable vanish, so when trying to access it later, it was not there and got looked up via the metatable - which had the original reference. Setting it to nil had no effect whatsoever. We simplify that approach and set the replacement function where before we had set this to nil. This is a partial fix for issue #1183 (and explains a comment in issue #686 which says that the old fix did not work). However, to really fix #1183 - if we want to do so - we would need a collate function that normalizes uppercase/lowercase before compare. --- frontend/ui/widget/filechooser.lua | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/frontend/ui/widget/filechooser.lua b/frontend/ui/widget/filechooser.lua index 386c4d2e4..c68258001 100644 --- a/frontend/ui/widget/filechooser.lua +++ b/frontend/ui/widget/filechooser.lua @@ -8,12 +8,12 @@ local DEBUG = require("dbg") local _ = require("gettext") local ffi = require("ffi") ffi.cdef[[ -int strcoll (char *str1, char *str2); +int strcoll (const char *str1, const char *str2); ]] -- string sort function respecting LC_COLLATE local function strcoll(str1, str2) - return ffi.C.strcoll(ffi.cast("char*", str1), ffi.cast("char*", str2)) <= 0 + return ffi.C.strcoll(str1, str2) < 0 end local FileChooser = Menu:extend{ @@ -38,8 +38,10 @@ function FileChooser:init() end return true end - -- disable string collating in Kobo devices. See issue koreader/koreader#686 - if Device:isKobo() then self.strcoll = nil end + -- circumvent string collating in Kobo devices. See issue koreader/koreader#686 + if Device:isKobo() then + self.strcoll = function(a, b) return a < b end + end self.item_table = self:genItemTableFromPath(self.path) Menu.init(self) -- call parent's init() end @@ -71,11 +73,9 @@ function FileChooser:genItemTableFromPath(path) local sorting = nil local reverse = self.reverse_collate if self.collate == "strcoll" then - sorting = self.strcoll and function(a, b) - return self.strcoll(a.name, b.name) == not reverse - end or function(a, b) - return (a.name < b.name) == not reverse - end + sorting = function(a, b) + return self.strcoll(a.name, b.name) == not reverse + end elseif self.collate == "access" then sorting = function(a, b) if reverse then From 3d03713cb13aa06f0db330da8a2f5dda50091a87 Mon Sep 17 00:00:00 2001 From: Hans-Werner Hilse Date: Sun, 16 Nov 2014 19:27:31 +0100 Subject: [PATCH 2/2] implement case-insensitive sort, make default and configurable This will convert any file name to lowercase before doing the comparison. Note that this will only work for ASCII character range, a full Unicode aware solution will be much more complicated. And in the end, file names are byte arrays, not character strings ;-) fixes #1183. --- defaults.lua | 6 ++++++ frontend/ui/widget/filechooser.lua | 10 ++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/defaults.lua b/defaults.lua index c2c290808..5bb771b53 100644 --- a/defaults.lua +++ b/defaults.lua @@ -155,6 +155,12 @@ DDICT_FONT_SIZE = 20 -- e.g. 2 changes the sensitivity by 1/2, 3 by 1/3 etc. FRONTLIGHT_SENSITIVITY_DECREASE = 2 +-- Normally, Koreader will present file lists sorted in case insensitive manner +-- when presenting an alphatically sorted list. So the Order is "A, b, C, d". +-- You can switch to a case sensitive sort ("A", "C", "b", "d") by disabling +-- insensitive sort +DALPHA_SORT_CASE_INSENSITIVE = true + -- Set a path to a folder that is filled by Calibre (must contain the file metadata.calibre) -- e.g. -- "/mnt/sd/.hidden" for Kobo with files in ".hidden" on the SD card diff --git a/frontend/ui/widget/filechooser.lua b/frontend/ui/widget/filechooser.lua index c68258001..d5bb80abc 100644 --- a/frontend/ui/widget/filechooser.lua +++ b/frontend/ui/widget/filechooser.lua @@ -73,8 +73,14 @@ function FileChooser:genItemTableFromPath(path) local sorting = nil local reverse = self.reverse_collate if self.collate == "strcoll" then - sorting = function(a, b) - return self.strcoll(a.name, b.name) == not reverse + if DALPHA_SORT_CASE_INSENSITIVE then + sorting = function(a, b) + return self.strcoll(string.lower(a.name), string.lower(b.name)) == not reverse + end + else + sorting = function(a, b) + return self.strcoll(a.name, b.name) == not reverse + end end elseif self.collate == "access" then sorting = function(a, b)