[RTL UI] use auto or LTR text direction in some specific cases

Allow TextBoxWidget new text direction/lang parameters to be
set on upper widgets, and propagate them all the way to it
(ScrollTextWidget, InputText, InputDialog, TextViewer).

Use specific non-default ones in some specific cases:
- Force LTR text direction when showing HTML and CSS, and
  configuration files (in some plugins).
- Use Wikipedia server language and text direction when
  showing an article.
- Use auto with Dictionary results, as we don't know the
  dictionary language, and they may contain mixed content.
- Force LTR when showing some paths (still needs more of them)

TextEditor plugin: add 2 new options "Auto paragraph direction"
and "Force paragraph direction LTR".

Footnotes popup: grab HTML direction, and forward it
to MuPDF for proper display.
reviewable/pr5680/r1
poire-z 4 years ago
parent 866c9571df
commit d6d49a64a7

@ -109,6 +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
max_width = Screen:getWidth() - 2*Size.padding.small,
truncate_left = true,
}

@ -781,6 +781,8 @@ function ReaderHighlight:viewSelectionHTML(debug_view)
text = css_text or _("Failed getting CSS content"),
text_face = Font:getFace("smallinfont"),
justified = false,
para_direction_rtl = false,
auto_para_direction = false,
buttons_table = {
{{
text = _("Prettify"),
@ -792,6 +794,8 @@ function ReaderHighlight:viewSelectionHTML(debug_view)
text = prettifyCss(css_text),
text_face = Font:getFace("smallinfont"),
justified = false,
para_direction_rtl = false,
auto_para_direction = false,
})
end,
}},
@ -838,6 +842,8 @@ function ReaderHighlight:viewSelectionHTML(debug_view)
text = html,
text_face = Font:getFace("smallinfont"),
justified = false,
para_direction_rtl = false,
auto_para_direction = false,
buttons_table = buttons_table,
}
UIManager:show(textviewer)

@ -1062,12 +1062,13 @@ function ReaderLink:showAsFootnotePopup(link, neglect_current_location)
-- then just ignore the whole stylesheet, including our own declarations
-- we add at start)
--
-- flags = 0x0000 to get the simplest/purest HTML without CSS
-- flags = 0x0001 to get the simplest/purest HTML without CSS, and dir=
-- and lang= attributes grabbed from parent nodes
local html
if extStartXP and extEndXP then
html = self.ui.document:getHTMLFromXPointers(extStartXP, extEndXP, 0x0000)
html = self.ui.document:getHTMLFromXPointers(extStartXP, extEndXP, 0x0001)
else
html = self.ui.document:getHTMLFromXPointer(target_xpointer, 0x0000, true)
html = self.ui.document:getHTMLFromXPointer(target_xpointer, 0x0001, true)
-- from_final_parent = true to get a possibly more complete footnote
end
if not html then

@ -97,6 +97,7 @@ function TweakInfoWidget:init()
text = css,
face = Font:getFace("infont", 16),
width = self.width - 2*Size.padding.large,
para_direction_rtl = false, -- LTR
}
})
if self.is_global_default then

@ -488,6 +488,7 @@ function ReaderWikipedia:lookupWikipedia(word, box, get_fullpage, forced_lang)
definition = definition,
is_fullpage = get_fullpage,
lang = lang,
rtl_lang = Wikipedia:isWikipediaLanguageRTL(lang),
images = page.images,
}
table.insert(results, result)

@ -312,6 +312,9 @@ function DictQuickLookup:update()
dialog = self,
-- allow for disabling justification
justified = G_reader_settings:nilOrTrue("dict_justify"),
lang = self.lang and self.lang:lower(), -- only available on wikipedia results
para_direction_rtl = self.rtl_lang, -- only available on wikipedia results
auto_para_direction = not self.is_wiki, -- only for dict results (we don't know their lang)
image_alt_face = self.image_alt_face,
images = self.images,
}
@ -659,6 +662,7 @@ function DictQuickLookup:changeDictionary(index)
self.is_html = self.results[index].is_html
self.css = self.results[index].css
self.lang = self.results[index].lang
self.rtl_lang = self.results[index].rtl_lang
self.images = self.results[index].images
if self.images and #self.images > 0 then
-- We'll be giving some images to textboxwidget that will

