mirror of https://github.com/koreader/koreader
interim merge of latest upstream
commit
f2e0eb3dfd
@ -0,0 +1 @@
|
||||
$root/.kobo/fmon/fmon $root/koreader.png $root/.kobo/koreader/koreader_kobo.sh &
|
@ -0,0 +1,87 @@
|
||||
require "ui/widget/filechooser"
|
||||
require "apps/filemanager/fmhistory"
|
||||
require "apps/filemanager/fmmenu"
|
||||
|
||||
|
||||
FileManager = InputContainer:extend{
|
||||
title = _("FileManager"),
|
||||
width = Screen:getWidth(),
|
||||
height = Screen:getHeight(),
|
||||
root_path = './',
|
||||
-- our own size
|
||||
dimen = Geom:new{ w = 400, h = 600 },
|
||||
onExit = function() end,
|
||||
}
|
||||
|
||||
function FileManager:init()
|
||||
local exclude_dirs = {"%.sdr$"}
|
||||
|
||||
self.show_parent = self.show_parent or self
|
||||
|
||||
self.banner = FrameContainer:new{
|
||||
padding = 0,
|
||||
bordersize = 0,
|
||||
TextWidget:new{
|
||||
face = Font:getFace("tfont", 24),
|
||||
text = self.title,
|
||||
}
|
||||
}
|
||||
|
||||
local file_chooser = FileChooser:new{
|
||||
-- remeber to adjust the height when new item is added to the group
|
||||
height = Screen:getHeight() - self.banner:getSize().h,
|
||||
is_popout = false,
|
||||
is_borderless = true,
|
||||
has_close_button = true,
|
||||
dir_filter = function(dirname)
|
||||
for _, pattern in ipairs(exclude_dirs) do
|
||||
if dirname:match(pattern) then return end
|
||||
end
|
||||
return true
|
||||
end,
|
||||
file_filter = function(filename)
|
||||
if DocumentRegistry:getProvider(filename) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
function file_chooser:onFileSelect(file)
|
||||
showReaderUI(file)
|
||||
return true
|
||||
end
|
||||
|
||||
self.layout = VerticalGroup:new{
|
||||
self.banner,
|
||||
file_chooser,
|
||||
}
|
||||
|
||||
local fm_ui = FrameContainer:new{
|
||||
padding = 0,
|
||||
bordersize = 0,
|
||||
background = 0,
|
||||
self.layout,
|
||||
}
|
||||
|
||||
self[1] = fm_ui
|
||||
|
||||
self.menu = FileManagerMenu:new{
|
||||
ui = self
|
||||
}
|
||||
table.insert(self, self.menu)
|
||||
table.insert(self, FileManagerHistory:new{
|
||||
ui = self,
|
||||
menu = self.menu
|
||||
})
|
||||
|
||||
self:handleEvent(Event:new("SetDimensions", self.dimen))
|
||||
end
|
||||
|
||||
|
||||
function FileManager:onClose()
|
||||
UIManager:close(self)
|
||||
if self.onExit then
|
||||
self:onExit()
|
||||
end
|
||||
return true
|
||||
end
|
@ -0,0 +1,73 @@
|
||||
FileManagerHistory = InputContainer:extend{
|
||||
hist_menu_title = _("History"),
|
||||
}
|
||||
|
||||
function FileManagerHistory:init()
|
||||
self.ui.menu:registerToMainMenu(self)
|
||||
end
|
||||
|
||||
function FileManagerHistory:onSetDimensions(dimen)
|
||||
self.dimen = dimen
|
||||
end
|
||||
|
||||
function FileManagerHistory:onShowHist()
|
||||
self:updateItemTable()
|
||||
|
||||
local menu_container = CenterContainer:new{
|
||||
dimen = Screen:getSize(),
|
||||
}
|
||||
|
||||
local hist_menu = Menu:new{
|
||||
title = _("History"),
|
||||
item_table = self.hist,
|
||||
ui = self.ui,
|
||||
width = Screen:getWidth()-50,
|
||||
height = Screen:getHeight()-50,
|
||||
show_parent = menu_container,
|
||||
}
|
||||
|
||||
table.insert(menu_container, hist_menu)
|
||||
|
||||
hist_menu.close_callback = function()
|
||||
UIManager:close(menu_container)
|
||||
end
|
||||
|
||||
UIManager:show(menu_container)
|
||||
return true
|
||||
end
|
||||
|
||||
function FileManagerHistory:addToMainMenu(tab_item_table)
|
||||
-- insert table to main reader menu
|
||||
table.insert(tab_item_table.main, {
|
||||
text = self.hist_menu_title,
|
||||
callback = function()
|
||||
self:onShowHist()
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
function FileManagerHistory:updateItemTable()
|
||||
function readHistDir(order_arg, re)
|
||||
local pipe_out = io.popen("ls "..order_arg.." -1 ./history")
|
||||
for f in pipe_out:lines() do
|
||||
table.insert(re, {
|
||||
dir = DocSettings:getPathFromHistory(f),
|
||||
name = DocSettings:getNameFromHistory(f),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
self.hist = {}
|
||||
local last_files = {}
|
||||
readHistDir("-c", last_files)
|
||||
for _,v in pairs(last_files) do
|
||||
table.insert(self.hist, {
|
||||
text = v.name,
|
||||
callback = function()
|
||||
showReaderUI(v.dir .. "/" .. v.name)
|
||||
end
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -0,0 +1,131 @@
|
||||
require "ui/widget/menu"
|
||||
require "ui/widget/touchmenu"
|
||||
|
||||
FileManagerMenu = InputContainer:extend{
|
||||
tab_item_table = nil,
|
||||
registered_widgets = {},
|
||||
}
|
||||
|
||||
function FileManagerMenu:init()
|
||||
self.tab_item_table = {
|
||||
main = {
|
||||
icon = "resources/icons/appbar.pokeball.png",
|
||||
},
|
||||
home = {
|
||||
icon = "resources/icons/appbar.home.png",
|
||||
callback = function()
|
||||
UIManager:close(self.menu_container)
|
||||
self.ui:onClose()
|
||||
end,
|
||||
},
|
||||
}
|
||||
self.registered_widgets = {}
|
||||
|
||||
if Device:hasKeyboard() then
|
||||
self.key_events = {
|
||||
ShowMenu = { { "Menu" }, doc = _("show menu") },
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function FileManagerMenu:initGesListener()
|
||||
self.ges_events = {
|
||||
TapShowMenu = {
|
||||
GestureRange:new{
|
||||
ges = "tap",
|
||||
range = Geom:new{
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = Screen:getWidth()*3/4,
|
||||
h = Screen:getHeight()/4,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function FileManagerMenu:setUpdateItemTable()
|
||||
for _, widget in pairs(self.registered_widgets) do
|
||||
widget:addToMainMenu(self.tab_item_table)
|
||||
end
|
||||
|
||||
if Device:hasFrontlight() then
|
||||
table.insert(self.tab_item_table.main, {
|
||||
text = _("Frontlight settings"),
|
||||
callback = function()
|
||||
ReaderFrontLight:onShowFlDialog()
|
||||
end
|
||||
})
|
||||
end
|
||||
table.insert(self.tab_item_table.main, {
|
||||
text = _("Help"),
|
||||
callback = function()
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("Please report bugs to https://github.com/koreader/ koreader/issues, Click at the bottom of the page for more options"),
|
||||
})
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
function FileManagerMenu:onShowMenu()
|
||||
if #self.tab_item_table.main == 0 then
|
||||
self:setUpdateItemTable()
|
||||
end
|
||||
|
||||
local menu_container = CenterContainer:new{
|
||||
ignore = "height",
|
||||
dimen = Screen:getSize(),
|
||||
}
|
||||
|
||||
local main_menu = nil
|
||||
if Device:isTouchDevice() then
|
||||
main_menu = TouchMenu:new{
|
||||
width = Screen:getWidth(),
|
||||
tab_item_table = {
|
||||
self.tab_item_table.main,
|
||||
self.tab_item_table.home,
|
||||
},
|
||||
show_parent = menu_container,
|
||||
}
|
||||
else
|
||||
main_menu = Menu:new{
|
||||
title = _("File manager menu"),
|
||||
item_table = {},
|
||||
width = Screen:getWidth() - 100,
|
||||
}
|
||||
|
||||
for _,item_table in pairs(self.tab_item_table) do
|
||||
for k,v in ipairs(item_table) do
|
||||
table.insert(main_menu.item_table, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
main_menu.close_callback = function ()
|
||||
UIManager:close(menu_container)
|
||||
end
|
||||
|
||||
menu_container[1] = main_menu
|
||||
-- maintain a reference to menu_container
|
||||
self.menu_container = menu_container
|
||||
UIManager:show(menu_container)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function FileManagerMenu:onTapShowMenu()
|
||||
self:onShowMenu()
|
||||
return true
|
||||
end
|
||||
|
||||
function FileManagerMenu:onSetDimensions(dimen)
|
||||
-- update listening according to new screen dimen
|
||||
if Device:isTouchDevice() then
|
||||
self:initGesListener()
|
||||
end
|
||||
end
|
||||
|
||||
function FileManagerMenu:registerToMainMenu(widget)
|
||||
table.insert(self.registered_widgets, widget)
|
||||
end
|
||||
|
@ -0,0 +1,190 @@
|
||||
-- lulip: LuaJIT line level profiler
|
||||
--
|
||||
-- Copyright (c) 2013 John Graham-Cumming
|
||||
--
|
||||
-- License: http://opensource.org/licenses/MIT
|
||||
|
||||
local io_lines = io.lines
|
||||
local io_open = io.open
|
||||
local pairs = pairs
|
||||
local print = print
|
||||
local debug = debug
|
||||
local tonumber = tonumber
|
||||
local setmetatable = setmetatable
|
||||
local table_sort = table.sort
|
||||
local table_insert = table.insert
|
||||
local string_find = string.find
|
||||
local string_sub = string.sub
|
||||
local string_gsub = string.gsub
|
||||
local string_format = string.format
|
||||
local ffi = require("ffi")
|
||||
|
||||
ffi.cdef[[
|
||||
typedef long time_t;
|
||||
|
||||
typedef struct timeval {
|
||||
time_t tv_sec;
|
||||
time_t tv_usec;
|
||||
} timeval;
|
||||
|
||||
int gettimeofday(struct timeval* t, void* tzp);
|
||||
]]
|
||||
|
||||
module(...)
|
||||
|
||||
local gettimeofday_struct = ffi.new("timeval")
|
||||
local function gettimeofday()
|
||||
ffi.C.gettimeofday(gettimeofday_struct, nil)
|
||||
return tonumber(gettimeofday_struct.tv_sec) * 1000000 + tonumber(gettimeofday_struct.tv_usec)
|
||||
end
|
||||
|
||||
local mt = { __index = _M }
|
||||
|
||||
-- new: create new profiler object
|
||||
function new(self)
|
||||
return setmetatable({
|
||||
|
||||
-- Time when start() and stop() were called in microseconds
|
||||
|
||||
start_time = 0,
|
||||
stop_time = 0,
|
||||
|
||||
-- Per line timing information
|
||||
|
||||
lines = {},
|
||||
|
||||
-- The current line being processed and when it was startd
|
||||
|
||||
current_line = nil,
|
||||
current_start = 0,
|
||||
|
||||
-- List of files to ignore. Set patterns using dont()
|
||||
|
||||
ignore = {},
|
||||
|
||||
-- List of short file names used as a cache
|
||||
|
||||
short = {},
|
||||
|
||||
-- Maximum number of rows of output data, set using maxrows()
|
||||
|
||||
rows = 20,
|
||||
}, mt)
|
||||
end
|
||||
|
||||
-- event: called when a line is executed
|
||||
function event(self, event, line)
|
||||
local now = gettimeofday()
|
||||
|
||||
local f = string_sub(debug.getinfo(3).source,2)
|
||||
for i=1,#self.ignore do
|
||||
if string_find(f, self.ignore[i], 1, true) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local short = self.short[f]
|
||||
if not short then
|
||||
local start = string_find(f, "[^/]+$")
|
||||
self.short[f] = string_sub(f, start)
|
||||
short = self.short[f]
|
||||
end
|
||||
|
||||
if self.current_line ~= nil then
|
||||
self.lines[self.current_line][1] =
|
||||
self.lines[self.current_line][1] + 1
|
||||
self.lines[self.current_line][2] =
|
||||
self.lines[self.current_line][2] + (now - self.current_start)
|
||||
end
|
||||
|
||||
self.current_line = short .. ':' .. line
|
||||
|
||||
if self.lines[self.current_line] == nil then
|
||||
self.lines[self.current_line] = {0, 0.0, f}
|
||||
end
|
||||
|
||||
self.current_start = gettimeofday()
|
||||
end
|
||||
|
||||
-- dont: tell the profiler to ignore files that match these patterns
|
||||
function dont(self, file)
|
||||
table_insert(self.ignore, file)
|
||||
end
|
||||
|
||||
-- maxrows: set the maximum number of rows of output
|
||||
function maxrows(self, max)
|
||||
self.rows = max
|
||||
end
|
||||
|
||||
-- start: begin profiling
|
||||
function start(self)
|
||||
self:dont('lulip.lua')
|
||||
self.start_time = gettimeofday()
|
||||
self.current_line = nil
|
||||
self.current_start = 0
|
||||
debug.sethook(function(e,l) self:event(e, l) end, "l")
|
||||
end
|
||||
|
||||
-- stop: end profiling
|
||||
function stop(self)
|
||||
self.stop_time = gettimeofday()
|
||||
debug.sethook()
|
||||
end
|
||||
|
||||
-- readfile: turn a file into an array for line-level access
|
||||
local function readfile(file)
|
||||
local lines = {}
|
||||
local ln = 1
|
||||
for line in io_lines(file) do
|
||||
lines[ln] = string_gsub(line, "^%s*(.-)%s*$", "%1")
|
||||
ln = ln + 1
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
-- dump: dump profile information to the named file
|
||||
function dump(self, file)
|
||||
local t = {}
|
||||
for l,d in pairs(self.lines) do
|
||||
table_insert(t, {line=l, data=d})
|
||||
end
|
||||
table_sort(t, function(a,b) return a["data"][2] > b["data"][2] end)
|
||||
|
||||
local files = {}
|
||||
|
||||
local f = io_open(file, "w")
|
||||
if not f then
|
||||
print("Failed to open output file " .. file)
|
||||
return
|
||||
end
|
||||
f:write([[
|
||||
<html>
|
||||
<head>
|
||||
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js">
|
||||
</script>
|
||||
<style>.code { padding-left: 20px; }</style>
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%">
|
||||
<thead><tr><th align="left">file:line</th><th align="right">count</th>
|
||||
<th align="right">elapsed (ms)</th><th align="left" class="code">line</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
]])
|
||||
|
||||
for j=1,self.rows do
|
||||
if not t[j] then break end
|
||||
local l = t[j]["line"]
|
||||
local d = t[j]["data"]
|
||||
if not files[d[3]] then
|
||||
files[d[3]] = readfile(d[3])
|
||||
end
|
||||
local ln = tonumber(string_sub(l, string_find(l, ":", 1, true)+1))
|
||||
f:write(string_format([[
|
||||
<tr><td>%s</td><td align="right">%i</td><td align="right">%.3f</td>
|
||||
<td class="code"><code class="prettyprint">%s</code></td></tr>]],
|
||||
l, d[1], d[2]/1000, files[d[3]][ln]))
|
||||
end
|
||||
f:write('</tbody></table></body></html')
|
||||
f:close()
|
||||
end
|
@ -1 +1 @@
|
||||
Subproject commit 698fb1764ffc0eafbd5cdb2dcc6d8165cca8d8f0
|
||||
Subproject commit 2dfda0da69b721c0145b174cf3e5fb578c2894e1
|
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
Loading…
Reference in New Issue