diff --git a/frontend/apps/filemanager/filemanager.lua b/frontend/apps/filemanager/filemanager.lua index 65e46a16c..e66056e94 100644 --- a/frontend/apps/filemanager/filemanager.lua +++ b/frontend/apps/filemanager/filemanager.lua @@ -1,5 +1,6 @@ local BD = require("ui/bidi") local Blitbuffer = require("ffi/blitbuffer") +local ButtonDialog = require("ui/widget/buttondialog") local ButtonDialogTitle = require("ui/widget/buttondialogtitle") local CheckButton = require("ui/widget/checkbutton") local ConfirmBox = require("ui/widget/confirmbox") @@ -9,7 +10,6 @@ local DocSettings = require("docsettings") local DocumentRegistry = require("document/documentregistry") local Event = require("ui/event") local FileChooser = require("ui/widget/filechooser") -local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo") local FileManagerCollection = require("apps/filemanager/filemanagercollection") local FileManagerConverter = require("apps/filemanager/filemanagerconverter") local FileManagerFileSearcher = require("apps/filemanager/filemanagerfilesearcher") @@ -52,7 +52,6 @@ local FileManager = InputContainer:extend{ mv_bin = Device:isAndroid() and "/system/bin/mv" or "/bin/mv", cp_bin = Device:isAndroid() and "/system/bin/cp" or "/bin/cp", - mkdir_bin = Device:isAndroid() and "/system/bin/mkdir" or "/bin/mkdir", } function FileManager:onSetRotationMode(rotation) @@ -120,7 +119,7 @@ function FileManager:setupLayout() button_padding = Screen:scaleBySize(5), left_icon = "home", left_icon_size_ratio = 1, - left_icon_tap_callback = function() self:goHome() end, + left_icon_tap_callback = function() self:onShowFolderMenu() end, left_icon_hold_callback = false, -- propagate long-press to dispatcher right_icon = "plus", right_icon_size_ratio = 1, @@ -135,7 +134,6 @@ function FileManager:setupLayout() path = self.root_path, focused_path = self.focused_file, show_parent = self.show_parent, - width = Screen:getWidth(), height = Screen:getHeight() - self.title_bar:getHeight(), is_popout = false, is_borderless = true, @@ -254,6 +252,9 @@ function FileManager:setupLayout() } if is_file then + local function close_dialog_callback() + UIManager:close(self.file_dialog) + end local function status_button_callback() UIManager:close(self.file_dialog) self:refreshPath() -- sidecar folder may be created/deleted @@ -305,39 +306,15 @@ function FileManager:setupLayout() self:showSetProviderButtons(file, one_time_providers) end, }, - { - text = _("Book information"), - id = "book_information", -- used by covermenu - callback = function() - UIManager:close(self.file_dialog) - FileManagerBookInfo:show(file) - end, - }, + filemanagerutil.genBookInformationButton(file, close_dialog_callback), }) table.insert(buttons, { - { - text = _("Book cover"), - id = "book_cover", -- used by covermenu - callback = function() - UIManager:close(self.file_dialog) - FileManagerBookInfo:onShowBookCover(file) - end, - }, - { - text = _("Book description"), - id = "book_description", -- used by covermenu - callback = function() - UIManager:close(self.file_dialog) - FileManagerBookInfo:onShowBookDescription(nil, file) - end, - }, + filemanagerutil.genBookCoverButton(file, close_dialog_callback), + filemanagerutil.genBookDescriptionButton(file, close_dialog_callback), }) if Device:canExecuteScript(file) then - local function button_callback() - UIManager:close(self.file_dialog) - end table.insert(buttons, { - filemanagerutil.genExecuteScriptButton(file, button_callback) + filemanagerutil.genExecuteScriptButton(file, close_dialog_callback), }) end if FileManagerConverter:isSupported(file) then @@ -348,7 +325,7 @@ function FileManager:setupLayout() UIManager:close(self.file_dialog) FileManagerConverter:showConvertButtons(file, self) end, - } + }, }) end end @@ -361,7 +338,7 @@ function FileManager:setupLayout() UIManager:close(self.file_dialog) file_manager:setHome(BaseUtil.realpath(file)) end - } + }, }) end @@ -850,7 +827,7 @@ end function FileManager:openRandomFile(dir) local random_file = DocumentRegistry:getRandomFile(dir, false) if random_file then - UIManager:show(MultiConfirmBox:new { + UIManager:show(MultiConfirmBox:new{ text = T(_("Do you want to open %1?"), BD.filename(BaseUtil.basename(random_file))), choice1_text = _("Open"), choice1_callback = function() @@ -864,7 +841,7 @@ function FileManager:openRandomFile(dir) end, }) else - UIManager:show(InfoMessage:new { + UIManager:show(InfoMessage:new{ text = _("File not found"), }) end @@ -895,7 +872,7 @@ function FileManager:pasteHere(file) end return true else - UIManager:show(InfoMessage:new { + UIManager:show(InfoMessage:new{ text = T(_("Failed to copy:\n%1\nto:\n%2"), BD.filepath(orig_name), BD.dirpath(dest_path)), icon = "notice-warning", }) @@ -911,7 +888,7 @@ function FileManager:pasteHere(file) ReadCollection:updateItemByPath(orig_file, dest_file) return true else - UIManager:show(InfoMessage:new { + UIManager:show(InfoMessage:new{ text = T(_("Failed to move:\n%1\nto:\n%2"), BD.filepath(orig_name), BD.dirpath(dest_path)), icon = "notice-warning", }) @@ -928,7 +905,7 @@ function FileManager:pasteHere(file) local mode = lfs.attributes(dest_file, "mode") if mode then - UIManager:show(ConfirmBox:new { + UIManager:show(ConfirmBox:new{ text = mode == "file" and T(_("File already exists:\n%1\nOverwrite file?"), BD.filename(orig_name)) or T(_("Folder already exists:\n%1\nOverwrite folder?"), BD.directory(orig_name)), ok_text = _("Overwrite"), @@ -1099,7 +1076,7 @@ function FileManager:renameFile(file, basename, is_file) else text = T(_("File already exists:\n%1\nFolder cannot be renamed."), BD.filename(basename)) end - UIManager:show(InfoMessage:new { + UIManager:show(InfoMessage:new{ text = text, icon = "notice-warning", }) @@ -1111,7 +1088,7 @@ function FileManager:renameFile(file, basename, is_file) text = T(_("Folder already exists:\n%1\nMove the folder inside it?"), BD.directory(basename)) ok_text = _("Move") end - UIManager:show(ConfirmBox:new { + UIManager:show(ConfirmBox:new{ text = text, ok_text = ok_text, ok_callback = function() @@ -1201,4 +1178,70 @@ function FileManager:onRefreshContent() self:onRefresh() end +function FileManager:onShowFolderMenu() + local button_dialog + local function genButton(button_text, button_path) + return {{ + text = button_text, + align = "left", + font_face = "smallinfofont", + font_size = 22, + font_bold = false, + avoid_text_truncation = false, + callback = function() + UIManager:close(button_dialog) + self.file_chooser:changeToPath(button_path) + end, + hold_callback = function() + return true -- do not move the menu + end, + }} + end + + local home_dir = G_reader_settings:readSetting("home_dir") or filemanagerutil.getDefaultDir() + local home_dir_shortened = G_reader_settings:nilOrTrue("shorten_home_dir") + local home_dir_not_locked = G_reader_settings:nilOrFalse("lock_home_folder") + local home_dir_suffix = " (" .. _("Home") .. ")" + local buttons = {} + -- root folder + local text + local path = "/" + local is_home = path == home_dir + local home_found = is_home or home_dir_not_locked + if home_found then + text = path + if is_home and home_dir_shortened then + text = text .. home_dir_suffix + end + table.insert(buttons, genButton(text, path)) + end + -- other folders + local indent = "" + for part in self.file_chooser.path:gmatch("([^/]+)") do + text = (#buttons == 0 and path or indent .. "└ ") .. part + path = path .. part .. "/" + is_home = path == home_dir or path == home_dir .. "/" + if not home_found and is_home then + home_found = true + end + if home_found then + if is_home and home_dir_shortened then + text = text .. home_dir_suffix + end + table.insert(buttons, genButton(text, path)) + indent = indent .. " " + end + end + + button_dialog = ButtonDialog:new{ + width = math.floor(Screen:getWidth() * 0.9), + shrink_unneeded_width = true, + buttons = buttons, + anchor = function() + return self.title_bar.left_button.image.dimen + end, + } + UIManager:show(button_dialog) +end + return FileManager diff --git a/frontend/apps/filemanager/filemanagercollection.lua b/frontend/apps/filemanager/filemanagercollection.lua index 2d764ed11..d8b3b9e3f 100644 --- a/frontend/apps/filemanager/filemanagercollection.lua +++ b/frontend/apps/filemanager/filemanagercollection.lua @@ -1,6 +1,5 @@ local ButtonDialogTitle = require("ui/widget/buttondialogtitle") local Device = require("device") -local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo") local Menu = require("ui/widget/menu") local ReadCollection = require("readcollection") local UIManager = require("ui/uimanager") @@ -36,8 +35,15 @@ function FileManagerCollection:updateItemTable() ReadCollection:prepareList(self.coll_menu.collection), select_number) end +function FileManagerCollection:onMenuChoice(item) + require("apps/reader/readerui"):showReader(item.file) +end + function FileManagerCollection:onMenuHold(item) self.collfile_dialog = nil + local function close_dialog_callback() + UIManager:close(self.collfile_dialog) + end local function status_button_callback() UIManager:close(self.collfile_dialog) self._manager:updateItemTable() @@ -89,37 +95,17 @@ function FileManagerCollection:onMenuHold(item) UIManager:show(sort_item) end, }, - { - text = _("Book information"), - id = "book_information", -- used by covermenu - callback = function() - UIManager:close(self.collfile_dialog) - FileManagerBookInfo:show(item.file) - end, - }, + filemanagerutil.genBookInformationButton(item.file, close_dialog_callback, item.dim), }) table.insert(buttons, { - { - text = _("Book cover"), - id = "book_cover", -- used by covermenu - callback = function() - UIManager:close(self.collfile_dialog) - FileManagerBookInfo:onShowBookCover(item.file) - end, - }, - { - text = _("Book description"), - id = "book_description", -- used by covermenu - callback = function() - UIManager:close(self.collfile_dialog) - FileManagerBookInfo:onShowBookDescription(nil, item.file) - end, - }, + filemanagerutil.genBookCoverButton(item.file, close_dialog_callback, item.dim), + filemanagerutil.genBookDescriptionButton(item.file, close_dialog_callback, item.dim), }) if Device:canExecuteScript(item.file) then local function button_callback() UIManager:close(self.collfile_dialog) + self.coll_menu.close_callback() end table.insert(buttons, { filemanagerutil.genExecuteScriptButton(item.file, button_callback) @@ -153,11 +139,10 @@ end function FileManagerCollection:onShowColl(collection) self.coll_menu = Menu:new{ ui = self.ui, - width = Screen:getWidth(), - height = Screen:getHeight(), covers_fullscreen = true, -- hint for UIManager:_repaint() is_borderless = true, is_popout = false, + onMenuChoice = self.onMenuChoice, onMenuHold = self.onMenuHold, onSetRotationMode = self.MenuSetRotationModeHandler, _manager = self, diff --git a/frontend/apps/filemanager/filemanagerhistory.lua b/frontend/apps/filemanager/filemanagerhistory.lua index 0c9e73b97..586fe7bd9 100644 --- a/frontend/apps/filemanager/filemanagerhistory.lua +++ b/frontend/apps/filemanager/filemanagerhistory.lua @@ -83,6 +83,9 @@ end function FileManagerHistory:onMenuHold(item) self.histfile_dialog = nil + local function close_dialog_callback() + UIManager:close(self.histfile_dialog) + end local function status_button_callback() UIManager:close(self.histfile_dialog) if self._manager.filter ~= "all" then @@ -125,11 +128,11 @@ function FileManagerHistory:onMenuHold(item) FileManager:showDeleteFileDialog(item.file, post_delete_callback) end, }, - filemanagerutil.genBookInformationButton(item.file, self.histfile_dialog, item.dim), + filemanagerutil.genBookInformationButton(item.file, close_dialog_callback, item.dim), }) table.insert(buttons, { - filemanagerutil.genBookCoverButton(item.file, self.histfile_dialog, item.dim), - filemanagerutil.genBookDescriptionButton(item.file, self.histfile_dialog, item.dim), + filemanagerutil.genBookCoverButton(item.file, close_dialog_callback, item.dim), + filemanagerutil.genBookDescriptionButton(item.file, close_dialog_callback, item.dim), }) self.histfile_dialog = ButtonDialogTitle:new{ @@ -226,7 +229,7 @@ function FileManagerHistory:showHistDialog() { text = _("Clear history of deleted files"), callback = function() - UIManager:show(ConfirmBox:new{ + local confirmbox = ConfirmBox:new{ text = _("Clear history of deleted files?"), ok_text = _("Clear"), ok_callback = function() @@ -234,7 +237,8 @@ function FileManagerHistory:showHistDialog() require("readhistory"):clearMissing() self:updateItemTable() end, - }) + } + UIManager:show(confirmbox) end, }, }) diff --git a/frontend/apps/filemanager/filemanagerutil.lua b/frontend/apps/filemanager/filemanagerutil.lua index 22f5a165c..b960d6acb 100644 --- a/frontend/apps/filemanager/filemanagerutil.lua +++ b/frontend/apps/filemanager/filemanagerutil.lua @@ -158,38 +158,38 @@ function filemanagerutil.genResetSettingsButton(file, caller_callback, button_di } end -function filemanagerutil.genBookInformationButton(file, dialog, button_disabled) +function filemanagerutil.genBookInformationButton(file, caller_callback, button_disabled) return { text = _("Book information"), id = "book_information", -- used by covermenu enabled = not button_disabled, callback = function() - UIManager:close(dialog) + caller_callback() require("apps/filemanager/filemanagerbookinfo"):show(file) end, } end -function filemanagerutil.genBookDescriptionButton(file, dialog, button_disabled) +function filemanagerutil.genBookCoverButton(file, caller_callback, button_disabled) return { - text = _("Book description"), - id = "book_description", -- used by covermenu + text = _("Book cover"), + id = "book_cover", -- used by covermenu enabled = not button_disabled, callback = function() - UIManager:close(dialog) - require("apps/filemanager/filemanagerbookinfo"):onShowBookDescription(nil, file) + caller_callback() + require("apps/filemanager/filemanagerbookinfo"):onShowBookCover(file) end, } end -function filemanagerutil.genBookCoverButton(file, dialog, button_disabled) +function filemanagerutil.genBookDescriptionButton(file, caller_callback, button_disabled) return { - text = _("Book cover"), - id = "book_cover", -- used by covermenu + text = _("Book description"), + id = "book_description", -- used by covermenu enabled = not button_disabled, callback = function() - UIManager:close(dialog) - require("apps/filemanager/filemanagerbookinfo"):onShowBookCover(file) + caller_callback() + require("apps/filemanager/filemanagerbookinfo"):onShowBookDescription(nil, file) end, } end diff --git a/frontend/readcollection.lua b/frontend/readcollection.lua index 4eef13493..b35beaf91 100644 --- a/frontend/readcollection.lua +++ b/frontend/readcollection.lua @@ -14,7 +14,6 @@ function ReadCollection:read(collection_name) local collections = LuaSettings:open(collection_file) local coll = collections:readSetting(collection_name) or {} local coll_max_item = 0 - for _, v in pairs(coll) do if v.order > coll_max_item then coll_max_item = v.order @@ -36,17 +35,15 @@ function ReadCollection:prepareList(collection_name) local data = self:read(collection_name) local list = {} for _, v in pairs(data) do - local file_exists = lfs.attributes(v.file, "mode") == "file" + local file_path = FFIUtil.realpath(v.file) or v.file -- keep orig file path of deleted files + local file_exists = lfs.attributes(file_path, "mode") == "file" table.insert(list, { order = v.order, + file = file_path, text = v.file:gsub(".*/", ""), - file = FFIUtil.realpath(v.file) or v.file, -- keep orig file path of deleted files - dim = not file_exists, -- "dim", as expected by Menu - mandatory = file_exists and util.getFriendlySize(lfs.attributes(v.file, "size") or 0), - callback = function() - local ReaderUI = require("apps/reader/readerui") - ReaderUI:showReader(v.file) - end + dim = not file_exists, + mandatory = file_exists and util.getFriendlySize(lfs.attributes(file_path, "size") or 0), + select_enabled = file_exists, }) end table.sort(list, function(v1,v2) @@ -62,7 +59,7 @@ function ReadCollection:removeItemByPath(path, is_dir) path = path .. "/" end local coll = self:readAllCollection() - for i, _ in pairs(coll) do + for i in pairs(coll) do local single_collection = coll[i] for item = #single_collection, 1, -1 do if not is_dir and single_collection[item].file == path then @@ -126,19 +123,16 @@ function ReadCollection:removeItem(item, collection_name) end function ReadCollection:writeCollection(coll_items, collection_name) - if not collection_name then collection_name = DEFAULT_COLLECTION_NAME end local collection = LuaSettings:open(collection_file) - collection:saveSetting(collection_name, coll_items) + collection:saveSetting(collection_name or DEFAULT_COLLECTION_NAME, coll_items) collection:flush() end function ReadCollection:addItem(file, collection_name) local coll, coll_max_item = self:read(collection_name) - coll_max_item = coll_max_item + 1 - local collection_item = - { + local collection_item = { file = file, - order = coll_max_item + order = coll_max_item + 1, } table.insert(coll, collection_item) self:writeCollection(coll, collection_name) @@ -151,8 +145,6 @@ function ReadCollection:checkItemExist(item, collection_name) return true end end - return false end return ReadCollection - diff --git a/frontend/ui/widget/buttontable.lua b/frontend/ui/widget/buttontable.lua index 08b285046..ef54de90a 100644 --- a/frontend/ui/widget/buttontable.lua +++ b/frontend/ui/widget/buttontable.lua @@ -89,6 +89,7 @@ function ButtonTable:init() padding = Size.padding.buttontable, -- a bit taller than standalone buttons, for easier tap padding_h = btn_entry.align == "left" and Size.padding.large or 0, -- allow text to take more of the horizontal space if centered + avoid_text_truncation = btn_entry.avoid_text_truncation, text_font_face = btn_entry.font_face, text_font_size = btn_entry.font_size, text_font_bold = btn_entry.font_bold,