From 1a1c2316b74cd2bc76ed446c3649739406a135c7 Mon Sep 17 00:00:00 2001 From: Mirus Date: Tue, 3 Mar 2026 08:01:47 +0200 Subject: [PATCH 1/5] chore: new Ukrainian localization strings (#1270) ## Summary * **What changes are included?** New Ukrainian localization strings ## Additional Context auto turn functionality https://github.com/crosspoint-reader/crosspoint-reader/pull/1219 --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**NO **_ --- lib/I18n/translations/ukrainian.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/I18n/translations/ukrainian.yaml b/lib/I18n/translations/ukrainian.yaml index 4bcb097f..88d96259 100644 --- a/lib/I18n/translations/ukrainian.yaml +++ b/lib/I18n/translations/ukrainian.yaml @@ -297,6 +297,7 @@ STR_GO_TO_PERCENT: "Перейти до %" STR_GO_HOME_BUTTON: "На головну" STR_SYNC_PROGRESS: "Прогрес синхронізації" STR_DELETE_CACHE: "Видалити кеш книги" +STR_DELETE: "Видалити" STR_DISPLAY_QR: "Показати сторінку як QR-код" STR_CHAPTER_PREFIX: "Розділ: " STR_PAGES_SEPARATOR: " сторінок | " @@ -334,3 +335,5 @@ STR_FOOTNOTES: "Зноски" STR_NO_FOOTNOTES: "На цій сторінці немає зносок" STR_LINK: "[посилання]" STR_SCREENSHOT_BUTTON: "Знімок екрана" +STR_AUTO_TURN_ENABLED: "Автоперегортання увімк: " +STR_AUTO_TURN_PAGES_PER_MIN: "Автоперегортання (ст/хв)" \ No newline at end of file From 2d0c99671abca8e3997a126f588cec0930ddd1f6 Mon Sep 17 00:00:00 2001 From: Dave Allie Date: Wed, 4 Mar 2026 01:41:02 +1100 Subject: [PATCH 2/5] fix: Enable DESTRUCTOR_CLOSES_FILE flag (#1075) ## Summary * Enable `DESTRUCTOR_CLOSES_FILE` flag * We're never intending to not close files, so if we accidentally leave them open as they're destructured, this will help close them. ## Additional Context * As spotted in https://github.com/crosspoint-reader/crosspoint-reader/pull/869, there are cases where we were accidentally not closing files Looks to use about 5K of flash. ``` RAM: [=== ] 31.5% (used 103100 bytes from 327680 bytes) Flash: [======= ] 68.9% (used 4513220 bytes from 6553600 bytes) ``` ``` RAM: [=== ] 31.5% (used 103100 bytes from 327680 bytes) Flash: [======= ] 68.9% (used 4518498 bytes from 6553600 bytes) ``` --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? No --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index fc6bd0f6..691f1570 100644 --- a/platformio.ini +++ b/platformio.ini @@ -24,6 +24,7 @@ build_flags = -DARDUINO_USB_CDC_ON_BOOT=1 -DEINK_DISPLAY_SINGLE_BUFFER_MODE=1 -DDISABLE_FS_H_WARNING=1 + -DDESTRUCTOR_CLOSES_FILE=1 # https://libexpat.github.io/doc/api/latest/#XML_GE -DXML_GE=0 -DXML_CONTEXT_BYTES=1024 From 857f5badf6320d60194af886557638a3416413c9 Mon Sep 17 00:00:00 2001 From: Uri Tauber <142022451+Uri-Tauber@users.noreply.github.com> Date: Tue, 3 Mar 2026 17:57:57 +0200 Subject: [PATCH 3/5] fix: add Technically Unsupported section to SCOPE.md (#1295) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary **Goal of this PR** Add an **"In-scope — technically not supported"** section to `SCOPE.md`. This clarifies hardware/UX limitations (e.g., clock support) and is intended to reduce recurring feature requests on topics already discussed. Based on discussions in #287 and #626. --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**< NO >**_ --- SCOPE.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/SCOPE.md b/SCOPE.md index 68099787..3559ec19 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -39,6 +39,14 @@ usability over "swiss-army-knife" functionality. * **Complex Annotation:** No typed out notes. These features are better suited for devices with better input capabilities and more powerful chips. +### In-scope — Technically Unsupported + +*These features align with CrossPoint's goals but are impractical on the current hardware or produce poor UX.* + +* **Clock Display:** The ESP32-C3's RTC drifts significantly during deep sleep; making the clock untrustworthy after any sleep cycle. NTP sync could help, but CrossPoint doesn't connect to the internet on every boot. + +* **PDF Rendering:** PDFs are fixed-layout documents, so rendering them requires displaying pages as images rather than reflowable text — resulting in constant panning and zooming that makes for a poor reading experience on e-ink. + ## 3. Idea Evaluation While I appreciate the desire to add new and exciting features to CrossPoint Reader, CrossPoint Reader is designed to be From c8cbbb3ffa956dab1a6b51f628df8d28b3a9eada Mon Sep 17 00:00:00 2001 From: jpirnay Date: Tue, 3 Mar 2026 16:59:06 +0100 Subject: [PATCH 4/5] feat: User setting for image display (#1291) ## Summary **What is the goal of this PR?** Add a user setting to decide image support: display, show placeholder instead, supress fully Fixes #1289 --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**< NO >**_ --- lib/Epub/Epub/Section.cpp | 23 +++++++++++-------- lib/Epub/Epub/Section.h | 7 +++--- .../Epub/parsers/ChapterHtmlSlimParser.cpp | 9 +++++++- lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h | 6 +++-- lib/I18n/translations/english.yaml | 4 ++++ src/CrossPointSettings.h | 7 ++++++ src/SettingsList.h | 3 +++ src/activities/reader/EpubReaderActivity.cpp | 6 +++-- 8 files changed, 48 insertions(+), 17 deletions(-) diff --git a/lib/Epub/Epub/Section.cpp b/lib/Epub/Epub/Section.cpp index 6e5aadf9..bc04d475 100644 --- a/lib/Epub/Epub/Section.cpp +++ b/lib/Epub/Epub/Section.cpp @@ -10,10 +10,10 @@ #include "parsers/ChapterHtmlSlimParser.h" namespace { -constexpr uint8_t SECTION_FILE_VERSION = 16; +constexpr uint8_t SECTION_FILE_VERSION = 17; constexpr uint32_t HEADER_SIZE = sizeof(uint8_t) + sizeof(int) + sizeof(float) + sizeof(bool) + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(bool) + sizeof(bool) + - sizeof(uint32_t); + sizeof(uint8_t) + sizeof(uint32_t); } // namespace uint32_t Section::onPageComplete(std::unique_ptr page) { @@ -36,7 +36,7 @@ uint32_t Section::onPageComplete(std::unique_ptr page) { void Section::writeSectionFileHeader(const int fontId, const float lineCompression, const bool extraParagraphSpacing, const uint8_t paragraphAlignment, const uint16_t viewportWidth, const uint16_t viewportHeight, const bool hyphenationEnabled, - const bool embeddedStyle) { + const bool embeddedStyle, const uint8_t imageRendering) { if (!file) { LOG_DBG("SCT", "File not open for writing header"); return; @@ -44,7 +44,7 @@ void Section::writeSectionFileHeader(const int fontId, const float lineCompressi static_assert(HEADER_SIZE == sizeof(SECTION_FILE_VERSION) + sizeof(fontId) + sizeof(lineCompression) + sizeof(extraParagraphSpacing) + sizeof(paragraphAlignment) + sizeof(viewportWidth) + sizeof(viewportHeight) + sizeof(pageCount) + sizeof(hyphenationEnabled) + - sizeof(embeddedStyle) + sizeof(uint32_t), + sizeof(embeddedStyle) + sizeof(imageRendering) + sizeof(uint32_t), "Header size mismatch"); serialization::writePod(file, SECTION_FILE_VERSION); serialization::writePod(file, fontId); @@ -55,13 +55,15 @@ void Section::writeSectionFileHeader(const int fontId, const float lineCompressi serialization::writePod(file, viewportHeight); serialization::writePod(file, hyphenationEnabled); serialization::writePod(file, embeddedStyle); + serialization::writePod(file, imageRendering); serialization::writePod(file, pageCount); // Placeholder for page count (will be initially 0 when written) serialization::writePod(file, static_cast(0)); // Placeholder for LUT offset } bool Section::loadSectionFile(const int fontId, const float lineCompression, const bool extraParagraphSpacing, const uint8_t paragraphAlignment, const uint16_t viewportWidth, - const uint16_t viewportHeight, const bool hyphenationEnabled, const bool embeddedStyle) { + const uint16_t viewportHeight, const bool hyphenationEnabled, const bool embeddedStyle, + const uint8_t imageRendering) { if (!Storage.openFileForRead("SCT", filePath, file)) { return false; } @@ -84,6 +86,7 @@ bool Section::loadSectionFile(const int fontId, const float lineCompression, con uint8_t fileParagraphAlignment; bool fileHyphenationEnabled; bool fileEmbeddedStyle; + uint8_t fileImageRendering; serialization::readPod(file, fileFontId); serialization::readPod(file, fileLineCompression); serialization::readPod(file, fileExtraParagraphSpacing); @@ -92,11 +95,13 @@ bool Section::loadSectionFile(const int fontId, const float lineCompression, con serialization::readPod(file, fileViewportHeight); serialization::readPod(file, fileHyphenationEnabled); serialization::readPod(file, fileEmbeddedStyle); + serialization::readPod(file, fileImageRendering); if (fontId != fileFontId || lineCompression != fileLineCompression || extraParagraphSpacing != fileExtraParagraphSpacing || paragraphAlignment != fileParagraphAlignment || viewportWidth != fileViewportWidth || viewportHeight != fileViewportHeight || - hyphenationEnabled != fileHyphenationEnabled || embeddedStyle != fileEmbeddedStyle) { + hyphenationEnabled != fileHyphenationEnabled || embeddedStyle != fileEmbeddedStyle || + imageRendering != fileImageRendering) { file.close(); LOG_ERR("SCT", "Deserialization failed: Parameters do not match"); clearCache(); @@ -129,7 +134,7 @@ bool Section::clearCache() const { bool Section::createSectionFile(const int fontId, const float lineCompression, const bool extraParagraphSpacing, const uint8_t paragraphAlignment, const uint16_t viewportWidth, const uint16_t viewportHeight, const bool hyphenationEnabled, const bool embeddedStyle, - const std::function& popupFn) { + const uint8_t imageRendering, const std::function& popupFn) { const auto localPath = epub->getSpineItem(spineIndex).href; const auto tmpHtmlPath = epub->getCachePath() + "/.tmp_" + std::to_string(spineIndex) + ".html"; @@ -179,7 +184,7 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c return false; } writeSectionFileHeader(fontId, lineCompression, extraParagraphSpacing, paragraphAlignment, viewportWidth, - viewportHeight, hyphenationEnabled, embeddedStyle); + viewportHeight, hyphenationEnabled, embeddedStyle, imageRendering); std::vector lut = {}; // Derive the content base directory and image cache path prefix for the parser @@ -201,7 +206,7 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c epub, tmpHtmlPath, renderer, fontId, lineCompression, extraParagraphSpacing, paragraphAlignment, viewportWidth, viewportHeight, hyphenationEnabled, [this, &lut](std::unique_ptr page) { lut.emplace_back(this->onPageComplete(std::move(page))); }, - embeddedStyle, contentBase, imageBasePath, popupFn, cssParser); + embeddedStyle, contentBase, imageBasePath, imageRendering, popupFn, cssParser); Hyphenator::setPreferredLanguage(epub->getLanguage()); success = visitor.parseAndBuildPages(); diff --git a/lib/Epub/Epub/Section.h b/lib/Epub/Epub/Section.h index 42a6d993..70fd0fe5 100644 --- a/lib/Epub/Epub/Section.h +++ b/lib/Epub/Epub/Section.h @@ -16,7 +16,7 @@ class Section { void writeSectionFileHeader(int fontId, float lineCompression, bool extraParagraphSpacing, uint8_t paragraphAlignment, uint16_t viewportWidth, uint16_t viewportHeight, bool hyphenationEnabled, - bool embeddedStyle); + bool embeddedStyle, uint8_t imageRendering); uint32_t onPageComplete(std::unique_ptr page); public: @@ -30,10 +30,11 @@ class Section { filePath(epub->getCachePath() + "/sections/" + std::to_string(spineIndex) + ".bin") {} ~Section() = default; bool loadSectionFile(int fontId, float lineCompression, bool extraParagraphSpacing, uint8_t paragraphAlignment, - uint16_t viewportWidth, uint16_t viewportHeight, bool hyphenationEnabled, bool embeddedStyle); + uint16_t viewportWidth, uint16_t viewportHeight, bool hyphenationEnabled, bool embeddedStyle, + uint8_t imageRendering); bool clearCache() const; bool createSectionFile(int fontId, float lineCompression, bool extraParagraphSpacing, uint8_t paragraphAlignment, uint16_t viewportWidth, uint16_t viewportHeight, bool hyphenationEnabled, bool embeddedStyle, - const std::function& popupFn = nullptr); + uint8_t imageRendering, const std::function& popupFn = nullptr); std::unique_ptr loadPageFromSectionFile(); }; diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp index 2753f928..6a0636bb 100644 --- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp +++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp @@ -243,7 +243,14 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* } } - if (!src.empty()) { + // imageRendering: 0=display, 1=placeholder (alt text only), 2=suppress entirely + if (self->imageRendering == 2) { + self->skipUntilDepth = self->depth; + self->depth += 1; + return; + } + + if (!src.empty() && self->imageRendering != 1) { LOG_DBG("EHP", "Found image: src=%s", src.c_str()); { diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h index 663ce860..ce530797 100644 --- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h +++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h @@ -48,6 +48,7 @@ class ChapterHtmlSlimParser { bool hyphenationEnabled; const CssParser* cssParser; bool embeddedStyle; + uint8_t imageRendering; std::string contentBase; std::string imageBasePath; int imageCounter = 0; @@ -94,8 +95,8 @@ class ChapterHtmlSlimParser { const uint16_t viewportHeight, const bool hyphenationEnabled, const std::function)>& completePageFn, const bool embeddedStyle, const std::string& contentBase, - const std::string& imageBasePath, const std::function& popupFn = nullptr, - const CssParser* cssParser = nullptr) + const std::string& imageBasePath, const uint8_t imageRendering = 0, + const std::function& popupFn = nullptr, const CssParser* cssParser = nullptr) : epub(epub), filepath(filepath), @@ -111,6 +112,7 @@ class ChapterHtmlSlimParser { popupFn(popupFn), cssParser(cssParser), embeddedStyle(embeddedStyle), + imageRendering(imageRendering), contentBase(contentBase), imageBasePath(imageBasePath) {} diff --git a/lib/I18n/translations/english.yaml b/lib/I18n/translations/english.yaml index f5b80b8e..38192cc9 100644 --- a/lib/I18n/translations/english.yaml +++ b/lib/I18n/translations/english.yaml @@ -92,6 +92,10 @@ STR_STATUS_BAR: "Status Bar" STR_HIDE_BATTERY: "Hide Battery %" STR_EXTRA_SPACING: "Extra Paragraph Spacing" STR_TEXT_AA: "Text Anti-Aliasing" +STR_IMAGES: "Images" +STR_IMAGES_DISPLAY: "Display" +STR_IMAGES_PLACEHOLDER: "Placeholder" +STR_IMAGES_SUPPRESS: "Suppress" STR_SHORT_PWR_BTN: "Short Power Button Click" STR_ORIENTATION: "Reading Orientation" STR_FRONT_BTN_LAYOUT: "Front Button Layout" diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index 5ba7bde2..9a0e298b 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -134,6 +134,9 @@ class CrossPointSettings { // UI Theme enum UI_THEME { CLASSIC = 0, LYRA = 1, LYRA_3_COVERS = 2 }; + // Image rendering in EPUB reader + enum IMAGE_RENDERING { IMAGES_DISPLAY = 0, IMAGES_PLACEHOLDER = 1, IMAGES_SUPPRESS = 2, IMAGE_RENDERING_COUNT }; + // Sleep screen settings uint8_t sleepScreen = DARK; // Sleep screen cover mode settings @@ -192,6 +195,10 @@ class CrossPointSettings { uint8_t fadingFix = 0; // Use book's embedded CSS styles for EPUB rendering (1 = enabled, 0 = disabled) uint8_t embeddedStyle = 1; + // Show hidden files/directories (starting with '.') in the file browser (0 = hidden, 1 = show) + uint8_t showHiddenFiles = 0; + // Image rendering mode in EPUB reader + uint8_t imageRendering = IMAGES_DISPLAY; ~CrossPointSettings() = default; diff --git a/src/SettingsList.h b/src/SettingsList.h index c10d58c6..f69c9e93 100644 --- a/src/SettingsList.h +++ b/src/SettingsList.h @@ -62,6 +62,9 @@ inline const std::vector& getSettingsList() { StrId::STR_CAT_READER), SettingInfo::Toggle(StrId::STR_TEXT_AA, &CrossPointSettings::textAntiAliasing, "textAntiAliasing", StrId::STR_CAT_READER), + SettingInfo::Enum(StrId::STR_IMAGES, &CrossPointSettings::imageRendering, + {StrId::STR_IMAGES_DISPLAY, StrId::STR_IMAGES_PLACEHOLDER, StrId::STR_IMAGES_SUPPRESS}, + "imageRendering", StrId::STR_CAT_READER), // --- Controls --- SettingInfo::Enum(StrId::STR_SIDE_BTN_LAYOUT, &CrossPointSettings::sideButtonLayout, {StrId::STR_PREV_NEXT, StrId::STR_NEXT_PREV}, "sideButtonLayout", StrId::STR_CAT_CONTROLS), diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index d889df5f..059d3ea1 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -571,14 +571,16 @@ void EpubReaderActivity::render(RenderLock&& lock) { if (!section->loadSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(), SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth, - viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle)) { + viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle, + SETTINGS.imageRendering)) { LOG_DBG("ERS", "Cache not found, building..."); const auto popupFn = [this]() { GUI.drawPopup(renderer, tr(STR_INDEXING)); }; if (!section->createSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(), SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth, - viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle, popupFn)) { + viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle, + SETTINGS.imageRendering, popupFn)) { LOG_ERR("ERS", "Failed to persist page data to SD"); section.reset(); return; From af4d87b7cc85d95a2cc97625fc12ac59b3d6cbc6 Mon Sep 17 00:00:00 2001 From: jpirnay Date: Tue, 3 Mar 2026 17:02:04 +0100 Subject: [PATCH 5/5] fix: Extend missing / amend existing German translations (#1226) ## Summary * **What is the goal of this PR?** Extend missing / amend existing German translations * **What changes are included?** German.yaml ## Additional Context --- --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**NO**_ Co-authored-by: Arthur Tazhitdinov --- lib/I18n/translations/german.yaml | 35 +++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/I18n/translations/german.yaml b/lib/I18n/translations/german.yaml index 863c0bcb..aebff633 100644 --- a/lib/I18n/translations/german.yaml +++ b/lib/I18n/translations/german.yaml @@ -63,7 +63,7 @@ STR_MAC_ADDRESS: "MAC-Adresse:" STR_CHECKING_WIFI: "WLAN prüfen…" STR_ENTER_WIFI_PASSWORD: "WLAN-Passwort eingeben" STR_ENTER_TEXT: "Text eingeben" -STR_TO_PREFIX: "bis" +STR_TO_PREFIX: "mit " STR_CALIBRE_DISCOVERING: "Calibre finden..." STR_CALIBRE_CONNECTING_TO: "Verbinden mit" STR_CALIBRE_CONNECTED_TO: "Verbunden mit" @@ -120,7 +120,7 @@ STR_SELECT_WALLPAPER: "Bildauswahl Standby" STR_CLEAR_READING_CACHE: "Lese-Cache leeren" STR_CALIBRE: "Calibre" STR_USERNAME: "Benutzername" -STR_PASSWORD: "Passwort nötig" +STR_PASSWORD: "Passwort" STR_SYNC_SERVER_URL: "Sync-Server-URL" STR_DOCUMENT_MATCHING: "Dateizuordnung" STR_AUTHENTICATE: "Authentifizieren" @@ -169,7 +169,7 @@ STR_FRONT_LAYOUT_BCLR: "Zurück, Bst, L, R" STR_FRONT_LAYOUT_LRBC: "L, R, Zurück, Bst" STR_FRONT_LAYOUT_LBCR: "L, Zurück, Bst, R" STR_PREV_NEXT: "Zurück/Weiter" -STR_NEXT_PREV: "Weiter/Zuürck" +STR_NEXT_PREV: "Weiter/Zurück" STR_BOOKERLY: "Bookerly" STR_NOTO_SANS: "Noto Sans" STR_OPEN_DYSLEXIC: "Open Dyslexic" @@ -236,6 +236,8 @@ STR_DOWNLOAD: "Herunterladen" STR_RETRY: "Wiederh." STR_YES: "Ja" STR_NO: "Nein" +STR_SHOW: "Zeigen" +STR_HIDE: "Ausblenden" STR_STATE_ON: "An" STR_STATE_OFF: "Aus" STR_NOT_SET: "Leer" @@ -248,6 +250,21 @@ STR_CAPS_OFF: "umsch" STR_OK_BUTTON: "OK" STR_SLEEP_COVER_FILTER: "Standby-Coverfilter" STR_FILTER_CONTRAST: "Kontrast" +STR_CUSTOMISE_STATUS_BAR: "Statusleiste anpassen" +STR_CHAPTER_PAGE_COUNT: "Kapitel-Seitenanzahl" +STR_BOOK_PROGRESS_PERCENTAGE: "Buchfortschritt in %" +STR_PROGRESS_BAR: "Fortschrittsbalken" +STR_PROGRESS_BAR_THICKNESS: "Balkenstärke" +STR_PROGRESS_BAR_THIN: "Dünn" +STR_PROGRESS_BAR_MEDIUM: "Mittel" +STR_PROGRESS_BAR_THICK: "Dick" +STR_BOOK: "Buch" +STR_CHAPTER: "Kapitel" +STR_EXAMPLE_CHAPTER: "Kapitel 21" +STR_EXAMPLE_BOOK: "Buchtitel" +STR_PREVIEW: "Vorschau" +STR_TITLE: "Titel" +STR_BATTERY: "Batterie" STR_UI_THEME: "System-Design" STR_THEME_CLASSIC: "Klassisch" STR_THEME_LYRA: "Lyra" @@ -280,6 +297,7 @@ STR_GO_TO_PERCENT: "Gehe zu %" STR_GO_HOME_BUTTON: "Zum Anfang" STR_SYNC_PROGRESS: "Fortschritt synchronisieren" STR_DELETE_CACHE: "Buch-Cache leeren" +STR_DISPLAY_QR: "Seite als QR anzeigen" STR_DELETE: "Löschen" STR_CHAPTER_PREFIX: "Kapitel:" STR_PAGES_SEPARATOR: " Seiten | " @@ -289,7 +307,7 @@ STR_KBD_SHIFT_CAPS: "UMSCH" STR_KBD_LOCK: "FESTST" STR_CALIBRE_URL_HINT: "Calibre: URL um /opds ergänzen" STR_PERCENT_STEP_HINT: "links/rechts: 1% hoch/runter: 10%" -STR_SYNCING_TIME: "Zeit synchonisieren…" +STR_SYNCING_TIME: "Zeit synchronisieren…" STR_CALC_HASH: "Dokument-Hash berechnen…" STR_HASH_FAILED: "Dokument-Hash fehlgeschlagen" STR_FETCH_PROGRESS: "Externen Fortschritt abrufen..." @@ -302,8 +320,8 @@ STR_LOCAL_LABEL: "Lokal:" STR_PAGE_OVERALL_FORMAT: " Seite %d, %.2f%% insgesamt" STR_PAGE_TOTAL_OVERALL_FORMAT: " Seite %d/%d, %.2f%% insgesamt" STR_DEVICE_FROM_FORMAT: " Von: %s" -STR_APPLY_REMOTE: "Ext. Fortschritt übern." -STR_UPLOAD_LOCAL: "Lokalen Fortschritt hochl." +STR_APPLY_REMOTE: "Externen Fortschritt übernehmen" +STR_UPLOAD_LOCAL: "Lokalen Fortschritt hochladen" STR_NO_REMOTE_MSG: "Kein externer Fortschritt" STR_UPLOAD_PROMPT: "Aktuelle Position hochladen?" STR_UPLOAD_SUCCESS: "Hochgeladen!" @@ -314,3 +332,8 @@ STR_BOOK_S_STYLE: "Buch-Stil" STR_EMBEDDED_STYLE: "Eingebetteter Stil" STR_OPDS_SERVER_URL: "OPDS-Server-URL" STR_SCREENSHOT_BUTTON: "Screenshot aufnehmen" +STR_FOOTNOTES: "Fußnoten" +STR_NO_FOOTNOTES: "Keine Fußnoten auf dieser Seite" +STR_LINK: "[Link]" +STR_AUTO_TURN_ENABLED: "Auto-Umblättern aktiv: " +STR_AUTO_TURN_PAGES_PER_MIN: "Auto-Umblättern (Seiten/Min.)"