FocusManager: fix round x use y layout
FocusManager: add tab and shift tab focus navigation support
FocusManager: handle Press key by default
FocusManager: make sure selected in instance level
FocusManager: add hold event support
FocusManager: Half move instead of edge move
FocusManager: add keymap override support
FocusManager: refocusWidget will delegate to parent FocusManager
Focusmanager: refocusWidget can execute on next tick
inputtext: can move out of focus on back
inputtext: fix cannot exit for non-touch device
inputtext: fix cannot input text with kindle dx physical keyboard
fontlightwidget: add non-touch support
datetimewidget: add non-touch support
datetimewidget: fix set date failed in kindle DX, fix datetimewidget month range to 1~23 by default
datetimewidget: make hour max value to 23
multiinputdialog: add non-touch support
checkbox: focusable and focus style
virtualkeyboard: no need to press two back to unfocus inputtext
virtualkeyboard: collect FocusManager event key names to let VirtualKeyboard disable them
openwithdialog: add non-touch support
inputdialog: can close via back button
enable all InputDialog and MultiInputDialog can be close by back
keyboardlayoutdialog: non-touch support
readertoc: non touch device can expand/collapse in toc
bookstatuswidget: non touch support
keyvaluepage: non-touch support
calendarview: non-touch support
Make it a real Document property, updated at init & toggle time.
Also, simplify a bunch of redundant nested lookups in ReaderView
(self.ui.view is self, self.ui.document is self.document).
widget
Since we only use a single icon, we have to take a few shortcuts:
* The icon itself is computed based on the average of both batteries.
* The actual value is the sum of both batteries.
* Much like everywhere else, charging means the *aux* battery charging
(i.e., connected to a power source).
Re #8741, which does the same for ReaderHeader.
- New button Go to bookmark in Bookmark details dialog.
- New button Latest bookmark in the popup menu.
- Empty input box for new note, new button Paste to
paste highlighted text (auto-text).
- Allow duplicated bookmarks to avoid orphaned highlights.
- TextBoxWidget: fix enabled up-arrow on empty box in InputDialog.
- Add new strikeout highlight style.
- Fix highlight style in pdf documents (save_document enabled)
not updated when KOReader highlight style changed.
- Fix ugly combination of mupdf and KOReader highlights
- FocusManager: allow managing sub widgets by merging their
"layout" in the main one; make "press" support simpler by
handling it as a fake tap event at the center of the
focused widget.
- Setup gestures on non-touch devices for new focus manager.
- ToggleSwitch: use child layout.
- ButtonProgressWidget: use child layout.
- SpinWidget and DoubleSpinWidget: add keyboard navigation.
Fix various issues with stacked Wikipedia lookup results,
and follow up lookups when invoked from Wikipedia lookup
history (where going to a search for language LL would
not use language LL when hitting "Full wikipedia").
Also tweak ReaderHighlight:onHoldRelease() to avoid
doing its stuff when onHold() is clearing highlight
(previous CheckButton was closing/clearing on hold
release, new TitleBar close button does that on hold).
- Book map: shows a map of content, including TOC,
boomarks, read pages, non-linear flows...
- Page browser: shows thumbnails of pages.
- ReaderThumbnail: new Reader module that provides
a service for generating thumbnails of book pages.
It makes available these 2 new fullscreen widgets.
- ReaderBookmark, ReaderLink, Statistics: add methods
to return new views of bookmarks, previous locations
and read pages, that are needed by BookMapWidget.
- ReaderToc: compute TOC max_depth.
- ReaderBookmark, ReaderHighlight: send events on
bookmark add/update/remove so thumbnails of the
pages impacted can be trashed.
When switching screen rotation, have the re-rendering
properly done only via :onUpdatePos().
When changing alt status bar font size, also have it
done via :onUpdatePos() instead of the next painting
(this also update any dogear position after the resize).
When in scroll mode (no alt status bar), be sure to
draw crengine progress bar at top (and not below the
not shown alt status bar).
Wrap document opening and re-renderings (which can block
the app for some time) with setIgnoreInput() to avoid ANR
on Android.
Any setting update that could possibly cause a re-rendering
should send the UpdatePos event, to ensure the re-rendering
happens in ReaderRolling:onUpdatePos() where precautions
are taken to avoid ANR.
Move Default and extra buttons above Cancel/OK.
Default values shown in the default button.
Precisions can be set for both values separately.
Minor geometry fix for consistence with SpinWidget.
Bookmark/highlight formats in crengine and mupdf are incompatible.
This backups and restores bookmarks and highlights when opening the
document with an incompatible engine, instead of deleting them.
Fuzzy searching doesn't work with CJK text: with Japanese,
we get large numbers of useless results because sdcv
decides to strip off the wrong part of the word.
It seems unlikely that sdcv correctly handles Korean
or Chinese, so just disable fuzzy searching on all
CJK-containing word lookups.
Add a "Select" button in the highlight dialog to initiate
text selection; on the next text selection, the text between
these 2 points will be selected.
Limited to a single page with non-CRE documents.
Also move "Search" button at end, so it's the one that
will be wide in case of an odd number of buttons.
It's possible for the user to have selected nothing, and trying to
operate on the nil highlight can cause confusion or crashes. This
restores the behaviour before commit 7a0e3d5e68 ("readerhighlight:
remove selected_word and use selected_text everywhere"), which missed
this case.
In addition, add some debug guards to ReaderHighlight methods which
cannot handle selected_text being nil (or at least, shouldn't be called
with selected_text being nil).
Fixes: 7a0e3d5e68 ("readerhighlight: remove selected_word and use selected_text everywhere")
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
Now that FileManager registers its UI modules in the same way as Reader,
this shouldn't be necessary but this protects us against some other app
creating a ReaderDictionary instance without having ui.languagesupport
registered properly.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
With the addition of the language support module, ReaderDictionary
tries to use modules registered with the UI instance, but the
FileManager doesn't provide key-based registration of its UI modules.
In order to allow the same code to be used by both FileManager and
Reader seamlessly, copy the :registerPlugin() method from Reader and use
it with FileManager. This will ensure any other hidden assumptions about
UI module registration are handled properly.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
- Add an icon to distinguish between page bookmarks, plain
highlights, and highlights with an added note
- Bookmark details: show both highlighted text and added note
- Bookmark list: allow filtering by type and/or by keyword
- New bookmark selection mode, to allow multiple removals
- New option: show separator line
This creates a new plugin system which hooks into a handful of reader
operations in order to allow plugins to add language-specific support
where the default reader falls short. The two hooks added are:
* During hold-without-pan taps, language plugins can modify the
selection in order to better match what users expect koreader to
highlight when selecting a single word.
The vast majority of CJK language words are more than one character,
but KOReader treats all CJK characters as a single word by default,
so adding this hook means that readers no longer need to manually
select the whole word every time they need to look something.
* During dictionary lookup, language plugins can propose alternative
candidate words to look up if the selected word could not be found in
the dictionary.
This is pretty necessary for Japanese and Korean, both of which are
highly agglutinative languages and the fuzzy searching system of
StarDict is simply not usable because often the inflection of the
word is so much longer than the dictionary form that sdcv decides to
chop off the actual word and search for the inflection (which yields
useless results).
This system is of particular interest for readers of CJK languages
(without this, looking up words using KOReader was fairly painful) but
this system is designed to be minimal and language-agnostic enough that
other languages could make use of it by creating their own plugins if
the default "whole word" highlight and fuzzy-search system doesn't match
their needs.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
In order to make startSdcv usable for plugins that might need to do
dictionary lookups in order to work, it is necessary to split out the
core of startSdcv into another method which returns the raw data from
sdcv.
In addition, in order to make it possible to amortise the cost of each
lookup (which could be fairly expensive) make it possible to pass
multiple words to rawSdcv at the same time. Sdcv supports passing
multiple words as arguments (which it then looks up in order and returns
a separate JSON array per line for each word) so we just need to tweak
the return style accordingly.
All of the deduplication and dummy results handling remains in startSdcv
because plugins might strongly depend on whether sdcv returned actual
results.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
There were two ways of specifing selected text for a highlight depending
on whether it was a "single word" or text selected using hold-and-pan.
In addition to being a bit more complicated than is necessary, with the
addition of the language support plugin system (where the "single word"
selected might be expanded), it makes more sense to simply use the same
logic and table structure for both cases.
The dictionary lookup special case (hold-without-pan triggering a
dictionary lookup by default) still works as before.
In addition, this patch fixes a minor inefficiency during dictionary
quick lookup -- before this patch, the highlight would be re-selected
because the quick lookup window is run concurrently and tries to fetch
ReaderHighlight.selected_text but this is set to nil immediately after
triggering the lookup. This is unnecessary because :clear() will be
called anyway when the quick pop-up closes, and so clearing this can be
left until then.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
* Use paintRect and plain colors instead of lightenRect and a weird
dimming factor.
* Update call sites to the new API
* Handle FP maths properly (i.e., floor coordinates & ceil dimensions at
the latest possible time).
* Fix border handling in the fill bar (make sure we actually honor it
when computin the x position, and that we won't overflow into it when
computing the width).
* Update docs
Bookmarks list:
- page numbers are displayed
- page bookmarks are marked with a star
- new setting: Sort by largest page number (default: checked)
New bookmark setting: Add page number / timestamp to bookmark
- If enabled (default), bookmark name is 'Page # notes @ time'.
- If disabled, bookmark name is equal to the notes field.
Rename bookmark dialog:
- page number and timestamp are displayed in the input
dialog description
- blank input renames bookmark to the default name in
accordance with the new setting
Also fix: changing boundaries of the highlight: the name of the
highlight is not changed if it was previously edited by the user.
Discussion in #6409.
Highlight action renamed to Long-press on text and moved from Gear - Document to Gear - Taps and gestures.
Added action Do nothing.
Removed menu item Typeset - Highlighting - Allow highlighting.
Fixed untranslated strings in the Cycle highlight action notification.
Long-press on images always opens ImageViewer. Closes#6409.
* Gestures: standardize hold to long-press
* Common settings menu: standardize hold to long-press
* Readerstyletweak: standardize hold to long-press
* Readersearch: standardize hold to long-press
Also: Text editor now closes its keyboard when calling Find
and Go to line (which open their own keyboards) to avoid
conflicts between multiple keyboards.
Includes among others:
- (Upstream) Various CHM handling fixes, and others
- HTML documents: rebuild TOC from headings after load
- Font: use metrics for underline offset and thickness
- epub.css, html5.css: tweak ruby styling
- CSS: fix EPUB's head>style content encoding
- CSS: add support for 'box-sizing: content-box/border-box'
- CSS: support for styling the <html> element
Also bump KoboUSBMS to v1.2.2 and FBInk to v1.24.0.
ReaderFont's "Generate font test document": update the
generated HTML so its ToC is build from proper HTML headings.
When enabled, if the book has some supported language tag
in its metadata, use it as the source language. Otherwise,
fallback to the current settings (auto-detect or selected
source language).
Go to the directory of the deleted file, instead of the folder you happend to switch into the reader from as this may have changed (via changing books from history etc)
Make "Taps and gestures - Page turns" available only in reader.
Move there other page turn related menu items from Navigation.
Remove duplicated code. Added standard "star" for default RTL.
TileCacheItem: add created_ts property.
Document: manage a tile_cache_validity_ts and ignore
older cached tiles.
This timestamps is updated when highlights are written
as annotations in, or deleted from, the PDF, so we can
get the most current rendered bitmap from MuPDF and
avoid highlight ghosts on old tiles.
Save this timestamp in doc settings so older cached to
disk tiles will also be ignored across re-openings.
Bump base for: mupdf.lua: update frontend pboxes with
MuPDF adjusted ones.
We may get multiple boxes when selecting texts, one for each
word, and we have to add spaces between the extracted words
ourselves. Previously, we were only adding a space if the
last char of previous word was ASCII, so missing spaces
after accents or greek words.
Try to do better by measuring the distances between boxes
and comparing to box heights, with a few heuristics.
Bump base for cre.cpp cleanup and utf8proc FFI.
Add a checkbutton for case sensitive search in FileBrowser,
and use Utf8Proc.lowercase() for case insensitive search.
Also use it in ReaderUserHyph as a replacement for
crengine getLowercasedWord().
- bump crengine: findText(): add support for regular
expression search.
- bump base: add thirdparty/srell/srell.hpp, a C++ library
that provides Unicode regex support, used by crengine.
- ReaderSearch: with credocuments, add checkboxes for case
sensitive and regular expression search.
Instead of baking in a hyphen, so as to avoid signed zeroes, or
confusion with page progress if page maps are enabled.
Also, made compact itemps RTL friendly.
Menu: display the right item ("mandatory") with a
smaller font size related to the left item font size,
instead of a function of perpage.
ToC popups: use same font size as in ToC.
Migrate *global* zoom_mode settings to genus/type, too.
Nothing can actually set this as a global anymore, but we still honored
it nonetheless.
Fix#7778
The hyphenation of a word can be changed from its default
by long pressing for 3 seconds and selecting 'Hyphenate'.
These overrides are stored in a per-language file, i.e:
koreader/settings/user-German.hyph.
By showing a warning, instead of not passing any -u flag to sdcv and letting it query *all* dictionaries if FS order...
Co-authored-by: Frans de Jonge <fransdejonge@gmail.com>
This is handled in an Event handler, but we have zero guarantee that
we're actually the *final* Event sent to the Document, and other Events
usually kinda need the Document instance to still be alive ;).
Delay action until the next tick to avoid potential crashes.
* Namely, ensure zoom_mode is consistent with genus & type *both ways*. (I only dealt with the "no zoom_mode" case in my original fixup).
Because documents with settings dating back from before the new zoom modes had "old" zoom_mode settings mixed with "new" genus/type defaults that didn't agree with each other.
It lead to super-confusing ConfigDialog behavior, because ConfigDialog was in fact not reflecting the reality.
(As the source of truth is actually `zoom_mode`).
* There was a snafu in manual mode, because of the extremely weird way prefixes are handled by Configurable/ReaderConfig/DocSettings/ConfigDialog.
So, make sure we only have a *single* zoom_factor, and that it's updated and saved properly under the right name everywhere.
Fixes inconsistencies between first swapping to manual mode, and what the ConfigDialog said/did (because again: possibly a lie), vs., re-opening the same document, which would magically use *different* settings, closer to what was expected (but still broken because of the prefix mismatch and a disagreement on defaults between the two variants).
Fallout from #6885
(i.e., when History is spawned from ReaderUI, delay the flash until we
*show* the next widget, instead of when we close the current RD
instance).
Prevents flashing the InfoMessage.
Notification: adds some functions so it can be used as
a notification manager.
Have various bits of code emitting events that may generate
notifications advertize themselves as the source for following
notifications.
Add a menu to allow selecting some subsets of sources
to show or hide.
Add a new reader module: ReaderScrolling, that exposes
some Scrolling options to the menu (which are to be used
by and implemented in ReaderPaging and ReaderRolling
themselves) and implement some inertial scrolling logic
used by both of them.
Default to "Classic scrolling" which is the expected
behaviour on phones and tablets.
The old CreDocument buggy behaviour is available as
"Turbo scrolling" for both Paging and Rolling documents.
Added a "On release scrolling" option that might be
useful on eInk to avoid dynamic pan/scrolling.
Try to avoid bad interactions between pan and swipe,
cancelling unwanted panning if we ended up doing a
swipe or multiswipe.
- TextWidget: avoid crash with small max_width (could happen
when opening menu on a small emulator window)
- TextWidget: avoid crash if re-used after :free()
- ReaderHighlight:clear(): fix possible crash when
scheduled and run after document closed
- DictQuickLookup: minor canSearch() tweak ('selected_text'
is normally available only on multiple words selection,
but is currently available on single word selection thanks
to some unrelated side effect)
Whith the new font size step of 0.5 (46a2d9c), the gesture
for increasing or decreasing font size would change the
size by only half of the given value.
* Tear down FM instances properly
* Don't manhandle ReaderUI too much, and document when the tests do
actively broken shit, like bypassing safeties to open two // ReaderUI
instances.
Namely, instead of making it lower priority than readerhighlight and
hoping for the best, make it higher priority, as it should (ReaderFooter
itself is *above* Reader, after all), with a sane set of fallthroughs:
* No footer
* No hold-to-skim
* Held outside the footer (but inside the footer tap zone)
This made the crap workaround from #7466 unnecessary, and actually fixes
the behavior in PDFs (because readerhighlight will match the *physical*
page, which may include off-screen content) and ePubs w/r eclaim bar
height (in which case, there's actual content behind the footer that
readerhighlight could have matched on).
Fix#7697
We've managed to trip a few of those on dimen fields post-init but
pre-paintTo in a few weird coner-cases, a point at which dimen is often
nil.
ConfigDialog: Deal with that very thing in update()
Fix#7656
A dotted line joining the ToC entry text to the
page number may make it easier to use.
(This replaces the menu item separator from d879062e.)
Also fix baselines aligment, which could be a bit off.
* FileManager/ReaderUI: Clarify the current instance accessor
Make it clearer that we actually store it in a *module/class* member, not an *instance* member.
Also, warn if there's a close/open mismatch.
Ought to be faster than our naive array-based approach.
Especially for the glyph cache, which has a solid amount of elements,
and is mostly cache hits.
(There are few things worse for performance in Lua than
table.remove @ !tail and table.insert @ !tail, which this was full of :/).
DocCache: New module that's now an actual Cache instance instead of a
weird hack. Replaces "Cache" (the instance) as used across Document &
co.
Only Cache instance with on-disk persistence.
ImageCache: Update to new Cache.
GlyphCache: Update to new Cache.
Also, actually free glyph bbs on eviction.
* Minor updates to the min & max cache sizes (16 & 64MB). Mostly to satisfy my power-of-two OCD.
* Purge broken on-disk cache files
* Optimize free RAM computations
* Start dropping LRU items when running low on memory before pre-rendring (hinting) pages in non-reflowable documents.
* Make serialize dump the most recently *displayed* page, as the actual MRU item is the most recently *hinted* page, not the current one.
* Use more accurate item size estimations across the whole codebase.
TileCacheItem:
* Drop lua-serialize in favor of Persist.
KoptInterface:
* Drop lua-serialize in favor of Persist.
* Make KOPTContext caching actually work by ensuring its hash is stable.
* Ensure that going from one to the other tears down the former and
its plugins before instantiating the latter and its plugins.
UIManager: Unify Event sending & broadcasting
* Make the two behave the same way (walk the widget stack from top to
bottom), and properly handle the window stack shrinking shrinking
*and* growing.
Previously, broadcasting happened bottom-to-top and didn't really
handle the list shrinking/growing, while sending only handled the list
shrinking by a single element, and hopefully that element being the one
the event was just sent to.
These two items combined allowed us to optimize suboptimal
refresh behavior with Menu and other Menu classes when
opening/closing a document.
e.g., the "opening document" Notification is now properly regional,
and the "open last doc" option no longer flashes like a crazy person
anymore.
Plugins: Allow optimizing Menu refresh with custom menus, too.
Requires moving Menu's close_callback *after* onMenuSelect, which, eh,
probably makes sense, and is probably harmless in the grand scheme of
things.
* PluginLoader: Allow querying whether a specific plugin is loaded (instantiated, actually).
Re #7598
* PluginLoader: Add a method to access a specific Plugin's instance
(Besides `self.ui[plugin_name]`, that is).
Requires some nastiness to avoid pinning stale references in memory :s.
* PluginLoader: Tweak genPluginManagerSubItem to keep from rebuilding `self.all_plugins`, it's using `loadPlugins`, which is cached, so it made no sense to re-compute this one.
Includes:
- MathML: a few minor fixes
- (Upstream) lvtext: fix possible index out of range
- Fonts: RegisterExternalFont() should take a documentId
- Fonts: fix: letter-spacing should not be applied on diacritic
- (Upstream) Fonts: more granular synthetic weights
- Fonts: synthesized weights: tweak some comments
- Fonts: keep hinting with synthetic weight
- Fonts: fix synthesized weight inconsitencies
- Fonts: fix getFontFileNameAndFaceIndex()
- Fonts: adds LVFontMan::RegularizeRegisteredFontsWeights()
- Fonts: handle synth_weight tweaks in glyph/glyphinfo slots
- (Upstream) Fonts: fix some compiler warnings
- Fix hyphenation on Armenian and Georgian text
Update the bottom menu widget "Font Weight" to allow more
granular weights than the previous "regular | bold".
Also bump thirdparty/luasec to v1.0.1.
Similar in spirit to the previous commit, although since we're drawn as
part of the CRe page, this is just the refresh per-se that's optimized,
it had no chance to actually be visible.
Make sure we don't repaint the footer over anything else than ReaderUI,
as some events are fired without direct UI interaction, so we can't be
assured of the actual state of the UI.
Fix#7556
Exposed since #7379, but could arguably happen with other existing
handlers before.
* Support cancelling individual moves.
Coopt the cancel button to actually do just that, cancel, instead of close.
* Don't close when hitting the accept button, allowing to chain multiple moves.
Changes are still propagated to the caller on each individual move, though.
* Update the new icons to match our usual stroke width.
* ReaderToc: Tweak padding around items to be a tad more balanced for multi-level ToCs, and perfectly balanced for flat ToCs. (Re #7548)
* ReaderToc: Make the onHold popup's width match said padding. (Re #7548)
* InfoMessage: Allow passing the alignment flag to TextBoxWidget
* ReaderToc: Center text inside the InfoMessage onHold popup
* Input: Don't create a new TimeVal object for input frame timestamps, just promote our existing table by assigning it the `TimeVal` metatable.
* TimeVal: Export (const) `zero` & `huge` TimeVal objects, because they're common enough in our codebase. (NOTE: not actually const, that's a Lua 5.4 feature ;p).
* GestureDetector: Explain the behavior of the `last_tevs` & `first_tevs` tables, and why one needs a new object and not the other.
* Speaking of, simplify the copy method for `first_tevs`, because it doesn't need to create a new TimeVal object, we can just reference the original, it's unique and re-assigned for each frame.
There have been a couple of these this month, and keeping stuff that should only ever run once piling up in their respective module was getting ugly, especially when it's usually simple stuff (settings, files).
So, move everything to a dedicated module, run by reader.lua on startup, and that will actually only do things once, when necessary.
Attempting to update a highlight when matching on a bookmark doesn't
make sense, and no longer works since #7411
Also, switch to ipairs(), and stop piggybacking on a new local that
shadows or uses the function's item argument.
It works in Lua, but it's super weird and error-prone.
Fix#7520 (regression since #7411).