Files
koreader/frontend/apps/filemanager/filemanager.lua
chrox 69e6b6b9cb hold on directory in filemanager can set the it as HOME directory
and this "HOME" directory will override the command line option passed to
koreader.

This patch implements #1434.
2015-03-12 16:29:15 +08:00

322 lines
9.9 KiB
Lua

local FileManagerHistory = require("apps/filemanager/filemanagerhistory")
local InputContainer = require("ui/widget/container/inputcontainer")
local FrameContainer = require("ui/widget/container/framecontainer")
local FileManagerMenu = require("apps/filemanager/filemanagermenu")
local DocumentRegistry = require("document/documentregistry")
local TextWidget = require("ui/widget/textwidget")
local FileChooser = require("ui/widget/filechooser")
local VerticalSpan = require("ui/widget/verticalspan")
local VerticalGroup = require("ui/widget/verticalgroup")
local ButtonDialog = require("ui/widget/buttondialog")
local lfs = require("libs/libkoreader-lfs")
local UIManager = require("ui/uimanager")
local Font = require("ui/font")
local Screen = require("device").screen
local Geom = require("ui/geometry")
local Device = require("device")
local Event = require("ui/event")
local DEBUG = require("dbg")
local _ = require("gettext")
local util = require("ffi/util")
local Blitbuffer = require("ffi/blitbuffer")
local FileManager = InputContainer:extend{
title = _("FileManager"),
root_path = lfs.currentdir(),
-- our own size
dimen = Geom:new{ w = 400, h = 600 },
onExit = function() end,
}
function FileManager:init()
self.show_parent = self.show_parent or self
self.banner = VerticalGroup:new{
TextWidget:new{
face = Font:getFace("tfont", 24),
text = self.title,
},
VerticalSpan:new{ width = Screen:scaleBySize(10) }
}
local g_show_hidden = G_reader_settings:readSetting("show_hidden")
local show_hidden = g_show_hidden == nil and DSHOWHIDDENFILES or g_show_hidden
local file_chooser = FileChooser:new{
-- remeber to adjust the height when new item is added to the group
path = self.root_path,
collate = G_reader_settings:readSetting("collate") or "strcoll",
show_parent = self.show_parent,
show_hidden = show_hidden,
width = Screen:getWidth(),
height = Screen:getHeight() - self.banner:getSize().h,
is_popout = false,
is_borderless = true,
has_close_button = true,
file_filter = function(filename)
if DocumentRegistry:getProvider(filename) then
return true
end
end,
close_callback = function() return self:onClose() end,
}
self.file_chooser = file_chooser
function file_chooser:onFileSelect(file)
local ReaderUI = require("apps/reader/readerui")
ReaderUI:showReader(file)
return true
end
local copyFile = function(file) self:copyFile(file) end
local pasteHere = function(file) self:pasteHere(file) end
local cutFile = function(file) self:cutFile(file) end
local deleteFile = function(file) self:deleteFile(file) end
local fileManager = self
function file_chooser:onFileHold(file)
--DEBUG("hold file", file)
local buttons = {
{
{
text = _("Copy"),
callback = function()
copyFile(file)
UIManager:close(self.file_dialog)
end,
},
{
text = _("Paste"),
enabled = fileManager.clipboard and true or false,
callback = function()
pasteHere(file)
self:refreshPath()
UIManager:close(self.file_dialog)
end,
},
},
{
{
text = _("Cut"),
callback = function()
cutFile(file)
UIManager:close(self.file_dialog)
end,
},
{
text = _("Delete"),
callback = function()
local path = util.realpath(file)
local ConfirmBox = require("ui/widget/confirmbox")
UIManager:close(self.file_dialog)
UIManager:show(ConfirmBox:new{
text = _("Are you sure that you want to delete this file?\n") .. file .. ("\n") .. _("If you delete a file, it is permanently lost."),
ok_callback = function()
deleteFile(file)
self:refreshPath()
end,
})
end,
},
},
}
if lfs.attributes(file, "mode") == "directory" then
local realpath = util.realpath(file)
table.insert(buttons, {
{
text = _("Set as HOME directory"),
callback = function()
G_reader_settings:saveSetting("home_dir", realpath)
UIManager:close(self.file_dialog)
end
}
})
end
self.file_dialog = ButtonDialog:new{
buttons = buttons,
}
UIManager:show(self.file_dialog)
return true
end
self.layout = VerticalGroup:new{
self.banner,
file_chooser,
}
local fm_ui = FrameContainer:new{
padding = 0,
bordersize = 0,
background = Blitbuffer.COLOR_WHITE,
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
})
if Device:hasKeys() then
self.key_events.Close = { {"Home"}, doc = "close filemanager" }
end
self:handleEvent(Event:new("SetDimensions", self.dimen))
end
function FileManager:resetDimen(dimen)
self.dimen = dimen
-- backup the root path and path items
self.root_path = self.file_chooser.path
local path_items_backup = {}
for k, v in pairs(self.file_chooser.path_items) do
path_items_backup[k] = v
end
-- reinit filemanager
self:init()
self.file_chooser.path_items = path_items_backup
self:onRefresh()
end
function FileManager:toggleHiddenFiles()
self.file_chooser:toggleHiddenFiles()
G_reader_settings:saveSetting("show_hidden", self.file_chooser.show_hidden)
end
function FileManager:setCollate(collate)
self.file_chooser:setCollate(collate)
G_reader_settings:saveSetting("collate", self.file_chooser.collate)
end
function FileManager:toggleReverseCollate()
self.file_chooser:toggleReverseCollate()
G_reader_settings:saveSetting("reverse_collate", self.file_chooser.reverse_collate)
end
function FileManager:onClose()
DEBUG("close filemanager")
G_reader_settings:saveSetting("fm_screen_mode", Screen:getScreenMode())
UIManager:close(self)
if self.onExit then
self:onExit()
end
return true
end
function FileManager:onRefresh()
self.file_chooser:refreshPath()
return true
end
function FileManager:getDefaultDir()
if Device:isKindle() then
return "/mnt/us/documents"
elseif Device:isKobo() then
return "/mnt/onboard"
elseif Device.isAndroid() then
return "/sdcard"
else
return "."
end
end
function FileManager:restoreScreenMode()
local screen_mode = G_reader_settings:readSetting("fm_screen_mode")
if Screen:getScreenMode() ~= screen_mode then
Screen:setScreenMode(screen_mode or "portrait")
end
UIManager:setDirty(self, "full")
end
function FileManager:showFiles(path)
DEBUG("show home page")
path = path or G_reader_settings:readSetting("lastdir") or self:getDefaultDir()
G_reader_settings:saveSetting("lastdir", path)
self:restoreScreenMode()
local file_manager = FileManager:new{
dimen = Screen:getSize(),
root_path = path,
onExit = function()
self.instance = nil
end
}
UIManager:show(file_manager)
self.instance = file_manager
end
function FileManager:copyFile(file)
self.cutfile = false
self.clipboard = file
end
function FileManager:cutFile(file)
self.cutfile = true
self.clipboard = file
end
function FileManager:pasteHere(file)
if self.clipboard then
file = util.realpath(file)
local orig = util.realpath(self.clipboard)
local dest = lfs.attributes(file, "mode") == "directory" and
file or file:match("(.*/)")
if self.cutfile then
util.execute("/bin/mv", orig, dest)
else
util.execute("/bin/cp", "-r", orig, dest)
end
end
end
function FileManager:deleteFile(file)
local InfoMessage = require("ui/widget/infomessage")
DEBUG("File to remove", util.realpath(file))
local rm = util.execute("/bin/rm", "-rf", util.realpath(file))
DEBUG("rm status", rm)
if rm == 0 then
UIManager:show(InfoMessage:new{
text = _("Successfully deleted\n") .. file,
timeout = 2,
})
else
UIManager:show(InfoMessage:new{
text = _("An error occurred while trying to delete\n") .. file,
})
end
end
function FileManager:getSortingMenuTable()
local fm = self
local collates = {
strcoll = {_("by title"), _("Sort by title")},
access = {_("by date"), _("Sort by date")},
}
local set_collate_table = function(collate)
return {
text = collates[collate][2],
checked_func = function()
return fm.file_chooser.collate == collate
end,
callback = function() fm:setCollate(collate) end,
}
end
return {
text_func = function()
return util.template(
_("Sort order: %1"),
collates[fm.file_chooser.collate][1]
)
end,
sub_item_table = {
set_collate_table("strcoll"),
set_collate_table("access"),
}
}
end
return FileManager