2012-10-21 16:53:33 +00:00
|
|
|
require "font"
|
|
|
|
require "keys"
|
|
|
|
require "settings"
|
2012-11-10 12:40:43 +00:00
|
|
|
require "screen"
|
2012-10-21 16:53:33 +00:00
|
|
|
require "pdfreader"
|
|
|
|
require "djvureader"
|
|
|
|
require "koptreader"
|
|
|
|
require "picviewer"
|
|
|
|
require "crereader"
|
|
|
|
|
|
|
|
registry = {
|
2012-10-22 18:47:54 +00:00
|
|
|
-- registry format:
|
|
|
|
-- reader_name = {reader_object, supported_formats, priority}
|
|
|
|
PDFReader = {PDFReader, ";pdf;xps;cbz;", 1},
|
|
|
|
DJVUReader = {DJVUReader, ";djvu;", 1},
|
2012-10-23 05:51:03 +00:00
|
|
|
PDFReflow = {KOPTReader, ";pdf;", 2},
|
|
|
|
DJVUReflow = {KOPTReader, ";djvu;", 2},
|
2012-10-22 18:47:54 +00:00
|
|
|
CREReader = {CREReader, ";epub;txt;rtf;htm;html;mobi;prc;azw;fb2;chm;pdb;doc;tcr;zip;", 1},
|
|
|
|
PICViewer = {PICViewer, ";jpg;jpeg;", 1},
|
2012-10-21 16:53:33 +00:00
|
|
|
-- seems to accept pdb-files for PalmDoc only
|
|
|
|
}
|
|
|
|
|
|
|
|
ReaderChooser = {
|
|
|
|
-- UI constants
|
|
|
|
title_H = 35, -- title height
|
|
|
|
title_bar_H = 15, -- title bar height
|
|
|
|
options_H = 35, -- options height
|
2012-10-22 18:47:54 +00:00
|
|
|
options_bar_T = 2, -- options bar thickness
|
2012-10-21 16:53:33 +00:00
|
|
|
spacing = 35, -- spacing between lines
|
2012-10-26 05:15:36 +00:00
|
|
|
WIDTH = 380, -- window width
|
|
|
|
HEIGHT = 220, -- window height
|
2012-10-22 18:47:54 +00:00
|
|
|
margin_I = 50, -- reader item margin
|
2012-10-21 16:53:33 +00:00
|
|
|
margin_O = 10, -- option margin
|
2012-10-23 05:51:03 +00:00
|
|
|
title_font_size = 23, -- title font size
|
|
|
|
item_font_size = 20, -- reader item font size
|
|
|
|
option_font_size = 17, -- option font size
|
2012-10-21 16:53:33 +00:00
|
|
|
|
2012-10-23 05:51:03 +00:00
|
|
|
-- title text
|
|
|
|
TITLE = "Complete action using",
|
2012-10-21 16:53:33 +00:00
|
|
|
-- options text
|
2012-10-22 18:47:54 +00:00
|
|
|
OPTION_TYPE = "Remember this type(T)",
|
|
|
|
OPTION_FILE = "Remember this file(F)",
|
2012-10-21 16:53:33 +00:00
|
|
|
|
|
|
|
-- data variables
|
|
|
|
readers = {},
|
|
|
|
final_choice = nil,
|
2012-10-22 05:08:36 +00:00
|
|
|
last_item = 0,
|
|
|
|
current_item = 1,
|
2012-10-21 16:53:33 +00:00
|
|
|
-- state variables
|
|
|
|
dialogdirty = true,
|
|
|
|
markerdirty = false,
|
|
|
|
optiondirty = true,
|
2012-11-07 08:52:06 +00:00
|
|
|
remember_preference = false,
|
|
|
|
remember_association = false,
|
2012-10-21 16:53:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function GetRegisteredReaders(ftype)
|
|
|
|
local s = ";"
|
|
|
|
local readers = {}
|
|
|
|
for key,value in pairs(registry) do
|
|
|
|
if string.find(value[2],s..ftype..s) then
|
|
|
|
table.insert(readers,key)
|
|
|
|
end
|
|
|
|
end
|
2012-10-22 18:47:54 +00:00
|
|
|
table.sort(readers, function(a,b) return registry[a][3]<registry[b][3] end)
|
2012-10-21 16:53:33 +00:00
|
|
|
return readers
|
|
|
|
end
|
|
|
|
|
2012-10-22 05:08:36 +00:00
|
|
|
-- find the first reader registered with this file type
|
|
|
|
function ReaderChooser:getReaderByType(ftype)
|
|
|
|
local readers = GetRegisteredReaders(ftype)
|
2012-10-22 19:01:32 +00:00
|
|
|
if #readers >= 1 then
|
2012-10-22 05:08:36 +00:00
|
|
|
return registry[readers[1]][1]
|
|
|
|
else
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function ReaderChooser:getReaderByName(filename)
|
2012-10-21 16:53:33 +00:00
|
|
|
local file_type = string.lower(string.match(filename, ".+%.([^.]+)"))
|
|
|
|
local readers = GetRegisteredReaders(file_type)
|
2012-10-22 15:58:04 +00:00
|
|
|
if #readers > 1 then -- more than one reader are registered with this file type
|
2012-11-07 06:13:47 +00:00
|
|
|
local file_settings = DocSettings:open(filename)
|
2012-11-07 08:52:06 +00:00
|
|
|
local reader_association = file_settings:readSetting("reader_association")
|
|
|
|
local reader_preferences = G_reader_settings:readSetting("reader_preferences")
|
|
|
|
Debug("Reading saved association:", reader_association)
|
|
|
|
if reader_association and reader_association ~= "N/A" then
|
2012-11-07 06:13:47 +00:00
|
|
|
file_settings:close()
|
2012-11-07 08:52:06 +00:00
|
|
|
return registry[reader_association][1]
|
2012-10-22 18:47:54 +00:00
|
|
|
|
2012-11-07 08:52:06 +00:00
|
|
|
elseif reader_preferences and reader_association ~= "N/A" then
|
|
|
|
default_reader = reader_preferences[file_type]
|
2012-10-22 18:47:54 +00:00
|
|
|
if default_reader then
|
|
|
|
return registry[default_reader][1]
|
|
|
|
end
|
2012-11-07 08:52:06 +00:00
|
|
|
end
|
|
|
|
-- need to choose reader
|
2012-11-10 12:40:43 +00:00
|
|
|
Screen:saveCurrentBB()
|
2012-11-07 08:52:06 +00:00
|
|
|
local name = self:choose(readers)
|
|
|
|
if name then
|
|
|
|
if self.remember_preference then
|
|
|
|
if not reader_preferences then
|
|
|
|
reader_preferences = {}
|
2012-10-21 16:53:33 +00:00
|
|
|
end
|
2012-11-07 08:52:06 +00:00
|
|
|
reader_preferences[file_type] = name
|
|
|
|
G_reader_settings:saveSetting("reader_preferences", reader_preferences)
|
|
|
|
file_settings:delSetting("reader_association") --override reader association
|
2012-10-21 16:53:33 +00:00
|
|
|
end
|
2012-11-07 08:52:06 +00:00
|
|
|
if self.remember_association then
|
|
|
|
Debug("Saving last reader:", name)
|
|
|
|
file_settings:saveSetting("reader_association", name)
|
|
|
|
end
|
|
|
|
file_settings:close()
|
2012-11-10 12:40:43 +00:00
|
|
|
Screen:restoreFromSavedBB()
|
2012-11-07 08:52:06 +00:00
|
|
|
return registry[name][1]
|
|
|
|
else
|
|
|
|
file_settings:close()
|
|
|
|
return nil
|
2012-10-21 16:53:33 +00:00
|
|
|
end
|
2012-11-07 06:13:47 +00:00
|
|
|
|
2012-10-22 15:58:04 +00:00
|
|
|
elseif #readers == 1 then
|
2012-10-21 16:53:33 +00:00
|
|
|
return registry[readers[1]][1]
|
|
|
|
else
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function ReaderChooser:drawBox(xpos, ypos, w, h, bgcolor, bdcolor)
|
|
|
|
-- draw dialog border
|
|
|
|
local r = 6 -- round corners
|
|
|
|
fb.bb:paintRect(xpos, ypos+r, w, h - r, bgcolor)
|
|
|
|
blitbuffer.paintBorder(fb.bb, xpos, ypos, w, r, r, bdcolor, r)
|
|
|
|
blitbuffer.paintBorder(fb.bb, xpos+2, ypos + 2, w - 4, r, r, bdcolor, r)
|
|
|
|
end
|
|
|
|
|
|
|
|
function ReaderChooser:drawTitle(text, xpos, ypos, w, font_face)
|
|
|
|
-- draw title text
|
|
|
|
renderUtf8Text(fb.bb, xpos+10, ypos+self.title_H, font_face, text, true)
|
|
|
|
-- draw title bar
|
|
|
|
fb.bb:paintRect(xpos, ypos+self.title_H+self.title_bar_H, w, 3, 5)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2012-10-23 05:51:03 +00:00
|
|
|
function ReaderChooser:drawReaderItem(name, xpos, ypos, font_face)
|
2012-10-21 16:53:33 +00:00
|
|
|
-- draw reader name
|
2012-10-23 05:51:03 +00:00
|
|
|
renderUtf8Text(fb.bb, xpos+self.margin_I, ypos, font_face, name, true)
|
|
|
|
return sizeUtf8Text(0, G_width, font_face, name, true).x
|
2012-10-21 16:53:33 +00:00
|
|
|
end
|
|
|
|
|
2012-10-23 05:51:03 +00:00
|
|
|
function ReaderChooser:drawOptions(xpos, ypos, barcolor, bgcolor, font_face)
|
2012-10-26 05:15:36 +00:00
|
|
|
local width, height = self.WIDTH, self.HEIGHT
|
2012-10-22 18:47:54 +00:00
|
|
|
local optbar_T = self.options_bar_T
|
|
|
|
-- draw option border
|
2012-10-23 08:43:59 +00:00
|
|
|
fb.bb:paintRect(xpos, ypos, width, optbar_T, barcolor)
|
2012-10-22 18:47:54 +00:00
|
|
|
fb.bb:paintRect(xpos+(width-optbar_T)/2, ypos, optbar_T, self.options_H, barcolor)
|
|
|
|
-- draw option cell
|
2012-11-07 08:52:06 +00:00
|
|
|
fb.bb:paintRect(xpos, ypos+optbar_T, (width-optbar_T)/2, self.options_H-optbar_T, bgcolor+3*(self.remember_preference and 1 or 0))
|
|
|
|
fb.bb:paintRect(xpos+(width+optbar_T)/2, ypos+optbar_T, (width-optbar_T)/2, self.options_H-optbar_T, bgcolor+3*(self.remember_association and 1 or 0))
|
2012-10-21 16:53:33 +00:00
|
|
|
-- draw option text
|
2012-10-23 05:51:03 +00:00
|
|
|
renderUtf8Text(fb.bb, xpos+self.margin_O, ypos+self.options_H/2+8, font_face, self.OPTION_TYPE, true)
|
|
|
|
renderUtf8Text(fb.bb, xpos+width/2+self.margin_O, ypos+self.options_H/2+8, font_face, self.OPTION_FILE, true)
|
2012-10-22 18:47:54 +00:00
|
|
|
fb:refresh(1, xpos, ypos, width, self.options_H-optbar_T)
|
2012-10-21 16:53:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function ReaderChooser:choose(readers)
|
|
|
|
self.readers = {}
|
|
|
|
self.final_choice = nil
|
|
|
|
self.readers = readers
|
|
|
|
self.dialogdirty = true
|
|
|
|
self.markerdirty = false
|
|
|
|
self.optiondirty = true
|
|
|
|
self:addAllCommands()
|
|
|
|
|
2012-10-23 05:51:03 +00:00
|
|
|
local tface = Font:getFace("tfont", self.title_font_size)
|
|
|
|
local cface = Font:getFace("cfont", self.item_font_size)
|
|
|
|
local fface = Font:getFace("ffont", self.option_font_size)
|
2012-10-21 16:53:33 +00:00
|
|
|
|
2012-10-26 05:15:36 +00:00
|
|
|
local width, height = self.WIDTH, self.HEIGHT
|
|
|
|
local topleft_x, topleft_y = (fb.bb:getWidth()-width)/2, (fb.bb:getHeight()-height)/2
|
|
|
|
local botleft_x, botleft_y = topleft_x, topleft_y+height
|
2012-10-21 16:53:33 +00:00
|
|
|
|
|
|
|
Debug("Drawing box")
|
|
|
|
self:drawBox(topleft_x, topleft_y, width, height, 3, 3)
|
|
|
|
Debug("Drawing title")
|
2012-10-23 05:51:03 +00:00
|
|
|
self:drawTitle(self.TITLE, topleft_x, topleft_y, width, tface)
|
2012-10-22 15:58:04 +00:00
|
|
|
|
2012-10-21 16:53:33 +00:00
|
|
|
local reader_text_width = {}
|
|
|
|
for index,name in ipairs(self.readers) do
|
|
|
|
Debug("Drawing reader:",index,name)
|
|
|
|
reader_text_width[index] = self:drawReaderItem(name, topleft_x, topleft_y+self.title_H+self.spacing*index+10, cface)
|
|
|
|
end
|
|
|
|
|
|
|
|
fb:refresh(1, topleft_x, topleft_y, width, height)
|
|
|
|
|
|
|
|
-- paint first reader marker
|
|
|
|
local xmarker = topleft_x + self.margin_I
|
|
|
|
local ymarker = topleft_y + self.title_H + self.title_bar_H
|
|
|
|
fb.bb:paintRect(xmarker, ymarker+self.spacing*self.current_item, reader_text_width[self.current_item], 3, 15)
|
|
|
|
fb:refresh(1, xmarker, ymarker+self.spacing*self.current_item, reader_text_width[self.current_item], 3)
|
|
|
|
|
|
|
|
local ev, keydef, command, ret_code
|
|
|
|
while true do
|
|
|
|
if self.markerdirty then
|
|
|
|
fb.bb:paintRect(xmarker, ymarker+self.spacing*self.last_item, reader_text_width[self.last_item], 3, 3)
|
|
|
|
fb:refresh(1, xmarker, ymarker+self.spacing*self.last_item, reader_text_width[self.last_item], 3)
|
|
|
|
fb.bb:paintRect(xmarker, ymarker+self.spacing*self.current_item, reader_text_width[self.current_item], 3, 15)
|
|
|
|
fb:refresh(1, xmarker, ymarker+self.spacing*self.current_item, reader_text_width[self.current_item], 3)
|
|
|
|
self.markerdirty = false
|
|
|
|
end
|
|
|
|
|
|
|
|
if self.optiondirty then
|
2012-10-22 18:47:54 +00:00
|
|
|
self:drawOptions(botleft_x, botleft_y-self.options_H, 5, 3, fface)
|
2012-10-21 16:53:33 +00:00
|
|
|
self.optiondirty = false
|
|
|
|
end
|
|
|
|
|
|
|
|
ev = input.saveWaitForEvent()
|
|
|
|
ev.code = adjustKeyEvents(ev)
|
|
|
|
if ev.type == EV_KEY and ev.value ~= EVENT_VALUE_KEY_RELEASE then
|
|
|
|
keydef = Keydef:new(ev.code, getKeyModifier())
|
|
|
|
Debug("key pressed: "..tostring(keydef))
|
|
|
|
command = self.commands:getByKeydef(keydef)
|
|
|
|
if command ~= nil then
|
|
|
|
Debug("command to execute: "..tostring(command))
|
|
|
|
ret_code = command.func(self, keydef)
|
|
|
|
else
|
|
|
|
Debug("command not found: "..tostring(command))
|
|
|
|
end
|
|
|
|
if ret_code == "break" then
|
|
|
|
ret_code = nil
|
|
|
|
if self.final_choice then
|
|
|
|
return self.readers[self.final_choice]
|
|
|
|
else
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end -- if
|
|
|
|
end -- while
|
|
|
|
end
|
|
|
|
|
|
|
|
-- add available commands
|
|
|
|
function ReaderChooser:addAllCommands()
|
|
|
|
self.commands = Commands:new{}
|
|
|
|
self.commands:add(KEY_FW_DOWN, nil, "joypad down",
|
|
|
|
"next item",
|
|
|
|
function(self)
|
|
|
|
self.last_item = self.current_item
|
2012-10-22 15:58:04 +00:00
|
|
|
self.current_item = (self.current_item + #self.readers + 1)%#self.readers
|
2012-10-21 16:53:33 +00:00
|
|
|
if self.current_item == 0 then
|
2012-10-22 15:58:04 +00:00
|
|
|
self.current_item = self.current_item + #self.readers
|
2012-10-21 16:53:33 +00:00
|
|
|
end
|
2012-10-22 15:58:04 +00:00
|
|
|
Debug("Last item:", self.last_item, "Current item:", self.current_item, "N items:", #self.readers)
|
2012-10-21 16:53:33 +00:00
|
|
|
self.markerdirty = true
|
|
|
|
end
|
|
|
|
)
|
|
|
|
self.commands:add(KEY_FW_UP, nil, "joypad up",
|
|
|
|
"previous item",
|
|
|
|
function(self)
|
|
|
|
self.last_item = self.current_item
|
2012-10-22 15:58:04 +00:00
|
|
|
self.current_item = (self.current_item + #self.readers - 1)%#self.readers
|
2012-10-21 16:53:33 +00:00
|
|
|
if self.current_item == 0 then
|
2012-10-22 15:58:04 +00:00
|
|
|
self.current_item = self.current_item + #self.readers
|
2012-10-21 16:53:33 +00:00
|
|
|
end
|
2012-10-22 15:58:04 +00:00
|
|
|
Debug("Last item:", self.last_item, "Current item:", self.current_item, "N items:", #self.readers)
|
2012-10-21 16:53:33 +00:00
|
|
|
self.markerdirty = true
|
|
|
|
end
|
|
|
|
)
|
|
|
|
|
2012-10-22 18:47:54 +00:00
|
|
|
self.commands:add(KEY_T, nil, "T",
|
|
|
|
"remember reader choice for this type",
|
2012-10-21 16:53:33 +00:00
|
|
|
function(self)
|
2012-11-07 08:52:06 +00:00
|
|
|
self.remember_preference = not self.remember_preference
|
2012-10-22 18:47:54 +00:00
|
|
|
self.optiondirty = true
|
2012-10-21 16:53:33 +00:00
|
|
|
end
|
|
|
|
)
|
|
|
|
|
2012-10-22 18:47:54 +00:00
|
|
|
self.commands:add(KEY_F, nil, "F",
|
|
|
|
"remember reader choice for this file",
|
2012-10-21 16:53:33 +00:00
|
|
|
function(self)
|
2012-11-07 08:52:06 +00:00
|
|
|
self.remember_association = not self.remember_association
|
2012-10-22 18:47:54 +00:00
|
|
|
self.optiondirty = true
|
2012-10-21 16:53:33 +00:00
|
|
|
end
|
|
|
|
)
|
|
|
|
|
|
|
|
self.commands:add({KEY_ENTER, KEY_FW_PRESS}, nil, "Enter",
|
|
|
|
"choose reader",
|
|
|
|
function(self)
|
|
|
|
self.final_choice = self.current_item
|
|
|
|
return "break"
|
|
|
|
end
|
|
|
|
)
|
2012-10-22 19:26:50 +00:00
|
|
|
self.commands:add(KEY_BACK, nil, "Back",
|
2012-10-21 16:53:33 +00:00
|
|
|
"back",
|
|
|
|
function(self)
|
|
|
|
return "break"
|
|
|
|
end
|
|
|
|
)
|
|
|
|
end
|