mirror of
https://github.com/koreader/koreader.git
synced 2025-12-13 20:36:53 +01:00
FileManager: allow case sensitive file search (#7956)
Bump base for cre.cpp cleanup and utf8proc FFI. Add a checkbutton for case sensitive search in FileBrowser, and use Utf8Proc.lowercase() for case insensitive search. Also use it in ReaderUserHyph as a replacement for crengine getLowercasedWord().
This commit is contained in:
2
base
2
base
Submodule base updated: dfa6f748a5...be4537e12d
@@ -1,12 +1,17 @@
|
||||
local CheckButton = require("ui/widget/checkbutton")
|
||||
local CenterContainer = require("ui/widget/container/centercontainer")
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local Font = require("ui/font")
|
||||
local HorizontalGroup = require("ui/widget/horizontalgroup")
|
||||
local HorizontalSpan = require("ui/widget/horizontalspan")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local InputContainer = require("ui/widget/container/inputcontainer")
|
||||
local InputDialog = require("ui/widget/inputdialog")
|
||||
local Menu = require("ui/widget/menu")
|
||||
local Size = require("ui/size")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local Utf8Proc = require("ffi/utf8proc")
|
||||
local VerticalGroup = require("ui/widget/verticalgroup")
|
||||
local lfs = require("libs/libkoreader-lfs")
|
||||
local BaseUtil = require("ffi/util")
|
||||
local util = require("util")
|
||||
@@ -73,9 +78,24 @@ function FileSearcher:setSearchResults()
|
||||
if keywords == "*" then -- one * to show all files
|
||||
self.results = self.files
|
||||
else
|
||||
if not self.case_sensitive then
|
||||
keywords = Utf8Proc.lowercase(keywords)
|
||||
end
|
||||
-- replace '.' with '%.'
|
||||
keywords = keywords:gsub("%.","%%%.")
|
||||
-- replace '*' with '.*'
|
||||
keywords = keywords:gsub("%*","%.%*")
|
||||
-- replace '?' with '.'
|
||||
keywords = keywords:gsub("%?","%.")
|
||||
for __,f in pairs(self.files) do
|
||||
if string.find(string.lower(f.name), string.lower(keywords)) and string.sub(f.name,-4) ~= ".sdr" then
|
||||
table.insert(self.results, f)
|
||||
if self.case_sensitive then
|
||||
if string.find(f.name, keywords) and string.sub(f.name,-4) ~= ".sdr" then
|
||||
table.insert(self.results, f)
|
||||
end
|
||||
else
|
||||
if string.find(Utf8Proc.lowercase(f.name), keywords) and string.sub(f.name,-4) ~= ".sdr" then
|
||||
table.insert(self.results, f)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -138,6 +158,35 @@ function FileSearcher:onShowFileSearch()
|
||||
},
|
||||
},
|
||||
}
|
||||
-- checkbox
|
||||
self.check_button_case = CheckButton:new{
|
||||
text = _("Case sensitive"),
|
||||
checked = self.case_sensitive,
|
||||
parent = self.search_dialog,
|
||||
callback = function()
|
||||
if not self.check_button_case.checked then
|
||||
self.check_button_case:check()
|
||||
self.case_sensitive = true
|
||||
else
|
||||
self.check_button_case:unCheck()
|
||||
self.case_sensitive = false
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
local checkbox_shift = math.floor((self.search_dialog.width - self.search_dialog._input_widget.width) / 2 + 0.5)
|
||||
local check_buttons = HorizontalGroup:new{
|
||||
HorizontalSpan:new{width = checkbox_shift},
|
||||
VerticalGroup:new{
|
||||
align = "left",
|
||||
self.check_button_case,
|
||||
},
|
||||
}
|
||||
|
||||
-- insert check buttons before the regular buttons
|
||||
local nb_elements = #self.search_dialog.dialog_frame[1]
|
||||
table.insert(self.search_dialog.dialog_frame[1], nb_elements-1, check_buttons)
|
||||
|
||||
UIManager:show(self.search_dialog)
|
||||
self.search_dialog:onShowKeyboard()
|
||||
end
|
||||
|
||||
@@ -662,8 +662,8 @@ To:
|
||||
text = _("File search"),
|
||||
help_text = _([[Search a book by filename in the current or home folder and its subfolders.
|
||||
|
||||
Wildcards for one '?' or more '*' characters can be used.
|
||||
A search for '*' will show all files.
|
||||
Search string supports Lua patterns.
|
||||
|
||||
Tap a book in the search results to open it.]]),
|
||||
callback = function()
|
||||
|
||||
@@ -4,6 +4,7 @@ local FFIUtil = require("ffi/util")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local InputDialog = require("ui/widget/inputdialog")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local Utf8Proc = require("ffi/utf8proc")
|
||||
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||
local lfs = require("libs/libkoreader-lfs")
|
||||
local logger = require("logger")
|
||||
@@ -29,7 +30,8 @@ end
|
||||
-- Unload is done automatically when a new dictionary is loaded.
|
||||
function ReaderUserHyph:loadDictionary(name, reload)
|
||||
if G_reader_settings:isTrue("hyph_user_dict") and lfs.attributes(name, "mode") == "file" then
|
||||
local ret = self.ui.document:setUserHyphenationDict(name, reload)
|
||||
logger.dbg("set user hyphenation dict", name, reload)
|
||||
local ret = cre.setUserHyphenationDict(name, reload)
|
||||
-- this should only happen, if a user edits a dictionary by hand or the user messed
|
||||
-- with the dictionary file by hand. -> Warning and disable.
|
||||
if ret == self.USER_DICT_ERROR_NOT_SORTED then
|
||||
@@ -45,7 +47,8 @@ function ReaderUserHyph:loadDictionary(name, reload)
|
||||
logger.warn("UserHyph: Dictionary " .. name .. " has corrupted entries.")
|
||||
end
|
||||
else
|
||||
self.ui.document:setUserHyphenationDict() -- clear crengine user hyph dict
|
||||
logger.dbg("reset user hyphenation dict")
|
||||
cre.setUserHyphenationDict("", true) -- clear crengine user hyph dict
|
||||
end
|
||||
end
|
||||
|
||||
@@ -101,7 +104,7 @@ function ReaderUserHyph:checkHyphenation(suggestion, word)
|
||||
end
|
||||
|
||||
suggestion = suggestion:gsub("-","")
|
||||
if self.ui.document:getLowercasedWord(suggestion) == self.ui.document:getLowercasedWord(word) then
|
||||
if Utf8Proc.lowercase(suggestion) == Utf8Proc.lowercase(word) then
|
||||
return true -- characters match (case insensitive)
|
||||
end
|
||||
return false
|
||||
@@ -117,22 +120,22 @@ function ReaderUserHyph:updateDictionary(word, hyphenation)
|
||||
return
|
||||
end
|
||||
|
||||
local word_lower = self.ui.document:getLowercasedWord(word)
|
||||
local word_lower = Utf8Proc.lowercase(word)
|
||||
local line
|
||||
|
||||
local dict = io.open(dict_file, "r")
|
||||
if dict then
|
||||
line = dict:read()
|
||||
--search entry
|
||||
while line and self.ui.document:getLowercasedWord(line:sub(1, line:find(";") - 1)) < word_lower do
|
||||
while line and Utf8Proc.lowercase(line:sub(1, line:find(";") - 1)) < word_lower do
|
||||
new_dict:write(line .. "\n")
|
||||
line = dict:read()
|
||||
end
|
||||
|
||||
-- last word = nil if EOF, else last_word=word if found in file, else last_word is word after the new entry
|
||||
if line then
|
||||
local last_word = self.ui.document:getLowercasedWord(line:sub(1, line:find(";") - 1))
|
||||
if last_word == self.ui.document:getLowercasedWord(word) then
|
||||
local last_word = Utf8Proc.lowercase(line:sub(1, line:find(";") - 1))
|
||||
if last_word == Utf8Proc.lowercase(word) then
|
||||
line = nil -- word found
|
||||
end
|
||||
else
|
||||
@@ -172,14 +175,14 @@ function ReaderUserHyph:modifyUserEntry(word)
|
||||
|
||||
if not self.ui.document then return end
|
||||
|
||||
local suggested_hyphenation = self.ui.document:getHyphenationForWord(word)
|
||||
local suggested_hyphenation = cre.getHyphenationForWord(word)
|
||||
|
||||
local input_dialog
|
||||
input_dialog = InputDialog:new{
|
||||
title = T(_("Hyphenate: %1"), word),
|
||||
description = _("Add hyphenation positions with hyphens ('-') or spaces (' ')."),
|
||||
input = suggested_hyphenation,
|
||||
old_hyph_lowercase = self.ui.document:getLowercasedWord(suggested_hyphenation),
|
||||
old_hyph_lowercase = Utf8Proc.lowercase(suggested_hyphenation),
|
||||
input_type = "string",
|
||||
buttons = {
|
||||
{
|
||||
@@ -207,7 +210,7 @@ function ReaderUserHyph:modifyUserEntry(word)
|
||||
|
||||
if self:checkHyphenation(new_suggestion, word) then
|
||||
-- don't save if no changes
|
||||
if self.ui.document:getLowercasedWord(new_suggestion) ~= input_dialog.old_hyph_lowercase then
|
||||
if Utf8Proc.lowercase(new_suggestion) ~= input_dialog.old_hyph_lowercase then
|
||||
self:updateDictionary(word, new_suggestion)
|
||||
end
|
||||
UIManager:close(input_dialog)
|
||||
|
||||
@@ -980,25 +980,6 @@ function CreDocument:setTextHyphenationSoftHyphensOnly(toggle)
|
||||
self._document:setStringProperty("crengine.textlang.hyphenation.soft.hyphens.only", toggle and 1 or 0)
|
||||
end
|
||||
|
||||
function CreDocument:setUserHyphenationDict(dict, reload)
|
||||
logger.dbg("CreDocument: set textlang hyphenation dict", dict or "none")
|
||||
return self._document:setUserHyphenationDict(dict or "", reload or false)
|
||||
end
|
||||
|
||||
function CreDocument:getHyphenationForWord(word)
|
||||
if word then
|
||||
return self._document:getHyphenationForWord(word)
|
||||
end
|
||||
return word
|
||||
end
|
||||
|
||||
function CreDocument:getLowercasedWord(word)
|
||||
if word then
|
||||
return self._document:getLowercasedWord(word)
|
||||
end
|
||||
return word
|
||||
end
|
||||
|
||||
function CreDocument:setTextHyphenationForceAlgorithmic(toggle)
|
||||
logger.dbg("CreDocument: set textlang hyphenation force algorithmic", toggle)
|
||||
self._document:setStringProperty("crengine.textlang.hyphenation.force.algorithmic", toggle and 1 or 0)
|
||||
|
||||
Reference in New Issue
Block a user