mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Merge remote-tracking branch 'upstream/master'
Conflicts: frontend/docsettings.lua
This commit is contained in:
@@ -8,4 +8,4 @@ make all
|
||||
retry_cmd 2 make testfront
|
||||
set +o pipefail
|
||||
luajit $(which luacheck) --no-color -q frontend | tee ./luacheck.out
|
||||
test $(grep Total ./luacheck.out | awk '{print $2}') -le 54
|
||||
test $(grep Total ./luacheck.out | awk '{print $2}') -le 53
|
||||
|
||||
@@ -12,7 +12,7 @@ local FileChooser = require("ui/widget/filechooser")
|
||||
local TextWidget = require("ui/widget/textwidget")
|
||||
local Blitbuffer = require("ffi/blitbuffer")
|
||||
local lfs = require("libs/libkoreader-lfs")
|
||||
local docsettings = require("docsettings")
|
||||
local DocSettings = require("docsettings")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local Screen = require("device").screen
|
||||
local Geom = require("ui/geometry")
|
||||
@@ -309,14 +309,7 @@ function FileManager:deleteFile(file)
|
||||
ok, err = os.remove(file_abs_path)
|
||||
if ok and err == nil then
|
||||
if is_doc ~= nil then
|
||||
-- also delete history/settings for documents
|
||||
local sidecar_dir = docsettings:getSidecarDir(file_abs_path)
|
||||
if lfs.attributes(sidecar_dir, "mode") == "directory" then
|
||||
util.purgeDir(sidecar_dir)
|
||||
end
|
||||
local legacy_history_file = docsettings:getHistoryPath(file)
|
||||
-- @todo: check return from os.remove
|
||||
os.remove(legacy_history_file)
|
||||
DocSettings:open(file):purge()
|
||||
end
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = util.template(_("Deleted %1"), file),
|
||||
|
||||
@@ -314,7 +314,13 @@ function ReaderFooter:updateFooterPos()
|
||||
self:updateFooterText()
|
||||
end
|
||||
|
||||
-- updateFooterText will start as a noop. After onReaderReady event is
|
||||
-- received, it will initialized as _updateFooterText
|
||||
function ReaderFooter:updateFooterText()
|
||||
end
|
||||
|
||||
-- only call this function after document is fully loaded
|
||||
function ReaderFooter:_updateFooterText()
|
||||
if self.settings.toc_markers and self.progress_bar.ticks == nil then
|
||||
local ticks_candidates = {}
|
||||
if self.ui.toc then
|
||||
@@ -410,6 +416,10 @@ function ReaderFooter:onUpdatePos()
|
||||
self:updateFooter()
|
||||
end
|
||||
|
||||
function ReaderFooter:onReaderReady()
|
||||
self.updateFooterText = self._updateFooterText
|
||||
self:updateFooter()
|
||||
end
|
||||
|
||||
function ReaderFooter:applyFooterMode(mode)
|
||||
-- three modes switcher for reader footer
|
||||
|
||||
@@ -321,7 +321,7 @@ function ReaderUI:init()
|
||||
v()
|
||||
end
|
||||
|
||||
-- After initialisation notify that document is loaded
|
||||
-- After initialisation notify that document is loaded and rendered
|
||||
-- CREngine only reports correct page count after rendering is done
|
||||
-- Need the same event for PDF document
|
||||
self:handleEvent(Event:new("ReaderReady", self.doc_settings))
|
||||
|
||||
@@ -30,9 +30,9 @@ function Dbg:turnOn()
|
||||
self.is_on = true
|
||||
|
||||
Dbg_mt.__call = function(dbg, ...) LvDEBUG(math.huge, ...) end
|
||||
Dbg.guard = function(_, module, method, pre_guard, post_guard)
|
||||
local old_method = module[method]
|
||||
module[method] = function(...)
|
||||
Dbg.guard = function(_, mod, method, pre_guard, post_guard)
|
||||
local old_method = mod[method]
|
||||
mod[method] = function(...)
|
||||
if pre_guard then
|
||||
pre_guard(...)
|
||||
end
|
||||
|
||||
@@ -5,7 +5,8 @@ local purgeDir = require("ffi/util").purgeDir
|
||||
|
||||
local DocSettings = {}
|
||||
|
||||
local history_dir = DataStorage:getHistoryDir()
|
||||
local HISTORY_DIR = DataStorage:getHistoryDir()
|
||||
local READER_SETTING_FILE = DataStorage:getDataDir() .. "/settings.reader.lua"
|
||||
|
||||
local function buildCandidate(file_path)
|
||||
if lfs.attributes(file_path, "mode") == "file" then
|
||||
@@ -21,7 +22,7 @@ function DocSettings:getSidecarDir(doc_path)
|
||||
end
|
||||
|
||||
function DocSettings:getHistoryPath(fullpath)
|
||||
return history_dir .. "/[" .. fullpath:gsub("(.*/)([^/]+)","%1] %2"):gsub("/","#") .. ".lua"
|
||||
return HISTORY_DIR .. "/[" .. fullpath:gsub("(.*/)([^/]+)","%1] %2"):gsub("/","#") .. ".lua"
|
||||
end
|
||||
|
||||
function DocSettings:getPathFromHistory(hist_name)
|
||||
@@ -39,24 +40,19 @@ function DocSettings:getNameFromHistory(hist_name)
|
||||
return string.sub(hist_name, s+2, -5)
|
||||
end
|
||||
|
||||
function DocSettings:purgeDocSettings(doc_path)
|
||||
purgeDir(self:getSidecarDir(doc_path))
|
||||
os.remove(self:getHistoryPath(doc_path))
|
||||
end
|
||||
|
||||
function DocSettings:open(docfile)
|
||||
-- TODO(zijiehe): Remove history_path, use only sidecar.
|
||||
local new = { data = {} }
|
||||
local ok, stored
|
||||
if docfile == ".reader" then
|
||||
-- we handle reader setting as special case
|
||||
new.history_file = DataStorage:getDataDir() .. "/settings.reader.lua"
|
||||
|
||||
new.history_file = READER_SETTING_FILE
|
||||
ok, stored = pcall(dofile, new.history_file)
|
||||
else
|
||||
new.history_file = self:getHistoryPath(docfile)
|
||||
|
||||
local sidecar = self:getSidecarDir(docfile)
|
||||
new.sidecar = sidecar
|
||||
if lfs.attributes(sidecar, "mode") ~= "directory" then
|
||||
lfs.mkdir(sidecar)
|
||||
end
|
||||
@@ -71,15 +67,15 @@ function DocSettings:open(docfile)
|
||||
|
||||
new.candidates = {}
|
||||
-- New sidecar file
|
||||
table.insert(new.candidates, buildCandidate(new.sidecar_file));
|
||||
table.insert(new.candidates, buildCandidate(new.sidecar_file))
|
||||
-- Legacy sidecar file
|
||||
table.insert(new.candidates, buildCandidate(
|
||||
self:getSidecarDir(docfile).."/"..
|
||||
sidecar.."/"..
|
||||
docfile:match(".*%/(.*)")..".lua"))
|
||||
-- Legacy history folder
|
||||
table.insert(new.candidates, buildCandidate(new.history_file));
|
||||
table.insert(new.candidates, buildCandidate(new.history_file))
|
||||
-- Legacy kpdfview setting
|
||||
table.insert(new.candidates, buildCandidate(docfile..".kpdfview.lua"));
|
||||
table.insert(new.candidates, buildCandidate(docfile..".kpdfview.lua"))
|
||||
table.sort(new.candidates, function(l, r)
|
||||
if l == nil then
|
||||
return false
|
||||
@@ -100,7 +96,7 @@ function DocSettings:open(docfile)
|
||||
new.data = stored
|
||||
end
|
||||
|
||||
return setmetatable(new, { __index = DocSettings})
|
||||
return setmetatable(new, {__index = DocSettings})
|
||||
end
|
||||
|
||||
function DocSettings:readSetting(key)
|
||||
@@ -157,12 +153,12 @@ function DocSettings:close()
|
||||
self:flush()
|
||||
end
|
||||
|
||||
function DocSettings:clear()
|
||||
function DocSettings:purge()
|
||||
if self.history_file then
|
||||
os.remove(self.history_file)
|
||||
end
|
||||
if self.sidecar_file then
|
||||
os.remove(self.sidecar_file)
|
||||
if lfs.attributes(self.sidecar, "mode") == "directory" then
|
||||
purgeDir(self.sidecar)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -81,12 +81,14 @@ function DictQuickLookup:init()
|
||||
HoldWord = {
|
||||
GestureRange:new{
|
||||
ges = "hold",
|
||||
range = function() return self.dimen end,
|
||||
range = function()
|
||||
return self.region
|
||||
end,
|
||||
},
|
||||
-- callback function when HoldWord is handled as args
|
||||
args = function(word)
|
||||
self.ui:handleEvent(Event:new("LookupWord",
|
||||
word, self.word_box))
|
||||
self.ui:handleEvent(
|
||||
Event:new("LookupWord", word, self.word_box))
|
||||
end
|
||||
},
|
||||
}
|
||||
@@ -293,6 +295,7 @@ function DictQuickLookup:onShow()
|
||||
end
|
||||
|
||||
function DictQuickLookup:getHighlightedItem()
|
||||
if not self.ui then return end
|
||||
return self.ui.highlight:getHighlightBookmarkItem()
|
||||
end
|
||||
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
--[[--
|
||||
A TextWidget that handles long text wrapping
|
||||
|
||||
Example:
|
||||
|
||||
local Foo = TextBoxWidget:new{
|
||||
face = Font:getFace("cfont", 25),
|
||||
text = 'We can show multiple lines.\nFoo.\nBar.',
|
||||
-- width = Screen:getWidth()*2/3,
|
||||
}
|
||||
UIManager:show(Foo)
|
||||
|
||||
]]
|
||||
|
||||
local Blitbuffer = require("ffi/blitbuffer")
|
||||
local Widget = require("ui/widget/widget")
|
||||
local LineWidget = require("ui/widget/linewidget")
|
||||
@@ -5,11 +19,7 @@ local RenderText = require("ui/rendertext")
|
||||
local Screen = require("device").screen
|
||||
local Geom = require("ui/geometry")
|
||||
local util = require("util")
|
||||
local DEBUG = require("dbg")
|
||||
|
||||
--[[
|
||||
A TextWidget that handles long text wrapping
|
||||
--]]
|
||||
local TextBoxWidget = Widget:new{
|
||||
text = nil,
|
||||
charlist = nil,
|
||||
@@ -29,11 +39,11 @@ local TextBoxWidget = Widget:new{
|
||||
}
|
||||
|
||||
function TextBoxWidget:init()
|
||||
local line_height = (1 + self.line_height) * self.face.size
|
||||
self.line_height_px = (1 + self.line_height) * self.face.size
|
||||
self.cursor_line = LineWidget:new{
|
||||
dimen = Geom:new{
|
||||
w = Screen:scaleBySize(1),
|
||||
h = line_height,
|
||||
h = self.line_height_px,
|
||||
}
|
||||
}
|
||||
self:_evalCharWidthList()
|
||||
@@ -51,7 +61,7 @@ function TextBoxWidget:init()
|
||||
self.dimen = Geom:new(self:getSize())
|
||||
end
|
||||
|
||||
-- Evaluate the width of each char in `self.charlist`.
|
||||
-- Split `self.text` into `self.charlist` and evaluate the width of each char in it.
|
||||
function TextBoxWidget:_evalCharWidthList()
|
||||
if self.charlist == nil then
|
||||
self.charlist = util.splitToChars(self.text)
|
||||
@@ -66,8 +76,9 @@ end
|
||||
|
||||
-- Split the text into logical lines to fit into the text box.
|
||||
function TextBoxWidget:_splitCharWidthList()
|
||||
self.vertical_string_list = {}
|
||||
self.vertical_string_list[1] = {text = "Demo hint", offset = 1, width = 0} -- hint for empty string
|
||||
self.vertical_string_list = {
|
||||
{text = "Demo hint", offset = 1, width = 0} -- hint for empty string
|
||||
}
|
||||
|
||||
local idx = 1
|
||||
local size = #self.char_width_list
|
||||
@@ -113,10 +124,15 @@ function TextBoxWidget:_splitCharWidthList()
|
||||
end
|
||||
end -- endif util.isSplitable(c)
|
||||
end -- endif cur_line_width > self.width
|
||||
self.vertical_string_list[ln] = {text = cur_line_text, offset = offset, width = cur_line_width}
|
||||
self.vertical_string_list[ln] = {
|
||||
text = cur_line_text,
|
||||
offset = offset,
|
||||
width = cur_line_width
|
||||
}
|
||||
if hard_newline then
|
||||
idx = idx + 1
|
||||
self.vertical_string_list[ln + 1] = {text = "", offset = idx, width = 0}
|
||||
-- FIXME: reuse newline entry
|
||||
self.vertical_string_list[ln+1] = {text = "", offset = idx, width = 0}
|
||||
end
|
||||
ln = ln + 1
|
||||
-- Make sure `idx` point to the next char to be processed in the next loop.
|
||||
@@ -125,11 +141,10 @@ end
|
||||
|
||||
function TextBoxWidget:_renderText(start_row_idx, end_row_idx)
|
||||
local font_height = self.face.size
|
||||
local line_height = (1 + self.line_height) * font_height
|
||||
if start_row_idx < 1 then start_row_idx = 1 end
|
||||
if end_row_idx > #self.vertical_string_list then end_row_idx = #self.vertical_string_list end
|
||||
local row_count = end_row_idx == 0 and 1 or end_row_idx - start_row_idx + 1
|
||||
local h = line_height * row_count
|
||||
local h = self.line_height_px * row_count
|
||||
self._bb = Blitbuffer.new(self.width, h)
|
||||
self._bb:fill(Blitbuffer.COLOR_WHITE)
|
||||
local y = font_height
|
||||
@@ -139,7 +154,7 @@ function TextBoxWidget:_renderText(start_row_idx, end_row_idx)
|
||||
--@TODO Don't use kerning for monospaced fonts. (houqp)
|
||||
-- refert to cb25029dddc42693cc7aaefbe47e9bd3b7e1a750 in master tree
|
||||
RenderText:renderUtf8Text(self._bb, pen_x, y, self.face, line.text, true, self.bold, self.fgcolor)
|
||||
y = y + line_height
|
||||
y = y + self.line_height_px
|
||||
end
|
||||
-- -- if text is shorter than one line, shrink to text's width
|
||||
-- if #v_list == 1 then
|
||||
@@ -162,17 +177,15 @@ function TextBoxWidget:_findCharPos()
|
||||
x = x + self.char_width_list[offset].width
|
||||
offset = offset + 1
|
||||
end
|
||||
local line_height = (1 + self.line_height) * self.face.size
|
||||
return x + 1, (ln - 1) * line_height -- offset `x` by 1 to avoid overlap
|
||||
return x + 1, (ln - 1) * self.line_height_px -- offset `x` by 1 to avoid overlap
|
||||
end
|
||||
|
||||
-- Click event: Move the cursor to a new location with (x, y), in pixels.
|
||||
-- Be aware of virtual line number of the scorllTextWidget.
|
||||
function TextBoxWidget:moveCursor(x, y)
|
||||
local w = 0
|
||||
local line_height = (1 + self.line_height) * self.face.size
|
||||
local ln = self.height == nil and 1 or self.virtual_line_num
|
||||
ln = ln + math.ceil(y / line_height) - 1
|
||||
ln = ln + math.ceil(y / self.line_height_px) - 1
|
||||
if ln > #self.vertical_string_list then
|
||||
ln = #self.vertical_string_list
|
||||
x = self.width
|
||||
@@ -191,13 +204,13 @@ function TextBoxWidget:moveCursor(x, y)
|
||||
end
|
||||
self:free()
|
||||
self:_renderText(1, #self.vertical_string_list)
|
||||
self.cursor_line:paintTo(self._bb, w + 1, (ln - self.virtual_line_num) * line_height)
|
||||
self.cursor_line:paintTo(self._bb, w + 1,
|
||||
(ln - self.virtual_line_num) * self.line_height_px)
|
||||
return offset
|
||||
end
|
||||
|
||||
function TextBoxWidget:getVisLineCount()
|
||||
local line_height = (1 + self.line_height) * self.face.size
|
||||
return math.floor(self.height / line_height)
|
||||
return math.floor(self.height / self.line_height_px)
|
||||
end
|
||||
|
||||
function TextBoxWidget:getAllLineCount()
|
||||
@@ -213,7 +226,7 @@ function TextBoxWidget:scrollDown()
|
||||
self.virtual_line_num = self.virtual_line_num + visible_line_count
|
||||
self:_renderText(self.virtual_line_num, self.virtual_line_num + visible_line_count - 1)
|
||||
end
|
||||
return (self.virtual_line_num - 1) / #self.vertical_string_list, (self.virtual_line_num - 1 + visible_line_count) / #self.vertical_string_list
|
||||
return (self.virtual_line_num - 1) / #self.vertical_string_list, (self.virtual_line_num - 1 + visible_line_count) / #self.vertical_string_list
|
||||
end
|
||||
|
||||
-- TODO: modify `charpos` so that it can render the cursor
|
||||
@@ -228,7 +241,7 @@ function TextBoxWidget:scrollUp()
|
||||
end
|
||||
self:_renderText(self.virtual_line_num, self.virtual_line_num + visible_line_count - 1)
|
||||
end
|
||||
return (self.virtual_line_num - 1) / #self.vertical_string_list, (self.virtual_line_num - 1 + visible_line_count) / #self.vertical_string_list
|
||||
return (self.virtual_line_num - 1) / #self.vertical_string_list, (self.virtual_line_num - 1 + visible_line_count) / #self.vertical_string_list
|
||||
end
|
||||
|
||||
function TextBoxWidget:getSize()
|
||||
@@ -252,21 +265,48 @@ function TextBoxWidget:free()
|
||||
end
|
||||
|
||||
function TextBoxWidget:onHoldWord(callback, ges)
|
||||
if not callback then return end
|
||||
|
||||
local x, y = ges.pos.x - self.dimen.x, ges.pos.y - self.dimen.y
|
||||
for _, l in ipairs(self.rendering_vlist) do
|
||||
for _, w in ipairs(l) do
|
||||
local box = w.box
|
||||
if x > box.x and x < box.x + box.w and
|
||||
y > box.y and y < box.y + box.h then
|
||||
DEBUG("found word", w, "at", x, y)
|
||||
if callback then
|
||||
callback(w.word)
|
||||
local line_num = math.ceil(y / self.line_height_px)
|
||||
local line = self.vertical_string_list[line_num]
|
||||
|
||||
if line then
|
||||
local char_start = line.offset
|
||||
local char_end -- char_end is non-inclusive
|
||||
if line_num >= #self.vertical_string_list then
|
||||
char_end = #self.char_width_list + 1
|
||||
else
|
||||
char_end = self.vertical_string_list[line_num+1].offset
|
||||
end
|
||||
local char_probe_x = 0
|
||||
local idx = char_start
|
||||
-- find which character the touch is holding
|
||||
while idx < char_end do
|
||||
local c = self.char_width_list[idx]
|
||||
-- FIXME: this might break if kerning is enabled
|
||||
char_probe_x = char_probe_x + c.width
|
||||
if char_probe_x > x then
|
||||
-- ignore spaces
|
||||
if c.char == " " then break end
|
||||
-- now find which word the character is in
|
||||
local words = util.splitToWords(line.text)
|
||||
local probe_idx = char_start
|
||||
for _,w in ipairs(words) do
|
||||
-- +1 for word separtor
|
||||
probe_idx = probe_idx + string.len(w)
|
||||
if idx <= probe_idx then
|
||||
callback(w)
|
||||
return
|
||||
end
|
||||
end
|
||||
break
|
||||
end
|
||||
idx = idx + 1
|
||||
end
|
||||
end
|
||||
return true
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
return TextBoxWidget
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
local BaseUtil = require("ffi/util")
|
||||
|
||||
--[[--
|
||||
Miscellaneous helper functions for KOReader frontend.
|
||||
]]
|
||||
]]
|
||||
|
||||
local BaseUtil = require("ffi/util")
|
||||
local util = {}
|
||||
|
||||
function util.stripePunctuations(word)
|
||||
if not word then return end
|
||||
-- strip ASCII punctuation characters around word
|
||||
-- and strip any generic punctuation (U+2000 - U+206F) in the word
|
||||
return word:gsub("\226[\128-\131][\128-\191]", ''):gsub("^%p+", ''):gsub("%p+$", '')
|
||||
--- Strip all punctuations and spaces in a string.
|
||||
---- @string text the string to be stripped
|
||||
---- @treturn string stripped text
|
||||
function util.stripePunctuations(text)
|
||||
if not text then return end
|
||||
-- strip ASCII punctuation characters around text
|
||||
-- and strip any generic punctuation (U+2000 - U+206F) in the text
|
||||
return text:gsub("\226[\128-\131][\128-\191]", ''):gsub("^%p+", ''):gsub("%p+$", '')
|
||||
end
|
||||
|
||||
--[[
|
||||
@@ -74,7 +76,7 @@ end
|
||||
|
||||
--- Returns number of keys in a table.
|
||||
---- @param T Lua table
|
||||
---- @return number of keys in table T
|
||||
---- @treturn int number of keys in table T
|
||||
function util.tableSize(T)
|
||||
local count = 0
|
||||
for _ in pairs(T) do count = count + 1 end
|
||||
@@ -97,8 +99,9 @@ function util.lastIndexOf(string, ch)
|
||||
end
|
||||
|
||||
|
||||
-- Split string into a list of UTF-8 chars.
|
||||
-- @text: the string to be splitted.
|
||||
--- Split string into a list of UTF-8 chars.
|
||||
---- @string text the string to be splitted.
|
||||
---- @treturn table list of UTF-8 chars
|
||||
function util.splitToChars(text)
|
||||
local tab = {}
|
||||
if text ~= nil then
|
||||
@@ -114,6 +117,20 @@ function util.splitToChars(text)
|
||||
return tab
|
||||
end
|
||||
|
||||
--- Split text into a list of words, spaces and punctuations.
|
||||
---- @string text text to split
|
||||
---- @treturn table list of words, spaces and punctuations
|
||||
function util.splitToWords(text)
|
||||
-- TODO: write test
|
||||
local wlist = {}
|
||||
for words in text:gmatch("[\32-\127\192-\255]+[\128-\191]*") do
|
||||
for word in util.gsplit(words, "[%s%p]+", true) do
|
||||
table.insert(wlist, word)
|
||||
end
|
||||
end
|
||||
return wlist
|
||||
end
|
||||
|
||||
-- Test whether a string could be separated by a char for multi-line rendering
|
||||
function util.isSplitable(c)
|
||||
return #c > 1 or c == " " or string.match(c, "%p") ~= nil
|
||||
|
||||
@@ -1,10 +1,40 @@
|
||||
require("commonrequire")
|
||||
local doc = require("docsettings")
|
||||
|
||||
describe("docsettings module", function()
|
||||
local docsettings
|
||||
|
||||
setup(function()
|
||||
require("commonrequire")
|
||||
docsettings = require("docsettings")
|
||||
end)
|
||||
it("should generate sidecar directory path", function()
|
||||
assert.Equals("../../foo.sdr", doc:getSidecarDir("../../foo.pdf"))
|
||||
assert.Equals("/foo/bar.sdr", doc:getSidecarDir("/foo/bar.pdf"))
|
||||
assert.Equals("baz.sdr", doc:getSidecarDir("baz.pdf"))
|
||||
assert.Equals("../../foo.sdr", docsettings:getSidecarDir("../../foo.pdf"))
|
||||
assert.Equals("/foo/bar.sdr", docsettings:getSidecarDir("/foo/bar.pdf"))
|
||||
assert.Equals("baz.sdr", docsettings:getSidecarDir("baz.pdf"))
|
||||
end)
|
||||
it("should read legacy history file", function()
|
||||
local file = "file.pdf"
|
||||
local d = docsettings:open(file)
|
||||
d:saveSetting("a", "b")
|
||||
d:close()
|
||||
-- Now the sidecar file should be written.
|
||||
|
||||
assert.False(os.rename(d.sidecar_file, d.history_file) == nil)
|
||||
d = docsettings:open(file)
|
||||
assert.Equals(d:readSetting("a"), "b")
|
||||
d:close()
|
||||
-- history_file should be removed as sidecar_file is preferred.
|
||||
assert.False(os.remove(d.sidecar_file) == nil)
|
||||
assert.True(os.remove(d.history_file) == nil)
|
||||
|
||||
assert.False(os.rename(d.sidecar_file, d.sidecar .. "/file.lua") == nil)
|
||||
d = docsettings:open(file)
|
||||
assert.Equals(d:readSetting("a"), "b")
|
||||
d:close()
|
||||
|
||||
assert.False(os.rename(d.sidecar_file, "file.kpdfview.lua") == nil)
|
||||
d = docsettings:open(file)
|
||||
assert.Equals(d:readSetting("a"), "b")
|
||||
d:close()
|
||||
|
||||
d:purge()
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
require("commonrequire")
|
||||
local FileManager = require("apps/filemanager/filemanager")
|
||||
local lfs = require("libs/libkoreader-lfs")
|
||||
local docsettings = require("docsettings")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local Screen = require("device").screen
|
||||
local util = require("ffi/util")
|
||||
local DEBUG = require("dbg")
|
||||
|
||||
describe("FileManager module", function()
|
||||
local FileManager, lfs, docsettings, UIManager, Screen, util
|
||||
setup(function()
|
||||
require("commonrequire")
|
||||
FileManager = require("apps/filemanager/filemanager")
|
||||
lfs = require("libs/libkoreader-lfs")
|
||||
docsettings = require("docsettings")
|
||||
UIManager = require("ui/uimanager")
|
||||
Screen = require("device").screen
|
||||
util = require("ffi/util")
|
||||
end)
|
||||
it("should show file manager", function()
|
||||
UIManager:quit()
|
||||
local filemanager = FileManager:new{
|
||||
|
||||
@@ -48,7 +48,7 @@ describe("ReaderBookmark module", function()
|
||||
local page = 10
|
||||
local readerui
|
||||
setup(function()
|
||||
DocSettings:purgeDocSettings(sample_epub)
|
||||
DocSettings:open(sample_epub):purge()
|
||||
readerui = ReaderUI:new{
|
||||
document = DocumentRegistry:openDocument(sample_epub),
|
||||
}
|
||||
@@ -130,7 +130,7 @@ describe("ReaderBookmark module", function()
|
||||
describe("bookmark for PDF document", function()
|
||||
local readerui
|
||||
setup(function()
|
||||
DocSettings:purgeDocSettings(sample_pdf)
|
||||
DocSettings:open(sample_pdf):purge()
|
||||
readerui = ReaderUI:new{
|
||||
document = DocumentRegistry:openDocument(sample_pdf),
|
||||
}
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
require("commonrequire")
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local ReaderUI = require("apps/reader/readerui")
|
||||
local DocSettings = require("docsettings")
|
||||
local UIManager = require("ui/uimanager")
|
||||
|
||||
describe("Readerui module", function()
|
||||
local DocumentRegistry, ReaderUI, DocSettings, UIManager
|
||||
local sample_epub = "spec/front/unit/data/leaves.epub"
|
||||
local readerui
|
||||
setup(function()
|
||||
require("commonrequire")
|
||||
DocumentRegistry = require("document/documentregistry")
|
||||
ReaderUI = require("apps/reader/readerui")
|
||||
DocSettings = require("docsettings")
|
||||
UIManager = require("ui/uimanager")
|
||||
|
||||
readerui = ReaderUI:new{
|
||||
document = DocumentRegistry:openDocument(sample_epub),
|
||||
}
|
||||
end)
|
||||
it("should save settings", function()
|
||||
-- remove history settings and sidecar settings
|
||||
DocSettings:open(sample_epub):clear()
|
||||
DocSettings:open(sample_epub):purge()
|
||||
local doc_settings = DocSettings:open(sample_epub)
|
||||
assert.are.same(doc_settings.data, {})
|
||||
readerui:saveSettings()
|
||||
|
||||
25
spec/unit/textboxwidget_spec.lua
Normal file
25
spec/unit/textboxwidget_spec.lua
Normal file
@@ -0,0 +1,25 @@
|
||||
describe("TextBoxWidget module", function()
|
||||
local TextBoxWidget, Font
|
||||
setup(function()
|
||||
require("commonrequire")
|
||||
Font = require("ui/font")
|
||||
TextBoxWidget = require("ui/widget/textboxwidget")
|
||||
end)
|
||||
|
||||
it("should select the correct word on HoldWord event", function()
|
||||
local tw = TextBoxWidget:new{
|
||||
dimen = {x = 0, y = 0},
|
||||
face = Font:getFace("cfont", 25),
|
||||
text = 'YOOOOOOOOOOOOOOOO\nFoo.\nBar.',
|
||||
}
|
||||
tw:onHoldWord(function(w)
|
||||
assert.is.same(w, 'YOOOOOOOOOOOOOOOO')
|
||||
end, {pos={x=110,y=4}})
|
||||
tw:onHoldWord(function(w)
|
||||
assert.is.same(w, 'Foo')
|
||||
end, {pos={x=0,y=50}})
|
||||
tw:onHoldWord(function(w)
|
||||
assert.is.same(w, 'Bar')
|
||||
end, {pos={x=20,y=80}})
|
||||
end)
|
||||
end)
|
||||
@@ -37,4 +37,19 @@ describe("util module", function()
|
||||
end
|
||||
assert.are_same(argv, {"./sdcv", "-nj", "words", "a lot", "more or less", "--data-dir=dict"})
|
||||
end)
|
||||
|
||||
it("should split line into words", function()
|
||||
local words = util.splitToWords("one two,three four . five")
|
||||
assert.are_same(words, {
|
||||
"one",
|
||||
" ",
|
||||
"two",
|
||||
",",
|
||||
"three",
|
||||
" ",
|
||||
"four",
|
||||
" . ",
|
||||
"five",
|
||||
})
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user