2020-01-04 00:18:51 +00:00
|
|
|
local BD = require("ui/bidi")
|
2023-06-08 05:27:52 +00:00
|
|
|
local ButtonDialog = require("ui/widget/buttondialog")
|
2023-11-09 05:34:56 +00:00
|
|
|
local CheckButton = require("ui/widget/checkbutton")
|
2021-07-23 15:14:25 +00:00
|
|
|
local ConfirmBox = require("ui/widget/confirmbox")
|
2024-02-07 08:35:52 +00:00
|
|
|
local DocSettings = require("docsettings")
|
|
|
|
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
|
2023-11-09 05:34:56 +00:00
|
|
|
local InputDialog = require("ui/widget/inputdialog")
|
2014-08-14 11:49:42 +00:00
|
|
|
local Menu = require("ui/widget/menu")
|
2024-05-01 06:01:59 +00:00
|
|
|
local ReadCollection = require("readcollection")
|
2017-04-25 16:49:39 +00:00
|
|
|
local UIManager = require("ui/uimanager")
|
Clarify our OOP semantics across the codebase (#9586)
Basically:
* Use `extend` for class definitions
* Use `new` for object instantiations
That includes some minor code cleanups along the way:
* Updated `Widget`'s docs to make the semantics clearer.
* Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283)
* Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass).
* Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events.
* Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier.
* Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references.
* ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak).
* Terminal: Make sure the shell is killed on plugin teardown.
* InputText: Fix Home/End/Del physical keys to behave sensibly.
* InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...).
* OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of.
* ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed!
* Kobo: Minor code cleanups.
2022-10-06 00:14:48 +00:00
|
|
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
2014-10-30 18:42:18 +00:00
|
|
|
local Screen = require("device").screen
|
2023-11-09 05:34:56 +00:00
|
|
|
local Utf8Proc = require("ffi/utf8proc")
|
2017-09-22 16:24:38 +00:00
|
|
|
local filemanagerutil = require("apps/filemanager/filemanagerutil")
|
2023-11-09 05:34:56 +00:00
|
|
|
local util = require("util")
|
2013-10-18 20:38:07 +00:00
|
|
|
local _ = require("gettext")
|
2022-03-15 15:16:04 +00:00
|
|
|
local C_ = _.pgettext
|
2023-02-17 21:06:55 +00:00
|
|
|
local T = require("ffi/util").template
|
2017-04-25 16:49:39 +00:00
|
|
|
|
Clarify our OOP semantics across the codebase (#9586)
Basically:
* Use `extend` for class definitions
* Use `new` for object instantiations
That includes some minor code cleanups along the way:
* Updated `Widget`'s docs to make the semantics clearer.
* Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283)
* Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass).
* Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events.
* Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier.
* Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references.
* ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak).
* Terminal: Make sure the shell is killed on plugin teardown.
* InputText: Fix Home/End/Del physical keys to behave sensibly.
* InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...).
* OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of.
* ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed!
* Kobo: Minor code cleanups.
2022-10-06 00:14:48 +00:00
|
|
|
local FileManagerHistory = WidgetContainer:extend{
|
2014-03-13 13:52:43 +00:00
|
|
|
hist_menu_title = _("History"),
|
2013-08-14 09:29:05 +00:00
|
|
|
}
|
|
|
|
|
2022-12-02 15:56:00 +00:00
|
|
|
local filter_text = {
|
2023-11-09 05:34:56 +00:00
|
|
|
all = C_("Book status filter", "All"),
|
|
|
|
reading = C_("Book status filter", "Reading"),
|
2022-03-15 15:16:04 +00:00
|
|
|
abandoned = C_("Book status filter", "On hold"),
|
2023-11-09 05:34:56 +00:00
|
|
|
complete = C_("Book status filter", "Finished"),
|
|
|
|
deleted = C_("Book status filter", "Deleted"),
|
|
|
|
new = C_("Book status filter", "New"),
|
2022-03-12 10:26:11 +00:00
|
|
|
}
|
|
|
|
|
2013-08-14 09:29:05 +00:00
|
|
|
function FileManagerHistory:init()
|
2014-03-13 13:52:43 +00:00
|
|
|
self.ui.menu:registerToMainMenu(self)
|
2013-08-14 09:29:05 +00:00
|
|
|
end
|
|
|
|
|
2017-03-04 13:46:38 +00:00
|
|
|
function FileManagerHistory:addToMainMenu(menu_items)
|
|
|
|
menu_items.history = {
|
2016-02-17 07:10:23 +00:00
|
|
|
text = self.hist_menu_title,
|
|
|
|
callback = function()
|
|
|
|
self:onShowHist()
|
|
|
|
end,
|
2017-02-28 21:46:32 +00:00
|
|
|
}
|
2016-02-17 07:10:23 +00:00
|
|
|
end
|
|
|
|
|
2022-12-02 15:56:00 +00:00
|
|
|
function FileManagerHistory:fetchStatuses(count)
|
|
|
|
for _, v in ipairs(require("readhistory").hist) do
|
2023-09-29 04:44:10 +00:00
|
|
|
local status
|
|
|
|
if v.dim then -- deleted file
|
|
|
|
status = "deleted"
|
|
|
|
elseif v.file == (self.ui.document and self.ui.document.file) then -- currently opened file
|
|
|
|
status = self.ui.doc_settings:readSetting("summary").status
|
|
|
|
else
|
|
|
|
status = filemanagerutil.getStatus(v.file)
|
2022-12-02 15:56:00 +00:00
|
|
|
end
|
2023-12-02 07:06:31 +00:00
|
|
|
if not filter_text[status] then
|
|
|
|
status = "reading"
|
|
|
|
end
|
2022-12-02 15:56:00 +00:00
|
|
|
if count then
|
2023-09-29 04:44:10 +00:00
|
|
|
self.count[status] = self.count[status] + 1
|
2022-12-02 15:56:00 +00:00
|
|
|
end
|
2023-09-29 04:44:10 +00:00
|
|
|
v.status = status
|
2022-12-02 15:56:00 +00:00
|
|
|
end
|
|
|
|
self.statuses_fetched = true
|
|
|
|
end
|
|
|
|
|
2016-02-17 07:10:23 +00:00
|
|
|
function FileManagerHistory:updateItemTable()
|
2022-03-12 10:26:11 +00:00
|
|
|
self.count = { all = #require("readhistory").hist,
|
|
|
|
reading = 0, abandoned = 0, complete = 0, deleted = 0, new = 0, }
|
|
|
|
local item_table = {}
|
|
|
|
for _, v in ipairs(require("readhistory").hist) do
|
2023-11-09 05:34:56 +00:00
|
|
|
if self:isItemMatch(v) then
|
2024-02-07 08:35:52 +00:00
|
|
|
v.mandatory_dim = (self.is_frozen and v.status == "complete") and true or nil
|
2022-03-12 10:26:11 +00:00
|
|
|
table.insert(item_table, v)
|
|
|
|
end
|
|
|
|
if self.statuses_fetched then
|
|
|
|
self.count[v.status] = self.count[v.status] + 1
|
|
|
|
end
|
|
|
|
end
|
2024-02-07 08:35:52 +00:00
|
|
|
local subtitle = ""
|
2023-11-09 05:34:56 +00:00
|
|
|
if self.search_string then
|
2023-12-28 05:47:56 +00:00
|
|
|
subtitle = T(_("Search results (%1)"), #item_table)
|
2024-05-01 06:01:59 +00:00
|
|
|
elseif self.selected_colections then
|
|
|
|
subtitle = T(_("Filtered by collections (%1)"), #item_table)
|
2023-11-09 05:34:56 +00:00
|
|
|
elseif self.filter ~= "all" then
|
2023-12-28 05:47:56 +00:00
|
|
|
subtitle = T(_("Status: %1 (%2)"), filter_text[self.filter]:lower(), #item_table)
|
2023-11-09 05:34:56 +00:00
|
|
|
end
|
2024-02-07 08:35:52 +00:00
|
|
|
self.hist_menu:switchItemTable(nil, item_table, -1, nil, subtitle)
|
2016-02-17 07:10:23 +00:00
|
|
|
end
|
|
|
|
|
2023-11-09 05:34:56 +00:00
|
|
|
function FileManagerHistory:isItemMatch(item)
|
|
|
|
if self.search_string then
|
|
|
|
local filename = self.case_sensitive and item.text or Utf8Proc.lowercase(util.fixUtf8(item.text, "?"))
|
|
|
|
if not filename:find(self.search_string) then
|
|
|
|
local book_props
|
|
|
|
if self.ui.coverbrowser then
|
|
|
|
book_props = self.ui.coverbrowser:getBookInfo(item.file)
|
|
|
|
end
|
|
|
|
if not book_props then
|
|
|
|
book_props = self.ui.bookinfo.getDocProps(item.file, nil, true) -- do not open the document
|
|
|
|
end
|
|
|
|
if not self.ui.bookinfo:findInProps(book_props, self.search_string, self.case_sensitive) then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2024-05-01 06:01:59 +00:00
|
|
|
if self.selected_colections then
|
|
|
|
for name in pairs(self.selected_colections) do
|
|
|
|
if not ReadCollection:isFileInCollection(item.file, name) then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2023-11-09 05:34:56 +00:00
|
|
|
return self.filter == "all" or item.status == self.filter
|
|
|
|
end
|
|
|
|
|
2013-08-14 09:29:05 +00:00
|
|
|
function FileManagerHistory:onSetDimensions(dimen)
|
2014-03-13 13:52:43 +00:00
|
|
|
self.dimen = dimen
|
2013-08-14 09:29:05 +00:00
|
|
|
end
|
|
|
|
|
2023-03-26 18:11:19 +00:00
|
|
|
function FileManagerHistory:onMenuChoice(item)
|
2023-11-09 05:34:56 +00:00
|
|
|
if self.ui.document then
|
|
|
|
if self.ui.document.file ~= item.file then
|
|
|
|
self.ui:switchDocument(item.file)
|
|
|
|
end
|
|
|
|
else
|
2024-01-26 21:01:45 +00:00
|
|
|
self.ui:openFile(item.file)
|
2023-11-09 05:34:56 +00:00
|
|
|
end
|
2023-03-26 18:11:19 +00:00
|
|
|
end
|
|
|
|
|
2014-01-22 18:03:44 +00:00
|
|
|
function FileManagerHistory:onMenuHold(item)
|
2024-01-26 21:01:45 +00:00
|
|
|
local file = item.file
|
2017-09-22 16:24:38 +00:00
|
|
|
self.histfile_dialog = nil
|
2024-02-07 08:35:52 +00:00
|
|
|
self.book_props = self.ui.coverbrowser and self.ui.coverbrowser:getBookInfo(file)
|
2024-01-26 21:01:45 +00:00
|
|
|
|
2023-03-31 16:35:27 +00:00
|
|
|
local function close_dialog_callback()
|
|
|
|
UIManager:close(self.histfile_dialog)
|
|
|
|
end
|
2023-06-08 05:27:52 +00:00
|
|
|
local function close_dialog_menu_callback()
|
|
|
|
UIManager:close(self.histfile_dialog)
|
|
|
|
self._manager.hist_menu.close_callback()
|
|
|
|
end
|
2024-01-26 21:01:45 +00:00
|
|
|
local function close_dialog_update_callback()
|
2023-02-17 21:06:55 +00:00
|
|
|
UIManager:close(self.histfile_dialog)
|
2024-02-07 08:35:52 +00:00
|
|
|
if self._manager.filter ~= "all" or self._manager.is_frozen then
|
2023-02-04 21:05:06 +00:00
|
|
|
self._manager:fetchStatuses(false)
|
|
|
|
else
|
|
|
|
self._manager.statuses_fetched = false
|
|
|
|
end
|
|
|
|
self._manager:updateItemTable()
|
2023-02-17 21:06:55 +00:00
|
|
|
self._manager.files_updated = true -- sidecar folder may be created/deleted
|
|
|
|
end
|
2024-01-26 21:01:45 +00:00
|
|
|
local is_currently_opened = file == (self.ui.document and self.ui.document.file)
|
2023-02-17 21:06:55 +00:00
|
|
|
|
|
|
|
local buttons = {}
|
2024-02-07 08:35:52 +00:00
|
|
|
local doc_settings_or_file
|
|
|
|
if is_currently_opened then
|
|
|
|
doc_settings_or_file = self.ui.doc_settings
|
|
|
|
if not self.book_props then
|
|
|
|
self.book_props = self.ui.doc_props
|
|
|
|
self.book_props.has_cover = true
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if DocSettings:hasSidecarFile(file) then
|
|
|
|
doc_settings_or_file = DocSettings:open(file)
|
|
|
|
if not self.book_props then
|
|
|
|
local props = doc_settings_or_file:readSetting("doc_props")
|
|
|
|
self.book_props = FileManagerBookInfo.extendProps(props, file)
|
|
|
|
self.book_props.has_cover = true
|
|
|
|
end
|
|
|
|
else
|
|
|
|
doc_settings_or_file = file
|
|
|
|
end
|
|
|
|
end
|
2023-09-29 04:44:10 +00:00
|
|
|
if not item.dim then
|
2024-01-26 21:01:45 +00:00
|
|
|
table.insert(buttons, filemanagerutil.genStatusButtonsRow(doc_settings_or_file, close_dialog_update_callback))
|
2023-02-17 21:06:55 +00:00
|
|
|
table.insert(buttons, {}) -- separator
|
2023-02-04 20:32:43 +00:00
|
|
|
end
|
2023-02-17 21:06:55 +00:00
|
|
|
table.insert(buttons, {
|
2024-02-07 08:35:52 +00:00
|
|
|
filemanagerutil.genResetSettingsButton(doc_settings_or_file, close_dialog_update_callback, is_currently_opened),
|
2024-05-01 06:01:59 +00:00
|
|
|
self._manager.ui.collections:genAddToCollectionButton(file, close_dialog_callback, nil, item.dim),
|
2023-02-17 21:06:55 +00:00
|
|
|
})
|
|
|
|
table.insert(buttons, {
|
2017-09-22 16:24:38 +00:00
|
|
|
{
|
2023-02-17 21:06:55 +00:00
|
|
|
text = _("Delete"),
|
|
|
|
enabled = not (item.dim or is_currently_opened),
|
|
|
|
callback = function()
|
|
|
|
local function post_delete_callback()
|
2017-09-22 16:24:38 +00:00
|
|
|
UIManager:close(self.histfile_dialog)
|
2023-02-17 21:06:55 +00:00
|
|
|
self._manager:updateItemTable()
|
|
|
|
self._manager.files_updated = true
|
|
|
|
end
|
|
|
|
local FileManager = require("apps/filemanager/filemanager")
|
2024-01-26 21:01:45 +00:00
|
|
|
FileManager:showDeleteFileDialog(file, post_delete_callback)
|
2023-02-17 21:06:55 +00:00
|
|
|
end,
|
2017-09-22 16:24:38 +00:00
|
|
|
},
|
2023-06-08 05:27:52 +00:00
|
|
|
{
|
|
|
|
text = _("Remove from history"),
|
|
|
|
callback = function()
|
|
|
|
UIManager:close(self.histfile_dialog)
|
|
|
|
require("readhistory"):removeItem(item)
|
|
|
|
self._manager:updateItemTable()
|
|
|
|
end,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
table.insert(buttons, {
|
2024-01-26 21:01:45 +00:00
|
|
|
filemanagerutil.genShowFolderButton(file, close_dialog_menu_callback, item.dim),
|
2024-02-07 08:35:52 +00:00
|
|
|
filemanagerutil.genBookInformationButton(file, self.book_props, close_dialog_callback, item.dim),
|
2023-02-17 21:06:55 +00:00
|
|
|
})
|
2023-03-07 20:24:42 +00:00
|
|
|
table.insert(buttons, {
|
2024-02-07 08:35:52 +00:00
|
|
|
filemanagerutil.genBookCoverButton(file, self.book_props, close_dialog_callback, item.dim),
|
|
|
|
filemanagerutil.genBookDescriptionButton(file, self.book_props, close_dialog_callback, item.dim),
|
2023-03-07 20:24:42 +00:00
|
|
|
})
|
2023-02-17 21:06:55 +00:00
|
|
|
|
2023-06-08 05:27:52 +00:00
|
|
|
self.histfile_dialog = ButtonDialog:new{
|
2023-11-09 05:34:56 +00:00
|
|
|
title = BD.filename(item.text),
|
2017-09-22 16:24:38 +00:00
|
|
|
title_align = "center",
|
|
|
|
buttons = buttons,
|
|
|
|
}
|
2014-03-13 13:52:43 +00:00
|
|
|
UIManager:show(self.histfile_dialog)
|
|
|
|
return true
|
2014-01-22 18:03:44 +00:00
|
|
|
end
|
2013-08-14 09:29:05 +00:00
|
|
|
|
2021-04-09 21:12:15 +00:00
|
|
|
-- Can't *actually* name it onSetRotationMode, or it also fires in FM itself ;).
|
|
|
|
function FileManagerHistory:MenuSetRotationModeHandler(rotation)
|
|
|
|
if rotation ~= nil and rotation ~= Screen:getRotationMode() then
|
|
|
|
UIManager:close(self._manager.hist_menu)
|
|
|
|
-- Also re-layout ReaderView or FileManager itself
|
|
|
|
if self._manager.ui.view and self._manager.ui.view.onSetRotationMode then
|
|
|
|
self._manager.ui.view:onSetRotationMode(rotation)
|
|
|
|
elseif self._manager.ui.onSetRotationMode then
|
|
|
|
self._manager.ui:onSetRotationMode(rotation)
|
|
|
|
else
|
|
|
|
Screen:setRotationMode(rotation)
|
|
|
|
end
|
|
|
|
self._manager:onShowHist()
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2023-11-09 05:34:56 +00:00
|
|
|
function FileManagerHistory:onShowHist(search_info)
|
2014-03-13 13:52:43 +00:00
|
|
|
self.hist_menu = Menu:new{
|
|
|
|
ui = self.ui,
|
2018-03-17 22:02:32 +00:00
|
|
|
covers_fullscreen = true, -- hint for UIManager:_repaint()
|
2017-08-14 11:15:12 +00:00
|
|
|
is_borderless = true,
|
2017-09-24 12:46:50 +00:00
|
|
|
is_popout = false,
|
2023-12-19 07:22:53 +00:00
|
|
|
title = self.hist_menu_title,
|
|
|
|
-- item and book cover thumbnail dimensions in Mosaic and Detailed list display modes
|
|
|
|
-- must be equal in File manager, History and Collection windows to avoid image scaling
|
|
|
|
title_bar_fm_style = true,
|
2022-03-12 10:26:11 +00:00
|
|
|
title_bar_left_icon = "appbar.menu",
|
|
|
|
onLeftButtonTap = function() self:showHistDialog() end,
|
2023-03-26 18:11:19 +00:00
|
|
|
onMenuChoice = self.onMenuChoice,
|
2014-03-13 13:52:43 +00:00
|
|
|
onMenuHold = self.onMenuHold,
|
2021-04-09 21:12:15 +00:00
|
|
|
onSetRotationMode = self.MenuSetRotationModeHandler,
|
2014-03-13 13:52:43 +00:00
|
|
|
_manager = self,
|
|
|
|
}
|
2021-04-09 17:38:17 +00:00
|
|
|
|
2023-11-09 05:34:56 +00:00
|
|
|
if search_info then
|
|
|
|
self.search_string = search_info.search_string
|
|
|
|
self.case_sensitive = search_info.case_sensitive
|
|
|
|
else
|
|
|
|
self.search_string = nil
|
2024-05-01 06:01:59 +00:00
|
|
|
self.selected_colections = nil
|
2023-11-09 05:34:56 +00:00
|
|
|
end
|
2022-12-02 15:56:00 +00:00
|
|
|
self.filter = G_reader_settings:readSetting("history_filter", "all")
|
2023-10-12 05:58:52 +00:00
|
|
|
self.is_frozen = G_reader_settings:isTrue("history_freeze_finished_books")
|
|
|
|
if self.filter ~= "all" or self.is_frozen then
|
2022-12-02 15:56:00 +00:00
|
|
|
self:fetchStatuses(false)
|
|
|
|
end
|
2014-03-13 13:52:43 +00:00
|
|
|
self:updateItemTable()
|
|
|
|
self.hist_menu.close_callback = function()
|
2023-02-17 21:06:55 +00:00
|
|
|
if self.files_updated then -- refresh Filemanager list of files
|
2023-11-09 05:34:56 +00:00
|
|
|
if self.ui.file_chooser then
|
|
|
|
self.ui.file_chooser:refreshPath()
|
2023-02-17 21:06:55 +00:00
|
|
|
end
|
|
|
|
self.files_updated = nil
|
|
|
|
end
|
2022-03-12 10:26:11 +00:00
|
|
|
self.statuses_fetched = nil
|
ReaderUI: Saner FM/RD lifecycle
* Ensure that going from one to the other tears down the former and
its plugins before instantiating the latter and its plugins.
UIManager: Unify Event sending & broadcasting
* Make the two behave the same way (walk the widget stack from top to
bottom), and properly handle the window stack shrinking shrinking
*and* growing.
Previously, broadcasting happened bottom-to-top and didn't really
handle the list shrinking/growing, while sending only handled the list
shrinking by a single element, and hopefully that element being the one
the event was just sent to.
These two items combined allowed us to optimize suboptimal
refresh behavior with Menu and other Menu classes when
opening/closing a document.
e.g., the "opening document" Notification is now properly regional,
and the "open last doc" option no longer flashes like a crazy person
anymore.
Plugins: Allow optimizing Menu refresh with custom menus, too.
Requires moving Menu's close_callback *after* onMenuSelect, which, eh,
probably makes sense, and is probably harmless in the grand scheme of
things.
2021-05-01 16:53:04 +00:00
|
|
|
UIManager:close(self.hist_menu)
|
2023-11-09 05:34:56 +00:00
|
|
|
self.hist_menu = nil
|
2022-12-02 15:56:00 +00:00
|
|
|
G_reader_settings:saveSetting("history_filter", self.filter)
|
2014-03-13 13:52:43 +00:00
|
|
|
end
|
2024-04-06 11:07:34 +00:00
|
|
|
UIManager:show(self.hist_menu, "flashui")
|
2014-03-13 13:52:43 +00:00
|
|
|
return true
|
2013-08-14 09:29:05 +00:00
|
|
|
end
|
|
|
|
|
2022-03-12 10:26:11 +00:00
|
|
|
function FileManagerHistory:showHistDialog()
|
|
|
|
if not self.statuses_fetched then
|
2022-12-02 15:56:00 +00:00
|
|
|
self:fetchStatuses(true)
|
2022-03-12 10:26:11 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
local hist_dialog
|
|
|
|
local buttons = {}
|
2022-12-02 15:56:00 +00:00
|
|
|
local function genFilterButton(filter)
|
2022-03-12 10:26:11 +00:00
|
|
|
return {
|
2022-12-02 15:56:00 +00:00
|
|
|
text = T(_("%1 (%2)"), filter_text[filter], self.count[filter]),
|
2022-03-12 10:26:11 +00:00
|
|
|
callback = function()
|
|
|
|
UIManager:close(hist_dialog)
|
2022-12-02 15:56:00 +00:00
|
|
|
self.filter = filter
|
2023-11-09 05:34:56 +00:00
|
|
|
if filter == "all" then -- reset all filters
|
|
|
|
self.search_string = nil
|
2024-05-01 06:01:59 +00:00
|
|
|
self.selected_colections = nil
|
2023-11-09 05:34:56 +00:00
|
|
|
end
|
2022-03-12 10:26:11 +00:00
|
|
|
self:updateItemTable()
|
|
|
|
end,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
table.insert(buttons, {
|
|
|
|
genFilterButton("all"),
|
|
|
|
genFilterButton("new"),
|
2023-02-17 21:06:55 +00:00
|
|
|
genFilterButton("deleted"),
|
2022-03-12 10:26:11 +00:00
|
|
|
})
|
2023-06-21 04:33:09 +00:00
|
|
|
table.insert(buttons, {
|
|
|
|
genFilterButton("reading"),
|
|
|
|
genFilterButton("abandoned"),
|
|
|
|
genFilterButton("complete"),
|
|
|
|
})
|
2024-05-01 06:01:59 +00:00
|
|
|
table.insert(buttons, {
|
|
|
|
{
|
|
|
|
text = _("Filter by collections"),
|
|
|
|
callback = function()
|
|
|
|
UIManager:close(hist_dialog)
|
|
|
|
local caller_callback = function()
|
|
|
|
self.selected_colections = self.ui.collections.selected_colections
|
|
|
|
self:updateItemTable()
|
|
|
|
end
|
|
|
|
self.ui.collections:onShowCollList({}, caller_callback, true) -- do not select any, no dialog to apply
|
|
|
|
end,
|
|
|
|
},
|
|
|
|
})
|
2023-11-09 05:34:56 +00:00
|
|
|
table.insert(buttons, {
|
|
|
|
{
|
|
|
|
text = _("Search in filename and book metadata"),
|
|
|
|
callback = function()
|
|
|
|
UIManager:close(hist_dialog)
|
|
|
|
self:onSearchHistory()
|
|
|
|
end,
|
|
|
|
},
|
|
|
|
})
|
2022-03-12 10:26:11 +00:00
|
|
|
if self.count.deleted > 0 then
|
2023-02-17 21:06:55 +00:00
|
|
|
table.insert(buttons, {}) -- separator
|
2022-03-12 10:26:11 +00:00
|
|
|
table.insert(buttons, {
|
|
|
|
{
|
|
|
|
text = _("Clear history of deleted files"),
|
|
|
|
callback = function()
|
2023-03-31 16:35:27 +00:00
|
|
|
local confirmbox = ConfirmBox:new{
|
2022-03-12 10:26:11 +00:00
|
|
|
text = _("Clear history of deleted files?"),
|
|
|
|
ok_text = _("Clear"),
|
|
|
|
ok_callback = function()
|
|
|
|
UIManager:close(hist_dialog)
|
|
|
|
require("readhistory"):clearMissing()
|
|
|
|
self:updateItemTable()
|
|
|
|
end,
|
2023-03-31 16:35:27 +00:00
|
|
|
}
|
|
|
|
UIManager:show(confirmbox)
|
2022-03-12 10:26:11 +00:00
|
|
|
end,
|
2023-02-17 21:06:55 +00:00
|
|
|
},
|
2022-03-12 10:26:11 +00:00
|
|
|
})
|
|
|
|
end
|
2023-06-08 05:27:52 +00:00
|
|
|
hist_dialog = ButtonDialog:new{
|
2022-03-12 10:26:11 +00:00
|
|
|
title = _("Filter by book status"),
|
|
|
|
title_align = "center",
|
|
|
|
buttons = buttons,
|
|
|
|
}
|
|
|
|
UIManager:show(hist_dialog)
|
|
|
|
end
|
|
|
|
|
2023-11-09 05:34:56 +00:00
|
|
|
function FileManagerHistory:onSearchHistory()
|
|
|
|
local search_dialog, check_button_case
|
|
|
|
search_dialog = InputDialog:new{
|
|
|
|
title = _("Enter text to search history for"),
|
|
|
|
input = self.search_string,
|
|
|
|
buttons = {
|
|
|
|
{
|
|
|
|
{
|
|
|
|
text = _("Cancel"),
|
|
|
|
id = "close",
|
|
|
|
callback = function()
|
|
|
|
UIManager:close(search_dialog)
|
|
|
|
end,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
text = _("Search"),
|
|
|
|
is_enter_default = true,
|
|
|
|
callback = function()
|
|
|
|
local search_string = search_dialog:getInputText()
|
|
|
|
if search_string ~= "" then
|
|
|
|
UIManager:close(search_dialog)
|
|
|
|
self.search_string = self.case_sensitive and search_string or search_string:lower()
|
|
|
|
if self.hist_menu then -- called from History
|
|
|
|
self:updateItemTable()
|
|
|
|
else -- called by Dispatcher
|
|
|
|
local search_info = {
|
|
|
|
search_string = self.search_string,
|
|
|
|
case_sensitive = self.case_sensitive,
|
|
|
|
}
|
|
|
|
self:onShowHist(search_info)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
check_button_case = CheckButton:new{
|
|
|
|
text = _("Case sensitive"),
|
|
|
|
checked = self.case_sensitive,
|
|
|
|
parent = search_dialog,
|
|
|
|
callback = function()
|
|
|
|
self.case_sensitive = check_button_case.checked
|
|
|
|
end,
|
|
|
|
}
|
|
|
|
search_dialog:addWidget(check_button_case)
|
|
|
|
UIManager:show(search_dialog)
|
|
|
|
search_dialog:onShowKeyboard()
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2023-09-06 06:41:10 +00:00
|
|
|
function FileManagerHistory:onBookMetadataChanged()
|
|
|
|
if self.hist_menu then
|
|
|
|
self.hist_menu:updateItems()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-01-22 18:03:44 +00:00
|
|
|
return FileManagerHistory
|