Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Browser: Context menu to show file content #139

Merged
merged 6 commits into from
Oct 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion applications/main/archive/application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
5 changes: 5 additions & 0 deletions applications/main/archive/helpers/archive_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
4 changes: 4 additions & 0 deletions applications/main/archive/helpers/archive_files.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down
7 changes: 7 additions & 0 deletions applications/main/archive/scenes/archive_scene_browser.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions applications/main/archive/scenes/archive_scene_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
147 changes: 147 additions & 0 deletions applications/main/archive/scenes/archive_scene_show.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
#include "../archive_i.h"
#include "../helpers/archive_browser.h"
#include <storage/storage.h>

#define TAG "Archive"

#define SHOW_MAX_FILE_SIZE 5000

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);
}
}

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;

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);

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) && (fileinfo.size > 2)) {
bool ok = storage_file_open(
file, furi_string_get_cstr(current->path), FSAM_READ, FSOM_OPEN_EXISTING);
if(ok) {
if(!text_show_read_lines(file, buffer)) {
goto text_file_read_err;
}
if(!furi_string_size(buffer)) {
goto text_file_read_err;
}

storage_file_seek(file, 0, true);

widget_add_text_scroll_element(
instance->widget, 0, 0, 128, 64, furi_string_get_cstr(buffer));

} else {
text_file_read_err:
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 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,
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 system error\e#",
false);
}
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);

furi_string_free(buffer);

storage_file_free(file);
furi_record_close(RECORD_STORAGE);

furi_string_free(filename);

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);
}
34 changes: 30 additions & 4 deletions applications/main/archive/views/archive_browser_view.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down Expand Up @@ -79,6 +80,12 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) {
menu_array_push_raw(model->context_menu),
item_info,
ArchiveBrowserEventFileMenuInfo);
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,
Expand All @@ -100,6 +107,12 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) {
menu_array_push_raw(model->context_menu),
item_pin,
ArchiveBrowserEventFileMenuPin);
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,
Expand All @@ -114,6 +127,12 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) {
menu_array_push_raw(model->context_menu),
item_info,
ArchiveBrowserEventFileMenuInfo);
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,
Expand All @@ -136,6 +155,12 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) {
menu_array_push_raw(model->context_menu),
item_info,
ArchiveBrowserEventFileMenuInfo);
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,
Expand All @@ -149,6 +174,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 {
Expand All @@ -160,9 +186,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,
Expand All @@ -172,10 +198,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) {
Expand Down
1 change: 1 addition & 0 deletions applications/main/archive/views/archive_browser_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ typedef enum {
ArchiveBrowserEventFileMenuRename,
ArchiveBrowserEventFileMenuDelete,
ArchiveBrowserEventFileMenuInfo,
ArchiveBrowserEventFileMenuShow,
ArchiveBrowserEventFileMenuClose,

ArchiveBrowserEventEnterDir,
Expand Down
4 changes: 2 additions & 2 deletions applications/main/subghz/subghz_history.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down