From 624586ec0364c2cfafd2aefdc66245dcbaeec6b4 Mon Sep 17 00:00:00 2001 From: bean <62624884+alpsfordays@users.noreply.github.com> Date: Sat, 10 Jan 2026 01:16:39 -0500 Subject: [PATCH] Traduction initiale --- src/activities/boot_sleep/BootActivity.cpp | 2 +- src/activities/boot_sleep/SleepActivity.cpp | 34 +++--- .../browser/OpdsBookBrowserActivity.cpp | 56 ++++----- src/activities/home/HomeActivity.cpp | 12 +- .../network/CalibreWirelessActivity.cpp | 2 +- .../network/CrossPointWebServerActivity.cpp | 106 +++++++++--------- .../network/NetworkModeSelectionActivity.cpp | 12 +- .../network/WifiSelectionActivity.cpp | 88 +++++++-------- src/activities/reader/EpubReaderActivity.cpp | 36 +++--- .../reader/FileSelectionActivity.cpp | 6 +- src/activities/reader/ReaderActivity.cpp | 14 +-- src/activities/reader/XtcReaderActivity.cpp | 8 +- .../settings/CalibreSettingsActivity.cpp | 8 +- src/activities/settings/OtaUpdateActivity.cpp | 40 +++---- src/activities/settings/SettingsActivity.cpp | 54 ++++----- 15 files changed, 239 insertions(+), 239 deletions(-) diff --git a/src/activities/boot_sleep/BootActivity.cpp b/src/activities/boot_sleep/BootActivity.cpp index 65eb6a07..fa4fce9b 100644 --- a/src/activities/boot_sleep/BootActivity.cpp +++ b/src/activities/boot_sleep/BootActivity.cpp @@ -14,7 +14,7 @@ void BootActivity::onEnter() { renderer.clearScreen(); renderer.drawImage(CrossLarge, (pageWidth + 128) / 2, (pageHeight - 128) / 2, 128, 128); renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 + 70, "CrossPoint", true, EpdFontFamily::BOLD); - renderer.drawCenteredText(SMALL_FONT_ID, pageHeight / 2 + 95, "BOOTING"); + renderer.drawCenteredText(SMALL_FONT_ID, pageHeight / 2 + 95, "DÉMARRAGE"); renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, CROSSPOINT_VERSION); renderer.displayBuffer(); } diff --git a/src/activities/boot_sleep/SleepActivity.cpp b/src/activities/boot_sleep/SleepActivity.cpp index 43e8e60b..b0abebce 100644 --- a/src/activities/boot_sleep/SleepActivity.cpp +++ b/src/activities/boot_sleep/SleepActivity.cpp @@ -13,7 +13,7 @@ void SleepActivity::onEnter() { Activity::onEnter(); - renderPopup("Entering Sleep..."); + renderPopup("Mise en veille..."); if (SETTINGS.sleepScreen == CrossPointSettings::SLEEP_SCREEN_MODE::BLANK) { return renderBlankSleepScreen(); @@ -64,13 +64,13 @@ void SleepActivity::renderCustomSleepScreen() const { } if (filename.substr(filename.length() - 4) != ".bmp") { - Serial.printf("[%lu] [SLP] Skipping non-.bmp file name: %s\n", millis(), name); + Serial.printf("[%lu] [SLP] Ignorer les noms de fichiers non-.bmp: %s\n", millis(), name); file.close(); continue; } Bitmap bitmap(file); if (bitmap.parseHeaders() != BmpReaderError::Ok) { - Serial.printf("[%lu] [SLP] Skipping invalid BMP file: %s\n", millis(), name); + Serial.printf("[%lu] [SLP] Ignorer le fichier BMP invalide: %s\n", millis(), name); file.close(); continue; } @@ -84,7 +84,7 @@ void SleepActivity::renderCustomSleepScreen() const { const auto filename = "/sleep/" + files[randomFileIndex]; FsFile file; if (SdMan.openFileForRead("SLP", filename, file)) { - Serial.printf("[%lu] [SLP] Randomly loading: /sleep/%s\n", millis(), files[randomFileIndex].c_str()); + Serial.printf("[%lu] [SLP] Chargement aléatoire: /sleep/%s\n", millis(), files[randomFileIndex].c_str()); delay(100); Bitmap bitmap(file); if (bitmap.parseHeaders() == BmpReaderError::Ok) { @@ -103,7 +103,7 @@ void SleepActivity::renderCustomSleepScreen() const { if (SdMan.openFileForRead("SLP", "/sleep.bmp", file)) { Bitmap bitmap(file); if (bitmap.parseHeaders() == BmpReaderError::Ok) { - Serial.printf("[%lu] [SLP] Loading: /sleep.bmp\n", millis()); + Serial.printf("[%lu] [SLP] Chargement: /sleep.bmp\n", millis()); renderBitmapSleepScreen(bitmap); return; } @@ -119,7 +119,7 @@ void SleepActivity::renderDefaultSleepScreen() const { renderer.clearScreen(); renderer.drawImage(CrossLarge, (pageWidth + 128) / 2, (pageHeight - 128) / 2, 128, 128); renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 + 70, "CrossPoint", true, EpdFontFamily::BOLD); - renderer.drawCenteredText(SMALL_FONT_ID, pageHeight / 2 + 95, "SLEEPING"); + renderer.drawCenteredText(SMALL_FONT_ID, pageHeight / 2 + 95, "EN VEILLE"); // Make sleep screen dark unless light is selected in settings if (SETTINGS.sleepScreen != CrossPointSettings::SLEEP_SCREEN_MODE::LIGHT) { @@ -135,34 +135,34 @@ void SleepActivity::renderBitmapSleepScreen(const Bitmap& bitmap) const { const auto pageHeight = renderer.getScreenHeight(); float cropX = 0, cropY = 0; - Serial.printf("[%lu] [SLP] bitmap %d x %d, screen %d x %d\n", millis(), bitmap.getWidth(), bitmap.getHeight(), + Serial.printf("[%lu] [SLP] bitmap %d x %d, écran %d x %d\n", millis(), bitmap.getWidth(), bitmap.getHeight(), pageWidth, pageHeight); if (bitmap.getWidth() > pageWidth || bitmap.getHeight() > pageHeight) { // image will scale, make sure placement is right float ratio = static_cast(bitmap.getWidth()) / static_cast(bitmap.getHeight()); const float screenRatio = static_cast(pageWidth) / static_cast(pageHeight); - Serial.printf("[%lu] [SLP] bitmap ratio: %f, screen ratio: %f\n", millis(), ratio, screenRatio); + Serial.printf("[%lu] [SLP] ratio bitmap: %f, ratio écran: %f\n", millis(), ratio, screenRatio); if (ratio > screenRatio) { // image wider than viewport ratio, scaled down image needs to be centered vertically if (SETTINGS.sleepScreenCoverMode == CrossPointSettings::SLEEP_SCREEN_COVER_MODE::CROP) { cropX = 1.0f - (screenRatio / ratio); - Serial.printf("[%lu] [SLP] Cropping bitmap x: %f\n", millis(), cropX); + Serial.printf("[%lu] [SLP] Recadrage de bitmap x: %f\n", millis(), cropX); ratio = (1.0f - cropX) * static_cast(bitmap.getWidth()) / static_cast(bitmap.getHeight()); } x = 0; y = std::round((static_cast(pageHeight) - static_cast(pageWidth) / ratio) / 2); - Serial.printf("[%lu] [SLP] Centering with ratio %f to y=%d\n", millis(), ratio, y); + Serial.printf("[%lu] [SLP] Centrage avec ratio de %f à y=%d\n", millis(), ratio, y); } else { // image taller than viewport ratio, scaled down image needs to be centered horizontally if (SETTINGS.sleepScreenCoverMode == CrossPointSettings::SLEEP_SCREEN_COVER_MODE::CROP) { cropY = 1.0f - (ratio / screenRatio); - Serial.printf("[%lu] [SLP] Cropping bitmap y: %f\n", millis(), cropY); + Serial.printf("[%lu] [SLP] Recadrage bitmap y: %f\n", millis(), cropY); ratio = static_cast(bitmap.getWidth()) / ((1.0f - cropY) * static_cast(bitmap.getHeight())); } x = std::round((pageWidth - pageHeight * ratio) / 2); y = 0; - Serial.printf("[%lu] [SLP] Centering with ratio %f to x=%d\n", millis(), ratio, x); + Serial.printf("[%lu] [SLP] Centrage avec ratio de %f à x=%d\n", millis(), ratio, x); } } else { // center the image @@ -170,7 +170,7 @@ void SleepActivity::renderBitmapSleepScreen(const Bitmap& bitmap) const { y = (pageHeight - bitmap.getHeight()) / 2; } - Serial.printf("[%lu] [SLP] drawing to %d x %d\n", millis(), x, y); + Serial.printf("[%lu] [SLP] dessinage à %d x %d\n", millis(), x, y); renderer.clearScreen(); renderer.drawBitmap(bitmap, x, y, pageWidth, pageHeight, cropX, cropY); renderer.displayBuffer(EInkDisplay::HALF_REFRESH); @@ -205,12 +205,12 @@ void SleepActivity::renderCoverSleepScreen() const { // Handle XTC file Xtc lastXtc(APP_STATE.openEpubPath, "/.crosspoint"); if (!lastXtc.load()) { - Serial.println("[SLP] Failed to load last XTC"); + Serial.println("[SLP] Chargement échoué du dernier XTC"); return renderDefaultSleepScreen(); } if (!lastXtc.generateCoverBmp()) { - Serial.println("[SLP] Failed to generate XTC cover bmp"); + Serial.println("[SLP] Génération échoué de bmp de couverture XTC"); return renderDefaultSleepScreen(); } @@ -219,12 +219,12 @@ void SleepActivity::renderCoverSleepScreen() const { // Handle EPUB file Epub lastEpub(APP_STATE.openEpubPath, "/.crosspoint"); if (!lastEpub.load()) { - Serial.println("[SLP] Failed to load last epub"); + Serial.println("[SLP] Chargement échoué du dernier epub"); return renderDefaultSleepScreen(); } if (!lastEpub.generateCoverBmp()) { - Serial.println("[SLP] Failed to generate cover bmp"); + Serial.println("[SLP] Génération échoué de bmp de couverture"); return renderDefaultSleepScreen(); } diff --git a/src/activities/browser/OpdsBookBrowserActivity.cpp b/src/activities/browser/OpdsBookBrowserActivity.cpp index b9dbac8e..30d74451 100644 --- a/src/activities/browser/OpdsBookBrowserActivity.cpp +++ b/src/activities/browser/OpdsBookBrowserActivity.cpp @@ -34,7 +34,7 @@ void OpdsBookBrowserActivity::onEnter() { currentPath = OPDS_ROOT_PATH; selectorIndex = 0; errorMessage.clear(); - statusMessage = "Checking WiFi..."; + statusMessage = "Verification du WiFi..."; updateRequired = true; xTaskCreate(&OpdsBookBrowserActivity::taskTrampoline, "OpdsBookBrowserTask", @@ -70,7 +70,7 @@ void OpdsBookBrowserActivity::loop() { if (state == BrowserState::ERROR) { if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) { state = BrowserState::LOADING; - statusMessage = "Loading..."; + statusMessage = "Chargement..."; updateRequired = true; fetchFeed(currentPath); } else if (mappedInput.wasReleased(MappedInputManager::Button::Back)) { @@ -155,11 +155,11 @@ void OpdsBookBrowserActivity::render() const { const auto pageWidth = renderer.getScreenWidth(); const auto pageHeight = renderer.getScreenHeight(); - renderer.drawCenteredText(UI_12_FONT_ID, 15, "Calibre Library", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, 15, "Bilbiothèque Calibre", true, EpdFontFamily::BOLD); if (state == BrowserState::CHECK_WIFI) { renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2, statusMessage.c_str()); - const auto labels = mappedInput.mapLabels("« Back", "", "", ""); + const auto labels = mappedInput.mapLabels("« Retour", "", "", ""); renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); renderer.displayBuffer(); return; @@ -167,23 +167,23 @@ void OpdsBookBrowserActivity::render() const { if (state == BrowserState::LOADING) { renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2, statusMessage.c_str()); - const auto labels = mappedInput.mapLabels("« Back", "", "", ""); + const auto labels = mappedInput.mapLabels("« Retour", "", "", ""); renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); renderer.displayBuffer(); return; } if (state == BrowserState::ERROR) { - renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 - 20, "Error:"); + renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 - 20, "Erreur:"); renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 + 10, errorMessage.c_str()); - const auto labels = mappedInput.mapLabels("« Back", "Retry", "", ""); + const auto labels = mappedInput.mapLabels("« Retour", "Reéssay.", "", ""); renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); renderer.displayBuffer(); return; } if (state == BrowserState::DOWNLOADING) { - renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 - 40, "Downloading..."); + renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 - 40, "Téléchargement..."); renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 - 10, statusMessage.c_str()); if (downloadTotal > 0) { const int barWidth = pageWidth - 100; @@ -198,15 +198,15 @@ void OpdsBookBrowserActivity::render() const { // Browsing state // Show appropriate button hint based on selected entry type - const char* confirmLabel = "Open"; + const char* confirmLabel = "Ouvrir"; if (!entries.empty() && entries[selectorIndex].type == OpdsEntryType::BOOK) { - confirmLabel = "Download"; + confirmLabel = "Télécharger"; } - const auto labels = mappedInput.mapLabels("« Back", confirmLabel, "", ""); + const auto labels = mappedInput.mapLabels("« Retour", confirmLabel, "", ""); renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); if (entries.empty()) { - renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2, "No entries found"); + renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2, "Aucune entrée trouvée"); renderer.displayBuffer(); return; } @@ -241,18 +241,18 @@ void OpdsBookBrowserActivity::fetchFeed(const std::string& path) { const char* serverUrl = SETTINGS.opdsServerUrl; if (strlen(serverUrl) == 0) { state = BrowserState::ERROR; - errorMessage = "No server URL configured"; + errorMessage = "Aucun URL serveur configuré"; updateRequired = true; return; } std::string url = UrlUtils::buildUrl(serverUrl, path); - Serial.printf("[%lu] [OPDS] Fetching: %s\n", millis(), url.c_str()); + Serial.printf("[%lu] [OPDS] Récupération: %s\n", millis(), url.c_str()); std::string content; if (!HttpDownloader::fetchUrl(url, content)) { state = BrowserState::ERROR; - errorMessage = "Failed to fetch feed"; + errorMessage = "Récupération du flux échouée"; updateRequired = true; return; } @@ -260,7 +260,7 @@ void OpdsBookBrowserActivity::fetchFeed(const std::string& path) { OpdsParser parser; if (!parser.parse(content.c_str(), content.size())) { state = BrowserState::ERROR; - errorMessage = "Failed to parse feed"; + errorMessage = "Analyse du flux échouée"; updateRequired = true; return; } @@ -270,7 +270,7 @@ void OpdsBookBrowserActivity::fetchFeed(const std::string& path) { if (entries.empty()) { state = BrowserState::ERROR; - errorMessage = "No entries found"; + errorMessage = "Aucune entrée trouvée"; updateRequired = true; return; } @@ -285,7 +285,7 @@ void OpdsBookBrowserActivity::navigateToEntry(const OpdsEntry& entry) { currentPath = entry.href; state = BrowserState::LOADING; - statusMessage = "Loading..."; + statusMessage = "Chargement..."; entries.clear(); selectorIndex = 0; updateRequired = true; @@ -303,7 +303,7 @@ void OpdsBookBrowserActivity::navigateBack() { navigationHistory.pop_back(); state = BrowserState::LOADING; - statusMessage = "Loading..."; + statusMessage = "Chargement..."; entries.clear(); selectorIndex = 0; updateRequired = true; @@ -329,7 +329,7 @@ void OpdsBookBrowserActivity::downloadBook(const OpdsEntry& book) { } std::string filename = "/" + StringUtils::sanitizeFilename(baseName) + ".epub"; - Serial.printf("[%lu] [OPDS] Downloading: %s -> %s\n", millis(), downloadUrl.c_str(), filename.c_str()); + Serial.printf("[%lu] [OPDS] Téléchargement: %s -> %s\n", millis(), downloadUrl.c_str(), filename.c_str()); const auto result = HttpDownloader::downloadToFile(downloadUrl, filename, [this](const size_t downloaded, const size_t total) { @@ -339,12 +339,12 @@ void OpdsBookBrowserActivity::downloadBook(const OpdsEntry& book) { }); if (result == HttpDownloader::OK) { - Serial.printf("[%lu] [OPDS] Download complete: %s\n", millis(), filename.c_str()); + Serial.printf("[%lu] [OPDS] Téléchargement terminé: %s\n", millis(), filename.c_str()); state = BrowserState::BROWSING; updateRequired = true; } else { state = BrowserState::ERROR; - errorMessage = "Download failed"; + errorMessage = "Téléchargement échoué"; updateRequired = true; } } @@ -353,21 +353,21 @@ void OpdsBookBrowserActivity::checkAndConnectWifi() { // Already connected? if (WiFi.status() == WL_CONNECTED) { state = BrowserState::LOADING; - statusMessage = "Loading..."; + statusMessage = "Chargement..."; updateRequired = true; fetchFeed(currentPath); return; } // Try to connect using saved credentials - statusMessage = "Connecting to WiFi..."; + statusMessage = "Connexion au WiFi..."; updateRequired = true; WIFI_STORE.loadFromFile(); const auto& credentials = WIFI_STORE.getCredentials(); if (credentials.empty()) { state = BrowserState::ERROR; - errorMessage = "No WiFi credentials saved"; + errorMessage = "Aucun identifiants sauvegardés"; updateRequired = true; return; } @@ -385,14 +385,14 @@ void OpdsBookBrowserActivity::checkAndConnectWifi() { } if (WiFi.status() == WL_CONNECTED) { - Serial.printf("[%lu] [OPDS] WiFi connected: %s\n", millis(), WiFi.localIP().toString().c_str()); + Serial.printf("[%lu] [OPDS] WiFi connecté: %s\n", millis(), WiFi.localIP().toString().c_str()); state = BrowserState::LOADING; - statusMessage = "Loading..."; + statusMessage = "Chargement..."; updateRequired = true; fetchFeed(currentPath); } else { state = BrowserState::ERROR; - errorMessage = "WiFi connection failed"; + errorMessage = "Connexion WiFi échouée"; updateRequired = true; } } diff --git a/src/activities/home/HomeActivity.cpp b/src/activities/home/HomeActivity.cpp index f34283d4..ece42938 100644 --- a/src/activities/home/HomeActivity.cpp +++ b/src/activities/home/HomeActivity.cpp @@ -277,21 +277,21 @@ void HomeActivity::render() const { } renderer.drawCenteredText(UI_10_FONT_ID, bookY + bookHeight - renderer.getLineHeight(UI_10_FONT_ID) * 3 / 2, - "Continue Reading", !bookSelected); + "Continuer la lecture", !bookSelected); } else { // No book to continue reading const int y = bookY + (bookHeight - renderer.getLineHeight(UI_12_FONT_ID) - renderer.getLineHeight(UI_10_FONT_ID)) / 2; - renderer.drawCenteredText(UI_12_FONT_ID, y, "No open book"); - renderer.drawCenteredText(UI_10_FONT_ID, y + renderer.getLineHeight(UI_12_FONT_ID), "Start reading below"); + renderer.drawCenteredText(UI_12_FONT_ID, y, "Aucun livre ouvert"); + renderer.drawCenteredText(UI_10_FONT_ID, y + renderer.getLineHeight(UI_12_FONT_ID), "Commencer la lecture au-dessous"); } // --- Bottom menu tiles --- // Build menu items dynamically - std::vector menuItems = {"Browse Files", "File Transfer", "Settings"}; + std::vector menuItems = {"Parcourir les fichiers", "Transfert de fichiers", "Paramètres"}; if (hasOpdsUrl) { // Insert Calibre Library after Browse Files - menuItems.insert(menuItems.begin() + 1, "Calibre Library"); + menuItems.insert(menuItems.begin() + 1, "Blibliothèque Calibre"); } const int menuTileWidth = pageWidth - 2 * margin; @@ -329,7 +329,7 @@ void HomeActivity::render() const { renderer.drawText(UI_10_FONT_ID, textX, textY, label, !selected); } - const auto labels = mappedInput.mapLabels("", "Confirm", "Up", "Down"); + const auto labels = mappedInput.mapLabels("", "Confirmer", "Haut", "Bas"); renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); const auto batteryX = pageWidth - 25 - renderer.getTextWidth(SMALL_FONT_ID, "100 %"); diff --git a/src/activities/network/CalibreWirelessActivity.cpp b/src/activities/network/CalibreWirelessActivity.cpp index 0ad9094a..3b3bb9d3 100644 --- a/src/activities/network/CalibreWirelessActivity.cpp +++ b/src/activities/network/CalibreWirelessActivity.cpp @@ -34,7 +34,7 @@ void CalibreWirelessActivity::onEnter() { stateMutex = xSemaphoreCreateMutex(); state = WirelessState::DISCOVERING; - statusMessage = "Discovering Calibre..."; + statusMessage = "Recherche de Calibre..."; errorMessage.clear(); calibreHostname.clear(); calibreHost.clear(); diff --git a/src/activities/network/CrossPointWebServerActivity.cpp b/src/activities/network/CrossPointWebServerActivity.cpp index dde05614..9ad5b2d2 100644 --- a/src/activities/network/CrossPointWebServerActivity.cpp +++ b/src/activities/network/CrossPointWebServerActivity.cpp @@ -15,7 +15,7 @@ namespace { // AP Mode configuration -constexpr const char* AP_SSID = "CrossPoint-Reader"; +constexpr const char* AP_SSID = "CrossPoint-Liseuse"; constexpr const char* AP_PASSWORD = nullptr; // Open network for ease of use constexpr const char* AP_HOSTNAME = "crosspoint"; constexpr uint8_t AP_CHANNEL = 1; @@ -34,7 +34,7 @@ void CrossPointWebServerActivity::taskTrampoline(void* param) { void CrossPointWebServerActivity::onEnter() { ActivityWithSubactivity::onEnter(); - Serial.printf("[%lu] [WEBACT] [MEM] Free heap at onEnter: %d bytes\n", millis(), ESP.getFreeHeap()); + Serial.printf("[%lu] [WEBACT] [MEM] Pile libre à onEnter: %d octets\n", millis(), ESP.getFreeHeap()); renderingMutex = xSemaphoreCreateMutex(); @@ -55,7 +55,7 @@ void CrossPointWebServerActivity::onEnter() { ); // Launch network mode selection subactivity - Serial.printf("[%lu] [WEBACT] Launching NetworkModeSelectionActivity...\n", millis()); + Serial.printf("[%lu] [WEBACT] Lancement de NetworkModeSelectionActivity...\n", millis()); enterNewActivity(new NetworkModeSelectionActivity( renderer, mappedInput, [this](const NetworkMode mode) { onNetworkModeSelected(mode); }, [this]() { onGoBack(); } // Cancel goes back to home @@ -65,7 +65,7 @@ void CrossPointWebServerActivity::onEnter() { void CrossPointWebServerActivity::onExit() { ActivityWithSubactivity::onExit(); - Serial.printf("[%lu] [WEBACT] [MEM] Free heap at onExit start: %d bytes\n", millis(), ESP.getFreeHeap()); + Serial.printf("[%lu] [WEBACT] [MEM] Pile libre au début de onExit: %d bytes\n", millis(), ESP.getFreeHeap()); state = WebServerActivityState::SHUTTING_DOWN; @@ -77,56 +77,56 @@ void CrossPointWebServerActivity::onExit() { // Stop DNS server if running (AP mode) if (dnsServer) { - Serial.printf("[%lu] [WEBACT] Stopping DNS server...\n", millis()); + Serial.printf("[%lu] [WEBACT] Arrêt du serveur DNS...\n", millis()); dnsServer->stop(); delete dnsServer; dnsServer = nullptr; } // CRITICAL: Wait for LWIP stack to flush any pending packets - Serial.printf("[%lu] [WEBACT] Waiting 500ms for network stack to flush pending packets...\n", millis()); + Serial.printf("[%lu] [WEBACT] Attente de 500ms de pile réseau pour vider les paquets en attente...\n", millis()); delay(500); // Disconnect WiFi gracefully if (isApMode) { - Serial.printf("[%lu] [WEBACT] Stopping WiFi AP...\n", millis()); + Serial.printf("[%lu] [WEBACT] Arrêt du WiFi AP...\n", millis()); WiFi.softAPdisconnect(true); } else { - Serial.printf("[%lu] [WEBACT] Disconnecting WiFi (graceful)...\n", millis()); + Serial.printf("[%lu] [WEBACT] Déconnexion du WiFi (gracieuse)...\n", millis()); WiFi.disconnect(false); // false = don't erase credentials, send disconnect frame } delay(100); // Allow disconnect frame to be sent - Serial.printf("[%lu] [WEBACT] Setting WiFi mode OFF...\n", millis()); + Serial.printf("[%lu] [WEBACT] Désactivation du WiFi...\n", millis()); WiFi.mode(WIFI_OFF); delay(100); // Allow WiFi hardware to fully power down - Serial.printf("[%lu] [WEBACT] [MEM] Free heap after WiFi disconnect: %d bytes\n", millis(), ESP.getFreeHeap()); + Serial.printf("[%lu] [WEBACT] [MEM] Pile libre après déconnexion du WiFi: %d octets\n", millis(), ESP.getFreeHeap()); // Acquire mutex before deleting task - Serial.printf("[%lu] [WEBACT] Acquiring rendering mutex before task deletion...\n", millis()); + Serial.printf("[%lu] [WEBACT] Acquisition du mutex de rendu avant la suppression de la tâche...\n", millis()); xSemaphoreTake(renderingMutex, portMAX_DELAY); // Delete the display task - Serial.printf("[%lu] [WEBACT] Deleting display task...\n", millis()); + Serial.printf("[%lu] [WEBACT] Suppression de la tâche d'affichage...\n", millis()); if (displayTaskHandle) { vTaskDelete(displayTaskHandle); displayTaskHandle = nullptr; - Serial.printf("[%lu] [WEBACT] Display task deleted\n", millis()); + Serial.printf("[%lu] [WEBACT] Tâche d'affichage supprimée\n", millis()); } // Delete the mutex - Serial.printf("[%lu] [WEBACT] Deleting mutex...\n", millis()); + Serial.printf("[%lu] [WEBACT] Suppression du mutex...\n", millis()); vSemaphoreDelete(renderingMutex); renderingMutex = nullptr; - Serial.printf("[%lu] [WEBACT] Mutex deleted\n", millis()); + Serial.printf("[%lu] [WEBACT] Mutex supprimé\n", millis()); - Serial.printf("[%lu] [WEBACT] [MEM] Free heap at onExit end: %d bytes\n", millis(), ESP.getFreeHeap()); + Serial.printf("[%lu] [WEBACT] [MEM] Pile libre à la fin de onExit: %d octets\n", millis(), ESP.getFreeHeap()); } void CrossPointWebServerActivity::onNetworkModeSelected(const NetworkMode mode) { - Serial.printf("[%lu] [WEBACT] Network mode selected: %s\n", millis(), - mode == NetworkMode::JOIN_NETWORK ? "Join Network" : "Create Hotspot"); + Serial.printf("[%lu] [WEBACT] Mode de réseau selectionné: %s\n", millis(), + mode == NetworkMode::JOIN_NETWORK ? "Réjoindre le réseau" : "Créer un point d'accès"); networkMode = mode; isApMode = (mode == NetworkMode::CREATE_HOTSPOT); @@ -136,11 +136,11 @@ void CrossPointWebServerActivity::onNetworkModeSelected(const NetworkMode mode) if (mode == NetworkMode::JOIN_NETWORK) { // STA mode - launch WiFi selection - Serial.printf("[%lu] [WEBACT] Turning on WiFi (STA mode)...\n", millis()); + Serial.printf("[%lu] [WEBACT] Lancement du WiFi (Mode STA)...\n", millis()); WiFi.mode(WIFI_STA); state = WebServerActivityState::WIFI_SELECTION; - Serial.printf("[%lu] [WEBACT] Launching WifiSelectionActivity...\n", millis()); + Serial.printf("[%lu] [WEBACT] Lancement de WifiSelectionActivity...\n", millis()); enterNewActivity(new WifiSelectionActivity(renderer, mappedInput, [this](const bool connected) { onWifiSelectionComplete(connected); })); } else { @@ -152,7 +152,7 @@ void CrossPointWebServerActivity::onNetworkModeSelected(const NetworkMode mode) } void CrossPointWebServerActivity::onWifiSelectionComplete(const bool connected) { - Serial.printf("[%lu] [WEBACT] WifiSelectionActivity completed, connected=%d\n", millis(), connected); + Serial.printf("[%lu] [WEBACT] WifiSelectionActivity terminé, connecté=%d\n", millis(), connected); if (connected) { // Get connection info before exiting subactivity @@ -164,7 +164,7 @@ void CrossPointWebServerActivity::onWifiSelectionComplete(const bool connected) // Start mDNS for hostname resolution if (MDNS.begin(AP_HOSTNAME)) { - Serial.printf("[%lu] [WEBACT] mDNS started: http://%s.local/\n", millis(), AP_HOSTNAME); + Serial.printf("[%lu] [WEBACT] mDNS lancé: http://%s.local/\n", millis(), AP_HOSTNAME); } // Start the web server @@ -180,8 +180,8 @@ void CrossPointWebServerActivity::onWifiSelectionComplete(const bool connected) } void CrossPointWebServerActivity::startAccessPoint() { - Serial.printf("[%lu] [WEBACT] Starting Access Point mode...\n", millis()); - Serial.printf("[%lu] [WEBACT] [MEM] Free heap before AP start: %d bytes\n", millis(), ESP.getFreeHeap()); + Serial.printf("[%lu] [WEBACT] Lancement du mode Access Point...\n", millis()); + Serial.printf("[%lu] [WEBACT] [MEM] Pile libre avant le début de AP: %d octets\n", millis(), ESP.getFreeHeap()); // Configure and start the AP WiFi.mode(WIFI_AP); @@ -197,7 +197,7 @@ void CrossPointWebServerActivity::startAccessPoint() { } if (!apStarted) { - Serial.printf("[%lu] [WEBACT] ERROR: Failed to start Access Point!\n", millis()); + Serial.printf("[%lu] [WEBACT] ERROR: Lancement de Access Point échoué!\n", millis()); onGoBack(); return; } @@ -211,15 +211,15 @@ void CrossPointWebServerActivity::startAccessPoint() { connectedIP = ipStr; connectedSSID = AP_SSID; - Serial.printf("[%lu] [WEBACT] Access Point started!\n", millis()); + Serial.printf("[%lu] [WEBACT] Access Point lancé!\n", millis()); Serial.printf("[%lu] [WEBACT] SSID: %s\n", millis(), AP_SSID); Serial.printf("[%lu] [WEBACT] IP: %s\n", millis(), connectedIP.c_str()); // Start mDNS for hostname resolution if (MDNS.begin(AP_HOSTNAME)) { - Serial.printf("[%lu] [WEBACT] mDNS started: http://%s.local/\n", millis(), AP_HOSTNAME); + Serial.printf("[%lu] [WEBACT] mDNS lancé: http://%s.local/\n", millis(), AP_HOSTNAME); } else { - Serial.printf("[%lu] [WEBACT] WARNING: mDNS failed to start\n", millis()); + Serial.printf("[%lu] [WEBACT] ATTENTION: lancement de mDNS échoué\n", millis()); } // Start DNS server for captive portal behavior @@ -227,16 +227,16 @@ void CrossPointWebServerActivity::startAccessPoint() { dnsServer = new DNSServer(); dnsServer->setErrorReplyCode(DNSReplyCode::NoError); dnsServer->start(DNS_PORT, "*", apIP); - Serial.printf("[%lu] [WEBACT] DNS server started for captive portal\n", millis()); + Serial.printf("[%lu] [WEBACT] Serveur DNS lancé pour portail captif\n", millis()); - Serial.printf("[%lu] [WEBACT] [MEM] Free heap after AP start: %d bytes\n", millis(), ESP.getFreeHeap()); + Serial.printf("[%lu] [WEBACT] [MEM] Pile libre après lancement de AP: %d octets\n", millis(), ESP.getFreeHeap()); // Start the web server startWebServer(); } void CrossPointWebServerActivity::startWebServer() { - Serial.printf("[%lu] [WEBACT] Starting web server...\n", millis()); + Serial.printf("[%lu] [WEBACT] Lancement du server web...\n", millis()); // Create the web server instance webServer.reset(new CrossPointWebServer()); @@ -244,16 +244,16 @@ void CrossPointWebServerActivity::startWebServer() { if (webServer->isRunning()) { state = WebServerActivityState::SERVER_RUNNING; - Serial.printf("[%lu] [WEBACT] Web server started successfully\n", millis()); + Serial.printf("[%lu] [WEBACT] Serveur web lancé avec succès!\n", millis()); // Force an immediate render since we're transitioning from a subactivity // that had its own rendering task. We need to make sure our display is shown. xSemaphoreTake(renderingMutex, portMAX_DELAY); render(); xSemaphoreGive(renderingMutex); - Serial.printf("[%lu] [WEBACT] Rendered File Transfer screen\n", millis()); + Serial.printf("[%lu] [WEBACT] Écran File Transfer rendu\n", millis()); } else { - Serial.printf("[%lu] [WEBACT] ERROR: Failed to start web server!\n", millis()); + Serial.printf("[%lu] [WEBACT] ERREUR: Lancement du serveur web échoué!\n", millis()); webServer.reset(); // Go back on error onGoBack(); @@ -262,9 +262,9 @@ void CrossPointWebServerActivity::startWebServer() { void CrossPointWebServerActivity::stopWebServer() { if (webServer && webServer->isRunning()) { - Serial.printf("[%lu] [WEBACT] Stopping web server...\n", millis()); + Serial.printf("[%lu] [WEBACT] Arrêt du serveur web...\n", millis()); webServer->stop(); - Serial.printf("[%lu] [WEBACT] Web server stopped\n", millis()); + Serial.printf("[%lu] [WEBACT] Serveur web arrêté\n", millis()); } webServer.reset(); } @@ -290,7 +290,7 @@ void CrossPointWebServerActivity::loop() { // Log if there's a significant gap between handleClient calls (>100ms) if (lastHandleClientTime > 0 && timeSinceLastHandleClient > 100) { - Serial.printf("[%lu] [WEBACT] WARNING: %lu ms gap since last handleClient\n", millis(), + Serial.printf("[%lu] [WEBACT] ATTENTION: %lu ms intervalle depuis le dernier handleClient\n", millis(), timeSinceLastHandleClient); } @@ -334,7 +334,7 @@ void CrossPointWebServerActivity::render() const { } else if (state == WebServerActivityState::AP_STARTING) { renderer.clearScreen(); const auto pageHeight = renderer.getScreenHeight(); - renderer.drawCenteredText(UI_12_FONT_ID, pageHeight / 2 - 20, "Starting Hotspot...", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, pageHeight / 2 - 20, "Lancement du point d'accès...", true, EpdFontFamily::BOLD); renderer.displayBuffer(); } } @@ -344,7 +344,7 @@ void drawQRCode(const GfxRenderer& renderer, const int x, const int y, const std // The structure to manage the QR code QRCode qrcode; uint8_t qrcodeBytes[qrcode_getBufferSize(4)]; - Serial.printf("[%lu] [WEBACT] QR Code (%lu): %s\n", millis(), data.length(), data.c_str()); + Serial.printf("[%lu] [WEBACT] Code QR (%lu): %s\n", millis(), data.length(), data.c_str()); qrcode_initText(&qrcode, qrcodeBytes, 4, ECC_LOW, data.c_str()); const uint8_t px = 6; // pixels per module @@ -365,21 +365,21 @@ void CrossPointWebServerActivity::renderServerRunning() const { // Use consistent line spacing constexpr int LINE_SPACING = 28; // Space between lines - renderer.drawCenteredText(UI_12_FONT_ID, 15, "File Transfer", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, 15, "Transfert de fichiers", true, EpdFontFamily::BOLD); if (isApMode) { // AP mode display - center the content block int startY = 55; - renderer.drawCenteredText(UI_10_FONT_ID, startY, "Hotspot Mode", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_10_FONT_ID, startY, "Mode de point d'accès", true, EpdFontFamily::BOLD); - std::string ssidInfo = "Network: " + connectedSSID; + std::string ssidInfo = "Réseau: " + connectedSSID; renderer.drawCenteredText(UI_10_FONT_ID, startY + LINE_SPACING, ssidInfo.c_str()); - renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 2, "Connect your device to this WiFi network"); + renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 2, "Connectez votre appareil à ce réseau"); renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 3, - "or scan QR code with your phone to connect to Wifi."); + "ou scannez le code QR avec votre cellulaire pour connecter au WiFi."); // Show QR code for URL const std::string wifiConfig = std::string("WIFI:S:") + connectedSSID + ";;"; drawQRCode(renderer, (480 - 6 * 33) / 2, startY + LINE_SPACING * 4, wifiConfig); @@ -390,24 +390,24 @@ void CrossPointWebServerActivity::renderServerRunning() const { renderer.drawCenteredText(UI_10_FONT_ID, startY + LINE_SPACING * 3, hostnameUrl.c_str(), true, EpdFontFamily::BOLD); // Show IP address as fallback - std::string ipUrl = "or http://" + connectedIP + "/"; + std::string ipUrl = "ou http://" + connectedIP + "/"; renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 4, ipUrl.c_str()); - renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 5, "Open this URL in your browser"); + renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 5, "Ouvrez cet URL dans votre navigateur"); // Show QR code for URL - renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 6, "or scan QR code with your phone:"); + renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 6, "ou scannez le code QR avec votre cellulaire:"); drawQRCode(renderer, (480 - 6 * 33) / 2, startY + LINE_SPACING * 7, hostnameUrl); } else { // STA mode display (original behavior) const int startY = 65; - std::string ssidInfo = "Network: " + connectedSSID; + std::string ssidInfo = "Réseau: " + connectedSSID; if (ssidInfo.length() > 28) { ssidInfo.replace(25, ssidInfo.length() - 25, "..."); } renderer.drawCenteredText(UI_10_FONT_ID, startY, ssidInfo.c_str()); - std::string ipInfo = "IP Address: " + connectedIP; + std::string ipInfo = "Adresse IP: " + connectedIP; renderer.drawCenteredText(UI_10_FONT_ID, startY + LINE_SPACING, ipInfo.c_str()); // Show web server URL prominently @@ -415,16 +415,16 @@ void CrossPointWebServerActivity::renderServerRunning() const { renderer.drawCenteredText(UI_10_FONT_ID, startY + LINE_SPACING * 2, webInfo.c_str(), true, EpdFontFamily::BOLD); // Also show hostname URL - std::string hostnameUrl = std::string("or http://") + AP_HOSTNAME + ".local/"; + std::string hostnameUrl = std::string("ou http://") + AP_HOSTNAME + ".local/"; renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 3, hostnameUrl.c_str()); - renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 4, "Open this URL in your browser"); + renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 4, "Ouvrez cet URL dans votre navigateur"); // Show QR code for URL drawQRCode(renderer, (480 - 6 * 33) / 2, startY + LINE_SPACING * 6, webInfo); - renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 5, "or scan QR code with your phone:"); + renderer.drawCenteredText(SMALL_FONT_ID, startY + LINE_SPACING * 5, "ou scannez le code QR avec votre cellulaire:"); } - const auto labels = mappedInput.mapLabels("« Exit", "", "", ""); + const auto labels = mappedInput.mapLabels("« Sortie", "", "", ""); renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); } diff --git a/src/activities/network/NetworkModeSelectionActivity.cpp b/src/activities/network/NetworkModeSelectionActivity.cpp index ad05f5b8..23377c66 100644 --- a/src/activities/network/NetworkModeSelectionActivity.cpp +++ b/src/activities/network/NetworkModeSelectionActivity.cpp @@ -7,9 +7,9 @@ namespace { constexpr int MENU_ITEM_COUNT = 2; -const char* MENU_ITEMS[MENU_ITEM_COUNT] = {"Join a Network", "Create Hotspot"}; -const char* MENU_DESCRIPTIONS[MENU_ITEM_COUNT] = {"Connect to an existing WiFi network", - "Create a WiFi network others can join"}; +const char* MENU_ITEMS[MENU_ITEM_COUNT] = {"Réjoindre un réseau", "Créer un point d'accès"}; +const char* MENU_DESCRIPTIONS[MENU_ITEM_COUNT] = {"Connecter à un réseau WiFi existant", + "Créez un réseau Wi-Fi auquel d'autres peuvent se connecter"}; } // namespace void NetworkModeSelectionActivity::taskTrampoline(void* param) { @@ -97,10 +97,10 @@ void NetworkModeSelectionActivity::render() const { const auto pageHeight = renderer.getScreenHeight(); // Draw header - renderer.drawCenteredText(UI_12_FONT_ID, 15, "File Transfer", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, 15, "Transfert de fichiers", true, EpdFontFamily::BOLD); // Draw subtitle - renderer.drawCenteredText(UI_10_FONT_ID, 50, "How would you like to connect?"); + renderer.drawCenteredText(UI_10_FONT_ID, 50, "Comment voulez-vous connecter?"); // Draw menu items centered on screen constexpr int itemHeight = 50; // Height for each menu item (including description) @@ -122,7 +122,7 @@ void NetworkModeSelectionActivity::render() const { } // Draw help text at bottom - const auto labels = mappedInput.mapLabels("« Back", "Select", "", ""); + const auto labels = mappedInput.mapLabels("« Retour", "Select.", "", ""); renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); renderer.displayBuffer(); diff --git a/src/activities/network/WifiSelectionActivity.cpp b/src/activities/network/WifiSelectionActivity.cpp index a8653f43..22e81f2f 100644 --- a/src/activities/network/WifiSelectionActivity.cpp +++ b/src/activities/network/WifiSelectionActivity.cpp @@ -54,36 +54,36 @@ void WifiSelectionActivity::onEnter() { void WifiSelectionActivity::onExit() { Activity::onExit(); - Serial.printf("[%lu] [WIFI] [MEM] Free heap at onExit start: %d bytes\n", millis(), ESP.getFreeHeap()); + Serial.printf("[%lu] [WIFI] [MEM] Pile libre au début de onExit: %d octets\n", millis(), ESP.getFreeHeap()); // Stop any ongoing WiFi scan - Serial.printf("[%lu] [WIFI] Deleting WiFi scan...\n", millis()); + Serial.printf("[%lu] [WIFI] Suppression du scan WiFi...\n", millis()); WiFi.scanDelete(); - Serial.printf("[%lu] [WIFI] [MEM] Free heap after scanDelete: %d bytes\n", millis(), ESP.getFreeHeap()); + Serial.printf("[%lu] [WIFI] [MEM] Pile libre après scanDelete: %d octets\n", millis(), ESP.getFreeHeap()); // Note: We do NOT disconnect WiFi here - the parent activity (CrossPointWebServerActivity) // manages WiFi connection state. We just clean up the scan and task. // Acquire mutex before deleting task to ensure task isn't using it // This prevents hangs/crashes if the task holds the mutex when deleted - Serial.printf("[%lu] [WIFI] Acquiring rendering mutex before task deletion...\n", millis()); + Serial.printf("[%lu] [WIFI] Acquisition du mutex de rendu avant la suppression de la tâche...\n", millis()); xSemaphoreTake(renderingMutex, portMAX_DELAY); // Delete the display task (we now hold the mutex, so task is blocked if it needs it) - Serial.printf("[%lu] [WIFI] Deleting display task...\n", millis()); + Serial.printf("[%lu] [WIFI] Suppression de la tâche d'affichage...\n", millis()); if (displayTaskHandle) { vTaskDelete(displayTaskHandle); displayTaskHandle = nullptr; - Serial.printf("[%lu] [WIFI] Display task deleted\n", millis()); + Serial.printf("[%lu] [WIFI] Tâche d'affichage supprimée\n", millis()); } // Now safe to delete the mutex since we own it - Serial.printf("[%lu] [WIFI] Deleting mutex...\n", millis()); + Serial.printf("[%lu] [WIFI] Suppression de mutex...\n", millis()); vSemaphoreDelete(renderingMutex); renderingMutex = nullptr; - Serial.printf("[%lu] [WIFI] Mutex deleted\n", millis()); + Serial.printf("[%lu] [WIFI] Mutex supprimé\n", millis()); - Serial.printf("[%lu] [WIFI] [MEM] Free heap at onExit end: %d bytes\n", millis(), ESP.getFreeHeap()); + Serial.printf("[%lu] [WIFI] [MEM] Pile libre à la fin de onExit: %d octets\n", millis(), ESP.getFreeHeap()); } void WifiSelectionActivity::startWifiScan() { @@ -179,7 +179,7 @@ void WifiSelectionActivity::selectNetwork(const int index) { // Use saved password - connect directly enteredPassword = savedCred->password; usedSavedPassword = true; - Serial.printf("[%lu] [WiFi] Using saved password for %s, length: %zu\n", millis(), selectedSSID.c_str(), + Serial.printf("[%lu] [WiFi] Utilisation du mot de passe sauvegardé pour %s, longueur: %zu\n", millis(), selectedSSID.c_str(), enteredPassword.size()); attemptConnection(); return; @@ -191,7 +191,7 @@ void WifiSelectionActivity::selectNetwork(const int index) { // Don't allow screen updates while changing activity xSemaphoreTake(renderingMutex, portMAX_DELAY); enterNewActivity(new KeyboardEntryActivity( - renderer, mappedInput, "Enter WiFi Password", + renderer, mappedInput, "Entrez le mot de passe du WiFi", "", // No initial text 50, // Y position 64, // Max password length @@ -251,16 +251,16 @@ void WifiSelectionActivity::checkConnectionStatus() { updateRequired = true; } else { // Using saved password or open network - complete immediately - Serial.printf("[%lu] [WIFI] Connected with saved/open credentials, completing immediately\n", millis()); + Serial.printf("[%lu] [WIFI] Connecté avec les identifiants sauvegardés/ouverts, complétion immédiate\n", millis()); onComplete(true); } return; } if (status == WL_CONNECT_FAILED || status == WL_NO_SSID_AVAIL) { - connectionError = "Connection failed"; + connectionError = "Connexion échouée"; if (status == WL_NO_SSID_AVAIL) { - connectionError = "Network not found"; + connectionError = "Réseau introuvable"; } state = WifiSelectionState::CONNECTION_FAILED; updateRequired = true; @@ -505,14 +505,14 @@ void WifiSelectionActivity::renderNetworkList() const { const auto pageHeight = renderer.getScreenHeight(); // Draw header - renderer.drawCenteredText(UI_12_FONT_ID, 15, "WiFi Networks", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, 15, "Réseaux WiFi", true, EpdFontFamily::BOLD); if (networks.empty()) { // No networks found or scan failed const auto height = renderer.getLineHeight(UI_10_FONT_ID); const auto top = (pageHeight - height) / 2; - renderer.drawCenteredText(UI_10_FONT_ID, top, "No networks found"); - renderer.drawCenteredText(SMALL_FONT_ID, top + height + 10, "Press OK to scan again"); + renderer.drawCenteredText(UI_10_FONT_ID, top, "Aucun réseau trouvé"); + renderer.drawCenteredText(SMALL_FONT_ID, top + height + 10, "Appuyez OK pour scanner à nouveau"); } else { // Calculate how many networks we can display constexpr int startY = 60; @@ -568,13 +568,13 @@ void WifiSelectionActivity::renderNetworkList() const { // Show network count char countStr[32]; - snprintf(countStr, sizeof(countStr), "%zu networks found", networks.size()); + snprintf(countStr, sizeof(countStr), "%zu réseaux trouvés", networks.size()); renderer.drawText(SMALL_FONT_ID, 20, pageHeight - 90, countStr); } // Draw help text - renderer.drawText(SMALL_FONT_ID, 20, pageHeight - 75, "* = Encrypted | + = Saved"); - const auto labels = mappedInput.mapLabels("« Back", "Connect", "", ""); + renderer.drawText(SMALL_FONT_ID, 20, pageHeight - 75, "* = Crypté | + = Sauvegardé"); + const auto labels = mappedInput.mapLabels("« Retour", "Connecter", "", ""); renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); } @@ -584,9 +584,9 @@ void WifiSelectionActivity::renderConnecting() const { const auto top = (pageHeight - height) / 2; if (state == WifiSelectionState::SCANNING) { - renderer.drawCenteredText(UI_10_FONT_ID, top, "Scanning..."); + renderer.drawCenteredText(UI_10_FONT_ID, top, "Recherche..."); } else { - renderer.drawCenteredText(UI_12_FONT_ID, top - 40, "Connecting...", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, top - 40, "Connexion...", true, EpdFontFamily::BOLD); std::string ssidInfo = "to " + selectedSSID; if (ssidInfo.length() > 25) { @@ -601,18 +601,18 @@ void WifiSelectionActivity::renderConnected() const { const auto height = renderer.getLineHeight(UI_10_FONT_ID); const auto top = (pageHeight - height * 4) / 2; - renderer.drawCenteredText(UI_12_FONT_ID, top - 30, "Connected!", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, top - 30, "Connecté!", true, EpdFontFamily::BOLD); - std::string ssidInfo = "Network: " + selectedSSID; + std::string ssidInfo = "Réseau: " + selectedSSID; if (ssidInfo.length() > 28) { ssidInfo.replace(25, ssidInfo.length() - 25, "..."); } renderer.drawCenteredText(UI_10_FONT_ID, top + 10, ssidInfo.c_str()); - const std::string ipInfo = "IP Address: " + connectedIP; + const std::string ipInfo = "Adresse IP: " + connectedIP; renderer.drawCenteredText(UI_10_FONT_ID, top + 40, ipInfo.c_str()); - renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, "Press any button to continue"); + renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, "Appuyez sur n'importe quel bouton pour continuer"); } void WifiSelectionActivity::renderSavePrompt() const { @@ -621,15 +621,15 @@ void WifiSelectionActivity::renderSavePrompt() const { const auto height = renderer.getLineHeight(UI_10_FONT_ID); const auto top = (pageHeight - height * 3) / 2; - renderer.drawCenteredText(UI_12_FONT_ID, top - 40, "Connected!", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, top - 40, "Connecté!", true, EpdFontFamily::BOLD); - std::string ssidInfo = "Network: " + selectedSSID; + std::string ssidInfo = "Réseaux: " + selectedSSID; if (ssidInfo.length() > 28) { ssidInfo.replace(25, ssidInfo.length() - 25, "..."); } renderer.drawCenteredText(UI_10_FONT_ID, top, ssidInfo.c_str()); - renderer.drawCenteredText(UI_10_FONT_ID, top + 40, "Save password for next time?"); + renderer.drawCenteredText(UI_10_FONT_ID, top + 40, "Enregistrer le mot de passe pour la prochaine fois?"); // Draw Yes/No buttons const int buttonY = top + 80; @@ -640,19 +640,19 @@ void WifiSelectionActivity::renderSavePrompt() const { // Draw "Yes" button if (savePromptSelection == 0) { - renderer.drawText(UI_10_FONT_ID, startX, buttonY, "[Yes]"); + renderer.drawText(UI_10_FONT_ID, startX, buttonY, "[Oui]"); } else { - renderer.drawText(UI_10_FONT_ID, startX + 4, buttonY, "Yes"); + renderer.drawText(UI_10_FONT_ID, startX + 4, buttonY, "Oui"); } // Draw "No" button if (savePromptSelection == 1) { - renderer.drawText(UI_10_FONT_ID, startX + buttonWidth + buttonSpacing, buttonY, "[No]"); + renderer.drawText(UI_10_FONT_ID, startX + buttonWidth + buttonSpacing, buttonY, "[Non]"); } else { - renderer.drawText(UI_10_FONT_ID, startX + buttonWidth + buttonSpacing + 4, buttonY, "No"); + renderer.drawText(UI_10_FONT_ID, startX + buttonWidth + buttonSpacing + 4, buttonY, "Non"); } - renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, "LEFT/RIGHT: Select | OK: Confirm"); + renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, "GAUCHE/DROITE: Selectionner | OK: Confirmer"); } void WifiSelectionActivity::renderConnectionFailed() const { @@ -660,9 +660,9 @@ void WifiSelectionActivity::renderConnectionFailed() const { const auto height = renderer.getLineHeight(UI_10_FONT_ID); const auto top = (pageHeight - height * 2) / 2; - renderer.drawCenteredText(UI_12_FONT_ID, top - 20, "Connection Failed", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, top - 20, "Connexion échouée", true, EpdFontFamily::BOLD); renderer.drawCenteredText(UI_10_FONT_ID, top + 20, connectionError.c_str()); - renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, "Press any button to continue"); + renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, "Appuyez sur n'importe quel bouton pour continuer"); } void WifiSelectionActivity::renderForgetPrompt() const { @@ -671,15 +671,15 @@ void WifiSelectionActivity::renderForgetPrompt() const { const auto height = renderer.getLineHeight(UI_10_FONT_ID); const auto top = (pageHeight - height * 3) / 2; - renderer.drawCenteredText(UI_12_FONT_ID, top - 40, "Forget Network?", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, top - 40, "Oublier le réseau?", true, EpdFontFamily::BOLD); - std::string ssidInfo = "Network: " + selectedSSID; + std::string ssidInfo = "Réseau: " + selectedSSID; if (ssidInfo.length() > 28) { ssidInfo.replace(25, ssidInfo.length() - 25, "..."); } renderer.drawCenteredText(UI_10_FONT_ID, top, ssidInfo.c_str()); - renderer.drawCenteredText(UI_10_FONT_ID, top + 40, "Remove saved password?"); + renderer.drawCenteredText(UI_10_FONT_ID, top + 40, "Supprimer le mot de passe sauvegardé?"); // Draw Yes/No buttons const int buttonY = top + 80; @@ -690,17 +690,17 @@ void WifiSelectionActivity::renderForgetPrompt() const { // Draw "Yes" button if (forgetPromptSelection == 0) { - renderer.drawText(UI_10_FONT_ID, startX, buttonY, "[Yes]"); + renderer.drawText(UI_10_FONT_ID, startX, buttonY, "[Oui]"); } else { - renderer.drawText(UI_10_FONT_ID, startX + 4, buttonY, "Yes"); + renderer.drawText(UI_10_FONT_ID, startX + 4, buttonY, "Oui"); } // Draw "No" button if (forgetPromptSelection == 1) { - renderer.drawText(UI_10_FONT_ID, startX + buttonWidth + buttonSpacing, buttonY, "[No]"); + renderer.drawText(UI_10_FONT_ID, startX + buttonWidth + buttonSpacing, buttonY, "[Non]"); } else { - renderer.drawText(UI_10_FONT_ID, startX + buttonWidth + buttonSpacing + 4, buttonY, "No"); + renderer.drawText(UI_10_FONT_ID, startX + buttonWidth + buttonSpacing + 4, buttonY, "Non"); } - renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, "LEFT/RIGHT: Select | OK: Confirm"); + renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, "GAUCHE/DROITE: Selectionner | OK: Confirmer"); } diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index ac0ffd51..679089c5 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -59,7 +59,7 @@ void EpubReaderActivity::onEnter() { if (f.read(data, 4) == 4) { currentSpineIndex = data[0] + (data[1] << 8); nextPageNumber = data[2] + (data[3] << 8); - Serial.printf("[%lu] [ERS] Loaded cache: %d, %d\n", millis(), currentSpineIndex, nextPageNumber); + Serial.printf("[%lu] [ERS] Cache chargée: %d, %d\n", millis(), currentSpineIndex, nextPageNumber); } f.close(); } @@ -69,7 +69,7 @@ void EpubReaderActivity::onEnter() { int textSpineIndex = epub->getSpineIndexForTextReference(); if (textSpineIndex != 0) { currentSpineIndex = textSpineIndex; - Serial.printf("[%lu] [ERS] Opened for first time, navigating to text reference at index %d\n", millis(), + Serial.printf("[%lu] [ERS] Ouvert pour la première fois, navigation à la référence textuel à l'indice %d\n", millis(), textSpineIndex); } } @@ -242,7 +242,7 @@ void EpubReaderActivity::renderScreen() { // Show end of book screen if (currentSpineIndex == epub->getSpineItemsCount()) { renderer.clearScreen(); - renderer.drawCenteredText(UI_12_FONT_ID, 300, "End of book", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, 300, "Fin du livre", true, EpdFontFamily::BOLD); renderer.displayBuffer(); return; } @@ -258,7 +258,7 @@ void EpubReaderActivity::renderScreen() { if (!section) { const auto filepath = epub->getSpineItem(currentSpineIndex).href; - Serial.printf("[%lu] [ERS] Loading file: %s, index: %d\n", millis(), filepath.c_str(), currentSpineIndex); + Serial.printf("[%lu] [ERS] Chargement du fichier: %s, indice: %d\n", millis(), filepath.c_str(), currentSpineIndex); section = std::unique_ptr
(new Section(epub, currentSpineIndex, renderer)); const uint16_t viewportWidth = renderer.getScreenWidth() - orientedMarginLeft - orientedMarginRight; @@ -267,13 +267,13 @@ void EpubReaderActivity::renderScreen() { if (!section->loadSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(), SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth, viewportHeight)) { - Serial.printf("[%lu] [ERS] Cache not found, building...\n", millis()); + Serial.printf("[%lu] [ERS] Aucune cache trouvée, création...\n", millis()); // Progress bar dimensions constexpr int barWidth = 200; constexpr int barHeight = 10; constexpr int boxMargin = 20; - const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, "Indexing..."); + const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, "Indexage..."); const int boxWidthWithBar = (barWidth > textWidth ? barWidth : textWidth) + boxMargin * 2; const int boxWidthNoBar = textWidth + boxMargin * 2; const int boxHeightWithBar = renderer.getLineHeight(UI_12_FONT_ID) + barHeight + boxMargin * 3; @@ -287,7 +287,7 @@ void EpubReaderActivity::renderScreen() { // Always show "Indexing..." text first { renderer.fillRect(boxXNoBar, boxY, boxWidthNoBar, boxHeightNoBar, false); - renderer.drawText(UI_12_FONT_ID, boxXNoBar + boxMargin, boxY + boxMargin, "Indexing..."); + renderer.drawText(UI_12_FONT_ID, boxXNoBar + boxMargin, boxY + boxMargin, "Indexage..."); renderer.drawRect(boxXNoBar + 5, boxY + 5, boxWidthNoBar - 10, boxHeightNoBar - 10); renderer.displayBuffer(); pagesUntilFullRefresh = 0; @@ -296,7 +296,7 @@ void EpubReaderActivity::renderScreen() { // Setup callback - only called for chapters >= 50KB, redraws with progress bar auto progressSetup = [this, boxXWithBar, boxWidthWithBar, boxHeightWithBar, barX, barY] { renderer.fillRect(boxXWithBar, boxY, boxWidthWithBar, boxHeightWithBar, false); - renderer.drawText(UI_12_FONT_ID, boxXWithBar + boxMargin, boxY + boxMargin, "Indexing..."); + renderer.drawText(UI_12_FONT_ID, boxXWithBar + boxMargin, boxY + boxMargin, "Indexage..."); renderer.drawRect(boxXWithBar + 5, boxY + 5, boxWidthWithBar - 10, boxHeightWithBar - 10); renderer.drawRect(barX, barY, barWidth, barHeight); renderer.displayBuffer(); @@ -312,12 +312,12 @@ void EpubReaderActivity::renderScreen() { if (!section->createSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(), SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth, viewportHeight, progressSetup, progressCallback)) { - Serial.printf("[%lu] [ERS] Failed to persist page data to SD\n", millis()); + Serial.printf("[%lu] [ERS] Persistence des données de page au SD échouée\n", millis()); section.reset(); return; } } else { - Serial.printf("[%lu] [ERS] Cache found, skipping build...\n", millis()); + Serial.printf("[%lu] [ERS] Cache trouvée, sauter sa construction...\n", millis()); } if (nextPageNumber == UINT16_MAX) { @@ -330,16 +330,16 @@ void EpubReaderActivity::renderScreen() { renderer.clearScreen(); if (section->pageCount == 0) { - Serial.printf("[%lu] [ERS] No pages to render\n", millis()); - renderer.drawCenteredText(UI_12_FONT_ID, 300, "Empty chapter", true, EpdFontFamily::BOLD); + Serial.printf("[%lu] [ERS] Aucune page à afficher\n", millis()); + renderer.drawCenteredText(UI_12_FONT_ID, 300, "Chapitre vide", true, EpdFontFamily::BOLD); renderStatusBar(orientedMarginRight, orientedMarginBottom, orientedMarginLeft); renderer.displayBuffer(); return; } if (section->currentPage < 0 || section->currentPage >= section->pageCount) { - Serial.printf("[%lu] [ERS] Page out of bounds: %d (max %d)\n", millis(), section->currentPage, section->pageCount); - renderer.drawCenteredText(UI_12_FONT_ID, 300, "Out of bounds", true, EpdFontFamily::BOLD); + Serial.printf("[%lu] [ERS] Page hors limites: %d (max %d)\n", millis(), section->currentPage, section->pageCount); + renderer.drawCenteredText(UI_12_FONT_ID, 300, "Hors limites", true, EpdFontFamily::BOLD); renderStatusBar(orientedMarginRight, orientedMarginBottom, orientedMarginLeft); renderer.displayBuffer(); return; @@ -348,14 +348,14 @@ void EpubReaderActivity::renderScreen() { { auto p = section->loadPageFromSectionFile(); if (!p) { - Serial.printf("[%lu] [ERS] Failed to load page from SD - clearing section cache\n", millis()); + Serial.printf("[%lu] [ERS] Chargment de page du SD échoué - suppression de la cache de section\n", millis()); section->clearCache(); section.reset(); return renderScreen(); } const auto start = millis(); renderContents(std::move(p), orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft); - Serial.printf("[%lu] [ERS] Rendered page in %dms\n", millis(), millis() - start); + Serial.printf("[%lu] [ERS] Page rendue en %dms\n", millis(), millis() - start); } FsFile f; @@ -451,8 +451,8 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in std::string title; int titleWidth; if (tocIndex == -1) { - title = "Unnamed"; - titleWidth = renderer.getTextWidth(SMALL_FONT_ID, "Unnamed"); + title = "Sans nom"; + titleWidth = renderer.getTextWidth(SMALL_FONT_ID, "Sans nom"); } else { const auto tocItem = epub->getTocItem(tocIndex); title = tocItem.title; diff --git a/src/activities/reader/FileSelectionActivity.cpp b/src/activities/reader/FileSelectionActivity.cpp index 33c2c3e4..2db493b2 100644 --- a/src/activities/reader/FileSelectionActivity.cpp +++ b/src/activities/reader/FileSelectionActivity.cpp @@ -180,14 +180,14 @@ void FileSelectionActivity::render() const { renderer.clearScreen(); const auto pageWidth = renderer.getScreenWidth(); - renderer.drawCenteredText(UI_12_FONT_ID, 15, "Books", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, 15, "Livres", true, EpdFontFamily::BOLD); // Help text - const auto labels = mappedInput.mapLabels("« Home", "Open", "", ""); + const auto labels = mappedInput.mapLabels("« Accueil", "Ouvrir", "", ""); renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); if (files.empty()) { - renderer.drawText(UI_10_FONT_ID, 20, 60, "No books found"); + renderer.drawText(UI_10_FONT_ID, 20, 60, "Aucun livre trouvé"); renderer.displayBuffer(); return; } diff --git a/src/activities/reader/ReaderActivity.cpp b/src/activities/reader/ReaderActivity.cpp index cb123e1c..6d87edcd 100644 --- a/src/activities/reader/ReaderActivity.cpp +++ b/src/activities/reader/ReaderActivity.cpp @@ -22,7 +22,7 @@ bool ReaderActivity::isXtcFile(const std::string& path) { std::unique_ptr ReaderActivity::loadEpub(const std::string& path) { if (!SdMan.exists(path.c_str())) { - Serial.printf("[%lu] [ ] File does not exist: %s\n", millis(), path.c_str()); + Serial.printf("[%lu] [ ] Le fichier n'existe pas: %s\n", millis(), path.c_str()); return nullptr; } @@ -31,13 +31,13 @@ std::unique_ptr ReaderActivity::loadEpub(const std::string& path) { return epub; } - Serial.printf("[%lu] [ ] Failed to load epub\n", millis()); + Serial.printf("[%lu] [ ] Chargement de l'epub échoué\n", millis()); return nullptr; } std::unique_ptr ReaderActivity::loadXtc(const std::string& path) { if (!SdMan.exists(path.c_str())) { - Serial.printf("[%lu] [ ] File does not exist: %s\n", millis(), path.c_str()); + Serial.printf("[%lu] [ ] Le fichier n'existe pas: %s\n", millis(), path.c_str()); return nullptr; } @@ -46,14 +46,14 @@ std::unique_ptr ReaderActivity::loadXtc(const std::string& path) { return xtc; } - Serial.printf("[%lu] [ ] Failed to load XTC\n", millis()); + Serial.printf("[%lu] [ ] Chargement du XTC échoué\n", millis()); return nullptr; } void ReaderActivity::onSelectBookFile(const std::string& path) { currentBookPath = path; // Track current book path exitActivity(); - enterNewActivity(new FullScreenMessageActivity(renderer, mappedInput, "Loading...")); + enterNewActivity(new FullScreenMessageActivity(renderer, mappedInput, "Chargement...")); if (isXtcFile(path)) { // Load XTC file @@ -62,7 +62,7 @@ void ReaderActivity::onSelectBookFile(const std::string& path) { onGoToXtcReader(std::move(xtc)); } else { exitActivity(); - enterNewActivity(new FullScreenMessageActivity(renderer, mappedInput, "Failed to load XTC", + enterNewActivity(new FullScreenMessageActivity(renderer, mappedInput, "Chargement du XTC échoué", EpdFontFamily::REGULAR, EInkDisplay::HALF_REFRESH)); delay(2000); onGoToFileSelection(); @@ -74,7 +74,7 @@ void ReaderActivity::onSelectBookFile(const std::string& path) { onGoToEpubReader(std::move(epub)); } else { exitActivity(); - enterNewActivity(new FullScreenMessageActivity(renderer, mappedInput, "Failed to load epub", + enterNewActivity(new FullScreenMessageActivity(renderer, mappedInput, "Chargement de l'epub échoué", EpdFontFamily::REGULAR, EInkDisplay::HALF_REFRESH)); delay(2000); onGoToFileSelection(); diff --git a/src/activities/reader/XtcReaderActivity.cpp b/src/activities/reader/XtcReaderActivity.cpp index c0580cf6..d5d9cf37 100644 --- a/src/activities/reader/XtcReaderActivity.cpp +++ b/src/activities/reader/XtcReaderActivity.cpp @@ -251,7 +251,7 @@ void XtcReaderActivity::renderPage() { pixelCounts[getPixelValue(x, y)]++; } } - Serial.printf("[%lu] [XTR] Pixel distribution: White=%lu, DarkGrey=%lu, LightGrey=%lu, Black=%lu\n", millis(), + Serial.printf("[%lu] [XTR] Distribution des pixels: Blanc=%lu, GrisFoncé=%lu, GrisPâle=%lu, Noir=%lu\n", millis(), pixelCounts[0], pixelCounts[1], pixelCounts[2], pixelCounts[3]); // Pass 1: BW buffer - draw all non-white pixels as black @@ -315,7 +315,7 @@ void XtcReaderActivity::renderPage() { free(pageBuffer); - Serial.printf("[%lu] [XTR] Rendered page %lu/%lu (2-bit grayscale)\n", millis(), currentPage + 1, + Serial.printf("[%lu] [XTR] Page rendue %lu/%lu en niveaux de gris (2-bits)\n", millis(), currentPage + 1, xtc->getPageCount()); return; } else { @@ -352,7 +352,7 @@ void XtcReaderActivity::renderPage() { pagesUntilFullRefresh--; } - Serial.printf("[%lu] [XTR] Rendered page %lu/%lu (%u-bit)\n", millis(), currentPage + 1, xtc->getPageCount(), + Serial.printf("[%lu] [XTR] Page rendue %lu/%lu (%u-bits)\n", millis(), currentPage + 1, xtc->getPageCount(), bitDepth); } @@ -375,7 +375,7 @@ void XtcReaderActivity::loadProgress() { uint8_t data[4]; if (f.read(data, 4) == 4) { currentPage = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); - Serial.printf("[%lu] [XTR] Loaded progress: page %lu\n", millis(), currentPage); + Serial.printf("[%lu] [XTR] Progrès chargé: page %lu\n", millis(), currentPage); // Validate page number if (currentPage >= xtc->getPageCount()) { diff --git a/src/activities/settings/CalibreSettingsActivity.cpp b/src/activities/settings/CalibreSettingsActivity.cpp index 4f614ffc..c6065fcb 100644 --- a/src/activities/settings/CalibreSettingsActivity.cpp +++ b/src/activities/settings/CalibreSettingsActivity.cpp @@ -14,7 +14,7 @@ namespace { constexpr int MENU_ITEMS = 2; -const char* menuNames[MENU_ITEMS] = {"Calibre Web URL", "Connect as Wireless Device"}; +const char* menuNames[MENU_ITEMS] = {"URL web Calibre", "Connecter en tant qu'un appareil sans fil"}; } // namespace void CalibreSettingsActivity::taskTrampoline(void* param) { @@ -83,7 +83,7 @@ void CalibreSettingsActivity::handleSelection() { // Calibre Web URL exitActivity(); enterNewActivity(new KeyboardEntryActivity( - renderer, mappedInput, "Calibre Web URL", SETTINGS.opdsServerUrl, 10, + renderer, mappedInput, "URL web Calibre", SETTINGS.opdsServerUrl, 10, 127, // maxLength false, // not password [this](const std::string& url) { @@ -155,14 +155,14 @@ void CalibreSettingsActivity::render() { // Draw status for URL setting if (i == 0) { - const char* status = (strlen(SETTINGS.opdsServerUrl) > 0) ? "[Set]" : "[Not Set]"; + const char* status = (strlen(SETTINGS.opdsServerUrl) > 0) ? "[Défini]" : "[Indéfini]"; const auto width = renderer.getTextWidth(UI_10_FONT_ID, status); renderer.drawText(UI_10_FONT_ID, pageWidth - 20 - width, settingY, status, !isSelected); } } // Draw button hints - const auto labels = mappedInput.mapLabels("« Back", "Select", "", ""); + const auto labels = mappedInput.mapLabels("« Retour", "Select.", "", ""); renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); renderer.displayBuffer(); diff --git a/src/activities/settings/OtaUpdateActivity.cpp b/src/activities/settings/OtaUpdateActivity.cpp index 0393847d..347281d6 100644 --- a/src/activities/settings/OtaUpdateActivity.cpp +++ b/src/activities/settings/OtaUpdateActivity.cpp @@ -17,12 +17,12 @@ void OtaUpdateActivity::onWifiSelectionComplete(const bool success) { exitActivity(); if (!success) { - Serial.printf("[%lu] [OTA] WiFi connection failed, exiting\n", millis()); + Serial.printf("[%lu] [OTA] Connexion au WiFi a échouée, arrêt en cours\n", millis()); goBack(); return; } - Serial.printf("[%lu] [OTA] WiFi connected, checking for update\n", millis()); + Serial.printf("[%lu] [OTA] WiFi connecté, recherche de mises à jour\n", millis()); xSemaphoreTake(renderingMutex, portMAX_DELAY); state = CHECKING_FOR_UPDATE; @@ -31,7 +31,7 @@ void OtaUpdateActivity::onWifiSelectionComplete(const bool success) { vTaskDelay(10 / portTICK_PERIOD_MS); const auto res = updater.checkForUpdate(); if (res != OtaUpdater::OK) { - Serial.printf("[%lu] [OTA] Update check failed: %d\n", millis(), res); + Serial.printf("[%lu] [OTA] Recherce de mises à jour échouée: %d\n", millis(), res); xSemaphoreTake(renderingMutex, portMAX_DELAY); state = FAILED; xSemaphoreGive(renderingMutex); @@ -40,7 +40,7 @@ void OtaUpdateActivity::onWifiSelectionComplete(const bool success) { } if (!updater.isUpdateNewer()) { - Serial.printf("[%lu] [OTA] No new update available\n", millis()); + Serial.printf("[%lu] [OTA] Aucune nouvelle mise à jour disponible\n", millis()); xSemaphoreTake(renderingMutex, portMAX_DELAY); state = NO_UPDATE; xSemaphoreGive(renderingMutex); @@ -67,11 +67,11 @@ void OtaUpdateActivity::onEnter() { ); // Turn on WiFi immediately - Serial.printf("[%lu] [OTA] Turning on WiFi...\n", millis()); + Serial.printf("[%lu] [OTA] Activation du WiFi...\n", millis()); WiFi.mode(WIFI_STA); // Launch WiFi selection subactivity - Serial.printf("[%lu] [OTA] Launching WifiSelectionActivity...\n", millis()); + Serial.printf("[%lu] [OTA] Lancement de WifiSelectionActivity...\n", millis()); enterNewActivity(new WifiSelectionActivity(renderer, mappedInput, [this](const bool connected) { onWifiSelectionComplete(connected); })); } @@ -115,7 +115,7 @@ void OtaUpdateActivity::render() { float updaterProgress = 0; if (state == UPDATE_IN_PROGRESS) { - Serial.printf("[%lu] [OTA] Update progress: %d / %d\n", millis(), updater.processedSize, updater.totalSize); + Serial.printf("[%lu] [OTA] Progrès de la mise à jour : %d / %d\n", millis(), updater.processedSize, updater.totalSize); updaterProgress = static_cast(updater.processedSize) / static_cast(updater.totalSize); // Only update every 2% at the most if (static_cast(updaterProgress * 50) == lastUpdaterPercentage / 2) { @@ -127,27 +127,27 @@ void OtaUpdateActivity::render() { const auto pageWidth = renderer.getScreenWidth(); renderer.clearScreen(); - renderer.drawCenteredText(UI_12_FONT_ID, 15, "Update", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, 15, "Mise à jour", true, EpdFontFamily::BOLD); if (state == CHECKING_FOR_UPDATE) { - renderer.drawCenteredText(UI_10_FONT_ID, 300, "Checking for update...", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_10_FONT_ID, 300, "Recherche de mises à jour...", true, EpdFontFamily::BOLD); renderer.displayBuffer(); return; } if (state == WAITING_CONFIRMATION) { - renderer.drawCenteredText(UI_10_FONT_ID, 200, "New update available!", true, EpdFontFamily::BOLD); - renderer.drawText(UI_10_FONT_ID, 20, 250, "Current Version: " CROSSPOINT_VERSION); - renderer.drawText(UI_10_FONT_ID, 20, 270, ("New Version: " + updater.getLatestVersion()).c_str()); + renderer.drawCenteredText(UI_10_FONT_ID, 200, "Une mise à jour est disponible!", true, EpdFontFamily::BOLD); + renderer.drawText(UI_10_FONT_ID, 20, 250, "Version actuelle: " CROSSPOINT_VERSION); + renderer.drawText(UI_10_FONT_ID, 20, 270, ("Nouvelle version: " + updater.getLatestVersion()).c_str()); - const auto labels = mappedInput.mapLabels("Cancel", "Update", "", ""); + const auto labels = mappedInput.mapLabels("Annuler", "M-à-j", "", ""); renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); renderer.displayBuffer(); return; } if (state == UPDATE_IN_PROGRESS) { - renderer.drawCenteredText(UI_10_FONT_ID, 310, "Updating...", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_10_FONT_ID, 310, "Mise à jour...", true, EpdFontFamily::BOLD); renderer.drawRect(20, 350, pageWidth - 40, 50); renderer.fillRect(24, 354, static_cast(updaterProgress * static_cast(pageWidth - 44)), 42); renderer.drawCenteredText(UI_10_FONT_ID, 420, @@ -160,20 +160,20 @@ void OtaUpdateActivity::render() { } if (state == NO_UPDATE) { - renderer.drawCenteredText(UI_10_FONT_ID, 300, "No update available", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_10_FONT_ID, 300, "Aucune novelle mise à jour disponible", true, EpdFontFamily::BOLD); renderer.displayBuffer(); return; } if (state == FAILED) { - renderer.drawCenteredText(UI_10_FONT_ID, 300, "Update failed", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_10_FONT_ID, 300, "Mise à jour échouée", true, EpdFontFamily::BOLD); renderer.displayBuffer(); return; } if (state == FINISHED) { - renderer.drawCenteredText(UI_10_FONT_ID, 300, "Update complete", true, EpdFontFamily::BOLD); - renderer.drawCenteredText(UI_10_FONT_ID, 350, "Press and hold power button to turn back on"); + renderer.drawCenteredText(UI_10_FONT_ID, 300, "Mise à jour terminée", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_10_FONT_ID, 350, "Appuyez longuement sur le bouton d'alimentation pour rallumer"); renderer.displayBuffer(); state = SHUTTING_DOWN; return; @@ -188,7 +188,7 @@ void OtaUpdateActivity::loop() { if (state == WAITING_CONFIRMATION) { if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) { - Serial.printf("[%lu] [OTA] New update available, starting download...\n", millis()); + Serial.printf("[%lu] [OTA] Nouvelle mise à jour disponible, téléchargement commencé...\n", millis()); xSemaphoreTake(renderingMutex, portMAX_DELAY); state = UPDATE_IN_PROGRESS; xSemaphoreGive(renderingMutex); @@ -197,7 +197,7 @@ void OtaUpdateActivity::loop() { const auto res = updater.installUpdate([this](const size_t, const size_t) { updateRequired = true; }); if (res != OtaUpdater::OK) { - Serial.printf("[%lu] [OTA] Update failed: %d\n", millis(), res); + Serial.printf("[%lu] [OTA] Mise à jour échouée: %d\n", millis(), res); xSemaphoreTake(renderingMutex, portMAX_DELAY); state = FAILED; xSemaphoreGive(renderingMutex); diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 702db172..66e9b2fb 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -16,31 +16,31 @@ namespace { constexpr int settingsCount = 18; const SettingInfo settingsList[settingsCount] = { // Should match with SLEEP_SCREEN_MODE - SettingInfo::Enum("Sleep Screen", &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover", "None"}), - SettingInfo::Enum("Sleep Screen Cover Mode", &CrossPointSettings::sleepScreenCoverMode, {"Fit", "Crop"}), - SettingInfo::Enum("Status Bar", &CrossPointSettings::statusBar, {"None", "No Progress", "Full"}), - SettingInfo::Toggle("Extra Paragraph Spacing", &CrossPointSettings::extraParagraphSpacing), - SettingInfo::Toggle("Text Anti-Aliasing", &CrossPointSettings::textAntiAliasing), - SettingInfo::Toggle("Short Power Button Click", &CrossPointSettings::shortPwrBtn), - SettingInfo::Enum("Reading Orientation", &CrossPointSettings::orientation, - {"Portrait", "Landscape CW", "Inverted", "Landscape CCW"}), - SettingInfo::Enum("Front Button Layout", &CrossPointSettings::frontButtonLayout, - {"Bck, Cnfrm, Lft, Rght", "Lft, Rght, Bck, Cnfrm", "Lft, Bck, Cnfrm, Rght"}), - SettingInfo::Enum("Side Button Layout (reader)", &CrossPointSettings::sideButtonLayout, - {"Prev, Next", "Next, Prev"}), - SettingInfo::Enum("Reader Font Family", &CrossPointSettings::fontFamily, + SettingInfo::Enum("Écran de veille", &CrossPointSettings::sleepScreen, {"Sombre", "Clair", "Personnalisé", "Couverture", "Aucun"}), + SettingInfo::Enum("Mode de couverture de veille", &CrossPointSettings::sleepScreenCoverMode, {"Étirée", "Recadrée"}), + SettingInfo::Enum("Barre d'état", &CrossPointSettings::statusBar, {"Aucune", "Sans progrès", "Pleine"}), + SettingInfo::Toggle("Espace supplé. entre paragraphes", &CrossPointSettings::extraParagraphSpacing), + SettingInfo::Toggle("Anticrénelage du texte", &CrossPointSettings::textAntiAliasing), + SettingInfo::Toggle("Clic court du bouton alim.", &CrossPointSettings::shortPwrBtn), + SettingInfo::Enum("Orientation de lecture", &CrossPointSettings::orientation, + {"Portrait", "Paysage à droite", "Inversée", "Paysage à gauche"}), + SettingInfo::Enum("Disposition des boutons au front", &CrossPointSettings::frontButtonLayout, + {"Rtr, Cnfrmr, Gche, Drte", "Gche, Drte, Rtr, Cnfrmr", "Gche, Rtr, Cnfrmr, Drte"}), + SettingInfo::Enum("Disposition des boutons à droite (lis.)", &CrossPointSettings::sideButtonLayout, + {"Précédent, Prochaine", "Prochaine, Précédent"}), + SettingInfo::Enum("Police", &CrossPointSettings::fontFamily, {"Bookerly", "Noto Sans", "Open Dyslexic"}), - SettingInfo::Enum("Reader Font Size", &CrossPointSettings::fontSize, {"Small", "Medium", "Large", "X Large"}), - SettingInfo::Enum("Reader Line Spacing", &CrossPointSettings::lineSpacing, {"Tight", "Normal", "Wide"}), - SettingInfo::Value("Reader Screen Margin", &CrossPointSettings::screenMargin, {5, 40, 5}), - SettingInfo::Enum("Reader Paragraph Alignment", &CrossPointSettings::paragraphAlignment, - {"Justify", "Left", "Center", "Right"}), - SettingInfo::Enum("Time to Sleep", &CrossPointSettings::sleepTimeout, + SettingInfo::Enum("Taille de police", &CrossPointSettings::fontSize, {"Petit", "Medium", "Large", "Très Large"}), + SettingInfo::Enum("Espacement des lignes", &CrossPointSettings::lineSpacing, {"Fin", "Normal", "Large"}), + SettingInfo::Value("Marge d'écran", &CrossPointSettings::screenMargin, {5, 40, 5}), + SettingInfo::Enum("Alignement des lignes", &CrossPointSettings::paragraphAlignment, + {"Justifié", "Gauche", "Centré", "Droite"}), + SettingInfo::Enum("Temps de veille", &CrossPointSettings::sleepTimeout, {"1 min", "5 min", "10 min", "15 min", "30 min"}), - SettingInfo::Enum("Refresh Frequency", &CrossPointSettings::refreshFrequency, + SettingInfo::Enum("Fréquence de rafraîche.", &CrossPointSettings::refreshFrequency, {"1 page", "5 pages", "10 pages", "15 pages", "30 pages"}), - SettingInfo::Action("Calibre Settings"), - SettingInfo::Action("Check for updates")}; + SettingInfo::Action("Paramètres Calibre"), + SettingInfo::Action("Vérifier les mises à jour")}; } // namespace void SettingsActivity::taskTrampoline(void* param) { @@ -137,7 +137,7 @@ void SettingsActivity::toggleCurrentSetting() { SETTINGS.*(setting.valuePtr) = currentValue + setting.valueRange.step; } } else if (setting.type == SettingType::ACTION) { - if (strcmp(setting.name, "Calibre Settings") == 0) { + if (strcmp(setting.name, "Paramètres Calibre") == 0) { xSemaphoreTake(renderingMutex, portMAX_DELAY); exitActivity(); enterNewActivity(new CalibreSettingsActivity(renderer, mappedInput, [this] { @@ -145,7 +145,7 @@ void SettingsActivity::toggleCurrentSetting() { updateRequired = true; })); xSemaphoreGive(renderingMutex); - } else if (strcmp(setting.name, "Check for updates") == 0) { + } else if (strcmp(setting.name, "Verifier les mises à jour") == 0) { xSemaphoreTake(renderingMutex, portMAX_DELAY); exitActivity(); enterNewActivity(new OtaUpdateActivity(renderer, mappedInput, [this] { @@ -182,7 +182,7 @@ void SettingsActivity::render() const { const auto pageHeight = renderer.getScreenHeight(); // Draw header - renderer.drawCenteredText(UI_12_FONT_ID, 15, "Settings", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, 15, "Paramètres", true, EpdFontFamily::BOLD); // Draw selection renderer.fillRect(0, 60 + selectedSettingIndex * 30 - 2, pageWidth - 1, 30); @@ -198,7 +198,7 @@ void SettingsActivity::render() const { std::string valueText = ""; if (settingsList[i].type == SettingType::TOGGLE && settingsList[i].valuePtr != nullptr) { const bool value = SETTINGS.*(settingsList[i].valuePtr); - valueText = value ? "ON" : "OFF"; + valueText = value ? "OUI" : "NON"; } else if (settingsList[i].type == SettingType::ENUM && settingsList[i].valuePtr != nullptr) { const uint8_t value = SETTINGS.*(settingsList[i].valuePtr); valueText = settingsList[i].enumValues[value]; @@ -214,7 +214,7 @@ void SettingsActivity::render() const { pageHeight - 60, CROSSPOINT_VERSION); // Draw help text - const auto labels = mappedInput.mapLabels("« Save", "Toggle", "", ""); + const auto labels = mappedInput.mapLabels("« Enreg.", "Basculer", "", ""); renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); // Always use standard refresh for settings screen