File searcher: group operations (#11980)

This commit is contained in:
hius07
2024-06-06 11:44:03 +03:00
committed by GitHub
parent 79c13bee0c
commit 585afda4be
3 changed files with 161 additions and 56 deletions

View File

@@ -125,6 +125,7 @@ end
function FileManager:setupLayout()
self.show_parent = self.show_parent or self
self.title_bar = TitleBar:new{
show_parent = self.show_parent,
fullscreen = "true",
align = "center",
title = self.title,
@@ -137,7 +138,7 @@ function FileManager:setupLayout()
left_icon_size_ratio = 1,
left_icon_tap_callback = function() self:goHome() end,
left_icon_hold_callback = function() self:onShowFolderMenu() end,
right_icon = "plus",
right_icon = self.selected_files and "check" or "plus",
right_icon_size_ratio = 1,
right_icon_tap_callback = function() self:onShowPlusMenu() end,
right_icon_hold_callback = false, -- propagate long-press to dispatcher
@@ -166,37 +167,31 @@ function FileManager:setupLayout()
local file_manager = self
function file_chooser:onPathChanged(path) -- luacheck: ignore
function file_chooser:onPathChanged(path)
file_manager:updateTitleBarPath(path)
return true
end
function file_chooser:onFileSelect(item) -- luacheck: ignore
local file = item.path
if file_manager.select_mode then
if file_manager.selected_files[file] then
file_manager.selected_files[file] = nil
item.dim = nil
else
file_manager.selected_files[file] = true
item.dim = true
end
function file_chooser:onFileSelect(item)
if file_manager.selected_files then -- toggle selection
item.dim = not item.dim and true or nil
file_manager.selected_files[item.path] = item.dim
self:updateItems()
else
file_manager:openFile(file)
file_manager:openFile(item.path)
end
return true
end
function file_chooser:onFileHold(item)
if file_manager.select_mode then
if file_manager.selected_files then
file_manager:tapPlus()
else
self:showFileDialog(item)
end
end
function file_chooser:showFileDialog(item) -- luacheck: ignore
function file_chooser:showFileDialog(item)
local file = item.path
local is_file = item.is_file
local is_not_parent_folder = not item.is_go_up
@@ -234,7 +229,7 @@ function FileManager:setupLayout()
text = _("Select"),
callback = function()
UIManager:close(self.file_dialog)
file_manager:onToggleSelectMode(true) -- no full screen refresh
file_manager:onToggleSelectMode()
if is_file then
file_manager.selected_files[file] = true
item.dim = true
@@ -381,7 +376,7 @@ function FileManager:registerKeyEvents()
-- Override the menu.lua way of handling the back key
self.file_chooser.key_events.Back = { { Device.input.group.Back } }
if Device:hasScreenKB() then
self.key_events.KeyToggleWifi = { { "ScreenKB", "Home" }, event = "ToggleWifi" }
self.key_events.ToggleWifi = { { "ScreenKB", "Home" } }
end
if not Device:hasFewKeys() then
-- Also remove the handler assigned to the "Back" key by menu.lua
@@ -495,14 +490,21 @@ function FileManager:onShowPlusMenu()
return true
end
function FileManager:onToggleSelectMode(no_refresh)
function FileManager:onToggleSelectMode(do_refresh)
logger.dbg("toggle select mode")
self.select_mode = not self.select_mode
self.selected_files = self.select_mode and {} or nil
self.title_bar:setRightIcon(self.select_mode and "check" or "plus")
if not no_refresh then
self:onRefresh()
if self.selected_files then
self.selected_files = nil
self.title_bar:setRightIcon("plus")
if do_refresh then
self.file_chooser:refreshPath()
else
self.file_chooser:selectAllFilesInFolder(false) -- undim
end
else
self.selected_files = {}
self.title_bar:setRightIcon("check")
end
return true
end
function FileManager:tapPlus()
@@ -514,9 +516,9 @@ function FileManager:tapPlus()
end
local title, buttons
if self.select_mode then
if self.selected_files then
local function toggle_select_mode_callback()
self:onToggleSelectMode()
self:onToggleSelectMode(true)
end
local select_count = util.tableSize(self.selected_files)
local actions_enabled = select_count > 0
@@ -624,7 +626,7 @@ function FileManager:tapPlus()
text = _("Select files"),
callback = function()
UIManager:close(self.file_dialog)
self:onToggleSelectMode(true) -- no full screen refresh
self:onToggleSelectMode()
end,
},
},
@@ -722,7 +724,7 @@ function FileManager:tapPlus()
title = title,
title_align = "center",
buttons = buttons,
select_mode = self.select_mode, -- for coverbrowser
select_mode = self.selected_files and true or nil, -- for coverbrowser
}
UIManager:show(self.file_dialog)
end
@@ -746,9 +748,6 @@ function FileManager:reinit(path, focused_file)
-- looks unnecessary (cheap with classic mode, less cheap with
-- CoverBrowser plugin's cover image renderings)
-- self:onRefresh()
if self.select_mode then
self.title_bar:setRightIcon("check")
end
end
function FileManager:getCurrentDir()
@@ -989,7 +988,7 @@ function FileManager:pasteSelectedFiles(overwrite)
icon = "notice-warning",
})
else
self:onToggleSelectMode()
self:onToggleSelectMode(true)
end
end
@@ -1117,7 +1116,7 @@ function FileManager:deleteSelectedFiles()
icon = "notice-warning",
})
else
self:onToggleSelectMode()
self:onToggleSelectMode(true)
end
end
@@ -1208,7 +1207,7 @@ function FileManager:renameFile(file, basename, is_file)
end
--- @note: This is the *only* safe way to instantiate a new FileManager instance!
function FileManager:showFiles(path, focused_file)
function FileManager:showFiles(path, focused_file, selected_files)
-- Warn about and close any pre-existing FM instances first...
if FileManager.instance then
logger.warn("FileManager instance mismatch! Tried to spin up a new instance, while we still have an existing one:", tostring(FileManager.instance))
@@ -1224,6 +1223,7 @@ function FileManager:showFiles(path, focused_file)
covers_fullscreen = true, -- hint for UIManager:_repaint()
root_path = path,
focused_file = focused_file,
selected_files = selected_files,
}
UIManager:show(file_manager)
end
@@ -1348,6 +1348,7 @@ function FileManager:showSelectedFilesList()
item_table = selected_files,
is_borderless = true,
is_popout = false,
title_bar_fm_style = true,
truncate_left = true,
onMenuSelect = function(_, item)
UIManager:close(menu)

