Keep some menus open when Tap or Hold (#4189)

TouchMenu: added options to menu items with the following defaults:
    keep_menu_open = false
    hold_keep_menu_open = true
So, default for Tap callback is to close menu, and for Hold callback
to keep menu open.
In both cases, provide the TouchMenu instance as the 1st argument to
the callback functions (instead of a refresh_menu_func I added in #3941)
so the callback can do more things, like closing, refreshing,
changing menu items text and re-ordering...

ReaderZooming: show symbol for default (like it was done for
ReaderFont, ReaderHyphenation...)
TextEditor plugin: update the previously opened files list in real
time, so the menu can be kept open and used as the TextEditor main
interface.
SSH plugin: keep menu open and update the Start/Stop state in real time
ReadTimer plugin: tried to do what feels right (but I don't use it)

Also remove forgotten cp in the move/paste file code
pull/4203/head
poire-z 6 years ago committed by GitHub
parent 4320359b25
commit 850be52177
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -637,7 +637,6 @@ function FileManager:pasteHere(file)
timeout = 2, timeout = 2,
}) })
end end
util.execute(self.cp_bin, "-r", orig, dest)
end end
local info_file local info_file

@ -115,6 +115,12 @@ function FileManagerMenu:setUpdateItemTable()
} }
self.menu_items.items_per_page = { self.menu_items.items_per_page = {
text = _("Items per page"), text = _("Items per page"),
help_text = _([[This sets the number of items per page in:
- File browser and history in 'classic' display mode
- File and directory selection
- Table of content
- Bookmarks list]]),
keep_menu_open = true,
callback = function() callback = function()
local SpinWidget = require("ui/widget/spinwidget") local SpinWidget = require("ui/widget/spinwidget")
local curr_items = G_reader_settings:readSetting("items_per_page") or 14 local curr_items = G_reader_settings:readSetting("items_per_page") or 14

@ -228,6 +228,7 @@ function ReaderDictionary:addToMainMenu(menu_items)
}, },
{ {
text = _("Info on dictionary order"), text = _("Info on dictionary order"),
keep_menu_open = true,
callback = function() callback = function()
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
text = T(_( text = T(_(
@ -262,6 +263,7 @@ function ReaderDictionary:addToMainMenu(menu_items)
}, },
{ {
text = _("Clean dictionary lookup history"), text = _("Clean dictionary lookup history"),
keep_menu_open = true,
callback = function() callback = function()
UIManager:show(ConfirmBox:new{ UIManager:show(ConfirmBox:new{
text = _("Clean dictionary lookup history?"), text = _("Clean dictionary lookup history?"),

@ -68,9 +68,8 @@ function ReaderFont:init()
callback = function() callback = function()
self:setFont(v) self:setFont(v)
end, end,
hold_may_update_menu = true, hold_callback = function(touchmenu_instance)
hold_callback = function(refresh_menu_func) self:makeDefault(v, touchmenu_instance)
self:makeDefault(v, refresh_menu_func)
end, end,
checked_func = function() checked_func = function()
return v == self.font_face return v == self.font_face
@ -310,14 +309,14 @@ function ReaderFont:setFont(face)
end end
end end
function ReaderFont:makeDefault(face, refresh_menu_func) function ReaderFont:makeDefault(face, touchmenu_instance)
if face then if face then
UIManager:show(MultiConfirmBox:new{ UIManager:show(MultiConfirmBox:new{
text = T( _("Would you like %1 to be used as the default font (★), or the fallback font (<28>)?\n\nCharacters not found in the active font are shown in the fallback font instead."), face), text = T( _("Would you like %1 to be used as the default font (★), or the fallback font (<28>)?\n\nCharacters not found in the active font are shown in the fallback font instead."), face),
choice1_text = _("Default"), choice1_text = _("Default"),
choice1_callback = function() choice1_callback = function()
G_reader_settings:saveSetting("cre_font", face) G_reader_settings:saveSetting("cre_font", face)
if refresh_menu_func then refresh_menu_func() end if touchmenu_instance then touchmenu_instance:updateItems() end
end, end,
choice2_text = _("Fallback"), choice2_text = _("Fallback"),
choice2_callback = function() choice2_callback = function()
@ -325,7 +324,7 @@ function ReaderFont:makeDefault(face, refresh_menu_func)
G_reader_settings:saveSetting("fallback_font", face) G_reader_settings:saveSetting("fallback_font", face)
self.ui:handleEvent(Event:new("UpdatePos")) self.ui:handleEvent(Event:new("UpdatePos"))
end end
if refresh_menu_func then refresh_menu_func() end if touchmenu_instance then touchmenu_instance:updateItems() end
end, end,
}) })
end end

@ -103,7 +103,9 @@ function ReaderHighlight:genHighlightDrawerMenu()
callback = function() callback = function()
self.view.highlight.disabled = not self.view.highlight.disabled self.view.highlight.disabled = not self.view.highlight.disabled
end, end,
hold_callback = function() self:makeDefault(not self.view.highlight.disabled) end, hold_callback = function(touchmenu_instance)
self:makeDefault(not self.view.highlight.disabled)
end,
}, },
get_highlight_style("lighten"), get_highlight_style("lighten"),
get_highlight_style("underscore"), get_highlight_style("underscore"),
@ -736,7 +738,6 @@ function ReaderHighlight:makeDefault(highlight_disabled)
G_reader_settings:saveSetting("highlight_disabled", highlight_disabled) G_reader_settings:saveSetting("highlight_disabled", highlight_disabled)
end, end,
}) })
self.view.highlight.disabled = highlight_disabled
end end
return ReaderHighlight return ReaderHighlight

@ -112,8 +112,7 @@ function ReaderHyphenation:init()
-- signal readerrolling to update pos in new height, and redraw page -- signal readerrolling to update pos in new height, and redraw page
self.ui:handleEvent(Event:new("UpdatePos")) self.ui:handleEvent(Event:new("UpdatePos"))
end, end,
hold_may_update_menu = true, hold_callback = function(touchmenu_instance)
hold_callback = function(refresh_menu_func)
UIManager:show(MultiConfirmBox:new{ UIManager:show(MultiConfirmBox:new{
-- No real need for a way to remove default one, we can just -- No real need for a way to remove default one, we can just
-- toggle between setting a default OR a fallback (if a default -- toggle between setting a default OR a fallback (if a default
@ -125,13 +124,13 @@ function ReaderHyphenation:init()
choice1_callback = function() choice1_callback = function()
G_reader_settings:saveSetting("hyph_alg_default", v.filename) G_reader_settings:saveSetting("hyph_alg_default", v.filename)
G_reader_settings:delSetting("hyph_alg_fallback") G_reader_settings:delSetting("hyph_alg_fallback")
if refresh_menu_func then refresh_menu_func() end if touchmenu_instance then touchmenu_instance:updateItems() end
end, end,
choice2_text = _("Fallback"), choice2_text = _("Fallback"),
choice2_callback = function() choice2_callback = function()
G_reader_settings:saveSetting("hyph_alg_fallback", v.filename) G_reader_settings:saveSetting("hyph_alg_fallback", v.filename)
G_reader_settings:delSetting("hyph_alg_default") G_reader_settings:delSetting("hyph_alg_default")
if refresh_menu_func then refresh_menu_func() end if touchmenu_instance then touchmenu_instance:updateItems() end
end, end,
}) })
end, end,

@ -154,13 +154,15 @@ If any of the other Swipe to follow link options is enabled, this will work only
text = _("Go back to previous location"), text = _("Go back to previous location"),
enabled_func = function() return #self.location_stack > 0 end, enabled_func = function() return #self.location_stack > 0 end,
callback = function() self:onGoBackLink() end, callback = function() self:onGoBackLink() end,
hold_callback = function() UIManager:show(ConfirmBox:new{ hold_callback = function(touchmenu_instance)
text = _("Clear location history?"), UIManager:show(ConfirmBox:new{
ok_text = _("Clear"), text = _("Clear location history?"),
ok_callback = function() ok_text = _("Clear"),
self.location_stack = {} ok_callback = function()
end, self.location_stack = {}
}) touchmenu_instance:closeMenu()
end,
})
end, end,
} }
end end

@ -338,7 +338,6 @@ function ReaderStyleTweak:init()
self.enabled = not self.enabled self.enabled = not self.enabled
self:updateCssText(true) -- apply it immediately self:updateCssText(true) -- apply it immediately
end, end,
hold_may_update_menu = true, -- just to keep menu opened
hold_callback = function() hold_callback = function()
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
text = _( text = _(
@ -398,8 +397,7 @@ You can enable individual tweaks on this book with a tap, or view more details a
end end
return title return title
end, end,
hold_may_update_menu = true, hold_callback = function(touchmenu_instance)
hold_callback = function(refresh_menu_func)
UIManager:show(TweakInfoWidget:new{ UIManager:show(TweakInfoWidget:new{
tweak = item, tweak = item,
is_global_default = self.global_tweaks[item.id], is_global_default = self.global_tweaks[item.id],
@ -409,7 +407,7 @@ You can enable individual tweaks on this book with a tap, or view more details a
else else
self.global_tweaks[item.id] = true self.global_tweaks[item.id] = true
end end
refresh_menu_func() touchmenu_instance:updateItems()
self:updateCssText(true) -- apply it immediately self:updateCssText(true) -- apply it immediately
end end
}) })

@ -476,11 +476,12 @@ function ReaderToc:addToMainMenu(menu_items)
end, end,
} }
if self.ui.document:canHaveAlternativeToc() then if self.ui.document:canHaveAlternativeToc() then
menu_items.table_of_contents.hold_callback = function() menu_items.table_of_contents.hold_callback = function(touchmenu_instance)
if self.ui.document:isTocAlternativeToc() then if self.ui.document:isTocAlternativeToc() then
UIManager:show(ConfirmBox:new{ UIManager:show(ConfirmBox:new{
text = _("The table of content for this book is currently an alternative one built from the document headings.\nDo you want to get back the original table of content? (The book will be reloaded.)"), text = _("The table of content for this book is currently an alternative one built from the document headings.\nDo you want to get back the original table of content? (The book will be reloaded.)"),
ok_callback = function() ok_callback = function()
touchmenu_instance:closeMenu()
self.ui.doc_settings:delSetting("alternative_toc") self.ui.doc_settings:delSetting("alternative_toc")
self.ui.document:invalidateCacheFile() self.ui.document:invalidateCacheFile()
-- Allow for ConfirmBox to be closed before showing -- Allow for ConfirmBox to be closed before showing
@ -494,6 +495,7 @@ function ReaderToc:addToMainMenu(menu_items)
UIManager:show(ConfirmBox:new{ UIManager:show(ConfirmBox:new{
text = _("Do you want to use an alternative table of content built from the document headings?"), text = _("Do you want to use an alternative table of content built from the document headings?"),
ok_callback = function() ok_callback = function()
touchmenu_instance:closeMenu()
self:resetToc() self:resetToc()
self.ui.document:buildAlternativeToc() self.ui.document:buildAlternativeToc()
self.ui.doc_settings:saveSetting("alternative_toc", true) self.ui.doc_settings:saveSetting("alternative_toc", true)

@ -125,8 +125,8 @@ function ReaderTypeset:genStyleSheetMenu()
callback = function() callback = function()
self:setStyleSheet(css_file or self.ui.document.default_css) self:setStyleSheet(css_file or self.ui.document.default_css)
end, end,
hold_callback = function() hold_callback = function(touchmenu_instance)
self:makeDefaultStyleSheet(css_file, text) self:makeDefaultStyleSheet(css_file, text, touchmenu_instance)
end, end,
checked_func = function() checked_func = function()
if not css_file then -- "Auto" if not css_file then -- "Auto"
@ -301,11 +301,12 @@ function ReaderTypeset:makeDefaultFloatingPunctuation()
}) })
end end
function ReaderTypeset:makeDefaultStyleSheet(css, text) function ReaderTypeset:makeDefaultStyleSheet(css, text, touchmenu_instance)
UIManager:show(ConfirmBox:new{ UIManager:show(ConfirmBox:new{
text = T( _("Set default style to %1?"), text), text = T( _("Set default style to %1?"), text),
ok_callback = function() ok_callback = function()
G_reader_settings:saveSetting("copt_css", css) G_reader_settings:saveSetting("copt_css", css)
if touchmenu_instance then touchmenu_instance:updateItems() end
end, end,
}) })
end end

@ -118,6 +118,7 @@ function ReaderWikipedia:addToMainMenu(menu_items)
sub_item_table = { sub_item_table = {
{ {
text = _("Set Wikipedia languages"), text = _("Set Wikipedia languages"),
keep_menu_open = true,
callback = function() callback = function()
local wikilang_input local wikilang_input
local function save_wikilang() local function save_wikilang()
@ -171,6 +172,7 @@ function ReaderWikipedia:addToMainMenu(menu_items)
}, },
{ -- setting used by dictquicklookup { -- setting used by dictquicklookup
text = _("Set Wikipedia 'Save as EPUB' directory"), text = _("Set Wikipedia 'Save as EPUB' directory"),
keep_menu_open = true,
callback = function() callback = function()
local choose_directory = function() local choose_directory = function()
-- Default directory as chosen by DictQuickLookup -- Default directory as chosen by DictQuickLookup
@ -298,6 +300,7 @@ Where do you want them saved?]])
}, },
{ {
text = _("Clean Wikipedia history"), text = _("Clean Wikipedia history"),
keep_menu_open = true,
callback = function() callback = function()
UIManager:show(ConfirmBox:new{ UIManager:show(ConfirmBox:new{
text = _("Clean Wikipedia history?"), text = _("Clean Wikipedia history?"),

@ -318,62 +318,41 @@ end
function ReaderZooming:addToMainMenu(menu_items) function ReaderZooming:addToMainMenu(menu_items)
if self.ui.document.info.has_pages then if self.ui.document.info.has_pages then
local function getZoomModeMenuItem(text, mode, separator)
return {
text_func = function()
local default_zoom_mode = G_reader_settings:readSetting("zoom_mode") or self.DEFAULT_ZOOM_MODE
return text .. (mode == default_zoom_mode and "" or "")
end,
checked_func = function()
return self.zoom_mode == mode
end,
callback = self:genSetZoomModeCallBack(mode),
hold_callback = function(touchmenu_instance)
self:makeDefault(mode, touchmenu_instance)
end,
separator = separator,
}
end
menu_items.switch_zoom_mode = { menu_items.switch_zoom_mode = {
text = _("Switch zoom mode"), text = _("Switch zoom mode"),
enabled_func = function() enabled_func = function()
return self.ui.document.configurable.text_wrap ~= 1 return self.ui.document.configurable.text_wrap ~= 1
end, end,
sub_item_table = { sub_item_table = {
{ getZoomModeMenuItem(_("Zoom to fit content width"), "contentwidth"),
text = _("Zoom to fit content width"), getZoomModeMenuItem(_("Zoom to fit content height"), "contentheight", true),
checked_func = function() return self.zoom_mode == "contentwidth" end, getZoomModeMenuItem(_("Zoom to fit page width"), "pagewidth"),
callback = self:genSetZoomModeCallBack("contentwidth"), getZoomModeMenuItem(_("Zoom to fit page height"), "pageheight", true),
hold_callback = function() self:makeDefault("contentwidth") end, getZoomModeMenuItem(_("Zoom to fit column"), "column"),
}, getZoomModeMenuItem(_("Zoom to fit content"), "content"),
{ getZoomModeMenuItem(_("Zoom to fit page"), "page"),
text = _("Zoom to fit content height"),
checked_func = function() return self.zoom_mode == "contentheight" end,
callback = self:genSetZoomModeCallBack("contentheight"),
hold_callback = function() self:makeDefault("contentheight") end,
separator = true,
},
{
text = _("Zoom to fit page width"),
checked_func = function() return self.zoom_mode == "pagewidth" end,
callback = self:genSetZoomModeCallBack("pagewidth"),
hold_callback = function() self:makeDefault("pagewidth") end,
},
{
text = _("Zoom to fit page height"),
checked_func = function() return self.zoom_mode == "pageheight" end,
callback = self:genSetZoomModeCallBack("pageheight"),
hold_callback = function() self:makeDefault("pageheight") end,
separator = true,
},
{
text = _("Zoom to fit column"),
checked_func = function() return self.zoom_mode == "column" end,
callback = self:genSetZoomModeCallBack("column"),
hold_callback = function() self:makeDefault("column") end,
},
{
text = _("Zoom to fit content"),
checked_func = function() return self.zoom_mode == "content" end,
callback = self:genSetZoomModeCallBack("content"),
hold_callback = function() self:makeDefault("content") end,
},
{
text = _("Zoom to fit page"),
checked_func = function() return self.zoom_mode == "page" end,
callback = self:genSetZoomModeCallBack("page"),
hold_callback = function() self:makeDefault("page") end,
},
} }
} }
end end
end end
function ReaderZooming:makeDefault(zoom_mode) function ReaderZooming:makeDefault(zoom_mode, touchmenu_instance)
UIManager:show(ConfirmBox:new{ UIManager:show(ConfirmBox:new{
text = T( text = T(
_("Set default zoom mode to %1?"), _("Set default zoom mode to %1?"),
@ -381,6 +360,7 @@ function ReaderZooming:makeDefault(zoom_mode)
), ),
ok_callback = function() ok_callback = function()
G_reader_settings:saveSetting("zoom_mode", zoom_mode) G_reader_settings:saveSetting("zoom_mode", zoom_mode)
if touchmenu_instance then touchmenu_instance:updateItems() end
end, end,
}) })
end end

@ -15,6 +15,7 @@ end
local version = require("version"):getCurrentRevision() local version = require("version"):getCurrentRevision()
common_info.version = { common_info.version = {
text = _("Version"), text = _("Version"),
keep_menu_open = true,
callback = function() callback = function()
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
text = version, text = version,
@ -41,6 +42,7 @@ common_info.quickstart_guide = {
} }
common_info.about = { common_info.about = {
text = _("About"), text = _("About"),
keep_menu_open = true,
callback = function() callback = function()
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
text = T(_("KOReader %1\n\nA document viewer for E Ink devices.\n\nLicensed under Affero GPL v3. All dependencies are free software.\n\nhttp://koreader.rocks/"), version), text = T(_("KOReader %1\n\nA document viewer for E Ink devices.\n\nLicensed under Affero GPL v3. All dependencies are free software.\n\nhttp://koreader.rocks/"), version),
@ -49,6 +51,7 @@ common_info.about = {
} }
common_info.report_bug = { common_info.report_bug = {
text = _("Report a bug"), text = _("Report a bug"),
keep_menu_open = true,
callback = function() callback = function()
local model = Device.model local model = Device.model
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
@ -69,6 +72,7 @@ end
if Device:isKobo() then if Device:isKobo() then
common_info.reboot = { common_info.reboot = {
text = _("Reboot the device"), text = _("Reboot the device"),
keep_menu_open = true,
callback = function() callback = function()
UIManager:show(ConfirmBox:new{ UIManager:show(ConfirmBox:new{
text = _("Are you sure you want to reboot the device?"), text = _("Are you sure you want to reboot the device?"),
@ -81,6 +85,7 @@ if Device:isKobo() then
} }
common_info.poweroff = { common_info.poweroff = {
text = _("Power off"), text = _("Power off"),
keep_menu_open = true,
callback = function() callback = function()
UIManager:show(ConfirmBox:new{ UIManager:show(ConfirmBox:new{
text = _("Are you sure you want to power off the device?"), text = _("Are you sure you want to power off the device?"),

@ -27,6 +27,7 @@ if Device:setDateTime() then
sub_item_table = { sub_item_table = {
{ {
text = _("Set time"), text = _("Set time"),
keep_menu_open = true,
callback = function() callback = function()
local now_t = os.date("*t") local now_t = os.date("*t")
local curr_hour = now_t.hour local curr_hour = now_t.hour
@ -55,6 +56,7 @@ if Device:setDateTime() then
}, },
{ {
text = _("Set date"), text = _("Set date"),
keep_menu_open = true,
callback = function() callback = function()
local now_t = os.date("*t") local now_t = os.date("*t")
local curr_year = now_t.year local curr_year = now_t.year

@ -113,18 +113,21 @@ return {
sub_item_table = { sub_item_table = {
{ {
text = _("Screensaver folder"), text = _("Screensaver folder"),
keep_menu_open = true,
callback = function() callback = function()
Screensaver:chooseFolder() Screensaver:chooseFolder()
end, end,
}, },
{ {
text = _("Screensaver image"), text = _("Screensaver image"),
keep_menu_open = true,
callback = function() callback = function()
Screensaver:chooseFile() Screensaver:chooseFile()
end, end,
}, },
{ {
text = _("Screensaver message"), text = _("Screensaver message"),
keep_menu_open = true,
callback = function() callback = function()
Screensaver:setMessage() Screensaver:setMessage()
end, end,

@ -123,11 +123,11 @@ function NetworkMgr:getWifiMenuTable()
text = _("Wi-Fi connection"), text = _("Wi-Fi connection"),
enabled_func = function() return Device:isAndroid() or Device:isKindle() or Device:isKobo() end, enabled_func = function() return Device:isAndroid() or Device:isKindle() or Device:isKobo() end,
checked_func = function() return NetworkMgr:isOnline() end, checked_func = function() return NetworkMgr:isOnline() end,
callback = function(menu) callback = function(touchmenu_instance)
local wifi_status = NetworkMgr:isOnline() local wifi_status = NetworkMgr:isOnline()
local complete_callback = function() local complete_callback = function()
-- notify touch menu to update item check state -- notify touch menu to update item check state
menu:updateItems() touchmenu_instance:updateItems()
local Event = require("ui/event") local Event = require("ui/event")
-- if wifi was on, this callback will only be executed when the network has been -- if wifi was on, this callback will only be executed when the network has been
-- disconnected. -- disconnected.
@ -188,16 +188,17 @@ function NetworkMgr:getRestoreMenuTable()
text = _("Automatically restore Wi-Fi connection after resume"), text = _("Automatically restore Wi-Fi connection after resume"),
checked_func = function() return G_reader_settings:nilOrTrue("auto_restore_wifi") end, checked_func = function() return G_reader_settings:nilOrTrue("auto_restore_wifi") end,
enabled_func = function() return Device:isKobo() end, enabled_func = function() return Device:isKobo() end,
callback = function(menu) G_reader_settings:flipNilOrTrue("auto_restore_wifi") end, callback = function() G_reader_settings:flipNilOrTrue("auto_restore_wifi") end,
} }
end end
function NetworkMgr:getInfoMenuTable() function NetworkMgr:getInfoMenuTable()
return { return {
text = _("Network info"), text = _("Network info"),
keep_menu_open = true,
-- TODO: also show network info when device is authenticated to router but offline -- TODO: also show network info when device is authenticated to router but offline
enabled_func = function() return self:isOnline() end, enabled_func = function() return self:isOnline() end,
callback = function(menu) callback = function()
if Device.retrieveNetworkInfo then if Device.retrieveNetworkInfo then
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
text = Device:retrieveNetworkInfo(), text = Device:retrieveNetworkInfo(),
@ -249,7 +250,7 @@ function NetworkMgr:getDismissScanMenuTable()
text = _("Dismiss Wi-Fi scan popup after connection"), text = _("Dismiss Wi-Fi scan popup after connection"),
checked_func = function() return G_reader_settings:nilOrTrue("auto_dismiss_wifi_scan") end, checked_func = function() return G_reader_settings:nilOrTrue("auto_dismiss_wifi_scan") end,
--enabled_func = function() return Device:isKobo() end, --enabled_func = function() return Device:isKobo() end,
callback = function(menu) G_reader_settings:flipNilOrTrue("auto_dismiss_wifi_scan") end, callback = function() G_reader_settings:flipNilOrTrue("auto_dismiss_wifi_scan") end,
} }
end end

@ -143,6 +143,7 @@ local InputDialog = InputContainer:new{
-- This string is then shown: -- This string is then shown:
-- - on success: as the notification text instead of the default one -- - on success: as the notification text instead of the default one
-- - on failure: in an InfoMessage -- - on failure: in an InfoMessage
close_callback = nil, -- Called when closing (if discarded or saved, after save_callback if saved)
-- For use by TextEditor plugin: -- For use by TextEditor plugin:
view_pos_callback = nil, -- Called with no arg to get initial top_line_num/charpos, view_pos_callback = nil, -- Called with no arg to get initial top_line_num/charpos,
@ -607,6 +608,7 @@ function InputDialog:_addSaveCloseButtons()
cancel_text = self.close_cancel_button_text or _("Cancel"), cancel_text = self.close_cancel_button_text or _("Cancel"),
choice1_text = self.close_discard_button_text or _("Discard"), choice1_text = self.close_discard_button_text or _("Discard"),
choice1_callback = function() choice1_callback = function()
if self.close_callback then self.close_callback() end
UIManager:close(self) UIManager:close(self)
UIManager:show(Notification:new{ UIManager:show(Notification:new{
text = self.close_discarded_notif_text or _("Changes discarded"), text = self.close_discarded_notif_text or _("Changes discarded"),
@ -626,6 +628,7 @@ function InputDialog:_addSaveCloseButtons()
}) })
end end
else -- nil or true else -- nil or true
if self.close_callback then self.close_callback() end
UIManager:close(self) UIManager:close(self)
UIManager:show(Notification:new{ UIManager:show(Notification:new{
text = msg or _("Saved"), text = msg or _("Saved"),
@ -637,6 +640,7 @@ function InputDialog:_addSaveCloseButtons()
}) })
else else
-- Not modified, exit without any message -- Not modified, exit without any message
if self.close_callback then self.close_callback() end
UIManager:close(self) UIManager:close(self)
end end
end, end,

@ -693,7 +693,9 @@ function TouchMenu:onMenuSelect(item)
self.touch_menu_callback() self.touch_menu_callback()
end end
if item.tap_input or type(item.tap_input_func) == "function" then if item.tap_input or type(item.tap_input_func) == "function" then
self:closeMenu() if not item.keep_menu_open then
self:closeMenu()
end
if item.tap_input then if item.tap_input then
self:onInput(item.tap_input) self:onInput(item.tap_input)
else else
@ -714,10 +716,14 @@ function TouchMenu:onMenuSelect(item)
-- put stuff in scheduler so we can see -- put stuff in scheduler so we can see
-- the effect of inverted menu item -- the effect of inverted menu item
UIManager:tickAfterNext(function() UIManager:tickAfterNext(function()
-- Provide callback with us, so it can call our
-- closemenu() or updateItems() when it sees fit
-- (if not providing checked or checked_fund, caller
-- must set keep_menu_open=true if that is wished)
callback(self) callback(self)
if refresh then if refresh then
self:updateItems() self:updateItems()
else elseif not item.keep_menu_open then
self:closeMenu() self:closeMenu()
end end
end) end)
@ -737,7 +743,9 @@ function TouchMenu:onMenuHold(item)
self.touch_menu_callback() self.touch_menu_callback()
end end
if item.hold_input or type(item.hold_input_func) == "function" then if item.hold_input or type(item.hold_input_func) == "function" then
self:closeMenu() if item.hold_keep_menu_open == false then
self:closeMenu()
end
if item.hold_input then if item.hold_input then
self:onInput(item.hold_input) self:onInput(item.hold_input)
else else
@ -750,12 +758,15 @@ function TouchMenu:onMenuHold(item)
end end
if callback then if callback then
UIManager:tickAfterNext(function() UIManager:tickAfterNext(function()
if item.hold_may_update_menu then -- With hold, the default is to keep menu open, as we're
callback(function() self:updateItems() end) -- most often showing a ConfirmBox that can be cancelled
else -- (provide hold_keep_menu_open=false to override)
if item.hold_keep_menu_open == false then
self:closeMenu() self:closeMenu()
callback()
end end
-- Provide callback with us, so it can call our
-- closemenu() or updateItems() when it sees fit
callback(self)
end) end)
end end
elseif item.help_text or type(item.help_text_func) == "function" then elseif item.help_text or type(item.help_text_func) == "function" then

@ -4,10 +4,11 @@ local InfoMessage = require("ui/widget/infomessage") -- luacheck:ignore
local InputDialog = require("ui/widget/inputdialog") local InputDialog = require("ui/widget/inputdialog")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local WidgetContainer = require("ui/widget/container/widgetcontainer") local WidgetContainer = require("ui/widget/container/widgetcontainer")
local ffiutil = require("ffi/util")
local logger = require("logger") local logger = require("logger")
local util = require("util") local util = require("util")
local _ = require("gettext") local _ = require("gettext")
local T = require("ffi/util").template local T = ffiutil.template
-- This plugin uses a patched dropbear that adds two things: -- This plugin uses a patched dropbear that adds two things:
-- the -n option to bypass password checks -- the -n option to bypass password checks
@ -136,16 +137,31 @@ function SSH:addToMainMenu(menu_items)
sub_item_table = { sub_item_table = {
{ {
text = _("Start SSH server"), text = _("Start SSH server"),
callback = function() return self:start() end, keep_menu_open = true,
callback = function(touchmenu_instance)
self:start()
-- sleeping might not be needed, but it gives the feeling
-- something has been done and feedback is accurate
ffiutil.sleep(1)
touchmenu_instance:updateItems()
end,
enabled_func = function() return not self:isRunning() end, enabled_func = function() return not self:isRunning() end,
}, },
{ {
text = _("Stop SSH server"), text = _("Stop SSH server"),
callback = function() return self:stop() end, keep_menu_open = true,
callback = function(touchmenu_instance)
self:stop()
-- sleeping might not be needed, but it gives the feeling
-- something has been done and feedback is accurate
ffiutil.sleep(1)
touchmenu_instance:updateItems()
end,
enabled_func = function() return self:isRunning() end, enabled_func = function() return self:isRunning() end,
}, },
{ {
text = _("Change SSH port"), text = _("Change SSH port"),
keep_menu_open = true,
enabled_func = function() return not self:isRunning() end, enabled_func = function() return not self:isRunning() end,
callback = function() return self:show_port_dialog() end, callback = function() return self:show_port_dialog() end,
}, },
@ -157,6 +173,7 @@ function SSH:addToMainMenu(menu_items)
}, },
{ {
text = _("SSH public key"), text = _("SSH public key"),
keep_menu_open = true,
callback = function() callback = function()
local info = InfoMessage:new{ local info = InfoMessage:new{
timeout = 60, timeout = 60,

@ -293,6 +293,7 @@ end
function BatteryStatWidget:addToMainMenu(menu_items) function BatteryStatWidget:addToMainMenu(menu_items)
menu_items.battery_statistics = { menu_items.battery_statistics = {
text = _("Battery statistics"), text = _("Battery statistics"),
keep_menu_open = true,
callback = function() callback = function()
BatteryStat:showStatistics() BatteryStat:showStatistics()
end, end,

@ -334,6 +334,7 @@ function CoverBrowser:addToMainMenu(menu_items)
}, },
{ {
text = _("Prune cache of removed books"), text = _("Prune cache of removed books"),
keep_menu_open = true,
callback = function() callback = function()
local ConfirmBox = require("ui/widget/confirmbox") local ConfirmBox = require("ui/widget/confirmbox")
UIManager:close(self.file_dialog) UIManager:close(self.file_dialog)
@ -356,6 +357,7 @@ function CoverBrowser:addToMainMenu(menu_items)
}, },
{ {
text = _("Compact cache database"), text = _("Compact cache database"),
keep_menu_open = true,
callback = function() callback = function()
local ConfirmBox = require("ui/widget/confirmbox") local ConfirmBox = require("ui/widget/confirmbox")
UIManager:close(self.file_dialog) UIManager:close(self.file_dialog)
@ -377,6 +379,7 @@ function CoverBrowser:addToMainMenu(menu_items)
}, },
{ {
text = _("Delete cache database"), text = _("Delete cache database"),
keep_menu_open = true,
callback = function() callback = function()
local ConfirmBox = require("ui/widget/confirmbox") local ConfirmBox = require("ui/widget/confirmbox")
UIManager:close(self.file_dialog) UIManager:close(self.file_dialog)

@ -29,12 +29,15 @@ function Goodreads:addToMainMenu(menu_items)
sub_item_table = { sub_item_table = {
{ {
text = _("Settings"), text = _("Settings"),
keep_menu_open = true,
callback = function() self:updateSettings() end, callback = function() self:updateSettings() end,
}, },
{ {
text = _("Search all books"), text = _("Search all books"),
callback = function() keep_menu_open = true,
callback = function(touchmenu_instance)
if self.goodreads_key ~= "" then if self.goodreads_key ~= "" then
touchmenu_instance:closeMenu()
self:search("all") self:search("all")
else else
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
@ -45,8 +48,10 @@ function Goodreads:addToMainMenu(menu_items)
}, },
{ {
text = _("Search for book by title"), text = _("Search for book by title"),
callback = function() keep_menu_open = true,
callback = function(touchmenu_instance)
if self.goodreads_key ~= "" then if self.goodreads_key ~= "" then
touchmenu_instance:closeMenu()
self:search("title") self:search("title")
else else
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
@ -57,10 +62,11 @@ function Goodreads:addToMainMenu(menu_items)
}, },
{ {
text = _("Search for book by author"), text = _("Search for book by author"),
callback = function() keep_menu_open = true,
callback = function(touchmenu_instance)
if self.goodreads_key ~= "" then if self.goodreads_key ~= "" then
touchmenu_instance:closeMenu()
self:search("author") self:search("author")
else else
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
text = _("Please set up your Goodreads key in the settings dialog"), text = _("Please set up your Goodreads key in the settings dialog"),

@ -230,6 +230,7 @@ end
function KoboLight:addToMainMenu(menu_items) function KoboLight:addToMainMenu(menu_items)
menu_items.frontlight_gesture_controller = { menu_items.frontlight_gesture_controller = {
text = _("Frontlight gesture controller"), text = _("Frontlight gesture controller"),
keep_menu_open = true,
callback = function() callback = function()
local image_name local image_name
local nl_text = "" local nl_text = ""

@ -94,6 +94,7 @@ function KOSync:addToMainMenu(menu_items)
return self.kosync_userkey and (_("Logout")) return self.kosync_userkey and (_("Logout"))
or _("Register") .. " / " .. _("Login") or _("Register") .. " / " .. _("Login")
end, end,
keep_menu_open = true,
callback_func = function() callback_func = function()
return self.kosync_userkey and return self.kosync_userkey and
function() self:logout() end or function() self:logout() end or
@ -205,6 +206,7 @@ function KOSync:addToMainMenu(menu_items)
}, },
{ {
text = _("Custom sync server"), text = _("Custom sync server"),
keep_menu_open = true,
tap_input_func = function() tap_input_func = function()
return { return {
title = _("Custom progress sync server address"), title = _("Custom progress sync server address"),

@ -74,6 +74,7 @@ function NewsDownloader:addToMainMenu(menu_items)
sub_item_table = { sub_item_table = {
{ {
text = _("Download news"), text = _("Download news"),
keep_menu_open = true,
callback = function() callback = function()
if not NetworkMgr:isOnline() then if not NetworkMgr:isOnline() then
wifi_enabled_before_action = false wifi_enabled_before_action = false
@ -96,6 +97,7 @@ function NewsDownloader:addToMainMenu(menu_items)
}, },
{ {
text = _("Remove news"), text = _("Remove news"),
keep_menu_open = true,
callback = function() self:removeNewsButKeepFeedConfig() end, callback = function() self:removeNewsButKeepFeedConfig() end,
}, },
{ {
@ -103,16 +105,19 @@ function NewsDownloader:addToMainMenu(menu_items)
sub_item_table = { sub_item_table = {
{ {
text = _("Change feeds configuration"), text = _("Change feeds configuration"),
keep_menu_open = true,
callback = function() self:changeFeedConfig() end, callback = function() self:changeFeedConfig() end,
}, },
{ {
text = _("Set custom download directory"), text = _("Set custom download directory"),
keep_menu_open = true,
callback = function() self:setCustomDownloadDirectory() end, callback = function() self:setCustomDownloadDirectory() end,
}, },
}, },
}, },
{ {
text = _("Help"), text = _("Help"),
keep_menu_open = true,
callback = function() callback = function()
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
text = T(_("News downloader retrieves RSS and Atom news entries and stores them to:\n%1\n\nEach entry is a separate html file, that can be browsed by KOReader file manager.\nItems download limit can be configured in Settings."), text = T(_("News downloader retrieves RSS and Atom news entries and stores them to:\n%1\n\nEach entry is a separate html file, that can be browsed by KOReader file manager.\nItems download limit can be configured in Settings."),

@ -173,12 +173,14 @@ function PerceptionExpander:addToMainMenu(menu_items)
}, },
{ {
text = _("Settings"), text = _("Settings"),
keep_menu_open = true,
callback = function() callback = function()
self:showSettingsDialog() self:showSettingsDialog()
end, end,
}, },
{ {
text = _("About"), text = _("About"),
keep_menu_open = true,
callback = function() callback = function()
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
text = _("For more information see wiki page Perception Expander Plugin"), text = _("For more information see wiki page Perception Expander Plugin"),

@ -69,7 +69,8 @@ function ReadTimer:addToMainMenu(menu_items)
sub_item_table = { sub_item_table = {
{ {
text = _("Time"), text = _("Time"),
callback = function() keep_menu_open = true,
callback = function(touchmenu_instance)
local now_t = os.date("*t") local now_t = os.date("*t")
local curr_hour = now_t.hour local curr_hour = now_t.hour
local curr_min = now_t.min local curr_min = now_t.min
@ -80,6 +81,7 @@ function ReadTimer:addToMainMenu(menu_items)
ok_text = _("Set timer"), ok_text = _("Set timer"),
title_text = _("Set reader timer"), title_text = _("Set reader timer"),
callback = function(time) callback = function(time)
touchmenu_instance:closeMenu()
self:unschedule() self:unschedule()
local timer_sec_from_mignight = time.hour*3600 + time.min*60 local timer_sec_from_mignight = time.hour*3600 + time.min*60
local seconds local seconds
@ -125,7 +127,8 @@ function ReadTimer:addToMainMenu(menu_items)
}, },
{ {
text = _("Minutes from now"), text = _("Minutes from now"),
callback = function() keep_menu_open = true,
callback = function(touchmenu_instance)
local remain_time = {} local remain_time = {}
local remain_hours, remain_minutes = self:remainingTime() local remain_hours, remain_minutes = self:remainingTime()
if not remain_hours and not remain_minutes then if not remain_hours and not remain_minutes then
@ -142,6 +145,7 @@ function ReadTimer:addToMainMenu(menu_items)
ok_text = _("Set timer"), ok_text = _("Set timer"),
title_text = _("Set reader timer from now (hours:minutes)"), title_text = _("Set reader timer from now (hours:minutes)"),
callback = function(time) callback = function(time)
touchmenu_instance:closeMenu()
self:unschedule() self:unschedule()
local seconds = time.hour * 3600 + time.min * 60 local seconds = time.hour * 3600 + time.min * 60
if seconds > 0 then if seconds > 0 then
@ -175,11 +179,13 @@ function ReadTimer:addToMainMenu(menu_items)
}, },
{ {
text = _("Stop timer"), text = _("Stop timer"),
keep_menu_open = true,
enabled_func = function() enabled_func = function()
return self:scheduled() return self:scheduled()
end, end,
callback = function() callback = function(touchmenu_instance)
self:unschedule() self:unschedule()
touchmenu_instance:updateItems()
end, end,
}, },
}, },

@ -62,6 +62,7 @@ function Send2Ebook:addToMainMenu(menu_items)
sub_item_table = { sub_item_table = {
{ {
text = _("Download and remove from server"), text = _("Download and remove from server"),
keep_menu_open = true,
callback = function() callback = function()
if not NetworkMgr:isOnline() then if not NetworkMgr:isOnline() then
wifi_enabled_before_action = false wifi_enabled_before_action = false
@ -84,18 +85,22 @@ function Send2Ebook:addToMainMenu(menu_items)
}, },
{ {
text = _("Remove read (opened) articles"), text = _("Remove read (opened) articles"),
keep_menu_open = true,
callback = self.removeReadActicles, callback = self.removeReadActicles,
}, },
{ {
text = _("Set custom download directory"), text = _("Set custom download directory"),
keep_menu_open = true,
callback = self.setCustomDownloadDirectory, callback = self.setCustomDownloadDirectory,
}, },
{ {
text = _("Settings"), text = _("Settings"),
keep_menu_open = true,
callback = self.editFtpConnection, callback = self.editFtpConnection,
}, },
{ {
text = _("Help"), text = _("Help"),
keep_menu_open = true,
callback = function() callback = function()
UIManager:show(InfoMessage:new{ UIManager:show(InfoMessage:new{
text = T(_('Send2Ebook lets you send articles found on PC/Android phone to your Ebook reader (using ftp server).\n\nMore details: https://github.com/mwoz123/send2ebook\n\nDownloads to local folder: %1'), download_dir_path) text = T(_('Send2Ebook lets you send articles found on PC/Android phone to your Ebook reader (using ftp server).\n\nMore details: https://github.com/mwoz123/send2ebook\n\nDownloads to local folder: %1'), download_dir_path)

@ -676,16 +676,19 @@ function ReaderStatistics:addToMainMenu(menu_items)
self:getStatisticEnabledMenuItem(), self:getStatisticEnabledMenuItem(),
{ {
text = _("Settings"), text = _("Settings"),
keep_menu_open = true,
callback = function() self:updateSettings() end, callback = function() self:updateSettings() end,
}, },
{ {
text = _("Reset book statistics"), text = _("Reset book statistics"),
keep_menu_open = true,
callback = function() callback = function()
self:resetBook() self:resetBook()
end end
}, },
{ {
text = _("Current book"), text = _("Current book"),
keep_menu_open = true,
callback = function() callback = function()
UIManager:show(KeyValuePage:new{ UIManager:show(KeyValuePage:new{
title = _("Statistics"), title = _("Statistics"),
@ -696,6 +699,7 @@ function ReaderStatistics:addToMainMenu(menu_items)
}, },
{ {
text = _("Reading progress"), text = _("Reading progress"),
keep_menu_open = true,
callback = function() callback = function()
self:insertDB(self.id_curr_book) self:insertDB(self.id_curr_book)
local current_period, current_pages = self:getCurrentBookStats() local current_period, current_pages = self:getCurrentBookStats()
@ -717,6 +721,7 @@ function ReaderStatistics:addToMainMenu(menu_items)
}, },
{ {
text = _("Time range"), text = _("Time range"),
keep_menu_open = true,
callback = function() callback = function()
self:statMenu() self:statMenu()
end end

@ -249,6 +249,7 @@ end
function SystemStatWidget:addToMainMenu(menu_items) function SystemStatWidget:addToMainMenu(menu_items)
menu_items.system_statistics = { menu_items.system_statistics = {
text = _("System statistics"), text = _("System statistics"),
keep_menu_open = true,
callback = function() callback = function()
SystemStat:showStatistics() SystemStat:showStatistics()
end, end,

@ -88,6 +88,7 @@ end
function Terminal:addToMainMenu(menu_items) function Terminal:addToMainMenu(menu_items)
menu_items.terminal = { menu_items.terminal = {
text = _("Terminal emulator"), text = _("Terminal emulator"),
keep_menu_open = true,
callback = function() callback = function()
self:start() self:start()
end, end,

@ -78,12 +78,14 @@ end
function TextEditor:getSubMenuItems() function TextEditor:getSubMenuItems()
self:loadSettings() self:loadSettings()
self.whenDoneFunc = nil -- discard reference to previous TouchMenu instance
local sub_item_table = { local sub_item_table = {
{ {
text = _("Text editor settings"), text = _("Text editor settings"),
sub_item_table = { sub_item_table = {
{ {
text = _("Set text font size"), text = _("Set text font size"),
keep_menu_open = true,
callback = function() callback = function()
local SpinWidget = require("ui/widget/spinwidget") local SpinWidget = require("ui/widget/spinwidget")
local font_size = self.font_size local font_size = self.font_size
@ -118,13 +120,17 @@ function TextEditor:getSubMenuItems()
}, },
{ {
text = _("Select a file to open"), text = _("Select a file to open"),
callback = function() keep_menu_open = true,
callback = function(touchmenu_instance)
self:setupWhenDoneFunc(touchmenu_instance)
self:chooseFile() self:chooseFile()
end, end,
}, },
{ {
text = _("Edit a new empty file"), text = _("Edit a new empty file"),
callback = function() keep_menu_open = true,
callback = function(touchmenu_instance)
self:setupWhenDoneFunc(touchmenu_instance)
self:newFile() self:newFile()
end, end,
separator = true, separator = true,
@ -135,10 +141,13 @@ function TextEditor:getSubMenuItems()
local directory, filename = util.splitFilePathName(file_path) -- luacheck: no unused local directory, filename = util.splitFilePathName(file_path) -- luacheck: no unused
table.insert(sub_item_table, { table.insert(sub_item_table, {
text = T("%1. %2", i, filename), text = T("%1. %2", i, filename),
callback = function() keep_menu_open = true,
callback = function(touchmenu_instance)
self:setupWhenDoneFunc(touchmenu_instance)
self:checkEditFile(file_path, true) self:checkEditFile(file_path, true)
end, end,
hold_callback = function() _texteditor_id = file_path, -- for removal from menu itself
hold_callback = function(touchmenu_instance)
-- Show full path and some info, and propose to remove from history -- Show full path and some info, and propose to remove from history
local text local text
local attr = lfs.attributes(file_path) local attr = lfs.attributes(file_path)
@ -157,6 +166,14 @@ function TextEditor:getSubMenuItems()
cancel_text = _("No"), cancel_text = _("No"),
ok_callback = function() ok_callback = function()
self:removeFromHistory(file_path) self:removeFromHistory(file_path)
-- Also remove from menu itself
for j=1, #sub_item_table do
if sub_item_table[j]._texteditor_id == file_path then
table.remove(sub_item_table, j)
break
end
end
touchmenu_instance:updateItems()
end, end,
}) })
end, end,
@ -165,6 +182,26 @@ function TextEditor:getSubMenuItems()
return sub_item_table return sub_item_table
end end
function TextEditor:setupWhenDoneFunc(touchmenu_instance)
-- This will keep a reference to the TouchMenu instance, that may not
-- get released if file opening is aborted while in the file selection
-- widgets and dialogs (quite complicated to call a resetWhenDoneFunc()
-- in every abort case). But :getSubMenuItems() will release it when
-- the TextEditor menu is opened again.
self.whenDoneFunc = function()
touchmenu_instance.item_table = self:getSubMenuItems()
touchmenu_instance.page = 1
touchmenu_instance:updateItems()
end
end
function TextEditor:execWhenDoneFunc()
if self.whenDoneFunc then
self.whenDoneFunc()
self.whenDoneFunc = nil
end
end
function TextEditor:removeFromHistory(file_path) function TextEditor:removeFromHistory(file_path)
for i=#self.history, 1, -1 do for i=#self.history, 1, -1 do
if self.history[i] == file_path then if self.history[i] == file_path then
@ -416,6 +453,10 @@ function TextEditor:editFile(file_path, readonly)
reset_callback = function(content) -- Will add a Reset button reset_callback = function(content) -- Will add a Reset button
return self:readFileContent(file_path), _("Text reset to last saved content") return self:readFileContent(file_path), _("Text reset to last saved content")
end, end,
-- Close callback
close_callback = function()
self:execWhenDoneFunc()
end,
-- File saving callback -- File saving callback
save_callback = function(content, closing) -- Will add Save/Close buttons save_callback = function(content, closing) -- Will add Save/Close buttons
if self.readonly then if self.readonly then

@ -56,6 +56,7 @@ end
local menuItem = { local menuItem = {
text = _("Synchronize time"), text = _("Synchronize time"),
keep_menu_open = true,
callback = function() callback = function()
if NetworkMgr:isOnline() then if NetworkMgr:isOnline() then
execute() execute()

Loading…
Cancel
Save