diff --git a/applications/main/archive/archive.c b/applications/main/archive/archive.c index 588087fd2..5b7638152 100644 --- a/applications/main/archive/archive.c +++ b/applications/main/archive/archive.c @@ -22,6 +22,7 @@ static ArchiveApp* archive_alloc() { ArchiveApp* archive = malloc(sizeof(ArchiveApp)); archive->fav_move_str = furi_string_alloc(); + archive->file_extension = furi_string_alloc(); archive->scene_manager = scene_manager_alloc(&archive_scene_handlers, archive); archive->view_dispatcher = view_dispatcher_alloc(); @@ -82,6 +83,7 @@ void archive_free(ArchiveApp* archive) { browser_free(archive->browser); furi_string_free(archive->fav_move_str); + furi_string_free(archive->file_extension); furi_record_close(RECORD_DIALOGS); archive->dialogs = NULL; diff --git a/applications/main/archive/archive_i.h b/applications/main/archive/archive_i.h index b96145827..bd683c22d 100644 --- a/applications/main/archive/archive_i.h +++ b/applications/main/archive/archive_i.h @@ -38,7 +38,7 @@ struct ArchiveApp { FuriString* fav_move_str; char text_store[MAX_NAME_LEN]; - char file_extension[MAX_EXT_LEN + 1]; + FuriString* file_extension; }; -void archive_show_loading_popup(ArchiveApp* context, bool show); \ No newline at end of file +void archive_show_loading_popup(ArchiveApp* context, bool show); diff --git a/applications/main/archive/helpers/archive_files.c b/applications/main/archive/helpers/archive_files.c index 8865262fb..e1083ecd4 100644 --- a/applications/main/archive/helpers/archive_files.c +++ b/applications/main/archive/helpers/archive_files.c @@ -138,24 +138,26 @@ FS_Error archive_copy_rename_file_or_dir( if(find_name && storage_common_exists(fs_api, dst_path)) { FuriString* dir_path = furi_string_alloc(); FuriString* filename = furi_string_alloc(); - char extension[MAX_EXT_LEN] = {0}; + FuriString* file_ext = furi_string_alloc(); - path_extract_filename(dst_str, filename, true); path_extract_dirname(furi_string_get_cstr(dst_str), dir_path); - path_extract_extension(dst_str, extension, MAX_EXT_LEN); + path_extract_filename(dst_str, filename, true); + path_extract_ext_str(dst_str, file_ext); storage_get_next_filename( fs_api, furi_string_get_cstr(dir_path), furi_string_get_cstr(filename), - extension, + furi_string_get_cstr(file_ext), dst_str, 255); - furi_string_cat_printf(dir_path, "/%s%s", furi_string_get_cstr(dst_str), extension); + furi_string_cat_printf( + dir_path, "/%s%s", furi_string_get_cstr(dst_str), furi_string_get_cstr(file_ext)); furi_string_set(dst_str, dir_path); furi_string_free(dir_path); furi_string_free(filename); + furi_string_free(file_ext); } if(copy) { diff --git a/applications/main/archive/scenes/archive_scene_rename.c b/applications/main/archive/scenes/archive_scene_rename.c index 850cde349..8401ce1c2 100644 --- a/applications/main/archive/scenes/archive_scene_rename.c +++ b/applications/main/archive/scenes/archive_scene_rename.c @@ -25,25 +25,19 @@ void archive_scene_rename_on_enter(void* context) { FuriString* path_name = furi_string_alloc(); FuriString* path_folder = furi_string_alloc(); - if(current->type == ArchiveFileTypeFolder) { - // Set file ext to empty since we need to see folder name here - strcpy(archive->file_extension, ""); - // Extract folder name and copy into text_store + ArchiveTabEnum tab = archive_get_tab(archive->browser); + bool hide_ext = tab != ArchiveTabBrowser && tab != ArchiveTabInternal; + + if(current->type == ArchiveFileTypeFolder || !hide_ext) { + furi_string_reset(archive->file_extension); path_extract_basename(furi_string_get_cstr(current->path), path_name); - strlcpy(archive->text_store, furi_string_get_cstr(path_name), MAX_NAME_LEN); - text_input_set_header_text(text_input, "Rename directory:"); - } else /*if(current->type != ArchiveFileTypeUnknown) */ { - // Extract file name and copy into text_store + } else { + path_extract_ext_str(current->path, archive->file_extension); path_extract_filename(current->path, path_name, true); - strlcpy(archive->text_store, furi_string_get_cstr(path_name), MAX_NAME_LEN); - // Extract file extension for validator and rename func - path_extract_extension(current->path, archive->file_extension, MAX_EXT_LEN); - text_input_set_header_text(text_input, "Rename file:"); - } /*else { - path_extract_filename(current->path, path_name, false); - strlcpy(archive->text_store, furi_string_get_cstr(path_name), MAX_NAME_LEN); - text_input_set_header_text(text_input, "Rename unknown file:"); - }*/ + } + strlcpy(archive->text_store, furi_string_get_cstr(path_name), MAX_NAME_LEN); + text_input_set_header_text( + text_input, current->type == ArchiveFileTypeFolder ? "Rename directory:" : "Rename file:"); // Get current folder (for file) or previous folder (for folder) for validator path_extract_dirname(furi_string_get_cstr(current->path), path_folder); @@ -58,7 +52,9 @@ void archive_scene_rename_on_enter(void* context) { // Init validator to show message to user that name already exist ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - furi_string_get_cstr(path_folder), archive->file_extension, archive->text_store); + furi_string_get_cstr(path_folder), + furi_string_get_cstr(archive->file_extension), + archive->text_store); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); furi_string_free(path_name); @@ -74,27 +70,18 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == SCENE_RENAME_CUSTOM_EVENT) { const char* path_src = archive_get_name(archive->browser); - ArchiveFile_t* file = archive_get_current_file(archive->browser); FuriString* path_dst; path_dst = furi_string_alloc(); - if(file->type == ArchiveFileTypeFolder) { - // Rename folder/dir - path_extract_dirname(path_src, path_dst); - furi_string_cat_printf(path_dst, "/%s", archive->text_store); - } else if(file->type != ArchiveFileTypeUnknown) { - // Rename known type - path_extract_dirname(path_src, path_dst); - furi_string_cat_printf( - path_dst, "/%s%s", archive->text_store, known_ext[file->type]); - } else { - // Rename unknown type - path_extract_dirname(path_src, path_dst); - furi_string_cat_printf( - path_dst, "/%s%s", archive->text_store, archive->file_extension); - } + path_extract_dirname(path_src, path_dst); + furi_string_cat_printf( + path_dst, + "/%s%s", + archive->text_store, + furi_string_get_cstr(archive->file_extension)); + // Long time process if this is directory view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewStack); archive_show_loading_popup(archive, true); diff --git a/applications/main/archive/views/archive_browser_view.h b/applications/main/archive/views/archive_browser_view.h index ed18df387..7d8eef65c 100644 --- a/applications/main/archive/views/archive_browser_view.h +++ b/applications/main/archive/views/archive_browser_view.h @@ -16,7 +16,6 @@ #define MAX_LEN_PX 110 #define MAX_NAME_LEN 255 -#define MAX_EXT_LEN 6 #define FRAME_HEIGHT 12 #define MENU_ITEMS 5u #define MOVE_OFFSET 5u diff --git a/applications/services/storage/storage_external_api.c b/applications/services/storage/storage_external_api.c index bfedb3e1e..38ff80252 100644 --- a/applications/services/storage/storage_external_api.c +++ b/applications/services/storage/storage_external_api.c @@ -8,7 +8,6 @@ #include "toolbox/path.h" #define MAX_NAME_LENGTH 256 -#define MAX_EXT_LEN 16 #define FILE_BUFFER_SIZE 512 #define TAG "StorageAPI" @@ -666,30 +665,31 @@ FS_Error storage_common_merge(Storage* storage, const char* old_path, const char error = storage_common_stat(storage, new_path, &fileinfo); if(error == FSE_OK) { furi_string_set(new_path_next, new_path); - FuriString* dir_path; - FuriString* filename; - char extension[MAX_EXT_LEN] = {0}; - - dir_path = furi_string_alloc(); - filename = furi_string_alloc(); + FuriString* dir_path = furi_string_alloc(); + FuriString* filename = furi_string_alloc(); + FuriString* file_ext = furi_string_alloc(); path_extract_filename(new_path_next, filename, true); path_extract_dirname(new_path, dir_path); - path_extract_extension(new_path_next, extension, MAX_EXT_LEN); + path_extract_ext_str(new_path_next, file_ext); storage_get_next_filename( storage, furi_string_get_cstr(dir_path), furi_string_get_cstr(filename), - extension, + furi_string_get_cstr(file_ext), new_path_next, 255); furi_string_cat_printf( - dir_path, "/%s%s", furi_string_get_cstr(new_path_next), extension); + dir_path, + "/%s%s", + furi_string_get_cstr(new_path_next), + furi_string_get_cstr(file_ext)); furi_string_set(new_path_next, dir_path); furi_string_free(dir_path); furi_string_free(filename); + furi_string_free(file_ext); new_path_tmp = furi_string_get_cstr(new_path_next); } else { new_path_tmp = new_path; diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 23fe7ac3c..d44f72d8e 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -2233,6 +2233,7 @@ Function,+,path_concat,void,"const char*, const char*, FuriString*" Function,+,path_contains_only_ascii,_Bool,const char* Function,+,path_extract_basename,void,"const char*, FuriString*" Function,+,path_extract_dirname,void,"const char*, FuriString*" +Function,+,path_extract_ext_str,void,"FuriString*, FuriString*" Function,+,path_extract_extension,void,"FuriString*, char*, size_t" Function,+,path_extract_filename,void,"FuriString*, FuriString*, _Bool" Function,+,path_extract_filename_no_ext,void,"const char*, FuriString*" diff --git a/lib/toolbox/path.c b/lib/toolbox/path.c index 3d161a196..78a9ea8e9 100644 --- a/lib/toolbox/path.c +++ b/lib/toolbox/path.c @@ -34,6 +34,18 @@ void path_extract_filename(FuriString* path, FuriString* name, bool trim_ext) { } } +void path_extract_ext_str(FuriString* path, FuriString* ext) { + size_t dot = furi_string_search_rchar(path, '.'); + size_t filename_start = furi_string_search_rchar(path, '/'); + + if(dot != FURI_STRING_FAILURE && filename_start != FURI_STRING_FAILURE && + filename_start < dot) { + furi_string_set_n(ext, path, dot, furi_string_size(path) - dot); + } else { + furi_string_reset(ext); + } +} + void path_extract_extension(FuriString* path, char* ext, size_t ext_len_max) { size_t dot = furi_string_search_rchar(path, '.'); size_t filename_start = furi_string_search_rchar(path, '/'); diff --git a/lib/toolbox/path.h b/lib/toolbox/path.h index e6145b715..6296cfb3f 100644 --- a/lib/toolbox/path.h +++ b/lib/toolbox/path.h @@ -22,6 +22,14 @@ void path_extract_filename_no_ext(const char* path, FuriString* filename); */ void path_extract_filename(FuriString* path, FuriString* filename, bool trim_ext); +/** + * @brief Extract file extension string from path. + * + * @param path path string + * @param ext output extension furi string + */ +void path_extract_ext_str(FuriString* path, FuriString* ext); + /** * @brief Extract file extension from path. *