mirror of
https://github.com/koreader/koreader.git
synced 2025-12-24 12:14:05 +01:00
Notebook file (#12699)
This commit is contained in:
@@ -12,17 +12,18 @@ local DocumentRegistry = require("document/documentregistry")
|
|||||||
local Event = require("ui/event")
|
local Event = require("ui/event")
|
||||||
local InfoMessage = require("ui/widget/infomessage")
|
local InfoMessage = require("ui/widget/infomessage")
|
||||||
local InputDialog = require("ui/widget/inputdialog")
|
local InputDialog = require("ui/widget/inputdialog")
|
||||||
|
local Notification = require("ui/widget/notification")
|
||||||
local TextViewer = require("ui/widget/textviewer")
|
local TextViewer = require("ui/widget/textviewer")
|
||||||
local UIManager = require("ui/uimanager")
|
local UIManager = require("ui/uimanager")
|
||||||
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
local Utf8Proc = require("ffi/utf8proc")
|
local ffiUtil = require("ffi/util")
|
||||||
local filemanagerutil = require("apps/filemanager/filemanagerutil")
|
local filemanagerutil = require("apps/filemanager/filemanagerutil")
|
||||||
local lfs = require("libs/libkoreader-lfs")
|
local lfs = require("libs/libkoreader-lfs")
|
||||||
local util = require("util")
|
local util = require("util")
|
||||||
local _ = require("gettext")
|
local _ = require("gettext")
|
||||||
local N_ = _.ngettext
|
local N_ = _.ngettext
|
||||||
local Screen = Device.screen
|
local Screen = Device.screen
|
||||||
local T = require("ffi/util").template
|
local T = ffiUtil.template
|
||||||
|
|
||||||
local BookInfo = WidgetContainer:extend{
|
local BookInfo = WidgetContainer:extend{
|
||||||
title = _("Book information"),
|
title = _("Book information"),
|
||||||
@@ -73,6 +74,15 @@ function BookInfo:show(doc_settings_or_file, book_props)
|
|||||||
-- File section
|
-- File section
|
||||||
local has_sidecar = type(doc_settings_or_file) == "table"
|
local has_sidecar = type(doc_settings_or_file) == "table"
|
||||||
local file = has_sidecar and doc_settings_or_file:readSetting("doc_path") or doc_settings_or_file
|
local file = has_sidecar and doc_settings_or_file:readSetting("doc_path") or doc_settings_or_file
|
||||||
|
self.is_current_doc = self.document and self.document.file == file
|
||||||
|
if not has_sidecar and self.is_current_doc then
|
||||||
|
doc_settings_or_file = self.ui.doc_settings
|
||||||
|
has_sidecar = true
|
||||||
|
end
|
||||||
|
if not has_sidecar and DocSettings:hasSidecarFile(file) then
|
||||||
|
doc_settings_or_file = DocSettings:open(file)
|
||||||
|
has_sidecar = true
|
||||||
|
end
|
||||||
local folder, filename = util.splitFilePathName(file)
|
local folder, filename = util.splitFilePathName(file)
|
||||||
local __, filetype = filemanagerutil.splitFileNameType(filename)
|
local __, filetype = filemanagerutil.splitFileNameType(filename)
|
||||||
local attr = lfs.attributes(file)
|
local attr = lfs.attributes(file)
|
||||||
@@ -172,7 +182,15 @@ function BookInfo:show(doc_settings_or_file, book_props)
|
|||||||
table.insert(kv_pairs, { _("Rating:"), ("★"):rep(rating) .. ("☆"):rep(self.rating_max - rating),
|
table.insert(kv_pairs, { _("Rating:"), ("★"):rep(rating) .. ("☆"):rep(self.rating_max - rating),
|
||||||
hold_callback = summary_hold_callback })
|
hold_callback = summary_hold_callback })
|
||||||
table.insert(kv_pairs, { _("Review:"), summary.note or _("N/A"),
|
table.insert(kv_pairs, { _("Review:"), summary.note or _("N/A"),
|
||||||
hold_callback = summary_hold_callback })
|
hold_callback = summary_hold_callback, separator = true })
|
||||||
|
|
||||||
|
-- Notebook file
|
||||||
|
local notebook_file = self:getNotebookFile(doc_settings_or_file)
|
||||||
|
local notebook_file_callback = function()
|
||||||
|
self:showNotebookFileDialog(notebook_file, doc_settings_or_file, book_props)
|
||||||
|
end
|
||||||
|
table.insert(kv_pairs, { _("Notebook file:"), notebook_file:gsub(".*/", ""),
|
||||||
|
callback = notebook_file_callback })
|
||||||
|
|
||||||
local KeyValuePage = require("ui/widget/keyvaluepage")
|
local KeyValuePage = require("ui/widget/keyvaluepage")
|
||||||
self.kvp_widget = KeyValuePage:new{
|
self.kvp_widget = KeyValuePage:new{
|
||||||
@@ -296,10 +314,7 @@ function BookInfo:findInProps(book_props, search_string, case_sensitive)
|
|||||||
elseif key == "description" then
|
elseif key == "description" then
|
||||||
prop = util.htmlToPlainTextIfHtml(prop)
|
prop = util.htmlToPlainTextIfHtml(prop)
|
||||||
end
|
end
|
||||||
if not case_sensitive then
|
if util.stringSearch(prop, search_string, case_sensitive) ~= 0 then
|
||||||
prop = Utf8Proc.lowercase(util.fixUtf8(prop, "?"))
|
|
||||||
end
|
|
||||||
if prop:find(search_string) then
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -469,7 +484,7 @@ function BookInfo:setCustomMetadata(file, book_props, prop_key, prop_value)
|
|||||||
if prop_key == "title" then -- generate when resetting the customized title and original is empty
|
if prop_key == "title" then -- generate when resetting the customized title and original is empty
|
||||||
book_props.display_title = book_props.title or filemanagerutil.splitFileNameType(file)
|
book_props.display_title = book_props.title or filemanagerutil.splitFileNameType(file)
|
||||||
end
|
end
|
||||||
if self.document and self.document.file == file then -- currently opened document
|
if self.is_current_doc then
|
||||||
self.ui.doc_props[prop_key] = prop_value
|
self.ui.doc_props[prop_key] = prop_value
|
||||||
if prop_key == "title" then
|
if prop_key == "title" then
|
||||||
self.ui.doc_props.display_title = book_props.display_title
|
self.ui.doc_props.display_title = book_props.display_title
|
||||||
@@ -666,6 +681,159 @@ function BookInfo:editSummary(doc_settings_or_file, book_props)
|
|||||||
input_dialog:onShowKeyboard(true)
|
input_dialog:onShowKeyboard(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- notebook file
|
||||||
|
|
||||||
|
function BookInfo:getNotebookFile(doc_settings_or_file)
|
||||||
|
local notebook_file
|
||||||
|
if type(doc_settings_or_file) == "table" then
|
||||||
|
notebook_file = doc_settings_or_file:readSetting("notebook_file")
|
||||||
|
end
|
||||||
|
if notebook_file == nil then
|
||||||
|
notebook_file = G_reader_settings:readSetting("notebook_file")
|
||||||
|
if notebook_file == nil then
|
||||||
|
if type(doc_settings_or_file) == "table" then
|
||||||
|
notebook_file = doc_settings_or_file:readSetting("doc_path") .. ".txt"
|
||||||
|
elseif type(doc_settings_or_file) == "string" then
|
||||||
|
notebook_file = doc_settings_or_file .. ".txt"
|
||||||
|
else
|
||||||
|
local home_folder = G_reader_settings:readSetting("home_dir") or filemanagerutil.getDefaultDir()
|
||||||
|
notebook_file = ffiUtil.realpath(home_folder) .. "/notebook.txt"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return notebook_file
|
||||||
|
end
|
||||||
|
|
||||||
|
function BookInfo:showNotebookFileDialog(notebook_file, doc_settings_or_file, book_props)
|
||||||
|
local has_sidecar = type(doc_settings_or_file) == "table"
|
||||||
|
local file = has_sidecar and doc_settings_or_file:readSetting("doc_path") or doc_settings_or_file
|
||||||
|
local function saveNotebookFile(new_notebook_file)
|
||||||
|
if not has_sidecar then
|
||||||
|
doc_settings_or_file = DocSettings:open(doc_settings_or_file)
|
||||||
|
end
|
||||||
|
doc_settings_or_file:saveSetting("notebook_file", new_notebook_file)
|
||||||
|
if not self.is_current_doc then
|
||||||
|
if new_notebook_file or doc_settings_or_file:readSetting("summary") then
|
||||||
|
doc_settings_or_file:flush()
|
||||||
|
else -- remove empty sidecar
|
||||||
|
doc_settings_or_file:purge(nil, { doc_settings = true }) -- keep custom
|
||||||
|
doc_settings_or_file = file -- to reopen bookinfo
|
||||||
|
end
|
||||||
|
self.summary_updated = true -- refresh FM
|
||||||
|
end
|
||||||
|
self.kvp_widget:onClose()
|
||||||
|
self:show(doc_settings_or_file, book_props)
|
||||||
|
end
|
||||||
|
|
||||||
|
local button_dialog
|
||||||
|
local local_notebook_file = file .. ".txt"
|
||||||
|
local default_notebook_file = G_reader_settings:readSetting("notebook_file")
|
||||||
|
local buttons = {
|
||||||
|
{
|
||||||
|
{
|
||||||
|
text = _("Use default"),
|
||||||
|
enabled = default_notebook_file ~= nil and notebook_file ~= default_notebook_file,
|
||||||
|
callback = function()
|
||||||
|
UIManager:close(button_dialog)
|
||||||
|
saveNotebookFile(default_notebook_file)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = _("Reset default"),
|
||||||
|
enabled = default_notebook_file ~= nil,
|
||||||
|
callback = function()
|
||||||
|
UIManager:close(button_dialog)
|
||||||
|
G_reader_settings:delSetting("notebook_file")
|
||||||
|
Notification:notify(_("Notebook file default location reset"), Notification.SOURCE_ALWAYS_SHOW)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
text = _("Use local"),
|
||||||
|
enabled = notebook_file ~= local_notebook_file,
|
||||||
|
callback = function()
|
||||||
|
UIManager:close(button_dialog)
|
||||||
|
saveNotebookFile(local_notebook_file)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = _("Set as default"),
|
||||||
|
enabled = notebook_file ~= default_notebook_file,
|
||||||
|
callback = function()
|
||||||
|
UIManager:close(button_dialog)
|
||||||
|
G_reader_settings:saveSetting("notebook_file", notebook_file)
|
||||||
|
Notification:notify(_("Notebook file default location saved"), Notification.SOURCE_ALWAYS_SHOW)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
text = _("Choose"),
|
||||||
|
callback = function()
|
||||||
|
UIManager:close(button_dialog)
|
||||||
|
local PathChooser = require("ui/widget/pathchooser")
|
||||||
|
local path_chooser = PathChooser:new{
|
||||||
|
path = notebook_file:match("(.*)/"),
|
||||||
|
select_directory = false,
|
||||||
|
onConfirm = saveNotebookFile,
|
||||||
|
}
|
||||||
|
UIManager:show(path_chooser)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = _("Create"),
|
||||||
|
enabled = self.ui.texteditor ~= nil,
|
||||||
|
callback = function()
|
||||||
|
UIManager:close(button_dialog)
|
||||||
|
self.ui.texteditor:newFile(notebook_file, saveNotebookFile)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{}, -- separator
|
||||||
|
{
|
||||||
|
{
|
||||||
|
text = _("View"),
|
||||||
|
enabled = lfs.attributes(notebook_file, "mode") == "file",
|
||||||
|
callback = function()
|
||||||
|
UIManager:close(button_dialog)
|
||||||
|
TextViewer.openFile(notebook_file)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = _("Edit"),
|
||||||
|
enabled = self.ui.texteditor ~= nil,
|
||||||
|
callback = function()
|
||||||
|
UIManager:close(button_dialog)
|
||||||
|
self.ui.texteditor:openFile(notebook_file, saveNotebookFile)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
button_dialog = ButtonDialog:new{
|
||||||
|
title = notebook_file,
|
||||||
|
title_align = "center",
|
||||||
|
buttons = buttons,
|
||||||
|
}
|
||||||
|
UIManager:show(button_dialog)
|
||||||
|
end
|
||||||
|
|
||||||
|
function BookInfo:onShowNotebookFile()
|
||||||
|
local notebook_file = self:getNotebookFile(self.ui.doc_settings)
|
||||||
|
if self.ui.texteditor then
|
||||||
|
local function saveNotebookFile(new_notebook_file)
|
||||||
|
if self.ui.doc_settings ~= nil then
|
||||||
|
self.ui.doc_settings:saveSetting("notebook_file", new_notebook_file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.ui.texteditor:openFile(notebook_file, saveNotebookFile)
|
||||||
|
elseif lfs.attributes(notebook_file, "mode") == "file" then
|
||||||
|
TextViewer.openFile(notebook_file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- book metadata (sdr)
|
||||||
|
|
||||||
function BookInfo:moveBookMetadata()
|
function BookInfo:moveBookMetadata()
|
||||||
-- called by filemanagermenu only
|
-- called by filemanagermenu only
|
||||||
local file_chooser = self.ui.file_chooser
|
local file_chooser = self.ui.file_chooser
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ local Device = require("device")
|
|||||||
local DocSettings = require("docsettings")
|
local DocSettings = require("docsettings")
|
||||||
local Event = require("ui/event")
|
local Event = require("ui/event")
|
||||||
local UIManager = require("ui/uimanager")
|
local UIManager = require("ui/uimanager")
|
||||||
local ffiutil = require("ffi/util")
|
local ffiUtil = require("ffi/util")
|
||||||
local lfs = require("libs/libkoreader-lfs")
|
local lfs = require("libs/libkoreader-lfs")
|
||||||
local util = require("util")
|
local util = require("util")
|
||||||
local _ = require("gettext")
|
local _ = require("gettext")
|
||||||
local T = ffiutil.template
|
local T = ffiUtil.template
|
||||||
|
|
||||||
local filemanagerutil = {}
|
local filemanagerutil = {}
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ function filemanagerutil.resetDocumentSettings(file)
|
|||||||
last_page = true,
|
last_page = true,
|
||||||
last_xpointer = true,
|
last_xpointer = true,
|
||||||
}
|
}
|
||||||
local file_abs_path = ffiutil.realpath(file)
|
local file_abs_path = ffiUtil.realpath(file)
|
||||||
if file_abs_path then
|
if file_abs_path then
|
||||||
local doc_settings = DocSettings:open(file_abs_path)
|
local doc_settings = DocSettings:open(file_abs_path)
|
||||||
for k in pairs(doc_settings.data) do
|
for k in pairs(doc_settings.data) do
|
||||||
@@ -141,7 +141,7 @@ function filemanagerutil.genStatusButtonsRow(doc_settings_or_file, caller_callba
|
|||||||
local file, summary, status
|
local file, summary, status
|
||||||
if type(doc_settings_or_file) == "table" then
|
if type(doc_settings_or_file) == "table" then
|
||||||
file = doc_settings_or_file:readSetting("doc_path")
|
file = doc_settings_or_file:readSetting("doc_path")
|
||||||
summary = doc_settings_or_file:readSetting("summary", {})
|
summary = doc_settings_or_file:readSetting("summary") or {}
|
||||||
status = summary.status
|
status = summary.status
|
||||||
else
|
else
|
||||||
file = doc_settings_or_file
|
file = doc_settings_or_file
|
||||||
@@ -175,7 +175,7 @@ function filemanagerutil.genResetSettingsButton(doc_settings_or_file, caller_cal
|
|||||||
file = doc_settings_or_file:readSetting("doc_path")
|
file = doc_settings_or_file:readSetting("doc_path")
|
||||||
has_sidecar_file = true
|
has_sidecar_file = true
|
||||||
else
|
else
|
||||||
file = ffiutil.realpath(doc_settings_or_file) or doc_settings_or_file
|
file = ffiUtil.realpath(doc_settings_or_file) or doc_settings_or_file
|
||||||
has_sidecar_file = DocSettings:hasSidecarFile(file)
|
has_sidecar_file = DocSettings:hasSidecarFile(file)
|
||||||
end
|
end
|
||||||
local custom_cover_file = DocSettings:findCustomCoverFile(file)
|
local custom_cover_file = DocSettings:findCustomCoverFile(file)
|
||||||
@@ -262,8 +262,8 @@ function filemanagerutil.genBookInformationButton(doc_settings_or_file, book_pro
|
|||||||
enabled = not button_disabled,
|
enabled = not button_disabled,
|
||||||
callback = function()
|
callback = function()
|
||||||
caller_callback()
|
caller_callback()
|
||||||
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
|
local ui = require("apps/reader/readerui").instance or require("apps/filemanager/filemanager").instance
|
||||||
FileManagerBookInfo:show(doc_settings_or_file, book_props and FileManagerBookInfo.extendProps(book_props))
|
ui.bookinfo:show(doc_settings_or_file, book_props and ui.bookinfo.extendProps(book_props))
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@@ -275,8 +275,8 @@ function filemanagerutil.genBookCoverButton(file, book_props, caller_callback, b
|
|||||||
enabled = (not button_disabled and (not book_props or has_cover)) and true or false,
|
enabled = (not button_disabled and (not book_props or has_cover)) and true or false,
|
||||||
callback = function()
|
callback = function()
|
||||||
caller_callback()
|
caller_callback()
|
||||||
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
|
local ui = require("apps/reader/readerui").instance or require("apps/filemanager/filemanager").instance
|
||||||
FileManagerBookInfo:onShowBookCover(file)
|
ui.bookinfo:onShowBookCover(file)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@@ -289,8 +289,8 @@ function filemanagerutil.genBookDescriptionButton(file, book_props, caller_callb
|
|||||||
enabled = (not (button_disabled or book_props) or description) and true or false,
|
enabled = (not (button_disabled or book_props) or description) and true or false,
|
||||||
callback = function()
|
callback = function()
|
||||||
caller_callback()
|
caller_callback()
|
||||||
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
|
local ui = require("apps/reader/readerui").instance or require("apps/filemanager/filemanager").instance
|
||||||
FileManagerBookInfo:onShowBookDescription(description, file)
|
ui.bookinfo:onShowBookDescription(description, file)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@@ -305,17 +305,17 @@ function filemanagerutil.genExecuteScriptButton(file, caller_callback)
|
|||||||
caller_callback()
|
caller_callback()
|
||||||
local script_is_running_msg = InfoMessage:new{
|
local script_is_running_msg = InfoMessage:new{
|
||||||
-- @translators %1 is the script's programming language (e.g., shell or python), %2 is the filename
|
-- @translators %1 is the script's programming language (e.g., shell or python), %2 is the filename
|
||||||
text = T(_("Running %1 script %2…"), util.getScriptType(file), BD.filename(ffiutil.basename(file))),
|
text = T(_("Running %1 script %2…"), util.getScriptType(file), BD.filename(ffiUtil.basename(file))),
|
||||||
}
|
}
|
||||||
UIManager:show(script_is_running_msg)
|
UIManager:show(script_is_running_msg)
|
||||||
UIManager:scheduleIn(0.5, function()
|
UIManager:scheduleIn(0.5, function()
|
||||||
local rv
|
local rv
|
||||||
if Device:isAndroid() then
|
if Device:isAndroid() then
|
||||||
Device:setIgnoreInput(true)
|
Device:setIgnoreInput(true)
|
||||||
rv = os.execute("sh " .. ffiutil.realpath(file)) -- run by sh, because sdcard has no execute permissions
|
rv = os.execute("sh " .. ffiUtil.realpath(file)) -- run by sh, because sdcard has no execute permissions
|
||||||
Device:setIgnoreInput(false)
|
Device:setIgnoreInput(false)
|
||||||
else
|
else
|
||||||
rv = os.execute(ffiutil.realpath(file))
|
rv = os.execute(ffiUtil.realpath(file))
|
||||||
end
|
end
|
||||||
UIManager:close(script_is_running_msg)
|
UIManager:close(script_is_running_msg)
|
||||||
if rv == 0 then
|
if rv == 0 then
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ local settingsList = {
|
|||||||
history_search = {category="none", event="SearchHistory", title=_("History search"), general=true},
|
history_search = {category="none", event="SearchHistory", title=_("History search"), general=true},
|
||||||
favorites = {category="none", event="ShowColl", title=_("Favorites"), general=true},
|
favorites = {category="none", event="ShowColl", title=_("Favorites"), general=true},
|
||||||
collections = {category="none", event="ShowCollList", title=_("Collections"), general=true},
|
collections = {category="none", event="ShowCollList", title=_("Collections"), general=true},
|
||||||
filemanager = {category="none", event="Home", title=_("File browser"), general=true, separator=true},
|
filemanager = {category="none", event="Home", title=_("File browser"), general=true},
|
||||||
|
notebook_file = {category="none", event="ShowNotebookFile", title=_("Notebook file"), general=true, separator=true},
|
||||||
----
|
----
|
||||||
dictionary_lookup = {category="none", event="ShowDictionaryLookup", title=_("Dictionary lookup"), general=true},
|
dictionary_lookup = {category="none", event="ShowDictionaryLookup", title=_("Dictionary lookup"), general=true},
|
||||||
wikipedia_lookup = {category="none", event="ShowWikipediaLookup", title=_("Wikipedia lookup"), general=true, separator=true},
|
wikipedia_lookup = {category="none", event="ShowWikipediaLookup", title=_("Wikipedia lookup"), general=true, separator=true},
|
||||||
@@ -185,7 +186,7 @@ local settingsList = {
|
|||||||
book_status = {category="none", event="ShowBookStatus", title=_("Book status"), reader=true},
|
book_status = {category="none", event="ShowBookStatus", title=_("Book status"), reader=true},
|
||||||
book_info = {category="none", event="ShowBookInfo", title=_("Book information"), reader=true},
|
book_info = {category="none", event="ShowBookInfo", title=_("Book information"), reader=true},
|
||||||
book_description = {category="none", event="ShowBookDescription", title=_("Book description"), reader=true},
|
book_description = {category="none", event="ShowBookDescription", title=_("Book description"), reader=true},
|
||||||
book_cover = {category="none", event="ShowBookCover", title=_("Book cover"), reader=true, separator=true},
|
book_cover = {category="none", event="ShowBookCover", title=_("Book cover"), reader=true},
|
||||||
----
|
----
|
||||||
translate_page = {category="none", event="TranslateCurrentPage", title=_("Translate current page"), reader=true, separator=true},
|
translate_page = {category="none", event="TranslateCurrentPage", title=_("Translate current page"), reader=true, separator=true},
|
||||||
----
|
----
|
||||||
@@ -289,6 +290,7 @@ local dispatcher_menu_order = {
|
|||||||
"favorites",
|
"favorites",
|
||||||
"collections",
|
"collections",
|
||||||
"filemanager",
|
"filemanager",
|
||||||
|
"notebook_file",
|
||||||
----
|
----
|
||||||
"dictionary_lookup",
|
"dictionary_lookup",
|
||||||
"wikipedia_lookup",
|
"wikipedia_lookup",
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ local PathChooser = require("ui/widget/pathchooser")
|
|||||||
local Trapper = require("ui/trapper")
|
local Trapper = require("ui/trapper")
|
||||||
local UIManager = require("ui/uimanager")
|
local UIManager = require("ui/uimanager")
|
||||||
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
local ffiutil = require("ffi/util")
|
local ffiUtil = require("ffi/util")
|
||||||
local lfs = require("libs/libkoreader-lfs")
|
local lfs = require("libs/libkoreader-lfs")
|
||||||
local logger = require("logger")
|
local logger = require("logger")
|
||||||
local util = require("util")
|
local util = require("util")
|
||||||
local _ = require("gettext")
|
local _ = require("gettext")
|
||||||
local Screen = require("device").screen
|
local Screen = require("device").screen
|
||||||
local T = ffiutil.template
|
local T = ffiUtil.template
|
||||||
|
|
||||||
local TextEditor = WidgetContainer:extend{
|
local TextEditor = WidgetContainer:extend{
|
||||||
name = "texteditor",
|
name = "texteditor",
|
||||||
@@ -60,8 +60,8 @@ function TextEditor:isFileTypeSupported(file)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function TextEditor:openFile(file)
|
function TextEditor:openFile(file, caller_callback)
|
||||||
self:checkEditFile(file)
|
self:checkEditFile(file, nil, nil, caller_callback)
|
||||||
end
|
end
|
||||||
|
|
||||||
function TextEditor:loadSettings()
|
function TextEditor:loadSettings()
|
||||||
@@ -72,7 +72,7 @@ function TextEditor:loadSettings()
|
|||||||
-- NOTE: addToHistory assigns a new object
|
-- NOTE: addToHistory assigns a new object
|
||||||
self.history = self.settings:readSetting("history") or {}
|
self.history = self.settings:readSetting("history") or {}
|
||||||
self.last_view_pos = self.settings:readSetting("last_view_pos") or {}
|
self.last_view_pos = self.settings:readSetting("last_view_pos") or {}
|
||||||
self.last_path = self.settings:readSetting("last_path") or ffiutil.realpath(DataStorage:getDataDir())
|
self.last_path = self.settings:readSetting("last_path") or ffiUtil.realpath(DataStorage:getDataDir())
|
||||||
self.font_face = self.settings:readSetting("font_face") or self.normal_font
|
self.font_face = self.settings:readSetting("font_face") or self.normal_font
|
||||||
self.font_size = self.settings:readSetting("font_size") or self.default_font_size
|
self.font_size = self.settings:readSetting("font_size") or self.default_font_size
|
||||||
-- The font settings could be saved in G_reader_setting if we want them
|
-- The font settings could be saved in G_reader_setting if we want them
|
||||||
@@ -342,55 +342,54 @@ function TextEditor:addToHistory(file_path)
|
|||||||
self.history = new_history
|
self.history = new_history
|
||||||
end
|
end
|
||||||
|
|
||||||
function TextEditor:newFile()
|
function TextEditor:newFile(new_path, caller_callback)
|
||||||
self:loadSettings()
|
self:loadSettings()
|
||||||
UIManager:show(ConfirmBox:new{
|
new_path = new_path or (self.last_path == "/" and "/" or self.last_path .. "/")
|
||||||
text = _([[To start editing a new file, you will have to:
|
local file_input
|
||||||
|
file_input = InputDialog:new{
|
||||||
- First choose a folder
|
title = _("Enter filename"),
|
||||||
- Then enter a name for the new file
|
input = new_path,
|
||||||
- And start editing it
|
buttons = {
|
||||||
|
{
|
||||||
Do you want to proceed?]]),
|
{
|
||||||
ok_text = _("Yes"),
|
text = _("Choose folder"),
|
||||||
cancel_text = _("No"),
|
callback = function()
|
||||||
ok_callback = function()
|
UIManager:close(file_input) -- need to close keyboard
|
||||||
local path_chooser = PathChooser:new{
|
local path_chooser = PathChooser:new{
|
||||||
select_file = false,
|
select_file = false,
|
||||||
path = self.last_path,
|
path = new_path:match("(.*)/"),
|
||||||
onConfirm = function(dir_path)
|
onConfirm = function(dir_path)
|
||||||
local file_input
|
self:newFile(dir_path .. "/", caller_callback)
|
||||||
file_input = InputDialog:new{
|
end,
|
||||||
title = _("Enter filename"),
|
}
|
||||||
input = dir_path == "/" and "/" or dir_path .. "/",
|
UIManager:show(path_chooser)
|
||||||
buttons = {{
|
end,
|
||||||
{
|
},
|
||||||
text = _("Cancel"),
|
},
|
||||||
id = "close",
|
{
|
||||||
callback = function()
|
{
|
||||||
UIManager:close(file_input)
|
text = _("Cancel"),
|
||||||
end,
|
id = "close",
|
||||||
},
|
callback = function()
|
||||||
{
|
UIManager:close(file_input)
|
||||||
text = _("Edit"),
|
end,
|
||||||
callback = function()
|
},
|
||||||
local file_path = file_input:getInputText()
|
{
|
||||||
UIManager:close(file_input)
|
text = _("Edit"),
|
||||||
-- Remember last_path
|
callback = function()
|
||||||
self.last_path = file_path:match("(.*)/")
|
local file_path = file_input:getInputText()
|
||||||
if self.last_path == "" then self.last_path = "/" end
|
UIManager:close(file_input)
|
||||||
self:checkEditFile(file_path, false, true)
|
-- Remember last_path
|
||||||
end,
|
self.last_path = file_path:match("(.*)/")
|
||||||
},
|
if self.last_path == "" then self.last_path = "/" end
|
||||||
}},
|
self:checkEditFile(file_path, false, true, caller_callback)
|
||||||
}
|
end,
|
||||||
UIManager:show(file_input)
|
},
|
||||||
file_input:onShowKeyboard()
|
},
|
||||||
end,
|
},
|
||||||
}
|
}
|
||||||
UIManager:show(path_chooser)
|
UIManager:show(file_input)
|
||||||
end,
|
file_input:onShowKeyboard()
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function TextEditor:chooseFile()
|
function TextEditor:chooseFile()
|
||||||
@@ -408,23 +407,23 @@ function TextEditor:chooseFile()
|
|||||||
UIManager:show(path_chooser)
|
UIManager:show(path_chooser)
|
||||||
end
|
end
|
||||||
|
|
||||||
function TextEditor:checkEditFile(file_path, from_history, possibly_new_file)
|
function TextEditor:checkEditFile(file_path, from_history, possibly_new_file, caller_callback)
|
||||||
self:loadSettings()
|
self:loadSettings()
|
||||||
local attr = lfs.attributes(file_path)
|
local attr = lfs.attributes(file_path)
|
||||||
if not possibly_new_file and not attr then
|
if not possibly_new_file and not attr then
|
||||||
UIManager:show(ConfirmBox:new{
|
UIManager:show(ConfirmBox:new{
|
||||||
text = T(_("This file does not exist anymore:\n\n%1\n\nDo you want to create it and start editing it?"), BD.filepath(file_path)),
|
text = T(_("This file does not exist:\n\n%1\n\nDo you want to create it and start editing it?"), BD.filepath(file_path)),
|
||||||
ok_text = _("Create"),
|
ok_text = _("Create"),
|
||||||
ok_callback = function()
|
ok_callback = function()
|
||||||
-- go again thru there with possibly_new_file=true
|
-- go again thru there with possibly_new_file=true
|
||||||
self:checkEditFile(file_path, from_history, true)
|
self:checkEditFile(file_path, from_history, true, caller_callback)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if attr then
|
if attr then
|
||||||
-- File exists: get its real path with symlink and ../ resolved
|
-- File exists: get its real path with symlink and ../ resolved
|
||||||
file_path = ffiutil.realpath(file_path)
|
file_path = ffiUtil.realpath(file_path)
|
||||||
attr = lfs.attributes(file_path)
|
attr = lfs.attributes(file_path)
|
||||||
end
|
end
|
||||||
if attr then -- File exists
|
if attr then -- File exists
|
||||||
@@ -451,11 +450,11 @@ function TextEditor:checkEditFile(file_path, from_history, possibly_new_file)
|
|||||||
BD.filepath(file_path), util.getFriendlySize(attr.size)),
|
BD.filepath(file_path), util.getFriendlySize(attr.size)),
|
||||||
ok_text = _("Open"),
|
ok_text = _("Open"),
|
||||||
ok_callback = function()
|
ok_callback = function()
|
||||||
self:editFile(file_path, readonly)
|
self:editFile(file_path, readonly, caller_callback)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
else
|
else
|
||||||
self:editFile(file_path, readonly)
|
self:editFile(file_path, readonly, caller_callback)
|
||||||
end
|
end
|
||||||
else -- File does not exist
|
else -- File does not exist
|
||||||
-- Try to create it just to check if writing to it later is possible
|
-- Try to create it just to check if writing to it later is possible
|
||||||
@@ -465,7 +464,7 @@ function TextEditor:checkEditFile(file_path, from_history, possibly_new_file)
|
|||||||
-- without saving in case the user has changed his mind.
|
-- without saving in case the user has changed his mind.
|
||||||
file:close()
|
file:close()
|
||||||
os.remove(file_path)
|
os.remove(file_path)
|
||||||
self:editFile(file_path)
|
self:editFile(file_path, nil, caller_callback)
|
||||||
else
|
else
|
||||||
UIManager:show(InfoMessage:new{
|
UIManager:show(InfoMessage:new{
|
||||||
text = T(_("This file can not be created:\n\n%1\n\nReason: %2"), BD.filepath(file_path), err)
|
text = T(_("This file can not be created:\n\n%1\n\nReason: %2"), BD.filepath(file_path), err)
|
||||||
@@ -475,12 +474,13 @@ function TextEditor:checkEditFile(file_path, from_history, possibly_new_file)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function TextEditor:saveFileContent(file_path, content)
|
function TextEditor:saveFileContent(file_path, content, caller_callback)
|
||||||
local ok, err = util.writeToFile(content, file_path)
|
local ok, err = util.writeToFile(content, file_path)
|
||||||
if ok then
|
if ok then
|
||||||
if self.ui.file_chooser then
|
if self.ui.file_chooser then
|
||||||
self.ui.file_chooser:refreshPath()
|
self.ui.file_chooser:refreshPath()
|
||||||
end
|
end
|
||||||
|
self.caller_callback = caller_callback -- will be called in self.input.close_callback
|
||||||
logger.info("TextEditor: saved file", file_path)
|
logger.info("TextEditor: saved file", file_path)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@@ -498,7 +498,7 @@ function TextEditor:deleteFile(file_path)
|
|||||||
return false, err
|
return false, err
|
||||||
end
|
end
|
||||||
|
|
||||||
function TextEditor:editFile(file_path, readonly)
|
function TextEditor:editFile(file_path, readonly, caller_callback)
|
||||||
self:addToHistory(file_path)
|
self:addToHistory(file_path)
|
||||||
local directory, filename = util.splitFilePathName(file_path) -- luacheck: no unused
|
local directory, filename = util.splitFilePathName(file_path) -- luacheck: no unused
|
||||||
local filename_without_suffix, filetype = util.splitFileNameSuffix(filename) -- luacheck: no unused
|
local filename_without_suffix, filetype = util.splitFileNameSuffix(filename) -- luacheck: no unused
|
||||||
@@ -578,6 +578,9 @@ function TextEditor:editFile(file_path, readonly)
|
|||||||
if self.input.rotation_mode_backup and self.input.rotation_mode_backup ~= Screen:getRotationMode() then
|
if self.input.rotation_mode_backup and self.input.rotation_mode_backup ~= Screen:getRotationMode() then
|
||||||
Screen:setRotationMode(self.input.rotation_mode_backup)
|
Screen:setRotationMode(self.input.rotation_mode_backup)
|
||||||
end
|
end
|
||||||
|
if self.caller_callback then
|
||||||
|
self.caller_callback(file_path)
|
||||||
|
end
|
||||||
self:execWhenDoneFunc()
|
self:execWhenDoneFunc()
|
||||||
end,
|
end,
|
||||||
-- File saving callback
|
-- File saving callback
|
||||||
@@ -588,7 +591,7 @@ function TextEditor:editFile(file_path, readonly)
|
|||||||
end
|
end
|
||||||
if content and #content > 0 then
|
if content and #content > 0 then
|
||||||
if not is_lua then
|
if not is_lua then
|
||||||
local ok, err = self:saveFileContent(file_path, content)
|
local ok, err = self:saveFileContent(file_path, content, caller_callback)
|
||||||
if ok then
|
if ok then
|
||||||
return true, _("File saved")
|
return true, _("File saved")
|
||||||
else
|
else
|
||||||
@@ -597,7 +600,7 @@ function TextEditor:editFile(file_path, readonly)
|
|||||||
end
|
end
|
||||||
local parse_error = util.checkLuaSyntax(content)
|
local parse_error = util.checkLuaSyntax(content)
|
||||||
if not parse_error then
|
if not parse_error then
|
||||||
local ok, err = self:saveFileContent(file_path, content)
|
local ok, err = self:saveFileContent(file_path, content, caller_callback)
|
||||||
if ok then
|
if ok then
|
||||||
return true, _("Lua syntax OK, file saved")
|
return true, _("Lua syntax OK, file saved")
|
||||||
else
|
else
|
||||||
@@ -615,7 +618,7 @@ Do you really want to save to this file?
|
|||||||
%2]]), parse_error, BD.filepath(file_path)), _("Do not save"), _("Save anyway"))
|
%2]]), parse_error, BD.filepath(file_path)), _("Do not save"), _("Save anyway"))
|
||||||
-- we'll get the safer "Do not save" on tap outside
|
-- we'll get the safer "Do not save" on tap outside
|
||||||
if save_anyway then
|
if save_anyway then
|
||||||
local ok, err = self:saveFileContent(file_path, content)
|
local ok, err = self:saveFileContent(file_path, content, caller_callback)
|
||||||
if ok then
|
if ok then
|
||||||
return true, _("File saved")
|
return true, _("File saved")
|
||||||
else
|
else
|
||||||
@@ -639,7 +642,7 @@ Do you want to keep this file as empty, or do you prefer to delete it?
|
|||||||
return false, T(_("Failed deleting file: %1"), err)
|
return false, T(_("Failed deleting file: %1"), err)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local ok, err = self:saveFileContent(file_path, content)
|
local ok, err = self:saveFileContent(file_path, content, caller_callback)
|
||||||
if ok then
|
if ok then
|
||||||
return true, _("File saved")
|
return true, _("File saved")
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user