diff --git a/base b/base
index 502bba07e..96c002d52 160000
--- a/base
+++ b/base
@@ -1 +1 @@
-Subproject commit 502bba07e57e652dcf85f0b2a5c6b1d52fbc0f75
+Subproject commit 96c002d5260b09148def07913b5e4363d9a58c23
diff --git a/frontend/apps/reader/modules/readerdictionary.lua b/frontend/apps/reader/modules/readerdictionary.lua
index cd72bbf01..06293296b 100644
--- a/frontend/apps/reader/modules/readerdictionary.lua
+++ b/frontend/apps/reader/modules/readerdictionary.lua
@@ -800,7 +800,7 @@ function ReaderDictionary:startSdcv(word, dict_names, fuzzy_search)
-- dummy results
final_results = {
{
- dict = "",
+ dict = _("Not available"),
word = word,
definition = lookup_cancelled and _("Dictionary lookup interrupted.") or _("No results."),
no_result = true,
@@ -849,6 +849,22 @@ function ReaderDictionary:stardictLookup(word, dict_names, fuzzy_search, box, li
return
end
+ -- If the user disabled all the dictionaries, go away.
+ if dict_names and #dict_names == 0 then
+ -- Dummy result
+ local nope = {
+ {
+ dict = _("Not available"),
+ word = word,
+ definition = _("There are no enabled dictionaries.\nPlease check the 'Dictionary settings' menu."),
+ no_result = true,
+ lookup_cancelled = false,
+ }
+ }
+ self:showDict(word, nope, box, link)
+ return
+ end
+
self:showLookupInfo(word, self.lookup_msg_delay)
self._lookup_start_tv = UIManager:getTime()
diff --git a/frontend/apps/reader/modules/readerfont.lua b/frontend/apps/reader/modules/readerfont.lua
index 2deb7abca..6fd82b6c9 100644
--- a/frontend/apps/reader/modules/readerfont.lua
+++ b/frontend/apps/reader/modules/readerfont.lua
@@ -209,7 +209,7 @@ function ReaderFont:onSetFontSize(new_size)
self.font_size = new_size
self.ui.document:setFontSize(Screen:scaleBySize(new_size))
self.ui:handleEvent(Event:new("UpdatePos"))
- Notification:notify(T(_("Font size set to %1."), self.font_size))
+ Notification:notify(T(_("Font size set to: %1."), self.font_size))
return true
end
@@ -217,7 +217,7 @@ function ReaderFont:onSetLineSpace(space)
self.line_space_percent = math.min(200, math.max(50, space))
self.ui.document:setInterlineSpacePercent(self.line_space_percent)
self.ui:handleEvent(Event:new("UpdatePos"))
- Notification:notify(T(_("Line spacing set to %1%."), self.line_space_percent))
+ Notification:notify(T(_("Line spacing set to: %1%."), self.line_space_percent))
return true
end
@@ -225,7 +225,7 @@ function ReaderFont:onSetFontBaseWeight(weight)
self.font_base_weight = weight
self.ui.document:setFontBaseWeight(weight)
self.ui:handleEvent(Event:new("UpdatePos"))
- Notification:notify(T(_("Font weight set to %1."), optionsutil:getOptionText("SetFontBaseWeight", weight)))
+ Notification:notify(T(_("Font weight set to: %1."), optionsutil:getOptionText("SetFontBaseWeight", weight)))
return true
end
@@ -233,7 +233,7 @@ function ReaderFont:onSetFontHinting(mode)
self.font_hinting = mode
self.ui.document:setFontHinting(mode)
self.ui:handleEvent(Event:new("UpdatePos"))
- Notification:notify(T(_("Font hinting set to %1."), optionsutil:getOptionText("SetFontHinting", mode)))
+ Notification:notify(T(_("Font hinting set to: %1"), optionsutil:getOptionText("SetFontHinting", mode)))
return true
end
@@ -241,7 +241,7 @@ function ReaderFont:onSetFontKerning(mode)
self.font_kerning = mode
self.ui.document:setFontKerning(mode)
self.ui:handleEvent(Event:new("UpdatePos"))
- Notification:notify(T(_("Font kerning set to %1."), optionsutil:getOptionText("SetFontKerning", mode)))
+ Notification:notify(T(_("Font kerning set to: %1"), optionsutil:getOptionText("SetFontKerning", mode)))
return true
end
@@ -249,7 +249,7 @@ function ReaderFont:onSetWordSpacing(values)
self.word_spacing = values
self.ui.document:setWordSpacing(values)
self.ui:handleEvent(Event:new("UpdatePos"))
- Notification:notify(T(_("Word spacing set to %1%, %2%."), values[1], values[2]))
+ Notification:notify(T(_("Word spacing set to: %1%, %2%"), values[1], values[2]))
return true
end
@@ -257,7 +257,7 @@ function ReaderFont:onSetWordExpansion(value)
self.word_expansion = value
self.ui.document:setWordExpansion(value)
self.ui:handleEvent(Event:new("UpdatePos"))
- Notification:notify(T(_("Word expansion set to %1%."), value))
+ Notification:notify(T(_("Word expansion set to: %1%."), value))
return true
end
@@ -266,7 +266,7 @@ function ReaderFont:onSetFontGamma(gamma)
self.ui.document:setGammaIndex(self.gamma_index)
local gamma_level = self.ui.document:getGammaLevel()
self.ui:handleEvent(Event:new("RedrawCurrentView"))
- Notification:notify(T(_("Font gamma set to %1."), optionsutil:getOptionText("SetFontGamma", gamma_level)))
+ Notification:notify(T(_("Font gamma set to: %1."), optionsutil:getOptionText("SetFontGamma", gamma_level)))
return true
end
diff --git a/frontend/apps/reader/modules/readerhighlight.lua b/frontend/apps/reader/modules/readerhighlight.lua
index 2e0047b1f..e3cc9296f 100644
--- a/frontend/apps/reader/modules/readerhighlight.lua
+++ b/frontend/apps/reader/modules/readerhighlight.lua
@@ -174,20 +174,6 @@ function ReaderHighlight:init()
}
end)
- -- User hyphenation dict
- self:addToHighlightDialog("11_user_dict", function(_self)
- return {
- text= _("Hyphenate"),
- show_in_highlight_dialog_func = function()
- return _self.ui.userHyph and _self.ui.userhyph:isAvailable() and not _self.selected_text.text:find("[ ,;-%.\n]")
- end,
- callback = function()
- _self.ui.userhyph:modifyUserEntry(_self.selected_text.text)
- _self:onClose()
- end,
- }
- end)
-
self.ui:registerPostInitCallback(function()
self.ui.menu:registerToMainMenu(self)
end)
diff --git a/frontend/apps/reader/modules/readertypeset.lua b/frontend/apps/reader/modules/readertypeset.lua
index c9e1b9179..53e7afa60 100644
--- a/frontend/apps/reader/modules/readertypeset.lua
+++ b/frontend/apps/reader/modules/readertypeset.lua
@@ -138,19 +138,27 @@ end
function ReaderTypeset:onToggleEmbeddedStyleSheet(toggle)
self:toggleEmbeddedStyleSheet(toggle)
- Notification:notify(T( _("Embedded styles are %1."), optionsutil:getOptionText("ToggleEmbeddedStyleSheet", toggle)))
+ if toggle then
+ Notification:notify(_("Enabled embedded styles."))
+ else
+ Notification:notify(_("Disabled embedded styles."))
+ end
return true
end
function ReaderTypeset:onToggleEmbeddedFonts(toggle)
self:toggleEmbeddedFonts(toggle)
- Notification:notify(T( _("Embedded fonts are %1."), optionsutil:getOptionText("ToggleEmbeddedFonts", toggle)))
+ if toggle then
+ Notification:notify(_("Enabled embedded fonts."))
+ else
+ Notification:notify(_("Disabled embedded fonts."))
+ end
return true
end
function ReaderTypeset:onToggleImageScaling(toggle)
self:toggleImageScaling(toggle)
- Notification:notify(T( _("Image scaling set to %1."), optionsutil:getOptionText("ToggleImageScaling", toggle)))
+ Notification:notify(T( _("Image scaling set to: %1"), optionsutil:getOptionText("ToggleImageScaling", toggle)))
return true
end
@@ -161,7 +169,7 @@ end
function ReaderTypeset:onSetBlockRenderingMode(mode)
self:setBlockRenderingMode(mode)
- Notification:notify(T( _("Render mode set to %1."), optionsutil:getOptionText("SetBlockRenderingMode", mode)))
+ Notification:notify(T( _("Render mode set to: %1"), optionsutil:getOptionText("SetBlockRenderingMode", mode)))
return true
end
@@ -183,7 +191,7 @@ local OBSOLETED_CSS = {
function ReaderTypeset:onSetRenderDPI(dpi)
self:setRenderDPI(dpi)
- Notification:notify(T( _("Zoom set to %1."), optionsutil:getOptionText("SetRenderDPI", dpi)))
+ Notification:notify(T( _("Zoom set to: %1"), optionsutil:getOptionText("SetRenderDPI", dpi)))
return true
end
diff --git a/frontend/apps/reader/modules/readertypography.lua b/frontend/apps/reader/modules/readertypography.lua
index 660c4d7ea..5ad82e922 100644
--- a/frontend/apps/reader/modules/readertypography.lua
+++ b/frontend/apps/reader/modules/readertypography.lua
@@ -237,7 +237,6 @@ When the book's language tag is not among our presets, no specific features will
})
self.text_lang_tag = lang_tag
self.ui.document:setTextMainLang(lang_tag)
- self.ui:handleEvent(Event:new("TypographyLanguageChanged"))
self.ui:handleEvent(Event:new("UpdatePos"))
end,
hold_callback = function(touchmenu_instance)
@@ -428,8 +427,8 @@ These settings will apply to all books with any hyphenation dictionary.
enabled_func = function()
return self.hyphenation and not self.hyph_soft_hyphens_only
end,
+ separator = true,
})
- table.insert(hyphenation_submenu, self.ui.userhyph:getMenuEntry())
table.insert(hyphenation_submenu, {
text_func = function()
-- Show the current language default hyph dict (ie: English_US for zh)
@@ -489,7 +488,7 @@ These settings will apply to all books with any hyphenation dictionary.
end,
})
table.insert(hyphenation_submenu, {
- text = _("Soft hyphens only"),
+ text = _("Soft-hyphens only"),
callback = function()
self.hyph_soft_hyphens_only = not self.hyph_soft_hyphens_only
self.hyph_force_algorithmic = false
@@ -761,7 +760,6 @@ function ReaderTypography:onReadSettings(config)
logger.dbg("Typography lang: no lang set, using", self.text_lang_tag)
end
self.ui.document:setTextMainLang(self.text_lang_tag)
- self.ui:handleEvent(Event:new("TypographyLanguageChanged"))
end
function ReaderTypography:onPreRenderDocument(config)
@@ -782,7 +780,6 @@ function ReaderTypography:onPreRenderDocument(config)
self.text_lang_tag = self.book_lang_tag
self.ui.doc_settings:saveSetting("text_lang", self.text_lang_tag)
self.ui.document:setTextMainLang(self.text_lang_tag)
- self.ui:handleEvent(Event:new("TypographyLanguageChanged"))
self.ui:handleEvent(Event:new("UpdatePos"))
end,
enabled_func = function()
@@ -812,7 +809,6 @@ function ReaderTypography:onPreRenderDocument(config)
end
self.text_lang_tag = self.book_lang_tag
self.ui.document:setTextMainLang(self.text_lang_tag)
- self.ui:handleEvent(Event:new("TypographyLanguageChanged"))
end
end
diff --git a/frontend/apps/reader/modules/readeruserhyph.lua b/frontend/apps/reader/modules/readeruserhyph.lua
deleted file mode 100644
index c9863b349..000000000
--- a/frontend/apps/reader/modules/readeruserhyph.lua
+++ /dev/null
@@ -1,228 +0,0 @@
-local DataStorage = require("datastorage")
-local Event = require("ui/event")
-local FFIUtil = require("ffi/util")
-local InfoMessage = require("ui/widget/infomessage")
-local InputDialog = require("ui/widget/inputdialog")
-local UIManager = require("ui/uimanager")
-local WidgetContainer = require("ui/widget/container/widgetcontainer")
-local lfs = require("libs/libkoreader-lfs")
-local logger = require("logger")
-local _ = require("gettext")
-local T = require("ffi/util").template
-
-local ReaderUserHyph = WidgetContainer:new{
- -- return values from setUserHyphenationDict (crengine's UserHyphDict::init())
- USER_DICT_RELOAD = 0,
- USER_DICT_NOCHANGE = 1,
- USER_DICT_MALFORMED = 2,
- USER_DICT_ERROR_NOT_SORTED = 3,
-}
-
--- returns path to the user dictionary
-function ReaderUserHyph:getDictionaryPath()
- return FFIUtil.joinPath(DataStorage:getSettingsDir(),
- "user-" .. tostring(self.ui.document:getTextMainLangDefaultHyphDictionary():gsub(".pattern$", "")) .. ".hyph")
-end
-
--- Load the user dictionary suitable for the actual language
--- if reload==true, force a reload
--- Unload is done automatically when a new dictionary is loaded.
-function ReaderUserHyph:loadDictionary(name, reload)
- if G_reader_settings:isTrue("hyph_user_dict") and lfs.attributes(name, "mode") == "file" then
- local ret = self.ui.document:setUserHyphenationDict(name, reload)
- -- this should only happen, if a user edits a dictionary by hand or the user messed
- -- with the dictionary file by hand. -> Warning and disable.
- if ret == self.USER_DICT_ERROR_NOT_SORTED then
- UIManager:show(InfoMessage:new{
- text = T(_("The user dictionary\n%1\nis not alphabetically sorted.\n\nIt has been disabled."), name),
- })
- logger.warn("UserHyph: Dictionary " .. name .. " is not sorted alphabetically.")
- G_reader_settings:makeFalse("hyph_user_dict")
- elseif ret == self.USER_DICT_MALFORMED then
- UIManager:show(InfoMessage:new{
- text = T(_("The user dictionary\n%1\nhas corrupted entries.\n\nOnly valid entries will be used."), name),
- })
- logger.warn("UserHyph: Dictionary " .. name .. " has corrupted entries.")
- end
- else
- self.ui.document:setUserHyphenationDict() -- clear crengine user hyph dict
- end
-end
-
--- Reload on change of the hyphenation language
-function ReaderUserHyph:onTypographyLanguageChanged()
- self:loadUserDictionary()
-end
-
--- Reload on "ChangedUserDictionary" event,
--- doesn't load dictionary if filesize and filename haven't changed
--- if reload==true reload
-function ReaderUserHyph:loadUserDictionary(reload)
- self:loadDictionary(self:isAvailable() and self:getDictionaryPath() or "", reload and true or false)
- self.ui:handleEvent(Event:new("UpdatePos"))
-end
-
--- Functions to use with the UI
-
-function ReaderUserHyph:isAvailable()
- return G_reader_settings:isTrue("hyph_user_dict") and self:_enabled()
-end
-
-function ReaderUserHyph:_enabled()
- return self.ui.typography.hyphenation
-end
-
--- add Menu entry
-function ReaderUserHyph:getMenuEntry()
- return {
- text = _("Custom hyphenation rules"),
- help_text = _("The hyphenation of a word can be changed from its default by long pressing for 3 seconds and selecting 'Hyphenate'."),
- callback = function()
- local hyph_user_dict = not G_reader_settings:isTrue("hyph_user_dict")
- G_reader_settings:saveSetting("hyph_user_dict", hyph_user_dict)
- self:loadUserDictionary() -- not needed to force a reload here
- end,
- checked_func = function()
- return self:isAvailable()
- end,
- enabled_func = function()
- return self:_enabled()
- end,
- separator = true,
- }
-end
-
--- Helper functions for dictionary entries-------------------------------------------
-
--- checks if suggestion is well formated
-function ReaderUserHyph:checkHyphenation(suggestion, word)
- if suggestion:find("%-%-") then
- return false -- two or more consecutive '-'
- end
-
- suggestion = suggestion:gsub("-","")
- if self.ui.document:getLowercasedWord(suggestion) == self.ui.document:getLowercasedWord(word) then
- return true -- characters match (case insensitive)
- end
- return false
-end
-
-function ReaderUserHyph:updateDictionary(word, hyphenation)
- local dict_file = self:getDictionaryPath()
- local new_dict_file = dict_file .. ".new"
-
- local new_dict = io.open(new_dict_file, "w")
- if not new_dict then
- logger.err("UserHyph: could not open " .. new_dict_file)
- return
- end
-
- local word_lower = self.ui.document:getLowercasedWord(word)
- local line
-
- local dict = io.open(dict_file, "r")
- if dict then
- line = dict:read()
- --search entry
- while line and self.ui.document:getLowercasedWord(line:sub(1, line:find(";") - 1)) < word_lower do
- new_dict:write(line .. "\n")
- line = dict:read()
- end
-
- -- last word = nil if EOF, else last_word=word if found in file, else last_word is word after the new entry
- if line then
- local last_word = self.ui.document:getLowercasedWord(line:sub(1, line:find(";") - 1))
- if last_word == self.ui.document:getLowercasedWord(word) then
- line = nil -- word found
- end
- else
- line = nil -- EOF
- end
- end
-
- -- write new entry
- if hyphenation and hyphenation ~= "" then
- new_dict:write(string.format("%s;%s\n", word, hyphenation))
- end
-
- -- write old entry if there was one
- if line then
- new_dict:write(line .. "\n")
- end
-
- if dict then
- repeat
- line = dict:read()
- if line then
- new_dict:write(line .. "\n")
- end
- until (not line)
- dict:close()
- os.remove(dict_file)
- end
-
- new_dict:close()
- os.rename(new_dict_file, dict_file)
-
- self:loadUserDictionary(true) -- dictionary has changed, force a reload here
-end
-
-function ReaderUserHyph:modifyUserEntry(word)
- if word:find("[ ,;-%.]") then return end -- no button if more than one word
-
- if not self.ui.document then return end
-
- local suggested_hyphenation = self.ui.document:getHyphenationForWord(word)
-
- local input_dialog
- input_dialog = InputDialog:new{
- title = T(_("Hyphenate: %1"), word),
- description = _("Add hyphenation positions with hyphens ('-') or spaces (' ')."),
- input = suggested_hyphenation,
- old_hyph_lowercase = self.ui.document:getLowercasedWord(suggested_hyphenation),
- input_type = "string",
- buttons = {
- {
- {
- text = _("Cancel"),
- callback = function()
- UIManager:close(input_dialog)
- end,
- },
- {
- text = _("Remove"),
- callback = function()
- UIManager:close(input_dialog)
- self:updateDictionary(word)
- end,
- },
- {
- text = _("Save"),
- is_enter_default = true,
- callback = function()
- local new_suggestion = input_dialog:getInputText()
- new_suggestion = new_suggestion:gsub(" ","-") -- replace spaces with hyphens
- new_suggestion = new_suggestion:gsub("^-","") -- remove leading hypenations
- new_suggestion = new_suggestion:gsub("-$","") -- remove trailing hypenations
-
- if self:checkHyphenation(new_suggestion, word) then
- -- don't save if no changes
- if self.ui.document:getLowercasedWord(new_suggestion) ~= input_dialog.old_hyph_lowercase then
- self:updateDictionary(word, new_suggestion)
- end
- UIManager:close(input_dialog)
- else
- UIManager:show(InfoMessage:new{
- text = T(_("Invalid hyphenation!"), self.dict_file),
- })
- end
- end,
- },
- },
- },
- }
- UIManager:show(input_dialog)
- input_dialog:onShowKeyboard()
-end
-
-return ReaderUserHyph
diff --git a/frontend/apps/reader/modules/readerview.lua b/frontend/apps/reader/modules/readerview.lua
index 4b6132983..efc55d3ae 100644
--- a/frontend/apps/reader/modules/readerview.lua
+++ b/frontend/apps/reader/modules/readerview.lua
@@ -715,7 +715,7 @@ function ReaderView:onSetRotationMode(rotation)
self.ui:handleEvent(Event:new("SetDimensions", new_screen_size))
self.ui:onScreenResize(new_screen_size)
self.ui:handleEvent(Event:new("InitScrollPageStates"))
- Notification:notify(T(_("Rotation mode set to %1."), optionsutil:getOptionText("SetRotationMode", rotation)))
+ Notification:notify(T(_("Rotation mode set to: %1"), optionsutil:getOptionText("SetRotationMode", rotation)))
return true
end
@@ -849,12 +849,12 @@ function ReaderView:onGammaUpdate(gamma)
if self.page_scroll then
self.ui:handleEvent(Event:new("UpdateScrollPageGamma", gamma))
end
- Notification:notify(T(_("Font gamma set to %1."), gamma))
+ Notification:notify(T(_("Font gamma set to: %1."), gamma))
end
function ReaderView:onFontSizeUpdate(font_size)
self.ui:handleEvent(Event:new("ReZoom", font_size))
- Notification:notify(T(_("Font zoom set to %1."), font_size))
+ Notification:notify(T(_("Font zoom set to: %1."), font_size))
end
function ReaderView:onDefectSizeUpdate()
@@ -874,7 +874,7 @@ function ReaderView:onSetViewMode(new_mode)
self.view_mode = new_mode
self.ui.document:setViewMode(new_mode)
self.ui:handleEvent(Event:new("ChangeViewMode"))
- Notification:notify(T( _("View mode set to %1."), optionsutil:getOptionText("SetViewMode", new_mode)))
+ Notification:notify(T( _("View mode set to: %1"), optionsutil:getOptionText("SetViewMode", new_mode)))
end
end
diff --git a/frontend/apps/reader/readerui.lua b/frontend/apps/reader/readerui.lua
index 03452a04a..85e0c7772 100644
--- a/frontend/apps/reader/readerui.lua
+++ b/frontend/apps/reader/readerui.lua
@@ -48,7 +48,6 @@ local ReaderStyleTweak = require("apps/reader/modules/readerstyletweak")
local ReaderToc = require("apps/reader/modules/readertoc")
local ReaderTypeset = require("apps/reader/modules/readertypeset")
local ReaderTypography = require("apps/reader/modules/readertypography")
-local ReaderUserHyph = require("apps/reader/modules/readeruserhyph")
local ReaderView = require("apps/reader/modules/readerview")
local ReaderWikipedia = require("apps/reader/modules/readerwikipedia")
local ReaderZooming = require("apps/reader/modules/readerzooming")
@@ -315,12 +314,6 @@ function ReaderUI:init()
view = self.view,
ui = self
})
- -- user hyphenation (must be registered before typography)
- self:registerModule("userhyph", ReaderUserHyph:new{
- dialog = self.dialog,
- view = self.view,
- ui = self
- })
-- typography menu (replaces previous hyphenation menu / ReaderHyphenation)
self:registerModule("typography", ReaderTypography:new{
dialog = self.dialog,
diff --git a/frontend/device/android/device.lua b/frontend/device/android/device.lua
index 908442705..47ac0e464 100644
--- a/frontend/device/android/device.lua
+++ b/frontend/device/android/device.lua
@@ -132,10 +132,11 @@ function Device:init()
device = self,
event_map = require("device/android/event_map"),
handleMiscEv = function(this, ev)
+ local Event = require("ui/event")
local UIManager = require("ui/uimanager")
logger.dbg("Android application event", ev.code)
if ev.code == C.APP_CMD_SAVE_STATE then
- return "SaveState"
+ UIManager:broadcastEvent(Event:new("SaveSettings"))
elseif ev.code == C.APP_CMD_DESTROY then
UIManager:quit()
elseif ev.code == C.APP_CMD_GAINED_FOCUS
@@ -152,7 +153,6 @@ function Device:init()
this.device.screen:resize()
local new_size = this.device.screen:getSize()
logger.info("Resizing screen to", new_size)
- local Event = require("ui/event")
local FileManager = require("apps/filemanager/filemanager")
UIManager:broadcastEvent(Event:new("SetDimensions", new_size))
UIManager:broadcastEvent(Event:new("ScreenResize", new_size))
@@ -166,10 +166,8 @@ function Device:init()
end
end
-- to-do: keyboard connected, disconnected
- elseif ev.code == C.APP_CMD_START then
- local Event = require("ui/event")
- UIManager:broadcastEvent(Event:new("Resume"))
elseif ev.code == C.APP_CMD_RESUME then
+ UIManager:broadcastEvent(Event:new("Resume"))
if external.when_back_callback then
external.when_back_callback()
external.when_back_callback = nil
@@ -207,14 +205,11 @@ function Device:init()
end
end
end
- elseif ev.code == C.APP_CMD_STOP then
- local Event = require("ui/event")
+ elseif ev.code == C.APP_CMD_PAUSE then
UIManager:broadcastEvent(Event:new("Suspend"))
elseif ev.code == C.AEVENT_POWER_CONNECTED then
- local Event = require("ui/event")
UIManager:broadcastEvent(Event:new("Charging"))
elseif ev.code == C.AEVENT_POWER_DISCONNECTED then
- local Event = require("ui/event")
UIManager:broadcastEvent(Event:new("NotCharging"))
elseif ev.code == C.AEVENT_DOWNLOAD_COMPLETE then
android.ota.isRunning = false
@@ -462,9 +457,9 @@ function Device:untar(archive, extract_to)
end
function Device:download(link, name, ok_text)
- local UIManager = require("ui/uimanager")
local ConfirmBox = require("ui/widget/confirmbox")
local InfoMessage = require("ui/widget/infomessage")
+ local UIManager = require("ui/uimanager")
local ok = android.download(link, name)
if ok == C.ADOWNLOAD_EXISTS then
self:install()
@@ -484,12 +479,14 @@ function Device:download(link, name, ok_text)
end
function Device:install()
- local UIManager = require("ui/uimanager")
local ConfirmBox = require("ui/widget/confirmbox")
+ local Event = require("ui/event")
+ local UIManager = require("ui/uimanager")
UIManager:show(ConfirmBox:new{
text = _("Update is ready. Install it now?"),
ok_text = _("Install"),
ok_callback = function()
+ UIManager:broadcastEvent(Event:new("SaveSettings"))
android.ota.install()
android.ota.isPending = false
end,
diff --git a/frontend/device/pocketbook/device.lua b/frontend/device/pocketbook/device.lua
index 1d10075ef..ed55ef5f9 100644
--- a/frontend/device/pocketbook/device.lua
+++ b/frontend/device/pocketbook/device.lua
@@ -488,6 +488,7 @@ local PocketBook626 = PocketBook:new{
local PocketBook627 = PocketBook:new{
model = "PBLux4",
display_dpi = 212,
+ isAlwaysPortrait = yes,
}
-- PocketBook Touch Lux 5 (628)
@@ -576,6 +577,16 @@ local PocketBook740_2 = PocketBook:new{
}
}
+-- PocketBook InkPad Color (741)
+local PocketBook741 = PocketBook:new{
+ model = "PBInkPadColor",
+ display_dpi = 300,
+ hasColorScreen = yes,
+ canUseCBB = no, -- 24bpp
+ isAlwaysPortrait = yes,
+ usingForcedRotation = landscape_ccw,
+}
+
-- PocketBook Color Lux (801)
local PocketBookColorLux = PocketBook:new{
model = "PBColorLux",
@@ -662,6 +673,8 @@ elseif codename == "PB740" then
return PocketBook740
elseif codename == "PB740-2" then
return PocketBook740_2
+elseif codename == "PB741" then
+ return PocketBook741
elseif codename == "PocketBook 840" then
return PocketBook840
elseif codename == "PB1040" then
diff --git a/frontend/device/thirdparty.lua b/frontend/device/thirdparty.lua
index 65bdfc41e..553fc8881 100644
--- a/frontend/device/thirdparty.lua
+++ b/frontend/device/thirdparty.lua
@@ -33,7 +33,9 @@ function M:new(o)
end
end
end
- logger.info(o:dump())
+ if o.is_user_list then
+ logger.info(o:dump())
+ end
return o
end
@@ -54,7 +56,7 @@ function M:checkMethod(role, method)
end
function M:dump()
- local str = (self.is_user_list and "user" or "platform") .. " thirdparty apps\n"
+ local str = "user defined thirdparty apps\n"
for i, role in ipairs(roles) do
local apps = self[role.."s"]
for index, _ in ipairs(apps or {}) do
diff --git a/frontend/document/credocument.lua b/frontend/document/credocument.lua
index 745908e89..a8b52029c 100644
--- a/frontend/document/credocument.lua
+++ b/frontend/document/credocument.lua
@@ -980,25 +980,6 @@ function CreDocument:setTextHyphenationSoftHyphensOnly(toggle)
self._document:setStringProperty("crengine.textlang.hyphenation.soft.hyphens.only", toggle and 1 or 0)
end
-function CreDocument:setUserHyphenationDict(dict, reload)
- logger.dbg("CreDocument: set textlang hyphenation dict", dict or "none")
- return self._document:setUserHyphenationDict(dict or "", reload or false)
-end
-
-function CreDocument:getHyphenationForWord(word)
- if word then
- return self._document:getHyphenationForWord(word)
- end
- return word
-end
-
-function CreDocument:getLowercasedWord(word)
- if word then
- return self._document:getLowercasedWord(word)
- end
- return word
-end
-
function CreDocument:setTextHyphenationForceAlgorithmic(toggle)
logger.dbg("CreDocument: set textlang hyphenation force algorithmic", toggle)
self._document:setStringProperty("crengine.textlang.hyphenation.force.algorithmic", toggle and 1 or 0)
diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua
index 6aca33208..fa13cbe8a 100644
--- a/frontend/ui/uimanager.lua
+++ b/frontend/ui/uimanager.lua
@@ -467,16 +467,16 @@ function UIManager:close(widget, refreshtype, refreshregion, refreshdither)
end
logger.dbg("close widget:", widget.name or widget.id or tostring(widget))
local dirty = false
- -- Ensure all the widgets can get onFlushSettings event.
+ -- First notify the closed widget to save its settings...
widget:handleEvent(Event:new("FlushSettings"))
- -- first send close event to widget
+ -- ...and notify it that it ought to be gone now.
widget:handleEvent(Event:new("CloseWidget"))
- -- make it disabled by default and check if any widget wants it disabled or enabled
+ -- Make sure it's disabled by default and check if there are any widgets that want it disabled or enabled.
Input.disable_double_tap = true
local requested_disable_double_tap = nil
local is_covered = false
local start_idx = 1
- -- then remove all references to that widget on stack and refresh
+ -- Then remove all references to that widget on stack and refresh.
for i = #self._window_stack, 1, -1 do
if self._window_stack[i].widget == widget then
self._dirty[self._window_stack[i].widget] = nil
diff --git a/frontend/ui/widget/datewidget.lua b/frontend/ui/widget/datewidget.lua
index 4fdef411d..2f3291523 100644
--- a/frontend/ui/widget/datewidget.lua
+++ b/frontend/ui/widget/datewidget.lua
@@ -210,7 +210,6 @@ function DateWidget:onCloseWidget()
UIManager:setDirty(nil, function()
return "ui", self.date_frame.dimen
end)
- return true
end
function DateWidget:onShow()
diff --git a/frontend/ui/widget/dictquicklookup.lua b/frontend/ui/widget/dictquicklookup.lua
index 3d45cf472..b2a345821 100644
--- a/frontend/ui/widget/dictquicklookup.lua
+++ b/frontend/ui/widget/dictquicklookup.lua
@@ -909,7 +909,6 @@ function DictQuickLookup:onCloseWidget()
UIManager:setDirty(nil, function()
return "flashui", nil
end)
- return true
end
function DictQuickLookup:onShow()
diff --git a/frontend/ui/widget/doublespinwidget.lua b/frontend/ui/widget/doublespinwidget.lua
index e24e71e30..cfba7505a 100644
--- a/frontend/ui/widget/doublespinwidget.lua
+++ b/frontend/ui/widget/doublespinwidget.lua
@@ -295,7 +295,6 @@ function DoubleSpinWidget:onCloseWidget()
UIManager:setDirty(nil, function()
return "ui", self.widget_frame.dimen
end)
- return true
end
function DoubleSpinWidget:onShow()
diff --git a/frontend/ui/widget/frontlightwidget.lua b/frontend/ui/widget/frontlightwidget.lua
index 5fd241670..c73f9af28 100644
--- a/frontend/ui/widget/frontlightwidget.lua
+++ b/frontend/ui/widget/frontlightwidget.lua
@@ -583,7 +583,6 @@ function FrontLightWidget:onCloseWidget()
UIManager:setDirty(nil, function()
return "flashui", self.light_frame.dimen
end)
- return true
end
function FrontLightWidget:onShow()
diff --git a/frontend/ui/widget/imageviewer.lua b/frontend/ui/widget/imageviewer.lua
index c69eff1f4..7cd9f5cd2 100644
--- a/frontend/ui/widget/imageviewer.lua
+++ b/frontend/ui/widget/imageviewer.lua
@@ -850,7 +850,6 @@ function ImageViewer:onCloseWidget()
UIManager:setDirty(nil, function()
return "flashui", self.main_frame.dimen
end)
- return true
end
return ImageViewer
diff --git a/frontend/ui/widget/infomessage.lua b/frontend/ui/widget/infomessage.lua
index dec9f6d75..7ae72ff08 100644
--- a/frontend/ui/widget/infomessage.lua
+++ b/frontend/ui/widget/infomessage.lua
@@ -206,16 +206,15 @@ function InfoMessage:onCloseWidget()
end
if self.invisible then
-- Still invisible, no setDirty needed
- return true
+ return
end
if self.no_refresh_on_close then
- return true
+ return
end
UIManager:setDirty(nil, function()
return "ui", self[1][1].dimen
end)
- return true
end
function InfoMessage:onShow()
diff --git a/frontend/ui/widget/inputdialog.lua b/frontend/ui/widget/inputdialog.lua
index 759acd736..f5609ffcb 100644
--- a/frontend/ui/widget/inputdialog.lua
+++ b/frontend/ui/widget/inputdialog.lua
@@ -391,6 +391,7 @@ function InputDialog:init()
scroll_callback = self._buttons_scroll_callback, -- nil if no Nav or Scroll buttons
scroll = true,
scroll_by_pan = self.scroll_by_pan,
+ has_nav_bar = self.add_nav_bar,
cursor_at_end = self.cursor_at_end,
readonly = self.readonly,
parent = self,
diff --git a/frontend/ui/widget/inputtext.lua b/frontend/ui/widget/inputtext.lua
index 2483b76ab..d565264cc 100644
--- a/frontend/ui/widget/inputtext.lua
+++ b/frontend/ui/widget/inputtext.lua
@@ -61,6 +61,7 @@ local InputText = InputContainer:new{
for_measurement_only = nil, -- When the widget is a one-off used to compute text height
do_select = false, -- to start text selection
selection_start_pos = nil, -- selection start position
+ is_keyboard_hidden = false, -- to be able to show the keyboard again when it was hidden (by VK itself)
}
-- only use PhysicalKeyboard if the device does not have touch screen
@@ -121,6 +122,11 @@ if Device:isTouchDevice() or Device:hasDPad() then
function InputText:onTapTextBox(arg, ges)
if self.parent.onSwitchFocus then
self.parent:onSwitchFocus(self)
+ else
+ if self.is_keyboard_hidden == true then
+ self:onShowKeyboard()
+ self.is_keyboard_hidden = false
+ end
end
if #self.charlist > 0 then -- Avoid cursor moving within a hint.
local textwidget_offset = self.margin + self.bordersize + self.padding
@@ -563,12 +569,21 @@ end
function InputText:onShowKeyboard(ignore_first_hold_release)
Device:startTextInput()
-
self.keyboard.ignore_first_hold_release = ignore_first_hold_release
UIManager:show(self.keyboard)
return true
end
+function InputText:onHideKeyboard()
+ if not self.has_nav_bar then
+ UIManager:close(self.keyboard)
+ Device:stopTextInput()
+ self.is_keyboard_hidden = true
+ end
+
+ return self.is_keyboard_hiddenend
+end
+
function InputText:onCloseKeyboard()
UIManager:close(self.keyboard)
Device:stopTextInput()
diff --git a/frontend/ui/widget/keyboardlayoutdialog.lua b/frontend/ui/widget/keyboardlayoutdialog.lua
index 8fadc4439..5296afcd6 100644
--- a/frontend/ui/widget/keyboardlayoutdialog.lua
+++ b/frontend/ui/widget/keyboardlayoutdialog.lua
@@ -157,7 +157,6 @@ function KeyboardLayoutDialog:onCloseWidget()
UIManager:setDirty(nil, function()
return "ui", self[1][1].dimen
end)
- return true
end
return KeyboardLayoutDialog
diff --git a/frontend/ui/widget/linkbox.lua b/frontend/ui/widget/linkbox.lua
index 59f03bf65..1003621a9 100644
--- a/frontend/ui/widget/linkbox.lua
+++ b/frontend/ui/widget/linkbox.lua
@@ -38,7 +38,6 @@ function LinkBox:onCloseWidget()
UIManager:setDirty(nil, function()
return "partial", self.box
end)
- return true
end
function LinkBox:onShow()
diff --git a/frontend/ui/widget/naturallightwidget.lua b/frontend/ui/widget/naturallightwidget.lua
index 594b65ce5..d10714b0c 100644
--- a/frontend/ui/widget/naturallightwidget.lua
+++ b/frontend/ui/widget/naturallightwidget.lua
@@ -381,7 +381,6 @@ function NaturalLightWidget:onCloseWidget()
end)
-- Tell frontlight widget that we're closed
self.fl_widget:naturalLightConfigClose()
- return true
end
function NaturalLightWidget:onShow()
diff --git a/frontend/ui/widget/notification.lua b/frontend/ui/widget/notification.lua
index c4c9ceccf..13b815b6f 100644
--- a/frontend/ui/widget/notification.lua
+++ b/frontend/ui/widget/notification.lua
@@ -182,7 +182,6 @@ function Notification:onCloseWidget()
UIManager:setDirty(nil, function()
return "ui", self.frame.dimen
end)
- return true
end
function Notification:onShow()
diff --git a/frontend/ui/widget/openwithdialog.lua b/frontend/ui/widget/openwithdialog.lua
index 8bb1b377a..cf8acc982 100644
--- a/frontend/ui/widget/openwithdialog.lua
+++ b/frontend/ui/widget/openwithdialog.lua
@@ -188,7 +188,6 @@ function OpenWithDialog:onCloseWidget()
UIManager:setDirty(nil, function()
return "ui", self.dialog_frame.dimen
end)
- return true
end
return OpenWithDialog
diff --git a/frontend/ui/widget/qrmessage.lua b/frontend/ui/widget/qrmessage.lua
index cb39d2d86..684bbb2aa 100644
--- a/frontend/ui/widget/qrmessage.lua
+++ b/frontend/ui/widget/qrmessage.lua
@@ -86,7 +86,6 @@ function QRMessage:onCloseWidget()
UIManager:setDirty(nil, function()
return "ui", self[1][1].dimen
end)
- return true
end
function QRMessage:onShow()
diff --git a/frontend/ui/widget/screensaverwidget.lua b/frontend/ui/widget/screensaverwidget.lua
index d03f0a70d..2d004241a 100644
--- a/frontend/ui/widget/screensaverwidget.lua
+++ b/frontend/ui/widget/screensaverwidget.lua
@@ -88,7 +88,6 @@ function ScreenSaverWidget:onCloseWidget()
UIManager:setDirty(nil, function()
return "full", self.main_frame.dimen
end)
- return true
end
return ScreenSaverWidget
diff --git a/frontend/ui/widget/skimtowidget.lua b/frontend/ui/widget/skimtowidget.lua
index d7ec7fbdb..b6b1bcadb 100644
--- a/frontend/ui/widget/skimtowidget.lua
+++ b/frontend/ui/widget/skimtowidget.lua
@@ -338,7 +338,6 @@ function SkimToWidget:onCloseWidget()
UIManager:setDirty(nil, function()
return "ui", self.skimto_frame.dimen
end)
- return true
end
function SkimToWidget:onShow()
diff --git a/frontend/ui/widget/spinwidget.lua b/frontend/ui/widget/spinwidget.lua
index b83d15477..a2d5b1c52 100644
--- a/frontend/ui/widget/spinwidget.lua
+++ b/frontend/ui/widget/spinwidget.lua
@@ -248,7 +248,6 @@ function SpinWidget:onCloseWidget()
UIManager:setDirty(nil, function()
return "ui", self.spin_frame.dimen
end)
- return true
end
function SpinWidget:onShow()
diff --git a/frontend/ui/widget/textviewer.lua b/frontend/ui/widget/textviewer.lua
index 602c957f2..096e5ac38 100644
--- a/frontend/ui/widget/textviewer.lua
+++ b/frontend/ui/widget/textviewer.lua
@@ -229,7 +229,6 @@ function TextViewer:onCloseWidget()
UIManager:setDirty(nil, function()
return "partial", self.frame.dimen
end)
- return true
end
function TextViewer:onShow()
diff --git a/frontend/ui/widget/timewidget.lua b/frontend/ui/widget/timewidget.lua
index 63bd95aac..a3bf01a02 100644
--- a/frontend/ui/widget/timewidget.lua
+++ b/frontend/ui/widget/timewidget.lua
@@ -195,7 +195,6 @@ function TimeWidget:onCloseWidget()
UIManager:setDirty(nil, function()
return "ui", self.time_frame.dimen
end)
- return true
end
function TimeWidget:onShow()
diff --git a/frontend/ui/widget/trapwidget.lua b/frontend/ui/widget/trapwidget.lua
index 7dba76521..b33d14b98 100644
--- a/frontend/ui/widget/trapwidget.lua
+++ b/frontend/ui/widget/trapwidget.lua
@@ -155,7 +155,6 @@ function TrapWidget:onCloseWidget()
return "ui", self.frame.dimen
end)
end
- return true
end
return TrapWidget
diff --git a/frontend/ui/widget/virtualkeyboard.lua b/frontend/ui/widget/virtualkeyboard.lua
index 519a30c7d..5dbd4868d 100644
--- a/frontend/ui/widget/virtualkeyboard.lua
+++ b/frontend/ui/widget/virtualkeyboard.lua
@@ -111,7 +111,7 @@ function VirtualKey:init()
self.keyboard:delToStartOfLine()
end
--self.skiphold = true
- elseif self.label =="←" then
+ elseif self.label == "←" then
self.callback = function() self.keyboard:leftChar() end
self.hold_callback = function()
self.ignore_key_release = true
@@ -127,6 +127,13 @@ function VirtualKey:init()
self.callback = function() self.keyboard:upLine() end
elseif self.label == "↓" then
self.callback = function() self.keyboard:downLine() end
+ self.hold_callback = function()
+ self.ignore_key_release = true
+ if not self.keyboard:onHideKeyboard() then
+ -- Keyboard was *not* actually hidden: refresh the key to clear the highlight
+ self:update_keyboard(false, true)
+ end
+ end
else
self.callback = function () self.keyboard:addChar(self.key) end
self.hold_callback = function()
@@ -520,6 +527,17 @@ function VirtualKeyPopup:init()
virtual_key.hold_callback = nil
-- close popup on hold release
virtual_key.onHoldReleaseKey = function()
+ -- NOTE: Check our *parent* key!
+ if parent_key.ignore_key_release then
+ parent_key.ignore_key_release = nil
+ return true
+ end
+ Device:performHapticFeedback("LONG_PRESS")
+ if virtual_key.keyboard.ignore_first_hold_release then
+ virtual_key.keyboard.ignore_first_hold_release = false
+ return true
+ end
+
virtual_key:onTapSelect(true)
UIManager:close(self)
return true
@@ -630,13 +648,19 @@ function VirtualKeyPopup:init()
}
if position_container.dimen.x < 0 then
position_container.dimen.x = 0
+ -- We effectively move the popup, which means the key underneath our finger may no longer *exactly* be parent_key.
+ -- Make sure we won't close the popup right away, as that would risk being a *different* key, in order to make that less confusing.
+ parent_key.ignore_key_release = true
elseif position_container.dimen.x + keyboard_frame.dimen.w > Screen:getWidth() then
position_container.dimen.x = Screen:getWidth() - keyboard_frame.dimen.w
+ parent_key.ignore_key_release = true
end
if position_container.dimen.y < 0 then
position_container.dimen.y = 0
+ parent_key.ignore_key_release = true
elseif position_container.dimen.y + keyboard_frame.dimen.h > Screen:getHeight() then
position_container.dimen.y = Screen:getHeight() - keyboard_frame.dimen.h
+ parent_key.ignore_key_release = true
end
self[1] = position_container
@@ -745,6 +769,10 @@ function VirtualKeyboard:onClose()
return true
end
+function VirtualKeyboard:onHideKeyboard()
+ return self.inputbox:onHideKeyboard()
+end
+
function VirtualKeyboard:onPressKey()
self:getFocusItem():handleEvent(Event:new("TapSelect"))
return true
@@ -771,7 +799,6 @@ end
function VirtualKeyboard:onCloseWidget()
self:_refresh(false)
- return true
end
function VirtualKeyboard:initLayer(layer)
diff --git a/platform/cervantes/koreader.sh b/platform/cervantes/koreader.sh
index 3bdb84424..6f975f88d 100755
--- a/platform/cervantes/koreader.sh
+++ b/platform/cervantes/koreader.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
export LC_ALL="en_US.UTF-8"
@@ -83,6 +83,9 @@ if [ "${STANDALONE}" != "true" ]; then
[ -x /etc/init.d/connman ] && /etc/init.d/connman stop
fi
+CRASH_COUNT=0
+CRASH_TS=0
+CRASH_PREV_TS=0
# **magic** values to request shell stuff. It starts at 85,
# any number lower than that will exit this script.
RESTART_KOREADER=85
@@ -91,18 +94,101 @@ ENTER_QBOOKAPP=87
RETURN_VALUE="${RESTART_KOREADER}"
# Loop forever until KOReader requests a normal exit.
-while [ "${RETURN_VALUE}" -ge "${RESTART_KOREADER}" ]; do
+while [ "${RETURN_VALUE}" -ne 0 ]; do
# move dictionaries from external storage to koreader private partition.
find /mnt/public/dict -type f -exec mv -v \{\} /mnt/private/koreader/data/dict \; 2>/dev/null
- # Do an update check now, so we can actually update KOReader via the "Restart KOReader" menu entry ;).
- ko_update_check
+ if [ ${RETURN_VALUE} -eq ${RESTART_KOREADER} ]; then
+ # Do an update check now, so we can actually update KOReader via the "Restart KOReader" menu entry ;).
+ ko_update_check
+ fi
# run KOReader
./reader.lua "$@" >>crash.log 2>&1
RETURN_VALUE=$?
+ if [ ${RETURN_VALUE} -ne 0 ] && [ "${RETURN_VALUE}" -ne "${ENTER_USBMS}" ] && [ "${RETURN_VALUE}" -ne "${ENTER_QBOOKAPP}" ] && [ "${RETURN_VALUE}" -ne "${RESTART_KOREADER}" ]; then
+ # Increment the crash counter
+ CRASH_COUNT=$((CRASH_COUNT + 1))
+ CRASH_TS=$(date +'%s')
+ # Reset it to a first crash if it's been a while since our last crash...
+ if [ $((CRASH_TS - CRASH_PREV_TS)) -ge 20 ]; then
+ CRASH_COUNT=1
+ fi
+
+ # Check if the user requested to always abort on crash
+ if grep -q '\["dev_abort_on_crash"\] = true' 'settings.reader.lua' 2>/dev/null; then
+ ALWAYS_ABORT="true"
+ # In which case, make sure we pause on *every* crash
+ CRASH_COUNT=1
+ else
+ ALWAYS_ABORT="false"
+ fi
+
+ # Show a fancy bomb on screen
+ viewWidth=600
+ viewHeight=800
+ FONTH=16
+ eval "$(./fbink -e | tr ';' '\n' | grep -e viewWidth -e viewHeight -e FONTH | tr '\n' ';')"
+ # Compute margins & sizes relative to the screen's resolution, so we end up with a similar layout, no matter the device.
+ # Height @ ~56.7%, w/ a margin worth 1.5 lines
+ bombHeight=$((viewHeight / 2 + viewHeight / 15))
+ bombMargin=$((FONTH + FONTH / 2))
+ # With a little notice at the top of the screen, on a big gray screen of death ;).
+ ./fbink -q -b -c -B GRAY9 -m -y 1 "Don't Panic! (Crash n°${CRASH_COUNT} -> ${RETURN_VALUE})"
+ if [ ${CRASH_COUNT} -eq 1 ]; then
+ # Warn that we're waiting on a tap to continue...
+ ./fbink -q -b -O -m -y 2 "Tap the screen to continue."
+ fi
+ # U+1F4A3, the hard way, because we can't use \u or \U escape sequences...
+ ./fbink -q -b -O -m -t regular=./fonts/freefont/FreeSerif.ttf,px=${bombHeight},top=${bombMargin} -- $'\xf0\x9f\x92\xa3'
+ # And then print the tail end of the log on the bottom of the screen...
+ crashLog="$(tail -n 25 crash.log | sed -e 's/\t/ /g')"
+ # The idea for the margins being to leave enough room for an fbink -Z bar, small horizontal margins, and a font size based on what 6pt looked like @ 265dpi
+ ./fbink -q -b -O -t regular=./fonts/droid/DroidSansMono.ttf,top=$((viewHeight / 2 + FONTH * 2 + FONTH / 2)),left=$((viewWidth / 60)),right=$((viewWidth / 60)),px=$((viewHeight / 64)) -- "${crashLog}"
+ # So far, we hadn't triggered an actual screen refresh, do that now, to make sure everything is bundled in a single flashing refresh.
+ ./fbink -q -f -s
+ # Cue a lemming's faceplant sound effect!
+
+ {
+ echo "!!!!"
+ echo "Uh oh, something went awry... (Crash n°${CRASH_COUNT}: $(date +'%x @ %X'))"
+ echo "Running on Linux $(uname -r) ($(uname -v))"
+ } >>crash.log 2>&1
+ if [ ${CRASH_COUNT} -lt 5 ] && [ "${ALWAYS_ABORT}" = "false" ]; then
+ echo "Attempting to restart KOReader . . ." >>crash.log 2>&1
+ echo "!!!!" >>crash.log 2>&1
+ fi
+
+ # Pause a bit if it's the first crash in a while, so that it actually has a chance of getting noticed ;).
+ if [ ${CRASH_COUNT} -eq 1 ]; then
+ # NOTE: We don't actually care about what head reads, we're just using it as a fancy sleep ;).
+ # i.e., we pause either until the 15s timeout, or until the user touches the screen.
+ timeout 15 head -c 24 /dev/input/event1 >/dev/null
+ fi
+ # Cycle the last crash timestamp
+ CRASH_PREV_TS=${CRASH_TS}
+
+ # But if we've crashed more than 5 consecutive times, exit, because we wouldn't want to be stuck in a loop...
+ # NOTE: No need to check for ALWAYS_ABORT, CRASH_COUNT will always be 1 when it's true ;).
+ if [ ${CRASH_COUNT} -ge 5 ]; then
+ echo "Too many consecutive crashes, aborting . . ." >>crash.log 2>&1
+ echo "!!!! ! !!!!" >>crash.log 2>&1
+ break
+ fi
+
+ # If the user requested to always abort on crash, do so.
+ if [ "${ALWAYS_ABORT}" = "true" ]; then
+ echo "Aborting . . ." >>crash.log 2>&1
+ echo "!!!! ! !!!!" >>crash.log 2>&1
+ break
+ fi
+ else
+ # Reset the crash counter if that was a sane exit/restart
+ CRASH_COUNT=0
+ fi
+
# check if KOReader requested to enter in mass storage mode.
if [ "${RETURN_VALUE}" -eq "${ENTER_USBMS}" ]; then
# NOTE: at this point we're sure that the safemode tool
diff --git a/platform/pocketbook/koreader.app b/platform/pocketbook/koreader.app
index cf8ea5529..2f3ad9b8d 100755
--- a/platform/pocketbook/koreader.app
+++ b/platform/pocketbook/koreader.app
@@ -33,13 +33,16 @@ ko_update_check() {
# NOTE: See frontend/ui/otamanager.lua for a few more details on how we squeeze a percentage out of tar's checkpoint feature
# NOTE: %B should always be 512 in our case, so let stat do part of the maths for us instead of using %s ;).
FILESIZE="$(stat -c %b "${NEWUPDATE}")"
- BLOCKS="$((FILESIZE / 20))"
- export CPOINTS="$((BLOCKS / 100))"
+ # shellcheck disable=SC2003
+ BLOCKS="$(expr "${FILESIZE}" / 20)"
+ # shellcheck disable=SC2003
+ CPOINTS="$(expr "${BLOCKS}" / 100)"
+ export CPOINTS
# NOTE: We don't run as root, but folders created over USBMS are owned by root, which yields fun permission shenanigans...
# c.f., https://github.com/koreader/koreader/issues/7581
KO_PB_TARLOG="/tmp/.koreader.tar"
# shellcheck disable=SC2016
- "${KOREADER_DIR}/tar" --no-same-permissions --no-same-owner --checkpoint="${CPOINTS}" --checkpoint-action=exec='printf "%s" $((TAR_CHECKPOINT / CPOINTS)) > ${FBINK_NAMED_PIPE}' -C "/mnt/ext1" -xf "${NEWUPDATE}" 2>"${KO_PB_TARLOG}"
+ "${KOREADER_DIR}/tar" --no-same-permissions --no-same-owner --checkpoint="${CPOINTS}" --checkpoint-action=exec='printf "%s" $(expr ${TAR_CHECKPOINT} / ${CPOINTS}) > ${FBINK_NAMED_PIPE}' -C "/mnt/ext1" -xf "${NEWUPDATE}" 2>"${KO_PB_TARLOG}"
fail=$?
kill -TERM "${FBINK_PID}"
# As mentioned above, filter out potential chmod & utime failures...
@@ -116,10 +119,12 @@ while [ "${RETURN_VALUE}" -ne 0 ]; do
# Did we crash?
if [ "${RETURN_VALUE}" -ne 0 ] && [ "${RETURN_VALUE}" -ne ${KO_RC_RESTART} ]; then
# Increment the crash counter
- CRASH_COUNT=$((CRASH_COUNT + 1))
- CRASH_TS=$(date +'%s')
+ # shellcheck disable=SC2003
+ CRASH_COUNT="$(expr ${CRASH_COUNT} + 1)"
+ CRASH_TS="$(date +'%s')"
# Reset it to a first crash if it's been a while since our last crash...
- if [ $((CRASH_TS - CRASH_PREV_TS)) -ge 20 ]; then
+ # shellcheck disable=SC2003
+ if [ "$(expr "${CRASH_TS}" - "${CRASH_PREV_TS}")" -ge 20 ]; then
CRASH_COUNT=1
fi
@@ -139,8 +144,10 @@ while [ "${RETURN_VALUE}" -ne 0 ]; do
eval "$("${KOREADER_DIR}/fbink" -e | tr ';' '\n' | grep -e viewWidth -e viewHeight -e FONTH | tr '\n' ';')"
# Compute margins & sizes relative to the screen's resolution, so we end up with a similar layout, no matter the device.
# Height @ ~56.7%, w/ a margin worth 1.5 lines
- bombHeight=$((viewHeight / 2 + viewHeight / 15))
- bombMargin=$((FONTH + FONTH / 2))
+ # shellcheck disable=SC2003
+ bombHeight="$(expr ${viewHeight} / 2 + ${viewHeight} / 15)"
+ # shellcheck disable=SC2003
+ bombMargin="$(expr ${FONTH} + ${FONTH} / 2)"
# With a little notice at the top of the screen, on a big gray screen of death ;).
"${KOREADER_DIR}/fbink" -q -b -c -B GRAY9 -m -y 1 "Don't Panic! (Crash n°${CRASH_COUNT} -> ${RETURN_VALUE})"
if [ ${CRASH_COUNT} -eq 1 ]; then
@@ -149,11 +156,12 @@ while [ "${RETURN_VALUE}" -ne 0 ]; do
fi
# U+1F4A3, the hard way, because we can't use \u or \U escape sequences...
# shellcheck disable=SC2039,SC3003
- "${KOREADER_DIR}/fbink" -q -b -O -m -t regular=${KOREADER_DIR}/fonts/freefont/FreeSerif.ttf,px=${bombHeight},top=${bombMargin} -- $'\xf0\x9f\x92\xa3'
+ "${KOREADER_DIR}/fbink" -q -b -O -m -t regular=${KOREADER_DIR}/fonts/freefont/FreeSerif.ttf,px="${bombHeight}",top="${bombMargin}" -- $'\xf0\x9f\x92\xa3'
# And then print the tail end of the log on the bottom of the screen...
crashLog="$(tail -n 25 crash.log | sed -e 's/\t/ /g')"
# The idea for the margins being to leave enough room for an fbink -Z bar, small horizontal margins, and a font size based on what 6pt looked like @ 265dpi
- "${KOREADER_DIR}/fbink" -q -b -O -t regular=${KOREADER_DIR}/fonts/droid/DroidSansMono.ttf,top=$((viewHeight / 2 + FONTH * 2 + FONTH / 2)),left=$((viewWidth / 60)),right=$((viewWidth / 60)),px=$((viewHeight / 64)) -- "${crashLog}"
+ # shellcheck disable=SC2003
+ "${KOREADER_DIR}/fbink" -q -b -O -t regular=${KOREADER_DIR}/fonts/droid/DroidSansMono.ttf,top="$(expr ${viewHeight} / 2 + ${FONTH} '*' 2 + ${FONTH} / 2)",left="$(expr ${viewWidth} / 60)",right="$(expr ${viewWidth} / 60)",px="$(expr ${viewHeight} / 64)" -- "${crashLog}"
# So far, we hadn't triggered an actual screen refresh, do that now, to make sure everything is bundled in a single flashing refresh.
${KOREADER_DIR}/fbink -q -f -s
# Cue a lemming's faceplant sound effect!
diff --git a/plugins/opds.koplugin/opdsbrowser.lua b/plugins/opds.koplugin/opdsbrowser.lua
index d8b0ac00f..8715a23d5 100644
--- a/plugins/opds.koplugin/opdsbrowser.lua
+++ b/plugins/opds.koplugin/opdsbrowser.lua
@@ -612,6 +612,7 @@ end
function OPDSBrowser:createNewDownloadDialog(path, buttons)
self.download_dialog = ButtonDialogTitle:new{
title = T(_("Download folder:\n%1\n\nDownload file type:"), BD.dirpath(path)),
+ use_info_style = true,
buttons = buttons
}
end
@@ -650,10 +651,10 @@ function OPDSBrowser:showDownloads(item)
table.insert(buttons, line)
end
table.insert(buttons, {})
- -- Set download folder button.
+ -- Set download folder and book info buttons.
table.insert(buttons, {
{
- text = _("Select another folder"),
+ text = _("Select folder"),
callback = function()
require("ui/downloadmgr"):new{
onConfirm = function(path)
@@ -667,7 +668,18 @@ function OPDSBrowser:showDownloads(item)
end,
}:chooseDir()
end,
- }
+ },
+ {
+ text = _("Book information"),
+ enabled = type(item.content) == "string",
+ callback = function()
+ local TextViewer = require("ui/widget/textviewer")
+ UIManager:show(TextViewer:new{
+ title = item.text,
+ text = util.htmlToPlainTextIfHtml(item.content),
+ })
+ end,
+ },
})
self:createNewDownloadDialog(self.getCurrentDownloadDir(), buttons)
diff --git a/plugins/opds.koplugin/opdsparser.lua b/plugins/opds.koplugin/opdsparser.lua
index 20ee727ed..a1c247a99 100644
--- a/plugins/opds.koplugin/opdsparser.lua
+++ b/plugins/opds.koplugin/opdsparser.lua
@@ -72,10 +72,6 @@ function OPDSParser:createFlatXTable(xlex, curr_element)
end
function OPDSParser:parse(text)
- -- Murder Calibre's whole "content" block, because luxl doesn't really deal well with various XHTML quirks,
- -- as the list of crappy replacements below attests to...
- -- There's also a high probability of finding orphaned tags or badly nested ones in there, which will screw everything up.
- text = text:gsub('.-', '')
-- luxl doesn't handle XML comments, so strip them
text = text:gsub("", "")
-- luxl is also particular about the syntax for self-closing, empty & orphaned tags...
@@ -84,8 +80,18 @@ function OPDSParser:parse(text)
text = text:gsub("<([bh]r)>", "<%1 />")
-- Some OPDS catalogs wrap text in a CDATA section, remove it as it causes parsing problems
text = text:gsub("", function (s)
- return s:gsub( "%p", {["&"] = "&", ["<"] = "<", [">"] = ">" } )
+ return s:gsub("%p", {["&"] = "&", ["<"] = "<", [">"] = ">"})
end )
+
+ -- NOTE: OPDS content tags are likely to contain a bunch of HTML or XHTML. We do *NOT* want to let luxl parse that,
+ -- because it doesn't really deal well with various XHTML quirks, as the list of crappy replacements above attests to...
+ -- There's also a high probability of finding orphaned tags or badly nested ones in there, which would screw everything up.
+ -- In any case, we just want to treat the whole thing as a single text node anyway, so, just mangle the markup to force luxl's hand.
+ text = text:gsub('', "")
+ text = text:gsub("(.-)", function (s)
+ return '' .. s:gsub("%p", {["<"] = "<", [">"] = ">", ['"'] = """, ["'"] = "'"}) .. ""
+ end )
+
local xlex = luxl.new(text, #text)
return assert(self:createFlatXTable(xlex))
end