From f44a8b6a1706244953ad35a4aaad317f039f73ee Mon Sep 17 00:00:00 2001 From: eshifri <46511024+eshifri@users.noreply.github.com> Date: Sat, 26 Feb 2022 14:42:40 -0800 Subject: [PATCH] feat: Support opening large log files on colorlcd (#1625) * Remove limit for the TXT file size for color LCD TX (#1612) * view log files * warning for long files and load speed-up --- radio/src/gui/colorlcd/radio_sdmanager.cpp | 29 +++++++++--- radio/src/gui/colorlcd/view_text.cpp | 52 ++++++++++++---------- radio/src/gui/colorlcd/view_text.h | 6 +-- radio/src/translations.cpp | 2 + radio/src/translations.h | 2 + radio/src/translations/cn.h.txt | 2 + radio/src/translations/cz.h.txt | 2 + radio/src/translations/de.h.txt | 2 + radio/src/translations/en.h.txt | 2 + radio/src/translations/es.h.txt | 2 + radio/src/translations/fi.h.txt | 2 + radio/src/translations/fr.h.txt | 2 + radio/src/translations/it.h.txt | 2 + radio/src/translations/nl.h.txt | 2 + radio/src/translations/pl.h.txt | 2 + radio/src/translations/pt.h.txt | 2 + radio/src/translations/se.h.txt | 2 + 17 files changed, 81 insertions(+), 34 deletions(-) diff --git a/radio/src/gui/colorlcd/radio_sdmanager.cpp b/radio/src/gui/colorlcd/radio_sdmanager.cpp index 89bff8725..f4e9304eb 100644 --- a/radio/src/gui/colorlcd/radio_sdmanager.cpp +++ b/radio/src/gui/colorlcd/radio_sdmanager.cpp @@ -30,6 +30,8 @@ #include "view_text.h" #include "file_preview.h" +constexpr int WARN_FILE_LENGTH = 96000; + class FileNameEditWindow : public Page { public: @@ -279,16 +281,31 @@ void RadioSdManagerPage::build(FormWindow * window) // else if (isExtensionMatching(ext, BITMAPS_EXT)) { // // TODO // } - else if (!strcasecmp(ext, TEXT_EXT)) { + else if (!strcasecmp(ext, TEXT_EXT) || !strcasecmp(ext, LOGS_EXT)) { menu->addLine(STR_VIEW_TEXT, [=]() { static char lfn[FF_MAX_LFN + 1]; // TODO optimize that! f_getcwd((TCHAR *)lfn, FF_MAX_LFN); + FIL file; + std::string fileName = + std::string(lfn) + "/" + std::string(name); + if (FR_OK == f_open(&file, (TCHAR *)fileName.c_str(), + FA_OPEN_EXISTING | FA_READ)) { + const int fileLenght = file.obj.objsize; + f_close(&file); - auto textView = new ViewTextWindow(lfn, name); - textView->setCloseHandler([=]() { - //window->clear(); - rebuild(window); - }); + if (fileLenght > WARN_FILE_LENGTH) { + char buf[64]; + sprintf(buf, " %s %dkB. %s", STR_FILE_SIZE, + fileLenght / 1024, STR_FILE_OPEN); + new ConfirmDialog(window, STR_WARNING, buf, [=] { + auto textView = new ViewTextWindow(lfn, name); + textView->setCloseHandler([=]() { rebuild(window); }); + }); + } else { + auto textView = new ViewTextWindow(lfn, name); + textView->setCloseHandler([=]() { rebuild(window); }); + } + } }); } if (!READ_ONLY() && !strcasecmp(ext, FIRMWARE_EXT)) { diff --git a/radio/src/gui/colorlcd/view_text.cpp b/radio/src/gui/colorlcd/view_text.cpp index e7fb60673..d72013ff6 100644 --- a/radio/src/gui/colorlcd/view_text.cpp +++ b/radio/src/gui/colorlcd/view_text.cpp @@ -52,6 +52,7 @@ void ViewTextWindow::extractNameSansExt() nameLength -= extLength; name.substr(nameLength); + openFromEnd = !strcmp(ext, LOGS_EXT); } void ViewTextWindow::buildBody(Window *window) @@ -59,6 +60,7 @@ void ViewTextWindow::buildBody(Window *window) GridLayout grid(window); grid.spacer(); int i; + FIL file; // assume average characte is 10 pixels wide, round the string length to tens. // Font is not fixed width, so this is for the worst case... @@ -74,22 +76,26 @@ void ViewTextWindow::buildBody(Window *window) memclear(lines[i], maxLineLength + 1); } - longestLine = 0; - loadFirstScreen(); + if (isInSetup) { + if (FR_OK == + f_open(&file, (TCHAR *)fullPath.c_str(), FA_OPEN_EXISTING | FA_READ)) { + const int fileLenght = file.obj.objsize; + maxLines = 20 * fileLenght / maxLineLength; + f_close(&file); - if (isInSetup == true) { - textBottom = false; - while (!textBottom) { - sdReadTextFileBlock(fullPath.c_str(), readLinesCount); - textVerticalOffset += 10; + textBottom = false; + longestLine = 0; + loadOneScreen(maxLines); + + maxPos = + (maxLines - maxScreenLines) * (PAGE_LINE_HEIGHT + PAGE_LINE_SPACING); + if (maxPos < body.getRect().h) maxPos = body.getRect().h; } - maxPos = - (maxLines - maxScreenLines) * (PAGE_LINE_HEIGHT + PAGE_LINE_SPACING); - if (maxPos < body.getRect().h) maxPos = body.getRect().h; } isInSetup = false; - loadFirstScreen(); + textVerticalOffset = 0; + loadOneScreen(openFromEnd ? (maxLines - maxScreenLines) : 0); for (i = 0; i < maxScreenLines; i++) { new DynamicText(window, grid.getSlot(), [=]() { @@ -98,7 +104,7 @@ void ViewTextWindow::buildBody(Window *window) return std::string(str); }); grid.nextLine(); - } + } } #if defined(HARDWARE_TOUCH) @@ -114,8 +120,8 @@ bool ViewTextWindow::onTouchSlide(coord_t x, coord_t y, coord_t startX, textVerticalOffset += lineStep; if (textVerticalOffset < 0) textVerticalOffset = 0; - // if (textBottom && lineStep > 0) textVerticalOffset -= lineStep; - if (textVerticalOffset > maxLines) textVerticalOffset = maxLines; + if (textVerticalOffset > maxLines - maxScreenLines) + textVerticalOffset = maxLines - maxScreenLines; sdReadTextFileBlock(fullPath.c_str(), readLinesCount); } return Page::onTouchSlide(x, y, startX, startY, slideX, slideY); @@ -178,9 +184,9 @@ void ViewTextWindow::checkEvents() Page::checkEvents(); } -void ViewTextWindow::loadFirstScreen() +void ViewTextWindow::loadOneScreen(int offset) { - textVerticalOffset = 0; + textVerticalOffset = offset; readLinesCount = 0; sdReadTextFileBlock(fullPath.c_str(), readLinesCount); } @@ -204,11 +210,10 @@ void ViewTextWindow::sdReadTextFileBlock(const char *filename, int &lines_count) result = f_open(&file, (TCHAR *)filename, FA_OPEN_EXISTING | FA_READ); if (result == FR_OK) { - for (int i = 0; i < TEXT_FILE_MAXSIZE && - f_read(&file, &c, 1, &sz) == FR_OK && sz == 1 && - (lines_count == 0 || - current_line - textVerticalOffset < maxScreenLines); - i++) { + while (f_read(&file, &c, 1, &sz) == FR_OK && sz == 1 && + (lines_count == 0 || + current_line - textVerticalOffset < maxScreenLines)) + { if (c == '\n' || line_length >= maxLineLength) { ++current_line; line_length = 1; @@ -271,9 +276,8 @@ void ViewTextWindow::drawVerticalScrollbar(BitmapBuffer *dc) { int readPos = textVerticalOffset * (PAGE_LINE_HEIGHT + PAGE_LINE_SPACING); - if (readPos < header.getRect().h << 1) readPos = header.getRect().h << 1; - - coord_t yofs = divRoundClosest(body.getRect().h * readPos, maxPos); + coord_t yofs = divRoundClosest(body.getRect().h * readPos, maxPos) + + header.getRect().h + (int)PAGE_LINE_SPACING; coord_t yhgt = divRoundClosest(body.getRect().h * body.getRect().h, maxPos); if (yhgt < 15) yhgt = 15; if (yhgt + yofs > maxPos) yhgt = maxPos - yofs; diff --git a/radio/src/gui/colorlcd/view_text.h b/radio/src/gui/colorlcd/view_text.h index ee6754b7f..b126c0843 100644 --- a/radio/src/gui/colorlcd/view_text.h +++ b/radio/src/gui/colorlcd/view_text.h @@ -26,8 +26,6 @@ #include "page.h" #include "static.h" -constexpr uint16_t TEXT_FILE_MAXSIZE = 20480; - class ViewTextWindow : public Page { public: @@ -49,7 +47,7 @@ class ViewTextWindow : public Page }; void sdReadTextFileBlock(const char* filename, int& lines_count); - void loadFirstScreen(void); + void loadOneScreen(int offset); #if defined(HARDWARE_TOUCH) bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, coord_t slideX, coord_t slideY) override; @@ -84,7 +82,6 @@ class ViewTextWindow : public Page std::string extension; unsigned int icon; - bool lastLine; uint16_t readCount; int longestLine; @@ -98,6 +95,7 @@ class ViewTextWindow : public Page int maxLines; bool textBottom; bool isInSetup; + bool openFromEnd; void extractNameSansExt(void); void buildBody(Window* window); diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 2b99b1bd4..3971f0e26 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -767,6 +767,8 @@ const char STR_MODULE_RANGE[] = TR_MODULE_RANGE; const char STR_RECEIVER_OPTIONS[] = TR_RECEIVER_OPTIONS; const char STR_SPORT_UPDATE_POWER_MODE[] = TR_SPORT_UPDATE_POWER_MODE; const char STR_TOUCH_PANEL[] = TR_TOUCH_PANEL; +const char STR_FILE_SIZE[] = TR_FILE_SIZE; +const char STR_FILE_OPEN[] = TR_FILE_OPEN; #if defined(COLORLCD) const char STR_ASSIGN_SPLASH[] = TR_ASSIGN_SPLASH; diff --git a/radio/src/translations.h b/radio/src/translations.h index 79c3dfb65..7ff46b3e8 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -196,6 +196,8 @@ extern const char STR_VPREC[]; extern const char STR_VCELLINDEX[]; extern const char STR_TOUCH_PANEL[]; extern const char STR_ADCFILTERVALUES[]; +extern const char STR_FILE_SIZE[]; +extern const char STR_FILE_OPEN[]; extern const char STR_BLUETOOTH[]; extern const char STR_BLUETOOTH_DISC[]; diff --git a/radio/src/translations/cn.h.txt b/radio/src/translations/cn.h.txt index 95fd0ee3a..a07141fcc 100644 --- a/radio/src/translations/cn.h.txt +++ b/radio/src/translations/cn.h.txt @@ -993,6 +993,8 @@ #define TR_SPORT_UPDATE_POWER_MODES "自动""开启" #define TR_NO_TELEMETRY_SCREENS "无回传页面" #define TR_TOUCH_PANEL "触摸屏:" +#define TR_FILE_SIZE "File size" +#define TR_FILE_OPEN "Open anyway?" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "名称" diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index 1560a6da6..fd62d2ed3 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -1043,6 +1043,8 @@ #define TR_SPORT_UPDATE_POWER_MODES "AUTO""ON\0 " #define TR_NO_TELEMETRY_SCREENS "No Telemetry Screens" #define TR_TOUCH_PANEL "Touch panel:" +#define TR_FILE_SIZE "File size" +#define TR_FILE_OPEN "Open anyway?" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Název" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 75e6a28a9..5c69d6f1f 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -1049,6 +1049,8 @@ #define TR_SPORT_UPDATE_POWER_MODES "AUTO""ON\0 " #define TR_NO_TELEMETRY_SCREENS "No Telemetry Screens" #define TR_TOUCH_PANEL "Touch panel:" +#define TR_FILE_SIZE "File size" +#define TR_FILE_OPEN "Open anyway?" // Horus and Taranis specific column headers #define TR_PHASES_HEADERS_NAME "Name " diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 06a73d0a0..8dbc22fda 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -1049,6 +1049,8 @@ #define TR_SPORT_UPDATE_POWER_MODES "AUTO""ON\0 " #define TR_NO_TELEMETRY_SCREENS "No Telemetry Screens" #define TR_TOUCH_PANEL "Touch panel:" +#define TR_FILE_SIZE "File size" +#define TR_FILE_OPEN "Open anyway?" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Name" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 0d93f9b81..f54a1d7c8 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -1049,6 +1049,8 @@ #define TR_SPORT_UPDATE_POWER_MODES "AUTO""ON\0 " #define TR_NO_TELEMETRY_SCREENS TR("No hay pant. telemetría", "No hay pantallas de telemetría") #define TR_TOUCH_PANEL "Pantalla táctil:" +#define TR_FILE_SIZE "File size" +#define TR_FILE_OPEN "Open anyway?" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Nombre" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index b2a1c7c3e..8a0747d77 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -1061,6 +1061,8 @@ #define TR_SPORT_UPDATE_POWER_MODES "AUTO""ON\0 " #define TR_NO_TELEMETRY_SCREENS "No Telemetry Screens" #define TR_TOUCH_PANEL "Touch panel:" +#define TR_FILE_SIZE "File size" +#define TR_FILE_OPEN "Open anyway?" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Name" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 623780c90..e6dc126b5 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -1073,6 +1073,8 @@ #define TR_SPORT_UPDATE_POWER_MODES "AUTO""ON\0 " #define TR_NO_TELEMETRY_SCREENS "No Telemetry Screens" #define TR_TOUCH_PANEL "Touch panel:" +#define TR_FILE_SIZE "File size" +#define TR_FILE_OPEN "Open anyway?" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Nom" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 308fb88aa..a6c3fd8df 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -1068,6 +1068,8 @@ #define TR_SPORT_UPDATE_POWER_MODES "AUTO""ON\0 " #define TR_NO_TELEMETRY_SCREENS "Nessuno Schermo Telemetria" #define TR_TOUCH_PANEL "Schermo touch:" +#define TR_FILE_SIZE "File size" +#define TR_FILE_OPEN "Open anyway?" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Nome" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 6cd7355c6..68e8547d3 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -1058,6 +1058,8 @@ #define TR_SPORT_UPDATE_POWER_MODES "AUTO""ON\0 " #define TR_NO_TELEMETRY_SCREENS "No Telemetry Screens" #define TR_TOUCH_PANEL "Touch panel:" +#define TR_FILE_SIZE "File size" +#define TR_FILE_OPEN "Open anyway?" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Name" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index 0315f0225..5177c08a2 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -1064,6 +1064,8 @@ #define TR_SPORT_UPDATE_POWER_MODES "AUTO""ON\0 " #define TR_NO_TELEMETRY_SCREENS "No Telemetry Screens" #define TR_TOUCH_PANEL "Touch panel:" +#define TR_FILE_SIZE "File size" +#define TR_FILE_OPEN "Open anyway?" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Nazwa" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index cf84f2e62..0f3d6a5ae 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -1072,6 +1072,8 @@ #define TR_SPORT_UPDATE_POWER_MODES "AUTO""ON\0 " #define TR_NO_TELEMETRY_SCREENS "No Telemetry Screens" #define TR_TOUCH_PANEL "Touch panel:" +#define TR_FILE_SIZE "File size" +#define TR_FILE_OPEN "Open anyway?" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Name" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 313d957bf..9743d9700 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -1072,6 +1072,8 @@ #define TR_SPORT_UPDATE_POWER_MODES "AUTO""ON\0 " #define TR_NO_TELEMETRY_SCREENS "No Telemetry Screens" #define TR_TOUCH_PANEL "Touch panel:" +#define TR_FILE_SIZE "File size" +#define TR_FILE_OPEN "Open anyway?" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Namn"