@ -181,6 +181,14 @@ local InputDialog = InputContainer:new{
button_padding = Size.padding.default,
border_size = Size.border.window,
-- See TextBoxWidget for details about these options
alignment = "left",
justified = false,
lang = nil,
para_direction_rtl = nil,
auto_para_direction = false,
alignment_strict = false,
-- for internal use
_text_modified = false, -- previous known modified status
_top_line_num = nil,
@ -307,6 +315,9 @@ function InputDialog:init()
width = self.text_width,
padding = self.input_padding,
margin = self.input_margin,
lang = self.lang, -- these might influence height
para_direction_rtl = self.para_direction_rtl,
auto_para_direction = self.auto_para_direction,
}
local text_height = input_widget:getTextHeight()
local line_height = input_widget:getLineHeight()
@ -351,6 +362,12 @@ function InputDialog:init()
text = self.input,
hint = self.input_hint,
face = self.input_face,
alignment = self.alignment,
justified = self.justified,
lang = self.lang,
para_direction_rtl = self.para_direction_rtl,
auto_para_direction = self.auto_para_direction,
alignment_strict = self.alignment_strict,
width = self.text_width,
height = self.text_height or nil,
padding = self.input_padding,

@ -42,6 +42,14 @@ local InputText = InputContainer:new{
margin = Size.margin.default,
bordersize = Size.border.inputtext,
-- See TextBoxWidget for details about these options
alignment = "left",
justified = false,
lang = nil,
para_direction_rtl = nil,
auto_para_direction = false,
alignment_strict = false,
-- for internal use
text_widget = nil, -- Text Widget for cursor movement, possibly a ScrollTextWidget
charlist = nil, -- table of individual chars from input string
@ -308,6 +316,9 @@ function InputText:initTextBox(text, char_added)
charlist = show_charlist,
face = self.face,
width = text_width,
lang = self.lang, -- these might influence height
para_direction_rtl = self.para_direction_rtl,
auto_para_direction = self.auto_para_direction,
}
self.height = text_widget:getTextHeight()
self.scroll = true
@ -322,6 +333,12 @@ function InputText:initTextBox(text, char_added)
editable = self.focused,
face = self.face,
fgcolor = fgcolor,
alignment = self.alignment,
justified = self.justified,
lang = self.lang,
para_direction_rtl = self.para_direction_rtl,
auto_para_direction = self.auto_para_direction,
alignment_strict = self.alignment_strict,
width = self.width,
height = self.height,
dialog = self.parent,
@ -337,6 +354,12 @@ function InputText:initTextBox(text, char_added)
editable = self.focused,
face = self.face,
fgcolor = fgcolor,
alignment = self.alignment,
justified = self.justified,
lang = self.lang,
para_direction_rtl = self.para_direction_rtl,
auto_para_direction = self.auto_para_direction,
alignment_strict = self.alignment_strict,
width = self.width,
height = self.height,
dialog = self.parent,

@ -611,6 +611,7 @@ function Menu:init()
self.path_text = TextWidget:new{
face = Font:getFace("xx_smallinfofont"),
text = self.path,
para_direction_rtl = false, -- force LTR
max_width = self.dimen.w - 2*Size.padding.small,
truncate_left = true,
}

