2
0
mirror of https://github.com/koreader/koreader synced 2024-11-16 06:12:56 +00:00
koreader/frontend/apps/filemanager/filemanagersetdefaults.lua

391 lines
14 KiB
Lua
Raw Normal View History

2017-04-29 08:38:09 +00:00
local CenterContainer = require("ui/widget/container/centercontainer")
local ConfirmBox = require("ui/widget/confirmbox")
local DataStorage = require("datastorage")
local Device = require("device")
2017-04-29 08:38:09 +00:00
local Font = require("ui/font")
2014-08-11 08:39:49 +00:00
local InfoMessage = require("ui/widget/infomessage")
local InputContainer = require("ui/widget/container/inputcontainer")
local InputDialog = require("ui/widget/inputdialog")
2017-04-29 08:38:09 +00:00
local Menu = require("ui/widget/menu")
2014-08-25 16:03:10 +00:00
local MultiInputDialog = require("ui/widget/multiinputdialog")
local Size = require("ui/size")
local UIManager = require("ui/uimanager")
2017-04-29 08:38:09 +00:00
local dump = require("dump")
2017-08-09 16:57:22 +00:00
local isAndroid, android = pcall(require, "android")
local logger = require("logger")
local util = require("ffi/util")
local _ = require("gettext")
2017-04-29 08:38:09 +00:00
local Screen = require("device").screen
local is_appimage = os.getenv("APPIMAGE")
2017-08-09 16:57:22 +00:00
local function getDefaultsPath()
local defaults_path = DataStorage:getDataDir() .. "/defaults.lua"
if isAndroid then
defaults_path = android.dir .. "/defaults.lua"
elseif is_appimage then
defaults_path = "defaults.lua"
2017-08-09 16:57:22 +00:00
end
return defaults_path
end
2017-08-09 16:57:22 +00:00
local defaults_path = getDefaultsPath()
local persistent_defaults_path = DataStorage:getDataDir() .. "/defaults.persistent.lua"
2014-08-11 08:39:49 +00:00
local SetDefaults = InputContainer:new{
defaults_name = {},
defaults_value = {},
2014-08-11 08:39:49 +00:00
results = {},
defaults_menu = {},
2016-09-22 07:36:09 +00:00
changed = {},
settings_changed = false,
2014-08-11 08:39:49 +00:00
}
function SetDefaults:ConfirmEdit()
2014-08-11 18:03:03 +00:00
if not SetDefaults.EditConfirmed then
UIManager:show(ConfirmBox:new{
2014-11-14 21:01:32 +00:00
text = _("Some changes will not work until the next restart. Be careful; the wrong settings might crash KOReader!\nAre you sure you want to continue?"),
2014-08-11 18:03:03 +00:00
ok_callback = function()
self.EditConfirmed = true
self:init()
end,
})
else
self:init()
end
2014-08-11 08:39:49 +00:00
end
function SetDefaults:init()
self.screen_width = Screen:getWidth()
self.screen_height = Screen:getHeight()
self.dialog_width = math.floor(math.min(self.screen_width, self.screen_height) * 0.95)
2014-08-11 08:39:49 +00:00
self.results = {}
local defaults = {}
local load_defaults = loadfile(defaults_path)
setfenv(load_defaults, defaults)
load_defaults()
local file = io.open(persistent_defaults_path, "r")
if file ~= nil then
file:close()
load_defaults = loadfile(persistent_defaults_path)
setfenv(load_defaults, defaults)
load_defaults()
end
local idx = 1
for n, v in util.orderedPairs(defaults) do
self.defaults_name[idx] = n
self.defaults_value[idx] = v
idx = idx + 1
end
2014-08-11 08:39:49 +00:00
local menu_container = CenterContainer:new{
dimen = Screen:getSize(),
}
--- @fixme
2016-07-17 05:46:17 +00:00
-- in this use case (an input dialog is closed and the menu container is
-- opened immediately) we need to set the full screen dirty because
-- otherwise only the input dialog part of the screen is refreshed.
2014-12-04 02:09:09 +00:00
menu_container.onShow = function()
Tame some ButtonTable users into re-using Buttontable instances if possible (#7166) * QuickDictLookup, ImageViewer, NumberPicker: Smarter `update` that will re-use most of the widget's layout instead of re-instantiating all the things. * SpinWidget/DoubleSpinWidget: The NumberPicker change above renders a hack to preserve alpha on these widgets almost unnecessary. Also fixed said hack to also apply to the center, value button. * Button: Don't re-instantiate the frame in setText/setIcon when unnecessary (e.g., no change at all, or no layout change). * Button: Add a refresh method that repaints and refreshes a *specific* Button (provided it's been painted once) all on its lonesome. * ConfigDialog: Free everything that's going to be re-instatiated on update * A few more post #7118 fixes: * SkimTo: Always flag the chapter nav buttons as vsync * Button: Fix the highlight on rounded buttons when vsync is enabled (e.g., it's now entirely visible, instead of showing a weird inverted corner glitch). * Some more heuristic tweaks in Menu/TouchMenu/Button/IconButton * ButtonTable: fix the annoying rounding issue I'd noticed in #7054 ;). * Enable dithering in TextBoxWidget (e.g., in the Wikipedia full view). This involved moving the HW dithering align fixup to base, where it always ought to have been ;). * Switch a few widgets that were using "partial" on close to "ui", or, more rarely, "flashui". The intent being to limit "partial" purely to the Reader, because it has a latency cost when mixed with other refreshes, which happens often enough in UI ;). * Minor documentation tweaks around UIManager's `setDirty` to reflect that change. * ReaderFooter: Force a footer repaint on resume if it is visible (otherwise, just update it). * ReaderBookmark: In the same vein, don't repaint an invisible footer on bookmark count changes.
2021-01-28 23:20:15 +00:00
UIManager:setDirty(nil, "ui")
2014-12-04 02:09:09 +00:00
end
2014-08-11 08:39:49 +00:00
self.defaults_menu = Menu:new{
width = self.screen_width - (Size.margin.fullscreen_popout * 2),
height = self.screen_height - (Size.margin.fullscreen_popout * 2),
2017-04-29 08:38:09 +00:00
cface = Font:getFace("smallinfofont"),
2014-08-11 08:39:49 +00:00
show_parent = menu_container,
_manager = self,
}
-- Prevent menu from closing when editing a value
function self.defaults_menu:onMenuSelect(item)
item.callback()
end
2014-08-11 08:39:49 +00:00
table.insert(menu_container, self.defaults_menu)
self.defaults_menu.close_callback = function()
logger.dbg("Closing defaults menu")
self:saveBeforeExit()
2014-08-11 08:39:49 +00:00
UIManager:close(menu_container)
end
local cancel_button = {
text = _("Cancel"),
enabled = true,
callback = function()
self:close()
end,
}
for i=1, #self.defaults_name do
self.changed[i] = false
local setting_name = self.defaults_name[i]
local setting_type = type(_G[setting_name])
if setting_type == "boolean" then
local editBoolean = function()
self.set_dialog = InputDialog:new{
title = setting_name,
input = tostring(self.defaults_value[i]),
buttons = {
{
cancel_button,
{
text = "true",
enabled = true,
callback = function()
self.defaults_value[i] = true
_G[setting_name] = true
2016-09-22 07:36:09 +00:00
self.settings_changed = true
self.changed[i] = true
self.results[i].text = self:build_setting(i)
self:close()
2017-02-01 14:24:21 +00:00
self.defaults_menu:switchItemTable("Defaults", self.results, i)
end
},
{
text = "false",
enabled = true,
callback = function()
self.defaults_value[i] = false
_G[setting_name] = false
2016-09-22 07:36:09 +00:00
self.settings_changed = true
self.changed[i] = true
self.results[i].text = self:build_setting(i)
2017-02-01 14:24:21 +00:00
self.defaults_menu:switchItemTable("Defaults", self.results, i)
self:close()
end
},
},
},
input_type = setting_type,
width = self.dialog_width,
}
UIManager:show(self.set_dialog)
self.set_dialog:onShowKeyboard()
end
table.insert(self.results, {
text = self:build_setting(i),
callback = editBoolean
})
elseif setting_type == "table" then
local editTable = function()
local fields = {}
for k, v in util.orderedPairs(_G[setting_name]) do
table.insert(fields, {
text = tostring(k) .. " = " .. tostring(v),
hint = "",
padding = Screen:scaleBySize(2),
margin = Screen:scaleBySize(2),
})
end
self.set_dialog = MultiInputDialog:new{
title = setting_name,
fields = fields,
buttons = {
{
cancel_button,
{
text = _("OK"),
enabled = true,
is_enter_default = true,
callback = function()
local new_table = {}
for _, field in ipairs(MultiInputDialog:getFields()) do
local key, value = field:match("^[^= ]+"), field:match("[^= ]+$")
new_table[tonumber(key) or key] = tonumber(value) or value
end
_G[setting_name] = new_table
self.defaults_value[i] = _G[setting_name]
2016-09-22 07:36:09 +00:00
self.settings_changed = true
self.changed[i] = true
self.results[i].text = self:build_setting(i)
self:close()
2017-02-01 14:24:21 +00:00
self.defaults_menu:switchItemTable("Defaults", self.results, i)
end,
},
},
},
width = self.dialog_width,
}
UIManager:show(self.set_dialog)
self.set_dialog:onShowKeyboard()
end
table.insert(self.results, {
text = self:build_setting(i),
callback = editTable
})
else
local editNumStr = function()
self.set_dialog = InputDialog:new{
title = setting_name,
input = tostring(self.defaults_value[i]),
buttons = {
{
cancel_button,
{
text = _("OK"),
is_enter_default = true,
enabled = true,
callback = function()
local new_value = self.set_dialog:getInputValue()
if _G[setting_name] ~= new_value then
_G[setting_name] = new_value
self.defaults_value[i] = new_value
2016-09-22 07:36:09 +00:00
self.settings_changed = true
self.changed[i] = true
self.results[i].text = self:build_setting(i)
end
self:close()
2017-02-01 14:24:21 +00:00
self.defaults_menu:switchItemTable("Defaults", self.results, i)
end,
2014-08-11 08:39:49 +00:00
},
},
},
input_type = setting_type,
width = self.dialog_width,
}
UIManager:show(self.set_dialog)
self.set_dialog:onShowKeyboard()
end
table.insert(self.results, {
text = self:build_setting(i),
callback = editNumStr
})
end
2014-08-11 08:39:49 +00:00
end
2017-02-01 14:24:21 +00:00
self.defaults_menu:switchItemTable("Defaults", self.results)
2014-08-11 08:39:49 +00:00
UIManager:show(menu_container)
end
function SetDefaults:close()
UIManager:close(self.set_dialog)
end
function SetDefaults:ConfirmSave()
UIManager:show(ConfirmBox:new{
text = _('Are you sure you want to save the settings to "defaults.persistent.lua"?'),
2014-08-11 08:39:49 +00:00
ok_callback = function()
2016-07-17 05:46:17 +00:00
self:saveSettings()
2014-08-11 08:39:49 +00:00
end,
})
end
function SetDefaults:build_setting(j)
local setting_name = self.defaults_name[j]
local ret = setting_name .. " = "
if type(_G[setting_name]) == "boolean" then
return ret .. tostring(self.defaults_value[j])
elseif type(_G[setting_name]) == "table" then
return ret .. "{...}"
elseif tonumber(self.defaults_value[j]) then
return ret .. tostring(tonumber(self.defaults_value[j]))
else
return ret .. "\"" .. tostring(self.defaults_value[j]) .. "\""
end
end
2016-07-17 05:46:17 +00:00
function SetDefaults:saveSettings()
self.results = {}
local persisted_defaults = {}
local file = io.open(persistent_defaults_path, "r")
if file ~= nil then
2014-08-11 08:39:49 +00:00
file:close()
local load_defaults = loadfile(persistent_defaults_path)
setfenv(load_defaults, persisted_defaults)
load_defaults()
2014-08-11 08:39:49 +00:00
end
local checked = {}
for j=1, #self.defaults_name do
if not self.changed[j] then checked[j] = true end
end
-- load default value for defaults
local defaults = {}
local load_defaults = loadfile(defaults_path)
setfenv(load_defaults, defaults)
load_defaults()
-- handle case "found in persistent" and changed, replace/delete it
for k, v in pairs(persisted_defaults) do
for j=1, #self.defaults_name do
if not checked[j]
and k == self.defaults_name[j] then
-- remove from persist if value got reverted back to the
-- default one
if defaults[k] == self.defaults_value[j] then
persisted_defaults[k] = nil
else
persisted_defaults[k] = self.defaults_value[j]
end
checked[j] = true
2014-08-11 08:39:49 +00:00
end
end
end
-- handle case "not in persistent and different in non-persistent", add to
-- persistent
for j=1, #self.defaults_name do
if not checked[j] then
persisted_defaults[self.defaults_name[j]] = self.defaults_value[j]
2014-08-11 08:39:49 +00:00
end
end
file = io.open(persistent_defaults_path, "w")
if file then
file:write("-- For configuration changes that persists between updates\n")
for k, v in pairs(persisted_defaults) do
local line = {}
table.insert(line, k)
table.insert(line, " = ")
table.insert(line, dump(v))
table.insert(line, "\n")
file:write(table.concat(line))
end
file:close()
UIManager:show(InfoMessage:new{
text = _("Default settings saved."),
})
2014-08-11 08:39:49 +00:00
end
2016-09-22 07:36:09 +00:00
self.settings_changed = false
2014-08-11 08:39:49 +00:00
end
function SetDefaults:saveBeforeExit(callback)
local save_text = _("Save and quit")
if Device:canRestart() then
save_text = _("Save and restart")
end
if self.settings_changed then
UIManager:show(ConfirmBox:new{
text = _("KOReader needs to be restarted to apply the new default settings."),
ok_text = save_text,
ok_callback = function()
self.settings_changed = false
self:saveSettings()
if Device:canRestart() then
UIManager:restartKOReader()
else
UIManager:quit()
end
end,
cancel_text = _("Discard changes"),
cancel_callback = function()
logger.info("discard defaults")
pcall(dofile, defaults_path)
pcall(dofile, persistent_defaults_path)
self.settings_changed = false
end,
})
end
end
2014-08-11 08:39:49 +00:00
return SetDefaults