mirror of
https://github.com/koreader/koreader
synced 2024-11-13 19:11:25 +00:00
eef938996f
Stuff was poking at the class object, not the instance's :s. Fix #9599
318 lines
12 KiB
Lua
318 lines
12 KiB
Lua
local CenterContainer = require("ui/widget/container/centercontainer")
|
|
local ConfirmBox = require("ui/widget/confirmbox")
|
|
local Device = require("device")
|
|
local InfoMessage = require("ui/widget/infomessage")
|
|
local InputDialog = require("ui/widget/inputdialog")
|
|
local Menu = require("ui/widget/menu")
|
|
local MultiInputDialog = require("ui/widget/multiinputdialog")
|
|
local Size = require("ui/size")
|
|
local UIManager = require("ui/uimanager")
|
|
local logger = require("logger")
|
|
local ffiUtil = require("ffi/util")
|
|
local util = require("util")
|
|
local _ = require("gettext")
|
|
local Screen = require("device").screen
|
|
|
|
local SetDefaultsWidget = CenterContainer:extend{
|
|
state = nil,
|
|
menu_entries = nil,
|
|
defaults_menu = nil,
|
|
settings_changed = false,
|
|
}
|
|
|
|
function SetDefaultsWidget:init()
|
|
-- This would usually be passed to the constructor, as CenterContainer's paintTo does *NOT* set/update self.dimen...
|
|
self.dimen = Screen:getSize()
|
|
-- Don't refresh the FM behind us. May leave stray bits of overflowed InputDialog behind in the popout border space.
|
|
self.covers_fullscreen = true
|
|
|
|
-- Then deal with our child widgets and our internal variables
|
|
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)
|
|
|
|
-- Keep track of what's an actual default, and what's been customized without actually touching the real data yet...
|
|
self.state = {}
|
|
local ro_defaults, rw_defaults = G_defaults:getDataTables()
|
|
for k, v in pairs(ro_defaults) do
|
|
self.state[k] = {
|
|
idx = 1,
|
|
value = v,
|
|
custom = false,
|
|
dirty = false,
|
|
default_value = v,
|
|
}
|
|
end
|
|
for k, v in pairs(rw_defaults) do
|
|
self.state[k].value = v
|
|
self.state[k].custom = true
|
|
end
|
|
|
|
-- Prepare our menu entires
|
|
self.menu_entries = {}
|
|
|
|
local set_dialog
|
|
local cancel_button = {
|
|
text = _("Cancel"),
|
|
id = "close",
|
|
enabled = true,
|
|
callback = function()
|
|
UIManager:close(set_dialog)
|
|
end,
|
|
}
|
|
|
|
local i = 0
|
|
for k, t in ffiUtil.orderedPairs(self.state) do
|
|
local v = t.value
|
|
i = i + 1
|
|
self.state[k].idx = i
|
|
local value_type = type(v)
|
|
if value_type == "boolean" then
|
|
local editBoolean = function()
|
|
set_dialog = InputDialog:new{
|
|
title = k,
|
|
input = tostring(self.state[k].value),
|
|
buttons = {
|
|
{
|
|
cancel_button,
|
|
{
|
|
text = _("Default"),
|
|
enabled = self.state[k].value ~= self.state[k].default_value,
|
|
callback = function()
|
|
UIManager:close(set_dialog)
|
|
self:update_menu_entry(k, self.state[k].default_value, value_type)
|
|
end
|
|
},
|
|
{
|
|
text = "true",
|
|
enabled = true,
|
|
callback = function()
|
|
UIManager:close(set_dialog)
|
|
self:update_menu_entry(k, true, value_type)
|
|
end
|
|
},
|
|
{
|
|
text = "false",
|
|
enabled = true,
|
|
callback = function()
|
|
UIManager:close(set_dialog)
|
|
self:update_menu_entry(k, false, value_type)
|
|
end
|
|
},
|
|
},
|
|
},
|
|
input_type = value_type,
|
|
width = self.dialog_width,
|
|
}
|
|
UIManager:show(set_dialog)
|
|
set_dialog:onShowKeyboard()
|
|
end
|
|
|
|
table.insert(self.menu_entries, {
|
|
text = self:gen_menu_entry(k, self.state[k].value, value_type),
|
|
bold = self.state[k].custom,
|
|
callback = editBoolean
|
|
})
|
|
elseif value_type == "table" then
|
|
local editTable = function()
|
|
local fields = {}
|
|
for key, value in ffiUtil.orderedPairs(self.state[k].value) do
|
|
table.insert(fields, {
|
|
text = tostring(key) .. " = " .. tostring(value),
|
|
input_type = type(value),
|
|
hint = "",
|
|
padding = Screen:scaleBySize(2),
|
|
margin = Screen:scaleBySize(2),
|
|
})
|
|
end
|
|
set_dialog = MultiInputDialog:new{
|
|
title = k,
|
|
fields = fields,
|
|
buttons = {
|
|
{
|
|
cancel_button,
|
|
{
|
|
text = _("Default"),
|
|
enabled = not util.tableEquals(self.state[k].value, self.state[k].default_value),
|
|
callback = function()
|
|
UIManager:close(set_dialog)
|
|
self:update_menu_entry(k, self.state[k].default_value, value_type)
|
|
end
|
|
},
|
|
{
|
|
text = _("OK"),
|
|
enabled = true,
|
|
is_enter_default = true,
|
|
callback = function()
|
|
UIManager:close(set_dialog)
|
|
local new_table = {}
|
|
for _, field in ipairs(set_dialog:getFields()) do
|
|
local key, value = field:match("^[^= ]+"), field:match("[^= ]+$")
|
|
new_table[tonumber(key) or key] = tonumber(value) or value
|
|
end
|
|
self:update_menu_entry(k, new_table, value_type)
|
|
end,
|
|
},
|
|
},
|
|
},
|
|
width = self.dialog_width,
|
|
}
|
|
UIManager:show(set_dialog)
|
|
set_dialog:onShowKeyboard()
|
|
end
|
|
|
|
table.insert(self.menu_entries, {
|
|
text = self:gen_menu_entry(k, self.state[k].value, value_type),
|
|
bold = self.state[k].custom,
|
|
callback = editTable
|
|
})
|
|
else
|
|
local editNumStr = function()
|
|
set_dialog = InputDialog:new{
|
|
title = k,
|
|
input = tostring(self.state[k].value),
|
|
buttons = {
|
|
{
|
|
cancel_button,
|
|
{
|
|
text = _("Default"),
|
|
enabled = self.state[k].value ~= self.state[k].default_value,
|
|
callback = function()
|
|
UIManager:close(set_dialog)
|
|
self:update_menu_entry(k, self.state[k].default_value, value_type)
|
|
end
|
|
},
|
|
{
|
|
text = _("OK"),
|
|
is_enter_default = true,
|
|
enabled = true,
|
|
callback = function()
|
|
UIManager:close(set_dialog)
|
|
local new_value = set_dialog:getInputValue()
|
|
self:update_menu_entry(k, new_value, value_type)
|
|
end,
|
|
},
|
|
},
|
|
},
|
|
input_type = value_type,
|
|
width = self.dialog_width,
|
|
}
|
|
UIManager:show(set_dialog)
|
|
set_dialog:onShowKeyboard()
|
|
end
|
|
|
|
table.insert(self.menu_entries, {
|
|
text = self:gen_menu_entry(k, self.state[k].value, value_type),
|
|
bold = self.state[k].custom,
|
|
callback = editNumStr
|
|
})
|
|
end
|
|
end
|
|
|
|
-- Now that we have stuff to display, instantiate our Menu
|
|
self.defaults_menu = Menu:new{
|
|
width = self.screen_width - (Size.margin.fullscreen_popout * 2),
|
|
height = self.screen_height - (Size.margin.fullscreen_popout * 2),
|
|
show_parent = self,
|
|
item_table = self.menu_entries,
|
|
title = _("Defaults"),
|
|
}
|
|
-- Prevent menu from closing when editing a value
|
|
function self.defaults_menu:onMenuSelect(item)
|
|
item.callback()
|
|
end
|
|
self.defaults_menu.close_callback = function()
|
|
logger.dbg("Closing defaults menu")
|
|
self:saveBeforeExit()
|
|
UIManager:close(self)
|
|
end
|
|
|
|
table.insert(self, self.defaults_menu)
|
|
end
|
|
|
|
function SetDefaultsWidget:gen_menu_entry(k, v, v_type)
|
|
local ret = k .. " = "
|
|
if v_type == "boolean" then
|
|
return ret .. tostring(v)
|
|
elseif v_type == "table" then
|
|
return ret .. "{...}"
|
|
elseif tonumber(v) then
|
|
return ret .. tostring(tonumber(v))
|
|
else
|
|
return ret .. "\"" .. tostring(v) .. "\""
|
|
end
|
|
end
|
|
|
|
function SetDefaultsWidget:update_menu_entry(k, v, v_type)
|
|
local idx = self.state[k].idx
|
|
self.state[k].value = v
|
|
self.state[k].dirty = true
|
|
self.settings_changed = true
|
|
self.menu_entries[idx].text = self:gen_menu_entry(k, v, v_type)
|
|
if util.tableEquals(v, self.state[k].default_value) then
|
|
self.menu_entries[idx].bold = false
|
|
else
|
|
self.menu_entries[idx].bold = true
|
|
end
|
|
self.defaults_menu:switchItemTable(nil, self.menu_entries, idx)
|
|
end
|
|
|
|
function SetDefaultsWidget:saveSettings()
|
|
-- Update dirty keys for real
|
|
for k, t in pairs(self.state) do
|
|
if t.dirty then
|
|
G_defaults:saveSetting(k, t.value)
|
|
end
|
|
end
|
|
|
|
-- And flush to disk
|
|
G_defaults:flush()
|
|
UIManager:show(InfoMessage:new{
|
|
text = _("Default settings saved."),
|
|
})
|
|
end
|
|
|
|
function SetDefaultsWidget: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{
|
|
dismissable = false,
|
|
text = _("KOReader needs to be restarted to apply the new default settings."),
|
|
ok_text = save_text,
|
|
ok_callback = function()
|
|
self:saveSettings()
|
|
if Device:canRestart() then
|
|
UIManager:restartKOReader()
|
|
else
|
|
UIManager:quit()
|
|
end
|
|
end,
|
|
cancel_text = _("Discard changes"),
|
|
cancel_callback = function()
|
|
logger.info("discard defaults")
|
|
end,
|
|
})
|
|
end
|
|
end
|
|
|
|
local SetDefaults = {}
|
|
|
|
function SetDefaults:ConfirmEdit()
|
|
if not SetDefaults.EditConfirmed then
|
|
UIManager:show(ConfirmBox:new{
|
|
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?"),
|
|
ok_callback = function()
|
|
SetDefaults.EditConfirmed = true
|
|
UIManager:show(SetDefaultsWidget:new{})
|
|
end,
|
|
})
|
|
else
|
|
UIManager:show(SetDefaultsWidget:new{})
|
|
end
|
|
end
|
|
|
|
return SetDefaults
|