@ -17,8 +17,6 @@ local Screen = Device.screen
local input_field, input_description
local MultiInputDialog = InputDialog:extend{
field = {},
field_hint = {},
fields = {},
description_padding = Size.padding.default,
description_margin = Size.margin.small,
@ -50,6 +48,13 @@ function MultiInputDialog:init()
parent = self,
padding = field.padding or nil,
margin = field.margin or nil,
-- Allow these to be specified per field if needed
alignment = field.alignment or self.alignment,
justified = field.justified or self.justified,
lang = field.lang or self.lang,
para_direction_rtl = field.para_direction_rtl or self.para_direction_rtl,
auto_para_direction = field.auto_para_direction or self.auto_para_direction,
alignment_strict = field.alignment_strict or self.alignment_strict,
}
if Device:hasDPad() then
-- little hack to piggyback on the layout of the button_table to handle the new InputText

@ -22,7 +22,6 @@ local ScrollTextWidget = InputContainer:new{
charpos = nil,
top_line_num = nil,
editable = false,
justified = false,
scroll_callback = nil, -- called with (low, high) when view is scrolled
scroll_by_pan = false, -- allow scrolling by lines with Pan
face = nil,
@ -33,6 +32,13 @@ local ScrollTextWidget = InputContainer:new{
text_scroll_span = Screen:scaleBySize(12),
dialog = nil,
images = nil,
-- See TextBoxWidget for details about these options
alignment = "left",
justified = false,
lang = nil,
para_direction_rtl = nil,
auto_para_direction = false,
alignment_strict = false,
}
function ScrollTextWidget:init()
@ -43,13 +49,18 @@ function ScrollTextWidget:init()
top_line_num = self.top_line_num,
dialog = self.dialog,
editable = self.editable,
justified = self.justified,
face = self.face,
image_alt_face = self.image_alt_face,
fgcolor = self.fgcolor,
width = self.width - self.scroll_bar_width - self.text_scroll_span,
height = self.height,
images = self.images,
alignment = self.alignment,
justified = self.justified,
lang = self.lang,
para_direction_rtl = self.para_direction_rtl,
auto_para_direction = self.auto_para_direction,
alignment_strict = self.alignment_strict,
}
local visible_line_count = self.text_widget:getVisLineCount()
local total_line_count = self.text_widget:getAllLineCount()

