mirror of
https://github.com/koreader/koreader
synced 2024-10-31 21:20:20 +00:00
525b1957b9
* Menu/KeyValuePage/ReaderGoTo: Unify the dialogs. (Generally, "Enter page number" as title, and "Go to page" as OK button). * Allow *tapping* on pagination buttons, too. Added spacers around the text to accommodate for that. * Disable input handlers when <= 1 pages, while still printing the label in black. * Always display both the label and the chevrons, even on single page content. (Menu being an exception, because it can handle showing no content at all, in which case we hide the chevrons). * KVP: Tweak the pagination buttons layout in order to have consistent centering, regardless of whether the return arrow is enabled or not. (Also, match Menu's layout, more or less). * Menu: Minor layout tweaks to follow the KVP tweaks above. Fixes, among possibly other things, buttons in (non-FM) "List" menus overlapping the final entry (e.g., OPDS), and popout menus with a border being misaligned (e.g., Calibre, Find a file). * CalendarView: Minor layout tweaks to follow the KVP tweaks. Ensures the pagination buttons are laid out in the same way as everywhere else (they used to be a wee bit higher).
186 lines
6.9 KiB
Lua
186 lines
6.9 KiB
Lua
local CenterContainer = require("ui/widget/container/centercontainer")
|
|
local DocumentRegistry = require("document/documentregistry")
|
|
local Font = require("ui/font")
|
|
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 lfs = require("libs/libkoreader-lfs")
|
|
local BaseUtil = require("ffi/util")
|
|
local util = require("util")
|
|
local _ = require("gettext")
|
|
local Screen = require("device").screen
|
|
|
|
local FileSearcher = InputContainer:new{
|
|
search_dialog = nil,
|
|
|
|
--filesearcher
|
|
-- state buffer
|
|
dirs = {},
|
|
files = {},
|
|
results = {},
|
|
items = 0,
|
|
commands = nil,
|
|
|
|
--filemanagersearch
|
|
use_previous_search_results = false,
|
|
lastsearch = nil,
|
|
}
|
|
|
|
function FileSearcher:readDir()
|
|
self.dirs = {self.path}
|
|
self.files = {}
|
|
while #self.dirs ~= 0 do
|
|
local new_dirs = {}
|
|
-- handle each dir
|
|
for __, d in pairs(self.dirs) do
|
|
-- handle files in d
|
|
for f in lfs.dir(d) do
|
|
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
|
|
table.insert(new_dirs, fullpath)
|
|
table.insert(self.files, {name = f, path = fullpath, attr = attributes})
|
|
-- Always ignore macOS resource forks, too.
|
|
elseif attributes.mode == "file" and not util.stringStartsWith(f, "._") and DocumentRegistry:hasProvider(fullpath) then
|
|
table.insert(self.files, {name = f, path = fullpath, attr = attributes})
|
|
end
|
|
end
|
|
end
|
|
self.dirs = new_dirs
|
|
end
|
|
end
|
|
|
|
function FileSearcher:setSearchResults()
|
|
local FileManager = require("apps/filemanager/filemanager")
|
|
local ReaderUI = require("apps/reader/readerui")
|
|
local keywords = self.search_value
|
|
self.results = {}
|
|
if keywords == " " then -- one space to show all files
|
|
self.results = self.files
|
|
else
|
|
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
|
|
if f.attr.mode == "directory" then
|
|
f.text = f.name.."/"
|
|
f.name = nil
|
|
f.callback = function()
|
|
FileManager:showFiles(f.path)
|
|
end
|
|
table.insert(self.results, f)
|
|
else
|
|
f.text = f.name
|
|
f.name = nil
|
|
f.callback = function()
|
|
ReaderUI:showReader(f.path)
|
|
end
|
|
table.insert(self.results, f)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
self.keywords = keywords
|
|
self.items = #self.results
|
|
end
|
|
|
|
function FileSearcher:close()
|
|
if self.search_value then
|
|
UIManager:close(self.search_dialog)
|
|
if string.len(self.search_value) > 0 then
|
|
self:readDir() --- @todo this probably doesn't need to be repeated once it's been done
|
|
self:setSearchResults() --- @todo doesn't have to be repeated if the search term is the same
|
|
if #self.results > 0 then
|
|
self:showSearchResults() --- @todo something about no results
|
|
else
|
|
UIManager:show(
|
|
InfoMessage:new{
|
|
text = BaseUtil.template(_("Found no files matching '%1'."),
|
|
self.search_value)
|
|
}
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function FileSearcher:onShowFileSearch()
|
|
local dummy = self.search_value
|
|
local enabled_search_home_dir = true
|
|
if not G_reader_settings:readSetting("home_dir") then
|
|
enabled_search_home_dir = false
|
|
end
|
|
self.search_dialog = InputDialog:new{
|
|
title = _("Search for books by filename"),
|
|
input = self.search_value,
|
|
width = math.floor(Screen:getWidth() * 0.9),
|
|
buttons = {
|
|
{
|
|
{
|
|
text = _("Cancel"),
|
|
enabled = true,
|
|
callback = function()
|
|
self.search_dialog:onClose()
|
|
UIManager:close(self.search_dialog)
|
|
end,
|
|
},
|
|
{
|
|
text = _("Current folder"),
|
|
enabled = true,
|
|
callback = function()
|
|
self.path = self.ui.file_chooser and self.ui.file_chooser.path or self.ui:getLastDirFile()
|
|
self.search_value = self.search_dialog:getInputText()
|
|
if self.search_value == dummy then -- probably DELETE this if/else block
|
|
self.use_previous_search_results = true
|
|
else
|
|
self.use_previous_search_results = false
|
|
end
|
|
self:close()
|
|
end,
|
|
},
|
|
{
|
|
text = _("Home folder"),
|
|
enabled = enabled_search_home_dir,
|
|
callback = function()
|
|
self.path = G_reader_settings:readSetting("home_dir")
|
|
self.search_value = self.search_dialog:getInputText()
|
|
if self.search_value == dummy then -- probably DELETE this if/else block
|
|
self.use_previous_search_results = true
|
|
else
|
|
self.use_previous_search_results = false
|
|
end
|
|
self:close()
|
|
end,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
UIManager:show(self.search_dialog)
|
|
self.search_dialog:onShowKeyboard()
|
|
end
|
|
|
|
function FileSearcher:showSearchResults()
|
|
local menu_container = CenterContainer:new{
|
|
dimen = Screen:getSize(),
|
|
}
|
|
self.search_menu = Menu:new{
|
|
width = Screen:getWidth() - (Size.margin.fullscreen_popout * 2),
|
|
height = Screen:getHeight() - (Size.margin.fullscreen_popout * 2),
|
|
show_parent = menu_container,
|
|
onMenuHold = self.onMenuHold,
|
|
cface = Font:getFace("smallinfofont"),
|
|
_manager = self,
|
|
}
|
|
table.insert(menu_container, self.search_menu)
|
|
self.search_menu.close_callback = function()
|
|
UIManager:close(menu_container)
|
|
end
|
|
table.sort(self.results, function(v1,v2) return v1.text < v2.text end)
|
|
self.search_menu:switchItemTable(_("Search Results"), self.results)
|
|
UIManager:show(menu_container)
|
|
end
|
|
|
|
return FileSearcher
|