View File

@@ -97,14 +97,9 @@ function FileSearcher:onShowFileSearch(search_string)
end
function FileSearcher:doSearch()
local results
local dirs, files = self:getList()
-- If we have a FileChooser instance, use it, to be able to make use of its natsort cache
if self.ui.file_chooser then
results = self.ui.file_chooser:genItemTable(dirs, files)
else
results = FileChooser:genItemTable(dirs, files)
end
local results = (self.ui.file_chooser or FileChooser):genItemTable(dirs, files)
if #results > 0 then
self:showSearchResults(results)
else
@@ -221,31 +216,51 @@ end
function FileSearcher:showSearchResults(results)
self.search_menu = Menu:new{
title = T(_("Search results (%1)"), #results),
subtitle = T(_("Query: %1"), self.search_string),
item_table = results,
ui = self.ui,
covers_fullscreen = true, -- hint for UIManager:_repaint()
is_borderless = true,
is_popout = false,
title_bar_fm_style = true,
title_bar_left_icon = "appbar.menu",
onLeftButtonTap = function() self:setSelectMode() end,
onMenuSelect = self.onMenuSelect,
onMenuHold = self.onMenuHold,
handle_hold_on_hold_release = true,
ui = self.ui,
_manager = self,
}
self.search_menu.close_callback = function()
self.selected_files = nil
UIManager:close(self.search_menu)
if self.ui.file_chooser then
self.ui.file_chooser:refreshPath()
end
end
self:updateMenu(results)
UIManager:show(self.search_menu)
if self.no_metadata_count ~= 0 then
self:showSearchResultsMessage()
end
end
function FileSearcher:updateMenu(item_table)
item_table = item_table or self.search_menu.item_table
self.search_menu:switchItemTable(T(_("Search results (%1)"), #item_table), item_table, -1)
end
function FileSearcher:onMenuSelect(item)
if self._manager.selected_files then
if item.is_file then
item.dim = not item.dim and true or nil
self._manager.selected_files[item.path] = item.dim
self._manager:updateMenu()
end
else
self._manager:showFileDialog(item)
end
end
function FileSearcher:showFileDialog(item)
local file = item.path
local bookinfo, dialog
local function close_dialog_callback()
@@ -253,7 +268,11 @@ function FileSearcher:onMenuSelect(item)
end
local function close_dialog_menu_callback()
UIManager:close(dialog)
self.close_callback()
self.search_menu.close_callback()
end
local function update_item_callback()
item.mandatory = FileChooser:getMenuItemMandatory(item, FileChooser:getCollate())
self:updateMenu()
end
local buttons = {}
if item.is_file then
@@ -265,7 +284,7 @@ function FileSearcher:onMenuSelect(item)
table.insert(buttons, {}) -- separator
table.insert(buttons, {
filemanagerutil.genResetSettingsButton(file, close_dialog_callback, is_currently_opened),
self.ui.collections:genAddToCollectionButton(file, close_dialog_callback),
self.ui.collections:genAddToCollectionButton(file, close_dialog_callback, update_item_callback),
})
end
table.insert(buttons, {
@@ -275,13 +294,8 @@ function FileSearcher:onMenuSelect(item)
callback = function()
local function post_delete_callback()
UIManager:close(dialog)
for i, menu_item in ipairs(self.item_table) do
if menu_item.path == file then
table.remove(self.item_table, i)
break
end
self:switchItemTable(T(_("Search results (%1)"), #self.item_table), self.item_table)
end
table.remove(self.search_menu.item_table, item.idx)
self:updateMenu()
end
local FileManager = require("apps/filemanager/filemanager")
FileManager:showDeleteFileDialog(file, post_delete_callback)
@@ -296,9 +310,9 @@ function FileSearcher:onMenuSelect(item)
text = _("Open"),
enabled = DocumentRegistry:hasProvider(file, nil, true), -- allow auxiliary providers
callback = function()
close_dialog_callback()
close_dialog_menu_callback()
local FileManager = require("apps/filemanager/filemanager")
FileManager.openFile(self.ui, file, nil, self.close_callback)
FileManager.openFile(self.ui, file)
end,
},
})
@@ -319,10 +333,12 @@ function FileSearcher:onMenuSelect(item)
end
function FileSearcher:onMenuHold(item)
if self._manager.selected_files then return true end
if item.is_file then
if DocumentRegistry:hasProvider(item.path, nil, true) then
self.close_callback()
local FileManager = require("apps/filemanager/filemanager")
FileManager.openFile(self.ui, item.path, nil, self.close_callback)
FileManager.openFile(self.ui, item.path)
end
else
self.close_callback()
@@ -337,4 +353,92 @@ function FileSearcher:onMenuHold(item)
return true
end
function FileSearcher:setSelectMode()
if self.selected_files then
self:showSelectModeDialog()
else
self.selected_files = {}
self.search_menu:setTitleBarLeftIcon("check")
end
end
function FileSearcher:showSelectModeDialog()
local item_table = self.search_menu.item_table
local select_count = util.tableSize(self.selected_files)
local actions_enabled = select_count > 0
local title = actions_enabled and T(N_("1 file selected", "%1 files selected", select_count), select_count)
or _("No files selected")
local select_dialog
local buttons = {
{
{
text = _("Deselect all"),
enabled = actions_enabled,
callback = function()
UIManager:close(select_dialog)
for file in pairs (self.selected_files) do
self.selected_files[file] = nil
end
for _, item in ipairs(item_table) do
item.dim = nil
end
self:updateMenu()
end,
},
{
text = _("Select all"),
callback = function()
UIManager:close(select_dialog)
for _, item in ipairs(item_table) do
if item.is_file then
item.dim = true
self.selected_files[item.path] = true
end
end
self:updateMenu()
end,
},
},
{
{
text = _("Exit select mode"),
callback = function()
UIManager:close(select_dialog)
self.selected_files = nil
self.search_menu:setTitleBarLeftIcon("appbar.menu")
if actions_enabled then
for _, item in ipairs(item_table) do
item.dim = nil
end
end
self:updateMenu()
end,
},
{
text = _("Select in file browser"),
enabled = actions_enabled,
callback = function()
UIManager:close(select_dialog)
local selected_files = self.selected_files
self.search_menu.close_callback()
if self.ui.file_chooser then
self.ui.selected_files = selected_files
self.ui.title_bar:setRightIcon("check")
self.ui.file_chooser:refreshPath()
else -- called from Reader
self.ui:onClose()
self.ui:showFileManager(self.path .. "/", selected_files)
end
end,
},
},
}
select_dialog = ButtonDialog:new{
title = title,
title_align = "center",
buttons = buttons,
}
UIManager:show(select_dialog)
end
return FileSearcher

View File

@@ -563,7 +563,7 @@ function ReaderUI:getLastDirFile(to_file_browser)
return last_dir, last_file
end
function ReaderUI:showFileManager(file)
function ReaderUI:showFileManager(file, selected_files)
local FileManager = require("apps/filemanager/filemanager")
local last_dir, last_file
@@ -576,7 +576,7 @@ function ReaderUI:showFileManager(file)
if FileManager.instance then
FileManager.instance:reinit(last_dir, last_file)
else
FileManager:showFiles(last_dir, last_file)
FileManager:showFiles(last_dir, last_file, selected_files)
end
end