From 726b15ad014a3b3a842e04649a968bf3bd22f18b Mon Sep 17 00:00:00 2001 From: Hzj_jie Date: Sat, 11 Feb 2017 18:55:31 -0800 Subject: [PATCH] More sorting orders in file manager (#2535) --- frontend/apps/filemanager/filemanager.lua | 14 +++- frontend/ui/widget/filechooser.lua | 86 ++++++++++++++++++----- frontend/util.lua | 5 ++ 3 files changed, 86 insertions(+), 19 deletions(-) diff --git a/frontend/apps/filemanager/filemanager.lua b/frontend/apps/filemanager/filemanager.lua index 29806c05c..9349efc32 100644 --- a/frontend/apps/filemanager/filemanager.lua +++ b/frontend/apps/filemanager/filemanager.lua @@ -475,8 +475,12 @@ end function FileManager:getSortingMenuTable() local fm = self local collates = { - strcoll = {_("by title"), _("Sort by title")}, - access = {_("by date"), _("Sort by date")}, + strcoll = {_("title"), _("Sort by title")}, + access = {_("date read"), _("Sort by date of last read")}, + change = {_("date added"), _("Sort by date of adding")}, + modification = {_("date modified"), _("Sort by date of modification")}, + size = {_("size"), _("Sort by size")}, + type = {_("type"), _("Sort by type")}, } local set_collate_table = function(collate) return { @@ -490,13 +494,17 @@ function FileManager:getSortingMenuTable() return { text_func = function() return util.template( - _("Sort order: %1"), + _("Sort by %1"), collates[fm.file_chooser.collate][1] ) end, sub_item_table = { set_collate_table("strcoll"), set_collate_table("access"), + set_collate_table("change"), + set_collate_table("modification"), + set_collate_table("size"), + set_collate_table("type"), } } end diff --git a/frontend/ui/widget/filechooser.lua b/frontend/ui/widget/filechooser.lua index 38caa5968..b95c89c20 100644 --- a/frontend/ui/widget/filechooser.lua +++ b/frontend/ui/widget/filechooser.lua @@ -7,6 +7,7 @@ local DocSettings = require("docsettings") local util = require("ffi/util") local _ = require("gettext") local ffi = require("ffi") +local getFileNameSuffix = require("util").getFileNameSuffix ffi.cdef[[ int strcoll (const char *str1, const char *str2); ]] @@ -16,13 +17,16 @@ local function strcoll(str1, str2) return ffi.C.strcoll(str1, str2) < 0 end +local function kobostrcoll(str1, str2) + return str1 < str2 +end + local FileChooser = Menu:extend{ no_title = true, path = lfs.currentdir(), parent = nil, show_hidden = nil, exclude_dirs = {"%.sdr$"}, - strcoll = strcoll, collate = "strcoll", -- or collate = "access", reverse_collate = false, path_items = {}, -- store last browsed location(item index) for each path @@ -48,11 +52,17 @@ function FileChooser:init() if attributes ~= nil then if attributes.mode == "directory" and f ~= "." and f~=".." then if self.dir_filter(filename) then - table.insert(dirs, {name = f, attr = attributes}) + table.insert(dirs, {name = f, + suffix = getFileNameSuffix(f), + fullpath = filename, + attr = attributes}) end elseif attributes.mode == "file" then if self.file_filter == nil or self.file_filter(filename) then - table.insert(files, {name = f, attr = attributes}) + table.insert(files, {name = f, + suffix = getFileNameSuffix(f), + fullpath = filename, + attr = attributes}) end end end @@ -61,9 +71,23 @@ function FileChooser:init() end end + local strcoll_func = strcoll -- circumvent string collating in Kobo devices. See issue koreader/koreader#686 if Device:isKobo() then - self.strcoll = function(a, b) return a < b end + strcoll_func = kobostrcoll + end + self.strcoll = function(a, b) + if a == nil and b == nil then + return false + elseif a == nil then + return true + elseif b == nil then + return false + elseif DALPHA_SORT_CASE_INSENSITIVE then + return strcoll_func(string.lower(a), string.lower(b)) + else + return strcoll_func(a, b) + end end self.item_table = self:genItemTableFromPath(self.path) Menu.init(self) -- call parent's init() @@ -75,26 +99,56 @@ function FileChooser:genItemTableFromPath(path) self.list(path, dirs, files) - local sorting = nil - local reverse = self.reverse_collate + local sorting if self.collate == "strcoll" then - if DALPHA_SORT_CASE_INSENSITIVE then - sorting = function(a, b) - return self.strcoll(string.lower(a.name), string.lower(b.name)) == not reverse + sorting = function(a, b) + return self.strcoll(a.name, b.name) + end + elseif self.collate == "access" then + sorting = function(a, b) + if DocSettings:hasSidecarFile(a.fullpath) and not DocSettings:hasSidecarFile(b.fullpath) then + return true end - else - sorting = function(a, b) - return self.strcoll(a.name, b.name) == not reverse + if not DocSettings:hasSidecarFile(a.fullpath) and DocSettings:hasSidecarFile(b.fullpath) then + return false end + return a.attr.access > b.attr.access end - elseif self.collate == "access" then + elseif self.collate == "modification" then + sorting = function(a, b) + return a.attr.modification > b.attr.modification + end + elseif self.collate == "change" then + sorting = function(a, b) + if DocSettings:hasSidecarFile(a.fullpath) and not DocSettings:hasSidecarFile(b.fullpath) then + return false + end + if not DocSettings:hasSidecarFile(a.fullpath) and DocSettings:hasSidecarFile(b.fullpath) then + return true + end + return a.attr.change > b.attr.change + end + elseif self.collate == "size" then + sorting = function(a, b) + return a.attr.size < b.attr.size + end + elseif self.collate == "type" then sorting = function(a, b) - if reverse then - return a.attr.access < b.attr.access + if a.suffix == nil and b.suffix == nil then + return self.strcoll(a.name, b.name) else - return a.attr.access > b.attr.access + return self.strcoll(a.suffix, b.suffix) end end + else + sorting = function(a, b) + return a.name < b.name + end + end + + if self.reverse_collate then + local sorting_unreversed = sorting + sorting = function(a, b) return sorting_unreversed(b, a) end end table.sort(dirs, sorting) diff --git a/frontend/util.lua b/frontend/util.lua index 93fa1cec7..6cf044b10 100644 --- a/frontend/util.lua +++ b/frontend/util.lua @@ -266,6 +266,11 @@ function util.splitFileNameSuffix(file) return string.gsub(file, "(.*)%.(.*)", "%1"), string.gsub(file, ".*%.", "") end +function util.getFileNameSuffix(file) + local _, suffix = util.splitFileNameSuffix(file) + return suffix +end + function util.getMenuText(item) local text if item.text_func then