diff --git a/frontend/apps/filemanager/filemanager.lua b/frontend/apps/filemanager/filemanager.lua index 1f5986cb5..e0dfad963 100644 --- a/frontend/apps/filemanager/filemanager.lua +++ b/frontend/apps/filemanager/filemanager.lua @@ -148,6 +148,16 @@ function FileManager:toggleHiddenFiles() G_reader_settings:saveSetting("show_hidden", self.file_chooser.show_hidden) end +function FileManager:setCollate(collate) + self.file_chooser:setCollate(collate) + G_reader_settings:saveSetting("collate", self.file_chooser.collate) +end + +function FileManager:toggleReverseCollate() + self.file_chooser:toggleReverseCollate() + G_reader_settings:saveSetting("reverse_collate", self.file_chooser.reverse_collate) +end + function FileManager:onClose() DEBUG("close filemanager") UIManager:close(self) @@ -222,4 +232,31 @@ function FileManager:deleteFile(file) util.execute("/bin/rm", "-r", util.realpath(file)) end +local collates = { + strcoll = _("Title"), + access = _("Recent"), +} + +function FileManager:getSortingMenuTable() + local fm = self + local set_collate_table = function(collate) + return { + text = collates[collate], + checked_func = function() + return fm.file_chooser.collate == collate + end, + callback = function() fm:setCollate(collate) end, + } + end + return { + text_func = function() + return _("Sorting: ") .. collates[fm.file_chooser.collate] + end, + sub_item_table = { + set_collate_table("strcoll"), + set_collate_table("access"), + } + } +end + return FileManager diff --git a/frontend/apps/filemanager/filemanagermenu.lua b/frontend/apps/filemanager/filemanagermenu.lua index a53e1c958..06f399b5d 100644 --- a/frontend/apps/filemanager/filemanagermenu.lua +++ b/frontend/apps/filemanager/filemanagermenu.lua @@ -96,11 +96,15 @@ function FileManagerMenu:setUpdateItemTable() table.insert(self.tab_item_table.setting, { text = _("Show hidden files"), checked_func = function() return self.ui.file_chooser.show_hidden end, - callback = function() - self.ui:toggleHiddenFiles() - end + callback = function() self.ui:toggleHiddenFiles() end + }) + local FileManager = require("apps/filemanager/filemanager") + table.insert(self.tab_item_table.setting, self.ui:getSortingMenuTable()) + table.insert(self.tab_item_table.setting, { + text = _("Reverse sorting"), + checked_func = function() return self.ui.file_chooser.reverse_collate end, + callback = function() self.ui:toggleReverseCollate() end }) - table.insert(self.tab_item_table.setting, { text = _("Start with last opened file"), checked_func = function() return G_reader_settings:readSetting("open_last") end, diff --git a/frontend/ui/widget/filechooser.lua b/frontend/ui/widget/filechooser.lua index 1a2bde4d5..6a157cfe3 100644 --- a/frontend/ui/widget/filechooser.lua +++ b/frontend/ui/widget/filechooser.lua @@ -25,7 +25,9 @@ local FileChooser = Menu:extend{ show_hidden = nil, filter = function(filename) return true end, exclude_dirs = {"%.sdr$"}, - collate = strcoll, + strcoll = strcoll, + collate = "strcoll", -- or collate = "access", + reverse_collate = false, } function FileChooser:init() @@ -37,7 +39,7 @@ function FileChooser:init() return true end -- disable string collating in Kobo devices. See issue koreader/koreader#686 - if Device:isKobo() then self.collate = nil end + if Device:isKobo() then self.strcoll = nil end self.item_table = self:genItemTableFromPath(self.path) Menu.init(self) -- call parent's init() end @@ -52,26 +54,45 @@ function FileChooser:genItemTableFromPath(path) for f in iter, dir_obj do if self.show_hidden or not string.match(f, "^%.[^.]") then local filename = self.path.."/"..f - local filemode = lfs.attributes(filename, "mode") - if filemode == "directory" and f ~= "." and f~=".." then + local attributes = lfs.attributes(filename) + if attributes.mode == "directory" and f ~= "." and f~=".." then if self.dir_filter(filename) then - table.insert(dirs, f) + table.insert(dirs, {name = f, attr = attributes}) end - elseif filemode == "file" then + elseif attributes.mode == "file" then if self.file_filter(filename) then - table.insert(files, f) + table.insert(files, {name = f, attr = attributes}) end end end end end - table.sort(dirs, self.collate) - if path ~= "/" then table.insert(dirs, 1, "..") end - table.sort(files, self.collate) + + 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 + elseif self.collate == "access" then + sorting = function(a, b) + if reverse then + return a.attr.access < b.attr.access + else + return a.attr.access > b.attr.access + end + end + end + + table.sort(dirs, sorting) + if path ~= "/" then table.insert(dirs, 1, {name = ".."}) end + table.sort(files, sorting) local item_table = {} for i, dir in ipairs(dirs) do - local path = self.path.."/"..dir + local path = self.path.."/"..dir.name local items = 0 local ok, iter, dir_obj = pcall(lfs.dir, path) if ok then @@ -83,13 +104,13 @@ function FileChooser:genItemTableFromPath(path) end local istr = items .. (items > 1 and _(" items") or _(" item")) table.insert(item_table, { - text = dir.."/", + text = dir.name.."/", mandatory = istr, path = path }) end for _, file in ipairs(files) do - local full_path = self.path.."/"..file + local full_path = self.path.."/"..file.name local file_size = lfs.attributes(full_path, "size") or 0 local sstr = "" if file_size > 1024*1024 then @@ -100,7 +121,7 @@ function FileChooser:genItemTableFromPath(path) sstr = string.format("%d B", file_size) end table.insert(item_table, { - text = file, + text = file.name, mandatory = sstr, path = full_path }) @@ -133,6 +154,16 @@ function FileChooser:toggleHiddenFiles() self:refreshPath() end +function FileChooser:setCollate(collate) + self.collate = collate + self:refreshPath() +end + +function FileChooser:toggleReverseCollate() + self.reverse_collate = not self.reverse_collate + self:refreshPath() +end + function FileChooser:onMenuSelect(item) -- parent directory of dir without permission get nil mode -- we need to change to parent path in this case