LuaSettings: Add a method to initialize a setting properly (#7371)

* LuaSettings/DocSettings: Updated readSetting API to allow proper initialization to default.
Use it to initialize tables, e.g., fixing corner-cases in readerFooter that could prevent settings from being saved.
(Fixes an issue reported on Gitter).
* LuaSettings/DocSettings: Add simpler API than the the flip* ones to toggle boolean settings.
* Update LuaSettings/DocSettigns usage throughout the codebase to use the dedicated boolean methods wher appropriate, and clean up some of the more mind-bending uses.
* FileChooser: Implement an extended default exclusion list (fix #2360)
* ScreenSaver: Refactor to avoid the pile of kludges this was threatening to become. Code should be easier to follow and use, and fallbacks now behave as expected (fix #4418).
This commit is contained in:
NiLuJe
2021-03-06 22:44:18 +01:00
committed by GitHub
parent 15ef1a3a1b
commit bf6c0cdd6c
78 changed files with 1424 additions and 1218 deletions

View File

@@ -9,8 +9,6 @@ if not Device:isCervantes() and
return { disabled = true, }
end
local DataStorage = require("datastorage")
local LuaSettings = require("luasettings")
local PluginShare = require("pluginshare")
local UIManager = require("ui/uimanager")
local WidgetContainer = require("ui/widget/container/widgetcontainer")
@@ -19,39 +17,19 @@ local _ = require("gettext")
local T = require("ffi/util").template
local default_autoshutdown_timeout_seconds = 3*24*60*60
local default_auto_suspend_timeout_seconds = 60*60
local AutoSuspend = WidgetContainer:new{
name = "autosuspend",
is_doc_only = false,
autoshutdown_timeout_seconds = G_reader_settings:readSetting("autoshutdown_timeout_seconds") or default_autoshutdown_timeout_seconds,
settings = LuaSettings:open(DataStorage:getSettingsDir() .. "/koboautosuspend.lua"),
auto_suspend_timeout_seconds = G_reader_settings:readSetting("auto_suspend_timeout_seconds") or default_auto_suspend_timeout_seconds,
last_action_sec = os.time(),
standby_prevented = false,
}
function AutoSuspend:_readTimeoutSecFrom(settings)
local sec = settings:readSetting("auto_suspend_timeout_seconds")
if type(sec) == "number" then
return sec
end
return -1
end
function AutoSuspend:_readTimeoutSec()
local candidates = { self.settings, G_reader_settings }
for _, candidate in ipairs(candidates) do
local sec = self:_readTimeoutSecFrom(candidate)
if sec ~= -1 then
return sec
end
end
-- default setting is 60 minutes
return 60 * 60
end
function AutoSuspend:_enabled()
return self.auto_suspend_sec > 0
return self.auto_suspend_timeout_seconds > 0
end
function AutoSuspend:_enabledShutdown()
@@ -67,11 +45,11 @@ function AutoSuspend:_schedule()
local delay_suspend, delay_shutdown
if PluginShare.pause_auto_suspend or Device.standby_prevented or Device.powerd:isCharging() then
delay_suspend = self.auto_suspend_sec
delay_suspend = self.auto_suspend_timeout_seconds
delay_shutdown = self.autoshutdown_timeout_seconds
else
local now_ts = os.time()
delay_suspend = self.last_action_sec + self.auto_suspend_sec - now_ts
delay_suspend = self.last_action_sec + self.auto_suspend_timeout_seconds - now_ts
delay_shutdown = self.last_action_sec + self.autoshutdown_timeout_seconds - now_ts
end
@@ -111,7 +89,6 @@ end
function AutoSuspend:init()
if Device:isPocketBook() and not Device:canSuspend() then return end
UIManager.event_hook:registerWidget("InputEvent", self)
self.auto_suspend_sec = self:_readTimeoutSec()
self:_unschedule()
self:_start()
-- self.ui is nil in the testsuite
@@ -158,22 +135,20 @@ function AutoSuspend:addToMainMenu(menu_items)
local InfoMessage = require("ui/widget/infomessage")
local Screen = Device.screen
local SpinWidget = require("ui/widget/spinwidget")
local curr_items = G_reader_settings:readSetting("auto_suspend_timeout_seconds") or 60*60
local autosuspend_spin = SpinWidget:new {
width = math.floor(Screen:getWidth() * 0.6),
value = curr_items / 60,
value = self.auto_suspend_timeout_seconds / 60,
value_min = 5,
value_max = 240,
value_hold_step = 15,
ok_text = _("Set timeout"),
title_text = _("Timeout in minutes"),
callback = function(autosuspend_spin)
local autosuspend_timeout_seconds = autosuspend_spin.value * 60
self.auto_suspend_sec = autosuspend_timeout_seconds
G_reader_settings:saveSetting("auto_suspend_timeout_seconds", autosuspend_timeout_seconds)
self.auto_suspend_timeout_seconds = autosuspend_spin.value * 60
G_reader_settings:saveSetting("auto_suspend_timeout_seconds", self.auto_suspend_timeout_seconds)
UIManager:show(InfoMessage:new{
text = T(_("The system will automatically suspend after %1 minutes of inactivity."),
string.format("%.2f", autosuspend_timeout_seconds/60)),
string.format("%.2f", self.auto_suspend_timeout_seconds / 60)),
timeout = 3,
})
self:_unschedule()
@@ -191,10 +166,9 @@ function AutoSuspend:addToMainMenu(menu_items)
local InfoMessage = require("ui/widget/infomessage")
local Screen = Device.screen
local SpinWidget = require("ui/widget/spinwidget")
local curr_items = self.autoshutdown_timeout_seconds
local autosuspend_spin = SpinWidget:new {
width = math.floor(Screen:getWidth() * 0.6),
value = curr_items / 60 / 60,
value = self.autoshutdown_timeout_seconds / 60 / 60,
-- About a minute, good for testing and battery life fanatics.
-- Just high enough to avoid an instant shutdown death scenario.
value_min = 0.017,
@@ -206,12 +180,11 @@ function AutoSuspend:addToMainMenu(menu_items)
ok_text = _("Set timeout"),
title_text = _("Timeout in hours"),
callback = function(autosuspend_spin)
local autoshutdown_timeout_seconds = math.floor(autosuspend_spin.value * 60*60)
self.autoshutdown_timeout_seconds = autoshutdown_timeout_seconds
G_reader_settings:saveSetting("autoshutdown_timeout_seconds", autoshutdown_timeout_seconds)
self.autoshutdown_timeout_seconds = math.floor(autosuspend_spin.value * 60 * 60)
G_reader_settings:saveSetting("autoshutdown_timeout_seconds", self.autoshutdown_timeout_seconds)
UIManager:show(InfoMessage:new{
text = T(_("The system will automatically shut down after %1 hours of inactivity."),
string.format("%.2f", autoshutdown_timeout_seconds/60/60)),
string.format("%.2f", self.autoshutdown_timeout_seconds / 60 / 60)),
timeout = 3,
})
self:_unschedule()

View File

@@ -132,7 +132,7 @@ function AutoTurn:addToMainMenu(menu_items)
title_text = _("Timeout in seconds"),
cancel_callback = function()
self.enabled = false
G_reader_settings:flipFalse("autoturn_enabled")
G_reader_settings:makeFalse("autoturn_enabled")
self:_deprecateLastTask()
menu:updateItems()
end,
@@ -140,7 +140,7 @@ function AutoTurn:addToMainMenu(menu_items)
self.autoturn_sec = autoturn_spin.value
G_reader_settings:saveSetting("autoturn_timeout_seconds", autoturn_spin.value)
self.enabled = true
G_reader_settings:flipTrue("autoturn_enabled")
G_reader_settings:makeTrue("autoturn_enabled")
self:_deprecateLastTask()
self:_start()
menu:updateItems()

View File

@@ -133,10 +133,10 @@ function Calibre:getSearchMenuTable()
text = path,
keep_menu_open = true,
checked_func = function()
return cache:readSetting(path)
return cache:isTrue(path)
end,
callback = function()
cache:saveSetting(path, not cache:readSetting(path))
cache:toggle(path)
cache:flush()
CalibreSearch:invalidateCache()
end,
@@ -165,8 +165,7 @@ function Calibre:getSearchMenuTable()
return G_reader_settings:isTrue("calibre_search_from_reader")
end,
callback = function()
local current = G_reader_settings:isTrue("calibre_search_from_reader")
G_reader_settings:saveSetting("calibre_search_from_reader", not current)
G_reader_settings:toggle("calibre_search_from_reader")
UIManager:show(InfoMessage:new{
text = _("This will take effect on next restart."),
})

View File

@@ -49,7 +49,7 @@ local function findCalibreFiles(dir)
local function existOrLast(file)
local fullname
local options = { file, "." .. file }
for _, option in pairs(options) do
for _, option in ipairs(options) do
fullname = dir .. "/" .. option
if util.fileExists(fullname) then
return true, fullname
@@ -144,11 +144,10 @@ end
-- remove a book from our books table
function CalibreMetadata:removeBook(lpath)
for index, book in ipairs(self.books) do
if book.lpath == lpath then
table.remove(self.books, index)
end
local function drop_lpath(t, i, j)
return t[i].lpath ~= lpath
end
util.arrayRemove(self.books, drop_lpath)
end
-- gets the uuid and index of a book from its path
@@ -165,7 +164,7 @@ end
function CalibreMetadata:getBookId(index)
local book = {}
book.priKey = index
for _, key in pairs({ "uuid", "lpath", "last_modified"}) do
for _, key in ipairs({"uuid", "lpath", "last_modified"}) do
book[key] = self.books[index][key]
end
return book

View File

@@ -297,7 +297,7 @@ end
-- find books, series or tags
function CalibreSearch:find(option)
for _, opt in pairs(self.search_options) do
for _, opt in ipairs(self.search_options) do
self[opt] = G_reader_settings:nilOrTrue("calibre_search_"..opt)
end

View File

@@ -26,7 +26,7 @@ require("ffi/zeromq_h")
local extensions = require("extensions")
local function getExtensionPathLengths()
local t = {}
for _, v in pairs(extensions) do
for _, v in ipairs(extensions) do
-- magic number from calibre, see
-- https://github.com/koreader/koreader/pull/6177#discussion_r430753964
t[v] = 37

View File

@@ -66,7 +66,7 @@ function CoverBrowser:init()
BookInfoManager:saveSetting("filemanager_display_mode", "list_image_meta")
BookInfoManager:saveSetting("history_display_mode", "mosaic_image")
end
G_reader_settings:saveSetting("coverbrowser_initial_default_setup_done", true)
G_reader_settings:makeTrue("coverbrowser_initial_default_setup_done")
end
self:setupFileManagerDisplayMode(BookInfoManager:getSetting("filemanager_display_mode"))

View File

@@ -81,7 +81,7 @@ function CoverImage:cleanUpImage()
end
function CoverImage:createCoverImage(doc_settings)
if self.enabled and not doc_settings:readSetting("exclude_cover_image") == true then
if self.enabled and doc_settings:nilOrFalse("exclude_cover_image") then
local cover_image = self.ui.document:getCoverPageImage()
if cover_image then
local s_w, s_h = Device.screen:getWidth(), Device.screen:getHeight()
@@ -426,14 +426,14 @@ function CoverImage:addToMainMenu(menu_items)
{
text = _("Exclude this book cover"),
checked_func = function()
return self.ui and self.ui.doc_settings and self.ui.doc_settings:readSetting("exclude_cover_image") == true
return self.ui and self.ui.doc_settings and self.ui.doc_settings:isTrue("exclude_cover_image")
end,
callback = function()
if self.ui.doc_settings:readSetting("exclude_cover_image") == true then
self.ui.doc_settings:saveSetting("exclude_cover_image", false)
if self.ui.doc_settings:isTrue("exclude_cover_image") then
self.ui.doc_settings:makeFalse("exclude_cover_image")
self:createCoverImage(self.ui.doc_settings)
else
self.ui.doc_settings:saveSetting("exclude_cover_image", true)
self.ui.doc_settings:makeTrue("exclude_cover_image")
self:cleanUpImage()
end
self.ui:saveSettings()

View File

@@ -118,8 +118,8 @@ function Gestures:init()
if not lfs.attributes(gestures_path, "mode") then
FFIUtil.copyFile(defaults_path, gestures_path)
end
self.ignore_hold_corners = G_reader_settings:readSetting("ignore_hold_corners")
self.multiswipes_enabled = G_reader_settings:readSetting("multiswipes_enabled")
self.ignore_hold_corners = G_reader_settings:isTrue("ignore_hold_corners")
self.multiswipes_enabled = G_reader_settings:isTrue("multiswipes_enabled")
self.is_docless = self.ui == nil or self.ui.document == nil
self.ges_mode = self.is_docless and "gesture_fm" or "gesture_reader"
self.defaults = LuaSettings:open(defaults_path).data[self.ges_mode]
@@ -682,7 +682,7 @@ function Gestures:addToMainMenu(menu_items)
text = _("Turn on multiswipes"),
checked_func = function() return self.multiswipes_enabled end,
callback = function()
G_reader_settings:saveSetting("multiswipes_enabled", not self.multiswipes_enabled)
G_reader_settings:toggle("multiswipes_enabled")
self.multiswipes_enabled = G_reader_settings:isTrue("multiswipes_enabled")
end,
help_text = multiswipes_info_text,
@@ -1118,12 +1118,12 @@ function Gestures:multiswipeAction(multiswipe_directions, ges)
text = _("You have just performed your first multiswipe gesture.") .."\n\n".. multiswipes_info_text,
ok_text = _("Turn on"),
ok_callback = function()
G_reader_settings:saveSetting("multiswipes_enabled", true)
G_reader_settings:makeTrue("multiswipes_enabled")
self.multiswipes_enabled = true
end,
cancel_text = _("Turn off"),
cancel_callback = function()
G_reader_settings:saveSetting("multiswipes_enabled", false)
G_reader_settings:makeFalse("multiswipes_enabled")
self.multiswipes_enabled = false
end,
})

View File

@@ -193,7 +193,7 @@ function Migration:migrateGestures(caller)
end
end
caller.settings_data:flush()
G_reader_settings:saveSetting("gestures_migrated", true)
G_reader_settings:makeTrue("gestures_migrated")
end
return Migration

View File

@@ -15,7 +15,7 @@ local random = require("random")
local T = require("ffi/util").template
local _ = require("gettext")
if not G_reader_settings:readSetting("device_id") then
if G_reader_settings:hasNot("device_id") then
G_reader_settings:saveSetting("device_id", random.uuid())
end
@@ -104,6 +104,7 @@ function KOSync:onDispatcherRegisterActions()
end
function KOSync:onReaderReady()
--- @todo: Viable candidate for a port to the new readSetting API
local settings = G_reader_settings:readSetting("kosync") or {}
self.kosync_custom_server = settings.custom_server
self.kosync_username = settings.username

View File

@@ -97,12 +97,10 @@ function NewsDownloader:addToMainMenu(menu_items)
text = _("Never download images"),
keep_menu_open = true,
checked_func = function()
return news_downloader_settings:readSetting("never_download_images")
return news_downloader_settings:isTrue("never_download_images")
end,
callback = function()
local never_download_images = news_downloader_settings:readSetting("never_download_images") or false
logger.info("NewsDownloader: previous never_download_images: ", never_download_images)
news_downloader_settings:saveSetting("never_download_images", not never_download_images)
news_downloader_settings:toggle("never_download_images")
news_downloader_settings:flush()
end,
},
@@ -176,11 +174,11 @@ function NewsDownloader:loadConfigAndProcessFeeds()
return
end
local never_download_images = news_downloader_settings:readSetting("never_download_images") or false
local never_download_images = news_downloader_settings:isTrue("never_download_images")
local unsupported_feeds_urls = {}
local total_feed_entries = table.getn(feed_config)
local total_feed_entries = #feed_config
for idx, feed in ipairs(feed_config) do
local url = feed[1]
local limit = feed.limit

View File

@@ -36,8 +36,34 @@ local CatalogCache = Cache:new{
}
local OPDSBrowser = Menu:extend{
opds_servers = {},
opds_servers = G_reader_settings:readSetting("opds_servers", {
{
title = "Project Gutenberg",
url = "https://m.gutenberg.org/ebooks.opds/?format=opds",
},
{
title = "Feedbooks",
url = "https://catalog.feedbooks.com/catalog/public_domain.atom",
},
{
title = "ManyBooks",
url = "http://manybooks.net/opds/index.php",
},
{
title = "Internet Archive",
url = "https://bookserver.archive.org/",
},
{
title = "textos.info (Spanish)",
url = "https://www.textos.info/catalogo.atom",
},
{
title = "Gallica (French)",
url = "https://gallica.bnf.fr/opds",
},
}),
calibre_name = _("Local calibre library"),
calibre_opds = G_reader_settings:readSetting("calibre_opds", {}),
catalog_type = "application/atom%+xml",
search_type = "application/opensearchdescription%+xml",
@@ -53,38 +79,13 @@ local OPDSBrowser = Menu:extend{
}
function OPDSBrowser:init()
local servers = G_reader_settings:readSetting("opds_servers")
if not servers then -- If there are no saved servers, add some defaults
servers = {
{
title = "Project Gutenberg",
url = "https://m.gutenberg.org/ebooks.opds/?format=opds",
},
{
title = "Feedbooks",
url = "https://catalog.feedbooks.com/catalog/public_domain.atom",
},
{
title = "ManyBooks",
url = "http://manybooks.net/opds/index.php",
},
{
title = "Internet Archive",
url = "https://bookserver.archive.org/",
},
{
title = "textos.info (Spanish)",
url = "https://www.textos.info/catalogo.atom",
},
{
title = "Gallica (French)",
url = "https://gallica.bnf.fr/opds",
},
}
G_reader_settings:saveSetting("opds_servers", servers)
elseif servers[4] and servers[4].title == "Internet Archive" and servers[4].url == "http://bookserver.archive.org/catalog/" then
servers[4].url = "https://bookserver.archive.org"
-- Update deprecated URLs
for _, server in ipairs(self.opds_servers) do
if server.url == "http://bookserver.archive.org/catalog/" then
server.url = "https://bookserver.archive.org"
end
end
self.item_table = self:genItemTableFromRoot()
self.catalog_title = nil
Menu.init(self) -- call parent's init()
@@ -92,7 +93,6 @@ end
function OPDSBrowser:addServerFromInput(fields)
logger.info("New OPDS catalog input:", fields)
local servers = G_reader_settings:readSetting("opds_servers") or {}
local new_server = {
title = fields[1],
url = (fields[2]:match("^%a+://") and fields[2] or "http://" .. fields[2]),
@@ -101,31 +101,28 @@ function OPDSBrowser:addServerFromInput(fields)
-- Allow empty passwords
password = fields[4],
}
table.insert(servers, new_server)
G_reader_settings:saveSetting("opds_servers", servers)
table.insert(self.opds_servers, new_server)
self:init()
end
function OPDSBrowser:editCalibreFromInput(fields)
logger.dbg("Edit calibre server input:", fields)
local calibre = G_reader_settings:readSetting("calibre_opds") or {}
if fields[1] then
calibre.host = fields[1]
self.calibre_opds.host = fields[1]
end
if tonumber(fields[2]) then
calibre.port = fields[2]
self.calibre_opds.port = fields[2]
end
if fields[3] and fields[3] ~= "" then
calibre.username = fields[3]
self.calibre_opds.username = fields[3]
else
calibre.username = nil
self.calibre_opds.username = nil
end
if fields[4] then
calibre.password = fields[4]
self.calibre_opds.password = fields[4]
else
calibre.password = nil
self.calibre_opds.password = nil
end
G_reader_settings:saveSetting("calibre_opds", calibre)
self:init()
end
@@ -178,25 +175,24 @@ function OPDSBrowser:addNewCatalog()
end
function OPDSBrowser:editCalibreServer()
local calibre = G_reader_settings:readSetting("calibre_opds") or {}
self.add_server_dialog = MultiInputDialog:new{
title = _("Edit local calibre host and port"),
fields = {
{
--- @todo get IP address of current device
text = calibre.host or "192.168.1.1",
text = self.calibre_opds.host or "192.168.1.1",
hint = _("calibre host"),
},
{
text = calibre.port and tostring(calibre.port) or "8080",
text = self.calibre_opds.port and tostring(self.calibre_opds.port) or "8080",
hint = _("calibre port"),
},
{
text = calibre.username or "",
text = self.calibre_opds.username or "",
hint = _("Username (optional)"),
},
{
text = calibre.password or "",
text = self.calibre_opds.password or "",
hint = _("Password (optional)"),
text_type = "password",
},
@@ -229,8 +225,7 @@ end
function OPDSBrowser:genItemTableFromRoot()
local item_table = {}
local added_servers = G_reader_settings:readSetting("opds_servers") or {}
for _, server in ipairs(added_servers) do
for _, server in ipairs(self.opds_servers) do
table.insert(item_table, {
text = server.title,
content = server.subtitle,
@@ -242,8 +237,7 @@ function OPDSBrowser:genItemTableFromRoot()
searchable = server.searchable,
})
end
local calibre_opds = G_reader_settings:readSetting("calibre_opds") or {}
if not calibre_opds.host or not calibre_opds.port then
if not self.calibre_opds.host or not self.calibre_opds.port then
table.insert(item_table, {
text = self.calibre_name,
callback = function()
@@ -255,9 +249,9 @@ function OPDSBrowser:genItemTableFromRoot()
table.insert(item_table, {
text = self.calibre_name,
url = string.format("http://%s:%d/opds",
calibre_opds.host, calibre_opds.port),
username = calibre_opds.username,
password = calibre_opds.password,
self.calibre_opds.host, self.calibre_opds.port),
username = self.calibre_opds.username,
password = self.calibre_opds.password,
editable = true,
deletable = false,
searchable = false,
@@ -772,8 +766,7 @@ end
function OPDSBrowser:editServerFromInput(item, fields)
logger.info("Edit OPDS catalog input:", fields)
local servers = {}
for _, server in ipairs(G_reader_settings:readSetting("opds_servers") or {}) do
for _, server in ipairs(self.opds_servers) do
if server.title == item.text or server.url == item.url then
server.title = fields[1]
server.url = (fields[2]:match("^%a+://") and fields[2] or "http://" .. fields[2])
@@ -781,9 +774,7 @@ function OPDSBrowser:editServerFromInput(item, fields)
server.username = fields[3] ~= "" and fields[3] or nil
server.password = fields[4]
end
table.insert(servers, server)
end
G_reader_settings:saveSetting("opds_servers", servers)
self:init()
end
@@ -838,13 +829,12 @@ end
function OPDSBrowser:deleteOPDSServer(item)
logger.info("Delete OPDS server:", item)
local servers = {}
for _, server in ipairs(G_reader_settings:readSetting("opds_servers") or {}) do
if server.title ~= item.text or server.url ~= item.url then
table.insert(servers, server)
for i = #self.opds_servers, 1, -1 do
local server = self.opds_servers[i]
if server.title == item.text and server.url == item.url then
table.remove(self.opds_servers, i)
end
end
G_reader_settings:saveSetting("opds_servers", servers)
self:init()
end

View File

@@ -30,7 +30,7 @@ local PerceptionExpander = Widget:extend{
function PerceptionExpander:init()
if not self.settings then self:readSettingsFile() end
self.is_enabled = self.settings:readSetting("is_enabled") or false
self.is_enabled = self.settings:isTrue("is_enabled")
if not self.is_enabled then
return
end

View File

@@ -35,7 +35,7 @@ local DEFAULT_CALENDAR_NB_BOOK_SPANS = 3
local DB_SCHEMA_VERSION = 20201022
-- This is the query used to compute the total time spent reading distinct pages of the book,
-- capped at self.page_max_read_sec per distinct page.
-- capped at self.settings.max_sec per distinct page.
-- c.f., comments in insertDB
local STATISTICS_SQL_BOOK_CAPPED_TOTALS_QUERY = [[
SELECT count(*),
@@ -137,22 +137,15 @@ function ReaderStatistics:init()
end
self.start_current_period = os.time()
self:resetVolatileStats()
local settings = G_reader_settings:readSetting("statistics") or {}
self.page_min_read_sec = tonumber(settings.min_sec)
self.page_max_read_sec = tonumber(settings.max_sec)
self.calendar_start_day_of_week = settings.calendar_start_day_of_week
self.calendar_nb_book_spans = settings.calendar_nb_book_spans
self.calendar_show_histogram = settings.calendar_show_histogram
self.calendar_browse_future_months = settings.calendar_browse_future_months
self.is_enabled = not (settings.is_enabled == false)
self.convert_to_db = settings.convert_to_db
self.settings = G_reader_settings:readSetting("statistics", {})
self.settings.is_enabled = not (self.settings.is_enabled == false)
self.ui.menu:registerToMainMenu(self)
self:checkInitDatabase()
BookStatusWidget.getStats = function()
return self:getStatsBookStatus(self.id_curr_book, self.is_enabled)
return self:getStatsBookStatus(self.id_curr_book, self.settings.is_enabled)
end
ReaderFooter.getAvgTimePerPage = function()
if self.is_enabled then
if self.settings.is_enabled then
return self.avg_time
end
end
@@ -177,7 +170,7 @@ function ReaderStatistics:init()
end
function ReaderStatistics:initData()
if self:isDocless() or not self.is_enabled then
if self:isDocless() or not self.settings.is_enabled then
return
end
-- first execution
@@ -206,7 +199,7 @@ function ReaderStatistics:initData()
self.avg_time = self.book_read_time / self.book_read_pages
else
-- NOTE: Possibly less weird-looking than initializing this to 0?
self.avg_time = math.floor(0.50 * self.page_max_read_sec)
self.avg_time = math.floor(0.50 * self.settings.max_sec)
logger.dbg("ReaderStatistics: Initializing average time per page at 50% of the max value, i.e.,", self.avg_time)
end
end
@@ -276,7 +269,7 @@ end
function ReaderStatistics:checkInitDatabase()
local conn = SQ3.open(db_location)
if self.convert_to_db then -- if conversion to sqlite DB has already been done
if self.settings.convert_to_db then -- if conversion to sqlite DB has already been done
if not conn:exec("PRAGMA table_info('book');") then
UIManager:show(ConfirmBox:new{
text = T(_([[
@@ -352,7 +345,7 @@ Do you want to create an empty database?
conn = SQ3.open(db_location)
end
else -- Migrate stats for books in history from metadata.lua to sqlite database
self.convert_to_db = true
self.settings.convert_to_db = true
if not conn:exec("PRAGMA table_info('book');") then
local filename_first_history, quickstart_filename, __
if #ReadHistory.hist == 1 then
@@ -379,7 +372,6 @@ Please wait…
self:createDB(conn)
end
end
self:saveSettings()
end
conn:close()
end
@@ -593,8 +585,8 @@ function ReaderStatistics:addBookStatToDB(book_stats, conn)
conn:exec('BEGIN;')
stmt = conn:prepare("INSERT OR IGNORE INTO page_stat VALUES(?, ?, ?, ?);")
local avg_time = math.ceil(book_stats.total_time_in_sec / read_pages)
if avg_time > self.page_max_read_sec then
avg_time = self.page_max_read_sec
if avg_time > self.settings.max_sec then
avg_time = self.settings.max_sec
end
local first_read_page = book_stats.performance_in_pages[sorted_performance[1]]
if first_read_page > 1 then
@@ -606,10 +598,10 @@ function ReaderStatistics:addBookStatToDB(book_stats, conn)
for i=2, #sorted_performance do
start_open_page = sorted_performance[i-1]
local diff_time = sorted_performance[i] - sorted_performance[i-1]
if diff_time <= self.page_max_read_sec then
if diff_time <= self.settings.max_sec then
stmt:reset():bind(id_book, book_stats.performance_in_pages[sorted_performance[i-1]],
start_open_page, diff_time):step()
elseif diff_time > self.page_max_read_sec then --and diff_time <= 2 * avg_time then
elseif diff_time > self.settings.max_sec then --and diff_time <= 2 * avg_time then
stmt:reset():bind(id_book, book_stats.performance_in_pages[sorted_performance[i-1]],
start_open_page, avg_time):step()
end
@@ -640,7 +632,7 @@ function ReaderStatistics:migrateToDB(conn)
local nr_of_conv_books = 0
local exclude_titles = {}
for _, v in pairs(ReadHistory.hist) do
local book_stats = DocSettings:open(v.file):readSetting('stats')
local book_stats = DocSettings:open(v.file):readSetting("stats")
if book_stats and book_stats.title == "" then
book_stats.title = v.file:match("^.+/(.+)$")
end
@@ -767,9 +759,9 @@ function ReaderStatistics:insertDB(id_book, updated_pagecount)
-- NOTE: See the tail end of the discussions in #6761 for more context on the choice of this heuristic.
-- Basically, we're counting distinct pages,
-- while making sure the sum of durations per distinct page is clamped to self.page_max_read_sec
-- while making sure the sum of durations per distinct page is clamped to self.settings.max_sec
-- This is expressly tailored to a fairer computation of self.avg_time ;).
local book_read_pages, book_read_time = conn:rowexec(string.format(STATISTICS_SQL_BOOK_CAPPED_TOTALS_QUERY, self.page_max_read_sec, id_book))
local book_read_pages, book_read_time = conn:rowexec(string.format(STATISTICS_SQL_BOOK_CAPPED_TOTALS_QUERY, self.settings.max_sec, id_book))
-- NOTE: What we cache in the book table is the plain uncapped sum (mainly for deleteBooksByTotalDuration's benefit)...
local total_read_pages, total_read_time = conn:rowexec(string.format(STATISTICS_SQL_BOOK_TOTALS_QUERY, id_book))
@@ -810,7 +802,7 @@ function ReaderStatistics:getPageTimeTotalStats(id_book)
end
local conn = SQ3.open(db_location)
-- NOTE: Similarly, this one is used for time-based estimates and averages, so, use the capped variant
local total_pages, total_time = conn:rowexec(string.format(STATISTICS_SQL_BOOK_CAPPED_TOTALS_QUERY, self.page_max_read_sec, id_book))
local total_pages, total_time = conn:rowexec(string.format(STATISTICS_SQL_BOOK_CAPPED_TOTALS_QUERY, self.settings.max_sec, id_book))
conn:close()
if total_pages then
@@ -838,23 +830,22 @@ end
function ReaderStatistics:getStatisticEnabledMenuItem()
return {
text = _("Enabled"),
checked_func = function() return self.is_enabled end,
checked_func = function() return self.settings.is_enabled end,
callback = function()
-- if was enabled, have to save data to file
if self.is_enabled and not self:isDocless() then
if self.settings.is_enabled and not self:isDocless() then
self:insertDB(self.id_curr_book)
self.ui.doc_settings:saveSetting("stats", self.data)
end
self.is_enabled = not self.is_enabled
self.settings.is_enabled = not self.settings.is_enabled
-- if was disabled have to get data from db
if self.is_enabled and not self:isDocless() then
if self.settings.is_enabled and not self:isDocless() then
self:initData()
self.start_current_period = os.time()
self.curr_page = self.ui:getCurrentPage()
self:resetVolatileStats(self.start_current_period)
end
self:saveSettings()
if not self:isDocless() then
self.view.footer:onUpdateFooter()
end
@@ -873,21 +864,21 @@ function ReaderStatistics:addToMainMenu(menu_items)
{
text_func = function()
return T(_("Read page duration limits: %1 s / %2 s"),
self.page_min_read_sec, self.page_max_read_sec)
self.settings.min_sec, self.settings.max_sec)
end,
callback = function(touchmenu_instance)
local DoubleSpinWidget = require("/ui/widget/doublespinwidget")
local durations_widget
durations_widget = DoubleSpinWidget:new{
left_text = _("Min"),
left_value = self.page_min_read_sec,
left_value = self.settings.min_sec,
left_default = DEFAULT_MIN_READ_SEC,
left_min = 3,
left_max = 120,
left_step = 1,
left_hold_step = 10,
right_text = _("Max"),
right_value = self.page_max_read_sec,
right_value = self.settings.max_sec,
right_default = DEFAULT_MAX_READ_SEC,
right_min = 10,
right_max = 7200,
@@ -906,9 +897,8 @@ The max value ensures a page you stay on for a long time (because you fell aslee
if min > max then
min, max = max, min
end
self.page_min_read_sec = min
self.page_max_read_sec = max
self:saveSettings()
self.settings.min_sec = min
self.settings.max_sec = max
UIManager:close(durations_widget)
touchmenu_instance:updateItems()
end,
@@ -921,52 +911,52 @@ The max value ensures a page you stay on for a long time (because you fell aslee
{
text_func = function()
return T(_("Calendar weeks start on %1"),
longDayOfWeekTranslation[weekDays[self.calendar_start_day_of_week]])
longDayOfWeekTranslation[weekDays[self.settings.calendar_start_day_of_week]])
end,
sub_item_table = {
{ -- Friday (Bangladesh and Maldives)
text = longDayOfWeekTranslation[weekDays[6]],
checked_func = function() return self.calendar_start_day_of_week == 6 end,
callback = function() self.calendar_start_day_of_week = 6 end
checked_func = function() return self.settings.calendar_start_day_of_week == 6 end,
callback = function() self.settings.calendar_start_day_of_week = 6 end
},
{ -- Saturday (some Middle East countries)
text = longDayOfWeekTranslation[weekDays[7]],
checked_func = function() return self.calendar_start_day_of_week == 7 end,
callback = function() self.calendar_start_day_of_week = 7 end
checked_func = function() return self.settings.calendar_start_day_of_week == 7 end,
callback = function() self.settings.calendar_start_day_of_week = 7 end
},
{ -- Sunday
text = longDayOfWeekTranslation[weekDays[1]],
checked_func = function() return self.calendar_start_day_of_week == 1 end,
callback = function() self.calendar_start_day_of_week = 1 end
checked_func = function() return self.settings.calendar_start_day_of_week == 1 end,
callback = function() self.settings.calendar_start_day_of_week = 1 end
},
{ -- Monday
text = longDayOfWeekTranslation[weekDays[2]],
checked_func = function() return self.calendar_start_day_of_week == 2 end,
callback = function() self.calendar_start_day_of_week = 2 end
checked_func = function() return self.settings.calendar_start_day_of_week == 2 end,
callback = function() self.settings.calendar_start_day_of_week = 2 end
},
},
},
{
text_func = function()
return T(_("Books per calendar day: %1"), self.calendar_nb_book_spans)
return T(_("Books per calendar day: %1"), self.settings.calendar_nb_book_spans)
end,
callback = function(touchmenu_instance)
local SpinWidget = require("ui/widget/spinwidget")
UIManager:show(SpinWidget:new{
width = math.floor(Screen:getWidth() * 0.6),
value = self.calendar_nb_book_spans,
value = self.settings.calendar_nb_book_spans,
value_min = 1,
value_max = 5,
ok_text = _("Set"),
title_text = _("Books per calendar day"),
info_text = _("Set the max number of book spans to show for a day"),
callback = function(spin)
self.calendar_nb_book_spans = spin.value
self.settings.calendar_nb_book_spans = spin.value
touchmenu_instance:updateItems()
end,
extra_text = _("Use default"),
extra_callback = function()
self.calendar_nb_book_spans = DEFAULT_CALENDAR_NB_BOOK_SPANS
self.settings.calendar_nb_book_spans = DEFAULT_CALENDAR_NB_BOOK_SPANS
touchmenu_instance:updateItems()
end
})
@@ -975,16 +965,16 @@ The max value ensures a page you stay on for a long time (because you fell aslee
},
{
text = _("Show hourly histogram in calendar days"),
checked_func = function() return self.calendar_show_histogram end,
checked_func = function() return self.settings.calendar_show_histogram end,
callback = function()
self.calendar_show_histogram = not self.calendar_show_histogram
self.settings.calendar_show_histogram = not self.settings.calendar_show_histogram
end,
},
{
text = _("Allow browsing coming months"),
checked_func = function() return self.calendar_browse_future_months end,
checked_func = function() return self.settings.calendar_browse_future_months end,
callback = function()
self.calendar_browse_future_months = not self.calendar_browse_future_months
self.settings.calendar_browse_future_months = not self.settings.calendar_browse_future_months
end,
},
},
@@ -1003,7 +993,7 @@ The max value ensures a page you stay on for a long time (because you fell aslee
kv_pairs = self:getCurrentStat(self.id_curr_book),
})
end,
enabled_func = function() return not self:isDocless() and self.is_enabled end,
enabled_func = function() return not self:isDocless() and self.settings.is_enabled end,
},
{
text = _("Reading progress"),
@@ -1307,7 +1297,7 @@ function ReaderStatistics:getCurrentStat(id_book)
-- Current book statistics
-- Includes re-reads
{ _("Total time spent on this book"), util.secondsToClock(total_time_book, false) },
-- Capped to self.page_max_read_sec per distinct page
-- Capped to self.settings.max_sec per distinct page
{ _("Time spent reading this book"), util.secondsToClock(book_read_time, false) },
-- per days
{ _("Reading started"), os.date("%Y-%m-%d (%H:%M)", tonumber(first_open))},
@@ -1922,7 +1912,7 @@ function ReaderStatistics:genResetBookSubItemTable()
callback = function()
self:resetCurrentBook()
end,
enabled_func = function() return not self:isDocless() and self.is_enabled and self.id_curr_book end,
enabled_func = function() return not self:isDocless() and self.settings.is_enabled and self.id_curr_book end,
separator = true,
})
table.insert(sub_item_table, {
@@ -2052,7 +2042,7 @@ function ReaderStatistics:resetCurrentBook()
-- We also need to reset the time/page/avg tracking
self.book_read_pages = 0
self.book_read_time = 0
self.avg_time = math.floor(0.50 * self.page_max_read_sec)
self.avg_time = math.floor(0.50 * self.settings.max_sec)
logger.dbg("ReaderStatistics: Initializing average time per page at 50% of the max value, i.e.,", self.avg_time)
-- And the current volatile stats
@@ -2143,7 +2133,7 @@ function ReaderStatistics:onPosUpdate(pos, pageno)
end
function ReaderStatistics:onPageUpdate(pageno)
if self:isDocless() or not self.is_enabled then
if self:isDocless() or not self.settings.is_enabled then
return
end
@@ -2174,7 +2164,7 @@ function ReaderStatistics:onPageUpdate(pageno)
-- NOTE: If all goes well, given the earlier curr_page != pageno check, curr_duration should always be 0 here.
-- Compute the difference between now and the previous page's last timestamp
local diff_time = now_ts - then_ts
if diff_time >= self.page_min_read_sec and diff_time <= self.page_max_read_sec then
if diff_time >= self.settings.min_sec and diff_time <= self.settings.max_sec then
self.mem_read_time = self.mem_read_time + diff_time
-- If it's the first time we're computing a duration for this page, count it as read
if #page_data == 1 and curr_duration == 0 then
@@ -2182,13 +2172,13 @@ function ReaderStatistics:onPageUpdate(pageno)
end
-- Update the tuple with the computed duration
data_tuple[2] = curr_duration + diff_time
elseif diff_time > self.page_max_read_sec then
self.mem_read_time = self.mem_read_time + self.page_max_read_sec
elseif diff_time > self.settings.max_sec then
self.mem_read_time = self.mem_read_time + self.settings.max_sec
if #page_data == 1 and curr_duration == 0 then
self.mem_read_pages = self.mem_read_pages + 1
end
-- Update the tuple with the computed duration
data_tuple[2] = curr_duration + self.page_max_read_sec
data_tuple[2] = curr_duration + self.settings.max_sec
end
-- We want a flush to db every 50 page turns
@@ -2238,20 +2228,20 @@ function ReaderStatistics:importFromFile(base_path, item)
end
function ReaderStatistics:onCloseDocument()
if not self:isDocless() and self.is_enabled then
if not self:isDocless() and self.settings.is_enabled then
self.ui.doc_settings:saveSetting("stats", self.data)
self:insertDB(self.id_curr_book)
end
end
function ReaderStatistics:onAddHighlight()
if self.is_enabled then
if self.settings.is_enabled then
self.data.highlights = self.data.highlights + 1
end
end
function ReaderStatistics:onDelHighlight()
if self.is_enabled then
if self.settings.is_enabled then
if self.data.highlights > 0 then
self.data.highlights = self.data.highlights - 1
end
@@ -2259,14 +2249,13 @@ function ReaderStatistics:onDelHighlight()
end
function ReaderStatistics:onAddNote()
if self.is_enabled then
if self.settings.is_enabled then
self.data.notes = self.data.notes + 1
end
end
-- Triggered by auto_save_settings_interval_minutes
function ReaderStatistics:onSaveSettings()
self:saveSettings()
if not self:isDocless() then
self.ui.doc_settings:saveSetting("stats", self.data)
self:insertDB(self.id_curr_book)
@@ -2287,20 +2276,6 @@ function ReaderStatistics:onResume()
self:resetVolatileStats(self.start_current_period)
end
function ReaderStatistics:saveSettings()
local settings = {
min_sec = self.page_min_read_sec,
max_sec = self.page_max_read_sec,
is_enabled = self.is_enabled,
convert_to_db = self.convert_to_db,
calendar_start_day_of_week = self.calendar_start_day_of_week,
calendar_nb_book_spans = self.calendar_nb_book_spans,
calendar_show_histogram = self.calendar_show_histogram,
calendar_browse_future_months = self.calendar_browse_future_months,
}
G_reader_settings:saveSetting("statistics", settings)
end
function ReaderStatistics:onReadSettings(config)
self.data = config.data.stats or {}
end
@@ -2319,10 +2294,10 @@ function ReaderStatistics:getCalendarView()
monthTranslation = monthTranslation,
shortDayOfWeekTranslation = shortDayOfWeekTranslation,
longDayOfWeekTranslation = longDayOfWeekTranslation,
start_day_of_week = self.calendar_start_day_of_week,
nb_book_spans = self.calendar_nb_book_spans,
show_hourly_histogram = self.calendar_show_histogram,
browse_future_months = self.calendar_browse_future_months,
start_day_of_week = self.settings.calendar_start_day_of_week,
nb_book_spans = self.settings.calendar_nb_book_spans,
show_hourly_histogram = self.settings.calendar_show_histogram,
browse_future_months = self.settings.calendar_browse_future_months,
}
end
@@ -2433,7 +2408,7 @@ function ReaderStatistics:onShowReaderProgress()
end
function ReaderStatistics:onShowBookStats()
if self:isDocless() or not self.is_enabled then return end
if self:isDocless() or not self.settings.is_enabled then return end
local stats = KeyValuePage:new{
title = _("Current statistics"),
kv_pairs = self:getCurrentStat(self.id_curr_book),

View File

@@ -38,11 +38,10 @@ end
function Terminal:init()
self:onDispatcherRegisterActions()
self.ui.menu:registerToMainMenu(self)
self.shortcuts = self.settings:readSetting("shortcuts") or {}
self.shortcuts = self.settings:readSetting("shortcuts", {})
end
function Terminal:saveShortcuts()
self.settings:saveSetting("shortcuts", self.shortcuts)
self.settings:flush()
UIManager:show(InfoMessage:new{
text = _("Shortcuts saved"),
@@ -294,13 +293,12 @@ function Terminal:editName(item)
end
function Terminal:deleteShortcut(item)
local shortcuts = {}
for _, element in ipairs(self.shortcuts) do
if element.text ~= item.text and element.commands ~= item.commands then
table.insert(shortcuts, element)
for i = #self.shortcuts, 1, -1 do
local element = self.shortcuts[i]
if element.text == item.text and element.commands == item.commands then
table.remove(self.shortcuts, i)
end
end
self.shortcuts = shortcuts
self:saveShortcuts()
self:manageShortcuts()
end

View File

@@ -45,6 +45,7 @@ function TextEditor:loadSettings()
return
end
self.settings = LuaSettings:open(self.settings_file)
-- NOTE: addToHistory assigns a new object
self.history = self.settings:readSetting("history") or {}
self.last_view_pos = self.settings:readSetting("last_view_pos") or {}
self.last_path = self.settings:readSetting("last_path") or ffiutil.realpath(DataStorage:getDataDir())
@@ -56,10 +57,10 @@ function TextEditor:loadSettings()
--
-- Allow users to set their prefered font manually in text_editor.lua
-- (sadly, not via TextEditor itself, as they would be overriden on close)
if self.settings:readSetting("normal_font") then
if self.settings:has("normal_font") then
self.normal_font = self.settings:readSetting("normal_font")
end
if self.settings:readSetting("monospace_font") then
if self.settings:has("monospace_font") then
self.monospace_font = self.settings:readSetting("monospace_font")
end
self.auto_para_direction = self.settings:nilOrTrue("auto_para_direction")
@@ -254,7 +255,7 @@ function TextEditor:execWhenDoneFunc()
end
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
table.remove(self.history, i)
end

View File

@@ -233,7 +233,7 @@ function ZSync:subscribe()
self.received = {}
local zsync = self
require("ui/downloadmgr"):new{
show_hidden = G_reader_settings:readSetting("show_hidden"),
show_hidden = G_reader_settings:isTrue("show_hidden"),
onConfirm = function(inbox)
G_reader_settings:saveSetting("inbox_dir", inbox)
zsync:onChooseInbox(inbox)