FileSearcher honor filemanagers sorting order (#7978)

pull/7989/head
zwim 3 years ago committed by GitHub
parent 38a2a46969
commit 48d1b23469
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1101,7 +1101,7 @@ function FileManager:getSortingMenuTable()
local fm = self
local collates = {
strcoll = {_("filename"), _("Sort by filename")},
numeric = {_("numeric"), _("Sort by filename (natural sorting)")},
natural = {_("natural"), _("Sort by filename (natural sorting)")},
strcoll_mixed = {_("name mixed"), _("Sort by name mixed files and folders")},
access = {_("date read"), _("Sort by last read date")},
change = {_("date added"), _("Sort by date added")},
@ -1137,7 +1137,7 @@ function FileManager:getSortingMenuTable()
end,
sub_item_table = {
set_collate_table("strcoll"),
set_collate_table("numeric"),
set_collate_table("natural"),
set_collate_table("strcoll_mixed"),
set_collate_table("access"),
set_collate_table("change"),

@ -1,6 +1,7 @@
local CheckButton = require("ui/widget/checkbutton")
local CenterContainer = require("ui/widget/container/centercontainer")
local DocumentRegistry = require("document/documentregistry")
local FileChooser = require("ui/widget/filechooser")
local Font = require("ui/font")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan")
@ -45,7 +46,10 @@ function FileSearcher:readDir()
local fullpath = d.."/"..f
local attributes = lfs.attributes(fullpath) or {}
-- Don't traverse hidden folders if we're not showing them
if attributes.mode == "directory" and f ~= "." and f ~= ".." and (G_reader_settings:isTrue("show_hidden") or not util.stringStartsWith(f, ".")) then
if attributes.mode == "directory" and f ~= "." and f ~= ".."
and (G_reader_settings:isTrue("show_hidden") or not util.stringStartsWith(f, "."))
and FileChooser:show_dir(f)
then
table.insert(new_dirs, fullpath)
table.insert(self.files, {
name = f,
@ -56,7 +60,10 @@ function FileSearcher:readDir()
end,
})
-- Always ignore macOS resource forks, too.
elseif attributes.mode == "file" and not util.stringStartsWith(f, "._") and (show_unsupported or DocumentRegistry:hasProvider(fullpath)) then
elseif attributes.mode == "file" and not util.stringStartsWith(f, "._")
and (show_unsupported or DocumentRegistry:hasProvider(fullpath))
and FileChooser:show_file(f)
then
table.insert(self.files, {
name = f,
text = f,
@ -79,7 +86,7 @@ function FileSearcher:setSearchResults()
self.results = self.files
else
if not self.case_sensitive then
keywords = Utf8Proc.lowercase(keywords)
keywords = Utf8Proc.lowercase(util.fixUtf8(keywords, "?"))
end
-- replace '.' with '%.'
keywords = keywords:gsub("%.","%%%.")
@ -89,11 +96,11 @@ function FileSearcher:setSearchResults()
keywords = keywords:gsub("%?","%.")
for __,f in pairs(self.files) do
if self.case_sensitive then
if string.find(f.name, keywords) and string.sub(f.name,-4) ~= ".sdr" then
if string.find(f.name, keywords) then
table.insert(self.results, f)
end
else
if string.find(Utf8Proc.lowercase(f.name), keywords) and string.sub(f.name,-4) ~= ".sdr" then
if string.find(Utf8Proc.lowercase(util.fixUtf8(f.name, "?")), keywords) then
table.insert(self.results, f)
end
end
@ -128,7 +135,6 @@ function FileSearcher:onShowFileSearch()
{
{
text = _("Cancel"),
enabled = true,
callback = function()
self.search_dialog:onClose()
UIManager:close(self.search_dialog)
@ -146,7 +152,6 @@ function FileSearcher:onShowFileSearch()
},
{
text = _("Current folder"),
enabled = true,
is_enter_default = true,
callback = function()
self.search_value = self.search_dialog:getInputText()
@ -207,7 +212,12 @@ function FileSearcher:showSearchResults()
self.search_menu.close_callback = function()
UIManager:close(menu_container)
end
table.sort(self.results, function(v1,v2) return v1.text < v2.text end)
local collate = G_reader_settings:readSetting("collate") or "strcoll"
local reverse_collate = G_reader_settings:isTrue("reverse_collate")
local sorting = FileChooser:getSortingFunction(collate, reverse_collate)
table.sort(self.results, sorting)
self.search_menu:switchItemTable(_("Search results"), self.results)
UIManager:show(menu_container)
end

@ -665,6 +665,8 @@ To:
Wildcards for one '?' or more '*' characters can be used.
A search for '*' will show all files.
The sorting order is the same as in filemanager.
Tap a book in the search results to open it.]]),
callback = function()
self.ui:handleEvent(Event:new("ShowFileSearch"))

@ -7,7 +7,7 @@ local lfs = require("libs/libkoreader-lfs")
local logger = require("logger")
-- Date at which the last migration snippet was added
local CURRENT_MIGRATION_DATE = 20210629
local CURRENT_MIGRATION_DATE = 20210715
-- Retrieve the date of the previous migration, if any
local last_migration_date = G_reader_settings:readSetting("last_migration_date", 0)
@ -275,5 +275,16 @@ if last_migration_date < 20210629 then
end
end
-- 20210715, Rename `numeric` to `natural`, https://github.com/koreader/koreader/pull/7978
if last_migration_date < 20210715 then
logger.info("Performing one-time migration for 20210715")
if G_reader_settings:has("collate") then
local collate = G_reader_settings:readSetting("collate")
if collate == "numeric" then
G_reader_settings:saveSetting("collate", "natural")
end
end
end
-- We're done, store the current migration date
G_reader_settings:saveSetting("last_migration_date", CURRENT_MIGRATION_DATE)

@ -74,22 +74,22 @@ local FileChooser = Menu:extend{
-- from readable /storage/emulated/0/ - so we know it contains "0/")
local unreadable_dir_content = {}
function FileChooser:init()
self.width = Screen:getWidth()
-- Standard dir exclusion list
self.show_dir = function(dirname)
for _, pattern in ipairs(self.exclude_dirs) do
if dirname:match(pattern) then return false end
end
return true
function FileChooser:show_dir(dirname)
for _, pattern in ipairs(self.exclude_dirs) do
if dirname:match(pattern) then return false end
end
-- Standard file exclusion list
self.show_file = function(filename)
for _, pattern in ipairs(self.exclude_files) do
if filename:match(pattern) then return false end
end
return true
return true
end
function FileChooser:show_file(filename)
for _, pattern in ipairs(self.exclude_files) do
if filename:match(pattern) then return false end
end
return true
end
function FileChooser:init()
self.width = Screen:getWidth()
self.list = function(path, dirs, files, count_only)
-- lfs.dir directory without permission will give error
local ok, iter, dir_obj = pcall(lfs.dir, path)
@ -99,8 +99,8 @@ function FileChooser:init()
if count_only then
if ((not self.show_hidden and not util.stringStartsWith(f, "."))
or (self.show_hidden and f ~= "." and f ~= ".." and not util.stringStartsWith(f, "._")))
and self.show_dir(f)
and self.show_file(f)
and self:show_dir(f)
and self:show_file(f)
then
table.insert(dirs, true)
end
@ -109,7 +109,7 @@ function FileChooser:init()
local attributes = lfs.attributes(filename)
if attributes ~= nil then
if attributes.mode == "directory" and f ~= "." and f ~= ".." then
if self.show_dir(f) then
if self:show_dir(f) then
table.insert(dirs, {name = f,
suffix = getFileNameSuffix(f),
fullpath = filename,
@ -117,7 +117,7 @@ function FileChooser:init()
end
-- Always ignore macOS resource forks.
elseif attributes.mode == "file" and not util.stringStartsWith(f, "._") then
if self.show_file(f) then
if self:show_file(f) then
if self.file_filter == nil or self.file_filter(filename) or self.show_unsupported then
local percent_finished = 0
if self.collate == "percent_unopened_first" or self.collate == "percent_unopened_last" then
@ -166,27 +166,21 @@ function FileChooser:init()
Menu.init(self) -- call parent's init()
end
function FileChooser:genItemTableFromPath(path)
local dirs = {}
local files = {}
local up_folder_arrow = BD.mirroredUILayout() and BD.ltr("../ ⬆") or "⬆ ../"
self.list(path, dirs, files)
function FileChooser:getSortingFunction(collate, reverse_collate)
local sorting
if self.collate == "strcoll" then
if collate == "strcoll" then
sorting = function(a, b)
return ffiUtil.strcoll(a.name, b.name)
end
elseif self.collate == "access" then
elseif collate == "access" then
sorting = function(a, b)
return a.attr.access > b.attr.access
end
elseif self.collate == "modification" then
elseif collate == "modification" then
sorting = function(a, b)
return a.attr.modification > b.attr.modification
end
elseif self.collate == "change" then
elseif collate == "change" then
sorting = function(a, b)
if DocSettings:hasSidecarFile(a.fullpath) and not DocSettings:hasSidecarFile(b.fullpath) then
return false
@ -196,11 +190,11 @@ function FileChooser:genItemTableFromPath(path)
end
return a.attr.change > b.attr.change
end
elseif self.collate == "size" then
elseif collate == "size" then
sorting = function(a, b)
return a.attr.size < b.attr.size
end
elseif self.collate == "type" then
elseif collate == "type" then
sorting = function(a, b)
if a.suffix == nil and b.suffix == nil then
return ffiUtil.strcoll(a.name, b.name)
@ -208,17 +202,17 @@ function FileChooser:genItemTableFromPath(path)
return ffiUtil.strcoll(a.suffix, b.suffix)
end
end
elseif self.collate == "percent_unopened_first" or self.collate == "percent_unopened_last" then
elseif collate == "percent_unopened_first" or collate == "percent_unopened_last" then
sorting = function(a, b)
if DocSettings:hasSidecarFile(a.fullpath) and not DocSettings:hasSidecarFile(b.fullpath) then
if self.collate == "percent_unopened_first" then
if collate == "percent_unopened_first" then
return false
else
return true
end
end
if not DocSettings:hasSidecarFile(a.fullpath) and DocSettings:hasSidecarFile(b.fullpath) then
if self.collate == "percent_unopened_first" then
if collate == "percent_unopened_first" then
return true
else
return false
@ -233,7 +227,7 @@ function FileChooser:genItemTableFromPath(path)
return a.percent_finished < b.percent_finished
end
elseif self.collate == "numeric" then
elseif collate == "natural" then
-- adapted from: http://notebook.kulchenko.com/algorithms/alphanumeric-natural-sorting-for-humans-in-lua
local function addLeadingZeroes(d)
local dec, n = string.match(d, "(%.?)0*(.+)")
@ -249,11 +243,23 @@ function FileChooser:genItemTableFromPath(path)
end
end
if self.reverse_collate then
if reverse_collate then
local sorting_unreversed = sorting
sorting = function(a, b) return sorting_unreversed(b, a) end
end
return sorting
end
function FileChooser:genItemTableFromPath(path)
local dirs = {}
local files = {}
local up_folder_arrow = BD.mirroredUILayout() and BD.ltr("../ ⬆") or "⬆ ../"
self.list(path, dirs, files)
local sorting = self:getSortingFunction(self.collate, self.reverse_collate)
if self.collate ~= "strcoll_mixed" then
table.sort(dirs, sorting)
table.sort(files, sorting)

Loading…
Cancel
Save