Skip to content

Commit

Permalink
[feat] Open with: choose which engine to use for file
Browse files Browse the repository at this point in the history
  • Loading branch information
Frenzie committed Feb 1, 2018
1 parent 016c17e commit b00ed14
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 9 deletions.
9 changes: 9 additions & 0 deletions frontend/apps/filemanager/filemanager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,15 @@ function FileManager:init()
-- a little hack to get visual functionality grouping
{},
{
{
text = _("Open with…"),
enabled = lfs.attributes(file, "mode") == "file"
and #(DocumentRegistry:getProviders(file)) > 1,
callback = function()
UIManager:close(self.file_dialog)
DocumentRegistry:showSetProviderButtons(file, FileManager.instance, self, ReaderUI)
end,
},
{
text = _("Convert"),
enabled = lfs.attributes(file, "mode") == "file"
Expand Down
10 changes: 5 additions & 5 deletions frontend/apps/reader/readerui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ function ReaderUI:showFileManager()
end
end

function ReaderUI:showReader(file)
function ReaderUI:showReader(file, provider)
logger.dbg("show reader ui")
require("readhistory"):addItem(file)
if lfs.attributes(file, "mode") ~= "file" then
Expand All @@ -398,7 +398,7 @@ function ReaderUI:showReader(file)
UIManager:nextTick(function()
logger.dbg("creating coroutine for showing reader")
local co = coroutine.create(function()
self:doShowReader(file)
self:doShowReader(file, provider)
end)
local ok, err = coroutine.resume(co)
if err ~= nil or ok == false then
Expand All @@ -410,13 +410,13 @@ function ReaderUI:showReader(file)
end

local _running_instance = nil
function ReaderUI:doShowReader(file)
logger.info("opening file", file)
function ReaderUI:doShowReader(file, provider)
logger.info("opening file", file, "with" ,provider)
-- keep only one instance running
if _running_instance then
_running_instance:onClose()
end
local document = DocumentRegistry:openDocument(file)
local document = DocumentRegistry:openDocument(file, provider)
if not document then
UIManager:show(InfoMessage:new{
text = _("No reader engine for this file or invalid file.")
Expand Down
1 change: 1 addition & 0 deletions frontend/document/credocument.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ local CreDocument = Document:new{
fallback_font = G_reader_settings:readSetting("fallback_font") or "Noto Sans CJK SC",
default_css = "./data/cr3.css",
options = CreOptions,
provider = "crengine",
provider_name = "Cool Reader Engine",
}

Expand Down
1 change: 1 addition & 0 deletions frontend/document/djvudocument.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ local DjvuDocument = Document:new{
options = KoptOptions,
koptinterface = nil,
color_bb_type = Blitbuffer.TYPE_BBRGB24,
provider = "djvulibre",
provider_name = "DjVu Libre",
}

Expand Down
124 changes: 121 additions & 3 deletions frontend/document/documentregistry.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@
This is a registry for document providers
]]--

local ButtonDialogTitle = require("ui/widget/buttondialogtitle")
local ConfirmBox = require("ui/widget/confirmbox")
local Font = require("ui/font")
local UIManager = require("ui/uimanager")
local gettext = require("gettext")
local logger = require("logger")
local util = require("util")
local T = require("ffi/util").template

local DocumentRegistry = {
registry = {},
Expand All @@ -20,11 +27,35 @@ end

--- Returns the preferred registered document handler.
-- @string file
-- @treturn string provider, or nil
-- @treturn table provider, or nil
function DocumentRegistry:getProvider(file)
local providers = self:getProviders(file)

if providers then
-- provider for document
local doc_settings_provider = require("docsettings"):open(file):readSetting("provider")

if doc_settings_provider then
for _, provider in ipairs(providers) do
if provider.provider.provider == doc_settings_provider then
return provider.provider
end
end
end

-- global provider for filetype
local filename_suffix = util.getFileNameSuffix(file)
local g_settings_provider = G_reader_settings:readSetting("provider")

if g_settings_provider and g_settings_provider[filename_suffix] then
for _, provider in ipairs(providers) do
if provider.provider.provider == g_settings_provider[filename_suffix] then
return provider.provider
end
end
end

-- highest weighted provider
return providers[1].provider
end
end
Expand Down Expand Up @@ -54,14 +85,101 @@ function DocumentRegistry:getProviders(file)
end
end

function DocumentRegistry:openDocument(file)
--- Sets the preferred registered document handler.
-- @string file
-- @bool all
-- @treturn string provider, or nil
function DocumentRegistry:setProvider(file, all)
local _, suffix = util.splitFileNameSuffix(file)

print(suffix)
end

function DocumentRegistry:showSetProviderButtons(file, filemanager_instance, ui, reader_ui)
local _, filename_pure = util.splitFilePathName(file)
local filename_suffix = util.getFileNameSuffix(file)

local buttons = {}
local providers = self:getProviders(file)

for _, provider in ipairs(providers) do
table.insert(buttons, {
{
text = string.format("** %s **", provider.provider.provider_name),
},
})
table.insert(buttons, {
{
text = gettext("Just once"),
callback = function()
filemanager_instance:onClose()
reader_ui:showReader(file, provider.provider)
UIManager:close(self.set_provider_dialog)
end,
},
})
table.insert(buttons, {
{
text = gettext("This document"),
callback = function()
UIManager:show(ConfirmBox:new{
text = T(gettext("Always open '%2' with %1?"),
provider.provider.provider_name, filename_pure),
ok_text = gettext("Always"),
ok_callback = function()
local DocSettings = require("docsettings"):open(file)
DocSettings:saveSetting("provider", provider.provider.provider)
DocSettings:flush()

filemanager_instance:onClose()
reader_ui:showReader(file, provider.provider)
UIManager:close(self.set_provider_dialog)
end,
})
end,
},
})
table.insert(buttons, {
{
text = gettext("All documents"),
callback = function()
UIManager:show(ConfirmBox:new{
text = T(gettext("Always open %2 files with %1?"),
provider.provider.provider_name, filename_suffix),
ok_text = gettext("Always"),
ok_callback = function()
local filetype_provider = G_reader_settings:readSetting("provider") or {}
filetype_provider[filename_suffix] = provider.provider.provider
G_reader_settings:saveSetting("provider", filetype_provider)

filemanager_instance:onClose()
reader_ui:showReader(file, provider.provider)
UIManager:close(self.set_provider_dialog)
end,
})
end,
},
})
-- little trick for visual separation
table.insert(buttons, {})
end

self.set_provider_dialog = ButtonDialogTitle:new{
title = T(gettext("Open %1 with:"), filename_pure),
buttons = buttons,
}
UIManager:show(self.set_provider_dialog)
end

function DocumentRegistry:openDocument(file, provider)
-- force a GC, so that any previous document used memory can be reused
-- immediately by this new document without having to wait for the
-- next regular gc. The second call may help reclaming more memory.
collectgarbage()
collectgarbage()
if not self.registry[file] then
local provider = self:getProvider(file)
provider = provider or self:getProvider(file)

if provider ~= nil then
local ok, doc = pcall(provider.new, provider, {file = file})
if ok then
Expand Down
3 changes: 2 additions & 1 deletion frontend/document/pdfdocument.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ local PdfDocument = Document:new{
dc_null = DrawContext.new(),
options = KoptOptions,
koptinterface = nil,
provider = "mupdf",
provider_name = "MuPDF",
}

Expand Down Expand Up @@ -250,7 +251,7 @@ function PdfDocument:register(registry)
registry:addProvider("xhtml", "application/xhtml+xml", self, 100)
registry:addProvider("xml", "application/xml", self, 10)
registry:addProvider("xps", "application/oxps", self, 100)
registry:addProvider("zip", "application/zip", self, 100)
registry:addProvider("zip", "application/zip", self, 10)

--- Picture types ---
registry:addProvider("gif", "image/gif", self, 90)
Expand Down
1 change: 1 addition & 0 deletions frontend/document/picdocument.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ local PicDocument = Document:new{
_document = false,
is_pic = true,
dc_null = DrawContext.new(),
provider = "picdocument",
provider_name = "Picture Document",
}

Expand Down
28 changes: 28 additions & 0 deletions spec/unit/document_registry_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ describe("document registry module", function()

setup(function()
require("commonrequire")
DocSettings = require("docsettings")
DocumentRegistry = require("document/documentregistry")
end)

Expand All @@ -20,4 +21,31 @@ describe("document registry module", function()
assert.is_equal("MuPDF",
providers[2].provider.provider_name)
end)

it("should return per-document setting for rendering engine", function()
local path = "../../foo.epub"
local docsettings = DocSettings:open(path)
docsettings:saveSetting("provider", "mupdf")
docsettings:flush()

local provider = DocumentRegistry:getProvider(path)

assert.is_equal("mupdf", provider.provider)

docsettings:purge()
docsettings:flush()
end)

it("should return global setting for rendering engine", function()
local path = "../../foofoo.fb2"
local provider_setting = {}
provider_setting.fb2 = "mupdf"
G_reader_settings:saveSetting("provider", provider_setting)

local provider = DocumentRegistry:getProvider(path)

assert.is_equal("mupdf", provider.provider)

G_reader_settings:delSetting("provider")
end)
end)

0 comments on commit b00ed14

Please sign in to comment.