diff --git a/frontend/apps/filemanager/filemanagercollection.lua b/frontend/apps/filemanager/filemanagercollection.lua index 814582579..5c01762f4 100644 --- a/frontend/apps/filemanager/filemanagercollection.lua +++ b/frontend/apps/filemanager/filemanagercollection.lua @@ -1,5 +1,6 @@ local BD = require("ui/bidi") local ButtonDialog = require("ui/widget/buttondialog") +local CheckButton = require("ui/widget/checkbutton") local ConfirmBox = require("ui/widget/confirmbox") local Device = require("device") local DocSettings = require("docsettings") @@ -70,6 +71,7 @@ function FileManagerCollection:onShowColl(collection_name) title_bar_left_icon = "appbar.menu", onLeftButtonTap = function() self:showCollDialog() end, onReturn = function() + self.from_collection_name = collection_name self.coll_menu.close_callback() self:onShowCollList() end, @@ -353,7 +355,7 @@ function FileManagerCollection:updateCollListItemTable(do_init, item_number) item_table = self.coll_list.item_table end local title = T(_("Collections (%1)"), #item_table) - local subtitle + local itemmatch, subtitle if self.selected_collections then local selected_nb = util.tableSize(self.selected_collections) subtitle = self.selected_collections and T(_("Selected: %1"), selected_nb) @@ -365,8 +367,12 @@ function FileManagerCollection:updateCollListItemTable(do_init, item_number) end end end + elseif self.from_collection_name ~= nil then + itemmatch = { text = self.from_collection_name } + self.coll_list.path = true -- draw focus + self.from_collection_name = nil end - self.coll_list:switchItemTable(title, item_table, item_number or -1, nil, subtitle) + self.coll_list:switchItemTable(title, item_table, item_number or -1, itemmatch, subtitle) end function FileManagerCollection:onCollListChoice(item) @@ -484,6 +490,16 @@ function FileManagerCollection:showCollListDialog(caller_callback, no_dialog) end, }, }, + {}, + { + { + text = _("Collections search"), + callback = function() + UIManager:close(button_dialog) + self:onShowCollectionsSearchDialog() + end, + }, + }, } end button_dialog = ButtonDialog:new{ @@ -584,6 +600,120 @@ function FileManagerCollection:sortCollections() UIManager:show(sort_widget) end +function FileManagerCollection:onShowCollectionsSearchDialog(search_str) + local search_dialog, check_button_case + search_dialog = InputDialog:new{ + title = _("Enter text to search for"), + input = search_str or self.search_str, + buttons = { + { + { + text = _("Cancel"), + id = "close", + callback = function() + UIManager:close(search_dialog) + end, + }, + { + text = _("Search"), + callback = function() + local str = search_dialog:getInputText() + UIManager:close(search_dialog) + if str ~= "" then + self.search_str = str + self.case_sensitive = check_button_case.checked + local Trapper = require("ui/trapper") + Trapper:wrap(function() + self:searchCollections() + end) + end + end, + }, + }, + }, + } + check_button_case = CheckButton:new{ + text = _("Case sensitive"), + checked = self.case_sensitive, + parent = search_dialog, + } + search_dialog:addWidget(check_button_case) + UIManager:show(search_dialog) + search_dialog:onShowKeyboard() + return true +end + +function FileManagerCollection:searchCollections() + local function isFileMatch(file) + if self.search_str == "*" then + return true + end + if util.stringSearch(file:gsub(".*/", ""), self.search_str, self.case_sensitive) ~= 0 then + return true + end + local book_props = self.ui.coverbrowser and self.ui.coverbrowser:getBookInfo(file) or + self.ui.bookinfo.getDocProps(file, nil, true) -- do not open the document + if next(book_props) ~= nil and self.ui.bookinfo:findInProps(book_props, self.search_str, self.case_sensitive) then + return true + end + end + + local Trapper = require("ui/trapper") + local info = InfoMessage:new{ text = _("Searching… (tap to cancel)") } + UIManager:show(info) + UIManager:forceRePaint() + local completed, files_found, files_found_order = Trapper:dismissableRunInSubprocess(function() + local _files_found, _files_found_order = {}, {} + for coll_name, coll in pairs(ReadCollection.coll) do + local coll_order = ReadCollection.coll_order[coll_name] + for _, item in pairs(coll) do + if isFileMatch(item.file) then + local order_idx = _files_found[item.file] + if order_idx == nil then -- new + table.insert(_files_found_order, { + file = item.file, + coll_order = coll_order, + item_order = item.order, + }) + _files_found[item.file] = #_files_found_order -- order_idx + else -- previously found, update orders + if _files_found_order[order_idx].coll_order > coll_order then + _files_found_order[order_idx].coll_order = coll_order + _files_found_order[order_idx].item_order = item.order + end + end + end + end + end + return _files_found, _files_found_order + end, info) + if not completed then return end + UIManager:close(info) + + if #files_found_order == 0 then + UIManager:show(InfoMessage:new{ + text = T(_("No results for: %1"), self.search_str), + }) + else + table.sort(files_found_order, function(a, b) + if a.coll_order ~= b.coll_order then + return a.coll_order < b.coll_order + end + return a.item_order < b.item_order + end) + local coll_name = T(_("Search results: %1"), self.search_str) + ReadCollection:removeCollection(coll_name, true) + ReadCollection:addCollection(coll_name, true) + ReadCollection:addItemsMultiple(files_found, { [coll_name] = true }, true) + ReadCollection:updateCollectionOrder(coll_name, files_found_order) + if self.coll_list ~= nil then + UIManager:close(self.coll_list) + self.coll_list = nil + end + self:onShowColl(coll_name) + end +end + -- external function FileManagerCollection:genAddToCollectionButton(file_or_files, caller_pre_callback, caller_post_callback, button_disabled) diff --git a/frontend/dispatcher.lua b/frontend/dispatcher.lua index a66ad18fe..13aa7ef24 100644 --- a/frontend/dispatcher.lua +++ b/frontend/dispatcher.lua @@ -50,20 +50,21 @@ local Dispatcher = { -- See above for description. local settingsList = { -- General + filemanager = {category="none", event="Home", title=_("File browser"), general=true}, reading_progress = {category="none", event="ShowReaderProgress", title=_("Reading progress"), general=true}, open_previous_document = {category="none", event="OpenLastDoc", title=_("Open previous document"), general=true}, history = {category="none", event="ShowHist", title=_("History"), general=true}, history_search = {category="none", event="SearchHistory", title=_("History search"), general=true}, favorites = {category="none", event="ShowColl", title=_("Favorites"), general=true}, collections = {category="none", event="ShowCollList", title=_("Collections"), general=true}, - filemanager = {category="none", event="Home", title=_("File browser"), general=true}, - notebook_file = {category="none", event="ShowNotebookFile", title=_("Notebook file"), general=true, separator=true}, + collections_search = {category="none", event="ShowCollectionsSearchDialog", title=_("Collections search"), general=true, separator=true}, ---- dictionary_lookup = {category="none", event="ShowDictionaryLookup", title=_("Dictionary lookup"), general=true}, wikipedia_lookup = {category="none", event="ShowWikipediaLookup", title=_("Wikipedia lookup"), general=true, separator=true}, ---- show_menu = {category="none", event="ShowMenu", title=_("Show menu"), general=true}, menu_search = {category="none", event="MenuSearch", title=_("Menu search"), general=true}, + notebook_file = {category="none", event="ShowNotebookFile", title=_("Notebook file"), general=true}, screenshot = {category="none", event="Screenshot", title=_("Screenshot"), general=true, separator=true}, ---- @@ -283,20 +284,21 @@ local settingsList = { -- array for item order in menu local dispatcher_menu_order = { -- General + "filemanager", "reading_progress", "open_previous_document", "history", "history_search", "favorites", "collections", - "filemanager", - "notebook_file", + "collections_search", ---- "dictionary_lookup", "wikipedia_lookup", ---- "show_menu", "menu_search", + "notebook_file", "screenshot", ---- diff --git a/frontend/readcollection.lua b/frontend/readcollection.lua index 047fb1c39..5e34258d8 100644 --- a/frontend/readcollection.lua +++ b/frontend/readcollection.lua @@ -145,7 +145,7 @@ function ReadCollection:addRemoveItemMultiple(file, collections_to_add) self:write() end -function ReadCollection:addItemsMultiple(files, collections_to_add) +function ReadCollection:addItemsMultiple(files, collections_to_add, no_write) for file in pairs(files) do file = FFIUtil.realpath(file) or file for coll_name in pairs(collections_to_add) do @@ -156,7 +156,9 @@ function ReadCollection:addItemsMultiple(files, collections_to_add) end end end - self:write() + if not no_write then + self:write() + end end function ReadCollection:removeItem(file, collection_name, no_write) -- FM: delete file; FMColl: remove file @@ -288,7 +290,7 @@ end -- manage collections -function ReadCollection:addCollection(coll_name) +function ReadCollection:addCollection(coll_name, no_write) local max_order = 0 for _, order in pairs(self.coll_order) do if max_order < order then @@ -297,7 +299,9 @@ function ReadCollection:addCollection(coll_name) end self.coll_order[coll_name] = max_order + 1 self.coll[coll_name] = {} - self:write(coll_name) + if not no_write then + self:write() + end end function ReadCollection:renameCollection(coll_name, new_name) @@ -308,10 +312,12 @@ function ReadCollection:renameCollection(coll_name, new_name) self:write(new_name) end -function ReadCollection:removeCollection(coll_name) +function ReadCollection:removeCollection(coll_name, no_write) self.coll_order[coll_name] = nil self.coll[coll_name] = nil - self:write() + if not no_write then + self:write() + end end function ReadCollection:updateCollectionListOrder(ordered_coll)