@ -37,7 +37,18 @@ local TextViewer = InputContainer:new{
width = nil,
height = nil,
buttons_table = nil,
-- See TextBoxWidget for details about these options
-- We default to justified and auto_para_direction to adapt
-- to any kind of text we are given (book descriptions,
-- bookmarks' text, translation results...).
-- When used to display more technical text (HTML, CSS,
-- application logs...), it's best to reset them to false.
alignment = "left",
justified = true,
lang = nil,
para_direction_rtl = nil,
auto_para_direction = true,
alignment_strict = false,
title_face = Font:getFace("x_smalltfont"),
text_face = Font:getFace("x_smallinfofont"),
@ -157,7 +168,12 @@ function TextViewer:init()
width = self.width - 2*self.text_padding - 2*self.text_margin,
height = textw_height - 2*self.text_padding -2*self.text_margin,
dialog = self,
alignment = self.alignment,
justified = self.justified,
lang = self.lang,
para_direction_rtl = self.para_direction_rtl,
auto_para_direction = self.auto_para_direction,
alignment_strict = self.alignment_strict,
}
self.textw = FrameContainer:new{
padding = self.text_padding,

@ -681,6 +681,13 @@ local rtl_wiki_code = {
ks = "Kashmiri",
}
function Wikipedia:isWikipediaLanguageRTL(lang)
if lang and rtl_wiki_code[lang:lower()] then
return true
end
return false
end
-- Create an epub file (with possibly images)
function Wikipedia:createEpub(epub_path, page, lang, with_images)
-- Use Trapper to display progress and ask questions through the UI.
@ -1298,7 +1305,7 @@ table {
local see_online_version = T(_("See %1 for up-to-date content"), online_version_htmllink)
-- Set dir= attribute on the HTML tag for RTL languages
local html_dir = ""
if rtl_wiki_code[lang:lower()] then
if self:isWikipediaLanguageRTL(lang) then
html_dir = ' dir="rtl"'
end
epub:add("OEBPS/content.html", string.format([[

@ -51,6 +51,7 @@ function DocSettingTweak:editDirectoryDefaults()
title = T(_("Directory Defaults: %1"),directory_defaults_path),
input = defaults,
input_type = "string",
para_direction_rtl = false, -- force LTR
fullscreen = true,
condensed = true,
allow_newline = true,

@ -411,6 +411,7 @@ function NewsDownloader:changeFeedConfig()
title = T(_("Config: %1"),feed_config_path),
input = config,
input_type = "string",
para_direction_rtl = false, -- force LTR
fullscreen = true,
condensed = true,
allow_newline = true,

@ -23,6 +23,7 @@ function Terminal:start()
self.input = InputDialog:new{
title = _("Enter a command and press \"Execute\""),
input = self.command,
para_direction_rtl = false, -- force LTR
text_height = Screen:getHeight() * 0.4,
input_type = "string",
buttons = {{{

@ -1,3 +1,4 @@
local BD = require("ui/bidi")
local ConfirmBox = require("ui/widget/confirmbox")
local DataStorage = require("datastorage")
local Font = require("ui/font")
@ -54,6 +55,8 @@ function TextEditor:loadSettings()
if self.settings:readSetting("monospace_font") then
self.monospace_font = self.settings:readSetting("monospace_font")
end
self.auto_para_direction = self.settings:readSetting("auto_para_direction") or true
self.force_ltr_para_direction = self.settings:readSetting("force_ltr_para_direction") or false
end
function TextEditor:onFlushSettings()
@ -63,6 +66,8 @@ function TextEditor:onFlushSettings()
self.settings:saveSetting("last_path", self.last_path)
self.settings:saveSetting("font_face", self.font_face)
self.settings:saveSetting("font_size", self.font_size)
self.settings:saveSetting("auto_para_direction", self.auto_para_direction)
self.settings:saveSetting("force_ltr_para_direction", self.force_ltr_para_direction)
self.settings:flush()
end
end
@ -114,6 +119,32 @@ function TextEditor:getSubMenuItems()
self.font_face = self.monospace_font
end
end,
separator = true,
},
{
text = _("Auto paragraph direction"),
help_text = _([[
Detect the direction of each paragraph in the text: align to the right paragraphs in languages such as Arabic and Hebrew, while keeping other paragraphs aligned to the left.
If disabled, paragraphs align according to KOReader's language default direction.]]),
checked_func = function()
return self.auto_para_direction
end,
callback = function()
self.auto_para_direction = not self.auto_para_direction
end,
},
{
text = _("Force paragraph direction LTR"),
help_text = _([[
Force all text to be displayed Left-To-Right (LTR) and aligned to the left.
Enable this if you are mostly editing code, HTML, CSS]]),
enabled_func = BD.rtlUIText, -- only useful for RTL users editing code
checked_func = function()
return BD.rtlUIText() and self.force_ltr_para_direction
end,
callback = function()
self.force_ltr_para_direction = not self.force_ltr_para_direction
end,
},
},
separator = true,
@ -405,10 +436,16 @@ function TextEditor:editFile(file_path, readonly)
local filename_without_suffix, filetype = util.splitFileNameSuffix(filename) -- luacheck: no unused
local is_lua = filetype:lower() == "lua"
local input
local para_direction_rtl = nil -- use UI language direction
if self.force_ltr_para_direction then
para_direction_rtl = false -- force LTR
end
input = InputDialog:new{
title = filename,
input = self:readFileContent(file_path),
input_face = Font:getFace(self.font_face, self.font_size),
para_direction_rtl = para_direction_rtl,
auto_para_direction = self.auto_para_direction,
fullscreen = true,
condensed = true,
allow_newline = true,

Loading…
Cancel
Save