2
0
mirror of https://github.com/koreader/koreader synced 2024-11-16 06:12:56 +00:00
koreader/frontend/apps/filemanager/filemanagersetdefaults.lua
Robert d163f8281d Menu: configure number of items per page, wrap entries (#3589)
Configure number of items per page (from 6 to 24) - default is 14
Allow filenames to wrap so that we can see the full name
Used by File browser, History, Search Result, Bookmarks, Table of contents (only single line), File chooser, OPDS catalog
2018-01-13 23:38:53 +01:00

354 lines
13 KiB
Lua

local CenterContainer = require("ui/widget/container/centercontainer")
local ConfirmBox = require("ui/widget/confirmbox")
local DataStorage = require("datastorage")
local Font = require("ui/font")
local InfoMessage = require("ui/widget/infomessage")
local InputContainer = require("ui/widget/container/inputcontainer")
local InputDialog = require("ui/widget/inputdialog")
local Menu = require("ui/widget/menu")
local MultiInputDialog = require("ui/widget/multiinputdialog")
local UIManager = require("ui/uimanager")
local dump = require("dump")
local isAndroid, android = pcall(require, "android")
local util = require("ffi/util")
local _ = require("gettext")
local Screen = require("device").screen
local function getDefaultsPath()
local defaults_path = DataStorage:getDataDir() .. "/defaults.lua"
if isAndroid then
defaults_path = android.dir .. "/defaults.lua"
end
return defaults_path
end
local defaults_path = getDefaultsPath()
local persistent_defaults_path = DataStorage:getDataDir() .. "/defaults.persistent.lua"
local SetDefaults = InputContainer:new{
defaults_name = {},
defaults_value = {},
results = {},
defaults_menu = {},
initialized = false,
changed = {},
settings_changed = false,
}
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()
self.EditConfirmed = true
self:init()
end,
})
else
self:init()
end
end
function SetDefaults:init()
self.results = {}
if not self.initialized then
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 i = 1
for n, v in util.orderedPairs(defaults) do
self.defaults_name[i] = n
self.defaults_value[i] = v
i = i + 1
end
self.initialized = true
end
local menu_container = CenterContainer:new{
dimen = Screen:getSize(),
}
-- FIXME:
-- 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.
menu_container.onShow = function()
UIManager:setDirty(nil, "partial")
end
self.defaults_menu = Menu:new{
width = Screen:getWidth()-15,
height = Screen:getHeight()-15,
cface = Font:getFace("smallinfofont"),
perpage = G_reader_settings:readSetting("items_per_page") or 14,
show_parent = menu_container,
_manager = self,
}
table.insert(menu_container, self.defaults_menu)
self.defaults_menu.close_callback = function()
UIManager:close(menu_container)
end
local cancel_button = {
text = _("Cancel"),
enabled = true,
callback = function()
self:close()
UIManager:show(menu_container)
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
self.settings_changed = true
self.changed[i] = true
self.results[i].text = self:build_setting(i)
self:close()
self.defaults_menu:switchItemTable("Defaults", self.results, i)
UIManager:show(menu_container)
end
},
{
text = "false",
enabled = true,
callback = function()
self.defaults_value[i] = false
_G[setting_name] = false
self.settings_changed = true
self.changed[i] = true
self.results[i].text = self:build_setting(i)
self.defaults_menu:switchItemTable("Defaults", self.results, i)
self:close()
UIManager:show(menu_container)
end
},
},
},
input_type = setting_type,
width = Screen:getWidth() * 0.95,
}
self.set_dialog:onShowKeyboard()
UIManager:show(self.set_dialog)
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 = "",
})
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]
self.settings_changed = true
self.changed[i] = true
self.results[i].text = self:build_setting(i)
self:close()
self.defaults_menu:switchItemTable("Defaults", self.results, i)
UIManager:show(menu_container)
end,
},
},
},
width = Screen:getWidth() * 0.95,
height = Screen:getHeight() * 0.2,
}
self.set_dialog:onShowKeyboard()
UIManager:show(self.set_dialog)
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
self.settings_changed = true
self.changed[i] = true
self.results[i].text = self:build_setting(i)
end
self:close()
self.defaults_menu:switchItemTable("Defaults", self.results, i)
UIManager:show(menu_container)
end,
},
},
},
input_type = setting_type,
width = Screen:getWidth() * 0.95,
}
self.set_dialog:onShowKeyboard()
UIManager:show(self.set_dialog)
end
table.insert(self.results, {
text = self:build_setting(i),
callback = editNumStr
})
end
end
self.defaults_menu:switchItemTable("Defaults", self.results)
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"?'),
ok_callback = function()
self:saveSettings()
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
function SetDefaults:saveSettings()
self.results = {}
local persisted_defaults = {}
local file = io.open(persistent_defaults_path, "r")
if file ~= nil then
file:close()
local load_defaults = loadfile(persistent_defaults_path)
setfenv(load_defaults, persisted_defaults)
load_defaults()
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
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]
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."),
})
end
self.settings_changed = false
end
return SetDefaults