From 8e362b087ae78c81c8a2ffc8679366dffc1b5803 Mon Sep 17 00:00:00 2001 From: Aleksandr Skoriy Date: Fri, 28 Oct 2022 05:43:25 +0300 Subject: [PATCH 1/5] Browser: Context menu to show file content --- .../archive/scenes/archive_scene_browser.c | 7 ++ .../archive/scenes/archive_scene_config.h | 1 + .../main/archive/scenes/archive_scene_show.c | 73 +++++++++++++++++++ .../main/archive/views/archive_browser_view.c | 26 ++++++- .../main/archive/views/archive_browser_view.h | 1 + 5 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 applications/main/archive/scenes/archive_scene_show.c diff --git a/applications/main/archive/scenes/archive_scene_browser.c b/applications/main/archive/scenes/archive_scene_browser.c index dbf2219908..8eed81f6fe 100644 --- a/applications/main/archive/scenes/archive_scene_browser.c +++ b/applications/main/archive/scenes/archive_scene_browser.c @@ -150,6 +150,13 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneInfo); consumed = true; break; + case ArchiveBrowserEventFileMenuShow: + archive_show_file_menu(browser, false); + scene_manager_set_scene_state( + archive->scene_manager, ArchiveAppSceneBrowser, SCENE_STATE_DEFAULT); + scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneShow); + consumed = true; + break; case ArchiveBrowserEventFileMenuDelete: if(archive_get_tab(browser) != ArchiveTabFavorites) { scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneDelete); diff --git a/applications/main/archive/scenes/archive_scene_config.h b/applications/main/archive/scenes/archive_scene_config.h index 6dda7a20df..d16c6f1a69 100644 --- a/applications/main/archive/scenes/archive_scene_config.h +++ b/applications/main/archive/scenes/archive_scene_config.h @@ -2,3 +2,4 @@ ADD_SCENE(archive, browser, Browser) ADD_SCENE(archive, rename, Rename) ADD_SCENE(archive, delete, Delete) ADD_SCENE(archive, info, Info) +ADD_SCENE(archive, show, Show) diff --git a/applications/main/archive/scenes/archive_scene_show.c b/applications/main/archive/scenes/archive_scene_show.c new file mode 100644 index 0000000000..482585c1d4 --- /dev/null +++ b/applications/main/archive/scenes/archive_scene_show.c @@ -0,0 +1,73 @@ +#include "../archive_i.h" +#include "../helpers/archive_browser.h" +#include + +#define TAG "Archive" + +void archive_scene_show_widget_callback(GuiButtonType result, InputType type, void* context) { + furi_assert(context); + ArchiveApp* app = (ArchiveApp*)context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(app->view_dispatcher, result); + } +} + +void archive_scene_show_on_enter(void* context) { + furi_assert(context); + ArchiveApp* instance = context; + + FuriString* filename; + FuriString* str_size; + filename = furi_string_alloc(); + str_size = furi_string_alloc(); + + ArchiveFile_t* current = archive_get_current_file(instance->browser); + Storage* fs_api = furi_record_open(RECORD_STORAGE); + File* file = storage_file_alloc(fs_api); + uint32_t bytes_count; + + FileInfo fileinfo; + storage_common_stat(fs_api, furi_string_get_cstr(current->path), &fileinfo); + + storage_file_open(file, furi_string_get_cstr(current->path), FSAM_READ, FSOM_OPEN_EXISTING); + char* content = malloc(fileinfo.size + 1); + + bytes_count = storage_file_read(file, content, fileinfo.size); + content[bytes_count + 1] = 0; + + widget_add_text_scroll_element( + instance->widget, 0, 0, 128, 64, content); + + path_extract_filename(current->path, filename, false); + + // This one to return and cursor select this file + path_extract_filename_no_ext(furi_string_get_cstr(current->path), filename); + strlcpy(instance->text_store, furi_string_get_cstr(filename), MAX_NAME_LEN); + + free(content); + storage_file_close(file); + storage_file_free(file); + + furi_string_free(filename); + furi_string_free(str_size); + + view_dispatcher_switch_to_view(instance->view_dispatcher, ArchiveViewWidget); +} + +bool archive_scene_show_on_event(void* context, SceneManagerEvent event) { + furi_assert(context); + ArchiveApp* app = (ArchiveApp*)context; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_next_scene(app->scene_manager, ArchiveAppSceneBrowser); + return true; + } + return false; +} + +void archive_scene_show_on_exit(void* context) { + furi_assert(context); + ArchiveApp* app = (ArchiveApp*)context; + + widget_reset(app->widget); +} diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index cf25e7c892..b905a5a334 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -51,6 +51,7 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { FuriString* item_run = furi_string_alloc_set("Run In App"); FuriString* item_pin = furi_string_alloc_set("Pin"); FuriString* item_info = furi_string_alloc_set("Info"); + FuriString* item_show = furi_string_alloc_set("Show"); FuriString* item_rename = furi_string_alloc_set("Rename"); FuriString* item_delete = furi_string_alloc_set("Delete"); @@ -79,6 +80,10 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { menu_array_push_raw(model->context_menu), item_info, ArchiveBrowserEventFileMenuInfo); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_show, + ArchiveBrowserEventFileMenuShow); archive_menu_add_item( menu_array_push_raw(model->context_menu), item_rename, @@ -100,6 +105,10 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { menu_array_push_raw(model->context_menu), item_pin, ArchiveBrowserEventFileMenuPin); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_show, + ArchiveBrowserEventFileMenuShow); archive_menu_add_item( menu_array_push_raw(model->context_menu), item_rename, @@ -114,6 +123,10 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { menu_array_push_raw(model->context_menu), item_info, ArchiveBrowserEventFileMenuInfo); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_show, + ArchiveBrowserEventFileMenuShow); archive_menu_add_item( menu_array_push_raw(model->context_menu), item_pin, @@ -136,6 +149,10 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { menu_array_push_raw(model->context_menu), item_info, ArchiveBrowserEventFileMenuInfo); + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_show, + ArchiveBrowserEventFileMenuShow); archive_menu_add_item( menu_array_push_raw(model->context_menu), item_rename, @@ -149,6 +166,7 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { furi_string_free(item_run); furi_string_free(item_pin); furi_string_free(item_info); + furi_string_free(item_show); furi_string_free(item_rename); furi_string_free(item_delete); } /*else { @@ -160,9 +178,9 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { canvas_set_color(canvas, ColorWhite); uint8_t calc_height = menu_height - ((MENU_ITEMS - size_menu) * line_height); - canvas_draw_box(canvas, 71, 11, 57, calc_height + 4); + canvas_draw_box(canvas, 71, 1, 57, calc_height + 4); canvas_set_color(canvas, ColorBlack); - elements_slightly_rounded_frame(canvas, 70, 12, 58, calc_height + 4); + elements_slightly_rounded_frame(canvas, 70, 2, 58, calc_height + 4); /*FURI_LOG_D( TAG, @@ -172,10 +190,10 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { model->menu_idx);*/ for(size_t i = 0; i < size_menu; i++) { ArchiveContextMenuItem_t* current = menu_array_get(model->context_menu, i); - canvas_draw_str(canvas, 82, 21 + i * line_height, furi_string_get_cstr(current->text)); + canvas_draw_str(canvas, 82, 11 + i * line_height, furi_string_get_cstr(current->text)); } - canvas_draw_icon(canvas, 74, 14 + model->menu_idx * line_height, &I_ButtonRight_4x7); + canvas_draw_icon(canvas, 74, 4 + model->menu_idx * line_height, &I_ButtonRight_4x7); } static void archive_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar, bool moving) { diff --git a/applications/main/archive/views/archive_browser_view.h b/applications/main/archive/views/archive_browser_view.h index 67b50cb02e..7d01e5387c 100644 --- a/applications/main/archive/views/archive_browser_view.h +++ b/applications/main/archive/views/archive_browser_view.h @@ -40,6 +40,7 @@ typedef enum { ArchiveBrowserEventFileMenuRename, ArchiveBrowserEventFileMenuDelete, ArchiveBrowserEventFileMenuInfo, + ArchiveBrowserEventFileMenuShow, ArchiveBrowserEventFileMenuClose, ArchiveBrowserEventEnterDir, From ba69ee88f3a15462249f451321775ba3577aaa05 Mon Sep 17 00:00:00 2001 From: Aleksandr Skoriy Date: Fri, 28 Oct 2022 08:05:31 +0300 Subject: [PATCH 2/5] Add limitation for file size to not crash --- .../main/archive/scenes/archive_scene_show.c | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/applications/main/archive/scenes/archive_scene_show.c b/applications/main/archive/scenes/archive_scene_show.c index 482585c1d4..a503f19b29 100644 --- a/applications/main/archive/scenes/archive_scene_show.c +++ b/applications/main/archive/scenes/archive_scene_show.c @@ -4,6 +4,8 @@ #define TAG "Archive" +#define SHOW_MAX_FILE_SIZE 20000 + void archive_scene_show_widget_callback(GuiButtonType result, InputType type, void* context) { furi_assert(context); ArchiveApp* app = (ArchiveApp*)context; @@ -29,14 +31,23 @@ void archive_scene_show_on_enter(void* context) { FileInfo fileinfo; storage_common_stat(fs_api, furi_string_get_cstr(current->path), &fileinfo); - storage_file_open(file, furi_string_get_cstr(current->path), FSAM_READ, FSOM_OPEN_EXISTING); - char* content = malloc(fileinfo.size + 1); + if (fileinfo.size < SHOW_MAX_FILE_SIZE) { + storage_file_open(file, furi_string_get_cstr(current->path), FSAM_READ, FSOM_OPEN_EXISTING); + char* content = malloc(fileinfo.size + 1); + + bytes_count = storage_file_read(file, content, fileinfo.size); + content[bytes_count + 1] = 0; - bytes_count = storage_file_read(file, content, fileinfo.size); - content[bytes_count + 1] = 0; + widget_add_text_scroll_element( + instance->widget, 0, 0, 128, 64, content); - widget_add_text_scroll_element( - instance->widget, 0, 0, 128, 64, content); + free(content); + storage_file_close(file); + } else { + widget_add_text_box_element( + instance->widget, 0, 0, 128, 64, AlignLeft, AlignCenter, + "\e#Error:\nFile is too large to show\e#", false); + } path_extract_filename(current->path, filename, false); @@ -44,8 +55,6 @@ void archive_scene_show_on_enter(void* context) { path_extract_filename_no_ext(furi_string_get_cstr(current->path), filename); strlcpy(instance->text_store, furi_string_get_cstr(filename), MAX_NAME_LEN); - free(content); - storage_file_close(file); storage_file_free(file); furi_string_free(filename); From 2fd8c71626612aa007ec8a31a0e42a3b06e5a3d1 Mon Sep 17 00:00:00 2001 From: Aleksandr Skoriy Date: Fri, 28 Oct 2022 08:24:09 +0300 Subject: [PATCH 3/5] fix missing furi_record_close --- applications/main/archive/scenes/archive_scene_show.c | 1 + 1 file changed, 1 insertion(+) diff --git a/applications/main/archive/scenes/archive_scene_show.c b/applications/main/archive/scenes/archive_scene_show.c index a503f19b29..99672b19ae 100644 --- a/applications/main/archive/scenes/archive_scene_show.c +++ b/applications/main/archive/scenes/archive_scene_show.c @@ -56,6 +56,7 @@ void archive_scene_show_on_enter(void* context) { strlcpy(instance->text_store, furi_string_get_cstr(filename), MAX_NAME_LEN); storage_file_free(file); + furi_record_close(RECORD_STORAGE); furi_string_free(filename); furi_string_free(str_size); From 9fae52166c91f05d253521ad9e84ac6a1dd5c662 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 28 Oct 2022 16:05:17 +0300 Subject: [PATCH 4/5] fixes and improvements --- .../main/archive/helpers/archive_files.c | 5 ++ .../main/archive/helpers/archive_files.h | 4 ++ .../main/archive/scenes/archive_scene_show.c | 68 +++++++++++++------ .../main/archive/views/archive_browser_view.c | 40 ++++++----- applications/main/subghz/subghz_history.c | 4 +- 5 files changed, 83 insertions(+), 38 deletions(-) diff --git a/applications/main/archive/helpers/archive_files.c b/applications/main/archive/helpers/archive_files.c index 1bf51a2b02..5c06c1bdad 100644 --- a/applications/main/archive/helpers/archive_files.c +++ b/applications/main/archive/helpers/archive_files.c @@ -32,6 +32,11 @@ void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder if(is_folder) { file->type = ArchiveFileTypeFolder; } else { + char tmp_extension[MAX_EXT_LEN]; + path_extract_extension(file->path, tmp_extension, MAX_EXT_LEN); + if((strcmp(tmp_extension, ".txt") == 0) || (strcmp(tmp_extension, ".md") == 0)) { + file->is_text_file = true; + } file->type = ArchiveFileTypeUnknown; } } diff --git a/applications/main/archive/helpers/archive_files.h b/applications/main/archive/helpers/archive_files.h index d7b25a64b5..d2cd93a667 100644 --- a/applications/main/archive/helpers/archive_files.h +++ b/applications/main/archive/helpers/archive_files.h @@ -29,6 +29,7 @@ typedef struct { FuriString* custom_name; bool fav; bool is_app; + bool is_text_file; } ArchiveFile_t; static void ArchiveFile_t_init(ArchiveFile_t* obj) { @@ -38,6 +39,7 @@ static void ArchiveFile_t_init(ArchiveFile_t* obj) { obj->custom_name = furi_string_alloc(); obj->fav = false; obj->is_app = false; + obj->is_text_file = false; } static void ArchiveFile_t_init_set(ArchiveFile_t* obj, const ArchiveFile_t* src) { @@ -52,6 +54,7 @@ static void ArchiveFile_t_init_set(ArchiveFile_t* obj, const ArchiveFile_t* src) obj->custom_name = furi_string_alloc_set(src->custom_name); obj->fav = src->fav; obj->is_app = src->is_app; + obj->is_text_file = src->is_text_file; } static void ArchiveFile_t_set(ArchiveFile_t* obj, const ArchiveFile_t* src) { @@ -66,6 +69,7 @@ static void ArchiveFile_t_set(ArchiveFile_t* obj, const ArchiveFile_t* src) { furi_string_set(obj->custom_name, src->custom_name); obj->fav = src->fav; obj->is_app = src->is_app; + obj->is_text_file = src->is_text_file; } static void ArchiveFile_t_clear(ArchiveFile_t* obj) { diff --git a/applications/main/archive/scenes/archive_scene_show.c b/applications/main/archive/scenes/archive_scene_show.c index 99672b19ae..d1a6e16006 100644 --- a/applications/main/archive/scenes/archive_scene_show.c +++ b/applications/main/archive/scenes/archive_scene_show.c @@ -19,9 +19,7 @@ void archive_scene_show_on_enter(void* context) { ArchiveApp* instance = context; FuriString* filename; - FuriString* str_size; filename = furi_string_alloc(); - str_size = furi_string_alloc(); ArchiveFile_t* current = archive_get_current_file(instance->browser); Storage* fs_api = furi_record_open(RECORD_STORAGE); @@ -29,26 +27,57 @@ void archive_scene_show_on_enter(void* context) { uint32_t bytes_count; FileInfo fileinfo; - storage_common_stat(fs_api, furi_string_get_cstr(current->path), &fileinfo); - - if (fileinfo.size < SHOW_MAX_FILE_SIZE) { - storage_file_open(file, furi_string_get_cstr(current->path), FSAM_READ, FSOM_OPEN_EXISTING); - char* content = malloc(fileinfo.size + 1); - - bytes_count = storage_file_read(file, content, fileinfo.size); - content[bytes_count + 1] = 0; - - widget_add_text_scroll_element( - instance->widget, 0, 0, 128, 64, content); - - free(content); - storage_file_close(file); + FS_Error error = storage_common_stat(fs_api, furi_string_get_cstr(current->path), &fileinfo); + if(error == FSE_OK) { + if(fileinfo.size < SHOW_MAX_FILE_SIZE) { + bool ok = storage_file_open( + file, furi_string_get_cstr(current->path), FSAM_READ, FSOM_OPEN_EXISTING); + if(ok) { + char* content = malloc(fileinfo.size + 1); + + bytes_count = storage_file_read(file, content, fileinfo.size); + content[bytes_count + 1] = 0; + + widget_add_text_scroll_element(instance->widget, 0, 0, 128, 64, content); + + free(content); + } else { + widget_add_text_box_element( + instance->widget, + 0, + 0, + 128, + 64, + AlignLeft, + AlignCenter, + "\e#Error:\nStorage file open error\e#", + false); + } + storage_file_close(file); + } else { + widget_add_text_box_element( + instance->widget, + 0, + 0, + 128, + 64, + AlignLeft, + AlignCenter, + "\e#Error:\nFile is too large to show\e#", + false); + } } else { widget_add_text_box_element( - instance->widget, 0, 0, 128, 64, AlignLeft, AlignCenter, - "\e#Error:\nFile is too large to show\e#", false); + instance->widget, + 0, + 0, + 128, + 64, + AlignLeft, + AlignCenter, + "\e#Error:\nFile system error\e#", + false); } - path_extract_filename(current->path, filename, false); // This one to return and cursor select this file @@ -59,7 +88,6 @@ void archive_scene_show_on_enter(void* context) { furi_record_close(RECORD_STORAGE); furi_string_free(filename); - furi_string_free(str_size); view_dispatcher_switch_to_view(instance->view_dispatcher, ArchiveViewWidget); } diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index b905a5a334..1dc87319b0 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -80,10 +80,12 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { menu_array_push_raw(model->context_menu), item_info, ArchiveBrowserEventFileMenuInfo); - archive_menu_add_item( - menu_array_push_raw(model->context_menu), - item_show, - ArchiveBrowserEventFileMenuShow); + if(selected->is_text_file) { + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_show, + ArchiveBrowserEventFileMenuShow); + } archive_menu_add_item( menu_array_push_raw(model->context_menu), item_rename, @@ -105,10 +107,12 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { menu_array_push_raw(model->context_menu), item_pin, ArchiveBrowserEventFileMenuPin); - archive_menu_add_item( - menu_array_push_raw(model->context_menu), - item_show, - ArchiveBrowserEventFileMenuShow); + if(selected->type <= ArchiveFileTypeBadUsb) { + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_show, + ArchiveBrowserEventFileMenuShow); + } archive_menu_add_item( menu_array_push_raw(model->context_menu), item_rename, @@ -123,10 +127,12 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { menu_array_push_raw(model->context_menu), item_info, ArchiveBrowserEventFileMenuInfo); - archive_menu_add_item( - menu_array_push_raw(model->context_menu), - item_show, - ArchiveBrowserEventFileMenuShow); + if(selected->type <= ArchiveFileTypeBadUsb) { + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_show, + ArchiveBrowserEventFileMenuShow); + } archive_menu_add_item( menu_array_push_raw(model->context_menu), item_pin, @@ -149,10 +155,12 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { menu_array_push_raw(model->context_menu), item_info, ArchiveBrowserEventFileMenuInfo); - archive_menu_add_item( - menu_array_push_raw(model->context_menu), - item_show, - ArchiveBrowserEventFileMenuShow); + if(selected->type <= ArchiveFileTypeBadUsb) { + archive_menu_add_item( + menu_array_push_raw(model->context_menu), + item_show, + ArchiveBrowserEventFileMenuShow); + } archive_menu_add_item( menu_array_push_raw(model->context_menu), item_rename, diff --git a/applications/main/subghz/subghz_history.c b/applications/main/subghz/subghz_history.c index 8925fe7fcf..ddd00a7e43 100644 --- a/applications/main/subghz/subghz_history.c +++ b/applications/main/subghz/subghz_history.c @@ -63,9 +63,9 @@ FuriString* subghz_history_generate_temp_filename(uint32_t index) { bool subghz_history_is_tmp_dir_exists(SubGhzHistory* instance) { FileInfo file_info; - storage_common_stat(instance->storage, SUBGHZ_HISTORY_TMP_DIR, &file_info); + FS_Error error = storage_common_stat(instance->storage, SUBGHZ_HISTORY_TMP_DIR, &file_info); - if(storage_common_stat(instance->storage, SUBGHZ_HISTORY_TMP_DIR, &file_info) == FSE_OK) { + if(error == FSE_OK) { if(file_info.flags & FSF_DIRECTORY) { return true; } From dcf076b11ea9cb460cb7de7dd93d92e3204661f0 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 28 Oct 2022 17:16:47 +0300 Subject: [PATCH 5/5] more checks and limits --- applications/main/archive/application.fam | 2 +- .../main/archive/scenes/archive_scene_show.c | 52 ++++++++++++++++--- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/applications/main/archive/application.fam b/applications/main/archive/application.fam index f0a980ab01..309cee8d5f 100644 --- a/applications/main/archive/application.fam +++ b/applications/main/archive/application.fam @@ -5,7 +5,7 @@ App( entry_point="archive_app", cdefines=["APP_ARCHIVE"], requires=["gui"], - stack_size=4 * 1024, + stack_size=6 * 1024, icon="A_FileManager_14", order=0, ) diff --git a/applications/main/archive/scenes/archive_scene_show.c b/applications/main/archive/scenes/archive_scene_show.c index d1a6e16006..416c10ded4 100644 --- a/applications/main/archive/scenes/archive_scene_show.c +++ b/applications/main/archive/scenes/archive_scene_show.c @@ -4,7 +4,7 @@ #define TAG "Archive" -#define SHOW_MAX_FILE_SIZE 20000 +#define SHOW_MAX_FILE_SIZE 5000 void archive_scene_show_widget_callback(GuiButtonType result, InputType type, void* context) { furi_assert(context); @@ -14,6 +14,22 @@ void archive_scene_show_widget_callback(GuiButtonType result, InputType type, vo } } +static bool text_show_read_lines(File* file, FuriString* str_result) { + //furi_string_reset(str_result); + uint8_t buffer[SHOW_MAX_FILE_SIZE]; + + uint16_t read_count = storage_file_read(file, buffer, SHOW_MAX_FILE_SIZE); + if(storage_file_get_error(file) != FSE_OK) { + return false; + } + + for(uint16_t i = 0; i < read_count; i++) { + furi_string_push_back(str_result, buffer[i]); + } + + return true; +} + void archive_scene_show_on_enter(void* context) { furi_assert(context); ArchiveApp* instance = context; @@ -21,27 +37,34 @@ void archive_scene_show_on_enter(void* context) { FuriString* filename; filename = furi_string_alloc(); + FuriString* buffer; + buffer = furi_string_alloc(); + ArchiveFile_t* current = archive_get_current_file(instance->browser); Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); - uint32_t bytes_count; FileInfo fileinfo; FS_Error error = storage_common_stat(fs_api, furi_string_get_cstr(current->path), &fileinfo); if(error == FSE_OK) { - if(fileinfo.size < SHOW_MAX_FILE_SIZE) { + if((fileinfo.size < SHOW_MAX_FILE_SIZE) && (fileinfo.size > 2)) { bool ok = storage_file_open( file, furi_string_get_cstr(current->path), FSAM_READ, FSOM_OPEN_EXISTING); if(ok) { - char* content = malloc(fileinfo.size + 1); + if(!text_show_read_lines(file, buffer)) { + goto text_file_read_err; + } + if(!furi_string_size(buffer)) { + goto text_file_read_err; + } - bytes_count = storage_file_read(file, content, fileinfo.size); - content[bytes_count + 1] = 0; + storage_file_seek(file, 0, true); - widget_add_text_scroll_element(instance->widget, 0, 0, 128, 64, content); + widget_add_text_scroll_element( + instance->widget, 0, 0, 128, 64, furi_string_get_cstr(buffer)); - free(content); } else { + text_file_read_err: widget_add_text_box_element( instance->widget, 0, @@ -54,6 +77,17 @@ void archive_scene_show_on_enter(void* context) { false); } storage_file_close(file); + } else if(fileinfo.size < 2) { + widget_add_text_box_element( + instance->widget, + 0, + 0, + 128, + 64, + AlignLeft, + AlignCenter, + "\e#Error:\nFile is too small\e#", + false); } else { widget_add_text_box_element( instance->widget, @@ -84,6 +118,8 @@ void archive_scene_show_on_enter(void* context) { path_extract_filename_no_ext(furi_string_get_cstr(current->path), filename); strlcpy(instance->text_store, furi_string_get_cstr(filename), MAX_NAME_LEN); + furi_string_free(buffer); + storage_file_free(file); furi_record_close(RECORD_STORAGE);