[RTL UI] Bidi-wrap filenames, paths, urls, metadata

bidi.lua:
- Revert "Alias everything to Bidi.nowrap() when in LTR UI,
  as using LTR isolates seems uneeded when already LTR" (part
  of a628714f) which was a wrong assumption: we need proper
  wrappers for all things paths. Enhance some of these wrappers.
- Fix GetText RTL wrapping which was losing empty lines and
  trailing \n.

- Wrap all paths, directories, filenames in the code with
  these wrappers.
- Wrap all book metadata (title, authors...) with BD.auto(),
  as it helps fixing some edge cases (like open/close quotation
  marks which are not considered as bracket types by FriBiDi).
  (Needed some minor logic changes in CoverBrowser.)

- Tweak hyphenation menu text
- Update forgotten SortWidget for UI mirroring
- KoptConfig: update "justification" index for RTL re-ordering,
  following the recent addition of the page_gap_height option.
pull/5742/head
poire-z 4 years ago
parent a31abf79de
commit 0599c440cc

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ButtonDialog = require("ui/widget/buttondialog")
local ButtonDialogTitle = require("ui/widget/buttondialogtitle")
local ConfirmBox = require("ui/widget/confirmbox")
@ -343,7 +344,7 @@ end
function CloudStorage:onMenuHold(item)
if item.type == "folder_long_press" then
local title = T(_("Select this directory?\n\n%1"), item.url)
local title = T(_("Select this directory?\n\n%1"), BD.dirpath(item.url))
local onConfirm = self.onConfirm
local button_dialog
button_dialog = ButtonDialogTitle:new{
@ -524,7 +525,7 @@ function CloudStorage:synchronizeSettings(item)
local dropbox_sync_folder = item.sync_source_folder or "not set"
local local_sync_folder = item.sync_dest_folder or "not set"
syn_dialog = ButtonDialogTitle:new {
title = T(_("Dropbox folder:\n%1\nLocal folder:\n%2"), dropbox_sync_folder, local_sync_folder),
title = T(_("Dropbox folder:\n%1\nLocal folder:\n%2"), BD.dirpath(dropbox_sync_folder), BD.dirpath(local_sync_folder)),
title_align = "center",
buttons = {
{

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ConfirmBox = require("ui/widget/confirmbox")
local DocumentRegistry = require("document/documentregistry")
local DropBoxApi = require("apps/cloudstorage/dropboxapi")
@ -26,12 +27,12 @@ function DropBox:downloadFile(item, password, path, close)
local __, filename = util.splitFilePathName(path)
if G_reader_settings:isTrue("show_unsupported") and not DocumentRegistry:hasProvider(filename) then
UIManager:show(InfoMessage:new{
text = T(_("File saved to:\n%1"), path),
text = T(_("File saved to:\n%1"), BD.filename(path)),
})
else
UIManager:show(ConfirmBox:new{
text = T(_("File saved to:\n%1\nWould you like to read the downloaded book now?"),
path),
BD.filepath(path)),
ok_callback = function()
close()
ReaderUI:showReader(path)
@ -40,7 +41,7 @@ function DropBox:downloadFile(item, password, path, close)
end
else
UIManager:show(InfoMessage:new{
text = T(_("Could not save file to:\n%1"), path),
text = T(_("Could not save file to:\n%1"), BD.filepath(path)),
timeout = 3,
})
end

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ConfirmBox = require("ui/widget/confirmbox")
local DocumentRegistry = require("document/documentregistry")
local FtpApi = require("apps/cloudstorage/ftpapi")
@ -30,12 +31,12 @@ function Ftp:downloadFile(item, address, user, pass, path, close)
local __, filename = util.splitFilePathName(path)
if G_reader_settings:isTrue("show_unsupported") and not DocumentRegistry:hasProvider(filename) then
UIManager:show(InfoMessage:new{
text = T(_("File saved to:\n%1"), path),
text = T(_("File saved to:\n%1"), BD.filepath(path)),
})
else
UIManager:show(ConfirmBox:new{
text = T(_("File saved to:\n%1\nWould you like to read the downloaded book now?"),
path),
BD.filepath(path)),
ok_callback = function()
close()
ReaderUI:showReader(path)
@ -44,7 +45,7 @@ function Ftp:downloadFile(item, address, user, pass, path, close)
end
else
UIManager:show(InfoMessage:new{
text = T(_("Could not save file to:\n%1"), path),
text = T(_("Could not save file to:\n%1"), BD.filepath(path)),
timeout = 3,
})
end

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ConfirmBox = require("ui/widget/confirmbox")
local DocumentRegistry = require("document/documentregistry")
local InfoMessage = require("ui/widget/infomessage")
@ -22,12 +23,12 @@ function WebDav:downloadFile(item, address, username, password, local_path, clos
local __, filename = util.splitFilePathName(local_path)
if G_reader_settings:isTrue("show_unsupported") and not DocumentRegistry:hasProvider(filename) then
UIManager:show(InfoMessage:new{
text = T(_("File saved to:\n%1"), local_path),
text = T(_("File saved to:\n%1"), BD.filepath(local_path)),
})
else
UIManager:show(ConfirmBox:new{
text = T(_("File saved to:\n%1\nWould you like to read the downloaded book now?"),
local_path),
BD.filepath(local_path)),
ok_callback = function()
close()
ReaderUI:showReader(local_path)
@ -36,7 +37,7 @@ function WebDav:downloadFile(item, address, username, password, local_path, clos
end
else
UIManager:show(InfoMessage:new{
text = T(_("Could not save file to:\n%1"), local_path),
text = T(_("Could not save file to:\n%1"), BD.filepath(local_path)),
timeout = 3,
})
end

@ -109,8 +109,7 @@ function FileManager:init()
self.path_text = TextWidget:new{
face = Font:getFace("xx_smallinfofont"),
text = filemanagerutil.abbreviate(self.root_path),
para_direction_rtl = false, -- force LTR
text = BD.directory(filemanagerutil.abbreviate(self.root_path)),
max_width = Screen:getWidth() - 2*Size.padding.small,
truncate_left = true,
}
@ -179,7 +178,7 @@ function FileManager:init()
self.focused_file = nil -- use it only once
function file_chooser:onPathChanged(path) -- luacheck: ignore
FileManager.instance.path_text:setText(filemanagerutil.abbreviate(path))
FileManager.instance.path_text:setText(BD.directory(filemanagerutil.abbreviate(path)))
UIManager:setDirty(FileManager.instance, function()
return "ui", FileManager.instance.path_text.dimen, FileManager.instance.dithered
end)
@ -223,7 +222,7 @@ function FileManager:init()
enabled = DocSettings:hasSidecarFile(util.realpath(file)),
callback = function()
UIManager:show(ConfirmBox:new{
text = util.template(_("Purge .sdr to reset settings for this document?\n\n%1"), self.file_dialog.title),
text = util.template(_("Purge .sdr to reset settings for this document?\n\n%1"), BD.filename(self.file_dialog.title)),
ok_text = _("Purge"),
ok_callback = function()
filemanagerutil.purgeSettings(file)
@ -247,7 +246,7 @@ function FileManager:init()
text = _("Delete"),
callback = function()
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."),
text = _("Are you sure that you want to delete this file?\n") .. BD.filepath(file) .. ("\n") .. _("If you delete a file, it is permanently lost."),
ok_text = _("Delete"),
ok_callback = function()
deleteFile(file)
@ -358,8 +357,15 @@ function FileManager:init()
})
end
local title
if lfs.attributes(file, "mode") == "directory" then
title = BD.directory(file:match("([^/]+)$"))
else
title = BD.filename(file:match("([^/]+)$"))
end
self.file_dialog = ButtonDialogTitle:new{
title = file:match("([^/]+)$"),
title = title,
title_align = "center",
buttons = buttons,
}
@ -567,7 +573,7 @@ function FileManager:tapPlus()
end
self.file_dialog = ButtonDialogTitle:new{
title = filemanagerutil.abbreviate(self.file_chooser.path),
title = BD.dirpath(filemanagerutil.abbreviate(self.file_chooser.path)),
title_align = "center",
buttons = buttons,
}
@ -666,7 +672,7 @@ end
function FileManager:setHome(path)
path = path or self.file_chooser.path
UIManager:show(ConfirmBox:new{
text = util.template(_("Set '%1' as HOME directory?"), path),
text = util.template(_("Set '%1' as HOME directory?"), BD.dirpath(path)),
ok_text = _("Set as HOME"),
ok_callback = function()
G_reader_settings:saveSetting("home_dir", path)
@ -679,7 +685,7 @@ function FileManager:openRandomFile(dir)
local random_file = DocumentRegistry:getRandomFile(dir, false)
if random_file then
UIManager:show(MultiConfirmBox:new {
text = T(_("Do you want to open %1?"), util.basename(random_file)),
text = T(_("Do you want to open %1?"), BD.filename(util.basename(random_file))),
choice1_text = _("Open"),
choice1_callback = function()
FileManager.instance:onClose()
@ -724,12 +730,12 @@ function FileManager:pasteHere(file)
end
if util.execute(self.cp_bin, "-r", orig, dest) == 0 then
UIManager:show(InfoMessage:new {
text = T(_("Copied to: %1"), dest),
text = T(_("Copied to: %1"), BD.dirpath(dest)),
timeout = 2,
})
else
UIManager:show(InfoMessage:new {
text = T(_("An error occurred while trying to copy %1"), orig),
text = T(_("An error occurred while trying to copy %1"), BD.filepath(orig)),
timeout = 2,
})
end
@ -750,12 +756,12 @@ function FileManager:pasteHere(file)
G_reader_settings:saveSetting("lastfile", dest_file)
end
UIManager:show(InfoMessage:new {
text = T(_("Moved to: %1"), dest),
text = T(_("Moved to: %1"), BD.dirpath(dest)),
timeout = 2,
})
else
UIManager:show(InfoMessage:new {
text = T(_("An error occurred while trying to move %1"), orig),
text = T(_("An error occurred while trying to move %1"), BD.filepath(orig)),
timeout = 2,
})
end
@ -772,9 +778,9 @@ function FileManager:pasteHere(file)
if mode == "file" or mode == "directory" then
local text
if mode == "file" then
text = T(_("The file %1 already exists. Do you want to overwrite it?"), basename)
text = T(_("The file %1 already exists. Do you want to overwrite it?"), BD.filename(basename))
else
text = T(_("The directory %1 already exists. Do you want to overwrite it?"), basename)
text = T(_("The directory %1 already exists. Do you want to overwrite it?"), BD.directory(basename))
end
UIManager:show(ConfirmBox:new {
@ -800,7 +806,7 @@ function FileManager:createFolder(curr_folder, new_folder)
local text
if code == 0 then
self:onRefresh()
text = T(_("Folder created:\n%1"), new_folder)
text = T(_("Folder created:\n%1"), BD.directory(new_folder))
else
text = _("The folder has not been created.")
end
@ -815,7 +821,7 @@ function FileManager:deleteFile(file)
local file_abs_path = util.realpath(file)
if file_abs_path == nil then
UIManager:show(InfoMessage:new{
text = util.template(_("File %1 not found"), file),
text = util.template(_("File %1 not found"), BD.filepath(file)),
})
return
end
@ -839,12 +845,12 @@ function FileManager:deleteFile(file)
end
ReadCollection:removeItemByPath(file, is_dir)
UIManager:show(InfoMessage:new{
text = util.template(_("Deleted %1"), file),
text = util.template(_("Deleted %1"), BD.filepath(file)),
timeout = 2,
})
else
UIManager:show(InfoMessage:new{
text = util.template(_("An error occurred while trying to delete %1"), file),
text = util.template(_("An error occurred while trying to delete %1"), BD.filepath(file)),
})
end
end
@ -867,21 +873,21 @@ function FileManager:renameFile(file)
end
if move_history then
UIManager:show(InfoMessage:new{
text = util.template(_("Renamed from %1 to %2"), file, dest),
text = util.template(_("Renamed from %1 to %2"), BD.filepath(file), BD.filepath(dest)),
timeout = 2,
})
else
UIManager:show(InfoMessage:new{
text = util.template(
_("Failed to move history data of %1 to %2.\nThe reading history may be lost."),
file, dest),
BD.filepath(file), BD.filepath(dest)),
})
end
end
else
UIManager:show(InfoMessage:new{
text = util.template(
_("Failed to rename from %1 to %2"), file, dest),
_("Failed to rename from %1 to %2"), BD.filepath(file), BD.filepath(dest)),
})
end
end

@ -2,6 +2,7 @@
This module provides a way to display book information (filename and book metadata)
]]
local BD = require("ui/bidi")
local DocSettings = require("docsettings")
local DocumentRegistry = require("document/documentregistry")
local ImageViewer = require("ui/widget/imageviewer")
@ -46,10 +47,10 @@ function BookInfo:show(file, book_props)
local size_f = util.getFriendlySize(file_size)
local size_b = util.getFormattedSize(file_size)
local size = string.format("%s (%s bytes)", size_f, size_b)
table.insert(kv_pairs, { _("Filename:"), filename })
table.insert(kv_pairs, { _("Filename:"), BD.filename(filename) })
table.insert(kv_pairs, { _("Format:"), filetype:upper() })
table.insert(kv_pairs, { _("Size:"), size })
table.insert(kv_pairs, { _("Directory:"), filemanagerutil.abbreviate(directory) })
table.insert(kv_pairs, { _("Directory:"), BD.dirpath(filemanagerutil.abbreviate(directory)) })
table.insert(kv_pairs, "----")
-- book_props may be provided if caller already has them available
@ -123,10 +124,20 @@ function BookInfo:show(file, book_props)
local title = book_props.title
if title == "" or title == nil then title = _("N/A") end
table.insert(kv_pairs, { _("Title:"), title })
table.insert(kv_pairs, { _("Title:"), BD.auto(title) })
local authors = book_props.authors
if authors == "" or authors == nil then authors = _("N/A") end
if authors == "" or authors == nil then
authors = _("N/A")
elseif authors:find("\n") then -- BD auto isolate each author
authors = util.splitToArray(authors, "\n")
for i=1, #authors do
authors[i] = BD.auto(authors[i])
end
authors = table.concat(authors, "\n")
else
authors = BD.auto(authors)
end
table.insert(kv_pairs, { _("Authors:"), authors })
local series = book_props.series
@ -135,7 +146,7 @@ function BookInfo:show(file, book_props)
else -- Shorten calibre series decimal number (#4.0 => #4)
series = series:gsub("(#%d+)%.0$", "%1")
end
table.insert(kv_pairs, { _("Series:"), series })
table.insert(kv_pairs, { _("Series:"), BD.auto(series) })
local pages = book_props.pages
if pages == "" or pages == nil then pages = _("N/A") end
@ -146,7 +157,17 @@ function BookInfo:show(file, book_props)
table.insert(kv_pairs, { _("Language:"), language })
local keywords = book_props.keywords
if keywords == "" or keywords == nil then keywords = _("N/A") end
if keywords == "" or keywords == nil then
keywords = _("N/A")
elseif keywords:find("\n") then -- BD auto isolate each keywords
keywords = util.splitToArray(keywords, "\n")
for i=1, #keywords do
keywords[i] = BD.auto(keywords[i])
end
keywords = table.concat(keywords, "\n")
else
keywords = BD.auto(keywords)
end
table.insert(kv_pairs, { _("Keywords:"), keywords })
local description = book_props.description
@ -157,6 +178,9 @@ function BookInfo:show(file, book_props)
-- in PDF) be HTML.
description = util.htmlToPlainTextIfHtml(book_props.description)
end
-- (We don't BD wrap description: it may be multi-lines, and the value we set
-- here may be viewed in a TextViewer that has auto_para_direction=true, which
-- will show the right thing, that'd we rather not mess with BD wrapping.)
table.insert(kv_pairs, { _("Description:"), description })
-- Cover image

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ButtonDialogTitle = require("ui/widget/buttondialogtitle")
local DocSettings = require("docsettings")
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
@ -53,7 +54,7 @@ function FileManagerHistory:onMenuHold(item)
callback = function()
local ConfirmBox = require("ui/widget/confirmbox")
UIManager:show(ConfirmBox:new{
text = util.template(_("Purge .sdr to reset settings for this document?\n\n%1"), item.text),
text = util.template(_("Purge .sdr to reset settings for this document?\n\n%1"), BD.filename(item.text)),
ok_text = _("Purge"),
ok_callback = function()
filemanagerutil.purgeSettings(item.file)
@ -80,7 +81,7 @@ function FileManagerHistory:onMenuHold(item)
callback = function()
local ConfirmBox = require("ui/widget/confirmbox")
UIManager:show(ConfirmBox:new{
text = _("Are you sure that you want to delete this file?\n") .. item.file .. ("\n") .. _("If you delete a file, it is permanently lost."),
text = _("Are you sure that you want to delete this file?\n") .. BD.filepath(item.file) .. ("\n") .. _("If you delete a file, it is permanently lost."),
ok_text = _("Delete"),
ok_callback = function()
local FileManager = require("apps/filemanager/filemanager")
@ -116,7 +117,7 @@ function FileManagerHistory:onMenuHold(item)
},
}
self.histfile_dialog = ButtonDialogTitle:new{
title = item.text:match("([^/]+)$"),
title = BD.filename(item.text:match("([^/]+)$")),
title_align = "center",
buttons = buttons,
}

@ -469,7 +469,7 @@ function FileManagerMenu:setUpdateItemTable()
end
local last_file = G_reader_settings:readSetting("lastfile")
local path, file_name = util.splitFilePathName(last_file); -- luacheck: no unused
return T(_("Last: %1"), file_name)
return T(_("Last: %1"), BD.filename(file_name))
end,
enabled_func = function()
return G_reader_settings:readSetting("lastfile") ~= nil
@ -480,7 +480,7 @@ function FileManagerMenu:setUpdateItemTable()
hold_callback = function()
local last_file = G_reader_settings:readSetting("lastfile")
UIManager:show(ConfirmBox:new{
text = T(_("Would you like to open the last document: %1?"), last_file),
text = T(_("Would you like to open the last document: %1?"), BD.filepath(last_file)),
ok_text = _("OK"),
ok_callback = function()
self:openLastDoc()

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ButtonDialog = require("ui/widget/buttondialog")
local InfoMessage = require("ui/widget/infomessage")
local InputContainer = require("ui/widget/container/inputcontainer")
@ -73,7 +74,7 @@ function FileManagerShortcuts:addNewFolder()
title = self.title,
input = friendly_name,
input_type = "text",
description = T(_("Title for selected folder:\n%1"), path),
description = T(_("Title for selected folder:\n%1"), BD.dirpath(path)),
buttons = {
{
{
@ -162,7 +163,7 @@ function FileManagerShortcuts:editFolderShortcut(item)
title = _("Edit friendly name"),
input = item.friendly_name,
input_type = "text",
description = T(_("Rename title for selected folder:\n%1"), item.folder),
description = T(_("Rename title for selected folder:\n%1"), BD.dirpath(item.folder)),
buttons = {
{
{

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local Blitbuffer = require("ffi/blitbuffer")
local ConfirmBox = require("ui/widget/confirmbox")
local FrameContainer = require("ui/widget/container/framecontainer")
@ -26,7 +27,7 @@ function OPDSCatalog:init()
file_downloaded_callback = function(downloaded_file)
UIManager:show(ConfirmBox:new{
text = T(_("File saved to:\n%1\nWould you like to read the downloaded book now?"),
downloaded_file),
BD.filepath(downloaded_file)),
ok_text = _("Read now"),
cancel_text = _("Read later"),
ok_callback = function()

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ConfirmBox = require("ui/widget/confirmbox")
local DataStorage = require("datastorage")
local Device = require("device")
@ -233,7 +234,7 @@ function ReaderDictionary:addToMainMenu(menu_items)
text = T(_([[
If you'd like to change the order in which dictionaries are queried (and their results displayed), you can:
- move all dictionary directories out of %1.
- move them back there, one by one, in the order you want them to be used.]]), self.data_dir)
- move them back there, one by one, in the order you want them to be used.]]), BD.dirpath(self.data_dir))
})
end,
},
@ -928,7 +929,7 @@ function ReaderDictionary:downloadDictionary(dict, download_location, continue)
logger.dbg("file downloaded to", download_location)
else
UIManager:show(InfoMessage:new{
text = _("Could not save file to:\n") .. download_location,
text = _("Could not save file to:\n") .. BD.filepath(download_location),
--timeout = 3,
})
return false

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local CenterContainer = require("ui/widget/container/centercontainer")
local ConfirmBox = require("ui/widget/confirmbox")
local Device = require("device")
@ -397,7 +398,7 @@ a { color: black; }
f:write("</body></html>\n")
f:close()
UIManager:show(ConfirmBox:new{
text = T(_("Document created as:\n%1\n\nWould you like to read it now?"), fonts_test_path),
text = T(_("Document created as:\n%1\n\nWould you like to read it now?"), BD.filepath(fonts_test_path)),
ok_callback = function()
UIManager:scheduleIn(1.0, function()
self.ui:switchDocument(fonts_test_path)

@ -1490,7 +1490,7 @@ function ReaderGesture:gestureAction(action, ges)
local current_network = NetworkMgr:getCurrentNetwork()
-- this method is only available for some implementations
if current_network and current_network.ssid then
info_text = T(_("Already connected to network %1."), current_network.ssid)
info_text = T(_("Already connected to network %1."), BD.wrap(current_network.ssid))
else
info_text = _("Already connected.")
end

@ -791,7 +791,7 @@ function ReaderHighlight:viewSelectionHTML(debug_view)
if css_files then
for i=1, #css_files do
local button = {
text = T(_("View %1"), css_files[i]),
text = T(_("View %1"), BD.filepath(css_files[i])),
callback = function()
local css_text = self.ui.document:getDocumentFileContent(css_files[i])
local cssviewer

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local Device = require("device")
local Event = require("ui/event")
local InfoMessage = require("ui/widget/infomessage")
@ -25,13 +26,16 @@ function ReaderHyphenation:init()
table.insert(self.hyph_table, {
text_func = function()
local limits_text = _("language defaults")
if G_reader_settings:readSetting("hyph_left_hyphen_min")
or G_reader_settings:readSetting("hyph_right_hyphen_min") then
limits_text = T("%1 - %2", G_reader_settings:readSetting("hyph_left_hyphen_min"),
-- Note: with our callback, we either get hyph_left_hyphen_min and
-- hyph_right_hyphen_min both nil, or both defined.
if G_reader_settings:readSetting("hyph_left_hyphen_min") or
G_reader_settings:readSetting("hyph_right_hyphen_min") then
-- @translators to RTL language translators: %1/left is the min length of the start of a hyphenated word, %2/right is the min length of the end of a hyphenated word (note that there is yet no support for hyphenation with RTL languages, so this will mostly apply to LTR documents)
return T(_("Left/right minimal sizes: %1 - %2"),
G_reader_settings:readSetting("hyph_left_hyphen_min"),
G_reader_settings:readSetting("hyph_right_hyphen_min"))
end
return T(_("Left/right minimal sizes: %1"), limits_text)
return _("Left/right minimal sizes: language defaults")
end,
callback = function()
local DoubleSpinWidget = require("/ui/widget/doublespinwidget")
@ -120,7 +124,7 @@ These settings will apply to all books with any hyphenation dictionary.
self.hyph_alg = v.filename
self.ui.doc_settings:saveSetting("hyph_alg", self.hyph_alg)
UIManager:show(InfoMessage:new{
text = T(_("Changed hyphenation to %1."), v.name),
text = T(_("Changed hyphenation to %1."), BD.wrap(v.name)),
})
self.ui.document:setHyphDictionary(v.filename)
-- Apply hyphenation sides limits
@ -137,7 +141,7 @@ These settings will apply to all books with any hyphenation dictionary.
-- one is set, no fallback will ever be used - if a fallback one
-- is set, no default is wanted; so when we set one below, we
-- remove the other).
text = T( _("Would you like %1 to be used as the default (★) or fallback (<28>) hyphenation language?\n\nDefault will always take precedence while fallback will only be used if the language of the book can't be automatically determined."), v.name),
text = T( _("Would you like %1 to be used as the default (★) or fallback (<28>) hyphenation language?\n\nDefault will always take precedence while fallback will only be used if the language of the book can't be automatically determined."), BD.wrap(v.name)),
choice1_text = _("Default"),
choice1_callback = function()
G_reader_settings:saveSetting("hyph_alg_default", v.filename)

@ -534,7 +534,7 @@ function ReaderLink:onGotoLink(link, neglect_current_location, allow_footnote_po
display_filename = display_filename .. anchor
end
UIManager:show(ConfirmBox:new{
text = T(_("Would you like to read this local document?\n\n%1\n"), display_filename),
text = T(_("Would you like to read this local document?\n\n%1\n"), BD.filepath(display_filename)),
ok_callback = function()
UIManager:scheduleIn(0.1, function()
self.ui:switchDocument(linked_filename)
@ -543,7 +543,7 @@ function ReaderLink:onGotoLink(link, neglect_current_location, allow_footnote_po
})
else
UIManager:show(InfoMessage:new{
text = T(_("Link to unsupported local file:\n%1"), link_url),
text = T(_("Link to unsupported local file:\n%1"), BD.url(link_url)),
})
end
return true
@ -551,7 +551,7 @@ function ReaderLink:onGotoLink(link, neglect_current_location, allow_footnote_po
-- Not supported
UIManager:show(InfoMessage:new{
text = T(_("Invalid or external link:\n%1"), link_url),
text = T(_("Invalid or external link:\n%1"), BD.url(link_url)),
-- no timeout to allow user to type that link in his web browser
})
-- don't propagate, user will notice and tap elsewhere if he wants to change page
@ -658,7 +658,7 @@ function ReaderLink:onGoToExternalLink(link_url)
-- No external link handler
return false
end
text = T(_("External link:\n\n%1"), link_url)
text = T(_("External link:\n\n%1"), BD.url(link_url))
end
-- Add all alternative handlers buttons

@ -228,7 +228,7 @@ function ReaderMenu:setUpdateItemTable()
return _("Open previous document")
end
local path, file_name = util.splitFilePathName(previous_file) -- luacheck: no unused
return T(_("Previous: %1"), file_name)
return T(_("Previous: %1"), BD.filename(file_name))
end,
enabled_func = function()
return self:getPreviousFile() ~= nil
@ -239,7 +239,7 @@ function ReaderMenu:setUpdateItemTable()
hold_callback = function()
local previous_file = self:getPreviousFile()
UIManager:show(ConfirmBox:new{
text = T(_("Would you like to open the previous document: %1?"), previous_file),
text = T(_("Would you like to open the previous document: %1?"), BD.filepath(previous_file)),
ok_text = _("OK"),
ok_callback = function()
self.ui:switchDocument(previous_file)

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local BookStatusWidget = require("ui/widget/bookstatuswidget")
local ButtonDialogTitle = require("ui/widget/buttondialogtitle")
local Device = require("device")
@ -181,7 +182,7 @@ function ReaderStatus:deleteFile(file, text_end_book)
message_end_book = "You've reached the end of the document.\n"
end
UIManager:show(ConfirmBox:new{
text = T(_("%1Are you sure that you want to delete this file?\n%2\nIf you delete a file, it is permanently lost."), message_end_book, file),
text = T(_("%1Are you sure that you want to delete this file?\n%2\nIf you delete a file, it is permanently lost."), message_end_book, BD.filepath(file)),
ok_text = _("Delete"),
ok_callback = function()
local FileManager = require("apps/filemanager/filemanager")

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local Blitbuffer = require("ffi/blitbuffer")
local ButtonTable = require("ui/widget/buttontable")
local CenterContainer = require("ui/widget/container/centercontainer")
@ -498,7 +499,7 @@ You can enable individual tweaks on this book with a tap, or view more details a
table.insert(item_table, {
title = title,
id = file, -- keep ".css" in id, to distinguish between koreader/user tweaks
description = T(_("User style tweak at %1"), filepath),
description = T(_("User style tweak at %1"), BD.filepath(filepath)),
priority = 10, -- give user tweaks a higher priority
css_path = filepath,
})

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ConfirmBox = require("ui/widget/confirmbox")
local Event = require("ui/event")
local InfoMessage = require("ui/widget/infomessage")
@ -252,7 +253,7 @@ function ReaderTypeset:genStyleSheetMenu()
text_func = function()
local text = _("Obsolete")
if obsoleted_css[self.css] then
text = T(_("Obsolete (%1)"), obsoleted_css[self.css])
text = T(_("Obsolete (%1)"), BD.filename(obsoleted_css[self.css]))
end
if obsoleted_css[G_reader_settings:readSetting("copt_css")] then
text = text .. ""
@ -450,7 +451,7 @@ end
function ReaderTypeset:makeDefaultStyleSheet(css, text, touchmenu_instance)
UIManager:show(ConfirmBox:new{
text = T( _("Set default style to %1?"), text),
text = T( _("Set default style to %1?"), BD.filename(text)),
ok_callback = function()
G_reader_settings:saveSetting("copt_css", css)
if touchmenu_instance then touchmenu_instance:updateItems() end

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ButtonDialogTitle = require("ui/widget/buttondialogtitle")
local ConfirmBox = require("ui/widget/confirmbox")
local DataStorage = require("datastorage")
@ -175,7 +176,7 @@ function ReaderWikipedia:addToMainMenu(menu_items)
if not default_dir then default_dir = require("apps/filemanager/filemanagerutil").getDefaultDir() end
local dialog
dialog = ButtonDialogTitle:new{
title = T(_("Current Wikipedia 'Save as EPUB' directory:\n\n%1\n"), default_dir),
title = T(_("Current Wikipedia 'Save as EPUB' directory:\n\n%1\n"), BD.dirpath(default_dir)),
buttons = {
{
{
@ -220,7 +221,7 @@ function ReaderWikipedia:addToMainMenu(menu_items)
onConfirm = function(path)
G_reader_settings:saveSetting("wikipedia_save_dir", path)
UIManager:show(InfoMessage:new{
text = T(_("Wikipedia 'Save as EPUB' directory set to:\n%1"), path),
text = T(_("Wikipedia 'Save as EPUB' directory set to:\n%1"), BD.dirpath(path)),
})
end
}
@ -257,7 +258,7 @@ Where do you want them saved?]])
end
G_reader_settings:saveSetting("wikipedia_save_dir", wikipedia_dir)
UIManager:show(InfoMessage:new{
text = T(_("Wikipedia 'Save as EPUB' directory set to:\n%1"), wikipedia_dir),
text = T(_("Wikipedia 'Save as EPUB' directory set to:\n%1"), BD.dirpath(wikipedia_dir)),
})
end,
cancel_text = _("Select directory"),

@ -4,6 +4,7 @@ ReaderUI is an abstraction for a reader interface.
It works using data gathered from a document interface.
]]--
local BD = require("ui/bidi")
local Cache = require("cache")
local ConfirmBox = require("ui/widget/confirmbox")
local Device = require("device")
@ -448,14 +449,14 @@ function ReaderUI:showReader(file, provider)
if lfs.attributes(file, "mode") ~= "file" then
UIManager:show(InfoMessage:new{
text = T(_("File '%1' does not exist."), file)
text = T(_("File '%1' does not exist."), BD.filepath(file))
})
return
end
if not DocumentRegistry:hasProvider(file) and provider == nil then
UIManager:show(InfoMessage:new{
text = T(_("File '%1' is not supported."), file)
text = T(_("File '%1' is not supported."), BD.filepath(file))
})
self:showFileManager(file)
return
@ -471,7 +472,7 @@ function ReaderUI:showReader(file, provider)
(provider.provider == "mupdf" and type(bookmarks[1].page) == "string")) then
UIManager:show(ConfirmBox:new{
text = T(_("The document '%1' with bookmarks or highlights was previously opened with a different engine. To prevent issues, bookmarks need to be deleted before continuing."),
file),
BD.filepath(file)),
ok_text = _("Delete"),
ok_callback = function()
doc_settings:delSetting("bookmarks")
@ -488,7 +489,7 @@ end
function ReaderUI:showReaderCoroutine(file, provider)
UIManager:show(InfoMessage:new{
text = T(_("Opening file '%1'."), file),
text = T(_("Opening file '%1'."), BD.filepath(file)),
timeout = 0.0,
})
-- doShowReader might block for a long time, so force repaint here

@ -142,9 +142,10 @@ function Device:init()
-- we cannot blit to a window here since we have no focus yet.
local UIManager = require("ui/uimanager")
local InfoMessage = require("ui/widget/infomessage")
local BD = require("ui/bidi")
UIManager:scheduleIn(0.1, function()
UIManager:show(InfoMessage:new{
text = T(_("Opening file '%1'."), new_file),
text = T(_("Opening file '%1'."), BD.filepath(new_file)),
timeout = 0.0,
})
end)
@ -255,7 +256,8 @@ function Device:retrieveNetworkInfo()
if ip == "0" or gw == "0" then
return _("Not connected")
else
return T(_("Connected to %1\n IP address: %2\n gateway: %3"), ssid, ip, gw)
local BD = require("ui/bidi")
return T(_("Connected to %1\n IP address: %2\n gateway: %3"), BD.wrap(ssid), BD.ltr(ip), BD.ltr(gw))
end
end

@ -84,31 +84,35 @@ function Bidi.setup(lang)
Bidi.default = Bidi.rtl
Bidi.wrap = Bidi.rtl
Bidi.filename = Bidi._filename_rtl
Bidi.filepath = Bidi.ltr -- see if we need to split and _filename_rtl() the filename part
Bidi.directory = Bidi.ltr
Bidi.dirpath = Bidi.ltr
Bidi.path = Bidi.ltr
Bidi.url = Bidi.ltr
Bidi.filepath = Bidi._filepath_rtl -- filename auto, but with extension on the right
Bidi.directory = Bidi._path -- will keep any trailing / on the right
Bidi.dirpath = Bidi._path
Bidi.path = Bidi._path
Bidi.url = Bidi._path
else
Bidi.default = Bidi.ltr
Bidi.wrap = Bidi.nowrap
Bidi.filename = Bidi.nowrap
Bidi.filepath = Bidi.nowrap
Bidi.directory = Bidi.nowrap
Bidi.dirpath = Bidi.nowrap
Bidi.path = Bidi.nowrap
Bidi.url = Bidi.nowrap
Bidi.filename = Bidi._filename_ltr
Bidi.filepath = Bidi._filepath_ltr
Bidi.directory = Bidi._path -- will keep any trailing / on the right
Bidi.dirpath = Bidi._path
Bidi.path = Bidi._path
Bidi.url = Bidi._path
end
-- If RTL UI text, let's have untranslated strings (so english) still rendered LTR
if Bidi._rtl_ui_text then
_.wrapUntranslated = function(text)
-- We need to split by line and wrap each line as LTR (as the
-- paragraph direction will still be RTL).
local lines = {}
for s in text:gmatch("[^\r\n]+") do
table.insert(lines, Bidi.ltr(s))
local parts = {}
for part in util.gsplit(text, "\n", true, true) do
if part == "\n" then
table.insert(parts, "\n")
elseif part ~= "" then
table.insert(parts, Bidi.ltr(part))
end
end
return table.concat(lines, "\n")
return table.concat(parts)
end
else
_.wrapUntranslated = _.wrapUntranslated_nowrap
@ -171,6 +175,10 @@ local RLI = "\xE2\x81\xA7" -- U+2067 RLI / RIGHT-TO-LEFT ISOLATE
local FSI = "\xE2\x81\xA8" -- U+2068 FSI / FIRST STRONG ISOLATE
local PDI = "\xE2\x81\xA9" -- U+2069 PDI / POP DIRECTIONAL ISOLATE
-- Not currently needed:
-- local LRM = "\xE2\x80\x8E" -- U+200E LRM / LEFT-TO-RIGHT MARK
-- local RLM = "\xE2\x80\x8F" -- U+200F RLM / RIGHT-TO-LEFT MARK
function Bidi.ltr(text)
return string.format("%s%s%s", LRI, text, PDI)
end
@ -205,12 +213,29 @@ end
-- shown as real RTL).
-- Note: when the filename or path are standalone in a TextWidget, it's
-- better to use "para_direction_rtl = false" without any wrapping.
Bidi.filename = Bidi.nowrap -- aliased to Bidi._filename_rtl if _rtl_ui_text
Bidi.filepath = Bidi.nowrap -- aliased to Bidi.ltr if _rtl_ui_text
Bidi.directory = Bidi.nowrap -- aliased to Bidi.ltr if _rtl_ui_text
Bidi.dirpath = Bidi.nowrap -- aliased to Bidi.ltr if _rtl_ui_text
Bidi.path = Bidi.nowrap -- aliased to Bidi.ltr if _rtl_ui_text
Bidi.url = Bidi.nowrap -- aliased to Bidi.ltr if _rtl_ui_text
-- These are replaced above and aliased to the right wrapper depending
-- on Bidi._rtl_ui_text
Bidi.filename = Bidi.nowrap
Bidi.filepath = Bidi.nowrap
Bidi.directory = Bidi.nowrap
Bidi.dirpath = Bidi.nowrap
Bidi.path = Bidi.nowrap
Bidi.url = Bidi.nowrap
function Bidi._filename_ltr(filename)
-- We always want to show the extension on the left,
-- but the text before should be auto.
local name, suffix = util.splitFileNameSuffix(filename)
-- Let the first strong character of the filename decides
-- about the direction
if suffix == "" then
return Bidi.auto(name)
end
return Bidi.auto(name) .. "." .. suffix
-- No need to additionally wrap it in ltr(), as the
-- default text direction must be LTR.
-- return Bidi.ltr(Bidi.auto(name) .. "." .. suffix)
end
function Bidi._filename_rtl(filename)
-- We always want to show the extension either on the left
@ -219,7 +244,43 @@ function Bidi._filename_rtl(filename)
local name, suffix = util.splitFileNameSuffix(filename)
-- Let the first strong character of the filename decides
-- about the direction
if suffix == "" then
return Bidi.auto(name)
end
return Bidi.auto(name .. "." .. Bidi.ltr(suffix))
end
function Bidi._filename_auto_ext_right(filename)
-- Auto/First strong char for name part, but extension still
-- on the right
local name, suffix = util.splitFileNameSuffix(filename)
if suffix == "" then
return Bidi.auto(name)
end
return Bidi.ltr(Bidi.auto(name) .. "." .. suffix)
end
function Bidi._path(path)
-- by wrapping each component in path in FSI (first strong char)
local parts = {}
for part in util.gsplit(path, "/", true, true) do
if part == "/" then
table.insert(parts, "/")
elseif part ~= "" then
table.insert(parts, Bidi.auto(part))
end
end
return Bidi.ltr(table.concat(parts))
end
function Bidi._filepath_ltr(path)
local dirpath, filename = util.splitFilePathName(path)
return Bidi.ltr(Bidi._path(dirpath) .. filename)
end
function Bidi._filepath_rtl(path)
local dirpath, filename = util.splitFilePathName(path)
return Bidi.ltr(Bidi._path(dirpath) .. Bidi._filename_auto_ext_right(filename))
end
return Bidi

@ -334,7 +334,7 @@ if BD.mirroredUILayout() then
-- be mirrored - but that's not enough: we need to swap LEFT and RIGHT,
-- so they appear in a more expected and balanced order to RTL users:
-- {JUSTIFY, LEFT, CENTER, RIGHT, AUTO}
local j = KoptOptions[3].options[6]
local j = KoptOptions[3].options[7]
assert(j.name == "justification")
j.item_icons[2], j.item_icons[4] = j.item_icons[4], j.item_icons[2]
j.values[2], j.values[4] = j.values[4], j.values[2]

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ConfirmBox = require("ui/widget/confirmbox")
local Device = require("device")
local InfoMessage = require("ui/widget/infomessage")
@ -44,7 +45,7 @@ common_info.about = {
keep_menu_open = true,
callback = function()
UIManager:show(InfoMessage:new{
text = T(_("KOReader %1\n\nA document viewer for E Ink devices.\n\nLicensed under Affero GPL v3. All dependencies are free software.\n\nhttp://koreader.rocks/"), version),
text = T(_("KOReader %1\n\nA document viewer for E Ink devices.\n\nLicensed under Affero GPL v3. All dependencies are free software.\n\nhttp://koreader.rocks/"), BD.ltr(version)),
icon_file = "resources/ko-icon.png",
alpha = true,
})

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ConfirmBox = require("ui/widget/confirmbox")
local DataStorage = require("datastorage")
local Device = require("device")
@ -225,7 +226,7 @@ function NetworkMgr:getProxyMenuTable()
end
return {
text_func = function()
return T(_("HTTP proxy %1"), (proxy_enabled() and proxy() or ""))
return T(_("HTTP proxy %1"), (proxy_enabled() and BD.url(proxy()) or ""))
end,
checked_func = function() return proxy_enabled() end,
callback = function()
@ -388,7 +389,7 @@ function NetworkMgr:reconnectOrShowNetworkMenu(complete_callback)
complete_callback()
end
UIManager:show(InfoMessage:new{
text = T(_("Connected to network %1"), network.ssid),
text = T(_("Connected to network %1"), BD.wrap(network.ssid)),
timeout = 3,
})
return

@ -2,6 +2,7 @@
Checks for updates on the specified nightly build server.
]]
local BD = require("ui/bidi")
local ConfirmBox = require("ui/widget/confirmbox")
local DataStorage = require("datastorage")
local Device = require("device")
@ -243,13 +244,13 @@ function OTAManager:fetchAndProcessUpdate()
})
elseif ota_version then
local update_message = T(_("Do you want to update?\nInstalled version: %1\nAvailable version: %2"),
local_version,
ota_version)
BD.ltr(local_version),
BD.ltr(ota_version))
local update_ok_text = _("Update")
if ota_version < local_version then
update_message = T(_("The currently installed version is newer than the available version.\nWould you still like to continue and downgrade?\nInstalled version: %1\nAvailable version: %2"),
local_version,
ota_version)
BD.ltr(local_version),
BD.ltr(ota_version))
update_ok_text = _("Downgrade")
end
@ -262,9 +263,9 @@ function OTAManager:fetchAndProcessUpdate()
if isAndroid then
-- download the package if not present.
if android.download(link, ota_package) then
android.notification(T(_("The file %1 already exists."), ota_package))
android.notification(T(_("The file %1 already exists."), BD.filename(ota_package)))
else
android.notification(T(_("Downloading %1"), ota_package))
android.notification(T(_("Downloading %1"), BD.filename(ota_package)))
end
elseif Device:isSDL() then
Device:openLink(link)

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local Blitbuffer = require("ffi/blitbuffer")
local ButtonDialogTitle = require("ui/widget/buttondialogtitle")
local BookStatusWidget = require("ui/widget/bookstatuswidget")
@ -66,7 +67,7 @@ function Screensaver:chooseFolder()
logger.dbg("set screensaver directory to", path)
G_reader_settings:saveSetting("screensaver_dir", path)
UIManager:show(InfoMessage:new{
text = T(_("Screensaver directory set to:\n%1"), path),
text = T(_("Screensaver directory set to:\n%1"), BD.dirpath(path)),
timeout = 3,
})
end,
@ -87,7 +88,7 @@ function Screensaver:chooseFolder()
screensaver_dir = DataStorage:getDataDir() .. "/screenshots/"
end
self.choose_dialog = ButtonDialogTitle:new{
title = T(_("Current screensaver image directory:\n%1"), screensaver_dir),
title = T(_("Current screensaver image directory:\n%1"), BD.dirpath(screensaver_dir)),
buttons = buttons
}
UIManager:show(self.choose_dialog)
@ -120,13 +121,13 @@ function Screensaver:chooseFile(document_cover)
if document_cover then
G_reader_settings:saveSetting("screensaver_document_cover", file_path)
UIManager:show(InfoMessage:new{
text = T(_("Screensaver document cover set to:\n%1"), file_path),
text = T(_("Screensaver document cover set to:\n%1"), BD.filepath(file_path)),
timeout = 3,
})
else
G_reader_settings:saveSetting("screensaver_image", file_path)
UIManager:show(InfoMessage:new{
text = T(_("Screensaver image set to:\n%1"), file_path),
text = T(_("Screensaver image set to:\n%1"), BD.filepath(file_path)),
timeout = 3,
})
end
@ -149,8 +150,8 @@ function Screensaver:chooseFile(document_cover)
if screensaver_image == nil then
screensaver_image = DataStorage:getDataDir() .. "/resources/koreader.png"
end
local title = document_cover and T(_("Current screensaver document cover:\n%1"), screensaver_document_cover)
or T(_("Current screensaver image:\n%1"), screensaver_image)
local title = document_cover and T(_("Current screensaver document cover:\n%1"), BD.filepath(screensaver_document_cover))
or T(_("Current screensaver image:\n%1"), BD.filepath(screensaver_image))
self.choose_dialog = ButtonDialogTitle:new{
title = title,
buttons = buttons

@ -365,14 +365,14 @@ function DictQuickLookup:update()
end
local epub_path = dir .. "/" .. filename
UIManager:show(ConfirmBox:new{
text = T(_("Save as %1?"), filename),
text = T(_("Save as %1?"), BD.filename(filename)),
ok_callback = function()
UIManager:scheduleIn(0.1, function()
local Wikipedia = require("ui/wikipedia")
Wikipedia:createEpubWithUI(epub_path, self.lookupword, lang, function(success)
if success then
UIManager:show(ConfirmBox:new{
text = T(_("Article saved to:\n%1\n\nWould you like to read the downloaded article now?"), epub_path),
text = T(_("Article saved to:\n%1\n\nWould you like to read the downloaded article now?"), BD.filepath(epub_path)),
ok_callback = function()
-- close all dict/wiki windows, without scheduleIn(highlight.clear())
self:onHoldClose(true)

@ -627,8 +627,7 @@ function Menu:init()
if self.show_path then
self.path_text = TextWidget:new{
face = Font:getFace("xx_smallinfofont"),
text = self.path,
para_direction_rtl = false, -- force LTR
text = BD.directory(self.path),
max_width = self.dimen.w - 2*Size.padding.small,
truncate_left = true,
}
@ -1035,7 +1034,7 @@ function Menu:updateItems(select_number)
self:updatePageInfo(select_number)
if self.show_path then
self.path_text:setText(self.path)
self.path_text:setText(BD.directory(self.path))
end
UIManager:setDirty(self.show_parent, function()

@ -30,6 +30,7 @@ Example:
]]
local BD = require("ui/bidi")
local bit = require("bit")
local Blitbuffer = require("ffi/blitbuffer")
local CenterContainer = require("ui/widget/container/centercontainer")
@ -469,7 +470,7 @@ function NetworkSetting:init()
UIManager:close(self, 'ui', self.dimen)
end
UIManager:show(InfoMessage:new{
text = T(_("Connected to network %1"), connected_item.info.ssid),
text = T(_("Connected to network %1"), BD.wrap(connected_item.info.ssid)),
timeout = 3,
})
if self.connect_callback then

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ButtonDialog = require("ui/widget/buttondialog")
local ButtonDialogTitle = require("ui/widget/buttondialogtitle")
local Cache = require("cache")
@ -303,7 +304,7 @@ function OPDSBrowser:fetchFeed(item_url, username, password, method)
return
elseif code == 301 then
UIManager:show(InfoMessage:new{
text = T(_("The catalog has been permanently moved. Please update catalog URL to '%1'."), headers['Location']),
text = T(_("The catalog has been permanently moved. Please update catalog URL to '%1'."), BD.url(headers['Location'])),
})
elseif code == 401 then
UIManager:show(InfoMessage:new{
@ -355,7 +356,7 @@ function OPDSBrowser:getCatalog(item_url, username, password)
elseif not ok and catalog then
logger.info("cannot get catalog info from", item_url, catalog)
UIManager:show(InfoMessage:new{
text = T(_("Cannot get catalog info from %1"), (item_url or "")),
text = T(_("Cannot get catalog info from %1"), (BD.url(item_url) or "")),
})
return
end
@ -545,7 +546,7 @@ function OPDSBrowser:downloadFile(item, format, remote_url)
end
else
UIManager:show(InfoMessage:new {
text = _("Could not save file to:\n") .. local_path,
text = _("Could not save file to:\n") .. BD.filepath(local_path),
timeout = 3,
})
end
@ -559,7 +560,7 @@ function OPDSBrowser:downloadFile(item, format, remote_url)
if lfs.attributes(local_path, "mode") == "file" then
UIManager:show(ConfirmBox:new {
text = T(_("The file %1 already exists. Do you want to overwrite it?"), local_path),
text = T(_("The file %1 already exists. Do you want to overwrite it?"), BD.filepath(local_path)),
ok_text = _("Overwrite"),
ok_callback = function()
download()
@ -572,7 +573,7 @@ end
function OPDSBrowser:createNewDownloadDialog(path, buttons)
self.download_dialog = ButtonDialogTitle:new{
title = T(_("Download directory:\n%1\n\nDownload file type:"), path),
title = T(_("Download directory:\n%1\n\nDownload file type:"), BD.dirpath(path)),
buttons = buttons
}
end

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ButtonDialogTitle = require("ui/widget/buttondialogtitle")
local FileChooser = require("ui/widget/filechooser")
local Font = require("ui/font")
@ -104,14 +105,14 @@ function PathChooser:onMenuHold(item)
local filesize = util.getFormattedSize(attr.size)
local lastmod = os.date("%Y-%m-%d %H:%M", attr.modification)
title = T(_("Select this file?\n\n%1\n\nFile size: %2 bytes\nLast modified: %3"),
path, filesize, lastmod)
BD.filepath(path), filesize, lastmod)
else
title = T(_("Select this file?\n\n%1"), path)
title = T(_("Select this file?\n\n%1"), BD.filepath(path))
end
elseif attr.mode == "directory" then
title = T(_("Select this directory?\n\n%1"), path)
title = T(_("Select this directory?\n\n%1"), BD.dirpath(path))
else -- just in case we get something else
title = T(_("Select this path?\n\n%1"), path)
title = T(_("Select this path?\n\n%1"), BD.path(path))
end
local onConfirm = self.onConfirm
self.button_dialog = ButtonDialogTitle:new{

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ButtonDialogTitle = require("ui/widget/buttondialogtitle")
local ConfirmBox = require("ui/widget/confirmbox")
local DataStorage = require("datastorage")
@ -42,7 +43,7 @@ function Screenshoter:onScreenshot(filename)
local screenshot_name = filename or os.date(self.screenshot_fn_fmt)
Screen:shot(screenshot_name)
local widget = ConfirmBox:new{
text = T( _("Saved screenshot to %1.\nWould you like to set it as screensaver?"), screenshot_name),
text = T( _("Saved screenshot to %1.\nWould you like to set it as screensaver?"), BD.filepath(screenshot_name)),
ok_text = _("Yes"),
ok_callback = function()
G_reader_settings:saveSetting("screensaver_type", "image_file")
@ -67,7 +68,7 @@ function Screenshoter:chooseFolder()
onConfirm = function(path)
G_reader_settings:saveSetting("screenshot_dir", path .. "/")
UIManager:show(InfoMessage:new{
text = T(_("Screenshot directory set to:\n%1"), path),
text = T(_("Screenshot directory set to:\n%1"), BD.dirpath(path)),
timeout = 3,
})
end,
@ -85,7 +86,7 @@ function Screenshoter:chooseFolder()
})
local screenshot_dir = G_reader_settings:readSetting("screenshot_dir") or DataStorage:getDataDir() .. "/screenshots/"
self.choose_dialog = ButtonDialogTitle:new{
title = T(_("Current screenshot directory:\n%1"), screenshot_dir),
title = T(_("Current screenshot directory:\n%1"), BD.dirpath(screenshot_dir)),
buttons = buttons
}
UIManager:show(self.choose_dialog)

@ -182,8 +182,16 @@ function SortWidget:init()
self.item_height = Size.item.height_big
-- group for footer
local footer_left_text = ""
local footer_right_text = ""
local footer_first_up_text = "◀◀"
local footer_last_down_text = "▶▶"
if BD.mirroredUILayout() then
footer_left_text, footer_right_text = footer_right_text, footer_left_text
footer_first_up_text, footer_last_down_text = footer_last_down_text, footer_first_up_text
end
self.footer_left = Button:new{
text = "",
text = footer_left_text,
width = self.width_widget * 13 / 100,
callback = function() self:prevPage() end,
text_font_size = 28,
@ -192,7 +200,7 @@ function SortWidget:init()
radius = 0,
}
self.footer_right = Button:new{
text = "",
text = footer_right_text,
width = self.width_widget * 13 / 100,
callback = function() self:nextPage() end,
text_font_size = 28,
@ -201,7 +209,7 @@ function SortWidget:init()
radius = 0,
}
self.footer_first_up = Button:new{
text = "◀◀",
text = footer_first_up_text,
width = self.width_widget * 13 / 100,
callback = function()
if self.marked > 0 then
@ -216,7 +224,7 @@ function SortWidget:init()
radius = 0,
}
self.footer_last_down = Button:new{
text = "▶▶",
text = footer_last_down_text,
width = self.width_widget * 13 / 100,
callback = function()
if self.marked > 0 then
@ -415,13 +423,18 @@ function SortWidget:_populateItems()
)
end
self.footer_page:setText(T(_("%1/%2"), self.show_page, self.pages), self.width_widget * 22 / 100)
self.footer_page:setText(T(_("%1 / %2"), self.show_page, self.pages), self.width_widget * 22 / 100)
local footer_first_up_text = "◀◀"
local footer_last_down_text = "▶▶"
if BD.mirroredUILayout() then
footer_first_up_text, footer_last_down_text = footer_last_down_text, footer_first_up_text
end
if self.marked > 0 then
self.footer_first_up:setText("", self.width_widget * 13 / 100)
self.footer_last_down:setText("", self.width_widget * 13 / 100)
else
self.footer_first_up:setText("◀◀", self.width_widget * 13 / 100)
self.footer_last_down:setText("▶▶", self.width_widget * 13 / 100)
self.footer_first_up:setText(footer_first_up_text, self.width_widget * 13 / 100)
self.footer_last_down:setText(footer_last_down_text, self.width_widget * 13 / 100)
end
self.footer_left:enableDisable(self.show_page > 1)
self.footer_right:enableDisable(self.show_page < self.pages)

@ -954,14 +954,15 @@ end
function util.unpackArchive(archive, extract_to)
dbg.dassert(type(archive) == "string")
local BD = require("ui/bidi")
local ok
if archive:match("%.tar%.bz2$") or archive:match("%.tar%.gz$") or archive:match("%.tar%.lz$") or archive:match("%.tgz$") then
ok = os.execute(("./tar xf %q -C %q"):format(archive, extract_to))
else
return false, T(_("Couldn't extract archive:\n\n%1\n\nUnrecognized filename extension."), archive)
return false, T(_("Couldn't extract archive:\n\n%1\n\nUnrecognized filename extension."), BD.filepath(archive))
end
if not ok then
return false, T(_("Extracting archive failed:\n\n%1", archive))
return false, T(_("Extracting archive failed:\n\n%1", BD.filepath(archive)))
end
return true
end

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local DataStorage = require("datastorage")
local Device = require("device")
local InfoMessage = require("ui/widget/infomessage") -- luacheck:ignore
@ -178,7 +179,7 @@ function SSH:addToMainMenu(menu_items)
callback = function()
local info = InfoMessage:new{
timeout = 60,
text = T(_("Put your public SSH keys in %1"), path.."/settings/SSH/authorized_keys"),
text = T(_("Put your public SSH keys in %1"), BD.filepath(path.."/settings/SSH/authorized_keys")),
}
UIManager:show(info)
end,

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local InputContainer = require("ui/widget/container/inputcontainer")
local InfoMessage = require("ui/widget/infomessage")
local UIManager = require("ui/uimanager")
@ -127,7 +128,7 @@ function CalibreCompanion:addToMainMenu(menu_items)
address = G_reader_settings:readSetting("calibre_wireless_url")
address = string.format("%s:%s", address["address"], address["port"])
end
return T(_("Server address (%1)"), address)
return T(_("Server address (%1)"), BD.ltr(address))
end,
sub_item_table = {
{
@ -214,7 +215,7 @@ function CalibreCompanion:initCalibreMQ(host, port)
self:onReceiveJSON(data)
if not self.connect_message then
UIManager:show(InfoMessage:new{
text = T(_("Connected to calibre server at %1:%2"), host, port),
text = T(_("Connected to calibre server at %1"), BD.ltr(T("%1:%2", host, port))),
})
self.connect_message = true
if self.failed_connect_callback then
@ -467,7 +468,7 @@ function CalibreCompanion:sendBook(arg)
outfile:close()
logger.info("complete writing file", filename)
UIManager:show(InfoMessage:new{
text = _("Received file:") .. filename,
text = _("Received file:") .. BD.filepath(filename),
timeout = 1,
})
-- switch to JSON data receiving mode

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local Blitbuffer = require("ffi/blitbuffer")
local DataStorage = require("datastorage")
local Device = require("device")
@ -844,7 +845,7 @@ Do you want to prune the cache of removed books?]]
local orig_moved_offset = info.movable:getMovedOffset()
info:free()
info.text = T(_("Indexing %1 / %2…\n\n%3"), i, nb_files, filename)
info.text = T(_("Indexing %1 / %2…\n\n%3"), i, nb_files, BD.filename(filename))
info:init()
local text_widget = table.remove(info.movable[1][1], 3)
local text_widget_size = text_widget:getSize()

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local DocumentRegistry = require("document/documentregistry")
local DocSettings = require("docsettings")
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
@ -95,7 +96,7 @@ function CoverMenu:updateItems(select_number)
self:updatePageInfo(select_number)
if self.show_path then
self.path_text:setText(self.path)
self.path_text:setText(BD.directory(self.path))
end
self.show_parent.dithered = self._has_cover_images
UIManager:setDirty(self.show_parent, function()

@ -230,7 +230,7 @@ function ListMenuItem:update()
local pad_width = Screen:scaleBySize(10) -- on the left, in between, and on the right
local wleft_width = dimen.w - wright:getWidth() - 3*pad_width
local wleft = TextBoxWidget:new{
text = self.text,
text = BD.directory(self.text),
face = Font:getFace("cfont", _fontSize(20)),
width = wleft_width,
alignment = "left",
@ -479,17 +479,26 @@ function ListMenuItem:update()
local series_mode = BookInfoManager:getSetting("series_mode")
-- whether to use or not title and authors
-- (We wrap each metadata text with BD.auto() to get for each of them
-- the text direction from the first strong character - which should
-- individually be the best thing, and additionnaly prevent shuffling
-- if concatenated.)
if self.do_filename_only or bookinfo.ignore_meta then
title = filename_without_suffix -- made out above
title = BD.auto(title)
authors = nil
else
title = bookinfo.title and bookinfo.title or filename_without_suffix
title = BD.auto(title)
authors = bookinfo.authors
-- If multiple authors (crengine separates them with \n), we
-- can display them on multiple lines, but limit to 2, and
-- append "et al." to the 2nd if there are more
if authors and authors:find("\n") then
authors = util.splitToArray(authors, "\n")
for i=1, #authors do
authors[i] = BD.auto(authors[i])
end
if #authors > 1 and bookinfo.series and series_mode == "series_in_separate_line" then
authors = { T(_("%1 et al."), authors[1]) }
elseif #authors > 2 then
@ -499,12 +508,15 @@ function ListMenuItem:update()
-- as we'll fit 3 lines instead of 2, we can avoid some loops by starting from a lower font size
fontsize_title = _fontSize(17)
fontsize_authors = _fontSize(15)
elseif authors then
authors = BD.auto(authors)
end
end
-- add Series metadata if requested
if bookinfo.series then
-- Shorten calibre series decimal number (#4.0 => #4)
bookinfo.series = bookinfo.series:gsub("(#%d+)%.0$", "%1")
bookinfo.series = BD.auto(bookinfo.series)
if series_mode == "append_series_to_title" then
if title then
title = title .. " - " .. bookinfo.series
@ -645,6 +657,7 @@ function ListMenuItem:update()
if self.file_deleted then -- unless file was deleted (can happen with History)
hint = " " .. _("(deleted)")
end
local text = BD.filename(self.text)
local text_widget
local fontsize_no_bookinfo = _fontSize(18)
repeat
@ -652,7 +665,7 @@ function ListMenuItem:update()
text_widget:free()
end
text_widget = TextBoxWidget:new{
text = self.text .. hint,
text = text .. hint,
face = Font:getFace("cfont", fontsize_no_bookinfo),
width = dimen.w - 2 * Screen:scaleBySize(10),
alignment = "left",

@ -99,10 +99,15 @@ local FakeCover = FrameContainer:new{
padding = 0,
bordersize = Size.line.thin,
dim = nil,
-- Provided filename, title and authors should not be BD wrapped
filename = nil,
file_deleted = nil,
title = nil,
authors = nil,
-- The *_add should be provided BD wrapped if needed
filename_add = nil,
title_add = nil,
authors_add = nil,
-- these font sizes will be scaleBySize'd by Font:getFace()
authors_font_max = 20,
authors_font_min = 6,
@ -123,14 +128,25 @@ function FakeCover:init()
local title = self.title
local filename = self.filename
-- (some engines may have already given filename (without extension) as title)
local bd_wrap_title_as_filename = false
if not title then -- use filename as title (big and centered)
title = filename
filename = nil
if not self.title_add and self.filename_add then
-- filename_add ("…" or "(deleted)") always comes without any title_add
self.title_add = self.filename_add
self.filename_add = nil
end
bd_wrap_title_as_filename = true
end
if filename then
filename = BD.filename(filename)
end
-- If no authors, and title is filename without extension, it was
-- probably made by an engine, and we can consider it a filename, and
-- act according to common usage in naming files.
if not authors and title and self.filename:sub(1,title:len()) == title then
if not authors and title and self.filename and self.filename:sub(1,title:len()) == title then
bd_wrap_title_as_filename = true
-- Replace a hyphen surrounded by spaces (which most probably was
-- used to separate Authors/Title/Serie/Year/Categorie in the
-- filename with a \n
@ -150,16 +166,35 @@ function FakeCover:init()
-- together on a last line: so, move the zero-width-space
-- before it.
title = title:gsub("%.\xE2\x80\x8B(%w%w?%w?%w?%w?)$", "\xE2\x80\x8B.%1")
-- These substitutions will hopefully have no impact with the following BD wrapping
end
if title then
title = bd_wrap_title_as_filename and BD.filename(title) or BD.auto(title)
end
-- If multiple authors (crengine separates them with \n), we
-- can display them on multiple lines, but limit to 3, and
-- append "et al." on a 4th line if there are more
if authors and authors:find("\n") then
authors = util.splitToArray(authors, "\n")
for i=1, #authors do
authors[i] = BD.auto(authors[i])
end
if #authors > 3 then
authors = { authors[1], authors[2], T(_("%1 et al."), authors[3]) }
end
authors = table.concat(authors, "\n")
elseif authors then
authors = BD.auto(authors)
end
-- Add any _add, which must be already BD wrapped if needed
if self.filename_add then
filename = (filename and filename or "") .. self.filename_add
end
if self.title_add then
title = (title and title or "") .. self.title_add
end
if self.authors_add then
authors = (authors and authors or "") .. self.authors_add
end
-- We build the VerticalGroup widget with decreasing font sizes till
@ -207,7 +242,7 @@ function FakeCover:init()
end
if filename then
filename_wg = TextBoxWidget:new{
text = BD.filename(filename),
text = filename,
face = Font:getFace("cfont", math.max(self.filename_font_max - sizedec, self.filename_font_min)),
width = text_width,
alignment = "center",
@ -429,6 +464,7 @@ function MosaicMenuItem:update()
if text:match('/$') then -- remove /, more readable
text = text:sub(1, -2)
end
text = BD.directory(text)
local nbitems = TextBoxWidget:new{
text = self.mandatory,
face = Font:getFace("infont", 15),
@ -553,25 +589,27 @@ function MosaicMenuItem:update()
else
-- add Series metadata if requested
local series_mode = BookInfoManager:getSetting("series_mode")
local title_add, authors_add
if bookinfo.series then
-- Shorten calibre series decimal number (#4.0 => #4)
bookinfo.series = bookinfo.series:gsub("(#%d+)%.0$", "%1")
bookinfo.series = BD.auto(bookinfo.series)
if series_mode == "append_series_to_title" then
if bookinfo.title then
bookinfo.title = bookinfo.title .. " - " .. bookinfo.series
title_add = " - " .. bookinfo.series
else
bookinfo.title = bookinfo.series
title_add = bookinfo.series
end
end
if not bookinfo.authors then
if series_mode == "append_series_to_authors" or series_mode == "series_in_separate_line" then
bookinfo.authors = bookinfo.series
authors_add = bookinfo.series
end
else
if series_mode == "append_series_to_authors" then
bookinfo.authors = bookinfo.authors .. " - " .. bookinfo.series
authors_add = " - " .. bookinfo.series
elseif series_mode == "series_in_separate_line" then
bookinfo.authors = bookinfo.authors .. "\n \n" .. bookinfo.series
authors_add = "\n \n" .. bookinfo.series
end
end
end
@ -585,6 +623,8 @@ function MosaicMenuItem:update()
filename = self.text,
title = not bookinfo.ignore_meta and bookinfo.title,
authors = not bookinfo.ignore_meta and bookinfo.authors,
title_add = not bookinfo.ignore_meta and title_add,
authors_add = not bookinfo.ignore_meta and authors_add,
file_deleted = self.file_deleted,
}
}
@ -622,7 +662,8 @@ function MosaicMenuItem:update()
width = dimen.w,
height = dimen.h,
bordersize = border_size,
filename = self.text .. "\n" .. hint,
filename = self.text,
filename_add = "\n" .. hint,
initial_sizedec = 4, -- start with a smaller font when filenames only
file_deleted = self.file_deleted,
}

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local DataStorage = require("datastorage")
local FFIUtil = require("ffi/util")
local InputDialog = require("ui/widget/inputdialog")
@ -48,7 +49,7 @@ function DocSettingTweak:editDirectoryDefaults()
directory_defaults_file:close()
local config_editor
config_editor = InputDialog:new{
title = T(_("Directory Defaults: %1"),directory_defaults_path),
title = T(_("Directory Defaults: %1"), BD.filepath(directory_defaults_path)),
input = defaults,
input_type = "string",
para_direction_rtl = false, -- force LTR

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local InputContainer = require("ui/widget/container/inputcontainer")
local LoginDialog = require("ui/widget/logindialog")
local InfoMessage = require("ui/widget/infomessage")
@ -242,7 +243,7 @@ For Windows: netsh interface portproxy add listeningaddress:0.0.0.0 listeningpor
For Linux: $socat tcp-listen:41185,reuseaddr,fork tcp:localhost:41184
For more information, please visit https://github.com/koreader/koreader/wiki/Evernote-export.]])
,DataStorage:getDataDir())
, BD.dirpath(DataStorage:getDataDir()))
})
end
}
@ -595,7 +596,7 @@ function EvernoteExporter:exportClippings(clippings)
end
end
if (self.html_export or self.txt_export) and export_count > 0 then
msg = msg .. T(_("\nNotes can be found in %1/."), realpath(self.clipping_dir))
msg = msg .. T(_("\nNotes can be found in %1/."), BD.dirpath(realpath(self.clipping_dir)))
end
UIManager:show(InfoMessage:new{ text = msg })
end

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local DataStorage = require("datastorage")
--local DownloadBackend = require("internaldownloadbackend")
--local DownloadBackend = require("luahttpdownloadbackend")
@ -125,7 +126,7 @@ function NewsDownloader:addToMainMenu(menu_items)
callback = function()
UIManager:show(InfoMessage:new{
text = T(_("News downloader retrieves RSS and Atom news entries and stores them to:\n%1\n\nEach entry is a separate html file, that can be browsed by KOReader file manager.\nItems download limit can be configured in Settings."),
news_download_dir_path)
BD.dirpath(news_download_dir_path))
})
end,
},
@ -183,7 +184,7 @@ function NewsDownloader:loadConfigAndProcessFeeds()
local download_full_article = feed.download_full_article == nil or feed.download_full_article
local include_images = feed.include_images
if url and limit then
local feed_message = T(_("Processing %1/%2:\n%3"), idx, total_feed_entries, url)
local feed_message = T(_("Processing %1/%2:\n%3"), idx, total_feed_entries, BD.url(url))
UI:info(feed_message)
NewsDownloader:processFeedSource(url, tonumber(limit), unsupported_feeds_urls, download_full_article, include_images, feed_message)
else
@ -198,7 +199,7 @@ function NewsDownloader:loadConfigAndProcessFeeds()
for k,url in pairs(unsupported_feeds_urls) do
unsupported_urls = unsupported_urls .. url
if k ~= #unsupported_feeds_urls then
unsupported_urls = unsupported_urls .. ", "
unsupported_urls = BD.url(unsupported_urls) .. ", "
end
end
UI:info(T(_("Downloading news finished. Could not process some feeds. Unsupported format in: %1"), unsupported_urls))
@ -408,7 +409,7 @@ function NewsDownloader:changeFeedConfig()
feed_config_file:close()
local config_editor
config_editor = InputDialog:new{
title = T(_("Config: %1"),feed_config_path),
title = T(_("Config: %1"), BD.filepath(feed_config_path)),
input = config,
input_type = "string",
para_direction_rtl = false, -- force LTR

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local DataStorage = require("datastorage")
local DocSettings = require("frontend/docsettings")
local ReadHistory = require("readhistory")
@ -103,7 +104,7 @@ function Send2Ebook:addToMainMenu(menu_items)
keep_menu_open = true,
callback = function()
UIManager:show(InfoMessage:new{
text = T(_('Send2Ebook lets you send articles found on PC/Android phone to your Ebook reader (using ftp server).\n\nMore details: https://github.com/mwoz123/send2ebook\n\nDownloads to local folder: %1'), download_dir_path)
text = T(_('Send2Ebook lets you send articles found on PC/Android phone to your Ebook reader (using ftp server).\n\nMore details: https://github.com/mwoz123/send2ebook\n\nDownloads to local folder: %1'), BD.dirpath(download_dir_path))
})
end,
},
@ -143,7 +144,7 @@ function Send2Ebook:process()
local ftp_files_table = FtpApi:listFolder(connection_url .. ftp_config.folder, ftp_config.folder) --args looks strange but otherwise resonse with invalid paths
if not ftp_files_table then
info = InfoMessage:new{ text = T(_("Could not get file list for server: %1, user: %2, folder: %3"), ftp_config.address, ftp_config.username, ftp_config.folder) }
info = InfoMessage:new{ text = T(_("Could not get file list for server: %1, user: %2, folder: %3"), BD.ltr(ftp_config.address), ftp_config.username, BD.dirpath(ftp_config.folder)) }
else
local total_entries = table.getn(ftp_files_table)
logger.dbg("Send2Ebook: total_entries ", total_entries)

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local BookStatusWidget = require("ui/widget/bookstatuswidget")
local ConfirmBox = require("ui/widget/confirmbox")
local DataStorage = require("datastorage")
@ -235,7 +236,7 @@ Cannot open database in %1.
The database may have been moved or deleted.
Do you want to create an empty database?
]]),
db_location),
BD.filepath(db_location)),
cancel_text = _("Close"),
cancel_callback = function()
return

@ -171,7 +171,7 @@ Enable this if you are mostly editing code, HTML, CSS…]]),
local file_path = self.history[i]
local directory, filename = util.splitFilePathName(file_path) -- luacheck: no unused
table.insert(sub_item_table, {
text = T("%1. %2", i, filename),
text = T("%1. %2", i, BD.filename(filename)),
keep_menu_open = true,
callback = function(touchmenu_instance)
self:setupWhenDoneFunc(touchmenu_instance)
@ -186,10 +186,10 @@ Enable this if you are mostly editing code, HTML, CSS…]]),
local filesize = util.getFormattedSize(attr.size)
local lastmod = os.date("%Y-%m-%d %H:%M", attr.modification)
text = T(_("File path:\n%1\n\nFile size: %2 bytes\nLast modified: %3\n\nRemove this file from text editor history?"),
file_path, filesize, lastmod)
BD.filepath(file_path), filesize, lastmod)
else
text = T(_("File path:\n%1\n\nThis file does not exist anymore.\n\nRemove it from text editor history?"),
file_path)
BD.filepath(file_path))
end
UIManager:show(ConfirmBox:new{
text = text,
@ -332,7 +332,7 @@ function TextEditor:checkEditFile(file_path, from_history, possibly_new_file)
local attr = lfs.attributes(file_path)
if not possibly_new_file and not attr then
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?"), file_path),
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)),
ok_text = _("Yes"),
cancel_text = _("No"),
ok_callback = function()
@ -350,7 +350,7 @@ function TextEditor:checkEditFile(file_path, from_history, possibly_new_file)
if attr then -- File exists
if attr.mode ~= "file" then
UIManager:show(InfoMessage:new{
text = T(_("This file is not a regular file:\n\n%1"), file_path)
text = T(_("This file is not a regular file:\n\n%1"), BD.filepath(file_path))
})
return
end
@ -368,7 +368,7 @@ function TextEditor:checkEditFile(file_path, from_history, possibly_new_file)
if not from_history and attr.size > self.min_file_size_warn then
UIManager:show(ConfirmBox:new{
text = T(_("This file is %2:\n\n%1\n\nAre you sure you want to open it?\n\nOpening big files may take some time."),
file_path, util.getFriendlySize(attr.size)),
BD.filepath(file_path), util.getFriendlySize(attr.size)),
ok_text = _("Yes"),
cancel_text = _("No"),
ok_callback = function()
@ -389,7 +389,7 @@ function TextEditor:checkEditFile(file_path, from_history, possibly_new_file)
self:editFile(file_path)
else
UIManager:show(InfoMessage:new{
text = T(_("This file can not be created:\n\n%1\n\nReason: %2"), file_path, err)
text = T(_("This file can not be created:\n\n%1\n\nReason: %2"), BD.filepath(file_path), err)
})
return
end
@ -526,7 +526,7 @@ Lua syntax check failed:
KOReader may crash if this is saved.
Do you really want to save to this file?
%2]]), parse_error, 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
if save_anyway then
local ok, err = self:saveFileContent(file_path, content)
@ -543,7 +543,7 @@ Do you really want to save to this file?
Text content is empty.
Do you want to keep this file as empty, or do you prefer to delete it?
%1]]), file_path), _("Keep empty file"), _("Delete file"))
%1]]), BD.filepath(file_path)), _("Keep empty file"), _("Delete file"))
-- we'll get the safer "Keep empty file" on tap outside
if delete_file then
local ok, err = self:deleteFile(file_path)

@ -2,6 +2,7 @@
@module koplugin.wallabag
]]
local BD = require("ui/bidi")
local DataStorage = require("datastorage")
local DocSettings = require("docsettings")
local Event = require("ui/event")
@ -163,7 +164,7 @@ function Wallabag:addToMainMenu(menu_items)
else
path = filemanagerutil.abbreviate(self.directory)
end
return T(_("Set download directory (%1)"), path)
return T(_("Set download directory (%1)"), BD.dirpath(path))
end,
keep_menu_open = true,
callback = function(touchmenu_instance)
@ -261,7 +262,7 @@ The 'Synchronize remotely deleted files' option will remove local files that no
More details: https://wallabag.org
Downloads to directory: %1]]), filemanagerutil.abbreviate(self.directory))
Downloads to directory: %1]]), BD.dirpath(filemanagerutil.abbreviate(self.directory)))
})
end,
},
@ -824,7 +825,7 @@ Enter the details of your Wallabag server and account.
Client ID and client secret are long strings so you might prefer to save the empty settings and edit the config file directly in your installation directory:
%1/wallabag.lua
Restart KOReader after editing the config file.]]), DataStorage:getSettingsDir())
Restart KOReader after editing the config file.]]), BD.dirpath(DataStorage:getSettingsDir()))
self.settings_dialog = MultiInputDialog:new {
title = _("Wallabag settings"),
@ -994,11 +995,11 @@ function Wallabag:onAddWallabagArticle(article_url)
local wallabag_result = self:addArticle(article_url)
if wallabag_result then
UIManager:show(InfoMessage:new{
text = T(_("Article added to Wallabag:\n%1"), article_url),
text = T(_("Article added to Wallabag:\n%1"), BD.url(article_url)),
})
else
UIManager:show(InfoMessage:new{
text = T(_("Error adding link to Wallabag:\n%1"), article_url),
text = T(_("Error adding link to Wallabag:\n%1"), BD.url(article_url)),
})
end

Loading…
Cancel
Save