Merge pull request #814 from WS64/master

New function, browse series/tags, and sorting of all search results
pull/816/head
Huang Xin 10 years ago
commit 88c80f447b

@ -22,6 +22,7 @@ local Search = InputContainer:new{
authors2 = 6, authors2 = 6,
series_index = 7, series_index = 7,
tags2 = 8, tags2 = 8,
tags3 = 9,
count = 0, count = 0,
data = {}, data = {},
results = {}, results = {},
@ -29,9 +30,57 @@ local Search = InputContainer:new{
browse_tags = {}, browse_tags = {},
browse_series = {}, browse_series = {},
error = nil, error = nil,
use_previous_search_results = false use_previous_search_results = false,
lastsearch = nil,
} }
local function __genOrderedIndex( t )
-- this function is taken from http://lua-users.org/wiki/SortedIteration
local orderedIndex = {}
for key in pairs(t) do
table.insert( orderedIndex, key )
end
table.sort( orderedIndex )
return orderedIndex
end
local function orderedNext(t, state)
-- this function is taken from http://lua-users.org/wiki/SortedIteration
-- Equivalent of the next function, but returns the keys in the alphabetic
-- order. We use a temporary ordered key table that is stored in the
-- table being iterated.
if state == nil then
-- the first time, generate the index
t.__orderedIndex = __genOrderedIndex( t )
key = t.__orderedIndex[1]
return key, t[key]
end
-- fetch the next value
key = nil
for i = 1,table.getn(t.__orderedIndex) do
if t.__orderedIndex[i] == state then
key = t.__orderedIndex[i+1]
end
end
if key then
return key, t[key]
end
-- no more value to return, cleanup
t.__orderedIndex = nil
return
end
local function orderedPairs(t)
-- this function is taken from http://lua-users.org/wiki/SortedIteration
-- Equivalent of the pairs() function on tables. Allows to iterate
-- in order
return orderedNext, t, nil
end
local function unichar (value) local function unichar (value)
-- this function is taken from dkjson -- this function is taken from dkjson
-- http://dkolf.de/src/dkjson-lua.fsl/ -- http://dkolf.de/src/dkjson-lua.fsl/
@ -52,11 +101,6 @@ local function unichar (value)
end end
end end
local function fillbrowse()
if _browse_tags + _browse_series == 0 then
end
end
local function findcalibre(root) local function findcalibre(root)
local t = nil local t = nil
for entity in lfs.dir(root) do for entity in lfs.dir(root) do
@ -148,15 +192,57 @@ function Search:ShowSearch()
buttons = { buttons = {
{ {
{ {
text = _("Find"), text = _("Browse series"),
enabled = true,
callback = function()
self.search_value = self.search_dialog:getInputText()
if not settings_changed and self.search_value == dummy and self.lastsearch == "series" then
self.use_previous_search_results = true
else
self.use_previous_search_results = false
end
self.lastsearch = "series"
self:close()
end,
},
{
text = _("Browse tags"),
enabled = true,
callback = function()
self.search_value = self.search_dialog:getInputText()
if not settings_changed and self.search_value == dummy and self.lastsearch == "tags" then
self.use_previous_search_results = true
else
self.use_previous_search_results = false
end
self.lastsearch = "tags"
self:close()
end,
},
},
{
{
text = _("Cancel"),
enabled = true,
callback = function()
self.search_dialog:onClose()
UIManager:close(self.search_dialog)
--self.use_previous_search_results = true
--self.lastsearch = "tags"
self:close()
end,
},
{
text = _("Find books"),
enabled = true, enabled = true,
callback = function() callback = function()
self.search_value = self.search_dialog:getInputText() self.search_value = self.search_dialog:getInputText()
if not settings_changed and self.search_value == dummy then if not settings_changed and self.search_value == dummy and self.lastsearch == "find" then
self.use_previous_search_results = true self.use_previous_search_results = true
else else
self.use_previous_search_results = false self.use_previous_search_results = false
end end
self.lastsearch = "find"
self:close() self:close()
end, end,
}, },
@ -174,6 +260,7 @@ function Search:ShowSearch()
UIManager:show(InfoMessage:new{text = self.error .. _( " A search for a " .. calibre .. " file was not successful!"),}) UIManager:show(InfoMessage:new{text = self.error .. _( " A search for a " .. calibre .. " file was not successful!"),})
end end
end end
end end
function Search:init() function Search:init()
@ -183,14 +270,16 @@ function Search:init()
end end
function Search:close() function Search:close()
self.search_dialog:onClose() if self.search_value then
UIManager:close(self.search_dialog) self.search_dialog:onClose()
if string.len(self.search_value) > 0 then UIManager:close(self.search_dialog)
self:find() if string.len(self.search_value) > 0 or self.lastsearch ~= "find" then
self:find(self.lastsearch)
end
end end
end end
function Search:find() function Search:find(option)
local f = io.open(self.calibrefile) local f = io.open(self.calibrefile)
local line = f:read() local line = f:read()
local i = 1 local i = 1
@ -220,6 +309,7 @@ function Search:find()
self.data[i][self.authors2] = "" self.data[i][self.authors2] = ""
elseif s == self.tags then elseif s == self.tags then
self.data[i][self.tags2] = "" self.data[i][self.tags2] = ""
self.data[i][self.tags3] = ""
end end
while line ~= " ], " do while line ~= " ], " do
line = f:read() line = f:read()
@ -228,7 +318,10 @@ function Search:find()
if s == self.authors then if s == self.authors then
self.data[i][self.authors2] = self.data[i][self.authors2] .. " & " .. ReplaceHexChars(line,8,3) self.data[i][self.authors2] = self.data[i][self.authors2] .. " & " .. ReplaceHexChars(line,8,3)
elseif s == self.tags then elseif s == self.tags then
self.data[i][self.tags2] = self.data[i][self.tags2] .. " & " .. ReplaceHexChars(line,8,3) local dummy = ReplaceHexChars(line,8,3)
self.data[i][self.tags2] = self.data[i][self.tags2] .. " & " .. dummy
self.data[i][self.tags3] = self.data[i][self.tags3] .. "\n" .. dummy
self.browse_tags[dummy] = (self.browse_tags[dummy] or 0) + 1
end end
end end
end end
@ -237,22 +330,25 @@ function Search:find()
self.data[i][self.authors2] = string.sub(self.data[i][self.authors2],4) self.data[i][self.authors2] = string.sub(self.data[i][self.authors2],4)
elseif s == self.tags then elseif s == self.tags then
self.data[i][self.tags2] = string.sub(self.data[i][self.tags2],4) self.data[i][self.tags2] = string.sub(self.data[i][self.tags2],4)
self.data[i][self.tags3] = self.data[i][self.tags3] .. "\n"
end end
end end
if not self.use_previous_search_results then if not self.use_previous_search_results then
self.reults = {} self.results = {}
self.data = {} self.data = {}
self.browse_series = {}
self.browse_tags = {}
if SEARCH_CASESENSITIVE then if SEARCH_CASESENSITIVE then
upsearch = self.search_value upsearch = self.search_value or ""
else else
upsearch = string.upper(self.search_value) upsearch = string.upper(self.search_value or "")
end end
firstrun = true firstrun = true
self.data[i] = {"-","-","-","-","-","-","-","-"} self.data[i] = {"-","-","-","-","-","-","-","-","-"}
self.libraries[i] = 1 self.libraries[i] = 1
while line do while line do
@ -260,23 +356,38 @@ function Search:find()
-- new calibre data set -- new calibre data set
dummy = "" dummy = ""
if SEARCH_AUTHORS then dummy = dummy .. self.data[i][self.authors] .. "\n" end if option == "find" and SEARCH_AUTHORS then dummy = dummy .. self.data[i][self.authors] .. "\n" end
if SEARCH_TITLE then dummy = dummy .. self.data[i][self.title] .. "\n" end if option == "find" and SEARCH_TITLE then dummy = dummy .. self.data[i][self.title] .. "\n" end
if SEARCH_PATH then dummy = dummy .. self.data[i][self.path] .. "\n" end if option == "find" and SEARCH_PATH then dummy = dummy .. self.data[i][self.path] .. "\n" end
if SEARCH_SERIES then if (option == "series" or SEARCH_SERIES) and self.data[i][self.series] ~= "-" then
dummy = dummy .. self.data[i][self.series] .. "\n" dummy = dummy .. self.data[i][self.series] .. "\n"
self.browse_series[self.data[i][self.series]] = true self.browse_series[self.data[i][self.series]] = (self.browse_series[self.data[i][self.series]] or 0) + 1
end
if SEARCH_TAGS then
dummy = dummy .. self.data[i][self.tags] .. "\n"
self.browse_tags[self.data[i][self.tags]] = true
end end
if option == "tags" or SEARCH_TAGS then dummy = dummy .. self.data[i][self.tags] .. "\n" end
if not SEARCH_CASESENSITIVE then dummy = string.upper(dummy) end if not SEARCH_CASESENSITIVE then dummy = string.upper(dummy) end
if string.find(dummy,upsearch,nil,true) then if upsearch ~= "" then
i = i + 1 if string.find(dummy,upsearch,nil,true) then
i = i + 1
end
else
if option == "series" then
if self.browse_series[self.data[i][self.series]] then
i = i + 1
end
elseif option == "tags" then
local found = false
for j in string.gmatch(self.data[i][self.tags3],"\n[^\n]+") do
if j~="\n" and self.browse_tags[string.sub(j,2)] then
found = true
end
end
if found then
i = i + 1
end
end
end end
self.data[i] = {"-","-","-","-","-","-","-","-"} self.data[i] = {"-","-","-","-","-","-","-","-","-"}
if firstrun then if firstrun then
self.libraries[i] = 1 self.libraries[i] = 1
else else
@ -312,25 +423,40 @@ function Search:find()
end end
if self.count > 0 then if self.count > 0 then
self.data[self.count + 1] = nil self.data[self.count + 1] = nil
self:showresults() if option == "find" then
self:showresults()
else
self:browse(option,1)
end
else else
UIManager:show(InfoMessage:new{text = _("No match for " .. self.search_value)}) if option == "find" then
dummy = _("No match for " .. self.search_value)
else
dummy = _("No ") .. option .. _(" found")
if string.len(self.search_value) > 0 then
dummy = dummy .. _(" matching ") .. self.search_value
end
dummy = dummy .. "!"
end
UIManager:show(InfoMessage:new{text = dummy})
end end
end end
function Search:onMenuHold(item) function Search:onMenuHold(item)
if item.notchecked then if string.len(item.info or "") > 0 then
item.info = item.info .. item.path if item.notchecked then
local f = io.open(item.path) item.info = item.info .. item.path
if f == nil then local f = io.open(item.path)
item.info = item.info .. "\nFile not found!" if f == nil then
else item.info = item.info .. "\n" .. _("File not found!")
item.info = item.info .. "\n" .. string.format("%4.1fM",lfs.attributes(item.path, "size")/1024/1024) else
f:close() item.info = item.info .. "\n" .. _("Size: ") .. string.format("%4.1fM",lfs.attributes(item.path, "size")/1024/1024)
f:close()
end
item.notchecked = false
end end
item.notchecked = false UIManager:show(InfoMessage:new{text = item.info})
end end
UIManager:show(InfoMessage:new{text = item.info})
end end
function Search:showresults() function Search:showresults()
@ -374,15 +500,131 @@ function Search:showresults()
path = libpath .. self.data[i][self.path], path = libpath .. self.data[i][self.path],
text = self.data[i][self.authors] .. ": " .. self.data[i][self.title], text = self.data[i][self.authors] .. ": " .. self.data[i][self.title],
callback = function() callback = function()
if book then showReaderUI(book)
showReaderUI(book)
end
end end
}) })
i = i + 1 i = i + 1
end end
end end
self.search_menu:swithItemTable("Search Results", self.results) table.sort(self.results, function(v1,v2) return v1.text < v2.text end)
self.search_menu:swithItemTable(_("Search Results"), self.results)
UIManager:show(menu_container)
end
function Search:browse(option,run,chosen)
local restart_me = false
local menu_container = CenterContainer:new{
dimen = Screen:getSize(),
}
self.search_menu = Menu:new{
width = Screen:getWidth()-15,
height = Screen:getHeight()-15,
show_parent = menu_container,
onMenuHold = self.onMenuHold,
cface = Font:getFace("cfont", 22),
_manager = self,
}
table.insert(menu_container, self.search_menu)
self.search_menu.close_callback = function()
UIManager:close(menu_container)
if restart_me then
if string.len(self.search_value) > 0 or self.lastsearch ~= "find" then
self.use_previous_search_results = true
self:getCalibre(1)
self:find(self.lastsearch)
end
end
end
local upsearch
local dummy
if SEARCH_CASESENSITIVE then
upsearch = self.search_value or ""
else
upsearch = string.upper(self.search_value or "")
end
if run == 1 then
self.results = {}
if option == "series" then
for v,n in orderedPairs(self.browse_series) do
dummy = v
if not SEARCH_CASESENSITIVE then dummy = string.upper(dummy) end
if string.find(dummy,upsearch,nil,true) then
table.insert(self.results, {
text = v .. " (" .. tostring(self.browse_series[v]) .. ")",
callback = function()
self:browse(option,2,v)
end
})
end
end
else
for v,n in orderedPairs(self.browse_tags) do
dummy = v
if not SEARCH_CASESENSITIVE then dummy = string.upper(dummy) end
if string.find(dummy,upsearch,nil,true) then
table.insert(self.results, {
text = v .. " (" .. tostring(self.browse_tags[v]) .. ")",
callback = function()
self:browse(option,2,v)
end
})
end
end
end
else
restart_me = true
self.results = {}
local i = 1
while i <= self.count do
if (option == "tags" and self.data[i][self.tags3]:find("\n" .. chosen .. "\n",nil,true)) or (option == "series" and chosen == self.data[i][self.series]) then
local dummy = _("Title: ") .. (self.data[i][self.title] or "-") .. "\n \n" ..
_("Author(s): ") .. (self.data[i][self.authors2] or "-") .. "\n \n" ..
_("Tags: ") .. (self.data[i][self.tags2] or "-") .. "\n \n" ..
_("Series: ") .. (self.data[i][self.series] or "-")
if self.data[i][self.series] ~= "-" then
dummy = dummy .. " (" .. tostring(self.data[i][self.series_index]):gsub(".0$","") .. ")"
end
dummy = dummy .. "\n \n" .. _("Path: ")
local libpath
if self.libraries[i] == 1 then
libpath = SEARCH_LIBRARY_PATH
else
libpath = SEARCH_LIBRARY_PATH2
end
local book = libpath .. self.data[i][self.path]
local text
if option == "series" then
text = string.format("%6.1f",self.data[i][self.series_index]):gsub(".0$","") .. ": " .. self.data[i][self.title] .. " (" .. self.data[i][self.authors] .. ")"
else
text = self.data[i][self.authors] .. ": " .. self.data[i][self.title]
end
table.insert(self.results, {
text = text,
info = dummy,
notchecked = true,
path = libpath .. self.data[i][self.path],
callback = function()
showReaderUI(book)
end
})
end
i = i + 1
end
end
local dummy = ""
if run == 1 then
dummy = _("Browse ") .. option
else
dummy = chosen
end
table.sort(self.results, function(v1,v2) return v1.text < v2.text end)
self.search_menu:swithItemTable(dummy, self.results)
UIManager:show(menu_container) UIManager:show(menu_container)
end end

Loading…
Cancel
Save