Misc: Get rid of the legacy defaults.lua globals (#9546)

* This removes support for the following deprecated constants: `DTAP_ZONE_FLIPPING`, `DTAP_ZONE_BOOKMARK`, `DCREREADER_CONFIG_DEFAULT_FONT_GAMMA`
* The "Advanced settings" panel now highlights modified values in bold (think about:config in Firefox ;)).
* LuaData: Isolate global table lookup shenanigans, and fix a few issues in unused-in-prod codepaths.
* CodeStyle: Require module locals for Lua/C modules, too.
* ScreenSaver: Actually garbage collect our widget on close (ScreenSaver itself is not an instantiated object).
* DateTimeWidget: Code cleanups to ensure child widgets can be GC'ed.
reviewable/pr9566/r1
NiLuJe 2 years ago committed by GitHub
parent 46f729c248
commit 62059f8d68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,120 +5,11 @@ self = false
globals = { globals = {
"G_reader_settings", "G_reader_settings",
"G_defaults",
} }
read_globals = { read_globals = {
"_ENV", "_ENV",
"KOBO_SYNC_BRIGHTNESS_WITH_NICKEL",
"DHINTCOUNT",
"DRENDER_MODE",
"DGLOBAL_CACHE_SIZE_MINIMUM",
"DGLOBAL_CACHE_FREE_PROPORTION",
"DGLOBAL_CACHE_SIZE_MAXIMUM",
"DBACKGROUND_COLOR",
"DOUTER_PAGE_COLOR",
"DGENERIC_ICON_SIZE",
"DCREREADER_VIEW_MODE",
"DSHOWOVERLAP",
"DSHOWHIDDENFILES",
"DLANDSCAPE_CLOCKWISE_ROTATION",
"DCREREADER_TWO_PAGE_THRESHOLD",
"DOVERLAPPIXELS",
"FOLLOW_LINK_TIMEOUT",
"DTAP_ZONE_MENU",
"DTAP_ZONE_MENU_EXT",
"DTAP_ZONE_CONFIG",
"DTAP_ZONE_CONFIG_EXT",
"DTAP_ZONE_MINIBAR",
"DTAP_ZONE_FORWARD",
"DTAP_ZONE_BACKWARD",
"DTAP_ZONE_BOOKMARK",
"DTAP_ZONE_FLIPPING",
"DTAP_ZONE_TOP_LEFT",
"DTAP_ZONE_TOP_RIGHT",
"DTAP_ZONE_BOTTOM_LEFT",
"DTAP_ZONE_BOTTOM_RIGHT",
"DDOUBLE_TAP_ZONE_NEXT_CHAPTER",
"DDOUBLE_TAP_ZONE_PREV_CHAPTER",
"DKOPTREADER_CONFIG_FONT_SIZE",
"DKOPTREADER_CONFIG_TEXT_WRAP",
"DKOPTREADER_CONFIG_TRIM_PAGE",
"DKOPTREADER_CONFIG_DETECT_INDENT",
"DKOPTREADER_CONFIG_DEFECT_SIZE",
"DKOPTREADER_CONFIG_PAGE_MARGIN",
"DKOPTREADER_CONFIG_LINE_SPACING",
"DKOPTREADER_CONFIG_RENDER_QUALITY",
"DKOPTREADER_CONFIG_AUTO_STRAIGHTEN",
"DKOPTREADER_CONFIG_JUSTIFICATION",
"DKOPTREADER_CONFIG_MAX_COLUMNS",
"DKOPTREADER_CONFIG_CONTRAST",
"DKOPTREADER_CONFIG_WORD_SPACINGS",
"DKOPTREADER_CONFIG_DEFAULT_WORD_SPACING",
"DKOPTREADER_CONFIG_DOC_LANGS_TEXT",
"DKOPTREADER_CONFIG_DOC_LANGS_CODE",
"DKOPTREADER_CONFIG_DOC_DEFAULT_LANG_CODE",
"DCREREADER_CONFIG_FONT_SIZES",
"DCREREADER_CONFIG_DEFAULT_FONT_SIZE",
"DCREREADER_CONFIG_H_MARGIN_SIZES_SMALL",
"DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM",
"DCREREADER_CONFIG_H_MARGIN_SIZES_LARGE",
"DCREREADER_CONFIG_H_MARGIN_SIZES_X_LARGE",
"DCREREADER_CONFIG_H_MARGIN_SIZES_XX_LARGE",
"DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE",
"DCREREADER_CONFIG_H_MARGIN_SIZES_HUGE",
"DCREREADER_CONFIG_H_MARGIN_SIZES_X_HUGE",
"DCREREADER_CONFIG_H_MARGIN_SIZES_XX_HUGE",
"DCREREADER_CONFIG_T_MARGIN_SIZES_SMALL",
"DCREREADER_CONFIG_T_MARGIN_SIZES_MEDIUM",
"DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE",
"DCREREADER_CONFIG_T_MARGIN_SIZES_X_LARGE",
"DCREREADER_CONFIG_T_MARGIN_SIZES_XX_LARGE",
"DCREREADER_CONFIG_T_MARGIN_SIZES_XXX_LARGE",
"DCREREADER_CONFIG_T_MARGIN_SIZES_HUGE",
"DCREREADER_CONFIG_T_MARGIN_SIZES_X_HUGE",
"DCREREADER_CONFIG_T_MARGIN_SIZES_XX_HUGE",
"DCREREADER_CONFIG_B_MARGIN_SIZES_SMALL",
"DCREREADER_CONFIG_B_MARGIN_SIZES_MEDIUM",
"DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE",
"DCREREADER_CONFIG_B_MARGIN_SIZES_X_LARGE",
"DCREREADER_CONFIG_B_MARGIN_SIZES_XX_LARGE",
"DCREREADER_CONFIG_B_MARGIN_SIZES_XXX_LARGE",
"DCREREADER_CONFIG_B_MARGIN_SIZES_HUGE",
"DCREREADER_CONFIG_B_MARGIN_SIZES_X_HUGE",
"DCREREADER_CONFIG_B_MARGIN_SIZES_XX_HUGE",
"DCREREADER_CONFIG_LIGHTER_FONT_GAMMA",
"DCREREADER_CONFIG_DEFAULT_FONT_GAMMA",
"DCREREADER_CONFIG_DARKER_FONT_GAMMA",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_TINY",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_TINY",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_SMALL",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_SMALL",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_SMALL",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_SMALL",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_MEDIUM",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_XL_MEDIUM",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_XXL_MEDIUM",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_LARGE",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_LARGE",
"DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_LARGE",
"DCREREADER_CONFIG_WORD_SPACING_SMALL",
"DCREREADER_CONFIG_WORD_SPACING_MEDIUM",
"DCREREADER_CONFIG_WORD_SPACING_LARGE",
"DCREREADER_CONFIG_WORD_EXPANSION_NONE",
"DCREREADER_CONFIG_WORD_EXPANSION_SOME",
"DCREREADER_CONFIG_WORD_EXPANSION_MORE",
"DMINIBAR_CONTAINER_HEIGHT",
"DGESDETECT_DISABLE_DOUBLE_TAP",
"DALPHA_SORT_CASE_INSENSITIVE",
"KOBO_LIGHT_ON_START",
"NETWORK_PROXY",
"DUSE_TURBO_LIB",
"STARDICT_DATA_DIR",
"cre",
"lfs",
"lipc",
"xtext",
} }
exclude_files = { exclude_files = {

@ -1 +1 @@
Subproject commit 452695ff92a63476e90d9762f172c1486276901a Subproject commit 2ed9aba5de31e5e60f18bf451df735fe91ddde3a

@ -1,176 +1,154 @@
-- To make configuration changes that persists between (nightly) releases, -- To make configuration changes that persists between (nightly) releases,
-- copy defaults.lua to defaults.persistent.lua and make the changes there. -- copy defaults.lua to defaults.custom.lua and make the changes there,
-- or go to [Tools] > More tools > Advanced settings in the filemanager.
-- number of page turns between full screen refresh
-- default to do a full refresh on every 6 page turns
-- no longer needed
--DRCOUNTMAX = 6
return {
-- number of pages for hinting -- number of pages for hinting
-- default to pre-rendering 1 page -- default to pre-rendering 1 page
DHINTCOUNT = 1 DHINTCOUNT = 1,
-- full screen mode, 1 for true, 0 for false
-- no longer needed
--DFULL_SCREEN = 1
-- scroll mode, 1 for true, 0 for false
-- no longer needed
--DSCROLL_MODE = 1
-- default gamma setting:
-- no longer needed
--DGLOBALGAMMA = 1.0
-- DjVu page rendering mode (used in djvu.c:drawPage()) -- DjVu page rendering mode (used in djvu.c:drawPage())
-- See comments in djvureader.lua:DJVUReader:select_render_mode() -- See comments in djvureader.lua:DJVUReader:select_render_mode()
DRENDER_MODE = 0 -- 0 is COLOUR DRENDER_MODE = 0, -- 0 is COLOUR
-- minimum cache size -- minimum cache size
DGLOBAL_CACHE_SIZE_MINIMUM = 1024*1024*16 DGLOBAL_CACHE_SIZE_MINIMUM = 1024*1024*16,
-- proportion of system free memory used as global cache -- proportion of system free memory used as global cache
DGLOBAL_CACHE_FREE_PROPORTION = 0.4 DGLOBAL_CACHE_FREE_PROPORTION = 0.4,
-- maximum cache size -- maximum cache size
DGLOBAL_CACHE_SIZE_MAXIMUM = 1024*1024*512 DGLOBAL_CACHE_SIZE_MAXIMUM = 1024*1024*512,
-- background colour in non scroll mode: 8 = gray, 0 = white, 15 = black -- background colour in non scroll mode: 8 = gray, 0 = white, 15 = black
DBACKGROUND_COLOR = 0 DBACKGROUND_COLOR = 0,
-- outer page colour in scroll mode: 8 = gray, 0 = white, 15 = black -- outer page colour in scroll mode: 8 = gray, 0 = white, 15 = black
DOUTER_PAGE_COLOR = 0 DOUTER_PAGE_COLOR = 0,
-- generic icon size -- generic icon size
DGENERIC_ICON_SIZE = 40 DGENERIC_ICON_SIZE = 40,
-- supported view mode includes: "scroll" and "page" -- supported view mode includes: "scroll" and "page"
DCREREADER_VIEW_MODE = "page" DCREREADER_VIEW_MODE = "page",
-- show dimmed area to indicate page overlap in "page" view mode, -- show dimmed area to indicate page overlap in "page" view mode,
-- default to false -- default to false
DSHOWOVERLAP = false DSHOWOVERLAP = false,
-- show hidden files in filemanager -- show hidden files in filemanager
-- default to false -- default to false
DSHOWHIDDENFILES = false DSHOWHIDDENFILES = false,
-- landscape clockwise rotation -- landscape clockwise rotation
-- default to true, set to false for counterclockwise rotation -- default to true, set to false for counterclockwise rotation
DLANDSCAPE_CLOCKWISE_ROTATION = true DLANDSCAPE_CLOCKWISE_ROTATION = true,
-- default minimum screen height for reading with 2 pages in landscape mode -- default minimum screen height for reading with 2 pages in landscape mode
DCREREADER_TWO_PAGE_THRESHOLD = 7 DCREREADER_TWO_PAGE_THRESHOLD = 7,
-- page overlap pixels -- page overlap pixels
DOVERLAPPIXELS = 30 DOVERLAPPIXELS = 30,
-- timeout to show link rectangle around links -- timeout to show link rectangle around links
-- default to 0.5 second -- default to 0.5 second
-- set to 0 to disable showing rectangle and follow link immediately -- set to 0 to disable showing rectangle and follow link immediately
FOLLOW_LINK_TIMEOUT = 0.5 FOLLOW_LINK_TIMEOUT = 0.5,
-- customizable tap zones(rectangles) -- customizable tap zones(rectangles)
-- x: x coordinate of top left corner in proportion to screen width -- x: x coordinate of top left corner in proportion to screen width
-- y: y coordinate of top left corner in proportion to screen height -- y: y coordinate of top left corner in proportion to screen height
-- w: tap zone width in proportion to screen width -- w: tap zone width in proportion to screen width
-- h: tap zone height in proportion to screen height -- h: tap zone height in proportion to screen height
DTAP_ZONE_MENU = {x = 0, y = 0, w = 1, h = 1/8} DTAP_ZONE_MENU = {x = 0, y = 0, w = 1, h = 1/8},
DTAP_ZONE_MENU_EXT = {x = 1/4, y = 0, w = 2/4, h = 1/5} -- taller, narrower extension DTAP_ZONE_MENU_EXT = {x = 1/4, y = 0, w = 2/4, h = 1/5}, -- taller, narrower extension
DTAP_ZONE_CONFIG = {x = 0, y = 7/8, w = 1, h = 1/8} DTAP_ZONE_CONFIG = {x = 0, y = 7/8, w = 1, h = 1/8},
DTAP_ZONE_CONFIG_EXT = {x = 1/4, y = 4/5, w = 2/4, h = 1/5} -- taller, narrower extension DTAP_ZONE_CONFIG_EXT = {x = 1/4, y = 4/5, w = 2/4, h = 1/5}, -- taller, narrower extension
DTAP_ZONE_MINIBAR = {x = 0, y = 12/13, w = 1, h = 1/13} DTAP_ZONE_MINIBAR = {x = 0, y = 12/13, w = 1, h = 1/13},
DTAP_ZONE_FORWARD = {x = 1/4, y = 0, w = 3/4, h = 1} DTAP_ZONE_FORWARD = {x = 1/4, y = 0, w = 3/4, h = 1},
DTAP_ZONE_BACKWARD = {x = 0, y = 0, w = 1/4, h = 1} DTAP_ZONE_BACKWARD = {x = 0, y = 0, w = 1/4, h = 1},
-- DTAP_ZONE_BOOKMARK = {x = 7/8, y = 0, w = 1/8, h = 1/8} -- deprecated DTAP_ZONE_TOP_LEFT = {x = 0, y = 0, w = 1/8, h = 1/8},
-- DTAP_ZONE_FLIPPING = {x = 0, y = 0, w = 1/8, h = 1/8} -- deprecated DTAP_ZONE_TOP_RIGHT = {x = 7/8, y = 0, w = 1/8, h = 1/8},
DTAP_ZONE_TOP_LEFT = {x = 0, y = 0, w = 1/8, h = 1/8} DTAP_ZONE_BOTTOM_LEFT = {x = 0, y = 7/8, w = 1/8, h = 1/8},
DTAP_ZONE_TOP_RIGHT = {x = 7/8, y = 0, w = 1/8, h = 1/8} DTAP_ZONE_BOTTOM_RIGHT = {x = 7/8, y = 7/8, w = 1/8, h = 1/8},
DTAP_ZONE_BOTTOM_LEFT = {x = 0, y = 7/8, w = 1/8, h = 1/8} DDOUBLE_TAP_ZONE_NEXT_CHAPTER = {x = 1/4, y = 0, w = 3/4, h = 1},
DTAP_ZONE_BOTTOM_RIGHT = {x = 7/8, y = 7/8, w = 1/8, h = 1/8} DDOUBLE_TAP_ZONE_PREV_CHAPTER = {x = 0, y = 0, w = 1/4, h = 1},
DDOUBLE_TAP_ZONE_NEXT_CHAPTER = {x = 1/4, y = 0, w = 3/4, h = 1}
DDOUBLE_TAP_ZONE_PREV_CHAPTER = {x = 0, y = 0, w = 1/4, h = 1}
-- koptreader config defaults -- koptreader config defaults
DKOPTREADER_CONFIG_FONT_SIZE = 1.0 -- range from 0.1 to 3.0 DKOPTREADER_CONFIG_FONT_SIZE = 1.0, -- range from 0.1 to 3.0
DKOPTREADER_CONFIG_TEXT_WRAP = 0 -- 1 = on, 0 = off DKOPTREADER_CONFIG_TEXT_WRAP = 0, -- 1 = on, 0 = off
DKOPTREADER_CONFIG_TRIM_PAGE = 1 -- 1 = auto, 0 = manual DKOPTREADER_CONFIG_TRIM_PAGE = 1, -- 1 = auto, 0 = manual
DKOPTREADER_CONFIG_DETECT_INDENT = 1 -- 1 = enable, 0 = disable DKOPTREADER_CONFIG_DETECT_INDENT = 1, -- 1 = enable, 0 = disable
DKOPTREADER_CONFIG_DEFECT_SIZE = 1.0 -- range from 0.0 to 3.0 DKOPTREADER_CONFIG_DEFECT_SIZE = 1.0, -- range from 0.0 to 3.0
DKOPTREADER_CONFIG_PAGE_MARGIN = 0.10 -- range from 0.0 to 1.0 DKOPTREADER_CONFIG_PAGE_MARGIN = 0.10, -- range from 0.0 to 1.0
DKOPTREADER_CONFIG_LINE_SPACING = 1.2 -- range from 0.5 to 2.0 DKOPTREADER_CONFIG_LINE_SPACING = 1.2, -- range from 0.5 to 2.0
DKOPTREADER_CONFIG_RENDER_QUALITY = 1.0 -- range from 0.5 to 2.0 DKOPTREADER_CONFIG_RENDER_QUALITY = 1.0, -- range from 0.5 to 2.0
DKOPTREADER_CONFIG_AUTO_STRAIGHTEN = 0 -- range from 0 to 10 DKOPTREADER_CONFIG_AUTO_STRAIGHTEN = 0, -- range from 0 to 10
DKOPTREADER_CONFIG_JUSTIFICATION = 3 -- -1 = auto, 0 = left, 1 = center, 2 = right, 3 = full DKOPTREADER_CONFIG_JUSTIFICATION = 3, -- -1 = auto, 0 = left, 1 = center, 2 = right, 3 = full
DKOPTREADER_CONFIG_MAX_COLUMNS = 2 -- range from 1 to 4 DKOPTREADER_CONFIG_MAX_COLUMNS = 2, -- range from 1 to 4
DKOPTREADER_CONFIG_CONTRAST = 1.0 -- range from 0.2 to 2.0 DKOPTREADER_CONFIG_CONTRAST = 1.0, -- range from 0.2 to 2.0
-- word spacing for reflow -- word spacing for reflow
DKOPTREADER_CONFIG_WORD_SPACINGS = {0.05, -0.2, 0.375} -- range from (+/-)0.05 to (+/-)0.5 DKOPTREADER_CONFIG_WORD_SPACINGS = {0.05, -0.2, 0.375}, -- range from (+/-)0.05 to (+/-)0.5
DKOPTREADER_CONFIG_DEFAULT_WORD_SPACING = -0.2 -- range from (+/-)0.05 to (+/-)0.5 DKOPTREADER_CONFIG_DEFAULT_WORD_SPACING = -0.2, -- range from (+/-)0.05 to (+/-)0.5
-- document languages for OCR -- document languages for OCR
DKOPTREADER_CONFIG_DOC_LANGS_TEXT = {"English", "Chinese"} DKOPTREADER_CONFIG_DOC_LANGS_TEXT = {"English", "Chinese"},
DKOPTREADER_CONFIG_DOC_LANGS_CODE = {"eng", "chi_sim"} -- language code, make sure you have corresponding training data DKOPTREADER_CONFIG_DOC_LANGS_CODE = {"eng", "chi_sim"}, -- language code, make sure you have corresponding training data
DKOPTREADER_CONFIG_DOC_DEFAULT_LANG_CODE = "eng" -- that have filenames starting with the language codes DKOPTREADER_CONFIG_DOC_DEFAULT_LANG_CODE = "eng", -- that have filenames starting with the language codes
-- crereader font sizes -- crereader font sizes
-- feel free to add more entries in this list -- feel free to add more entries in this list
DCREREADER_CONFIG_FONT_SIZES = {12, 16, 20, 22, 24, 26, 28, 30, 34, 38, 44} -- option range from 12 to 44 DCREREADER_CONFIG_FONT_SIZES = {12, 16, 20, 22, 24, 26, 28, 30, 34, 38, 44}, -- option range from 12 to 44
DCREREADER_CONFIG_DEFAULT_FONT_SIZE = 22 -- default font size DCREREADER_CONFIG_DEFAULT_FONT_SIZE = 22, -- default font size
-- crereader margin sizes -- crereader margin sizes
-- horizontal margins {left, right} in (relative) pixels -- horizontal margins {left, right} in (relative) pixels
DCREREADER_CONFIG_H_MARGIN_SIZES_SMALL = {5, 5} DCREREADER_CONFIG_H_MARGIN_SIZES_SMALL = {5, 5},
DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM = {10, 10} DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM = {10, 10},
DCREREADER_CONFIG_H_MARGIN_SIZES_LARGE = {15, 15} DCREREADER_CONFIG_H_MARGIN_SIZES_LARGE = {15, 15},
DCREREADER_CONFIG_H_MARGIN_SIZES_X_LARGE = {20, 20} DCREREADER_CONFIG_H_MARGIN_SIZES_X_LARGE = {20, 20},
DCREREADER_CONFIG_H_MARGIN_SIZES_XX_LARGE = {30, 30} DCREREADER_CONFIG_H_MARGIN_SIZES_XX_LARGE = {30, 30},
DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE = {50, 50} DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE = {50, 50},
DCREREADER_CONFIG_H_MARGIN_SIZES_HUGE = {70, 70} DCREREADER_CONFIG_H_MARGIN_SIZES_HUGE = {70, 70},
DCREREADER_CONFIG_H_MARGIN_SIZES_X_HUGE = {100, 100} DCREREADER_CONFIG_H_MARGIN_SIZES_X_HUGE = {100, 100},
DCREREADER_CONFIG_H_MARGIN_SIZES_XX_HUGE = {140, 140} DCREREADER_CONFIG_H_MARGIN_SIZES_XX_HUGE = {140, 140},
-- top margin in (relative) pixels -- top margin in (relative) pixels
DCREREADER_CONFIG_T_MARGIN_SIZES_SMALL = 5 DCREREADER_CONFIG_T_MARGIN_SIZES_SMALL = 5,
DCREREADER_CONFIG_T_MARGIN_SIZES_MEDIUM = 10 DCREREADER_CONFIG_T_MARGIN_SIZES_MEDIUM = 10,
DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE = 15 DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE = 15,
DCREREADER_CONFIG_T_MARGIN_SIZES_X_LARGE = 20 DCREREADER_CONFIG_T_MARGIN_SIZES_X_LARGE = 20,
DCREREADER_CONFIG_T_MARGIN_SIZES_XX_LARGE = 30 DCREREADER_CONFIG_T_MARGIN_SIZES_XX_LARGE = 30,
DCREREADER_CONFIG_T_MARGIN_SIZES_XXX_LARGE = 50 DCREREADER_CONFIG_T_MARGIN_SIZES_XXX_LARGE = 50,
DCREREADER_CONFIG_T_MARGIN_SIZES_HUGE = 70 DCREREADER_CONFIG_T_MARGIN_SIZES_HUGE = 70,
DCREREADER_CONFIG_T_MARGIN_SIZES_X_HUGE = 100 DCREREADER_CONFIG_T_MARGIN_SIZES_X_HUGE = 100,
DCREREADER_CONFIG_T_MARGIN_SIZES_XX_HUGE = 140 DCREREADER_CONFIG_T_MARGIN_SIZES_XX_HUGE = 140,
-- bottom margin in (relative) pixels -- bottom margin in (relative) pixels
DCREREADER_CONFIG_B_MARGIN_SIZES_SMALL = 5 DCREREADER_CONFIG_B_MARGIN_SIZES_SMALL = 5,
DCREREADER_CONFIG_B_MARGIN_SIZES_MEDIUM = 10 DCREREADER_CONFIG_B_MARGIN_SIZES_MEDIUM = 10,
DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE = 15 DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE = 15,
DCREREADER_CONFIG_B_MARGIN_SIZES_X_LARGE = 20 DCREREADER_CONFIG_B_MARGIN_SIZES_X_LARGE = 20,
DCREREADER_CONFIG_B_MARGIN_SIZES_XX_LARGE = 30 DCREREADER_CONFIG_B_MARGIN_SIZES_XX_LARGE = 30,
DCREREADER_CONFIG_B_MARGIN_SIZES_XXX_LARGE = 50 DCREREADER_CONFIG_B_MARGIN_SIZES_XXX_LARGE = 50,
DCREREADER_CONFIG_B_MARGIN_SIZES_HUGE = 70 DCREREADER_CONFIG_B_MARGIN_SIZES_HUGE = 70,
DCREREADER_CONFIG_B_MARGIN_SIZES_X_HUGE = 100 DCREREADER_CONFIG_B_MARGIN_SIZES_X_HUGE = 100,
DCREREADER_CONFIG_B_MARGIN_SIZES_XX_HUGE = 140 DCREREADER_CONFIG_B_MARGIN_SIZES_XX_HUGE = 140,
-- crereader font gamma (no longer used)
-- DCREREADER_CONFIG_LIGHTER_FONT_GAMMA = 10
-- DCREREADER_CONFIG_DEFAULT_FONT_GAMMA = 15
-- DCREREADER_CONFIG_DARKER_FONT_GAMMA = 25
-- crereader line space percentage -- crereader line space percentage
DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_TINY = 70 DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_TINY = 70,
DCREREADER_CONFIG_LINE_SPACE_PERCENT_TINY = 75 DCREREADER_CONFIG_LINE_SPACE_PERCENT_TINY = 75,
DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_SMALL = 80 DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_SMALL = 80,
DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_SMALL = 85 DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_SMALL = 85,
DCREREADER_CONFIG_LINE_SPACE_PERCENT_SMALL = 90 DCREREADER_CONFIG_LINE_SPACE_PERCENT_SMALL = 90,
DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_SMALL = 95 DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_SMALL = 95,
DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM = 100 DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM = 100,
DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_MEDIUM = 105 DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_MEDIUM = 105,
DCREREADER_CONFIG_LINE_SPACE_PERCENT_XL_MEDIUM = 110 DCREREADER_CONFIG_LINE_SPACE_PERCENT_XL_MEDIUM = 110,
DCREREADER_CONFIG_LINE_SPACE_PERCENT_XXL_MEDIUM = 115 DCREREADER_CONFIG_LINE_SPACE_PERCENT_XXL_MEDIUM = 115,
DCREREADER_CONFIG_LINE_SPACE_PERCENT_LARGE = 120 DCREREADER_CONFIG_LINE_SPACE_PERCENT_LARGE = 120,
DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_LARGE = 125 DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_LARGE = 125,
DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_LARGE = 130 DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_LARGE = 130,
-- word spacing percentages -- word spacing percentages
-- 1st number scales the normal width of spaces in all font -- 1st number scales the normal width of spaces in all font
@ -182,138 +160,44 @@ DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_LARGE = 130
-- regular width. {99, 100} allows reducing it by at least 1px. -- regular width. {99, 100} allows reducing it by at least 1px.
-- (These replace the old settings DCREREADER_CONFIG_WORD_GAP_*, -- (These replace the old settings DCREREADER_CONFIG_WORD_GAP_*,
-- with the equivalence: new_option = { 100, old_option }.) -- with the equivalence: new_option = { 100, old_option }.)
DCREREADER_CONFIG_WORD_SPACING_SMALL = {75, 50} DCREREADER_CONFIG_WORD_SPACING_SMALL = {75, 50},
DCREREADER_CONFIG_WORD_SPACING_MEDIUM = {95, 75} DCREREADER_CONFIG_WORD_SPACING_MEDIUM = {95, 75},
DCREREADER_CONFIG_WORD_SPACING_LARGE = {100, 90} DCREREADER_CONFIG_WORD_SPACING_LARGE = {100, 90},
-- word expansion, to reduce excessive spacing on justified line -- word expansion, to reduce excessive spacing on justified line
-- by using letter spacing on the words -- by using letter spacing on the words
-- value is the max allowed added letter spacing, as a % of the font size -- value is the max allowed added letter spacing, as a % of the font size
DCREREADER_CONFIG_WORD_EXPANSION_NONE = 0 DCREREADER_CONFIG_WORD_EXPANSION_NONE = 0,
DCREREADER_CONFIG_WORD_EXPANSION_SOME = 5 DCREREADER_CONFIG_WORD_EXPANSION_SOME = 5,
DCREREADER_CONFIG_WORD_EXPANSION_MORE = 15 DCREREADER_CONFIG_WORD_EXPANSION_MORE = 15,
-- crereader progress bar (no longer needed)
-- 0 for top "full" progress bar
-- 1 for bottom "mini" progress bar
--DCREREADER_PROGRESS_BAR = 1
-- configure "mini" progress bar -- configure "mini" progress bar
-- no longer needed DMINIBAR_CONTAINER_HEIGHT = 14, -- Larger means more padding at the bottom, at the risk of eating into the last line
--DMINIBAR_TOC_MARKER_WIDTH = 2 -- Looses usefulness > 3
DMINIBAR_CONTAINER_HEIGHT = 14 -- Larger means more padding at the bottom, at the risk of eating into the last line
-- no longer needed
--DMINIBAR_FONT_SIZE = 14
-- no longer needed
--DMINIBAR_HEIGHT = 7 -- Should be smaller than DMINIBAR_CONTAINER_HEIGHT
-- change this to any numerical value if you want to automatically save settings when turning pages
-- no longer needed (now available in menu as an interval in minutes)
-- DAUTO_SAVE_PAGING_COUNT = nil
-- dictionary font size
-- no longer needed
--DDICT_FONT_SIZE = 20
-- Normally, KOReader will present file lists sorted in case insensitive manner -- Normally, KOReader will present file lists sorted in case insensitive manner
-- when presenting an alphatically sorted list. So the Order is "A, b, C, d". -- when presenting an alphatically sorted list. So the Order is "A, b, C, d".
-- You can switch to a case sensitive sort ("A", "C", "b", "d") by disabling -- You can switch to a case sensitive sort ("A", "C", "b", "d") by disabling
-- insensitive sort -- insensitive sort
DALPHA_SORT_CASE_INSENSITIVE = true DALPHA_SORT_CASE_INSENSITIVE = true,
-- no longer needed
-- Set a path to a folder that is filled by Calibre (must contain the file metadata.calibre)
-- e.g.
-- "/mnt/sd/.hidden" for Kobo with files in ".hidden" on the SD card
-- "/mnt/onboard/MyPath" for Kobo with files in "MyPath" on the device itself
-- "/mnt/us/documents/" for Kindle files in folder "documents"
--SEARCH_LIBRARY_PATH = ""
--SEARCH_LIBRARY_PATH2 = ""
--
-- Search parameters
--SEARCH_CASESENSITIVE = false
--
--SEARCH_AUTHORS = true
--SEARCH_TITLE = true
--SEARCH_TAGS = true
--SEARCH_SERIES = true
--SEARCH_PATH = true
-- Light parameter for Kobo -- Light parameter for Kobo
KOBO_LIGHT_ON_START = -2 -- -1, -2 or 0-100. KOBO_LIGHT_ON_START = -2, -- -1, -2 or 0-100.
-- -1 uses previous koreader session saved brightness -- -1 uses previous koreader session saved brightness
-- -2 uses 'Kobo eReader.conf' brighness, -- -2 uses 'Kobo eReader.conf' brighness,
-- other sets light on start to a fix brighness -- other sets light on start to a fix brighness
KOBO_SYNC_BRIGHTNESS_WITH_NICKEL = true -- Save brightness set in KOreader KOBO_SYNC_BRIGHTNESS_WITH_NICKEL = true, -- Save brightness set in KOreader
-- with nickel's 'Kobo eReader.conf' -- with nickel's 'Kobo eReader.conf'
-- Network proxy settings -- Network proxy settings
-- proxy url should be a string in the format of "http://localhost:3128" -- proxy url should be a string in the format of "http://localhost:3128"
-- proxy authentication is not supported yet. -- proxy authentication is not supported yet.
NETWORK_PROXY = nil NETWORK_PROXY = nil,
-- Experimental features -- Experimental features
-- Use turbo library to handle async HTTP request -- Use turbo library to handle async HTTP request
DUSE_TURBO_LIB = false DUSE_TURBO_LIB = false,
-- Absolute path to stardict files (override) -- Absolute path to stardict files (override)
-- By default they're stored in data/dict under dataDir. -- By default they're stored in data/dict under dataDir.
STARDICT_DATA_DIR = nil STARDICT_DATA_DIR = nil,
}
-- ####################################################################
-- following features are not supported right now
-- ####################################################################
-- set panning distance
--DSHIFT_X = 100
--DSHIFT_Y = 50
-- step to change zoom manually, default = 16%
--DSTEP_MANUAL_ZOOM = 16
--DPAN_BY_PAGE = false -- using shift_[xy] or width/height
--DPAN_MARGIN = 5 -- horizontal margin for two-column zoom (in pixels)
--DPAN_OVERLAP_VERTICAL = 30
-- tile cache configuration:
--DCACHE_MAX_MEMSIZE = 1024*1024*5 -- 5MB tile cache
--DCACHE_MAX_TTL = 20 -- time to live
-- renderer cache size
--DCACHE_DOCUMENT_SIZE = 1024*1024*8 -- FIXME random, needs testing
-- default value for battery level logging
--DBATTERY_LOGGING = false
-- delay for info messages in ms
--DINFO_NODELAY=0
--DINFO_DELAY=1500
-- toggle defaults
--DUNIREADER_SHOW_OVERLAP_ENABLE = true
--DUNIREADER_SHOW_LINKS_ENABLE = true
--DUNIREADER_COMICS_MODE_ENABLE = true
--DUNIREADER_RTL_MODE_ENABLE = false
--DUNIREADER_PAGE_MODE_ENABLE = false
--DDJVUREADER_SHOW_OVERLAP_ENABLE = true
--DDJVUREADER_SHOW_LINKS_ENABLE = false
--DDJVUREADER_COMICS_MODE_ENABLE = true
--DDJVUREADER_RTL_MODE_ENABLE = false
--DDJVUREADER_PAGE_MODE_ENABLE = false
--DKOPTREADER_SHOW_OVERLAP_ENABLE = true
--DKOPTREADER_SHOW_LINKS_ENABLE = false
--DKOPTREADER_COMICS_MODE_ENABLE = false
--DKOPTREADER_RTL_MODE_ENABLE = false
--DKOPTREADER_PAGE_MODE_ENABLE = false
--DPICVIEWER_SHOW_OVERLAP_ENABLE = false
--DPICVIEWER_SHOW_LINKS_ENABLE = false
--DPICVIEWER_COMICS_MODE_ENABLE = true
--DPICVIEWER_RTL_MODE_ENABLE = false
--DPICVIEWER_PAGE_MODE_ENABLE = false
--DKOPTREADER_CONFIG_MULTI_THREADS = 1 -- 1 = on, 0 = off
--DKOPTREADER_CONFIG_SCREEN_ROTATION = 0 -- 0, 90, 180, 270 degrees

@ -120,7 +120,7 @@ function FileManager:setupLayout()
right_icon_hold_callback = false, -- propagate long-press to dispatcher right_icon_hold_callback = false, -- propagate long-press to dispatcher
} }
local show_hidden = G_reader_settings:isTrue("show_hidden") or DSHOWHIDDENFILES local show_hidden = G_reader_settings:isTrue("show_hidden") or G_defaults:readSetting("DSHOWHIDDENFILES")
local show_unsupported = G_reader_settings:isTrue("show_unsupported") local show_unsupported = G_reader_settings:isTrue("show_unsupported")
local file_chooser = FileChooser:new{ local file_chooser = FileChooser:new{
-- remember to adjust the height when new item is added to the group -- remember to adjust the height when new item is added to the group

@ -55,6 +55,9 @@ end
function FileConverter:_mdFileToHtml(file, title) function FileConverter:_mdFileToHtml(file, title)
local f = io.open(file, "rb") local f = io.open(file, "rb")
if f == nil then
return
end
local content = f:read("*all") local content = f:read("*all")
f:close() f:close()
local html = self:mdToHtml(content, title) local html = self:mdToHtml(content, title)
@ -63,6 +66,9 @@ end
function FileConverter:writeStringToFile(content, file) function FileConverter:writeStringToFile(content, file)
local f = io.open(file, "w") local f = io.open(file, "w")
if f == nil then
return
end
f:write(content) f:write(content)
f:close() f:close()
end end
@ -104,7 +110,20 @@ function FileConverter:showConvertButtons(file, ui)
}, },
}, },
} }
self.convert_dialog.onCloseWidget = function(this)
local super = getmetatable(this)
if super.onCloseWidget then
-- Call our super's method, if any
super.onCloseWidget(this)
end
-- And then do our own cleanup
self:cleanup()
end
UIManager:show(self.convert_dialog) UIManager:show(self.convert_dialog)
end end
function FileConverter:cleanup()
self.convert_dialog = nil
end
return FileConverter return FileConverter

