Files
koreader/frontend/ui/reader/readerhighlight.lua
HW 2154e7e852 Further refactoring
This should finish the work to make all globals to local variables.
That allows LuaJIT to properly compile things by interning the
references to the relevant parts (rather than looking up globals
all the time which stops a trace).
2013-10-22 17:11:31 +02:00

369 lines
9.1 KiB
Lua

local InputContainer = require("ui/widget/container/inputcontainer")
local CenterContainer = require("ui/widget/container/centercontainer")
local FrameContainer = require("ui/widget/container/framecontainer")
local GestureRange = require("ui/gesturerange")
local Geom = require("ui/geometry")
local Screen = require("ui/screen")
local Device = require("ui/device")
local Event = require("ui/event")
local UIManager = require("ui/uimanager")
local ButtonTable = require("ui/widget/buttontable")
local Input = require("ui/input")
local _ = require("gettext")
local ReaderHighlight = InputContainer:new{}
function ReaderHighlight:init()
if Device:hasKeyboard() then
self.key_events = {
ShowToc = {
{ "." },
doc = _("highlight text") },
}
end
end
function ReaderHighlight:initGesListener()
self.ges_events = {
Tap = {
GestureRange:new{
ges = "tap",
range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight()
}
}
},
Hold = {
GestureRange:new{
ges = "hold",
range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight()
}
}
},
HoldRelease = {
GestureRange:new{
ges = "hold_release",
range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight()
}
}
},
HoldPan = {
GestureRange:new{
ges = "hold_pan",
range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight()
},
rate = 2.0,
}
},
}
end
function ReaderHighlight:onSetDimensions(dimen)
-- update listening according to new screen dimen
if Device:isTouchDevice() then
self:initGesListener()
end
end
function ReaderHighlight:onTap(arg, ges)
local function inside_box(ges, box)
local pos = self.view:screenToPageTransform(ges.pos)
if pos then
local x, y = pos.x, pos.y
if box.x <= x and box.y <= y
and box.x + box.w >= x
and box.y + box.h >= y then
return true
end
end
end
if self.hold_pos then
self.view.highlight.temp[self.hold_pos.page] = nil
UIManager:setDirty(self.dialog, "partial")
self.hold_pos = nil
return true
end
local pages = self.view:getCurrentPageList()
for key, page in pairs(pages) do
local items = self.view.highlight.saved[page]
if not items then items = {} end
for i = 1, #items do
local pos0, pos1 = items[i].pos0, items[i].pos1
local boxes = self.ui.document:getPageBoxesFromPositions(page, pos0, pos1)
if boxes then
for index, box in pairs(boxes) do
if inside_box(ges, box) then
DEBUG("Tap on hightlight")
self.edit_highlight_dialog = HighlightDialog:new{
buttons = {
{
{
text = _("Delete"),
callback = function()
self:deleteHighlight(page, i)
UIManager:close(self.edit_highlight_dialog)
end,
},
{
text = _("Edit"),
enabled = false,
callback = function()
self:editHighlight()
UIManager:close(self.edit_highlight_dialog)
end,
},
},
},
}
UIManager:show(self.edit_highlight_dialog)
return true
end
end
end
end
end
end
function ReaderHighlight:onHold(arg, ges)
self.hold_pos = self.view:screenToPageTransform(ges.pos)
DEBUG("hold position in page", self.hold_pos)
if not self.hold_pos then
DEBUG("not inside page area")
return true
end
self.selected_word = self.ui.document:getWordFromPosition(self.hold_pos)
DEBUG("selected word:", self.selected_word)
if self.selected_word then
local boxes = {}
table.insert(boxes, self.selected_word.sbox)
self.view.highlight.temp[self.hold_pos.page] = boxes
UIManager:setDirty(self.dialog, "partial")
end
return true
end
function ReaderHighlight:onHoldPan(arg, ges)
if self.hold_pos == nil then
DEBUG("no previous hold position")
return true
end
self.holdpan_pos = self.view:screenToPageTransform(ges.pos)
DEBUG("holdpan position in page", self.holdpan_pos)
self.selected_text = self.ui.document:getTextFromPositions(self.hold_pos, self.holdpan_pos)
DEBUG("selected text:", self.selected_text)
if self.selected_text then
self.view.highlight.temp[self.hold_pos.page] = self.selected_text.sboxes
-- remove selected word if hold moves out of word box
if self.selected_word and
not self.selected_word.sbox:contains(self.selected_text.sboxes[1]) then
self.selected_word = nil
end
UIManager:setDirty(self.dialog, "partial")
end
end
function ReaderHighlight:lookup(selected_word)
-- if we extracted text directly
if selected_word.word then
self.ui:handleEvent(Event:new("LookupWord", selected_word.word))
-- or we will do OCR
else
local word = self.ui.document:getOCRWord(self.hold_pos.page, selected_word)
DEBUG("OCRed word:", word)
self.ui:handleEvent(Event:new("LookupWord", word))
end
end
function ReaderHighlight:translate(selected_text)
if selected_text.text ~= "" then
self.ui:handleEvent(Event:new("TranslateText", selected_text.text))
-- or we will do OCR
else
local text = self.ui.document:getOCRText(self.hold_pos.page, selected_text)
DEBUG("OCRed text:", text)
self.ui:handleEvent(Event:new("TranslateText", text))
end
end
HighlightDialog = InputContainer:new{
buttons = nil,
tap_close_callback = nil,
}
function HighlightDialog:init()
if Device:hasKeyboard() then
key_events = {
AnyKeyPressed = { { Input.group.Any },
seqtext = "any key", doc = _("close dialog") }
}
else
self.ges_events.TapClose = {
GestureRange:new{
ges = "tap",
range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight(),
}
}
}
end
self[1] = CenterContainer:new{
dimen = Screen:getSize(),
FrameContainer:new{
ButtonTable:new{
width = Screen:getWidth()*0.9,
buttons = self.buttons,
},
background = 0,
bordersize = 2,
radius = 7,
padding = 2,
}
}
end
function HighlightDialog:onTapClose()
UIManager:close(self)
if self.tap_close_callback then
self.tap_close_callback()
end
return true
end
function ReaderHighlight:onHoldRelease(arg, ges)
if self.selected_word then
self:lookup(self.selected_word)
self.selected_word = nil
elseif self.selected_text then
DEBUG("show highlight dialog")
self.highlight_dialog = HighlightDialog:new{
buttons = {
{
{
text = _("Highlight"),
callback = function()
self:saveHighlight()
UIManager:close(self.highlight_dialog)
self.ui:handleEvent(Event:new("Tap"))
end,
},
{
text = _("Add Note"),
enabled = false,
callback = function()
self:addNote()
UIManager:close(self.highlight_dialog)
self.ui:handleEvent(Event:new("Tap"))
end,
},
},
{
{
text = _("Translate"),
callback = function()
self:translate(self.selected_text)
UIManager:close(self.highlight_dialog)
self.ui:handleEvent(Event:new("Tap"))
end,
},
{
text = _("Share"),
enabled = false,
callback = function()
self:shareHighlight()
UIManager:close(self.highlight_dialog)
self.ui:handleEvent(Event:new("Tap"))
end,
},
},
{
{
text = _("More"),
enabled = false,
callback = function()
self:moreAction()
UIManager:close(self.highlight_dialog)
self.ui:handleEvent(Event:new("Tap"))
end,
},
},
},
tap_close_callback = function() self.ui:handleEvent(Event:new("Tap")) end,
}
UIManager:show(self.highlight_dialog)
end
return true
end
function ReaderHighlight:saveHighlight()
DEBUG("save highlight")
local page = self.hold_pos.page
if self.hold_pos and self.selected_text then
if not self.view.highlight.saved[page] then
self.view.highlight.saved[page] = {}
end
local hl_item = {}
hl_item["text"] = self.selected_text.text
hl_item["pos0"] = self.selected_text.pos0
hl_item["pos1"] = self.selected_text.pos1
hl_item["datetime"] = os.date("%Y-%m-%d %H:%M:%S"),
table.insert(self.view.highlight.saved[page], hl_item)
if self.selected_text.text ~= "" then
self:exportToClippings(page, hl_item)
end
end
--DEBUG("saved hightlights", self.view.highlight.saved[page])
end
function ReaderHighlight:exportToClippings(page, item)
DEBUG("export highlight to My Clippings")
local clippings = io.open("/mnt/us/documents/My Clippings.txt", "a+")
if clippings then
local current_locale = os.setlocale()
os.setlocale("C")
clippings:write(self.document.file:gsub("(.*/)(.*)", "%2").."\n")
clippings:write("- Koreader Highlight Page "..page.." ")
clippings:write("| Added on "..os.date("%A, %b %d, %Y %I:%M:%S %p\n\n"))
clippings:write(item["text"].."\n")
clippings:write("==========\n")
clippings:close()
os.setlocale(current_locale)
end
end
function ReaderHighlight:addNote()
DEBUG("add Note")
end
function ReaderHighlight:shareHighlight()
DEBUG("share highlight")
end
function ReaderHighlight:moreAction()
DEBUG("more action")
end
function ReaderHighlight:deleteHighlight(page, i)
DEBUG("delete highlight")
table.remove(self.view.highlight.saved[page], i)
end
function ReaderHighlight:editHighlight()
DEBUG("edit highlight")
end
return ReaderHighlight