@ -9,6 +9,7 @@ local Menu = require("ui/widget/menu")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local Screen = require("device").screen local Screen = require("device").screen
local filemanagerutil = require("apps/filemanager/filemanagerutil") local filemanagerutil = require("apps/filemanager/filemanagerutil")
local lfs = require("libs/libkoreader-lfs")
local _ = require("gettext") local _ = require("gettext")
local C_ = _.pgettext local C_ = _.pgettext
local T = FFIUtil.template local T = FFIUtil.template

@ -62,6 +62,8 @@ end
function FileManagerMenu:initGesListener() function FileManagerMenu:initGesListener()
if not Device:isTouchDevice() then return end if not Device:isTouchDevice() then return end
local DTAP_ZONE_MENU = G_defaults:readSetting("DTAP_ZONE_MENU")
local DTAP_ZONE_MENU_EXT = G_defaults:readSetting("DTAP_ZONE_MENU_EXT")
self:registerTouchZones({ self:registerTouchZones({
{ {
id = "filemanager_tap", id = "filemanager_tap",
@ -422,9 +424,6 @@ To:
callback = function() callback = function()
SetDefaults:ConfirmEdit() SetDefaults:ConfirmEdit()
end, end,
hold_callback = function()
SetDefaults:ConfirmSave()
end,
} }
self.menu_items.plugin_management = { self.menu_items.plugin_management = {
text = _("Plugin management"), text = _("Plugin management"),

@ -1,373 +1,289 @@
local CenterContainer = require("ui/widget/container/centercontainer") local CenterContainer = require("ui/widget/container/centercontainer")
local ConfirmBox = require("ui/widget/confirmbox") local ConfirmBox = require("ui/widget/confirmbox")
local DataStorage = require("datastorage")
local Device = require("device") local Device = require("device")
local InfoMessage = require("ui/widget/infomessage") local InfoMessage = require("ui/widget/infomessage")
local InputContainer = require("ui/widget/container/inputcontainer")
local InputDialog = require("ui/widget/inputdialog") local InputDialog = require("ui/widget/inputdialog")
local Menu = require("ui/widget/menu") local Menu = require("ui/widget/menu")
local MultiInputDialog = require("ui/widget/multiinputdialog") local MultiInputDialog = require("ui/widget/multiinputdialog")
local Size = require("ui/size") local Size = require("ui/size")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local dump = require("dump")
local isAndroid, android = pcall(require, "android")
local logger = require("logger") local logger = require("logger")
local util = require("ffi/util") local ffiUtil = require("ffi/util")
local util = require("util")
local _ = require("gettext") local _ = require("gettext")
local Screen = require("device").screen local Screen = require("device").screen
local is_appimage = os.getenv("APPIMAGE") local SetDefaultsWidget = CenterContainer:extend{
state = nil,
local function getDefaultsPath() menu_entries = nil,
local defaults_path = DataStorage:getDataDir() .. "/defaults.lua" defaults_menu = nil,
if isAndroid then
defaults_path = android.dir .. "/defaults.lua"
elseif is_appimage then
defaults_path = "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 = {},
changed = {},
settings_changed = false, settings_changed = false,
} }
function SetDefaults:ConfirmEdit() function SetDefaultsWidget:init()
if not SetDefaults.EditConfirmed then -- We're a CenterContainer, so handle our own stuff first
UIManager:show(ConfirmBox:new{ self.dimen = Screen:getSize()
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?"), -- Don't refresh the FM behind us. May leave stray bits of overflowed InputDialog behind in the popout border space.
ok_callback = function() self.covers_fullscreen = true
self.EditConfirmed = true CenterContainer.init(self)
self:init()
end,
})
else
self:init()
end
end
function SetDefaults:init() -- Then deal with our child widgets and our internal variables
self.screen_width = Screen:getWidth() self.screen_width = Screen:getWidth()
self.screen_height = Screen:getHeight() self.screen_height = Screen:getHeight()
self.dialog_width = math.floor(math.min(self.screen_width, self.screen_height) * 0.95) self.dialog_width = math.floor(math.min(self.screen_width, self.screen_height) * 0.95)
self.results = {} -- Keep track of what's an actual default, and what's been customized without actually touching the real data yet...
self.state = {}
local defaults = {} local ro_defaults, rw_defaults = G_defaults:getDataTables()
local load_defaults = loadfile(defaults_path) for k, v in pairs(ro_defaults) do
setfenv(load_defaults, defaults) self.state[k] = {
load_defaults() idx = 1,
value = v,
local file = io.open(persistent_defaults_path, "r") custom = false,
if file ~= nil then dirty = false,
file:close() default_value = v,
load_defaults = loadfile(persistent_defaults_path) }
setfenv(load_defaults, defaults)
load_defaults()
end end
for k, v in pairs(rw_defaults) do
local idx = 1 self.state[k].value = v
for n, v in util.orderedPairs(defaults) do self.state[k].custom = true
self.defaults_name[idx] = n
self.defaults_value[idx] = v
idx = idx + 1
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, "ui")
end
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 = menu_container,
_manager = self,
}
-- Prevent menu from closing when editing a value
function self.defaults_menu:onMenuSelect(item)
item.callback()
end end
table.insert(menu_container, self.defaults_menu) -- Prepare our menu entires
self.defaults_menu.close_callback = function() self.menu_entries = {}
logger.dbg("Closing defaults menu")
self:saveBeforeExit()
UIManager:close(menu_container)
end
local set_dialog
local cancel_button = { local cancel_button = {
text = _("Cancel"), text = _("Cancel"),
id = "close", id = "close",
enabled = true, enabled = true,
callback = function() callback = function()
self:close() UIManager:close(set_dialog)
end, end,
} }
for i=1, #self.defaults_name do local i = 0
self.changed[i] = false for k, t in ffiUtil.orderedPairs(self.state) do
local setting_name = self.defaults_name[i] local v = t.value
local setting_type = type(_G[setting_name]) i = i + 1
if setting_type == "boolean" then self.state[k].idx = i
local value_type = type(v)
if value_type == "boolean" then
local editBoolean = function() local editBoolean = function()
self.set_dialog = InputDialog:new{ set_dialog = InputDialog:new{
title = setting_name, title = k,
input = tostring(self.defaults_value[i]), input = tostring(self.state[k].value),
buttons = { buttons = {
{ {
cancel_button, 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", text = "true",
enabled = true, enabled = true,
callback = function() callback = function()
self.defaults_value[i] = true UIManager:close(set_dialog)
_G[setting_name] = true self:update_menu_entry(k, true, value_type)
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)
end end
}, },
{ {
text = "false", text = "false",
enabled = true, enabled = true,
callback = function() callback = function()
self.defaults_value[i] = false UIManager:close(set_dialog)
_G[setting_name] = false self:update_menu_entry(k, false, value_type)
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()
end end
}, },
}, },
}, },
input_type = setting_type, input_type = value_type,
width = self.dialog_width, width = self.dialog_width,
} }
UIManager:show(self.set_dialog) UIManager:show(set_dialog)
self.set_dialog:onShowKeyboard() set_dialog:onShowKeyboard()
end end
table.insert(self.results, { table.insert(self.menu_entries, {
text = self:build_setting(i), text = self:gen_menu_entry(k, self.state[k].value, value_type),
bold = self.state[k].custom,
callback = editBoolean callback = editBoolean
}) })
elseif setting_type == "table" then elseif value_type == "table" then
local editTable = function() local editTable = function()
local fields = {} local fields = {}
for k, v in util.orderedPairs(_G[setting_name]) do for key, value in ffiUtil.orderedPairs(self.state[k].value) do
table.insert(fields, { table.insert(fields, {
text = tostring(k) .. " = " .. tostring(v), text = tostring(key) .. " = " .. tostring(value),
input_type = type(value),
hint = "", hint = "",
padding = Screen:scaleBySize(2), padding = Screen:scaleBySize(2),
margin = Screen:scaleBySize(2), margin = Screen:scaleBySize(2),
}) })
end end
self.set_dialog = MultiInputDialog:new{ set_dialog = MultiInputDialog:new{
title = setting_name, title = k,
fields = fields, fields = fields,
buttons = { buttons = {
{ {
cancel_button, 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"), text = _("OK"),
enabled = true, enabled = true,
is_enter_default = true, is_enter_default = true,
callback = function() callback = function()
UIManager:close(set_dialog)
local new_table = {} local new_table = {}
for _, field in ipairs(MultiInputDialog:getFields()) do for _, field in ipairs(MultiInputDialog:getFields()) do
local key, value = field:match("^[^= ]+"), field:match("[^= ]+$") local key, value = field:match("^[^= ]+"), field:match("[^= ]+$")
new_table[tonumber(key) or key] = tonumber(value) or value new_table[tonumber(key) or key] = tonumber(value) or value
end end
_G[setting_name] = new_table self:update_menu_entry(k, new_table, value_type)
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)
end, end,
}, },
}, },
}, },
width = self.dialog_width, width = self.dialog_width,
} }
UIManager:show(self.set_dialog) UIManager:show(set_dialog)
self.set_dialog:onShowKeyboard() set_dialog:onShowKeyboard()
end end
table.insert(self.results, { table.insert(self.menu_entries, {
text = self:build_setting(i), text = self:gen_menu_entry(k, self.state[k].value, value_type),
bold = self.state[k].custom,
callback = editTable callback = editTable
}) })
else else
local editNumStr = function() local editNumStr = function()
self.set_dialog = InputDialog:new{ set_dialog = InputDialog:new{
title = setting_name, title = k,
input = tostring(self.defaults_value[i]), input = tostring(self.state[k].value),
buttons = { buttons = {
{ {
cancel_button, 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"), text = _("OK"),
is_enter_default = true, is_enter_default = true,
enabled = true, enabled = true,
callback = function() callback = function()
local new_value = self.set_dialog:getInputValue() UIManager:close(set_dialog)
if _G[setting_name] ~= new_value then local new_value = set_dialog:getInputValue()
_G[setting_name] = new_value self:update_menu_entry(k, new_value, value_type)
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)
end, end,
}, },
}, },
}, },
input_type = setting_type, input_type = value_type,
width = self.dialog_width, width = self.dialog_width,
} }
UIManager:show(self.set_dialog) UIManager:show(set_dialog)
self.set_dialog:onShowKeyboard() set_dialog:onShowKeyboard()
end end
table.insert(self.results, { table.insert(self.menu_entries, {
text = self:build_setting(i), text = self:gen_menu_entry(k, self.state[k].value, value_type),
bold = self.state[k].custom,
callback = editNumStr callback = editNumStr
}) })
end end
end end
self.defaults_menu:switchItemTable("Defaults", self.results)
UIManager:show(menu_container)
end
function SetDefaults:close() -- Now that we have stuff to display, instantiate our Menu
UIManager:close(self.set_dialog) self.defaults_menu = Menu:new{
end 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
function SetDefaults:ConfirmSave() table.insert(self, self.defaults_menu)
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 end
function SetDefaults:build_setting(j) function SetDefaultsWidget:gen_menu_entry(k, v, v_type)
local setting_name = self.defaults_name[j] local ret = k .. " = "
local ret = setting_name .. " = " if v_type == "boolean" then
if type(_G[setting_name]) == "boolean" then return ret .. tostring(v)
return ret .. tostring(self.defaults_value[j]) elseif v_type == "table" then
elseif type(_G[setting_name]) == "table" then
return ret .. "{...}" return ret .. "{...}"
elseif tonumber(self.defaults_value[j]) then elseif tonumber(v) then
return ret .. tostring(tonumber(self.defaults_value[j])) return ret .. tostring(tonumber(v))
else else
return ret .. "\"" .. tostring(self.defaults_value[j]) .. "\"" return ret .. "\"" .. tostring(v) .. "\""
end end
end end
function SetDefaults:saveSettings() function SetDefaultsWidget:update_menu_entry(k, v, v_type)
self.results = {} local idx = self.state[k].idx
local persisted_defaults = {} self.state[k].value = v
local file = io.open(persistent_defaults_path, "r") self.state[k].dirty = true
if file ~= nil then self.settings_changed = true
file:close() self.menu_entries[idx].text = self:gen_menu_entry(k, v, v_type)
local load_defaults = loadfile(persistent_defaults_path) if util.tableEquals(v, self.state[k].default_value) then
setfenv(load_defaults, persisted_defaults) self.menu_entries[idx].bold = false
load_defaults() else
end self.menu_entries[idx].bold = true
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 end
self.defaults_menu:switchItemTable(nil, self.menu_entries, idx)
end
-- handle case "not in persistent and different in non-persistent", add to function SetDefaultsWidget:saveSettings()
-- persistent -- Update dirty keys for real
for j=1, #self.defaults_name do for k, t in pairs(self.state) do
if not checked[j] then if t.dirty then
persisted_defaults[self.defaults_name[j]] = self.defaults_value[j] G_defaults:saveSetting(k, t.value)
end end
end end
file = io.open(persistent_defaults_path, "w") -- And flush to disk
if file then G_defaults:flush()
file:write("-- For configuration changes that persists between updates\n") UIManager:show(InfoMessage:new{
for k, v in pairs(persisted_defaults) do text = _("Default settings saved."),
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 end
function SetDefaults:saveBeforeExit(callback) function SetDefaultsWidget:saveBeforeExit(callback)
local save_text = _("Save and quit") local save_text = _("Save and quit")
if Device:canRestart() then if Device:canRestart() then
save_text = _("Save and restart") save_text = _("Save and restart")
end end
if self.settings_changed then if self.settings_changed then
UIManager:show(ConfirmBox:new{ UIManager:show(ConfirmBox:new{
dismissable = false,
text = _("KOReader needs to be restarted to apply the new default settings."), text = _("KOReader needs to be restarted to apply the new default settings."),
ok_text = save_text, ok_text = save_text,
ok_callback = function() ok_callback = function()
self.settings_changed = false
self:saveSettings() self:saveSettings()
if Device:canRestart() then if Device:canRestart() then
UIManager:restartKOReader() UIManager:restartKOReader()
@ -378,12 +294,25 @@ function SetDefaults:saveBeforeExit(callback)
cancel_text = _("Discard changes"), cancel_text = _("Discard changes"),
cancel_callback = function() cancel_callback = function()
logger.info("discard defaults") logger.info("discard defaults")
pcall(dofile, defaults_path)
pcall(dofile, persistent_defaults_path)
self.settings_changed = false
end, end,
}) })
end 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 return SetDefaults

@ -36,7 +36,8 @@ ReaderActivityIndicator = EventListener:new{}
function ReaderActivityIndicator:isStub() return false end function ReaderActivityIndicator:isStub() return false end
function ReaderActivityIndicator:init() function ReaderActivityIndicator:init()
if (pcall(require, "liblipclua")) then local haslipc, lipc = pcall(require, "liblipclua")
if haslipc then
self.lipc_handle = lipc.init("com.github.koreader.activityindicator") self.lipc_handle = lipc.init("com.github.koreader.activityindicator")
end end
end end

@ -35,6 +35,10 @@ function ReaderConfig:init()
end end
function ReaderConfig:initGesListener() function ReaderConfig:initGesListener()
if not Device:isTouchDevice() then return end
local DTAP_ZONE_CONFIG = G_defaults:readSetting("DTAP_ZONE_CONFIG")
local DTAP_ZONE_CONFIG_EXT = G_defaults:readSetting("DTAP_ZONE_CONFIG_EXT")
self.ui:registerTouchZones({ self.ui:registerTouchZones({
{ {
id = "readerconfigmenu_tap", id = "readerconfigmenu_tap",

@ -19,6 +19,7 @@ local UIManager = require("ui/uimanager")
local ffi = require("ffi") local ffi = require("ffi")
local C = ffi.C local C = ffi.C
local ffiUtil = require("ffi/util") local ffiUtil = require("ffi/util")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
local time = require("ui/time") local time = require("ui/time")
local util = require("util") local util = require("util")
@ -106,7 +107,7 @@ function ReaderDictionary:init()
if self.ui then if self.ui then
self.ui.menu:registerToMainMenu(self) self.ui.menu:registerToMainMenu(self)
end end
self.data_dir = STARDICT_DATA_DIR or self.data_dir = G_defaults:readSetting("STARDICT_DATA_DIR") or
os.getenv("STARDICT_DATA_DIR") or os.getenv("STARDICT_DATA_DIR") or
DataStorage:getDataDir() .. "/data/dict" DataStorage:getDataDir() .. "/data/dict"
@ -1051,7 +1052,6 @@ function ReaderDictionary:downloadDictionaryPrep(dict, size)
local dummy, filename = util.splitFilePathName(dict.url) local dummy, filename = util.splitFilePathName(dict.url)
local download_location = string.format("%s/%s", self.data_dir, filename) local download_location = string.format("%s/%s", self.data_dir, filename)
local lfs = require("libs/libkoreader-lfs")
if lfs.attributes(download_location) then if lfs.attributes(download_location) then
UIManager:show(ConfirmBox:new{ UIManager:show(ConfirmBox:new{
text = _("File already exists. Overwrite?"), text = _("File already exists. Overwrite?"),

@ -58,13 +58,13 @@ function ReaderDogear:onReadSettings(config)
-- Adjust to CreDocument margins (as done in ReaderTypeset) -- Adjust to CreDocument margins (as done in ReaderTypeset)
local h_margins = config:readSetting("copt_h_page_margins") local h_margins = config:readSetting("copt_h_page_margins")
or G_reader_settings:readSetting("copt_h_page_margins") or G_reader_settings:readSetting("copt_h_page_margins")
or DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM or G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM")
local t_margin = config:readSetting("copt_t_page_margin") local t_margin = config:readSetting("copt_t_page_margin")
or G_reader_settings:readSetting("copt_t_page_margin") or G_reader_settings:readSetting("copt_t_page_margin")
or DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE or G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE")
local b_margin = config:readSetting("copt_b_page_margin") local b_margin = config:readSetting("copt_b_page_margin")
or G_reader_settings:readSetting("copt_b_page_margin") or G_reader_settings:readSetting("copt_b_page_margin")
or DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE or G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE")
local margins = { h_margins[1], t_margin, h_margins[2], b_margin } local margins = { h_margins[1], t_margin, h_margins[2], b_margin }
self:onSetPageMargins(margins) self:onSetPageMargins(margins)
end end

@ -12,6 +12,7 @@ local MultiConfirmBox = require("ui/widget/multiconfirmbox")
local Notification = require("ui/widget/notification") local Notification = require("ui/widget/notification")
local Screen = require("device").screen local Screen = require("device").screen
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local cre -- Delayed loading
local T = require("ffi/util").template local T = require("ffi/util").template
local _ = require("gettext") local _ = require("gettext")
local C_ = _.pgettext local C_ = _.pgettext
@ -52,8 +53,9 @@ function ReaderFont:init()
separator = true, separator = true,
}) })
-- Font list -- Font list
cre = require("document/credocument"):engineInit()
local face_list = cre.getFontFaces() local face_list = cre.getFontFaces()
for k,v in ipairs(face_list) do for k, v in ipairs(face_list) do
local font_filename, font_faceindex, is_monospace = cre.getFontFaceFilenameAndFaceIndex(v) local font_filename, font_faceindex, is_monospace = cre.getFontFaceFilenameAndFaceIndex(v)
table.insert(self.face_table, { table.insert(self.face_table, {
text_func = function() text_func = function()
@ -121,7 +123,7 @@ function ReaderFont:onReadSettings(config)
self.font_size = config:readSetting("font_size") self.font_size = config:readSetting("font_size")
or G_reader_settings:readSetting("copt_font_size") or G_reader_settings:readSetting("copt_font_size")
or DCREREADER_CONFIG_DEFAULT_FONT_SIZE or G_defaults:readSetting("DCREREADER_CONFIG_DEFAULT_FONT_SIZE")
or 22 or 22
self.ui.document:setFontSize(Screen:scaleBySize(self.font_size)) self.ui.document:setFontSize(Screen:scaleBySize(self.font_size))
@ -157,12 +159,11 @@ function ReaderFont:onReadSettings(config)
self.line_space_percent = config:readSetting("line_space_percent") self.line_space_percent = config:readSetting("line_space_percent")
or G_reader_settings:readSetting("copt_line_spacing") or G_reader_settings:readSetting("copt_line_spacing")
or DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM or G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM")
self.ui.document:setInterlineSpacePercent(self.line_space_percent) self.ui.document:setInterlineSpacePercent(self.line_space_percent)
self.gamma_index = config:readSetting("gamma_index") self.gamma_index = config:readSetting("gamma_index")
or G_reader_settings:readSetting("copt_font_gamma") or G_reader_settings:readSetting("copt_font_gamma")
or DCREREADER_CONFIG_DEFAULT_FONT_GAMMA
or 15 -- gamma = 1.0 or 15 -- gamma = 1.0
self.ui.document:setGammaIndex(self.gamma_index) self.ui.document:setGammaIndex(self.gamma_index)

@ -441,7 +441,7 @@ local ReaderFooter = WidgetContainer:extend{
progress_percentage = 0.0, progress_percentage = 0.0,
footer_text = nil, footer_text = nil,
text_font_face = "ffont", text_font_face = "ffont",
height = Screen:scaleBySize(DMINIBAR_CONTAINER_HEIGHT), height = Screen:scaleBySize(G_defaults:readSetting("DMINIBAR_CONTAINER_HEIGHT")),
horizontal_margin = Size.span.horizontal_default, horizontal_margin = Size.span.horizontal_default,
bottom_padding = Size.padding.tiny, bottom_padding = Size.padding.tiny,
settings = {}, settings = {},
@ -477,7 +477,7 @@ ReaderFooter.default_settings = {
toc_markers_width = 2, -- unscaled_size_check: ignore toc_markers_width = 2, -- unscaled_size_check: ignore
text_font_size = 14, -- unscaled_size_check: ignore text_font_size = 14, -- unscaled_size_check: ignore
text_font_bold = false, text_font_bold = false,
container_height = DMINIBAR_CONTAINER_HEIGHT, container_height = G_defaults:readSetting("DMINIBAR_CONTAINER_HEIGHT"),
container_bottom_padding = 1, -- unscaled_size_check: ignore container_bottom_padding = 1, -- unscaled_size_check: ignore
progress_margin_width = Screen:scaleBySize(Device:isAndroid() and material_pixels or 10), -- default margin (like self.horizontal_margin) progress_margin_width = Screen:scaleBySize(Device:isAndroid() and material_pixels or 10), -- default margin (like self.horizontal_margin)
progress_bar_min_width_pct = 20, progress_bar_min_width_pct = 20,
@ -820,6 +820,7 @@ end
function ReaderFooter:setupTouchZones() function ReaderFooter:setupTouchZones()
if not Device:isTouchDevice() then return end if not Device:isTouchDevice() then return end
local DTAP_ZONE_MINIBAR = G_defaults:readSetting("DTAP_ZONE_MINIBAR")
local footer_screen_zone = { local footer_screen_zone = {
ratio_x = DTAP_ZONE_MINIBAR.x, ratio_y = DTAP_ZONE_MINIBAR.y, ratio_x = DTAP_ZONE_MINIBAR.x, ratio_y = DTAP_ZONE_MINIBAR.y,
ratio_w = DTAP_ZONE_MINIBAR.w, ratio_h = DTAP_ZONE_MINIBAR.h, ratio_w = DTAP_ZONE_MINIBAR.w, ratio_h = DTAP_ZONE_MINIBAR.h,
@ -996,12 +997,8 @@ function ReaderFooter:addToMainMenu(menu_items)
-- menu item to fake footer tapping when touch area is disabled -- menu item to fake footer tapping when touch area is disabled
local settings_submenu_num = 1 local settings_submenu_num = 1
if Geom:new{ local DTAP_ZONE_MINIBAR = G_defaults:readSetting("DTAP_ZONE_MINIBAR")
x = DTAP_ZONE_MINIBAR.x, if DTAP_ZONE_MINIBAR.h == 0 or DTAP_ZONE_MINIBAR.w == 0 then
y = DTAP_ZONE_MINIBAR.y,
w = DTAP_ZONE_MINIBAR.w,
h = DTAP_ZONE_MINIBAR.h
}:area() == 0 then
table.insert(sub_items, { table.insert(sub_items, {
text = _("Toggle mode"), text = _("Toggle mode"),
enabled_func = function() enabled_func = function()
@ -1250,7 +1247,7 @@ function ReaderFooter:addToMainMenu(menu_items)
value = container_height, value = container_height,
value_min = 7, value_min = 7,
value_max = 98, value_max = 98,
default_value = DMINIBAR_CONTAINER_HEIGHT, default_value = G_defaults:readSetting("DMINIBAR_CONTAINER_HEIGHT"),
ok_text = _("Set height"), ok_text = _("Set height"),
title_text = _("Container height"), title_text = _("Container height"),
keep_shown_on_apply = true, keep_shown_on_apply = true,
@ -2084,9 +2081,7 @@ function ReaderFooter:setTocMarkers(reset)
end end
-- This is implemented by the Statistics plugin -- This is implemented by the Statistics plugin
function ReaderFooter:getAvgTimePerPage() function ReaderFooter:getAvgTimePerPage() end
return
end
function ReaderFooter:getDataFromStatistics(title, pages) function ReaderFooter:getDataFromStatistics(title, pages)
local sec = _("N/A") local sec = _("N/A")
@ -2296,7 +2291,7 @@ function ReaderFooter:onReadSettings(config)
if not self.ui.document.info.has_pages then if not self.ui.document.info.has_pages then
local h_margins = config:readSetting("copt_h_page_margins") local h_margins = config:readSetting("copt_h_page_margins")
or G_reader_settings:readSetting("copt_h_page_margins") or G_reader_settings:readSetting("copt_h_page_margins")
or DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM or G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM")
self.book_margins_footer_width = math.floor((h_margins[1] + h_margins[2])/2) self.book_margins_footer_width = math.floor((h_margins[1] + h_margins[2])/2)
end end
end end

@ -1,5 +1,7 @@
local EventListener = require("ui/widget/eventlistener") local EventListener = require("ui/widget/eventlistener")
local DHINTCOUNT = G_defaults:readSetting("DHINTCOUNT")
local ReaderHinting = EventListener:new{ local ReaderHinting = EventListener:new{
hinting_states = {} hinting_states = {}
} }

@ -68,9 +68,9 @@ end
function ReaderKoptListener:onDocLangUpdate(lang) function ReaderKoptListener:onDocLangUpdate(lang)
if lang == "chi_sim" or lang == "chi_tra" or if lang == "chi_sim" or lang == "chi_tra" or
lang == "jpn" or lang == "kor" then lang == "jpn" or lang == "kor" then
self.document.configurable.word_spacing = DKOPTREADER_CONFIG_WORD_SPACINGS[1] self.document.configurable.word_spacing = G_defaults:readSetting("DKOPTREADER_CONFIG_WORD_SPACINGS")[1]
else else
self.document.configurable.word_spacing = DKOPTREADER_CONFIG_WORD_SPACINGS[3] self.document.configurable.word_spacing = G_defaults:readSetting("DKOPTREADER_CONFIG_WORD_SPACINGS")[3]
end end
end end

@ -14,6 +14,7 @@ local Notification = require("ui/widget/notification")
local QRMessage = require("ui/widget/qrmessage") local QRMessage = require("ui/widget/qrmessage")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local ffiutil = require("ffi/util") local ffiutil = require("ffi/util")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
local util = require("util") local util = require("util")
local _ = require("gettext") local _ = require("gettext")
@ -465,7 +466,7 @@ function ReaderLink:showLinkBox(link, allow_footnote_popup)
if sbox then if sbox then
UIManager:show(LinkBox:new{ UIManager:show(LinkBox:new{
box = sbox, box = sbox,
timeout = FOLLOW_LINK_TIMEOUT, timeout = G_defaults:readSetting("FOLLOW_LINK_TIMEOUT"),
callback = function() callback = function()
self:onGotoLink(link.link, false, allow_footnote_popup) self:onGotoLink(link.link, false, allow_footnote_popup)
end end

@ -88,6 +88,8 @@ function ReaderMenu:onReaderReady()
self.onGesture = nil self.onGesture = nil
if not Device:isTouchDevice() then return end if not Device:isTouchDevice() then return end
local DTAP_ZONE_MENU = G_defaults:readSetting("DTAP_ZONE_MENU")
local DTAP_ZONE_MENU_EXT = G_defaults:readSetting("DTAP_ZONE_MENU_EXT")
self.ui:registerTouchZones({ self.ui:registerTouchZones({
{ {
id = "readermenu_tap", id = "readermenu_tap",

@ -89,7 +89,7 @@ end
function ReaderPageMap:onReadSettings(config) function ReaderPageMap:onReadSettings(config)
local h_margins = config:readSetting("copt_h_page_margins") local h_margins = config:readSetting("copt_h_page_margins")
or G_reader_settings:readSetting("copt_h_page_margins") or G_reader_settings:readSetting("copt_h_page_margins")
or DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM or G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM")
self.max_left_label_width = Screen:scaleBySize(h_margins[1]) self.max_left_label_width = Screen:scaleBySize(h_margins[1])
self.max_right_label_width = Screen:scaleBySize(h_margins[2]) self.max_right_label_width = Screen:scaleBySize(h_margins[2])

@ -33,7 +33,7 @@ local ReaderPaging = InputContainer:new{
number_of_pages = 0, number_of_pages = 0,
visible_area = nil, visible_area = nil,
page_area = nil, page_area = nil,
overlap = Screen:scaleBySize(DOVERLAPPIXELS), overlap = Screen:scaleBySize(G_defaults:readSetting("DOVERLAPPIXELS")),
page_flipping_mode = false, page_flipping_mode = false,
bookmark_flipping_mode = false, bookmark_flipping_mode = false,

@ -9,6 +9,7 @@ local ReaderPanning = require("apps/reader/modules/readerpanning")
local Size = require("ui/size") local Size = require("ui/size")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local bit = require("bit") local bit = require("bit")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
local time = require("ui/time") local time = require("ui/time")
local _ = require("gettext") local _ = require("gettext")
@ -152,6 +153,7 @@ function ReaderRolling:onReadSettings(config)
self.ui.document:requestDomVersion(config:readSetting("cre_dom_version")) self.ui.document:requestDomVersion(config:readSetting("cre_dom_version"))
-- If we're using a DOM version without normalized XPointers, some stuff -- If we're using a DOM version without normalized XPointers, some stuff
-- may need tweaking: -- may need tweaking:
local cre = require("document/credocument"):engineInit()
if config:readSetting("cre_dom_version") < cre.getDomVersionWithNormalizedXPointers() then if config:readSetting("cre_dom_version") < cre.getDomVersionWithNormalizedXPointers() then
-- Show some warning when styles "display:" have changed that -- Show some warning when styles "display:" have changed that
-- bookmarks may break -- bookmarks may break

@ -12,6 +12,8 @@ local _ = require("gettext")
local Screen = Device.screen local Screen = Device.screen
local T = require("ffi/util").template local T = require("ffi/util").template
local DGENERIC_ICON_SIZE = G_defaults:readSetting("DGENERIC_ICON_SIZE")
local ReaderSearch = InputContainer:new{ local ReaderSearch = InputContainer:new{
direction = 0, -- 0 for search forward, 1 for search backward direction = 0, -- 0 for search forward, 1 for search backward
case_insensitive = true, -- default to case insensitive case_insensitive = true, -- default to case insensitive

@ -90,13 +90,13 @@ function ReaderTypeset:onReadSettings(config)
-- set page margins -- set page margins
local h_margins = config:readSetting("copt_h_page_margins") local h_margins = config:readSetting("copt_h_page_margins")
or G_reader_settings:readSetting("copt_h_page_margins") or G_reader_settings:readSetting("copt_h_page_margins")
or DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM or G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM")
local t_margin = config:readSetting("copt_t_page_margin") local t_margin = config:readSetting("copt_t_page_margin")
or G_reader_settings:readSetting("copt_t_page_margin") or G_reader_settings:readSetting("copt_t_page_margin")
or DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE or G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE")
local b_margin = config:readSetting("copt_b_page_margin") local b_margin = config:readSetting("copt_b_page_margin")
or G_reader_settings:readSetting("copt_b_page_margin") or G_reader_settings:readSetting("copt_b_page_margin")
or DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE or G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE")
self.unscaled_margins = { h_margins[1], t_margin, h_margins[2], b_margin } self.unscaled_margins = { h_margins[1], t_margin, h_margins[2], b_margin }
self:onSetPageMargins(self.unscaled_margins) self:onSetPageMargins(self.unscaled_margins)
self.sync_t_b_page_margins = config:readSetting("copt_sync_t_b_page_margins") self.sync_t_b_page_margins = config:readSetting("copt_sync_t_b_page_margins")

@ -151,6 +151,7 @@ When the book's language tag is not among our presets, no specific features will
-- Show infos about TextLangMan seen lang_tags and loaded hyph dicts -- Show infos about TextLangMan seen lang_tags and loaded hyph dicts
local lang_infos = {} local lang_infos = {}
local seen_hyph_dicts = {} -- to avoid outputing count and size for shared hyph dicts local seen_hyph_dicts = {} -- to avoid outputing count and size for shared hyph dicts
local cre = require("document/credocument"):engineInit()
local main_lang_tag, main_lang_active_hyph_dict, loaded_lang_infos = cre.getTextLangStatus() -- luacheck: no unused local main_lang_tag, main_lang_active_hyph_dict, loaded_lang_infos = cre.getTextLangStatus() -- luacheck: no unused
-- First output main lang tag -- First output main lang tag
local main_lang_info = loaded_lang_infos[main_lang_tag] local main_lang_info = loaded_lang_infos[main_lang_tag]
@ -360,6 +361,7 @@ When the book's language tag is not among our presets, no specific features will
end, end,
callback = function() callback = function()
local DoubleSpinWidget = require("/ui/widget/doublespinwidget") local DoubleSpinWidget = require("/ui/widget/doublespinwidget")
local cre = require("document/credocument"):engineInit()
local hyph_alg, alg_left_hyphen_min, alg_right_hyphen_min = cre.getSelectedHyphDict() -- luacheck: no unused local hyph_alg, alg_left_hyphen_min, alg_right_hyphen_min = cre.getSelectedHyphDict() -- luacheck: no unused
local hyph_limits_widget = DoubleSpinWidget:new{ local hyph_limits_widget = DoubleSpinWidget:new{
-- Min (1) and max (10) values are enforced by crengine -- Min (1) and max (10) values are enforced by crengine

@ -34,6 +34,7 @@ end
-- if reload==true, force a reload -- if reload==true, force a reload
-- Unload is done automatically when a new dictionary is loaded. -- Unload is done automatically when a new dictionary is loaded.
function ReaderUserHyph:loadDictionary(name, reload, no_scrubbing) function ReaderUserHyph:loadDictionary(name, reload, no_scrubbing)
local cre = require("document/credocument"):engineInit()
if G_reader_settings:isTrue("hyph_user_dict") and lfs.attributes(name, "mode") == "file" then if G_reader_settings:isTrue("hyph_user_dict") and lfs.attributes(name, "mode") == "file" then
logger.dbg("set user hyphenation dict", name, reload, no_scrubbing) logger.dbg("set user hyphenation dict", name, reload, no_scrubbing)
local ret = cre.setUserHyphenationDict(name, reload) local ret = cre.setUserHyphenationDict(name, reload)
@ -265,6 +266,7 @@ function ReaderUserHyph:modifyUserEntry(word)
word = Utf8Proc.normalize_NFC(word) word = Utf8Proc.normalize_NFC(word)
end end
local cre = require("document/credocument"):engineInit()
local suggested_hyphenation = cre.getHyphenationForWord(word) local suggested_hyphenation = cre.getHyphenationForWord(word)
-- word may have some strange punctuation marks (as the upper dot), -- word may have some strange punctuation marks (as the upper dot),

@ -39,7 +39,7 @@ local ReaderView = OverlapGroup:extend{
offset = nil, offset = nil,
bbox = nil, bbox = nil,
}, },
outer_page_color = Blitbuffer.gray(DOUTER_PAGE_COLOR / 15), outer_page_color = Blitbuffer.gray(G_defaults:readSetting("DOUTER_PAGE_COLOR") / 15),
-- highlight with "lighten" or "underscore" or "strikeout" or "invert" -- highlight with "lighten" or "underscore" or "strikeout" or "invert"
highlight = { highlight = {
lighten_factor = G_reader_settings:readSetting("highlight_lighten_factor", 0.2), lighten_factor = G_reader_settings:readSetting("highlight_lighten_factor", 0.2),
@ -57,7 +57,7 @@ local ReaderView = OverlapGroup:extend{
note_mark_pos_x2 = nil, -- page 2 in two-page mode note_mark_pos_x2 = nil, -- page 2 in two-page mode
-- PDF/DjVu continuous paging -- PDF/DjVu continuous paging
page_scroll = nil, page_scroll = nil,
page_bgcolor = Blitbuffer.gray(DBACKGROUND_COLOR / 15), page_bgcolor = Blitbuffer.gray(G_defaults:readSetting("DBACKGROUND_COLOR") / 15),
page_states = {}, page_states = {},
-- properties of the gap drawn between each page in scroll mode: -- properties of the gap drawn between each page in scroll mode:
page_gap = { page_gap = {
@ -65,9 +65,9 @@ local ReaderView = OverlapGroup:extend{
color = Blitbuffer.gray((G_reader_settings:readSetting("page_gap_color") or 8) / 15), color = Blitbuffer.gray((G_reader_settings:readSetting("page_gap_color") or 8) / 15),
}, },
-- DjVu page rendering mode (used in djvu.c:drawPage()) -- DjVu page rendering mode (used in djvu.c:drawPage())
render_mode = DRENDER_MODE, -- default to COLOR render_mode = G_defaults:readSetting("DRENDER_MODE"), -- default to COLOR
-- Crengine view mode -- Crengine view mode
view_mode = DCREREADER_VIEW_MODE, -- default to page mode view_mode = G_defaults:readSetting("DCREREADER_VIEW_MODE"), -- default to page mode
hinting = true, hinting = true,
-- visible area within current viewing page -- visible area within current viewing page
@ -883,7 +883,7 @@ function ReaderView:onReadSettings(config)
end end
end end
self.inverse_reading_order = config:isTrue("inverse_reading_order") or G_reader_settings:isTrue("inverse_reading_order") self.inverse_reading_order = config:isTrue("inverse_reading_order") or G_reader_settings:isTrue("inverse_reading_order")
self.page_overlap_enable = config:isTrue("show_overlap_enable") or G_reader_settings:isTrue("page_overlap_enable") or DSHOWOVERLAP self.page_overlap_enable = config:isTrue("show_overlap_enable") or G_reader_settings:isTrue("page_overlap_enable") or G_defaults:readSetting("DSHOWOVERLAP")
self.page_overlap_style = config:readSetting("page_overlap_style") or G_reader_settings:readSetting("page_overlap_style") or "dim" self.page_overlap_style = config:readSetting("page_overlap_style") or G_reader_settings:readSetting("page_overlap_style") or "dim"
self.page_gap.height = Screen:scaleBySize(config:readSetting("kopt_page_gap_height") self.page_gap.height = Screen:scaleBySize(config:readSetting("kopt_page_gap_height")
or G_reader_settings:readSetting("kopt_page_gap_height") or G_reader_settings:readSetting("kopt_page_gap_height")
@ -1141,16 +1141,18 @@ function ReaderView:getTapZones()
local forward_zone, backward_zone local forward_zone, backward_zone
local tap_zones_type = G_reader_settings:readSetting("page_turns_tap_zones", "default") local tap_zones_type = G_reader_settings:readSetting("page_turns_tap_zones", "default")
if tap_zones_type == "default" then if tap_zones_type == "default" then
local DTAP_ZONE_FORWARD = G_defaults:readSetting("DTAP_ZONE_FORWARD")
forward_zone = { forward_zone = {
ratio_x = DTAP_ZONE_FORWARD.x, ratio_y = DTAP_ZONE_FORWARD.y, ratio_x = DTAP_ZONE_FORWARD.x, ratio_y = DTAP_ZONE_FORWARD.y,
ratio_w = DTAP_ZONE_FORWARD.w, ratio_h = DTAP_ZONE_FORWARD.h, ratio_w = DTAP_ZONE_FORWARD.w, ratio_h = DTAP_ZONE_FORWARD.h,
} }
local DTAP_ZONE_BACKWARD = G_defaults:readSetting("DTAP_ZONE_BACKWARD")
backward_zone = { backward_zone = {
ratio_x = DTAP_ZONE_BACKWARD.x, ratio_y = DTAP_ZONE_BACKWARD.y, ratio_x = DTAP_ZONE_BACKWARD.x, ratio_y = DTAP_ZONE_BACKWARD.y,
ratio_w = DTAP_ZONE_BACKWARD.w, ratio_h = DTAP_ZONE_BACKWARD.h, ratio_w = DTAP_ZONE_BACKWARD.w, ratio_h = DTAP_ZONE_BACKWARD.h,
} }
else -- user defined page turns tap zones else -- user defined page turns tap zones
local tap_zone_forward_w = G_reader_settings:readSetting("page_turns_tap_zone_forward_size_ratio", DTAP_ZONE_FORWARD.w) local tap_zone_forward_w = G_reader_settings:readSetting("page_turns_tap_zone_forward_size_ratio", G_defaults:readSetting("DTAP_ZONE_FORWARD").w)
local tap_zone_backward_w = 1 - tap_zone_forward_w local tap_zone_backward_w = 1 - tap_zone_forward_w
if tap_zones_type == "left_right" then if tap_zones_type == "left_right" then
forward_zone = { forward_zone = {

@ -20,12 +20,12 @@ local KoboPowerD = BasePowerD:new{
fl_was_on = nil, fl_was_on = nil,
} }
--- @todo Remove KOBO_LIGHT_ON_START --- @todo Remove G_defaults:readSetting("KOBO_LIGHT_ON_START")
function KoboPowerD:_syncKoboLightOnStart() function KoboPowerD:_syncKoboLightOnStart()
local new_intensity = nil local new_intensity = nil
local is_frontlight_on = nil local is_frontlight_on = nil
local new_warmth = nil local new_warmth = nil
local kobo_light_on_start = tonumber(KOBO_LIGHT_ON_START) local kobo_light_on_start = tonumber(G_defaults:readSetting("KOBO_LIGHT_ON_START"))
if kobo_light_on_start then if kobo_light_on_start then
if kobo_light_on_start > 0 then if kobo_light_on_start > 0 then
new_intensity = math.min(kobo_light_on_start, 100) new_intensity = math.min(kobo_light_on_start, 100)
@ -203,7 +203,7 @@ function KoboPowerD:saveSettings()
G_reader_settings:saveSetting("frontlight_warmth", cur_warmth) G_reader_settings:saveSetting("frontlight_warmth", cur_warmth)
end end
-- And to "Kobo eReader.conf" if needed -- And to "Kobo eReader.conf" if needed
if KOBO_SYNC_BRIGHTNESS_WITH_NICKEL then if G_defaults:readSetting("KOBO_SYNC_BRIGHTNESS_WITH_NICKEL") then
if NickelConf.frontLightState.get() ~= nil then if NickelConf.frontLightState.get() ~= nil then
if NickelConf.frontLightState.get() ~= cur_is_fl_on then if NickelConf.frontLightState.get() ~= cur_is_fl_on then
NickelConf.frontLightState.set(cur_is_fl_on) NickelConf.frontLightState.set(cur_is_fl_on)

@ -9,6 +9,7 @@ local Screen = require("device").screen
local buffer = require("string.buffer") local buffer = require("string.buffer")
local ffi = require("ffi") local ffi = require("ffi")
local C = ffi.C local C = ffi.C
local cre -- Delayed loading
local lfs = require("libs/libkoreader-lfs") local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
local lru = require("ffi/lru") local lru = require("ffi/lru")
@ -107,7 +108,7 @@ end
function CreDocument:engineInit() function CreDocument:engineInit()
if not engine_initialized then if not engine_initialized then
require "libs/libkoreader-cre" cre = require("libs/libkoreader-cre")
-- initialize cache -- initialize cache
self:cacheInit() self:cacheInit()
@ -116,9 +117,9 @@ function CreDocument:engineInit()
-- we need to initialize the CRE font list -- we need to initialize the CRE font list
local fonts = FontList:getFontList() local fonts = FontList:getFontList()
for _k, _v in ipairs(fonts) do for k, v in ipairs(fonts) do
if not _v:find("/urw/") and not _v:find("/nerdfonts/symbols.ttf") then if not v:find("/urw/") and not v:find("/nerdfonts/symbols.ttf") then
local ok, err = pcall(cre.registerFont, _v) local ok, err = pcall(cre.registerFont, v)
if not ok then if not ok then
logger.err("failed to register crengine font:", err) logger.err("failed to register crengine font:", err)
end end
@ -138,6 +139,8 @@ function CreDocument:engineInit()
engine_initialized = true engine_initialized = true
end end
return cre
end end
function CreDocument:init() function CreDocument:init()
@ -164,7 +167,7 @@ function CreDocument:init()
end end
-- This mode must be the same as the default one set as ReaderView.view_mode -- This mode must be the same as the default one set as ReaderView.view_mode
self._view_mode = DCREREADER_VIEW_MODE == "scroll" and self.SCROLL_VIEW_MODE or self.PAGE_VIEW_MODE self._view_mode = G_defaults:readSetting("DCREREADER_VIEW_MODE") == "scroll" and self.SCROLL_VIEW_MODE or self.PAGE_VIEW_MODE
local ok local ok
ok, self._document = pcall(cre.newDocView, CanvasContext:getWidth(), CanvasContext:getHeight(), self._view_mode) ok, self._document = pcall(cre.newDocView, CanvasContext:getWidth(), CanvasContext:getHeight(), self._view_mode)
@ -290,7 +293,7 @@ function CreDocument:render()
-- This is now configurable and done by ReaderRolling: -- This is now configurable and done by ReaderRolling:
-- -- set visible page count in landscape -- -- set visible page count in landscape
-- if math.max(CanvasContext:getWidth(), CanvasContext:getHeight()) / CanvasContext:getDPI() -- if math.max(CanvasContext:getWidth(), CanvasContext:getHeight()) / CanvasContext:getDPI()
-- < DCREREADER_TWO_PAGE_THRESHOLD then -- < G_defaults:readSetting("DCREREADER_TWO_PAGE_THRESHOLD") then
-- self:setVisiblePageCount(1) -- self:setVisiblePageCount(1)
-- end -- end
logger.dbg("CreDocument: rendering document...") logger.dbg("CreDocument: rendering document...")

@ -10,10 +10,12 @@ local logger = require("logger")
local md5 = require("ffi/sha2").md5 local md5 = require("ffi/sha2").md5
local util = require("util") local util = require("util")
local DHINTCOUNT = G_defaults:readSetting("DHINTCOUNT")
local function calcCacheMemSize() local function calcCacheMemSize()
local min = DGLOBAL_CACHE_SIZE_MINIMUM local min = G_defaults:readSetting("DGLOBAL_CACHE_SIZE_MINIMUM")
local max = DGLOBAL_CACHE_SIZE_MAXIMUM local max = G_defaults:readSetting("DGLOBAL_CACHE_SIZE_MAXIMUM")
local calc = util.calcFreeMem() * (DGLOBAL_CACHE_FREE_PROPORTION or 0) local calc = util.calcFreeMem() * (G_defaults:readSetting("DGLOBAL_CACHE_FREE_PROPORTION") or 0)
return math.min(max, math.max(min, calc)) return math.min(max, math.max(min, calc))
end end
local doccache_size = calcCacheMemSize() local doccache_size = calcCacheMemSize()

@ -82,21 +82,21 @@ function OCREngine:onFree()
end end
function KoptInterface:setDefaultConfigurable(configurable) function KoptInterface:setDefaultConfigurable(configurable)
configurable.doc_language = DKOPTREADER_CONFIG_DOC_DEFAULT_LANG_CODE configurable.doc_language = G_defaults:readSetting("DKOPTREADER_CONFIG_DOC_DEFAULT_LANG_CODE")
configurable.trim_page = DKOPTREADER_CONFIG_TRIM_PAGE configurable.trim_page = G_defaults:readSetting("DKOPTREADER_CONFIG_TRIM_PAGE")
configurable.text_wrap = DKOPTREADER_CONFIG_TEXT_WRAP configurable.text_wrap = G_defaults:readSetting("DKOPTREADER_CONFIG_TEXT_WRAP")
configurable.detect_indent = DKOPTREADER_CONFIG_DETECT_INDENT configurable.detect_indent = G_defaults:readSetting("DKOPTREADER_CONFIG_DETECT_INDENT")
configurable.max_columns = DKOPTREADER_CONFIG_MAX_COLUMNS configurable.max_columns = G_defaults:readSetting("DKOPTREADER_CONFIG_MAX_COLUMNS")
configurable.auto_straighten = DKOPTREADER_CONFIG_AUTO_STRAIGHTEN configurable.auto_straighten = G_defaults:readSetting("DKOPTREADER_CONFIG_AUTO_STRAIGHTEN")
configurable.justification = DKOPTREADER_CONFIG_JUSTIFICATION configurable.justification = G_defaults:readSetting("DKOPTREADER_CONFIG_JUSTIFICATION")
configurable.writing_direction = 0 configurable.writing_direction = 0
configurable.font_size = DKOPTREADER_CONFIG_FONT_SIZE configurable.font_size = G_defaults:readSetting("DKOPTREADER_CONFIG_FONT_SIZE")
configurable.page_margin = DKOPTREADER_CONFIG_PAGE_MARGIN configurable.page_margin = G_defaults:readSetting("DKOPTREADER_CONFIG_PAGE_MARGIN")
configurable.quality = DKOPTREADER_CONFIG_RENDER_QUALITY configurable.quality = G_defaults:readSetting("DKOPTREADER_CONFIG_RENDER_QUALITY")
configurable.contrast = DKOPTREADER_CONFIG_CONTRAST configurable.contrast = G_defaults:readSetting("DKOPTREADER_CONFIG_CONTRAST")
configurable.defect_size = DKOPTREADER_CONFIG_DEFECT_SIZE configurable.defect_size = G_defaults:readSetting("DKOPTREADER_CONFIG_DEFECT_SIZE")
configurable.line_spacing = DKOPTREADER_CONFIG_LINE_SPACING configurable.line_spacing = G_defaults:readSetting("DKOPTREADER_CONFIG_LINE_SPACING")
configurable.word_spacing = DKOPTREADER_CONFIG_DEFAULT_WORD_SPACING configurable.word_spacing = G_defaults:readSetting("DKOPTREADER_CONFIG_DEFAULT_WORD_SPACING")
end end
function KoptInterface:waitForContext(kc) function KoptInterface:waitForContext(kc)
@ -275,7 +275,7 @@ function KoptInterface:getCachedContext(doc, pageno)
logger.dbg("reflowing page", pageno, "in foreground") logger.dbg("reflowing page", pageno, "in foreground")
-- reflow page -- reflow page
--local secs, usecs = FFIUtil.gettime() --local secs, usecs = FFIUtil.gettime()
page:reflow(kc, doc.render_mode or DRENDER_MODE) -- Fall backs to a default set to DDJVU_RENDER_COLOR page:reflow(kc, doc.render_mode or G_defaults:readSetting("DRENDER_MODE")) -- Fall backs to a default set to DDJVU_RENDER_COLOR
page:close() page:close()
--local nsecs, nusecs = FFIUtil.gettime() --local nsecs, nusecs = FFIUtil.gettime()
--local dur = nsecs - secs + (nusecs - usecs) / 1000000 --local dur = nsecs - secs + (nusecs - usecs) / 1000000

@ -74,8 +74,8 @@ function PdfDocument:convertKoptToReflowableFontSize(font_size)
return size * default_font_size return size * default_font_size
elseif G_reader_settings:readSetting("kopt_font_size") then elseif G_reader_settings:readSetting("kopt_font_size") then
return G_reader_settings:readSetting("kopt_font_size") * default_font_size return G_reader_settings:readSetting("kopt_font_size") * default_font_size
elseif DKOPTREADER_CONFIG_FONT_SIZE then elseif G_defaults:readSetting("DKOPTREADER_CONFIG_FONT_SIZE") then
return DKOPTREADER_CONFIG_FONT_SIZE * default_font_size return G_defaults:readSetting("DKOPTREADER_CONFIG_FONT_SIZE") * default_font_size
else else
return default_font_size return default_font_size
end end

@ -268,7 +268,7 @@ function FontList:getLocalizedFontName(file, index)
end end
function FontList:getFontArgFunc() function FontList:getFontArgFunc()
require("document/credocument"):engineInit() local cre = require("document/credocument"):engineInit()
local toggle = {} local toggle = {}
local face_list = cre.getFontFaces() local face_list = cre.getFontFaces()
for _, v in ipairs(face_list) do for _, v in ipairs(face_list) do

@ -5,6 +5,7 @@ Handles append-mostly data such as KOReader's bookmarks and dictionary search hi
local LuaSettings = require("luasettings") local LuaSettings = require("luasettings")
local dbg = require("dbg") local dbg = require("dbg")
local dump = require("dump") local dump = require("dump")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
local util = require("util") local util = require("util")
@ -28,36 +29,54 @@ function LuaData:open(file_path, o) -- luacheck: ignore 312
local new = {file=file_path, data={}} local new = {file=file_path, data={}}
-- some magic to allow for self-describing function names -- Some magic to allow for self-describing function names:
local _local = {} -- We'll use data_env both as the environment when loading the data, *and* its metatable,
_local.__index = _local -- *and* as the target of its index lookup metamethod.
setmetatable(_G, _local) -- Its NameEntry field is a function responsible for actually storing the data in the right place in the LuaData object.
_local[self.name.."Entry"] = function(table) -- It gets called via __index lookup in the global scope (i.e., the env) when Lua tries to resolve
-- the global NameEntry function calls in our stored data.
-- NOTE: We could also make the metatable's __index field point to a function, and handle the lookup ourselves inside it,
-- but using an empty env with loadfile is not a bad idea to begin with anyway ;).
local data_env = {}
data_env.__index = data_env
setmetatable(data_env, data_env)
data_env[self.name.."Entry"] = function(table)
if table.index then if table.index then
-- we've got a deleted setting, overwrite with nil -- We've got a deleted setting, overwrite with nil and be done with it.
if not table.data then new.data[table.index] = nil end if not table.data then
new.data[table.index] = new.data[table.index] or {} new.data[table.index] = nil
local size = util.tableSize(table.data) return
if size == 1 then end
for key, value in pairs(table.data) do
new.data[table.index][key] = value if type(table.data) == "table" then
new.data[table.index] = new.data[table.index] or {}
local size = util.tableSize(table.data)
if size == 1 then
-- It's an incremental array element, insert it in the array at its proper index
for key, value in pairs(table.data) do
new.data[table.index][key] = value
end
else
-- It's a complex table, just replace the whole thing
new.data[table.index] = table.data
end end
else else
new.data[table.index] = table.data new.data[table.index] = table.data
end end
-- we've got it all at once
else else
-- It's an untagged blob, use it as-is
new.data = table new.data = table
end end
end end
local ok = false local ok, err
if lfs.attributes(new.file, "mode") == "file" then if lfs.attributes(new.file, "mode") == "file" then
ok = pcall(dofile, new.file) ok, err = loadfile(new.file, "t", data_env)
if ok then if ok then
logger.dbg("data is read from ", new.file) logger.dbg("data is read from", new.file)
ok()
else else
logger.dbg(new.file, " is invalid, remove.") logger.dbg(new.file, "is invalid, removed.", err)
os.remove(new.file) os.remove(new.file)
end end
end end
@ -65,11 +84,13 @@ function LuaData:open(file_path, o) -- luacheck: ignore 312
for i=1, self.max_backups, 1 do for i=1, self.max_backups, 1 do
local backup_file = new.file..".old."..i local backup_file = new.file..".old."..i
if lfs.attributes(backup_file, "mode") == "file" then if lfs.attributes(backup_file, "mode") == "file" then
if pcall(dofile, backup_file) then ok, err = loadfile(backup_file, "t", data_env)
logger.dbg("data is read from ", backup_file) if ok then
logger.dbg("data is read from", backup_file)
ok()
break break
else else
logger.dbg(backup_file, " is invalid, remove.") logger.dbg(backup_file, "is invalid, removed.", err)
os.remove(backup_file) os.remove(backup_file)
end end
end end
@ -109,10 +130,9 @@ function LuaData:addTableItem(table_name, value)
} }
end end
local _orig_removeTableItem = LuaSettings.removeTableItem
--- Removes index from table. --- Removes index from table.
function LuaData:removeTableItem(key, index) function LuaData:removeTableItem(key, index)
_orig_removeTableItem(self, key, index) LuaSettings.removeTableItem(self, key, index)
self:flush() self:flush()
return self return self
end end
@ -123,6 +143,7 @@ function LuaData:append(data)
local f_out = io.open(self.file, "a") local f_out = io.open(self.file, "a")
if f_out ~= nil then if f_out ~= nil then
os.setlocale('C', 'numeric') os.setlocale('C', 'numeric')
-- NOTE: This is a function call, with a table as its single argument. Parentheses are elided.
f_out:write(self.name.."Entry") f_out:write(self.name.."Entry")
f_out:write(dump(data)) f_out:write(dump(data))
f_out:write("\n") f_out:write("\n")
@ -145,17 +166,17 @@ function LuaData:flush()
if lfs.attributes(self.file, "mode") == "file" then if lfs.attributes(self.file, "mode") == "file" then
for i=1, self.max_backups, 1 do for i=1, self.max_backups, 1 do
if lfs.attributes(self.file..".old."..i, "mode") == "file" then if lfs.attributes(self.file..".old."..i, "mode") == "file" then
logger.dbg("LuaData: Rename ", self.file .. ".old." .. i, " to ", self.file .. ".old." .. i+1) logger.dbg("LuaData: Rename", self.file .. ".old." .. i, "to", self.file .. ".old." .. i+1)
os.rename(self.file, self.file .. ".old." .. i+1) os.rename(self.file, self.file .. ".old." .. i+1)
else else
break break
end end
end end
logger.dbg("LuaData: Rename ", self.file, " to ", self.file .. ".old.1") logger.dbg("LuaData: Rename", self.file, "to", self.file .. ".old.1")
os.rename(self.file, self.file .. ".old.1") os.rename(self.file, self.file .. ".old.1")
end end
logger.dbg("LuaData: Write to ", self.file) logger.dbg("LuaData: Write to", self.file)
local f_out = io.open(self.file, "w") local f_out = io.open(self.file, "w")
if f_out ~= nil then if f_out ~= nil then
os.setlocale('C', 'numeric') os.setlocale('C', 'numeric')

@ -0,0 +1,191 @@
--[[--
Subclass of LuaSettings dedicated to handling the legacy global constants.
]]
local DataStorage = require("datastorage")
local LuaSettings = require("luasettings")
local dump = require("dump")
local ffiutil = require("ffi/util")
local util = require("util")
local isAndroid, android = pcall(require, "android")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger")
local LuaDefaults = LuaSettings:new{
ro = nil, -- will contain the defaults.lua k/v pairs (const)
rw = nil, -- will only contain non-defaults user-modified k/v pairs
}
--- Opens a settings file.
function LuaDefaults:open(path)
local file_path = path or DataStorage:getDataDir() .. "/defaults.custom.lua"
local new = {file = file_path}
local ok, stored
-- File being absent and returning an empty table is a use case,
-- so logger.warn() only if there was an existing file
local existing = lfs.attributes(new.file, "mode") == "file"
ok, stored = pcall(dofile, new.file)
if ok and stored then
new.rw = stored
else
if existing then logger.warn("Failed reading", new.file, "(probably corrupted).") end
-- Fallback to .old if it exists
ok, stored = pcall(dofile, new.file..".old")
if ok and stored then
if existing then logger.warn("read from backup file", new.file..".old") end
new.rw = stored
else
if existing then logger.warn("no usable backup file for", new.file, "to read from") end
new.rw = {}
end
end
-- The actual defaults file, on the other hand, is set in stone.
-- We just have to deal with some platform shenanigans...
local defaults_path = DataStorage:getDataDir() .. "/defaults.lua"
if isAndroid then
defaults_path = android.dir .. "/defaults.lua"
elseif os.getenv("APPIMAGE") then
defaults_path = "defaults.lua"
end
ok, stored = pcall(dofile, defaults_path)
if ok and stored then
new.ro = stored
else
error("Failed reading " .. defaults_path)
end
return setmetatable(new, {__index = LuaDefaults})
end
--- Reads a setting, optionally initializing it to a default.
function LuaDefaults:readSetting(key, default)
if not default then
if self:hasBeenCustomized(key) then
return self.rw[key]
else
return self.ro[key]
end
end
if not self:hasBeenCustomized(key) then
self.rw[key] = default
return self.rw[key]
end
if self:hasBeenCustomized(key) then
return self.rw[key]
else
return self.ro[key]
end
end
--- Saves a setting.
function LuaDefaults:saveSetting(key, value)
if util.tableEquals(self.ro[key], value, true) then
-- Only keep actually custom settings in the rw table ;).
return self:delSetting(key)
else
self.rw[key] = value
end
return self
end
--- Deletes a setting.
function LuaDefaults:delSetting(key)
self.rw[key] = nil
return self
end
--- Checks if setting exists.
function LuaDefaults:has(key)
return self.ro[key] ~= nil
end
--- Checks if setting does not exist.
function LuaDefaults:hasNot(key)
return self.ro[key] == nil
end
--- Checks if setting has been customized.
function LuaDefaults:hasBeenCustomized(key)
return self.rw[key] ~= nil
end
--- Checks if setting has NOT been customized.
function LuaDefaults:hasNotBeenCustomized(key)
return self.rw[key] == nil
end
--- Checks if setting is `true` (boolean).
function LuaDefaults:isTrue(key)
if self:hasBeenCustomized(key) then
return self.rw[key] == true
else
return self.ro[key] == true
end
end
--- Checks if setting is `false` (boolean).
function LuaDefaults:isFalse(key)
if self:hasBeenCustomized(key) then
return self.rw[key] == false
else
return self.ro[key] == false
end
end
--- Low-level API for filemanagersetdefaults
function LuaDefaults:getDataTables()
return self.ro, self.rw
end
function LuaDefaults:readDefaultSetting(key)
return self.ro[key]
end
-- NOP unsupported LuaSettings APIs
function LuaDefaults:wrap() end
function LuaDefaults:child() end
function LuaDefaults:initializeExtSettings() end
function LuaDefaults:getSettingForExt() end
function LuaDefaults:saveSettingForExt() end
function LuaDefaults:addTableItem() end
function LuaDefaults:removeTableItem() end
function LuaDefaults:reset() end
--- Writes settings to disk.
function LuaDefaults:flush()
if not self.file then return end
local directory_updated = false
if lfs.attributes(self.file, "mode") == "file" then
-- As an additional safety measure (to the ffiutil.fsync* calls
-- used below), we only backup the file to .old when it has
-- not been modified in the last 60 seconds. This should ensure
-- in the case the fsync calls are not supported that the OS
-- may have itself sync'ed that file content in the meantime.
local mtime = lfs.attributes(self.file, "modification")
if mtime < os.time() - 60 then
os.rename(self.file, self.file .. ".old")
directory_updated = true -- fsync directory content too below
end
end
local f_out = io.open(self.file, "w")
if f_out ~= nil then
os.setlocale('C', 'numeric')
f_out:write("-- we can read Lua syntax here!\nreturn ")
f_out:write(dump(self.rw, nil, true))
f_out:write("\n")
ffiutil.fsyncOpenedFile(f_out) -- force flush to the storage device
f_out:close()
end
if directory_updated then
-- Ensure the file renaming is flushed to storage device
ffiutil.fsyncDirectory(self.file)
end
return self
end
return LuaDefaults

@ -124,7 +124,7 @@ function PluginLoader:loadPlugins()
table.insert(self.enabled_plugins, plugin_module) table.insert(self.enabled_plugins, plugin_module)
end end
else else
logger.dbg("Plugin ", mainfile, " has been disabled.") logger.dbg("Plugin", mainfile, "has been disabled.")
end end
package.path = package_path package.path = package_path
package.cpath = package_cpath package.cpath = package_cpath
@ -203,7 +203,7 @@ function PluginLoader:createPluginInstance(plugin, attr)
self.loaded_plugins[plugin.name] = re self.loaded_plugins[plugin.name] = re
return ok, re return ok, re
else -- re is the error message else -- re is the error message
logger.err("Failed to initialize", plugin.name, "plugin: ", re) logger.err("Failed to initialize", plugin.name, "plugin:", re)
return nil, re return nil, re
end end
end end

@ -136,29 +136,29 @@ This is disabled in scroll mode. Switching from page mode with two columns to sc
name_text = _("L/R Margins"), name_text = _("L/R Margins"),
buttonprogress = true, buttonprogress = true,
values = { values = {
DCREREADER_CONFIG_H_MARGIN_SIZES_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_SMALL"),
DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM"),
DCREREADER_CONFIG_H_MARGIN_SIZES_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_LARGE"),
DCREREADER_CONFIG_H_MARGIN_SIZES_X_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_X_LARGE"),
DCREREADER_CONFIG_H_MARGIN_SIZES_XX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_XX_LARGE"),
DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE"),
DCREREADER_CONFIG_H_MARGIN_SIZES_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_HUGE"),
DCREREADER_CONFIG_H_MARGIN_SIZES_X_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_X_HUGE"),
DCREREADER_CONFIG_H_MARGIN_SIZES_XX_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_XX_HUGE"),
}, },
default_pos = 2, default_pos = 2,
default_value = DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM, default_value = G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM"),
event = "SetPageHorizMargins", event = "SetPageHorizMargins",
args = { args = {
DCREREADER_CONFIG_H_MARGIN_SIZES_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_SMALL"),
DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_MEDIUM"),
DCREREADER_CONFIG_H_MARGIN_SIZES_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_LARGE"),
DCREREADER_CONFIG_H_MARGIN_SIZES_X_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_X_LARGE"),
DCREREADER_CONFIG_H_MARGIN_SIZES_XX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_XX_LARGE"),
DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE"),
DCREREADER_CONFIG_H_MARGIN_SIZES_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_HUGE"),
DCREREADER_CONFIG_H_MARGIN_SIZES_X_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_X_HUGE"),
DCREREADER_CONFIG_H_MARGIN_SIZES_XX_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_H_MARGIN_SIZES_XX_HUGE"),
}, },
hide_on_apply = true, hide_on_apply = true,
name_text_hold_callback = optionsutil.showValuesHMargins, name_text_hold_callback = optionsutil.showValuesHMargins,
@ -198,29 +198,29 @@ In the top menu → Settings → Status bar, you can choose whether the bottom m
name_text = _("Top Margin"), name_text = _("Top Margin"),
buttonprogress = true, buttonprogress = true,
values = { values = {
DCREREADER_CONFIG_T_MARGIN_SIZES_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_SMALL"),
DCREREADER_CONFIG_T_MARGIN_SIZES_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_MEDIUM"),
DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE"),
DCREREADER_CONFIG_T_MARGIN_SIZES_X_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_X_LARGE"),
DCREREADER_CONFIG_T_MARGIN_SIZES_XX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_XX_LARGE"),
DCREREADER_CONFIG_T_MARGIN_SIZES_XXX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_XXX_LARGE"),
DCREREADER_CONFIG_T_MARGIN_SIZES_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_HUGE"),
DCREREADER_CONFIG_T_MARGIN_SIZES_X_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_X_HUGE"),
DCREREADER_CONFIG_T_MARGIN_SIZES_XX_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_XX_HUGE"),
}, },
default_pos = 3, default_pos = 3,
default_value = DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE, default_value = G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE"),
event = "SetPageTopMargin", event = "SetPageTopMargin",
args = { args = {
DCREREADER_CONFIG_T_MARGIN_SIZES_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_SMALL"),
DCREREADER_CONFIG_T_MARGIN_SIZES_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_MEDIUM"),
DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_LARGE"),
DCREREADER_CONFIG_T_MARGIN_SIZES_X_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_X_LARGE"),
DCREREADER_CONFIG_T_MARGIN_SIZES_XX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_XX_LARGE"),
DCREREADER_CONFIG_T_MARGIN_SIZES_XXX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_XXX_LARGE"),
DCREREADER_CONFIG_T_MARGIN_SIZES_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_HUGE"),
DCREREADER_CONFIG_T_MARGIN_SIZES_X_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_X_HUGE"),
DCREREADER_CONFIG_T_MARGIN_SIZES_XX_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_T_MARGIN_SIZES_XX_HUGE"),
}, },
hide_on_apply = true, hide_on_apply = true,
name_text_hold_callback = function(configurable, opt, prefix) name_text_hold_callback = function(configurable, opt, prefix)
@ -252,29 +252,29 @@ In the top menu → Settings → Status bar, you can choose whether the bottom m
name_text = _("Bottom Margin"), name_text = _("Bottom Margin"),
buttonprogress = true, buttonprogress = true,
values = { values = {
DCREREADER_CONFIG_B_MARGIN_SIZES_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_SMALL"),
DCREREADER_CONFIG_B_MARGIN_SIZES_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_MEDIUM"),
DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE"),
DCREREADER_CONFIG_B_MARGIN_SIZES_X_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_X_LARGE"),
DCREREADER_CONFIG_B_MARGIN_SIZES_XX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_XX_LARGE"),
DCREREADER_CONFIG_B_MARGIN_SIZES_XXX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_XXX_LARGE"),
DCREREADER_CONFIG_B_MARGIN_SIZES_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_HUGE"),
DCREREADER_CONFIG_B_MARGIN_SIZES_X_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_X_HUGE"),
DCREREADER_CONFIG_B_MARGIN_SIZES_XX_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_XX_HUGE"),
}, },
default_pos = 3, default_pos = 3,
default_value = DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE, default_value = G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE"),
event = "SetPageBottomMargin", event = "SetPageBottomMargin",
args = { args = {
DCREREADER_CONFIG_B_MARGIN_SIZES_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_SMALL"),
DCREREADER_CONFIG_B_MARGIN_SIZES_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_MEDIUM"),
DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_LARGE"),
DCREREADER_CONFIG_B_MARGIN_SIZES_X_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_X_LARGE"),
DCREREADER_CONFIG_B_MARGIN_SIZES_XX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_XX_LARGE"),
DCREREADER_CONFIG_B_MARGIN_SIZES_XXX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_XXX_LARGE"),
DCREREADER_CONFIG_B_MARGIN_SIZES_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_HUGE"),
DCREREADER_CONFIG_B_MARGIN_SIZES_X_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_X_HUGE"),
DCREREADER_CONFIG_B_MARGIN_SIZES_XX_HUGE, G_defaults:readSetting("DCREREADER_CONFIG_B_MARGIN_SIZES_XX_HUGE"),
}, },
hide_on_apply = true, hide_on_apply = true,
name_text_hold_callback = function(configurable, opt, prefix) name_text_hold_callback = function(configurable, opt, prefix)
@ -368,22 +368,22 @@ Note that your selected font size is not affected by this setting.]]),
name_text = _("Line Spacing"), name_text = _("Line Spacing"),
buttonprogress = true, buttonprogress = true,
values = { values = {
DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_TINY, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_TINY"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_TINY, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_TINY"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_SMALL"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_SMALL"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_SMALL"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_SMALL"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_MEDIUM"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_XL_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_XL_MEDIUM"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_XXL_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_XXL_MEDIUM"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_LARGE"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_LARGE"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_LARGE"),
}, },
default_pos = 7, default_pos = 7,
default_value = DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM, default_value = G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM"),
more_options = true, more_options = true,
more_options_param = { more_options_param = {
value_min = 50, value_min = 50,
@ -394,19 +394,19 @@ Note that your selected font size is not affected by this setting.]]),
}, },
event = "SetLineSpace", event = "SetLineSpace",
args = { args = {
DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_TINY, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_TINY"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_TINY, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_TINY"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_SMALL"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_SMALL"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_SMALL"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_SMALL"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_MEDIUM"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_L_MEDIUM"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_XL_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_XL_MEDIUM"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_XXL_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_XXL_MEDIUM"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_LARGE"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_X_LARGE"),
DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_LINE_SPACE_PERCENT_XX_LARGE"),
}, },
name_text_hold_callback = optionsutil.showValues, name_text_hold_callback = optionsutil.showValues,
show_true_value_func = function(val) -- add "%" show_true_value_func = function(val) -- add "%"
@ -421,13 +421,13 @@ Note that your selected font size is not affected by this setting.]]),
{ {
name = "font_size", name = "font_size",
alt_name_text = _("Font Size"), alt_name_text = _("Font Size"),
item_text = tableOfNumbersToTableOfStrings(DCREREADER_CONFIG_FONT_SIZES), item_text = tableOfNumbersToTableOfStrings(G_defaults:readSetting("DCREREADER_CONFIG_FONT_SIZES")),
item_align_center = 1.0, item_align_center = 1.0,
spacing = 15, spacing = 15,
item_font_size = DCREREADER_CONFIG_FONT_SIZES, item_font_size = G_defaults:readSetting("DCREREADER_CONFIG_FONT_SIZES"),
values = DCREREADER_CONFIG_FONT_SIZES, values = G_defaults:readSetting("DCREREADER_CONFIG_FONT_SIZES"),
default_value = DCREREADER_CONFIG_DEFAULT_FONT_SIZE, default_value = G_defaults:readSetting("DCREREADER_CONFIG_DEFAULT_FONT_SIZE"),
args = DCREREADER_CONFIG_FONT_SIZES, args = G_defaults:readSetting("DCREREADER_CONFIG_FONT_SIZES"),
event = "SetFontSize", event = "SetFontSize",
}, },
{ {
@ -483,15 +483,15 @@ Note that your selected font size is not affected by this setting.]]),
}, },
toggle = {C_("Word spacing", "small"), C_("Word spacing", "medium"), C_("Word spacing", "large")}, toggle = {C_("Word spacing", "small"), C_("Word spacing", "medium"), C_("Word spacing", "large")},
values = { values = {
DCREREADER_CONFIG_WORD_SPACING_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_WORD_SPACING_SMALL"),
DCREREADER_CONFIG_WORD_SPACING_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_WORD_SPACING_MEDIUM"),
DCREREADER_CONFIG_WORD_SPACING_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_WORD_SPACING_LARGE"),
}, },
default_value = DCREREADER_CONFIG_WORD_SPACING_MEDIUM, default_value = G_defaults:readSetting("DCREREADER_CONFIG_WORD_SPACING_MEDIUM"),
args = { args = {
DCREREADER_CONFIG_WORD_SPACING_SMALL, G_defaults:readSetting("DCREREADER_CONFIG_WORD_SPACING_SMALL"),
DCREREADER_CONFIG_WORD_SPACING_MEDIUM, G_defaults:readSetting("DCREREADER_CONFIG_WORD_SPACING_MEDIUM"),
DCREREADER_CONFIG_WORD_SPACING_LARGE, G_defaults:readSetting("DCREREADER_CONFIG_WORD_SPACING_LARGE"),
}, },
event = "SetWordSpacing", event = "SetWordSpacing",
help_text = _([[Tells the rendering engine by how much to scale the width of each 'space' character in the text from its regular width, and by how much it can additionally reduce them to make more words fit on a line (100% means no reduction).]]), help_text = _([[Tells the rendering engine by how much to scale the width of each 'space' character in the text from its regular width, and by how much it can additionally reduce them to make more words fit on a line (100% means no reduction).]]),
@ -522,15 +522,15 @@ Note that your selected font size is not affected by this setting.]]),
}, },
toggle = {C_("Word expansion", "none"), C_("Word expansion", "some"), C_("Word expansion", "more")}, toggle = {C_("Word expansion", "none"), C_("Word expansion", "some"), C_("Word expansion", "more")},
values = { values = {
DCREREADER_CONFIG_WORD_EXPANSION_NONE, G_defaults:readSetting("DCREREADER_CONFIG_WORD_EXPANSION_NONE"),
DCREREADER_CONFIG_WORD_EXPANSION_SOME, G_defaults:readSetting("DCREREADER_CONFIG_WORD_EXPANSION_SOME"),
DCREREADER_CONFIG_WORD_EXPANSION_MORE, G_defaults:readSetting("DCREREADER_CONFIG_WORD_EXPANSION_MORE"),
}, },
default_value = DCREREADER_CONFIG_WORD_EXPANSION_NONE, default_value = G_defaults:readSetting("DCREREADER_CONFIG_WORD_EXPANSION_NONE"),
args = { args = {
DCREREADER_CONFIG_WORD_EXPANSION_NONE, G_defaults:readSetting("DCREREADER_CONFIG_WORD_EXPANSION_NONE"),
DCREREADER_CONFIG_WORD_EXPANSION_SOME, G_defaults:readSetting("DCREREADER_CONFIG_WORD_EXPANSION_SOME"),
DCREREADER_CONFIG_WORD_EXPANSION_MORE, G_defaults:readSetting("DCREREADER_CONFIG_WORD_EXPANSION_MORE"),
}, },
event = "SetWordExpansion", event = "SetWordExpansion",
help_text = _([[On justified lines having too wide spaces, allow distributing the excessive space into words by expanding them with letter spacing. This sets the max allowed letter spacing as a % of the font size.]]), help_text = _([[On justified lines having too wide spaces, allow distributing the excessive space into words by expanding them with letter spacing. This sets the max allowed letter spacing as a % of the font size.]]),
@ -620,6 +620,7 @@ Note that your selected font size is not affected by this setting.]]),
- +3 will use the "Bold (700)" variation of a font if available. - +3 will use the "Bold (700)" variation of a font if available.
If a font variation is not available, as well as for fractional adjustments, it will be synthesized from the nearest available weight.]]), If a font variation is not available, as well as for fractional adjustments, it will be synthesized from the nearest available weight.]]),
help_text_func = function(configurable, document) help_text_func = function(configurable, document)
local cre = require("document/credocument"):engineInit()
local font_face = document:getFontFace() local font_face = document:getFontFace()
local available_weights = prettifyCreWeights(cre.getFontFaceAvailableWeights(font_face)) local available_weights = prettifyCreWeights(cre.getFontFaceAvailableWeights(font_face))
return T(_("The default font '%1' provides the following weight classes: %2."), font_face, table.concat(available_weights, C_("List separator", ", "))) return T(_("The default font '%1' provides the following weight classes: %2."), font_face, table.concat(available_weights, C_("List separator", ", ")))

@ -86,7 +86,7 @@ local KoptOptions = {
toggle = {C_("Page crop", "none"), C_("Page crop", "auto"), C_("Page crop", "semi-auto"), C_("Page crop", "manual")}, toggle = {C_("Page crop", "none"), C_("Page crop", "auto"), C_("Page crop", "semi-auto"), C_("Page crop", "manual")},
alternate = false, alternate = false,
values = {3, 1, 2, 0}, values = {3, 1, 2, 0},
default_value = DKOPTREADER_CONFIG_TRIM_PAGE, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_TRIM_PAGE"),
enabled_func = function() return Device:isTouchDevice() or Device:hasDPad() end, enabled_func = function() return Device:isTouchDevice() or Device:hasDPad() end,
event = "PageCrop", event = "PageCrop",
args = {"none", "auto", "semi-auto", "manual"}, args = {"none", "auto", "semi-auto", "manual"},
@ -105,7 +105,7 @@ In 'semi-auto' and 'manual' modes, you may need to define areas once on an odd p
name_text = _("Margin"), name_text = _("Margin"),
toggle = {C_("Page margin", "small"), C_("Page margin", "medium"), C_("Page margin", "large")}, toggle = {C_("Page margin", "small"), C_("Page margin", "medium"), C_("Page margin", "large")},
values = {0.05, 0.10, 0.25}, values = {0.05, 0.10, 0.25},
default_value = DKOPTREADER_CONFIG_PAGE_MARGIN, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_PAGE_MARGIN"),
event = "MarginUpdate", event = "MarginUpdate",
name_text_hold_callback = optionsutil.showValues, name_text_hold_callback = optionsutil.showValues,
help_text = _([[Set margins to be applied after page-crop and zoom modes are applied.]]), help_text = _([[Set margins to be applied after page-crop and zoom modes are applied.]]),
@ -118,7 +118,7 @@ In 'semi-auto' and 'manual' modes, you may need to define areas once on an odd p
event = "DummyEvent", event = "DummyEvent",
args = {0, 5, 10, 15, 25}, args = {0, 5, 10, 15, 25},
more_options = true, more_options = true,
default_value = DKOPTREADER_CONFIG_AUTO_STRAIGHTEN, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_AUTO_STRAIGHTEN"),
name_text_hold_callback = optionsutil.showValues, name_text_hold_callback = optionsutil.showValues,
help_text = _([[Attempt to automatically straighten tilted source pages. help_text = _([[Attempt to automatically straighten tilted source pages.
Will rotate up to specified value.]]), Will rotate up to specified value.]]),
@ -361,7 +361,7 @@ left to right or reverse, top to bottom or reverse.]]),
name_text = _("Line Spacing"), name_text = _("Line Spacing"),
toggle = {C_("Line spacing", "small"), C_("Line spacing", "medium"), C_("Line spacing", "large")}, toggle = {C_("Line spacing", "small"), C_("Line spacing", "medium"), C_("Line spacing", "large")},
values = {1.0, 1.2, 1.4}, values = {1.0, 1.2, 1.4},
default_value = DKOPTREADER_CONFIG_LINE_SPACING, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_LINE_SPACING"),
advanced = true, advanced = true,
enabled_func = function(configurable) enabled_func = function(configurable)
-- seems to only work in reflow mode -- seems to only work in reflow mode
@ -382,7 +382,7 @@ left to right or reverse, top to bottom or reverse.]]),
"align.justify", "align.justify",
}, },
values = {-1,0,1,2,3}, values = {-1,0,1,2,3},
default_value = DKOPTREADER_CONFIG_JUSTIFICATION, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_JUSTIFICATION"),
advanced = true, advanced = true,
enabled_func = function(configurable) enabled_func = function(configurable)
return optionsutil.enableIfEquals(configurable, "text_wrap", 1) return optionsutil.enableIfEquals(configurable, "text_wrap", 1)
@ -411,7 +411,7 @@ The first option ("auto") tries to automatically align reflowed text as it is in
item_font_size = FONT_SCALE_DISPLAY_SIZE, item_font_size = FONT_SCALE_DISPLAY_SIZE,
args = FONT_SCALE_FACTORS, args = FONT_SCALE_FACTORS,
values = FONT_SCALE_FACTORS, values = FONT_SCALE_FACTORS,
default_value = DKOPTREADER_CONFIG_FONT_SIZE, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_FONT_SIZE"),
event = "FontSizeUpdate", event = "FontSizeUpdate",
enabled_func = function(configurable, document) enabled_func = function(configurable, document)
if document.is_reflowable then return true end if document.is_reflowable then return true end
@ -445,8 +445,8 @@ The first option ("auto") tries to automatically align reflowed text as it is in
name = "word_spacing", name = "word_spacing",
name_text = _("Word Gap"), name_text = _("Word Gap"),
toggle = {C_("Word gap", "small"), C_("Word gap", "auto"), C_("Word gap", "large")}, toggle = {C_("Word gap", "small"), C_("Word gap", "auto"), C_("Word gap", "large")},
values = DKOPTREADER_CONFIG_WORD_SPACINGS, values = G_defaults:readSetting("DKOPTREADER_CONFIG_WORD_SPACINGS"),
default_value = DKOPTREADER_CONFIG_DEFAULT_WORD_SPACING, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_DEFAULT_WORD_SPACING"),
enabled_func = function(configurable) enabled_func = function(configurable)
return optionsutil.enableIfEquals(configurable, "text_wrap", 1) return optionsutil.enableIfEquals(configurable, "text_wrap", 1)
end, end,
@ -459,7 +459,7 @@ The first option ("auto") tries to automatically align reflowed text as it is in
name_text = _("Reflow"), name_text = _("Reflow"),
toggle = {_("off"), _("on")}, toggle = {_("off"), _("on")},
values = {0, 1}, values = {0, 1},
default_value = DKOPTREADER_CONFIG_TEXT_WRAP, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_TEXT_WRAP"),
event = "ReflowUpdated", event = "ReflowUpdated",
name_text_hold_callback = optionsutil.showValues, name_text_hold_callback = optionsutil.showValues,
help_text = _([[Reflow mode extracts text and images from the original document, possibly discarding some formatting, and reflows it on the screen for easier reading. help_text = _([[Reflow mode extracts text and images from the original document, possibly discarding some formatting, and reflows it on the screen for easier reading.
@ -478,7 +478,7 @@ Some of the other settings are only available when reflow mode is enabled.]]),
-- For pdf reflowing mode (kopt_contrast): -- For pdf reflowing mode (kopt_contrast):
values = {1/0.8, 1/1.0, 1/1.5, 1/2.0, 1/4.0, 1/6.0, 1/10.0, 1/50.0}, values = {1/0.8, 1/1.0, 1/1.5, 1/2.0, 1/4.0, 1/6.0, 1/10.0, 1/50.0},
default_pos = 2, default_pos = 2,
default_value = DKOPTREADER_CONFIG_CONTRAST, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_CONTRAST"),
event = "GammaUpdate", event = "GammaUpdate",
-- For pdf non-reflowing mode (mupdf): -- For pdf non-reflowing mode (mupdf):
args = {0.8, 1.0, 1.5, 2.0, 4.0, 6.0, 10.0, 50.0}, args = {0.8, 1.0, 1.5, 2.0, 4.0, 6.0, 10.0, 50.0},
@ -526,7 +526,7 @@ This can also be used to remove some gray background or to convert a grayscale o
name_text = C_("Quality", "Render Quality"), name_text = C_("Quality", "Render Quality"),
toggle = {C_("Quality", "low"), C_("Quality", "default"), C_("Quality", "high")}, toggle = {C_("Quality", "low"), C_("Quality", "default"), C_("Quality", "high")},
values={0.5, 1.0, 1.5}, values={0.5, 1.0, 1.5},
default_value = DKOPTREADER_CONFIG_RENDER_QUALITY, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_RENDER_QUALITY"),
advanced = true, advanced = true,
enabled_func = function(configurable) enabled_func = function(configurable)
return optionsutil.enableIfEquals(configurable, "text_wrap", 1) return optionsutil.enableIfEquals(configurable, "text_wrap", 1)
@ -542,11 +542,11 @@ This can also be used to remove some gray background or to convert a grayscale o
{ {
name = "doc_language", name = "doc_language",
name_text = _("Document Language"), name_text = _("Document Language"),
toggle = DKOPTREADER_CONFIG_DOC_LANGS_TEXT, toggle = G_defaults:readSetting("DKOPTREADER_CONFIG_DOC_LANGS_TEXT"),
values = DKOPTREADER_CONFIG_DOC_LANGS_CODE, values = G_defaults:readSetting("DKOPTREADER_CONFIG_DOC_LANGS_CODE"),
default_value = DKOPTREADER_CONFIG_DOC_DEFAULT_LANG_CODE, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_DOC_DEFAULT_LANG_CODE"),
event = "DocLangUpdate", event = "DocLangUpdate",
args = DKOPTREADER_CONFIG_DOC_LANGS_CODE, args = G_defaults:readSetting("DKOPTREADER_CONFIG_DOC_LANGS_CODE"),
name_text_hold_callback = optionsutil.showValues, name_text_hold_callback = optionsutil.showValues,
help_text = _([[Set the language to be used by the OCR engine.]]), help_text = _([[Set the language to be used by the OCR engine.]]),
}, },
@ -586,7 +586,7 @@ This can also be used to remove some gray background or to convert a grayscale o
name_text = _("Reflow Speckle Ignore Size"), name_text = _("Reflow Speckle Ignore Size"),
toggle = {_("small"), _("medium"), _("large")}, toggle = {_("small"), _("medium"), _("large")},
values = {1.0, 3.0, 5.0}, values = {1.0, 3.0, 5.0},
default_value = DKOPTREADER_CONFIG_DEFECT_SIZE, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_DEFECT_SIZE"),
event = "DefectSizeUpdate", event = "DefectSizeUpdate",
show = false, -- might work somehow, but larger values than 1.0 might easily eat content show = false, -- might work somehow, but larger values than 1.0 might easily eat content
enabled_func = function(configurable) enabled_func = function(configurable)
@ -599,7 +599,7 @@ This can also be used to remove some gray background or to convert a grayscale o
name_text = _("Indentation"), name_text = _("Indentation"),
toggle = {_("off"), _("on")}, toggle = {_("off"), _("on")},
values = {0, 1}, values = {0, 1},
default_value = DKOPTREADER_CONFIG_DETECT_INDENT, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_DETECT_INDENT"),
show = false, -- does not work show = false, -- does not work
enabled_func = function(configurable) enabled_func = function(configurable)
return optionsutil.enableIfEquals(configurable, "text_wrap", 1) return optionsutil.enableIfEquals(configurable, "text_wrap", 1)
@ -615,7 +615,7 @@ This can also be used to remove some gray background or to convert a grayscale o
"column.three", "column.three",
}, },
values = {1, 2, 3}, values = {1, 2, 3},
default_value = DKOPTREADER_CONFIG_MAX_COLUMNS, default_value = G_defaults:readSetting("DKOPTREADER_CONFIG_MAX_COLUMNS"),
enabled_func = function(configurable) enabled_func = function(configurable)
return optionsutil.enableIfEquals(configurable, "text_wrap", 1) return optionsutil.enableIfEquals(configurable, "text_wrap", 1)
end, end,

@ -7,7 +7,7 @@ local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
-- Date at which the last migration snippet was added -- Date at which the last migration snippet was added
local CURRENT_MIGRATION_DATE = 20220914 local CURRENT_MIGRATION_DATE = 20220922
-- Retrieve the date of the previous migration, if any -- Retrieve the date of the previous migration, if any
local last_migration_date = G_reader_settings:readSetting("last_migration_date", 0) local last_migration_date = G_reader_settings:readSetting("last_migration_date", 0)
@ -446,5 +446,34 @@ if last_migration_date < 20220914 then
end end
end end
-- The great defaults.persistent.lua migration to LuaDefaults
if last_migration_date < 20220922 then
logger.info("Performing one-time migration for 20220922")
local defaults_path = DataStorage:getDataDir() .. "/defaults.persistent.lua"
local defaults = {}
local load_defaults, err = loadfile(defaults_path, "t", defaults)
if not load_defaults then
logger.warn("loadfile:", err)
else
load_defaults()
end
for k, v in pairs(defaults) do
-- Don't migrate deprecated settings
if G_defaults:has(k) then
G_defaults:saveSetting(k, v)
end
end
G_defaults:flush()
local archived_path = DataStorage:getDataDir() .. "/defaults.legacy.lua"
local ok
ok, err = os.rename(defaults_path, archived_path)
if not ok then
logger.warn("os.rename:", err)
end
end
-- We're done, store the current migration date -- We're done, store the current migration date
G_reader_settings:saveSetting("last_migration_date", CURRENT_MIGRATION_DATE) G_reader_settings:saveSetting("last_migration_date", CURRENT_MIGRATION_DATE)

@ -3,6 +3,7 @@ local Device = require("device")
local InfoMessage = require("ui/widget/infomessage") local InfoMessage = require("ui/widget/infomessage")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local Version = require("version") local Version = require("version")
local lfs = require("libs/libkoreader-lfs")
local _ = require("gettext") local _ = require("gettext")
local T = require("ffi/util").template local T = require("ffi/util").template

@ -28,7 +28,7 @@ genTapZonesMenu("left_right")
genTapZonesMenu("top_bottom") genTapZonesMenu("top_bottom")
table.insert(page_turns_tap_zones_sub_items, { table.insert(page_turns_tap_zones_sub_items, {
text_func = function() text_func = function()
local size = math.floor(G_reader_settings:readSetting("page_turns_tap_zone_forward_size_ratio", DTAP_ZONE_FORWARD.w) * 100) local size = math.floor(G_reader_settings:readSetting("page_turns_tap_zone_forward_size_ratio", G_defaults:readSetting("DTAP_ZONE_FORWARD").w) * 100)
return T(_("Forward tap zone size: %1%"), size) return T(_("Forward tap zone size: %1%"), size)
end, end,
enabled_func = function() enabled_func = function()
@ -37,14 +37,14 @@ table.insert(page_turns_tap_zones_sub_items, {
keep_menu_open = true, keep_menu_open = true,
callback = function(touchmenu_instance) callback = function(touchmenu_instance)
local is_left_right = G_reader_settings:readSetting("page_turns_tap_zones") == "left_right" local is_left_right = G_reader_settings:readSetting("page_turns_tap_zones") == "left_right"
local size = math.floor(G_reader_settings:readSetting("page_turns_tap_zone_forward_size_ratio", DTAP_ZONE_FORWARD.w) * 100) local size = math.floor(G_reader_settings:readSetting("page_turns_tap_zone_forward_size_ratio", G_defaults:readSetting("DTAP_ZONE_FORWARD").w) * 100)
UIManager:show(require("ui/widget/spinwidget"):new{ UIManager:show(require("ui/widget/spinwidget"):new{
title_text = is_left_right and _("Forward tap zone width") or _("Forward tap zone height"), title_text = is_left_right and _("Forward tap zone width") or _("Forward tap zone height"),
info_text = is_left_right and _("Percentage of screen width") or _("Percentage of screen height"), info_text = is_left_right and _("Percentage of screen width") or _("Percentage of screen height"),
value = size, value = size,
value_min = 0, value_min = 0,
value_max = 100, value_max = 100,
default_value = math.floor(DTAP_ZONE_FORWARD.w * 100), default_value = math.floor(G_defaults:readSetting("DTAP_ZONE_FORWARD").w * 100),
callback = function(spin) callback = function(spin)
G_reader_settings:saveSetting("page_turns_tap_zone_forward_size_ratio", spin.value / 100) G_reader_settings:saveSetting("page_turns_tap_zone_forward_size_ratio", spin.value / 100)
ReaderUI.instance.view:setupTouchZones() ReaderUI.instance.view:setupTouchZones()

@ -707,9 +707,9 @@ function NetworkMgr:setWirelessBackend(name, options)
require("ui/network/"..name).init(self, options) require("ui/network/"..name).init(self, options)
end end
-- set network proxy if global variable NETWORK_PROXY is defined -- set network proxy if global variable G_defaults:readSetting("NETWORK_PROXY") is defined
if NETWORK_PROXY then if G_defaults:readSetting("NETWORK_PROXY") then
NetworkMgr:setHTTPProxy(NETWORK_PROXY) NetworkMgr:setHTTPProxy(G_defaults:readSetting("NETWORK_PROXY"))
end end

@ -104,7 +104,7 @@ end
-- @int height requested height -- @int height requested height
-- @treturn BlitBuffer -- @treturn BlitBuffer
function RenderImage:renderSVGImageDataWithCRengine(data, size, width, height) function RenderImage:renderSVGImageDataWithCRengine(data, size, width, height)
require("document/credocument"):engineInit() local cre = require("document/credocument"):engineInit()
local image_data, image_w, image_h = cre.renderImageData(data, size, width, height) local image_data, image_w, image_h = cre.renderImageData(data, size, width, height)
if not image_data then if not image_data then
logger.warn("failed rendering image (SVG/CRengine)") logger.warn("failed rendering image (SVG/CRengine)")

@ -240,11 +240,12 @@ end
function Screensaver:chooseFolder() function Screensaver:chooseFolder()
local buttons = {} local buttons = {}
local choose_dialog
table.insert(buttons, { table.insert(buttons, {
{ {
text = _("Choose screensaver folder"), text = _("Choose screensaver folder"),
callback = function() callback = function()
UIManager:close(self.choose_dialog) UIManager:close(choose_dialog)
require("ui/downloadmgr"):new{ require("ui/downloadmgr"):new{
onConfirm = function(path) onConfirm = function(path)
logger.dbg("set screensaver directory to", path) logger.dbg("set screensaver directory to", path)
@ -262,27 +263,28 @@ function Screensaver:chooseFolder()
{ {
text = _("Close"), text = _("Close"),
callback = function() callback = function()
UIManager:close(self.choose_dialog) UIManager:close(choose_dialog)
end, end,
} }
}) })
local screensaver_dir = G_reader_settings:readSetting("screensaver_dir") local screensaver_dir = G_reader_settings:readSetting("screensaver_dir")
or _("N/A") or _("N/A")
self.choose_dialog = ButtonDialogTitle:new{ choose_dialog = ButtonDialogTitle:new{
title = T(_("Current screensaver image folder:\n%1"), BD.dirpath(screensaver_dir)), title = T(_("Current screensaver image folder:\n%1"), BD.dirpath(screensaver_dir)),
buttons = buttons buttons = buttons
} }
UIManager:show(self.choose_dialog) UIManager:show(choose_dialog)
end end
function Screensaver:chooseFile(document_cover) function Screensaver:chooseFile(document_cover)
local text = document_cover and _("Choose document cover") or _("Choose screensaver image") local text = document_cover and _("Choose document cover") or _("Choose screensaver image")
local buttons = {} local buttons = {}
local choose_dialog
table.insert(buttons, { table.insert(buttons, {
{ {
text = text, text = text,
callback = function() callback = function()
UIManager:close(self.choose_dialog) UIManager:close(choose_dialog)
local PathChooser = require("ui/widget/pathchooser") local PathChooser = require("ui/widget/pathchooser")
local path_chooser = PathChooser:new{ local path_chooser = PathChooser:new{
select_directory = false, select_directory = false,
@ -319,7 +321,7 @@ function Screensaver:chooseFile(document_cover)
{ {
text = _("Close"), text = _("Close"),
callback = function() callback = function()
UIManager:close(self.choose_dialog) UIManager:close(choose_dialog)
end, end,
} }
}) })
@ -329,11 +331,11 @@ function Screensaver:chooseFile(document_cover)
or _("N/A") or _("N/A")
local title = document_cover and T(_("Current screensaver document cover:\n%1"), BD.filepath(screensaver_document_cover)) local title = document_cover and T(_("Current screensaver document cover:\n%1"), BD.filepath(screensaver_document_cover))
or T(_("Current screensaver image:\n%1"), BD.filepath(screensaver_image)) or T(_("Current screensaver image:\n%1"), BD.filepath(screensaver_image))
self.choose_dialog = ButtonDialogTitle:new{ choose_dialog = ButtonDialogTitle:new{
title = title, title = title,
buttons = buttons buttons = buttons
} }
UIManager:show(self.choose_dialog) UIManager:show(choose_dialog)
end end
function Screensaver:isExcluded() function Screensaver:isExcluded()
@ -362,7 +364,8 @@ function Screensaver:setMessage()
local InputDialog = require("ui/widget/inputdialog") local InputDialog = require("ui/widget/inputdialog")
local screensaver_message = G_reader_settings:readSetting("screensaver_message") local screensaver_message = G_reader_settings:readSetting("screensaver_message")
or self.default_screensaver_message or self.default_screensaver_message
self.input_dialog = InputDialog:new{ local input_dialog
input_dialog = InputDialog:new{
title = "Screensaver message", title = "Screensaver message",
description = _("Enter the message to be displayed by the screensaver. The following escape sequences can be used:\n %p percentage read\n %c current page number\n %t total number of pages\n %T title\n %A authors\n %S series\n %h time left in chapter\n %H time left in document"), description = _("Enter the message to be displayed by the screensaver. The following escape sequences can be used:\n %p percentage read\n %c current page number\n %t total number of pages\n %T title\n %A authors\n %S series\n %h time left in chapter\n %H time left in document"),
input = screensaver_message, input = screensaver_message,
@ -372,22 +375,22 @@ function Screensaver:setMessage()
text = _("Cancel"), text = _("Cancel"),
id = "close", id = "close",
callback = function() callback = function()
UIManager:close(self.input_dialog) UIManager:close(input_dialog)
end, end,
}, },
{ {
text = _("Set message"), text = _("Set message"),
is_enter_default = true, is_enter_default = true,
callback = function() callback = function()
G_reader_settings:saveSetting("screensaver_message", self.input_dialog:getInputText()) G_reader_settings:saveSetting("screensaver_message", input_dialog:getInputText())
UIManager:close(self.input_dialog) UIManager:close(input_dialog)
end, end,
}, },
}, },
}, },
} }
UIManager:show(self.input_dialog) UIManager:show(input_dialog)
self.input_dialog:onShowKeyboard() input_dialog:onShowKeyboard()
end end
function Screensaver:setStretchLimit(touchmenu_instance) function Screensaver:setStretchLimit(touchmenu_instance)
@ -462,29 +465,24 @@ function Screensaver:setup(event, fallback_message)
end end
end end
-- Reset state
self.lastfile = nil
self.image = nil
self.image_file = nil
-- Check lastfile and setup the requested mode's resources, or a fallback mode if the required resources are unavailable. -- Check lastfile and setup the requested mode's resources, or a fallback mode if the required resources are unavailable.
local ReaderUI = require("apps/reader/readerui") local ReaderUI = require("apps/reader/readerui")
local ui = ReaderUI:_getRunningInstance() local ui = ReaderUI:_getRunningInstance()
self.lastfile = G_reader_settings:readSetting("lastfile") local lastfile = G_reader_settings:readSetting("lastfile")
if self.screensaver_type == "document_cover" then if self.screensaver_type == "document_cover" then
-- Set lastfile to the document of which we want to show the cover. -- Set lastfile to the document of which we want to show the cover.
self.lastfile = G_reader_settings:readSetting("screensaver_document_cover") lastfile = G_reader_settings:readSetting("screensaver_document_cover")
self.screensaver_type = "cover" self.screensaver_type = "cover"
end end
if self.screensaver_type == "cover" then if self.screensaver_type == "cover" then
self.lastfile = self.lastfile ~= nil and self.lastfile or G_reader_settings:readSetting("lastfile") lastfile = lastfile ~= nil and lastfile or G_reader_settings:readSetting("lastfile")
local excluded local excluded
if DocSettings:hasSidecarFile(self.lastfile) then if DocSettings:hasSidecarFile(lastfile) then
local doc_settings local doc_settings
if ui and ui.doc_settings then if ui and ui.doc_settings then
doc_settings = ui.doc_settings doc_settings = ui.doc_settings
else else
doc_settings = DocSettings:open(self.lastfile) doc_settings = DocSettings:open(lastfile)
end end
excluded = doc_settings:isTrue("exclude_screensaver") excluded = doc_settings:isTrue("exclude_screensaver")
else else
@ -492,12 +490,12 @@ function Screensaver:setup(event, fallback_message)
excluded = false excluded = false
end end
if not excluded then if not excluded then
if self.lastfile and lfs.attributes(self.lastfile, "mode") == "file" then if lastfile and lfs.attributes(lastfile, "mode") == "file" then
if ui and ui.document then if ui and ui.document then
local doc = ui.document local doc = ui.document
self.image = doc:getCoverPageImage() self.image = doc:getCoverPageImage()
else else
local doc = DocumentRegistry:openDocument(self.lastfile) local doc = DocumentRegistry:openDocument(lastfile)
if doc.loadDocument then -- CreDocument if doc.loadDocument then -- CreDocument
doc:loadDocument(false) -- load only metadata doc:loadDocument(false) -- load only metadata
end end
@ -516,7 +514,7 @@ function Screensaver:setup(event, fallback_message)
end end
end end
if self.screensaver_type == "bookstatus" then if self.screensaver_type == "bookstatus" then
if self.lastfile and lfs.attributes(self.lastfile, "mode") == "file" then if lastfile and lfs.attributes(lastfile, "mode") == "file" then
if not ui then if not ui then
self.screensaver_type = "disable" self.screensaver_type = "disable"
self.show_message = true self.show_message = true
@ -748,19 +746,26 @@ function Screensaver:show()
} }
self.screensaver_widget.modal = true self.screensaver_widget.modal = true
self.screensaver_widget.dithered = true self.screensaver_widget.dithered = true
-- NOTE: ScreenSaver itself is not a widget, so make sure we cleanup behind us...
self.screensaver_widget.onCloseWidget = function(this)
-- this is self.screensaver_widget (i.e., an object instantiated from ScreenSaverWidget)
local super = getmetatable(this)
-- super is the class object of self.screensaver_widget (i.e., ScreenSaverWidget)
if super.onCloseWidget then
super.onCloseWidget(this)
end
-- self is ScreenSaver (upvalue)
self:cleanup()
end
UIManager:show(self.screensaver_widget, "full") UIManager:show(self.screensaver_widget, "full")
end end
end end
function Screensaver:close_widget() function Screensaver:close_widget()
logger.dbg("close screensaver")
if self.screensaver_widget then if self.screensaver_widget then
UIManager:close(self.screensaver_widget) UIManager:close(self.screensaver_widget)
self.screensaver_widget = nil
end
if self.delayed_close then
self.delayed_close = nil
end end
end end
@ -788,4 +793,19 @@ function Screensaver:close()
end end
end end
function Screensaver:cleanup()
self.show_message = nil
self.screensaver_type = nil
self.prefix = nil
self.fallback_message = nil
self.overlay_message = nil
self.screensaver_background = nil
self.image = nil
self.image_file = nil
self.delayed_close = nil
self.screensaver_widget = nil
end
return Screensaver return Screensaver

@ -1433,7 +1433,7 @@ function UIManager:onRotation()
end end
function UIManager:initLooper() function UIManager:initLooper()
if DUSE_TURBO_LIB and not self.looper then if G_defaults:readSetting("DUSE_TURBO_LIB") and not self.looper then
TURBO_SSL = true -- luacheck: ignore TURBO_SSL = true -- luacheck: ignore
__TURBO_USE_LUASOCKET__ = true -- luacheck: ignore __TURBO_USE_LUASOCKET__ = true -- luacheck: ignore
local turbo = require("turbo") local turbo = require("turbo")

@ -33,6 +33,8 @@ local _ = require("gettext")
local Screen = Device.screen local Screen = Device.screen
local logger = require("logger") local logger = require("logger")
local DGENERIC_ICON_SIZE = G_defaults:readSetting("DGENERIC_ICON_SIZE")
local Button = InputContainer:new{ local Button = InputContainer:new{
text = nil, -- mandatory (unless icon is provided) text = nil, -- mandatory (unless icon is provided)
text_func = nil, text_func = nil,

@ -33,6 +33,8 @@ local _ = require("gettext")
local Screen = Device.screen local Screen = Device.screen
local T = require("ffi/util").template local T = require("ffi/util").template
local DGENERIC_ICON_SIZE = G_defaults:readSetting("DGENERIC_ICON_SIZE")
local OptionTextItem = InputContainer:new{} local OptionTextItem = InputContainer:new{}
function OptionTextItem:init() function OptionTextItem:init()
@ -547,7 +549,7 @@ function ConfigOption:init()
or max_toggle_width or max_toggle_width
local row_count = self.options[c].row_count or 1 local row_count = self.options[c].row_count or 1
local toggle_height = Screen:scaleBySize(self.options[c].height local toggle_height = Screen:scaleBySize(self.options[c].height
or 30 * row_count) or (30 * row_count))
if self.options[c].more_options then if self.options[c].more_options then
table.insert(self.options[c].toggle, "") table.insert(self.options[c].toggle, "")
table.insert(self.options[c].args, "") table.insert(self.options[c].args, "")
@ -1458,12 +1460,14 @@ function ConfigDialog:onTapCloseMenu(arg, ges_ev)
end end
function ConfigDialog:onSwipeCloseMenu(arg, ges_ev) function ConfigDialog:onSwipeCloseMenu(arg, ges_ev)
local DTAP_ZONE_CONFIG = G_defaults:readSetting("DTAP_ZONE_CONFIG")
local range = Geom:new{ local range = Geom:new{
x = DTAP_ZONE_CONFIG.x * Screen:getWidth(), x = DTAP_ZONE_CONFIG.x * Screen:getWidth(),
y = DTAP_ZONE_CONFIG.y * Screen:getHeight(), y = DTAP_ZONE_CONFIG.y * Screen:getHeight(),
w = DTAP_ZONE_CONFIG.w * Screen:getWidth(), w = DTAP_ZONE_CONFIG.w * Screen:getWidth(),
h = DTAP_ZONE_CONFIG.h * Screen:getHeight(), h = DTAP_ZONE_CONFIG.h * Screen:getHeight(),
} }
local DTAP_ZONE_CONFIG_EXT = G_defaults:readSetting("DTAP_ZONE_CONFIG_EXT")
local range_ext = Geom:new{ local range_ext = Geom:new{
x = DTAP_ZONE_CONFIG_EXT.x * Screen:getWidth(), x = DTAP_ZONE_CONFIG_EXT.x * Screen:getWidth(),
y = DTAP_ZONE_CONFIG_EXT.y * Screen:getHeight(), y = DTAP_ZONE_CONFIG_EXT.y * Screen:getHeight(),

@ -71,7 +71,7 @@ local _ = require("gettext")
local Screen = Device.screen local Screen = Device.screen
local T = require("ffi/util").template local T = require("ffi/util").template
local DateTimeWidget = FocusManager:new{ local DateTimeWidget = FocusManager:extend{
title_face = Font:getFace("x_smalltfont"), title_face = Font:getFace("x_smalltfont"),
info_text = nil, info_text = nil,
width = nil, width = nil,
@ -137,24 +137,21 @@ function DateTimeWidget:init()
self:createLayout() self:createLayout()
end end
-- Just a dummy with no operation
local dummy_widget = {}
function dummy_widget:free() end
function dummy_widget:getValue() end
function dummy_widget:update() end
local year_widget, month_widget, day_widget, hour_widget, min_widget, sec_widget
local separator_date, separator_date_time, separator_time
function DateTimeWidget:createLayout() function DateTimeWidget:createLayout()
-- the following calculation is stolen from NumberPickerWidget -- Empty table w/ the methods we use NOP'ed
local dummy_widget = {}
function dummy_widget:free() end
function dummy_widget:getValue() end
function dummy_widget:update() end
-- The following calculation is stolen from NumberPickerWidget
local number_picker_widgets_width = math.floor(math.min(self.screen_width, self.screen_height) * 0.2) local number_picker_widgets_width = math.floor(math.min(self.screen_width, self.screen_height) * 0.2)
if self.nb_pickers > 3 then if self.nb_pickers > 3 then
number_picker_widgets_width = math.floor(number_picker_widgets_width * 3 / self.nb_pickers) number_picker_widgets_width = math.floor(number_picker_widgets_width * 3 / self.nb_pickers)
end end
if self.year then if self.year then
year_widget = NumberPickerWidget:new{ self.year_widget = NumberPickerWidget:new{
show_parent = self, show_parent = self,
value = self.year, value = self.year,
value_min = self.year_min or 2021, value_min = self.year_min or 2021,
@ -163,12 +160,12 @@ function DateTimeWidget:createLayout()
value_hold_step = self.year_hold_step or 4, value_hold_step = self.year_hold_step or 4,
width = number_picker_widgets_width, width = number_picker_widgets_width,
} }
self:mergeLayoutInHorizontal(year_widget) self:mergeLayoutInHorizontal(self.year_widget)
else else
year_widget = dummy_widget self.year_widget = dummy_widget
end end
if self.month then if self.month then
month_widget = NumberPickerWidget:new{ self.month_widget = NumberPickerWidget:new{
show_parent = self, show_parent = self,
value = self.month, value = self.month,
value_min = self.month_min or 1, value_min = self.month_min or 1,
@ -177,12 +174,12 @@ function DateTimeWidget:createLayout()
value_hold_step = self.month_hold_step or 3, value_hold_step = self.month_hold_step or 3,
width = number_picker_widgets_width, width = number_picker_widgets_width,
} }
self:mergeLayoutInHorizontal(month_widget) self:mergeLayoutInHorizontal(self.month_widget)
else else
month_widget = dummy_widget self.month_widget = dummy_widget
end end
if self.day then if self.day then
day_widget = NumberPickerWidget:new{ self.day_widget = NumberPickerWidget:new{
show_parent = self, show_parent = self,
value = self.day, value = self.day,
value_min = self.day_min or 1, value_min = self.day_min or 1,
@ -191,13 +188,13 @@ function DateTimeWidget:createLayout()
value_hold_step = self.day_hold_step or 3, value_hold_step = self.day_hold_step or 3,
width = number_picker_widgets_width, width = number_picker_widgets_width,
} }
self:mergeLayoutInHorizontal(day_widget) self:mergeLayoutInHorizontal(self.day_widget)
else else
day_widget = dummy_widget self.day_widget = dummy_widget
end end
if self.hour then if self.hour then
hour_widget = NumberPickerWidget:new{ self.hour_widget = NumberPickerWidget:new{
show_parent = self, show_parent = self,
value = self.hour, value = self.hour,
value_min = self.hour_min or 0, value_min = self.hour_min or 0,
@ -206,12 +203,12 @@ function DateTimeWidget:createLayout()
value_hold_step = self.hour_hold_step or 4, value_hold_step = self.hour_hold_step or 4,
width = number_picker_widgets_width, width = number_picker_widgets_width,
} }
self:mergeLayoutInHorizontal(hour_widget) self:mergeLayoutInHorizontal(self.hour_widget)
else else
hour_widget = dummy_widget self.hour_widget = dummy_widget
end end
if self.min then if self.min then
min_widget = NumberPickerWidget:new{ self.min_widget = NumberPickerWidget:new{
show_parent = self, show_parent = self,
value = self.min, value = self.min,
value_min = self.min_min or 0, value_min = self.min_min or 0,
@ -220,12 +217,12 @@ function DateTimeWidget:createLayout()
value_hold_step = self.min_hold_step or 10, value_hold_step = self.min_hold_step or 10,
width = number_picker_widgets_width, width = number_picker_widgets_width,
} }
self:mergeLayoutInHorizontal(min_widget) self:mergeLayoutInHorizontal(self.min_widget)
else else
min_widget = dummy_widget self.min_widget = dummy_widget
end end
if self.sec then if self.sec then
sec_widget = NumberPickerWidget:new{ self.sec_widget = NumberPickerWidget:new{
show_parent = self, show_parent = self,
value = self.sec, value = self.sec,
value_min = self.sec_min or 0, value_min = self.sec_min or 0,
@ -234,39 +231,39 @@ function DateTimeWidget:createLayout()
value_hold_step = self.sec_hold_step or 10, value_hold_step = self.sec_hold_step or 10,
width = number_picker_widgets_width, width = number_picker_widgets_width,
} }
self:mergeLayoutInHorizontal(sec_widget) self:mergeLayoutInHorizontal(self.sec_widget)
else else
sec_widget = dummy_widget self.sec_widget = dummy_widget
end end
separator_date = TextWidget:new{ local separator_date = TextWidget:new{
text = "", text = "",
face = self.title_face, face = self.title_face,
bold = true, bold = true,
} }
separator_time = TextWidget:new{ local separator_time = TextWidget:new{
text = ":", text = ":",
face = self.title_face, face = self.title_face,
bold = true, bold = true,
} }
separator_date_time = TextWidget:new{ local separator_date_time = TextWidget:new{
text = "/", text = "/",
face = self.title_face, face = self.title_face,
bold = true, bold = true,
} }
local date_group = HorizontalGroup:new{ local date_group = HorizontalGroup:new{
align = "center", align = "center",
year_widget, -- 1 self.year_widget, -- 1
separator_date, -- 2 separator_date, -- 2
month_widget, -- 3 self.month_widget, -- 3
separator_date, -- 4 separator_date, -- 4
day_widget, -- 5 self.day_widget, -- 5
separator_date_time, -- 6 separator_date_time, -- 6
hour_widget, -- 7 self.hour_widget, -- 7
separator_time, -- 8 separator_time, -- 8
min_widget, -- 9 self.min_widget, -- 9
separator_time, -- 10 separator_time, -- 10
sec_widget, -- 11 self.sec_widget, -- 11
} }
-- remove empty widgets plus trailling placeholder -- remove empty widgets plus trailling placeholder
@ -300,12 +297,12 @@ function DateTimeWidget:createLayout()
callback = function() callback = function()
if self.default_callback then if self.default_callback then
self.default_callback({ self.default_callback({
year = year_widget:getValue(), year = self.year_widget:getValue(),
month = month_widget:getValue(), month = self.month_widget:getValue(),
day = day_widget:getValue(), day = self.day_widget:getValue(),
hour = hour_widget:getValue(), hour = self.hour_widget:getValue(),
minute = min_widget:getValue(), minute = self.min_widget:getValue(),
second = sec_widget:getValue(), second = self.sec_widget:getValue(),
}) })
end end
if not self.keep_shown_on_apply then -- assume extra wants it same as ok if not self.keep_shown_on_apply then -- assume extra wants it same as ok
@ -339,12 +336,12 @@ function DateTimeWidget:createLayout()
text = self.ok_text, text = self.ok_text,
callback = function() callback = function()
if self.callback then if self.callback then
self.year = year_widget:getValue() self.year = self.year_widget:getValue()
self.month = month_widget:getValue() self.month = self.month_widget:getValue()
self.day = day_widget:getValue() self.day = self.day_widget:getValue()
self.hour = hour_widget:getValue() self.hour = self.hour_widget:getValue()
self.min = min_widget:getValue() self.min = self.min_widget:getValue()
self.sec = sec_widget:getValue() self.sec = self.sec_widget:getValue()
self:callback(self) self:callback(self)
end end
self:onClose() self:onClose()
@ -405,30 +402,23 @@ function DateTimeWidget:createLayout()
end end
function DateTimeWidget:update(year, month, day, hour, min, sec) function DateTimeWidget:update(year, month, day, hour, min, sec)
year_widget.value = year self.year_widget.value = year
year_widget:update() self.year_widget:update()
month_widget.value = month self.month_widget.value = month
month_widget:update() self.month_widget:update()
day_widget.value = day self.day_widget.value = day
day_widget:update() self.day_widget:update()
hour_widget.value = hour self.hour_widget.value = hour
hour_widget:update() self.hour_widget:update()
min_widget.value = min self.min_widget.value = min
min_widget:update() self.min_widget:update()
sec_widget.value = sec self.sec_widget.value = sec
sec_widget:update() self.sec_widget:update()
end end
function DateTimeWidget:onCloseWidget() function DateTimeWidget:onCloseWidget()
year_widget:free() -- Let our main WidgetContainer free its child widgets
month_widget:free() self[1]:free()
day_widget:free()
hour_widget:free()
min_widget:free()
sec_widget:free()
separator_date:free()
separator_date_time:free()
separator_time:free()
UIManager:setDirty(nil, function() UIManager:setDirty(nil, function()
return "ui", self.date_frame.dimen return "ui", self.date_frame.dimen

@ -217,6 +217,7 @@ function FootnoteWidget:init()
local font_css = "" local font_css = ""
if G_reader_settings:isTrue("footnote_popup_use_book_font") then if G_reader_settings:isTrue("footnote_popup_use_book_font") then
local cre = require("document/credocument"):engineInit()
-- Note: we can't provide any base weight (as supported by crengine), as MuPDF -- Note: we can't provide any base weight (as supported by crengine), as MuPDF
-- will use the bold font for anything with a weight > 400. We can only use the -- will use the bold font for anything with a weight > 400. We can only use the
-- font as-is, without its natural weight tweaked. -- font as-is, without its natural weight tweaked.

@ -13,6 +13,8 @@ local VerticalGroup = require("ui/widget/verticalgroup")
local VerticalSpan = require("ui/widget/verticalspan") local VerticalSpan = require("ui/widget/verticalspan")
local Screen = Device.screen local Screen = Device.screen
local DGENERIC_ICON_SIZE = G_defaults:readSetting("DGENERIC_ICON_SIZE")
local IconButton = InputContainer:new{ local IconButton = InputContainer:new{
icon = "notice-warning", icon = "notice-warning",
icon_rotation_angle = 0, icon_rotation_angle = 0,

@ -5,6 +5,9 @@ Subclass of ImageWidget to show icons
local DataStorage = require("datastorage") local DataStorage = require("datastorage")
local ImageWidget = require("ui/widget/imagewidget") local ImageWidget = require("ui/widget/imagewidget")
local Screen = require("device").screen local Screen = require("device").screen
local lfs = require("libs/libkoreader-lfs")
local DGENERIC_ICON_SIZE = G_defaults:readSetting("DGENERIC_ICON_SIZE")
-- Directories to look for icons by name, with any of the accepted suffixes -- Directories to look for icons by name, with any of the accepted suffixes
local ICONS_DIRS = {} local ICONS_DIRS = {}

@ -408,7 +408,7 @@ function ImageViewer:_new_image_wg()
-- in portrait mode, rotate according to this global setting so we are -- in portrait mode, rotate according to this global setting so we are
-- like in landscape mode -- like in landscape mode
-- NOTE: This is the sole user of this legacy global left! -- NOTE: This is the sole user of this legacy global left!
local rotate_clockwise = DLANDSCAPE_CLOCKWISE_ROTATION local rotate_clockwise = G_defaults:readSetting("DLANDSCAPE_CLOCKWISE_ROTATION")
if Screen:getWidth() > Screen:getHeight() then if Screen:getWidth() > Screen:getHeight() then
-- in landscape mode, counter-rotate landscape rotation so we are -- in landscape mode, counter-rotate landscape rotation so we are
-- back like in portrait mode -- back like in portrait mode

@ -32,7 +32,7 @@ local _ = require("gettext")
local T = require("ffi/util").template local T = require("ffi/util").template
local Screen = Device.screen local Screen = Device.screen
local NumberPickerWidget = FocusManager:new{ local NumberPickerWidget = FocusManager:extend{
spinner_face = Font:getFace("smalltfont"), spinner_face = Font:getFace("smalltfont"),
precision = "%02d", precision = "%02d",
width = nil, width = nil,

@ -162,7 +162,6 @@ function ScreenSaverWidget:onClose()
local Screensaver = require("ui/screensaver") local Screensaver = require("ui/screensaver")
if Screensaver.delayed_close then if Screensaver.delayed_close then
UIManager:unschedule(Screensaver.close_widget) UIManager:unschedule(Screensaver.close_widget)
Screensaver.delayed_close = nil
end end
UIManager:close(self) UIManager:close(self)

@ -30,6 +30,7 @@ local logger = require("logger")
local dbg = require("dbg") local dbg = require("dbg")
local time = require("ui/time") local time = require("ui/time")
local util = require("util") local util = require("util")
local xtext -- Delayed (and optional) loading
local Screen = require("device").screen local Screen = require("device").screen
local TextBoxWidget = InputContainer:new{ local TextBoxWidget = InputContainer:new{
@ -244,7 +245,7 @@ end
function TextBoxWidget:_measureWithXText() function TextBoxWidget:_measureWithXText()
if not self._xtext_loaded then if not self._xtext_loaded then
require("libs/libkoreader-xtext") xtext = require("libs/libkoreader-xtext")
TextBoxWidget._xtext_loaded = true TextBoxWidget._xtext_loaded = true
end end
if type(self.charlist) == "table" then if type(self.charlist) == "table" then
@ -819,7 +820,7 @@ function TextBoxWidget:_renderText(start_row_idx, end_row_idx)
end end
self:_shapeLine(line) self:_shapeLine(line)
if line.xglyphs then -- non-empty line if line.xglyphs then -- non-empty line
for __, xglyph in ipairs(line.xglyphs) do for _, xglyph in ipairs(line.xglyphs) do
if not xglyph.no_drawing then if not xglyph.no_drawing then
local face = self.face.getFallbackFont(xglyph.font_num) -- callback (not a method) local face = self.face.getFallbackFont(xglyph.font_num) -- callback (not a method)
local glyph = RenderText:getGlyphByIndex(face, xglyph.glyph, self.bold) local glyph = RenderText:getGlyphByIndex(face, xglyph.glyph, self.bold)
@ -1854,8 +1855,6 @@ function TextBoxWidget:onHoldWord(callback, ges)
idx = idx + 1 idx = idx + 1
end end
end end
return
end end
-- Allow selection of one or more words (with no visual feedback) -- Allow selection of one or more words (with no visual feedback)

@ -22,6 +22,7 @@ local Widget = require("ui/widget/widget")
local Screen = require("device").screen local Screen = require("device").screen
local dbg = require("dbg") local dbg = require("dbg")
local util = require("util") local util = require("util")
local xtext -- Delayed (and optional) loading
local TextWidget = Widget:new{ local TextWidget = Widget:new{
text = nil, text = nil,
@ -183,7 +184,7 @@ dbg:guard(TextWidget, "updateSize",
function TextWidget:_measureWithXText() function TextWidget:_measureWithXText()
if not self._xtext_loaded then if not self._xtext_loaded then
require("libs/libkoreader-xtext") xtext = require("libs/libkoreader-xtext")
TextWidget._xtext_loaded = true TextWidget._xtext_loaded = true
end end
self._xtext = xtext.new(self.text, self.face, self.auto_para_direction, self._xtext = xtext.new(self.text, self.face, self.auto_para_direction,

@ -15,6 +15,8 @@ local VerticalGroup = require("ui/widget/verticalgroup")
local VerticalSpan = require("ui/widget/verticalspan") local VerticalSpan = require("ui/widget/verticalspan")
local Screen = Device.screen local Screen = Device.screen
local DGENERIC_ICON_SIZE = G_defaults:readSetting("DGENERIC_ICON_SIZE")
local TitleBar = OverlapGroup:extend{ local TitleBar = OverlapGroup:extend{
width = nil, -- default to screen width width = nil, -- default to screen width
fullscreen = false, -- larger font and small adjustments if fullscreen fullscreen = false, -- larger font and small adjustments if fullscreen

@ -34,6 +34,8 @@ local T = require("ffi/util").template
local Input = Device.input local Input = Device.input
local Screen = Device.screen local Screen = Device.screen
local DGENERIC_ICON_SIZE = G_defaults:readSetting("DGENERIC_ICON_SIZE")
--[[ --[[
TouchMenuItem widget TouchMenuItem widget
--]] --]]

@ -2,6 +2,7 @@ local JSON = require("json")
local RenderImage = require("ui/renderimage") local RenderImage = require("ui/renderimage")
local Screen = require("device").screen local Screen = require("device").screen
local ffiutil = require("ffi/util") local ffiutil = require("ffi/util")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
local util = require("util") local util = require("util")
local _ = require("gettext") local _ = require("gettext")

@ -4,6 +4,7 @@ This module contains miscellaneous helper functions for the KOReader frontend.
local BaseUtil = require("ffi/util") local BaseUtil = require("ffi/util")
local Utf8Proc = require("ffi/utf8proc") local Utf8Proc = require("ffi/utf8proc")
local lfs = require("libs/libkoreader-lfs")
local _ = require("gettext") local _ = require("gettext")
local C_ = _.pgettext local C_ = _.pgettext
local T = BaseUtil.template local T = BaseUtil.template
@ -332,7 +333,7 @@ function util.tableEquals(o1, o2, ignore_mt)
if not ignore_mt then if not ignore_mt then
local mt1 = getmetatable(o1) local mt1 = getmetatable(o1)
if mt1 and mt1.__eq then if mt1 and mt1.__eq then
--compare using built in method -- Compare using built in method
return o1 == o2 return o1 == o2
end end
end end
@ -873,7 +874,6 @@ end
---- @string path ---- @string path
---- @treturn bool ---- @treturn bool
function util.isEmptyDir(path) function util.isEmptyDir(path)
local lfs = require("libs/libkoreader-lfs")
-- lfs.dir will crash rather than return nil if directory doesn't exist O_o -- lfs.dir will crash rather than return nil if directory doesn't exist O_o
local ok, iter, dir_obj = pcall(lfs.dir, path) local ok, iter, dir_obj = pcall(lfs.dir, path)
if not ok then return end if not ok then return end
@ -900,7 +900,6 @@ end
---- @string path ---- @string path
---- @treturn bool ---- @treturn bool
function util.pathExists(path) function util.pathExists(path)
local lfs = require("libs/libkoreader-lfs")
return lfs.attributes(path, "mode") ~= nil return lfs.attributes(path, "mode") ~= nil
end end
@ -918,7 +917,6 @@ function util.makePath(path)
return nil, err.." (creating "..path..")" return nil, err.." (creating "..path..")"
end end
local lfs = require("libs/libkoreader-lfs")
return lfs.mkdir(path) return lfs.mkdir(path)
end end
@ -926,7 +924,6 @@ end
-- @string path of the file to remove -- @string path of the file to remove
-- @treturn bool true on success; nil, err_message on error -- @treturn bool true on success; nil, err_message on error
function util.removeFile(file) function util.removeFile(file)
local lfs = require("libs/libkoreader-lfs")
if file and lfs.attributes(file, "mode") == "file" then if file and lfs.attributes(file, "mode") == "file" then
return os.remove(file) return os.remove(file)
elseif file then elseif file then
@ -951,7 +948,6 @@ function util.diskUsage(dir)
end end
end end
local err = { total = nil, used = nil, available = nil } local err = { total = nil, used = nil, available = nil }
local lfs = require("libs/libkoreader-lfs")
if not dir or lfs.attributes(dir, "mode") ~= "directory" then return err end if not dir or lfs.attributes(dir, "mode") ~= "directory" then return err end
local usage = doCommand(dir) local usage = doCommand(dir)
if not usage then return err end if not usage then return err end
@ -1356,8 +1352,8 @@ function util.shell_escape(args)
return table.concat(escaped_args, " ") return table.concat(escaped_args, " ")
end end
--- Clear all the elements from a table without reassignment. --- Clear all the elements from an array without reassignment.
--- @table t the table to be cleared --- @table t the array to be cleared
function util.clearTable(t) function util.clearTable(t)
local c = #t local c = #t
for i = 0, c do t[i] = nil end for i = 0, c do t[i] = nil end
@ -1404,7 +1400,7 @@ function util.checkLuaSyntax(lua_text)
end end
-- Replace: [string "blah blah..."]:3: '=' expected near '123' -- Replace: [string "blah blah..."]:3: '=' expected near '123'
-- with: Line 3: '=' expected near '123' -- with: Line 3: '=' expected near '123'
err = err:gsub("%[string \".-%\"]:", "Line ") err = err and err:gsub("%[string \".-%\"]:", "Line ")
return err return err
end end

@ -404,7 +404,7 @@ function BookInfoManager:extractBookInfo(filepath, cover_specs)
-- We need to init engine (if no crengine book has yet been opened), -- We need to init engine (if no crengine book has yet been opened),
-- so it does not reset our temporary cache dir when we first open -- so it does not reset our temporary cache dir when we first open
-- a crengine book for extraction. -- a crengine book for extraction.
require("document/credocument"):engineInit() local cre = require("document/credocument"):engineInit()
-- If we wanted to disallow caching completely: -- If we wanted to disallow caching completely:
-- cre.initCache("", 1024*1024*32) -- empty path = no cache -- cre.initCache("", 1024*1024*32) -- empty path = no cache
-- But it's best to use a cache for quicker and less memory -- But it's best to use a cache for quicker and less memory

@ -14,6 +14,7 @@ local WidgetContainer = require("ui/widget/container/widgetcontainer")
local _ = require("gettext") local _ = require("gettext")
local T = FFIUtil.template local T = FFIUtil.template
local filemanagerutil = require("apps/filemanager/filemanagerutil") local filemanagerutil = require("apps/filemanager/filemanagerutil")
local lfs = require("libs/libkoreader-lfs")
local util = require("util") local util = require("util")
local DocSettingTweak = WidgetContainer:new{ local DocSettingTweak = WidgetContainer:new{
@ -51,6 +52,9 @@ end
function DocSettingTweak:editDirectoryDefaults() function DocSettingTweak:editDirectoryDefaults()
local directory_defaults_file = io.open(directory_defaults_path, "rb") local directory_defaults_file = io.open(directory_defaults_path, "rb")
if not directory_defaults_file then
return
end
local defaults = directory_defaults_file:read("*all") local defaults = directory_defaults_file:read("*all")
directory_defaults_file:close() directory_defaults_file:close()
local config_editor local config_editor
@ -74,6 +78,9 @@ function DocSettingTweak:editDirectoryDefaults()
local syntax_okay, syntax_error = pcall(loadstring(content)) local syntax_okay, syntax_error = pcall(loadstring(content))
if syntax_okay then if syntax_okay then
directory_defaults_file = io.open(directory_defaults_path, "w") directory_defaults_file = io.open(directory_defaults_path, "w")
if not directory_defaults_file then
return false, _("Missing defaults file")
end
directory_defaults_file:write(content) directory_defaults_file:write(content)
directory_defaults_file:close() directory_defaults_file:close()
DocSettingTweak:loadDefaults() DocSettingTweak:loadDefaults()

@ -1,6 +1,7 @@
local DocumentRegistry = require("document/documentregistry") local DocumentRegistry = require("document/documentregistry")
local DocSettings = require("docsettings") local DocSettings = require("docsettings")
local ReadHistory = require("readhistory") local ReadHistory = require("readhistory")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
local md5 = require("ffi/sha2").md5 local md5 = require("ffi/sha2").md5
local util = require("util") local util = require("util")

@ -15,12 +15,13 @@ local LuaSettings = require("luasettings")
local Screen = require("device").screen local Screen = require("device").screen
local SpinWidget = require("ui/widget/spinwidget") local SpinWidget = require("ui/widget/spinwidget")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger")
local util = require("util") local util = require("util")
local T = FFIUtil.template local T = FFIUtil.template
local time = require("ui/time") local time = require("ui/time")
local _ = require("gettext") local _ = require("gettext")
local C_ = _.pgettext local C_ = _.pgettext
local logger = require("logger")
if not Device:isTouchDevice() then if not Device:isTouchDevice() then
return { disabled = true, } return { disabled = true, }
@ -739,46 +740,48 @@ function Gestures:setupGesture(ges)
ratio_w = 1, ratio_h = 1/8, ratio_w = 1, ratio_h = 1/8,
} }
-- legacy global variable DTAP_ZONE_FLIPPING may still be defined in default.persistent.lua local dtap_zone_top_left = G_defaults:readSetting("DTAP_ZONE_TOP_LEFT")
local dtap_zone_top_left = DTAP_ZONE_FLIPPING and DTAP_ZONE_FLIPPING or DTAP_ZONE_TOP_LEFT
local zone_top_left_corner = { local zone_top_left_corner = {
ratio_x = dtap_zone_top_left.x, ratio_x = dtap_zone_top_left.x,
ratio_y = dtap_zone_top_left.y, ratio_y = dtap_zone_top_left.y,
ratio_w = dtap_zone_top_left.w, ratio_w = dtap_zone_top_left.w,
ratio_h = dtap_zone_top_left.h, ratio_h = dtap_zone_top_left.h,
} }
-- legacy global variable DTAP_ZONE_BOOKMARK may still be defined in default.persistent.lua local dtap_zone_top_right = G_defaults:readSetting("DTAP_ZONE_TOP_RIGHT")
local dtap_zone_top_right = DTAP_ZONE_BOOKMARK and DTAP_ZONE_BOOKMARK or DTAP_ZONE_TOP_RIGHT
local zone_top_right_corner = { local zone_top_right_corner = {
ratio_x = dtap_zone_top_right.x, ratio_x = dtap_zone_top_right.x,
ratio_y = dtap_zone_top_right.y, ratio_y = dtap_zone_top_right.y,
ratio_w = dtap_zone_top_right.w, ratio_w = dtap_zone_top_right.w,
ratio_h = dtap_zone_top_right.h, ratio_h = dtap_zone_top_right.h,
} }
local dtap_zone_bottom_left = G_defaults:readSetting("DTAP_ZONE_BOTTOM_LEFT")
local zone_bottom_left_corner = { local zone_bottom_left_corner = {
ratio_x = DTAP_ZONE_BOTTOM_LEFT.x, ratio_x = dtap_zone_bottom_left.x,
ratio_y = DTAP_ZONE_BOTTOM_LEFT.y, ratio_y = dtap_zone_bottom_left.y,
ratio_w = DTAP_ZONE_BOTTOM_LEFT.w, ratio_w = dtap_zone_bottom_left.w,
ratio_h = DTAP_ZONE_BOTTOM_LEFT.h, ratio_h = dtap_zone_bottom_left.h,
} }
local dtap_zone_bottom_right = G_defaults:readSetting("DTAP_ZONE_BOTTOM_RIGHT")
local zone_bottom_right_corner = { local zone_bottom_right_corner = {
ratio_x = DTAP_ZONE_BOTTOM_RIGHT.x, ratio_x = dtap_zone_bottom_right.x,
ratio_y = DTAP_ZONE_BOTTOM_RIGHT.y, ratio_y = dtap_zone_bottom_right.y,
ratio_w = DTAP_ZONE_BOTTOM_RIGHT.w, ratio_w = dtap_zone_bottom_right.w,
ratio_h = DTAP_ZONE_BOTTOM_RIGHT.h, ratio_h = dtap_zone_bottom_right.h,
} }
-- NOTE: The defaults are effectively mapped to DTAP_ZONE_BACKWARD & DTAP_ZONE_FORWARD -- NOTE: The defaults are effectively mapped to G_defaults:readSetting("DTAP_ZONE_BACKWARD") & G_defaults:readSetting("DTAP_ZONE_FORWARD")
local ddouble_tap_zone_prev_chapter = G_defaults:readSetting("DDOUBLE_TAP_ZONE_PREV_CHAPTER")
local zone_left = { local zone_left = {
ratio_x = DDOUBLE_TAP_ZONE_PREV_CHAPTER.x, ratio_x = ddouble_tap_zone_prev_chapter.x,
ratio_y = DDOUBLE_TAP_ZONE_PREV_CHAPTER.y, ratio_y = ddouble_tap_zone_prev_chapter.y,
ratio_w = DDOUBLE_TAP_ZONE_PREV_CHAPTER.w, ratio_w = ddouble_tap_zone_prev_chapter.w,
ratio_h = DDOUBLE_TAP_ZONE_PREV_CHAPTER.h, ratio_h = ddouble_tap_zone_prev_chapter.h,
} }
local ddouble_tap_zone_next_chapter = G_defaults:readSetting("DDOUBLE_TAP_ZONE_NEXT_CHAPTER")
local zone_right = { local zone_right = {
ratio_x = DDOUBLE_TAP_ZONE_NEXT_CHAPTER.x, ratio_x = ddouble_tap_zone_next_chapter.x,
ratio_y = DDOUBLE_TAP_ZONE_NEXT_CHAPTER.y, ratio_y = ddouble_tap_zone_next_chapter.y,
ratio_w = DDOUBLE_TAP_ZONE_NEXT_CHAPTER.w, ratio_w = ddouble_tap_zone_next_chapter.w,
ratio_h = DDOUBLE_TAP_ZONE_NEXT_CHAPTER.h, ratio_h = ddouble_tap_zone_next_chapter.h,
} }
local overrides_tap_corner local overrides_tap_corner

@ -1,6 +1,7 @@
local Version = require("version") local Version = require("version")
local ffiutil = require("ffi/util") local ffiutil = require("ffi/util")
local http = require("socket.http") local http = require("socket.http")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
local socket = require("socket") local socket = require("socket")

@ -16,6 +16,7 @@ local NetworkMgr = require("ui/network/manager")
local Persist = require("persist") local Persist = require("persist")
local WidgetContainer = require("ui/widget/container/widgetcontainer") local WidgetContainer = require("ui/widget/container/widgetcontainer")
local dateparser = require("lib.dateparser") local dateparser = require("lib.dateparser")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
local util = require("util") local util = require("util")
local _ = require("gettext") local _ = require("gettext")

@ -19,6 +19,7 @@ local Trapper = require("ui/trapper")
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
local WidgetContainer = require("ui/widget/container/widgetcontainer") local WidgetContainer = require("ui/widget/container/widgetcontainer")
local ffiutil = require("ffi/util") local ffiutil = require("ffi/util")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
local util = require("util") local util = require("util")
local _ = require("gettext") local _ = require("gettext")

@ -23,6 +23,7 @@ local UIManager = require("ui/uimanager")
local WidgetContainer = require("ui/widget/container/widgetcontainer") local WidgetContainer = require("ui/widget/container/widgetcontainer")
local filemanagerutil = require("apps/filemanager/filemanagerutil") local filemanagerutil = require("apps/filemanager/filemanagerutil")
local http = require("socket.http") local http = require("socket.http")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger") local logger = require("logger")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
local socket = require("socket") local socket = require("socket")

@ -21,18 +21,16 @@ local userpatch = require("userpatch")
userpatch.applyPatches(userpatch.early_once) userpatch.applyPatches(userpatch.early_once)
userpatch.applyPatches(userpatch.early) userpatch.applyPatches(userpatch.early)
-- Load default settings
require("defaults")
local DataStorage = require("datastorage")
pcall(dofile, DataStorage:getDataDir() .. "/defaults.persistent.lua")
io.stdout:write(" [*] Version: ", require("version"):getCurrentRevision(), "\n\n") io.stdout:write(" [*] Version: ", require("version"):getCurrentRevision(), "\n\n")
io.stdout:flush() io.stdout:flush()
-- Load default settings
G_defaults = require("luadefaults"):open()
-- Read settings and check for language override -- Read settings and check for language override
-- Has to be done before requiring other files because -- Has to be done before requiring other files because
-- they might call gettext on load -- they might call gettext on load
local DataStorage = require("datastorage")
G_reader_settings = require("luasettings"):open( G_reader_settings = require("luasettings"):open(
DataStorage:getDataDir().."/settings.reader.lua") DataStorage:getDataDir().."/settings.reader.lua")

@ -43,8 +43,13 @@ require("dbg"):turnOff()
local logger = require("logger") local logger = require("logger")
logger:setLevel(logger.levels.warn) logger:setLevel(logger.levels.warn)
-- global reader settings -- global defaults
local DataStorage = require("datastorage") local DataStorage = require("datastorage")
os.remove(DataStorage:getDataDir() .. "/defaults.tests.lua")
os.remove(DataStorage:getDataDir() .. "/defaults.tests.lua.old")
G_defaults = require("luadefaults"):open(DataStorage:getDataDir() .. "/defaults.tests.lua")
-- global reader settings
os.remove(DataStorage:getDataDir().."/settings.reader.lua") os.remove(DataStorage:getDataDir().."/settings.reader.lua")
G_reader_settings = require("luasettings"):open(".reader") G_reader_settings = require("luasettings"):open(".reader")

@ -1,101 +1,49 @@
describe("defaults module", function() describe("defaults module", function()
local Defaults, DataStorage local Defaults, DataStorage, lfs, persistent_filename
setup(function() setup(function()
require("commonrequire") require("commonrequire")
Defaults = require("apps/filemanager/filemanagersetdefaults")
DataStorage = require("datastorage") DataStorage = require("datastorage")
persistent_filename = DataStorage:getDataDir() .. "/defaults.defaults_spec.lua"
Defaults = require("luadefaults"):open(persistent_filename)
lfs = require("libs/libkoreader-lfs")
end) end)
it("should load all defaults from defaults.lua", function() it("should load all defaults from defaults.lua", function()
Defaults:init() assert.is_true(Defaults:has("DHINTCOUNT"))
assert.is_same(98, #Defaults.defaults_name) Defaults:close()
end) end)
it("should save changes to defaults.persistent.lua", function() it("should save changes to defaults.custom.lua", function()
local persistent_filename = DataStorage:getDataDir() .. "/defaults.persistent.lua"
os.remove(persistent_filename) os.remove(persistent_filename)
os.remove(persistent_filename .. ".old")
-- To see indices and help updating this when new settings are added: -- This defaults to false
-- for i=1, 98 do print(i.." ".. Defaults.defaults_name[i]) end Defaults:makeTrue("DSHOWOVERLAP")
assert.is_true(Defaults:hasBeenCustomized("DSHOWOVERLAP"))
assert.is_true(Defaults:isTrue("DSHOWOVERLAP"))
-- not in persistent but checked in defaults Defaults:close()
Defaults.changed[18] = true assert.is_true(lfs.attributes(persistent_filename, "mode") == "file")
Defaults.changed[48] = true
Defaults.changed[54] = true Defaults = nil
Defaults.changed[83] = true Defaults = require("luadefaults"):open(persistent_filename)
Defaults:saveSettings() assert.is_true(Defaults:hasBeenCustomized("DSHOWOVERLAP"))
assert.is_same(98, #Defaults.defaults_name) assert.is_true(Defaults:isTrue("DSHOWOVERLAP"))
assert.is_same("DTAP_ZONE_BACKWARD", Defaults.defaults_name[84]) Defaults:makeFalse("DSHOWOVERLAP")
assert.is_same("DCREREADER_CONFIG_WORD_SPACING_LARGE", Defaults.defaults_name[48]) Defaults:close()
assert.is_same("DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE", Defaults.defaults_name[18])
dofile(persistent_filename)
assert.is_same(DCREREADER_CONFIG_WORD_SPACING_LARGE, { [1] = 100, [2] = 90 })
assert.is_same(DTAP_ZONE_BACKWARD, { ["y"] = 0, ["x"] = 0, ["h"] = 1, ["w"] = 0.25 })
assert.is_same(DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE, { [1] = 50, [2] = 50 })
assert.is_same(DDOUBLE_TAP_ZONE_PREV_CHAPTER, { ["y"] = 0, ["x"] = 0, ["h"] = 1, ["w"] = 0.25 })
-- in persistent
Defaults:init()
Defaults.changed[54] = true
Defaults.defaults_value[54] = {
y = 0,
x = 0,
h = 0.25,
w = 0.75
}
Defaults.changed[84] = true
Defaults.defaults_value[84] = {
y = 10,
x = 10.125,
h = 20.25,
w = 20.75
}
Defaults:saveSettings()
dofile(persistent_filename)
assert.is_same(DCREREADER_CONFIG_WORD_SPACING_LARGE, { [2] = 90, [1] = 100 })
assert.is_same(DDOUBLE_TAP_ZONE_PREV_CHAPTER, {
["y"] = 0,
["x"] = 0,
["h"] = 0.25,
["w"] = 0.75
})
assert.is_same(DCREREADER_CONFIG_H_MARGIN_SIZES_XXX_LARGE, { [2] = 50, [1] = 50 })
assert.is_same(DTAP_ZONE_BACKWARD, {
["y"] = 10,
["x"] = 10.125,
["h"] = 20.25,
["w"] = 20.75
})
os.remove(persistent_filename) os.remove(persistent_filename)
os.remove(persistent_filename .. ".old")
end) end)
it("should delete entry from defaults.persistent.lua if value is reverted back to default", function() it("should delete entry from defaults.custom.lua if value is reverted back to default", function()
local persistent_filename = DataStorage:getDataDir() .. "/defaults.persistent.lua" -- This defaults to false
local fd = io.open(persistent_filename, "w") Defaults:makeTrue("DSHOWOVERLAP")
fd:write( assert.is_true(Defaults:hasBeenCustomized("DSHOWOVERLAP"))
[[-- For configuration changes that persists between updates assert.is_true(Defaults:isTrue("DSHOWOVERLAP"))
DCREREADER_CONFIG_H_MARGIN_SIZES_LARGE = { Defaults:makeFalse("DSHOWOVERLAP")
[1] = 15, assert.is_true(Defaults:hasNotBeenCustomized("DSHOWOVERLAP"))
[2] = 15 assert.is_true(Defaults:isFalse("DSHOWOVERLAP"))
} Defaults:close()
DCREREADER_VIEW_MODE = "page"
DHINTCOUNT = 2
]])
fd:close()
-- in persistent
Defaults:init()
Defaults.changed[56] = true
Defaults.defaults_value[56] = 1
Defaults:saveSettings()
dofile(persistent_filename)
assert.Equals(DCREREADER_VIEW_MODE, "page")
assert.is_same(DCREREADER_CONFIG_H_MARGIN_SIZES_LARGE, {
[2] = 15,
[1] = 15
})
assert.Equals(DGLOBAL_CACHE_FREE_PROPORTION, 1)
assert.Equals(DHINTCOUNT, 2)
os.remove(persistent_filename)
end) end)
end) end)

@ -48,10 +48,11 @@ describe("PDF document module", function()
end) end)
describe("EPUB document module", function() describe("EPUB document module", function()
local DocumentRegistry local DocumentRegistry, cre
setup(function() setup(function()
require("commonrequire") require("commonrequire")
cre = require("libs/libkoreader-cre")
DocumentRegistry = require("document/documentregistry") DocumentRegistry = require("document/documentregistry")
end) end)

@ -1,11 +1,13 @@
-- set true to test httpclient
DUSE_TURBO_LIB = false --luacheck: ignore
describe("HTTP client module #notest #nocov", function() describe("HTTP client module #notest #nocov", function()
local UIManager local UIManager
setup(function() setup(function()
require("commonrequire") require("commonrequire")
UIManager = require("ui/uimanager") UIManager = require("ui/uimanager")
-- Set true to test httpclient
G_defaults:makeFalse("DUSE_TURBO_LIB")
end)
teardown(function()
G_defaults:delSetting("DUSE_TURBO_LIB")
end) end)
local requests = 0 local requests = 0

@ -1,7 +1,8 @@
describe("luadata module", function() describe("luadata module", function()
local Settings local Settings, lfs
setup(function() setup(function()
require("commonrequire") require("commonrequire")
lfs = require("libs/libkoreader-lfs")
Settings = require("frontend/luadata"):open("this-is-not-a-valid-file") Settings = require("frontend/luadata"):open("this-is-not-a-valid-file")
end) end)

@ -551,9 +551,10 @@ describe("Readerfooter module", function()
end) end)
it("should support toggle footer through menu if tap zone is disabled", function() it("should support toggle footer through menu if tap zone is disabled", function()
local saved_tap_zone_minibar = DTAP_ZONE_MINIBAR local DTAP_ZONE_MINIBAR = G_defaults:readSetting("DTAP_ZONE_MINIBAR")
DTAP_ZONE_MINIBAR.w = 0 --luacheck: ignore DTAP_ZONE_MINIBAR.w = 0
DTAP_ZONE_MINIBAR.h = 0 --luacheck: ignore DTAP_ZONE_MINIBAR.h = 0
G_defaults:saveSetting("DTAP_ZONE_MINIBAR", DTAP_ZONE_MINIBAR)
local sample_pdf = "spec/front/unit/data/2col.pdf" local sample_pdf = "spec/front/unit/data/2col.pdf"
purgeDir(DocSettings:getSidecarDir(sample_pdf)) purgeDir(DocSettings:getSidecarDir(sample_pdf))
@ -590,7 +591,7 @@ describe("Readerfooter module", function()
tapFooterMenu(fake_menu, "Toggle mode") tapFooterMenu(fake_menu, "Toggle mode")
assert.is.same(3, footer.mode) assert.is.same(3, footer.mode)
DTAP_ZONE_MINIBAR = saved_tap_zone_minibar --luacheck: ignore G_defaults:delSetting("DTAP_ZONE_MINIBAR")
readerui:closeDocument() readerui:closeDocument()
readerui:onClose() readerui:onClose()
end) end)

Loading…
Cancel
Save