diff --git a/applications/bad_usb/bad_usb_app.c b/applications/bad_usb/bad_usb_app.c index 65ccc575b..eb647e004 100644 --- a/applications/bad_usb/bad_usb_app.c +++ b/applications/bad_usb/bad_usb_app.c @@ -1,5 +1,4 @@ #include "bad_usb_app_i.h" -#include "m-string.h" #include #include #include @@ -23,13 +22,33 @@ static void bad_usb_app_tick_event_callback(void* context) { scene_manager_handle_tick_event(app->scene_manager); } +static bool bad_usb_check_assets() { + Storage* fs_api = furi_record_open("storage"); + + File* dir = storage_file_alloc(fs_api); + bool ret = false; + + if(storage_dir_open(dir, BAD_USB_APP_PATH_FOLDER)) { + ret = true; + } + + storage_dir_close(dir); + storage_file_free(dir); + + furi_record_close("storage"); + + return ret; +} + BadUsbApp* bad_usb_app_alloc(char* arg) { BadUsbApp* app = malloc(sizeof(BadUsbApp)); - string_init(app->file_path); - if(arg != NULL) { - string_set_str(app->file_path, arg); + string_t filename; + string_init(filename); + path_extract_filename_no_ext(arg, filename); + strncpy(app->file_name, string_get_cstr(filename), BAD_USB_FILE_NAME_LEN); + string_clear(filename); } app->gui = furi_record_open("gui"); @@ -64,11 +83,13 @@ BadUsbApp* bad_usb_app_alloc(char* arg) { app->error = BadUsbAppErrorCloseRpc; scene_manager_next_scene(app->scene_manager, BadUsbSceneError); } else { - if(!string_empty_p(app->file_path)) { + if(*app->file_name != '\0') { scene_manager_next_scene(app->scene_manager, BadUsbSceneWork); - } else { - string_set_str(app->file_path, BAD_USB_APP_PATH_FOLDER); + } else if(bad_usb_check_assets()) { scene_manager_next_scene(app->scene_manager, BadUsbSceneFileSelect); + } else { + app->error = BadUsbAppErrorNoFiles; + scene_manager_next_scene(app->scene_manager, BadUsbSceneError); } } @@ -96,8 +117,6 @@ void bad_usb_app_free(BadUsbApp* app) { furi_record_close("notification"); furi_record_close("dialogs"); - string_clear(app->file_path); - free(app); } diff --git a/applications/bad_usb/bad_usb_app_i.h b/applications/bad_usb/bad_usb_app_i.h index c82419e0f..67f5816b8 100644 --- a/applications/bad_usb/bad_usb_app_i.h +++ b/applications/bad_usb/bad_usb_app_i.h @@ -16,6 +16,7 @@ #define BAD_USB_APP_PATH_FOLDER "/any/badusb" #define BAD_USB_APP_EXTENSION ".txt" +#define BAD_USB_FILE_NAME_LEN 40 typedef enum { BadUsbAppErrorNoFiles, @@ -31,7 +32,7 @@ struct BadUsbApp { Widget* widget; BadUsbAppError error; - string_t file_path; + char file_name[BAD_USB_FILE_NAME_LEN + 1]; BadUsb* bad_usb_view; BadUsbScript* bad_usb_script; }; diff --git a/applications/bad_usb/scenes/bad_usb_scene_file_select.c b/applications/bad_usb/scenes/bad_usb_scene_file_select.c index 1e6ba895a..82f03bab0 100644 --- a/applications/bad_usb/scenes/bad_usb_scene_file_select.c +++ b/applications/bad_usb/scenes/bad_usb_scene_file_select.c @@ -5,16 +5,14 @@ static bool bad_usb_file_select(BadUsbApp* bad_usb) { furi_assert(bad_usb); - // Input events and views are managed by file_browser - bool res = dialog_file_browser_show( + // Input events and views are managed by file_select + bool res = dialog_file_select_show( bad_usb->dialogs, - bad_usb->file_path, - bad_usb->file_path, + BAD_USB_APP_PATH_FOLDER, BAD_USB_APP_EXTENSION, - true, - &I_badusb_10px, - true); - + bad_usb->file_name, + sizeof(bad_usb->file_name), + NULL); return res; } diff --git a/applications/bad_usb/scenes/bad_usb_scene_work.c b/applications/bad_usb/scenes/bad_usb_scene_work.c index 516cbde3a..a3a46803a 100644 --- a/applications/bad_usb/scenes/bad_usb_scene_work.c +++ b/applications/bad_usb/scenes/bad_usb_scene_work.c @@ -2,8 +2,6 @@ #include "../bad_usb_app_i.h" #include "../views/bad_usb_view.h" #include "furi_hal.h" -#include "m-string.h" -#include "toolbox/path.h" void bad_usb_scene_work_ok_callback(InputType type, void* context) { furi_assert(context); @@ -30,9 +28,10 @@ void bad_usb_scene_work_on_enter(void* context) { string_t file_name; string_init(file_name); - path_extract_filename(app->file_path, file_name, true); - bad_usb_set_file_name(app->bad_usb_view, string_get_cstr(file_name)); - app->bad_usb_script = bad_usb_script_open(app->file_path); + bad_usb_set_file_name(app->bad_usb_view, app->file_name); + string_printf( + file_name, "%s/%s%s", BAD_USB_APP_PATH_FOLDER, app->file_name, BAD_USB_APP_EXTENSION); + app->bad_usb_script = bad_usb_script_open(file_name); string_clear(file_name); diff --git a/applications/bad_usb/views/bad_usb_view.c b/applications/bad_usb/views/bad_usb_view.c index 430885df3..5b6fe6e89 100644 --- a/applications/bad_usb/views/bad_usb_view.c +++ b/applications/bad_usb/views/bad_usb_view.c @@ -2,8 +2,6 @@ #include "../bad_usb_script.h" #include -#define MAX_NAME_LEN 64 - struct BadUsb { View* view; BadUsbOkCallback callback; @@ -11,7 +9,7 @@ struct BadUsb { }; typedef struct { - char file_name[MAX_NAME_LEN]; + char* file_name; BadUsbState state; uint8_t anim_frame; } BadUsbModel; @@ -151,11 +149,11 @@ void bad_usb_set_ok_callback(BadUsb* bad_usb, BadUsbOkCallback callback, void* c }); } -void bad_usb_set_file_name(BadUsb* bad_usb, const char* name) { +void bad_usb_set_file_name(BadUsb* bad_usb, char* name) { furi_assert(name); with_view_model( bad_usb->view, (BadUsbModel * model) { - strncpy(model->file_name, name, MAX_NAME_LEN); + model->file_name = name; return true; }); } diff --git a/applications/bad_usb/views/bad_usb_view.h b/applications/bad_usb/views/bad_usb_view.h index 80a47e2ca..f5a8a0fab 100755 --- a/applications/bad_usb/views/bad_usb_view.h +++ b/applications/bad_usb/views/bad_usb_view.h @@ -14,6 +14,6 @@ View* bad_usb_get_view(BadUsb* bad_usb); void bad_usb_set_ok_callback(BadUsb* bad_usb, BadUsbOkCallback callback, void* context); -void bad_usb_set_file_name(BadUsb* bad_usb, const char* name); +void bad_usb_set_file_name(BadUsb* bad_usb, char* name); void bad_usb_set_state(BadUsb* bad_usb, BadUsbState* st); diff --git a/applications/debug_tools/file_browser_test/file_browser_app.c b/applications/debug_tools/file_browser_test/file_browser_app.c index c9b63ecb0..a408f5cde 100644 --- a/applications/debug_tools/file_browser_test/file_browser_app.c +++ b/applications/debug_tools/file_browser_test/file_browser_app.c @@ -48,7 +48,7 @@ FileBrowserApp* file_browser_app_alloc(char* arg) { app->widget = widget_alloc(); string_init(app->file_path); - app->file_browser = file_browser_alloc(app->file_path); + app->file_browser = file_browser_alloc(&(app->file_path)); file_browser_configure(app->file_browser, "*", true, &I_badusb_10px, true); view_dispatcher_add_view( diff --git a/applications/debug_tools/file_browser_test/scenes/file_browser_scene_browser.c b/applications/debug_tools/file_browser_test/scenes/file_browser_scene_browser.c index ca16ad0d1..9c570cec0 100644 --- a/applications/debug_tools/file_browser_test/scenes/file_browser_scene_browser.c +++ b/applications/debug_tools/file_browser_test/scenes/file_browser_scene_browser.c @@ -20,10 +20,12 @@ bool file_browser_scene_browser_on_event(void* context, SceneManagerEvent event) return consumed; } -static void file_browser_callback(void* context) { +static void file_browser_callback(void* context, bool state) { FileBrowserApp* app = context; furi_assert(app); view_dispatcher_send_custom_event(app->view_dispatcher, SceneManagerEventTypeCustom); + + UNUSED(state); } void file_browser_scene_browser_on_enter(void* context) { diff --git a/applications/desktop/desktop.c b/applications/desktop/desktop.c index 34c169e07..514166375 100644 --- a/applications/desktop/desktop.c +++ b/applications/desktop/desktop.c @@ -56,7 +56,12 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) { return true; case DesktopGlobalAutoLock: if(!loader_is_locked(desktop->loader)) { - desktop_lock(desktop); + if(desktop->settings.pin_code.length > 0) { + desktop_pin_lock(&desktop->settings); + desktop_lock(desktop); + } else { + desktop_lock(desktop); + } } return true; } diff --git a/applications/dialogs/dialogs.c b/applications/dialogs/dialogs.c index 8929dc116..cf4a2ad68 100644 --- a/applications/dialogs/dialogs.c +++ b/applications/dialogs/dialogs.c @@ -1,7 +1,6 @@ -#include "dialogs/dialogs_message.h" #include "dialogs_i.h" #include "dialogs_api_lock.h" -#include "dialogs_module_file_browser.h" +#include "dialogs_module_file_select.h" #include "dialogs_module_message.h" static DialogsApp* dialogs_app_alloc() { @@ -14,9 +13,9 @@ static DialogsApp* dialogs_app_alloc() { static void dialogs_app_process_message(DialogsApp* app, DialogsAppMessage* message) { UNUSED(app); switch(message->command) { - case DialogsAppCommandFileBrowser: + case DialogsAppCommandFileOpen: message->return_data->bool_value = - dialogs_app_process_module_file_browser(&message->data->file_browser); + dialogs_app_process_module_file_select(&message->data->file_select); break; case DialogsAppCommandDialog: message->return_data->dialog_value = diff --git a/applications/dialogs/dialogs.h b/applications/dialogs/dialogs.h index 536060565..9c71c0989 100644 --- a/applications/dialogs/dialogs.h +++ b/applications/dialogs/dialogs.h @@ -1,7 +1,6 @@ #pragma once #include #include -#include "m-string.h" #ifdef __cplusplus extern "C" { @@ -11,27 +10,25 @@ extern "C" { typedef struct DialogsApp DialogsApp; -/****************** FILE BROWSER ******************/ +/****************** FILE SELECT ******************/ /** - * Shows and processes the file browser dialog + * Shows and processes the file selection dialog * @param context api pointer - * @param result_path selected file path string pointer - * @param path preselected file path string pointer + * @param path path to directory * @param extension file extension to be offered for selection - * @param skip_assets true - do not show assets folders - * @param icon file icon pointer, NULL for default icon - * @param hide_ext true - hide extensions for files + * @param selected_filename buffer where the selected filename will be saved + * @param selected_filename_size and the size of this buffer + * @param preselected_filename filename to be preselected * @return bool whether a file was selected */ -bool dialog_file_browser_show( +bool dialog_file_select_show( DialogsApp* context, - string_ptr result_path, - string_ptr path, + const char* path, const char* extension, - bool skip_assets, - const Icon* icon, - bool hide_ext); + char* result, + uint8_t result_size, + const char* preselected_filename); /****************** MESSAGE ******************/ diff --git a/applications/dialogs/dialogs_api.c b/applications/dialogs/dialogs_api.c index fab3a5eae..c4efb287d 100644 --- a/applications/dialogs/dialogs_api.c +++ b/applications/dialogs/dialogs_api.c @@ -1,36 +1,31 @@ -#include "dialogs/dialogs_message.h" #include "dialogs_i.h" #include "dialogs_api_lock.h" -#include "m-string.h" -/****************** File browser ******************/ +/****************** File select ******************/ -bool dialog_file_browser_show( +bool dialog_file_select_show( DialogsApp* context, - string_ptr result_path, - string_ptr path, + const char* path, const char* extension, - bool skip_assets, - const Icon* icon, - bool hide_ext) { + char* result, + uint8_t result_size, + const char* preselected_filename) { FuriApiLock lock = API_LOCK_INIT_LOCKED(); furi_check(lock != NULL); DialogsAppData data = { - .file_browser = { + .file_select = { + .path = path, .extension = extension, - .result_path = result_path, - .file_icon = icon, - .hide_ext = hide_ext, - .skip_assets = skip_assets, - .preselected_filename = path, - + .result = result, + .result_size = result_size, + .preselected_filename = preselected_filename, }}; DialogsAppReturn return_data; DialogsAppMessage message = { .lock = lock, - .command = DialogsAppCommandFileBrowser, + .command = DialogsAppCommandFileOpen, .data = &data, .return_data = &return_data, }; diff --git a/applications/dialogs/dialogs_message.h b/applications/dialogs/dialogs_message.h index ccfbdece5..d7b5fabf4 100644 --- a/applications/dialogs/dialogs_message.h +++ b/applications/dialogs/dialogs_message.h @@ -2,27 +2,25 @@ #include #include "dialogs_i.h" #include "dialogs_api_lock.h" -#include "m-string.h" #ifdef __cplusplus extern "C" { #endif typedef struct { + const char* path; const char* extension; - bool skip_assets; - bool hide_ext; - const Icon* file_icon; - string_ptr result_path; - string_ptr preselected_filename; -} DialogsAppMessageDataFileBrowser; + char* result; + uint8_t result_size; + const char* preselected_filename; +} DialogsAppMessageDataFileSelect; typedef struct { const DialogMessage* message; } DialogsAppMessageDataDialog; typedef union { - DialogsAppMessageDataFileBrowser file_browser; + DialogsAppMessageDataFileSelect file_select; DialogsAppMessageDataDialog dialog; } DialogsAppData; @@ -32,7 +30,7 @@ typedef union { } DialogsAppReturn; typedef enum { - DialogsAppCommandFileBrowser, + DialogsAppCommandFileOpen, DialogsAppCommandDialog, } DialogsAppCommand; diff --git a/applications/dialogs/dialogs_module_file_browser.c b/applications/dialogs/dialogs_module_file_browser.c deleted file mode 100644 index ecd0ca79b..000000000 --- a/applications/dialogs/dialogs_module_file_browser.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "dialogs_i.h" -#include "dialogs_api_lock.h" -#include "gui/modules/file_browser.h" - -typedef struct { - FuriApiLock lock; - bool result; -} DialogsAppFileBrowserContext; - -static void dialogs_app_file_browser_back_callback(void* context) { - furi_assert(context); - DialogsAppFileBrowserContext* file_browser_context = context; - file_browser_context->result = false; - API_LOCK_UNLOCK(file_browser_context->lock); -} - -static void dialogs_app_file_browser_callback(void* context) { - furi_assert(context); - DialogsAppFileBrowserContext* file_browser_context = context; - file_browser_context->result = true; - API_LOCK_UNLOCK(file_browser_context->lock); -} - -bool dialogs_app_process_module_file_browser(const DialogsAppMessageDataFileBrowser* data) { - bool ret = false; - Gui* gui = furi_record_open("gui"); - - DialogsAppFileBrowserContext* file_browser_context = - malloc(sizeof(DialogsAppFileBrowserContext)); - file_browser_context->lock = API_LOCK_INIT_LOCKED(); - - ViewHolder* view_holder = view_holder_alloc(); - view_holder_attach_to_gui(view_holder, gui); - view_holder_set_back_callback( - view_holder, dialogs_app_file_browser_back_callback, file_browser_context); - - FileBrowser* file_browser = file_browser_alloc(data->result_path); - file_browser_set_callback( - file_browser, dialogs_app_file_browser_callback, file_browser_context); - file_browser_configure( - file_browser, data->extension, data->skip_assets, data->file_icon, data->hide_ext); - file_browser_start(file_browser, data->preselected_filename); - - view_holder_set_view(view_holder, file_browser_get_view(file_browser)); - view_holder_start(view_holder); - API_LOCK_WAIT_UNTIL_UNLOCK(file_browser_context->lock); - - ret = file_browser_context->result; - - view_holder_stop(view_holder); - view_holder_free(view_holder); - file_browser_stop(file_browser); - file_browser_free(file_browser); - API_LOCK_FREE(file_browser_context->lock); - free(file_browser_context); - furi_record_close("gui"); - - return ret; -} diff --git a/applications/dialogs/dialogs_module_file_browser.h b/applications/dialogs/dialogs_module_file_browser.h deleted file mode 100644 index b6cbdf6a5..000000000 --- a/applications/dialogs/dialogs_module_file_browser.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "dialogs_message.h" - -#ifdef __cplusplus -extern "C" { -#endif - -bool dialogs_app_process_module_file_browser(const DialogsAppMessageDataFileBrowser* data); - -#ifdef __cplusplus -} -#endif diff --git a/applications/gui/modules/file_browser.c b/applications/gui/modules/file_browser.c index 1cef1d079..919750962 100644 --- a/applications/gui/modules/file_browser.c +++ b/applications/gui/modules/file_browser.c @@ -10,7 +10,6 @@ #include #include #include -#include "toolbox/path.h" #define LIST_ITEMS 5u #define MAX_LEN_PX 110 @@ -61,13 +60,13 @@ ARRAY_DEF( struct FileBrowser { View* view; BrowserWorker* worker; - const char* ext_filter; + char* ext_filter; bool skip_assets; FileBrowserCallback callback; void* context; - string_ptr result_path; + string_t* result_path; }; typedef struct { @@ -101,7 +100,7 @@ static void browser_list_load_cb(void* context, uint32_t list_load_offset); static void browser_list_item_cb(void* context, string_t item_path, bool is_folder, bool is_last); static void browser_long_load_cb(void* context); -FileBrowser* file_browser_alloc(string_ptr result_path) { +FileBrowser* file_browser_alloc(string_t* result_path) { furi_assert(result_path); FileBrowser* browser = malloc(sizeof(FileBrowser)); browser->view = view_alloc(); @@ -141,7 +140,7 @@ View* file_browser_get_view(FileBrowser* browser) { void file_browser_configure( FileBrowser* browser, - const char* extension, + char* extension, bool skip_assets, const Icon* file_icon, bool hide_ext) { @@ -251,7 +250,6 @@ static void with_view_model( browser->view, (FileBrowserModel * model) { - items_array_reset(model->items); if(is_root) { model->item_cnt = item_cnt; model->item_idx = (file_idx > 0) ? file_idx : 0; @@ -385,7 +383,7 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { BrowserItem_t* item = items_array_get( model->items, CLAMP(idx - model->array_offset, (int32_t)(array_size - 1), 0)); item_type = item->type; - path_extract_filename( + file_browser_worker_get_filename( item->path, filename, (model->hide_ext) && (item_type == BrowserItemTypeFile)); } else { string_set_str(filename, "---"); @@ -507,9 +505,9 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { file_browser_worker_folder_enter( browser->worker, selected_item->path, select_index); } else if(selected_item->type == BrowserItemTypeFile) { - string_set(browser->result_path, selected_item->path); + string_set(*(browser->result_path), selected_item->path); if(browser->callback) { - browser->callback(browser->context); + browser->callback(browser->context, true); } } } diff --git a/applications/gui/modules/file_browser.h b/applications/gui/modules/file_browser.h index ebc64509a..b77c6e65c 100644 --- a/applications/gui/modules/file_browser.h +++ b/applications/gui/modules/file_browser.h @@ -13,9 +13,9 @@ extern "C" { #endif typedef struct FileBrowser FileBrowser; -typedef void (*FileBrowserCallback)(void* context); +typedef void (*FileBrowserCallback)(void* context, bool state); -FileBrowser* file_browser_alloc(string_ptr result_path); +FileBrowser* file_browser_alloc(string_t* result_path); void file_browser_free(FileBrowser* browser); @@ -23,7 +23,7 @@ View* file_browser_get_view(FileBrowser* browser); void file_browser_configure( FileBrowser* browser, - const char* extension, + char* extension, bool skip_assets, const Icon* file_icon, bool hide_ext); diff --git a/applications/gui/modules/file_browser_worker.c b/applications/gui/modules/file_browser_worker.c index 93baba008..13fc97111 100644 --- a/applications/gui/modules/file_browser_worker.c +++ b/applications/gui/modules/file_browser_worker.c @@ -8,7 +8,6 @@ #include #include #include -#include "toolbox/path.h" #define TAG "BrowserWorker" @@ -150,7 +149,6 @@ static bool browser_folder_init( (*item_cnt)++; } if(total_files_cnt == LONG_LOAD_THRESHOLD) { - // There are too many files in folder and counting them will take some time - send callback to app if(browser->long_load_cb) { browser->long_load_cb(browser->cb_ctx); } @@ -257,7 +255,7 @@ static int32_t browser_worker(void* context) { string_t filename; string_init(filename); if(browser_path_is_file(browser->path_next)) { - path_extract_filename(browser->path_next, filename, false); + file_browser_worker_get_filename(browser->path_next, filename, false); } osThreadFlagsSet(furi_thread_get_thread_id(browser->thread), WorkerEvtFolderEnter); @@ -321,7 +319,21 @@ static int32_t browser_worker(void* context) { return 0; } -BrowserWorker* file_browser_worker_alloc(string_t path, const char* filter_ext, bool skip_assets) { +void file_browser_worker_get_filename(string_t path, string_t name, bool trim_ext) { + size_t filename_start = string_search_rchar(path, '/'); + if(filename_start > 0) { + filename_start++; + string_set_n(name, path, filename_start, string_size(path) - filename_start); + } + if(trim_ext) { + size_t dot = string_search_rchar(name, '.'); + if(dot > 0) { + string_left(name, dot); + } + } +} + +BrowserWorker* file_browser_worker_alloc(string_t path, char* filter_ext, bool skip_assets) { BrowserWorker* browser = malloc(sizeof(BrowserWorker)); idx_last_array_init(browser->idx_last); diff --git a/applications/gui/modules/file_browser_worker.h b/applications/gui/modules/file_browser_worker.h index b0d360a38..821d5103f 100644 --- a/applications/gui/modules/file_browser_worker.h +++ b/applications/gui/modules/file_browser_worker.h @@ -22,7 +22,9 @@ typedef void (*BrowserWorkerListItemCallback)( bool is_last); typedef void (*BrowserWorkerLongLoadCallback)(void* context); -BrowserWorker* file_browser_worker_alloc(string_t path, const char* filter_ext, bool skip_assets); +void file_browser_worker_get_filename(string_t path, string_t name, bool trim_ext); + +BrowserWorker* file_browser_worker_alloc(string_t path, char* filter_ext, bool skip_assets); void file_browser_worker_free(BrowserWorker* browser); diff --git a/applications/gui/modules/validators.c b/applications/gui/modules/validators.c index 546423d02..242dbe682 100644 --- a/applications/gui/modules/validators.c +++ b/applications/gui/modules/validators.c @@ -3,7 +3,7 @@ #include "applications/storage/storage.h" struct ValidatorIsFile { - char* app_path_folder; + const char* app_path_folder; const char* app_extension; char* current_name; }; @@ -40,7 +40,7 @@ ValidatorIsFile* validator_is_file_alloc_init( const char* current_name) { ValidatorIsFile* instance = malloc(sizeof(ValidatorIsFile)); - instance->app_path_folder = strdup(app_path_folder); + instance->app_path_folder = app_path_folder; instance->app_extension = app_extension; instance->current_name = strdup(current_name); @@ -49,7 +49,6 @@ ValidatorIsFile* validator_is_file_alloc_init( void validator_is_file_free(ValidatorIsFile* instance) { furi_assert(instance); - free(instance->app_path_folder); free(instance->current_name); free(instance); } diff --git a/applications/ibutton/ibutton.c b/applications/ibutton/ibutton.c index b1b5bf62f..a38f077f3 100644 --- a/applications/ibutton/ibutton.c +++ b/applications/ibutton/ibutton.c @@ -1,8 +1,7 @@ #include "ibutton.h" -#include "assets_icons.h" #include "ibutton_i.h" #include "ibutton/scenes/ibutton_scene.h" -#include "m-string.h" + #include #include @@ -86,8 +85,6 @@ void ibutton_tick_event_callback(void* context) { iButton* ibutton_alloc() { iButton* ibutton = malloc(sizeof(iButton)); - string_init(ibutton->file_path); - ibutton->scene_manager = scene_manager_alloc(&ibutton_scene_handlers, ibutton); ibutton->view_dispatcher = view_dispatcher_alloc(); @@ -179,28 +176,49 @@ void ibutton_free(iButton* ibutton) { ibutton_worker_free(ibutton->key_worker); ibutton_key_free(ibutton->key); - string_clear(ibutton->file_path); - free(ibutton); } bool ibutton_file_select(iButton* ibutton) { - bool success = dialog_file_browser_show( + bool success = dialog_file_select_show( ibutton->dialogs, - ibutton->file_path, - ibutton->file_path, + IBUTTON_APP_FOLDER, IBUTTON_APP_EXTENSION, - true, - &I_ibutt_10px, - true); + ibutton->file_name, + IBUTTON_FILE_NAME_SIZE, + ibutton_key_get_name_p(ibutton->key)); if(success) { - success = ibutton_load_key_data(ibutton, ibutton->file_path); + string_t key_str; + string_init_printf( + key_str, "%s/%s%s", IBUTTON_APP_FOLDER, ibutton->file_name, IBUTTON_APP_EXTENSION); + success = ibutton_load_key_data(ibutton, key_str); + + if(success) { + ibutton_key_set_name(ibutton->key, ibutton->file_name); + } + + string_clear(key_str); } return success; } +bool ibutton_load_key(iButton* ibutton, const char* key_name) { + string_t key_path; + string_init_set_str(key_path, key_name); + + const bool success = ibutton_load_key_data(ibutton, key_path); + + if(success) { + path_extract_filename_no_ext(key_name, key_path); + ibutton_key_set_name(ibutton->key, string_get_cstr(key_path)); + } + + string_clear(key_path); + return success; +} + bool ibutton_save_key(iButton* ibutton, const char* key_name) { // Create ibutton directory if necessary ibutton_make_app_folder(ibutton); @@ -208,22 +226,27 @@ bool ibutton_save_key(iButton* ibutton, const char* key_name) { FlipperFormat* file = flipper_format_file_alloc(ibutton->storage); iButtonKey* key = ibutton->key; + string_t key_file_name; bool result = false; + string_init(key_file_name); do { // First remove key if it was saved (we rename the key) - ibutton_delete_key(ibutton); + if(!ibutton_delete_key(ibutton)) break; + + // Save the key + ibutton_key_set_name(key, key_name); // Set full file name, for new key - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { - size_t filename_start = string_search_rchar(ibutton->file_path, '/'); - string_left(ibutton->file_path, filename_start); - } - - string_cat_printf(ibutton->file_path, "/%s%s", key_name, IBUTTON_APP_EXTENSION); + string_printf( + key_file_name, + "%s/%s%s", + IBUTTON_APP_FOLDER, + ibutton_key_get_name_p(key), + IBUTTON_APP_EXTENSION); // Open file for write - if(!flipper_format_file_open_always(file, string_get_cstr(ibutton->file_path))) break; + if(!flipper_format_file_open_always(file, string_get_cstr(key_file_name))) break; // Write header if(!flipper_format_write_header_cstr(file, IBUTTON_APP_FILE_TYPE, 1)) break; @@ -248,6 +271,8 @@ bool ibutton_save_key(iButton* ibutton, const char* key_name) { flipper_format_free(file); + string_clear(key_file_name); + if(!result) { dialog_message_show_storage_error(ibutton->dialogs, "Cannot save\nkey file"); } @@ -256,8 +281,17 @@ bool ibutton_save_key(iButton* ibutton, const char* key_name) { } bool ibutton_delete_key(iButton* ibutton) { + string_t file_name; bool result = false; - result = storage_simply_remove(ibutton->storage, string_get_cstr(ibutton->file_path)); + + string_init_printf( + file_name, + "%s/%s%s", + IBUTTON_APP_FOLDER, + ibutton_key_get_name_p(ibutton->key), + IBUTTON_APP_EXTENSION); + result = storage_simply_remove(ibutton->storage, string_get_cstr(file_name)); + string_clear(file_name); return result; } @@ -301,17 +335,8 @@ int32_t ibutton_app(void* p) { ibutton_make_app_folder(ibutton); - bool key_loaded = false; - - if(p) { - string_set_str(ibutton->file_path, (const char*)p); - if(ibutton_load_key_data(ibutton, ibutton->file_path)) { - key_loaded = true; - // TODO: Display an error if the key from p could not be loaded - } - } - - if(key_loaded) { + if(p && ibutton_load_key(ibutton, (const char*)p)) { + // TODO: Display an error if the key from p could not be loaded scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); } else { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneStart); diff --git a/applications/ibutton/ibutton_i.h b/applications/ibutton/ibutton_i.h index e66712bee..36857fd64 100644 --- a/applications/ibutton/ibutton_i.h +++ b/applications/ibutton/ibutton_i.h @@ -41,7 +41,7 @@ struct iButton { iButtonWorker* key_worker; iButtonKey* key; - string_t file_path; + char file_name[IBUTTON_FILE_NAME_SIZE]; char text_store[IBUTTON_TEXT_STORE_SIZE + 1]; Submenu* submenu; @@ -74,6 +74,7 @@ typedef enum { } iButtonNotificationMessage; bool ibutton_file_select(iButton* ibutton); +bool ibutton_load_key(iButton* ibutton, const char* key_name); bool ibutton_save_key(iButton* ibutton, const char* key_name); bool ibutton_delete_key(iButton* ibutton); void ibutton_text_store_set(iButton* ibutton, const char* text, ...); diff --git a/applications/ibutton/scenes/ibutton_scene_add_type.c b/applications/ibutton/scenes/ibutton_scene_add_type.c index 273330e71..db129295a 100644 --- a/applications/ibutton/scenes/ibutton_scene_add_type.c +++ b/applications/ibutton/scenes/ibutton_scene_add_type.c @@ -1,5 +1,4 @@ #include "../ibutton_i.h" -#include "m-string.h" enum SubmenuIndex { SubmenuIndexCyfral, @@ -45,7 +44,7 @@ bool ibutton_scene_add_type_on_event(void* context, SceneManagerEvent event) { furi_crash("Unknown key type"); } - string_set_str(ibutton->file_path, IBUTTON_APP_FOLDER); + ibutton_key_set_name(key, ""); ibutton_key_clear_data(key); scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddValue); } diff --git a/applications/ibutton/scenes/ibutton_scene_delete_confirm.c b/applications/ibutton/scenes/ibutton_scene_delete_confirm.c index 51f1f2794..73ea97cc6 100644 --- a/applications/ibutton/scenes/ibutton_scene_delete_confirm.c +++ b/applications/ibutton/scenes/ibutton_scene_delete_confirm.c @@ -1,5 +1,4 @@ #include "../ibutton_i.h" -#include static void ibutton_scene_delete_confirm_widget_callback( GuiButtonType result, @@ -17,11 +16,7 @@ void ibutton_scene_delete_confirm_on_enter(void* context) { iButtonKey* key = ibutton->key; const uint8_t* key_data = ibutton_key_get_data_p(key); - string_t key_name; - string_init(key_name); - path_extract_filename(ibutton->file_path, key_name, true); - - ibutton_text_store_set(ibutton, "\e#Delete %s?\e#", string_get_cstr(key_name)); + ibutton_text_store_set(ibutton, "\e#Delete %s?\e#", ibutton_key_get_name_p(key)); widget_add_text_box_element( widget, 0, 0, 128, 27, AlignCenter, AlignCenter, ibutton->text_store, false); widget_add_button_element( @@ -67,8 +62,6 @@ void ibutton_scene_delete_confirm_on_enter(void* context) { widget, 64, 33, AlignCenter, AlignBottom, FontSecondary, ibutton->text_store); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); - - string_clear(key_name); } bool ibutton_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/ibutton/scenes/ibutton_scene_emulate.c b/applications/ibutton/scenes/ibutton_scene_emulate.c index 590223979..8ffe73b66 100644 --- a/applications/ibutton/scenes/ibutton_scene_emulate.c +++ b/applications/ibutton/scenes/ibutton_scene_emulate.c @@ -1,6 +1,5 @@ #include "../ibutton_i.h" #include -#include static void ibutton_scene_emulate_callback(void* context, bool emulated) { iButton* ibutton = context; @@ -16,19 +15,14 @@ void ibutton_scene_emulate_on_enter(void* context) { iButtonKey* key = ibutton->key; const uint8_t* key_data = ibutton_key_get_data_p(key); - - string_t key_name; - string_init(key_name); - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { - path_extract_filename(ibutton->file_path, key_name, true); - } + const char* key_name = ibutton_key_get_name_p(key); uint8_t line_count = 2; DOLPHIN_DEED(DolphinDeedIbuttonEmulate); // check that stored key has name - if(!string_empty_p(key_name)) { - ibutton_text_store_set(ibutton, "emulating\n%s", string_get_cstr(key_name)); + if(strcmp(key_name, "") != 0) { + ibutton_text_store_set(ibutton, "emulating\n%s", key_name); line_count = 2; } else { // if not, show key data @@ -83,8 +77,6 @@ void ibutton_scene_emulate_on_enter(void* context) { ibutton_worker_emulate_set_callback( ibutton->key_worker, ibutton_scene_emulate_callback, ibutton); ibutton_worker_emulate_start(ibutton->key_worker, key); - - string_clear(key_name); } bool ibutton_scene_emulate_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/ibutton/scenes/ibutton_scene_info.c b/applications/ibutton/scenes/ibutton_scene_info.c index bd364ada8..5b0af1d8f 100644 --- a/applications/ibutton/scenes/ibutton_scene_info.c +++ b/applications/ibutton/scenes/ibutton_scene_info.c @@ -1,5 +1,4 @@ #include "../ibutton_i.h" -#include void ibutton_scene_info_on_enter(void* context) { iButton* ibutton = context; @@ -8,11 +7,7 @@ void ibutton_scene_info_on_enter(void* context) { const uint8_t* key_data = ibutton_key_get_data_p(key); - string_t key_name; - string_init(key_name); - path_extract_filename(ibutton->file_path, key_name, true); - - ibutton_text_store_set(ibutton, "%s", string_get_cstr(key_name)); + ibutton_text_store_set(ibutton, "%s", ibutton_key_get_name_p(key)); widget_add_text_box_element( widget, 0, 0, 128, 28, AlignCenter, AlignCenter, ibutton->text_store, false); @@ -51,8 +46,6 @@ void ibutton_scene_info_on_enter(void* context) { widget, 64, 35, AlignCenter, AlignBottom, FontPrimary, ibutton->text_store); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); - - string_clear(key_name); } bool ibutton_scene_info_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/ibutton/scenes/ibutton_scene_read.c b/applications/ibutton/scenes/ibutton_scene_read.c index 0cc0a8dff..a25f27e60 100644 --- a/applications/ibutton/scenes/ibutton_scene_read.c +++ b/applications/ibutton/scenes/ibutton_scene_read.c @@ -18,7 +18,7 @@ void ibutton_scene_read_on_enter(void* context) { popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); - string_set_str(ibutton->file_path, IBUTTON_APP_FOLDER); + ibutton_key_set_name(key, ""); ibutton_worker_read_set_callback(worker, ibutton_scene_read_callback, ibutton); ibutton_worker_read_start(worker, key); diff --git a/applications/ibutton/scenes/ibutton_scene_save_name.c b/applications/ibutton/scenes/ibutton_scene_save_name.c index 6caf5d2d5..b1baf6afc 100644 --- a/applications/ibutton/scenes/ibutton_scene_save_name.c +++ b/applications/ibutton/scenes/ibutton_scene_save_name.c @@ -1,7 +1,5 @@ #include "../ibutton_i.h" -#include "m-string.h" #include -#include static void ibutton_scene_save_name_text_input_callback(void* context) { iButton* ibutton = context; @@ -12,17 +10,13 @@ void ibutton_scene_save_name_on_enter(void* context) { iButton* ibutton = context; TextInput* text_input = ibutton->text_input; - string_t key_name; - string_init(key_name); - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { - path_extract_filename(ibutton->file_path, key_name, true); - } + const char* key_name = ibutton_key_get_name_p(ibutton->key); + const bool key_name_is_empty = !strcmp(key_name, ""); - const bool key_name_is_empty = string_empty_p(key_name); if(key_name_is_empty) { set_random_name(ibutton->text_store, IBUTTON_TEXT_STORE_SIZE); } else { - ibutton_text_store_set(ibutton, "%s", string_get_cstr(key_name)); + ibutton_text_store_set(ibutton, "%s", key_name); } text_input_set_header_text(text_input, "Name the key"); @@ -34,19 +28,11 @@ void ibutton_scene_save_name_on_enter(void* context) { IBUTTON_KEY_NAME_SIZE, key_name_is_empty); - string_t folder_path; - string_init(folder_path); - - path_extract_dirname(string_get_cstr(ibutton->file_path), folder_path); - - ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), IBUTTON_APP_EXTENSION, string_get_cstr(key_name)); + ValidatorIsFile* validator_is_file = + validator_is_file_alloc_init(IBUTTON_APP_FOLDER, IBUTTON_APP_EXTENSION, key_name); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewTextInput); - - string_clear(key_name); - string_clear(folder_path); } bool ibutton_scene_save_name_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/ibutton/scenes/ibutton_scene_start.c b/applications/ibutton/scenes/ibutton_scene_start.c index cc8af9839..a3141f5ad 100644 --- a/applications/ibutton/scenes/ibutton_scene_start.c +++ b/applications/ibutton/scenes/ibutton_scene_start.c @@ -36,7 +36,6 @@ bool ibutton_scene_start_on_event(void* context, SceneManagerEvent event) { if(event.event == SubmenuIndexRead) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead); } else if(event.event == SubmenuIndexSaved) { - string_set_str(ibutton->file_path, IBUTTON_APP_FOLDER); scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSelectKey); } else if(event.event == SubmenuIndexAdd) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddType); diff --git a/applications/ibutton/scenes/ibutton_scene_write.c b/applications/ibutton/scenes/ibutton_scene_write.c index 4ce19408a..35e45d83b 100644 --- a/applications/ibutton/scenes/ibutton_scene_write.c +++ b/applications/ibutton/scenes/ibutton_scene_write.c @@ -1,6 +1,4 @@ #include "../ibutton_i.h" -#include "m-string.h" -#include "toolbox/path.h" typedef enum { iButtonSceneWriteStateDefault, @@ -19,18 +17,13 @@ void ibutton_scene_write_on_enter(void* context) { iButtonWorker* worker = ibutton->key_worker; const uint8_t* key_data = ibutton_key_get_data_p(key); - - string_t key_name; - string_init(key_name); - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { - path_extract_filename(ibutton->file_path, key_name, true); - } + const char* key_name = ibutton_key_get_name_p(key); uint8_t line_count = 2; // check that stored key has name - if(!string_empty_p(key_name)) { - ibutton_text_store_set(ibutton, "writing\n%s", string_get_cstr(key_name)); + if(strcmp(key_name, "") != 0) { + ibutton_text_store_set(ibutton, "writing\n%s", key_name); line_count = 2; } else { // if not, show key data @@ -86,8 +79,6 @@ void ibutton_scene_write_on_enter(void* context) { ibutton_worker_write_set_callback(worker, ibutton_scene_write_callback, ibutton); ibutton_worker_write_start(worker, key); - - string_clear(key_name); } bool ibutton_scene_write_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/infrared/infrared_app.cpp b/applications/infrared/infrared_app.cpp index 1ac859d10..5dc3b311d 100644 --- a/applications/infrared/infrared_app.cpp +++ b/applications/infrared/infrared_app.cpp @@ -1,5 +1,4 @@ #include "infrared_app.h" -#include "m-string.h" #include #include #include @@ -13,18 +12,20 @@ int32_t InfraredApp::run(void* args) { bool exit = false; if(args) { - string_t path; - string_init_set_str(path, (char*)args); - if(string_end_with_str_p(path, InfraredApp::infrared_extension)) { - bool result = remote_manager.load(path); + std::string path = static_cast(args); + std::string remote_name(path, path.find_last_of('/') + 1, path.size()); + auto last_dot = remote_name.find_last_of('.'); + if(last_dot != std::string::npos) { + remote_name.erase(last_dot); + path.erase(path.find_last_of('/')); + bool result = remote_manager.load(path, remote_name); if(result) { current_scene = InfraredApp::Scene::Remote; } else { - printf("Failed to load remote \'%s\'\r\n", string_get_cstr(path)); + printf("Failed to load remote \'%s\'\r\n", remote_name.c_str()); return -1; } } - string_clear(path); } scenes[current_scene]->on_enter(this); @@ -50,7 +51,6 @@ int32_t InfraredApp::run(void* args) { InfraredApp::InfraredApp() { furi_check(InfraredAppRemoteManager::max_button_name_length < get_text_store_size()); - string_init_set_str(file_path, InfraredApp::infrared_directory); notification = static_cast(furi_record_open("notification")); dialogs = static_cast(furi_record_open("dialogs")); infrared_worker = infrared_worker_alloc(); @@ -60,7 +60,6 @@ InfraredApp::~InfraredApp() { infrared_worker_free(infrared_worker); furi_record_close("notification"); furi_record_close("dialogs"); - string_clear(file_path); for(auto& [key, scene] : scenes) delete scene; } diff --git a/applications/infrared/infrared_app.h b/applications/infrared/infrared_app.h index 1cb8b6617..e0db7c51b 100644 --- a/applications/infrared/infrared_app.h +++ b/applications/infrared/infrared_app.h @@ -251,8 +251,6 @@ public: /** Main class destructor, deinitializes all critical objects */ ~InfraredApp(); - string_t file_path; - /** Path to Infrared directory */ static constexpr const char* infrared_directory = "/any/infrared"; /** Infrared files extension (remote files and universal databases) */ diff --git a/applications/infrared/infrared_app_remote_manager.cpp b/applications/infrared/infrared_app_remote_manager.cpp index faeccb39e..4fd645532 100644 --- a/applications/infrared/infrared_app_remote_manager.cpp +++ b/applications/infrared/infrared_app_remote_manager.cpp @@ -1,5 +1,3 @@ -#include "m-string.h" -#include "storage/filesystem_api_defines.h" #include #include "infrared_app_remote_manager.h" #include "infrared/helpers/infrared_parser.h" @@ -13,58 +11,44 @@ #include #include #include "infrared_app.h" -#include static const char* default_remote_name = "remote"; -void InfraredAppRemoteManager::find_vacant_remote_name(string_t name, string_t path) { +std::string InfraredAppRemoteManager::make_full_name( + const std::string& path, + const std::string& remote_name) const { + return std::string("") + path + "/" + remote_name + InfraredApp::infrared_extension; +} + +std::string InfraredAppRemoteManager::find_vacant_remote_name(const std::string& name) { + std::string result_name; Storage* storage = static_cast(furi_record_open("storage")); - string_t base_path; - string_init_set(base_path, path); + FS_Error error = storage_common_stat( + storage, make_full_name(InfraredApp::infrared_directory, name).c_str(), NULL); - if(string_end_with_str_p(base_path, InfraredApp::infrared_extension)) { - size_t filename_start = string_search_rchar(base_path, '/'); - string_left(base_path, filename_start); - } - - string_printf( - base_path, - "%s/%s%s", - string_get_cstr(path), - string_get_cstr(name), - InfraredApp::infrared_extension); - - FS_Error error = storage_common_stat(storage, string_get_cstr(base_path), NULL); - - if(error == FSE_OK) { + if(error == FSE_NOT_EXIST) { + result_name = name; + } else if(error != FSE_OK) { + result_name = std::string(); + } else { /* if suggested name is occupied, try another one (name2, name3, etc) */ - size_t dot = string_search_rchar(base_path, '.'); - string_left(base_path, dot); - - string_t path_temp; - string_init(path_temp); - uint32_t i = 1; + std::string new_name; do { - string_printf( - path_temp, - "%s%u%s", - string_get_cstr(base_path), - ++i, - InfraredApp::infrared_extension); - error = storage_common_stat(storage, string_get_cstr(path_temp), NULL); + new_name = make_full_name(InfraredApp::infrared_directory, name + std::to_string(++i)); + error = storage_common_stat(storage, new_name.c_str(), NULL); } while(error == FSE_OK); - string_clear(path_temp); - if(error == FSE_NOT_EXIST) { - string_cat_printf(name, "%u", i); + result_name = name + std::to_string(i); + } else { + result_name = std::string(); } } - string_clear(base_path); furi_record_close("storage"); + return result_name; } bool InfraredAppRemoteManager::add_button(const char* button_name, const InfraredAppSignal& signal) { @@ -77,23 +61,12 @@ bool InfraredAppRemoteManager::add_remote_with_button( const InfraredAppSignal& signal) { furi_check(button_name != nullptr); - string_t new_name; - string_init_set_str(new_name, default_remote_name); - - string_t new_path; - string_init_set_str(new_path, InfraredApp::infrared_directory); - - find_vacant_remote_name(new_name, new_path); - - string_cat_printf( - new_path, "/%s%s", string_get_cstr(new_name), InfraredApp::infrared_extension); - - remote = std::make_unique(new_path); - remote->name = std::string(string_get_cstr(new_name)); - - string_clear(new_path); - string_clear(new_name); + auto new_name = find_vacant_remote_name(default_remote_name); + if(new_name.empty()) { + return false; + } + remote = std::make_unique(InfraredApp::infrared_directory, new_name); return add_button(button_name, signal); } @@ -120,7 +93,8 @@ const InfraredAppSignal& InfraredAppRemoteManager::get_button_data(size_t index) bool InfraredAppRemoteManager::delete_remote() { Storage* storage = static_cast(furi_record_open("storage")); - FS_Error error = storage_common_remove(storage, string_get_cstr(remote->path)); + FS_Error error = + storage_common_remove(storage, make_full_name(remote->path, remote->name).c_str()); reset_remote(); furi_record_close("storage"); @@ -154,33 +128,22 @@ std::string InfraredAppRemoteManager::get_remote_name() { bool InfraredAppRemoteManager::rename_remote(const char* str) { furi_check(str != nullptr); furi_check(remote.get() != nullptr); - furi_check(!string_empty_p(remote->path)); if(!remote->name.compare(str)) { return true; } - string_t new_name; - string_init_set_str(new_name, str); - find_vacant_remote_name(new_name, remote->path); - - string_t new_path; - string_init_set(new_path, remote->path); - if(string_end_with_str_p(new_path, InfraredApp::infrared_extension)) { - size_t filename_start = string_search_rchar(new_path, '/'); - string_left(new_path, filename_start); + auto new_name = find_vacant_remote_name(str); + if(new_name.empty()) { + return false; } - string_cat_printf( - new_path, "/%s%s", string_get_cstr(new_name), InfraredApp::infrared_extension); Storage* storage = static_cast(furi_record_open("storage")); - FS_Error error = - storage_common_rename(storage, string_get_cstr(remote->path), string_get_cstr(new_path)); - remote->name = std::string(string_get_cstr(new_name)); - - string_clear(new_name); - string_clear(new_path); + std::string old_filename = make_full_name(remote->path, remote->name); + std::string new_filename = make_full_name(remote->path, new_name); + FS_Error error = storage_common_rename(storage, old_filename.c_str(), new_filename.c_str()); + remote->name = new_name; furi_record_close("storage"); return (error == FSE_OK || error == FSE_EXIST); @@ -208,8 +171,10 @@ bool InfraredAppRemoteManager::store(void) { FlipperFormat* ff = flipper_format_file_alloc(storage); - FURI_LOG_I("RemoteManager", "store file: \'%s\'", string_get_cstr(remote->path)); - result = flipper_format_file_open_always(ff, string_get_cstr(remote->path)); + FURI_LOG_I( + "RemoteManager", "store file: \'%s\'", make_full_name(remote->path, remote->name).c_str()); + result = + flipper_format_file_open_always(ff, make_full_name(remote->path, remote->name).c_str()); if(result) { result = flipper_format_write_header_cstr(ff, "IR signals file", 1); } @@ -227,13 +192,13 @@ bool InfraredAppRemoteManager::store(void) { return result; } -bool InfraredAppRemoteManager::load(string_t path) { +bool InfraredAppRemoteManager::load(const std::string& path, const std::string& remote_name) { bool result = false; Storage* storage = static_cast(furi_record_open("storage")); FlipperFormat* ff = flipper_format_file_alloc(storage); - FURI_LOG_I("RemoteManager", "load file: \'%s\'", string_get_cstr(path)); - result = flipper_format_file_open_existing(ff, string_get_cstr(path)); + FURI_LOG_I("RemoteManager", "load file: \'%s\'", make_full_name(path, remote_name).c_str()); + result = flipper_format_file_open_existing(ff, make_full_name(path, remote_name).c_str()); if(result) { string_t header; string_init(header); @@ -245,14 +210,7 @@ bool InfraredAppRemoteManager::load(string_t path) { string_clear(header); } if(result) { - string_t new_name; - string_init(new_name); - - remote = std::make_unique(path); - path_extract_filename(path, new_name, true); - remote->name = std::string(string_get_cstr(new_name)); - - string_clear(new_name); + remote = std::make_unique(path, remote_name); InfraredAppSignal signal; std::string signal_name; while(infrared_parser_read_signal(ff, signal, signal_name)) { diff --git a/applications/infrared/infrared_app_remote_manager.h b/applications/infrared/infrared_app_remote_manager.h index b6f0b170f..31557d54b 100644 --- a/applications/infrared/infrared_app_remote_manager.h +++ b/applications/infrared/infrared_app_remote_manager.h @@ -8,7 +8,6 @@ #include "infrared_app_signal.h" -#include "m-string.h" #include #include @@ -61,19 +60,17 @@ class InfraredAppRemote { /** Name of remote */ std::string name; /** Path to remote file */ - string_t path; + std::string path; public: /** Initialize new remote * * @param path - remote file path + * @param name - new remote name */ - InfraredAppRemote(string_t file_path) { - string_init_set(path, file_path); - } - - ~InfraredAppRemote() { - string_clear(path); + InfraredAppRemote(const std::string& path, const std::string& name) + : name(name) + , path(path) { } }; @@ -81,6 +78,12 @@ public: class InfraredAppRemoteManager { /** Remote instance. There can be 1 remote loaded at a time. */ std::unique_ptr remote; + /** Make full name from remote name + * + * @param remote_name name of remote + * @retval full name of remote on disk + */ + std::string make_full_name(const std::string& path, const std::string& remote_name) const; public: /** Restriction to button name length. Buttons larger are ignored. */ @@ -122,9 +125,9 @@ public: * incremented digit(2,3,4,etc) added to name and check repeated. * * @param name - suggested remote name - * @param path - remote file path + * @retval garanteed free remote name, prefixed with suggested */ - void find_vacant_remote_name(string_t name, string_t path); + std::string find_vacant_remote_name(const std::string& name); /** Get button list * @@ -182,8 +185,8 @@ public: /** Load data from disk into current remote * - * @param path - path to remote file + * @param name - name of remote to load * @retval true if success, false otherwise */ - bool load(string_t path); + bool load(const std::string& path, const std::string& name); }; diff --git a/applications/infrared/scene/infrared_app_scene_edit_rename.cpp b/applications/infrared/scene/infrared_app_scene_edit_rename.cpp index 761da49f3..dc63c64b1 100644 --- a/applications/infrared/scene/infrared_app_scene_edit_rename.cpp +++ b/applications/infrared/scene/infrared_app_scene_edit_rename.cpp @@ -1,6 +1,4 @@ #include "../infrared_app.h" -#include "m-string.h" -#include "toolbox/path.h" void InfraredAppSceneEditRename::on_enter(InfraredApp* app) { InfraredAppViewManager* view_manager = app->get_view_manager(); @@ -23,18 +21,9 @@ void InfraredAppSceneEditRename::on_enter(InfraredApp* app) { enter_name_length = InfraredAppRemoteManager::max_remote_name_length; text_input_set_header_text(text_input, "Name the remote"); - string_t folder_path; - string_init(folder_path); - - if(string_end_with_str_p(app->file_path, InfraredApp::infrared_extension)) { - path_extract_dirname(string_get_cstr(app->file_path), folder_path); - } - ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), app->infrared_extension, remote_name.c_str()); + app->infrared_directory, app->infrared_extension, remote_name.c_str()); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - - string_clear(folder_path); } text_input_set_result_callback( diff --git a/applications/infrared/scene/infrared_app_scene_remote_list.cpp b/applications/infrared/scene/infrared_app_scene_remote_list.cpp index c72acb6e8..f59ff3e91 100644 --- a/applications/infrared/scene/infrared_app_scene_remote_list.cpp +++ b/applications/infrared/scene/infrared_app_scene_remote_list.cpp @@ -1,5 +1,4 @@ #include "../infrared_app.h" -#include "assets_icons.h" #include "infrared/infrared_app_event.h" #include @@ -9,6 +8,11 @@ void InfraredAppSceneRemoteList::on_enter(InfraredApp* app) { bool result = false; bool file_select_result; auto remote_manager = app->get_remote_manager(); + auto last_selected_remote = remote_manager->get_remote_name(); + const char* last_selected_remote_name = + last_selected_remote.size() ? last_selected_remote.c_str() : nullptr; + auto filename_ts = + std::make_unique(InfraredAppRemoteManager::max_remote_name_length); DialogsApp* dialogs = app->get_dialogs(); InfraredAppViewManager* view_manager = app->get_view_manager(); @@ -16,17 +20,16 @@ void InfraredAppSceneRemoteList::on_enter(InfraredApp* app) { button_menu_reset(button_menu); view_manager->switch_to(InfraredAppViewManager::ViewId::ButtonMenu); - file_select_result = dialog_file_browser_show( + file_select_result = dialog_file_select_show( dialogs, - app->file_path, - app->file_path, + InfraredApp::infrared_directory, InfraredApp::infrared_extension, - true, - &I_ir_10px, - true); + filename_ts->text, + filename_ts->text_size, + last_selected_remote_name); if(file_select_result) { - if(remote_manager->load(app->file_path)) { + if(remote_manager->load(InfraredApp::infrared_directory, std::string(filename_ts->text))) { app->switch_to_next_scene(InfraredApp::Scene::Remote); result = true; } diff --git a/applications/infrared/scene/infrared_app_scene_start.cpp b/applications/infrared/scene/infrared_app_scene_start.cpp index 5efdce7a0..c42ab9fed 100644 --- a/applications/infrared/scene/infrared_app_scene_start.cpp +++ b/applications/infrared/scene/infrared_app_scene_start.cpp @@ -26,8 +26,6 @@ void InfraredAppSceneStart::on_enter(InfraredApp* app) { submenu, "Learn New Remote", SubmenuIndexLearnNewRemote, submenu_callback, app); submenu_add_item(submenu, "Saved Remotes", SubmenuIndexSavedRemotes, submenu_callback, app); submenu_set_selected_item(submenu, submenu_item_selected); - - string_set_str(app->file_path, InfraredApp::infrared_directory); submenu_item_selected = 0; view_manager->switch_to(InfraredAppViewManager::ViewId::Submenu); diff --git a/applications/lfrfid/lfrfid_app.cpp b/applications/lfrfid/lfrfid_app.cpp index 4027a07ea..c2274234b 100644 --- a/applications/lfrfid/lfrfid_app.cpp +++ b/applications/lfrfid/lfrfid_app.cpp @@ -1,7 +1,4 @@ #include "lfrfid_app.h" -#include "assets_icons.h" -#include "furi/common_defines.h" -#include "m-string.h" #include "scene/lfrfid_app_scene_start.h" #include "scene/lfrfid_app_scene_read.h" #include "scene/lfrfid_app_scene_read_success.h" @@ -34,11 +31,9 @@ LfRfidApp::LfRfidApp() , storage{"storage"} , dialogs{"dialogs"} , text_store(40) { - string_init_set_str(file_path, app_folder); } LfRfidApp::~LfRfidApp() { - string_clear(file_path); } void LfRfidApp::run(void* _args) { @@ -47,8 +42,7 @@ void LfRfidApp::run(void* _args) { make_app_folder(); if(strlen(args)) { - string_set_str(file_path, args); - load_key_data(file_path, &worker.key); + load_key_data(args, &worker.key); scene_controller.add_scene(SceneType::Emulate, new LfRfidAppSceneEmulate()); scene_controller.process(100, SceneType::Emulate); } else { @@ -75,49 +69,65 @@ void LfRfidApp::run(void* _args) { } bool LfRfidApp::save_key(RfidKey* key) { + string_t file_name; bool result = false; make_app_folder(); - if(string_end_with_str_p(file_path, app_extension)) { - size_t filename_start = string_search_rchar(file_path, '/'); - string_left(file_path, filename_start); - } + string_init_printf(file_name, "%s/%s%s", app_folder, key->get_name(), app_extension); + result = save_key_data(string_get_cstr(file_name), key); + string_clear(file_name); - string_cat_printf(file_path, "/%s%s", key->get_name(), app_extension); - - result = save_key_data(file_path, key); return result; } bool LfRfidApp::load_key_from_file_select(bool need_restore) { - if(!need_restore) { - string_set_str(file_path, app_folder); - } + TextStore* filename_ts = new TextStore(64); + bool result = false; - bool result = dialog_file_browser_show( - dialogs, file_path, file_path, app_extension, true, &I_125_10px, true); + if(need_restore) { + result = dialog_file_select_show( + dialogs, + app_folder, + app_extension, + filename_ts->text, + filename_ts->text_size, + worker.key.get_name()); + } else { + result = dialog_file_select_show( + dialogs, app_folder, app_extension, filename_ts->text, filename_ts->text_size, NULL); + } if(result) { - result = load_key_data(file_path, &worker.key); + string_t key_str; + string_init_printf(key_str, "%s/%s%s", app_folder, filename_ts->text, app_extension); + result = load_key_data(string_get_cstr(key_str), &worker.key); + string_clear(key_str); } + delete filename_ts; return result; } bool LfRfidApp::delete_key(RfidKey* key) { - UNUSED(key); - return storage_simply_remove(storage, string_get_cstr(file_path)); + string_t file_name; + bool result = false; + + string_init_printf(file_name, "%s/%s%s", app_folder, key->get_name(), app_extension); + result = storage_simply_remove(storage, string_get_cstr(file_name)); + string_clear(file_name); + + return result; } -bool LfRfidApp::load_key_data(string_t path, RfidKey* key) { +bool LfRfidApp::load_key_data(const char* path, RfidKey* key) { FlipperFormat* file = flipper_format_file_alloc(storage); bool result = false; string_t str_result; string_init(str_result); do { - if(!flipper_format_file_open_existing(file, string_get_cstr(path))) break; + if(!flipper_format_file_open_existing(file, path)) break; // header uint32_t version; @@ -139,7 +149,7 @@ bool LfRfidApp::load_key_data(string_t path, RfidKey* key) { break; loaded_key.set_data(key_data, loaded_key.get_type_data_count()); - path_extract_filename(path, str_result, true); + path_extract_filename_no_ext(path, str_result); loaded_key.set_name(string_get_cstr(str_result)); *key = loaded_key; @@ -156,12 +166,12 @@ bool LfRfidApp::load_key_data(string_t path, RfidKey* key) { return result; } -bool LfRfidApp::save_key_data(string_t path, RfidKey* key) { +bool LfRfidApp::save_key_data(const char* path, RfidKey* key) { FlipperFormat* file = flipper_format_file_alloc(storage); bool result = false; do { - if(!flipper_format_file_open_always(file, string_get_cstr(path))) break; + if(!flipper_format_file_open_always(file, path)) break; if(!flipper_format_write_header_cstr(file, app_filetype, 1)) break; if(!flipper_format_write_comment_cstr(file, "Key type can be EM4100, H10301 or I40134")) break; diff --git a/applications/lfrfid/lfrfid_app.h b/applications/lfrfid/lfrfid_app.h index 3f8209a1d..dddfb753a 100644 --- a/applications/lfrfid/lfrfid_app.h +++ b/applications/lfrfid/lfrfid_app.h @@ -1,5 +1,4 @@ #pragma once -#include "m-string.h" #include #include @@ -77,8 +76,6 @@ public: TextStore text_store; - string_t file_path; - void run(void* args); static const char* app_folder; @@ -89,8 +86,8 @@ public: bool load_key_from_file_select(bool need_restore); bool delete_key(RfidKey* key); - bool load_key_data(string_t path, RfidKey* key); - bool save_key_data(string_t path, RfidKey* key); + bool load_key_data(const char* path, RfidKey* key); + bool save_key_data(const char* path, RfidKey* key); void make_app_folder(); }; diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp b/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp index d7ba2c9ed..d460724e2 100644 --- a/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp +++ b/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp @@ -1,14 +1,11 @@ #include "lfrfid_app_scene_save_name.h" -#include "m-string.h" #include -#include void LfRfidAppSceneSaveName::on_enter(LfRfidApp* app, bool /* need_restore */) { const char* key_name = app->worker.key.get_name(); bool key_name_empty = !strcmp(key_name, ""); if(key_name_empty) { - string_set_str(app->file_path, app->app_folder); set_random_name(app->text_store.text, app->text_store.text_size); } else { app->text_store.set("%s", key_name); @@ -24,17 +21,10 @@ void LfRfidAppSceneSaveName::on_enter(LfRfidApp* app, bool /* need_restore */) { app->worker.key.get_name_length(), key_name_empty); - string_t folder_path; - string_init(folder_path); - - path_extract_dirname(string_get_cstr(app->file_path), folder_path); - ValidatorIsFile* validator_is_file = - validator_is_file_alloc_init(string_get_cstr(folder_path), app->app_extension, key_name); + validator_is_file_alloc_init(app->app_folder, app->app_extension, key_name); text_input->set_validator(validator_is_file_callback, validator_is_file); - string_clear(folder_path); - app->view_controller.switch_to(); } diff --git a/applications/music_player/music_player.c b/applications/music_player/music_player.c index 9b5dda0fa..6dfef4920 100644 --- a/applications/music_player/music_player.c +++ b/applications/music_player/music_player.c @@ -1,5 +1,3 @@ -#include "assets_icons.h" -#include "m-string.h" #include #include @@ -300,23 +298,23 @@ int32_t music_player_app(void* p) { if(p) { string_cat_str(file_path, p); } else { - string_set_str(file_path, MUSIC_PLAYER_APP_PATH_FOLDER); - + char file_name[256] = {0}; DialogsApp* dialogs = furi_record_open("dialogs"); - bool res = dialog_file_browser_show( + bool res = dialog_file_select_show( dialogs, - file_path, - file_path, + MUSIC_PLAYER_APP_PATH_FOLDER, MUSIC_PLAYER_APP_EXTENSION, - true, - &I_music_10px, - false); - + file_name, + 255, + NULL); furi_record_close("dialogs"); if(!res) { FURI_LOG_E(TAG, "No file selected"); break; } + string_cat_str(file_path, MUSIC_PLAYER_APP_PATH_FOLDER); + string_cat_str(file_path, "/"); + string_cat_str(file_path, file_name); } if(!music_player_worker_load(music_player->worker, string_get_cstr(file_path))) { diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c index ca3fc45aa..63f0c3ccb 100644 --- a/applications/nfc/nfc_device.c +++ b/applications/nfc/nfc_device.c @@ -1,6 +1,4 @@ #include "nfc_device.h" -#include "assets_icons.h" -#include "m-string.h" #include "nfc_types.h" #include @@ -16,7 +14,6 @@ NfcDevice* nfc_device_alloc() { NfcDevice* nfc_dev = malloc(sizeof(NfcDevice)); nfc_dev->storage = furi_record_open("storage"); nfc_dev->dialogs = furi_record_open("dialogs"); - string_init(nfc_dev->load_path); return nfc_dev; } @@ -25,7 +22,6 @@ void nfc_device_free(NfcDevice* nfc_dev) { nfc_device_clear(nfc_dev); furi_record_close("storage"); furi_record_close("dialogs"); - string_clear(nfc_dev->load_path); free(nfc_dev); } @@ -734,24 +730,11 @@ void nfc_device_set_name(NfcDevice* dev, const char* name) { strlcpy(dev->dev_name, name, NFC_DEV_NAME_MAX_LEN); } -static void nfc_device_get_path_without_ext(string_t orig_path, string_t shadow_path) { - // TODO: this won't work if there is ".nfc" anywhere in the path other than - // at the end - size_t ext_start = string_search_str(orig_path, NFC_APP_EXTENSION); - string_set_n(shadow_path, orig_path, 0, ext_start); -} - -static void nfc_device_get_shadow_path(string_t orig_path, string_t shadow_path) { - nfc_device_get_path_without_ext(orig_path, shadow_path); - string_cat_printf(shadow_path, "%s", NFC_APP_SHADOW_EXTENSION); -} - static bool nfc_device_save_file( NfcDevice* dev, const char* dev_name, const char* folder, - const char* extension, - bool use_load_path) { + const char* extension) { furi_assert(dev); bool saved = false; @@ -761,19 +744,10 @@ static bool nfc_device_save_file( string_init(temp_str); do { - if(use_load_path && !string_empty_p(dev->load_path)) { - // Get directory name - path_extract_dirname(string_get_cstr(dev->load_path), temp_str); - // Create nfc directory if necessary - if(!storage_simply_mkdir(dev->storage, string_get_cstr(temp_str))) break; - // Make path to file to save - string_cat_printf(temp_str, "/%s%s", dev_name, extension); - } else { - // Create nfc directory if necessary - if(!storage_simply_mkdir(dev->storage, NFC_APP_FOLDER)) break; - // First remove nfc device file if it was saved - string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); - } + // Create nfc directory if necessary + if(!storage_simply_mkdir(dev->storage, NFC_APP_FOLDER)) break; + // First remove nfc device file if it was saved + string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); // Open file if(!flipper_format_file_open_always(file, string_get_cstr(temp_str))) break; // Write header @@ -812,12 +786,12 @@ static bool nfc_device_save_file( } bool nfc_device_save(NfcDevice* dev, const char* dev_name) { - return nfc_device_save_file(dev, dev_name, NFC_APP_FOLDER, NFC_APP_EXTENSION, true); + return nfc_device_save_file(dev, dev_name, NFC_APP_FOLDER, NFC_APP_EXTENSION); } bool nfc_device_save_shadow(NfcDevice* dev, const char* dev_name) { dev->shadow_file_exist = true; - return nfc_device_save_file(dev, dev_name, NFC_APP_FOLDER, NFC_APP_SHADOW_EXTENSION, true); + return nfc_device_save_file(dev, dev_name, NFC_APP_FOLDER, NFC_APP_SHADOW_EXTENSION); } static bool nfc_device_load_data(NfcDevice* dev, string_t path) { @@ -831,7 +805,9 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path) { do { // Check existance of shadow file - nfc_device_get_shadow_path(path, temp_str); + size_t ext_start = string_search_str(path, NFC_APP_EXTENSION); + string_set_n(temp_str, path, 0, ext_start); + string_cat_printf(temp_str, "%s", NFC_APP_SHADOW_EXTENSION); dev->shadow_file_exist = storage_common_stat(dev->storage, string_get_cstr(temp_str), NULL) == FSE_OK; // Open shadow file if it exists. If not - open original @@ -888,16 +864,15 @@ bool nfc_device_load(NfcDevice* dev, const char* file_path) { furi_assert(file_path); // Load device data - string_set_str(dev->load_path, file_path); - bool dev_load = nfc_device_load_data(dev, dev->load_path); + string_t path; + string_init_set_str(path, file_path); + bool dev_load = nfc_device_load_data(dev, path); if(dev_load) { // Set device name - string_t filename; - string_init(filename); - path_extract_filename_no_ext(file_path, filename); - nfc_device_set_name(dev, string_get_cstr(filename)); - string_clear(filename); + path_extract_filename_no_ext(file_path, path); + nfc_device_set_name(dev, string_get_cstr(path)); } + string_clear(path); return dev_load; } @@ -905,19 +880,23 @@ bool nfc_device_load(NfcDevice* dev, const char* file_path) { bool nfc_file_select(NfcDevice* dev) { furi_assert(dev); - // Input events and views are managed by file_browser - bool res = dialog_file_browser_show( - dev->dialogs, dev->load_path, dev->load_path, NFC_APP_EXTENSION, true, &I_Nfc_10px, true); + // Input events and views are managed by file_select + bool res = dialog_file_select_show( + dev->dialogs, + NFC_APP_FOLDER, + NFC_APP_EXTENSION, + dev->file_name, + sizeof(dev->file_name), + dev->dev_name); if(res) { - string_t filename; - string_init(filename); - path_extract_filename(dev->load_path, filename, true); - strncpy(dev->dev_name, string_get_cstr(filename), NFC_DEV_NAME_MAX_LEN); - res = nfc_device_load_data(dev, dev->load_path); + string_t dev_str; + // Get key file path + string_init_printf(dev_str, "%s/%s%s", NFC_APP_FOLDER, dev->file_name, NFC_APP_EXTENSION); + res = nfc_device_load_data(dev, dev_str); if(res) { - nfc_device_set_name(dev, dev->dev_name); + nfc_device_set_name(dev, dev->file_name); } - string_clear(filename); + string_clear(dev_str); } return res; @@ -935,10 +914,9 @@ void nfc_device_clear(NfcDevice* dev) { nfc_device_data_clear(&dev->dev_data); memset(&dev->dev_data, 0, sizeof(dev->dev_data)); dev->format = NfcDeviceSaveFormatUid; - string_set_str(dev->load_path, NFC_APP_FOLDER); } -bool nfc_device_delete(NfcDevice* dev, bool use_load_path) { +bool nfc_device_delete(NfcDevice* dev) { furi_assert(dev); bool deleted = false; @@ -947,20 +925,12 @@ bool nfc_device_delete(NfcDevice* dev, bool use_load_path) { do { // Delete original file - if(use_load_path && !string_empty_p(dev->load_path)) { - string_set(file_path, dev->load_path); - } else { - string_printf(file_path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION); - } + string_init_printf(file_path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION); if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break; // Delete shadow file if it exists if(dev->shadow_file_exist) { - if(use_load_path && !string_empty_p(dev->load_path)) { - nfc_device_get_shadow_path(dev->load_path, file_path); - } else { - string_printf( - file_path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_SHADOW_EXTENSION); - } + string_printf( + file_path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_SHADOW_EXTENSION); if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break; } deleted = true; @@ -974,29 +944,19 @@ bool nfc_device_delete(NfcDevice* dev, bool use_load_path) { return deleted; } -bool nfc_device_restore(NfcDevice* dev, bool use_load_path) { +bool nfc_device_restore(NfcDevice* dev) { furi_assert(dev); furi_assert(dev->shadow_file_exist); bool restored = false; string_t path; - string_init(path); - do { - if(use_load_path && !string_empty_p(dev->load_path)) { - nfc_device_get_shadow_path(dev->load_path, path); - } else { - string_printf( - path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_SHADOW_EXTENSION); - } + string_init_printf( + path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_SHADOW_EXTENSION); if(!storage_simply_remove(dev->storage, string_get_cstr(path))) break; dev->shadow_file_exist = false; - if(use_load_path && !string_empty_p(dev->load_path)) { - string_set(path, dev->load_path); - } else { - string_printf(path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION); - } + string_printf(path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION); if(!nfc_device_load_data(dev, path)) break; restored = true; } while(0); diff --git a/applications/nfc/nfc_device.h b/applications/nfc/nfc_device.h index 400f6c363..215f637fa 100644 --- a/applications/nfc/nfc_device.h +++ b/applications/nfc/nfc_device.h @@ -12,6 +12,7 @@ #include #define NFC_DEV_NAME_MAX_LEN 22 +#define NFC_FILE_NAME_MAX_LEN 120 #define NFC_READER_DATA_MAX_SIZE 64 #define NFC_APP_FOLDER "/any/nfc" @@ -56,7 +57,7 @@ typedef struct { DialogsApp* dialogs; NfcDeviceData dev_data; char dev_name[NFC_DEV_NAME_MAX_LEN + 1]; - string_t load_path; + char file_name[NFC_FILE_NAME_MAX_LEN]; NfcDeviceSaveFormat format; bool shadow_file_exist; } NfcDevice; @@ -79,6 +80,6 @@ void nfc_device_data_clear(NfcDeviceData* dev); void nfc_device_clear(NfcDevice* dev); -bool nfc_device_delete(NfcDevice* dev, bool use_load_path); +bool nfc_device_delete(NfcDevice* dev); -bool nfc_device_restore(NfcDevice* dev, bool use_load_path); +bool nfc_device_restore(NfcDevice* dev); diff --git a/applications/nfc/scenes/nfc_scene_delete.c b/applications/nfc/scenes/nfc_scene_delete.c index 1946b9290..e8ba3e440 100755 --- a/applications/nfc/scenes/nfc_scene_delete.c +++ b/applications/nfc/scenes/nfc_scene_delete.c @@ -73,7 +73,7 @@ bool nfc_scene_delete_on_event(void* context, SceneManagerEvent event) { if(event.event == GuiButtonTypeLeft) { return scene_manager_previous_scene(nfc->scene_manager); } else if(event.event == GuiButtonTypeRight) { - if(nfc_device_delete(nfc->dev, true)) { + if(nfc_device_delete(nfc->dev)) { scene_manager_next_scene(nfc->scene_manager, NfcSceneDeleteSuccess); } else { scene_manager_search_and_switch_to_previous_scene( diff --git a/applications/nfc/scenes/nfc_scene_save_name.c b/applications/nfc/scenes/nfc_scene_save_name.c index d5e05472a..e95c97eb4 100755 --- a/applications/nfc/scenes/nfc_scene_save_name.c +++ b/applications/nfc/scenes/nfc_scene_save_name.c @@ -1,8 +1,6 @@ #include "../nfc_i.h" -#include "m-string.h" #include #include -#include void nfc_scene_save_name_text_input_callback(void* context) { Nfc* nfc = context; @@ -31,22 +29,11 @@ void nfc_scene_save_name_on_enter(void* context) { NFC_DEV_NAME_MAX_LEN, dev_name_empty); - string_t folder_path; - string_init(folder_path); - - if(string_end_with_str_p(nfc->dev->load_path, NFC_APP_EXTENSION)) { - path_extract_dirname(string_get_cstr(nfc->dev->load_path), folder_path); - } else { - string_set_str(folder_path, NFC_APP_FOLDER); - } - - ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), NFC_APP_EXTENSION, nfc->dev->dev_name); + ValidatorIsFile* validator_is_file = + validator_is_file_alloc_init(NFC_APP_FOLDER, NFC_APP_EXTENSION, nfc->dev->dev_name); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextInput); - - string_clear(folder_path); } bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) { @@ -56,7 +43,7 @@ bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventTextInputDone) { if(strcmp(nfc->dev->dev_name, "")) { - nfc_device_delete(nfc->dev, true); + nfc_device_delete(nfc->dev); } if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetUid)) { nfc->dev->dev_data.nfc_data = nfc->dev_edit_data; diff --git a/applications/nfc/scenes/nfc_scene_save_success.c b/applications/nfc/scenes/nfc_scene_save_success.c index 5c15a509a..985897a6d 100644 --- a/applications/nfc/scenes/nfc_scene_save_success.c +++ b/applications/nfc/scenes/nfc_scene_save_success.c @@ -30,6 +30,9 @@ bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) { if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneCardMenu)) { consumed = scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneCardMenu); + } else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) { + consumed = scene_manager_search_and_switch_to_another_scene( + nfc->scene_manager, NfcSceneFileSelect); } else if(scene_manager_has_previous_scene( nfc->scene_manager, NfcSceneMifareDesfireMenu)) { consumed = scene_manager_search_and_switch_to_previous_scene( diff --git a/applications/nfc/scenes/nfc_scene_saved_menu.c b/applications/nfc/scenes/nfc_scene_saved_menu.c index f2b2dea37..1b435ccd1 100644 --- a/applications/nfc/scenes/nfc_scene_saved_menu.c +++ b/applications/nfc/scenes/nfc_scene_saved_menu.c @@ -78,7 +78,7 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo); consumed = true; } else if(event.event == SubmenuIndexRestoreOriginal) { - if(!nfc_device_restore(nfc->dev, true)) { + if(!nfc_device_restore(nfc->dev)) { scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneStart); } else { diff --git a/applications/nfc/scenes/nfc_scene_set_type.c b/applications/nfc/scenes/nfc_scene_set_type.c index 0fe63424f..0dbb4f7ea 100755 --- a/applications/nfc/scenes/nfc_scene_set_type.c +++ b/applications/nfc/scenes/nfc_scene_set_type.c @@ -1,5 +1,4 @@ #include "../nfc_i.h" -#include "m-string.h" enum SubmenuIndex { SubmenuIndexNFCA4, @@ -17,7 +16,6 @@ void nfc_scene_set_type_on_enter(void* context) { Submenu* submenu = nfc->submenu; // Clear device name nfc_device_set_name(nfc->dev, ""); - string_set_str(nfc->dev->load_path, ""); submenu_add_item( submenu, "NFC-A 7-bytes UID", SubmenuIndexNFCA7, nfc_scene_set_type_submenu_callback, nfc); submenu_add_item( diff --git a/applications/notification/notification_settings_app.c b/applications/notification/notification_settings_app.c index bcb1b6a27..8254473fe 100644 --- a/applications/notification/notification_settings_app.c +++ b/applications/notification/notification_settings_app.c @@ -46,16 +46,17 @@ const char* const volume_text[VOLUME_COUNT] = { }; const float volume_value[VOLUME_COUNT] = {0.0f, 0.25f, 0.5f, 0.75f, 1.0f}; -#define DELAY_COUNT 6 +#define DELAY_COUNT 7 const char* const delay_text[DELAY_COUNT] = { "1s", "5s", "15s", "30s", "60s", + "90s", "120s", }; -const uint32_t delay_value[DELAY_COUNT] = {1000, 5000, 15000, 30000, 60000, 120000}; +const uint32_t delay_value[DELAY_COUNT] = {1000, 5000, 15000, 30000, 60000, 90000, 120000}; #define VIBRO_COUNT 2 const char* const vibro_text[VIBRO_COUNT] = { diff --git a/applications/snake_game/snake_game.c b/applications/snake_game/snake_game.c index bb9e207de..b07210ee5 100644 --- a/applications/snake_game/snake_game.c +++ b/applications/snake_game/snake_game.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include typedef struct { // +-----x @@ -298,6 +300,11 @@ static void snake_game_process_game_step(SnakeState* const snake_state) { bool eatFruit = (next_step.x == snake_state->fruit.x) && (next_step.y == snake_state->fruit.y); if(eatFruit) { + NotificationApp* notification = furi_record_open("notification"); + notification_message(notification, &sequence_single_vibro); + notification_message(notification, &sequence_blink_white_100); + furi_record_close("notification"); + snake_state->len++; if(snake_state->len >= MAX_SNAKE_LEN) { snake_state->state = GameStateGameOver; diff --git a/applications/subghz/scenes/subghz_scene_delete.c b/applications/subghz/scenes/subghz_scene_delete.c index 43151de20..83d6d4751 100644 --- a/applications/subghz/scenes/subghz_scene_delete.c +++ b/applications/subghz/scenes/subghz_scene_delete.c @@ -49,7 +49,7 @@ bool subghz_scene_delete_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneDelete) { - string_set(subghz->file_path_tmp, subghz->file_path); + strncpy(subghz->file_path_tmp, subghz->file_path, SUBGHZ_MAX_LEN_NAME); if(subghz_delete_file(subghz)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess); } else { diff --git a/applications/subghz/scenes/subghz_scene_delete_raw.c b/applications/subghz/scenes/subghz_scene_delete_raw.c index a20968d5b..03f0eb81b 100644 --- a/applications/subghz/scenes/subghz_scene_delete_raw.c +++ b/applications/subghz/scenes/subghz_scene_delete_raw.c @@ -24,7 +24,7 @@ void subghz_scene_delete_raw_on_enter(void* context) { char delete_str[SUBGHZ_MAX_LEN_NAME + 16]; string_t file_name; string_init(file_name); - path_extract_filename(subghz->file_path, file_name, true); + path_extract_filename_no_ext(subghz->file_path, file_name); snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", string_get_cstr(file_name)); string_clear(file_name); @@ -61,7 +61,7 @@ bool subghz_scene_delete_raw_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneDeleteRAW) { - string_set(subghz->file_path_tmp, subghz->file_path); + strncpy(subghz->file_path_tmp, subghz->file_path, SUBGHZ_MAX_LEN_NAME); if(subghz_delete_file(subghz)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess); } else { diff --git a/applications/subghz/scenes/subghz_scene_more_raw.c b/applications/subghz/scenes/subghz_scene_more_raw.c index a5bade927..54bd08158 100644 --- a/applications/subghz/scenes/subghz_scene_more_raw.c +++ b/applications/subghz/scenes/subghz_scene_more_raw.c @@ -45,7 +45,7 @@ bool subghz_scene_more_raw_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteRAW); return true; } else if(event.event == SubmenuIndexEdit) { - string_reset(subghz->file_path_tmp); + memset(subghz->file_path_tmp, 0, sizeof(subghz->file_path_tmp)); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneMoreRAW, SubmenuIndexEdit); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); diff --git a/applications/subghz/scenes/subghz_scene_save_name.c b/applications/subghz/scenes/subghz_scene_save_name.c index 95fc19388..617709cc7 100644 --- a/applications/subghz/scenes/subghz_scene_save_name.c +++ b/applications/subghz/scenes/subghz_scene_save_name.c @@ -1,6 +1,4 @@ #include "../subghz_i.h" -#include "m-string.h" -#include "subghz/types.h" #include #include "../helpers/subghz_custom_event.h" #include @@ -22,49 +20,45 @@ void subghz_scene_save_name_on_enter(void* context) { bool dev_name_empty = false; string_t file_name; - string_t dir_name; string_init(file_name); - string_init(dir_name); - if(!subghz_path_is_file(subghz->file_path)) { + if(!strcmp(subghz->file_path, "")) { char file_name_buf[SUBGHZ_MAX_LEN_NAME] = {0}; set_random_name(file_name_buf, SUBGHZ_MAX_LEN_NAME); - string_set_str(file_name, file_name_buf); - string_set_str(subghz->file_path, SUBGHZ_APP_FOLDER); + string_set(file_name, file_name_buf); + strncpy(subghz->file_dir, SUBGHZ_APP_FOLDER, SUBGHZ_MAX_LEN_NAME); //highlighting the entire filename by default dev_name_empty = true; } else { - string_set(subghz->file_path_tmp, subghz->file_path); - path_extract_dirname(string_get_cstr(subghz->file_path), dir_name); - path_extract_filename(subghz->file_path, file_name, true); + strncpy(subghz->file_path_tmp, subghz->file_path, SUBGHZ_MAX_LEN_NAME); + path_extract_dirname(subghz->file_path, file_name); + strncpy(subghz->file_dir, string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME); + path_extract_filename_no_ext(subghz->file_path, file_name); if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerNoSet) { subghz_get_next_name_file(subghz, SUBGHZ_MAX_LEN_NAME); - path_extract_filename(subghz->file_path, file_name, true); + path_extract_filename_no_ext(subghz->file_path, file_name); if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) == SubGhzCustomEventManagerSetRAW) { dev_name_empty = true; } } - string_set(subghz->file_path, dir_name); } - - strncpy(subghz->file_name_tmp, string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME); + strncpy(subghz->file_path, string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME); text_input_set_header_text(text_input, "Name signal"); text_input_set_result_callback( text_input, subghz_scene_save_name_text_input_callback, subghz, - subghz->file_name_tmp, + subghz->file_path, MAX_TEXT_INPUT_LEN, // buffer size dev_name_empty); - ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(subghz->file_path), SUBGHZ_APP_EXTENSION, NULL); + ValidatorIsFile* validator_is_file = + validator_is_file_alloc_init(subghz->file_dir, SUBGHZ_APP_EXTENSION, NULL); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); string_clear(file_name); - string_clear(dir_name); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdTextInput); } @@ -72,15 +66,18 @@ void subghz_scene_save_name_on_enter(void* context) { bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeBack) { - string_set(subghz->file_path, subghz->file_path_tmp); + strncpy(subghz->file_path, subghz->file_path_tmp, SUBGHZ_MAX_LEN_NAME); scene_manager_previous_scene(subghz->scene_manager); return true; } else if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneSaveName) { - if(strcmp(subghz->file_name_tmp, "")) { - string_cat_printf( - subghz->file_path, "/%s%s", subghz->file_name_tmp, SUBGHZ_APP_EXTENSION); - if(subghz_path_is_file(subghz->file_path_tmp)) { + if(strcmp(subghz->file_path, "")) { + string_t temp_str; + string_init_printf( + temp_str, "%s/%s%s", subghz->file_dir, subghz->file_path, SUBGHZ_APP_EXTENSION); + strncpy(subghz->file_path, string_get_cstr(temp_str), SUBGHZ_MAX_LEN_NAME); + string_clear(temp_str); + if(strcmp(subghz->file_path_tmp, "")) { if(!subghz_rename_file(subghz)) { return false; } @@ -88,7 +85,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType) != SubGhzCustomEventManagerNoSet) { subghz_save_protocol_to_file( - subghz, subghz->txrx->fff_data, string_get_cstr(subghz->file_path)); + subghz, subghz->txrx->fff_data, subghz->file_path); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneSetType, @@ -98,14 +95,13 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { subghz, subghz_history_get_raw_data( subghz->txrx->history, subghz->txrx->idx_menu_chosen), - string_get_cstr(subghz->file_path)); + subghz->file_path); } } if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerNoSet) { - subghz_protocol_raw_gen_fff_data( - subghz->txrx->fff_data, string_get_cstr(subghz->file_path)); + subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, subghz->file_path); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet); } else { @@ -115,7 +111,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess); return true; } else { - string_set_str(subghz->error_str, "No name file"); + string_set(subghz->error_str, "No name file"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); return true; } diff --git a/applications/subghz/scenes/subghz_scene_transmitter.c b/applications/subghz/scenes/subghz_scene_transmitter.c index b8b22749c..38ab84994 100644 --- a/applications/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/subghz/scenes/subghz_scene_transmitter.c @@ -94,7 +94,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneStart); return true; } else if(event.event == SubGhzCustomEventViewTransmitterError) { - string_set_str(subghz->error_str, "Protocol not found"); + string_set(subghz->error_str, "Protocol not found"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); } } else if(event.type == SceneManagerEventTypeTick) { diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 6c92a5d6b..f919e1cf2 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -303,7 +303,7 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { UNUSED(context); string_t file_name; string_init(file_name); - string_set_str(file_name, "/any/subghz/test.sub"); + string_set(file_name, "/any/subghz/test.sub"); Storage* storage = furi_record_open("storage"); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); diff --git a/applications/subghz/subghz_history.c b/applications/subghz/subghz_history.c index a8f86eecb..cb30726ba 100644 --- a/applications/subghz/subghz_history.c +++ b/applications/subghz/subghz_history.c @@ -169,14 +169,14 @@ bool subghz_history_add_to_history( break; } if(!strcmp(string_get_cstr(instance->tmp_string), "KeeLoq")) { - string_set_str(instance->tmp_string, "KL "); + string_set(instance->tmp_string, "KL "); if(!flipper_format_read_string(item->flipper_string, "Manufacture", text)) { FURI_LOG_E(TAG, "Missing Protocol"); break; } string_cat(instance->tmp_string, text); } else if(!strcmp(string_get_cstr(instance->tmp_string), "Star Line")) { - string_set_str(instance->tmp_string, "SL "); + string_set(instance->tmp_string, "SL "); if(!flipper_format_read_string(item->flipper_string, "Manufacture", text)) { FURI_LOG_E(TAG, "Missing Protocol"); break; diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index 5439fd2a9..690e85f74 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -1,8 +1,5 @@ #include "subghz_i.h" -#include "assets_icons.h" -#include "m-string.h" -#include "subghz/types.h" #include #include #include @@ -48,11 +45,11 @@ void subghz_get_frequency_modulation(SubGhz* subghz, string_t frequency, string_ if(modulation != NULL) { if(subghz->txrx->preset == FuriHalSubGhzPresetOok650Async || subghz->txrx->preset == FuriHalSubGhzPresetOok270Async) { - string_set_str(modulation, "AM"); + string_set(modulation, "AM"); } else if( subghz->txrx->preset == FuriHalSubGhzPreset2FSKDev238Async || subghz->txrx->preset == FuriHalSubGhzPreset2FSKDev476Async) { - string_set_str(modulation, "FM"); + string_set(modulation, "FM"); } else { furi_crash("SugGhz: Modulation is incorrect."); } @@ -194,9 +191,8 @@ void subghz_tx_stop(SubGhz* subghz) { //if protocol dynamic then we save the last upload if((subghz->txrx->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) && - (subghz_path_is_file(subghz->file_path))) { - subghz_save_protocol_to_file( - subghz, subghz->txrx->fff_data, string_get_cstr(subghz->file_path)); + (strcmp(subghz->file_path, ""))) { + subghz_save_protocol_to_file(subghz, subghz->txrx->fff_data, subghz->file_path); } subghz_idle(subghz); notification_message(subghz->notifications, &sequence_reset_red); @@ -338,10 +334,10 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) { bool res = false; - if(subghz_path_is_file(subghz->file_path)) { + if(strcmp(subghz->file_path, "")) { //get the name of the next free file - path_extract_filename(subghz->file_path, file_name, true); - path_extract_dirname(string_get_cstr(subghz->file_path), file_path); + path_extract_filename_no_ext(subghz->file_path, file_name); + path_extract_dirname(subghz->file_path, file_path); storage_get_next_filename( storage, @@ -357,7 +353,7 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) { string_get_cstr(file_path), string_get_cstr(file_name), SUBGHZ_APP_EXTENSION); - string_set(subghz->file_path, temp_str); + strncpy(subghz->file_path, string_get_cstr(temp_str), SUBGHZ_MAX_LEN_NAME); res = true; } @@ -417,17 +413,19 @@ bool subghz_load_protocol_from_file(SubGhz* subghz) { string_init(file_path); // Input events and views are managed by file_select - bool res = dialog_file_browser_show( + bool res = dialog_file_select_show( subghz->dialogs, - subghz->file_path, - subghz->file_path, + SUBGHZ_APP_FOLDER, SUBGHZ_APP_EXTENSION, - true, - &I_sub1_10px, - true); + subghz->file_path, + sizeof(subghz->file_path), + NULL); if(res) { - res = subghz_key_load(subghz, string_get_cstr(subghz->file_path)); + string_printf( + file_path, "%s/%s%s", SUBGHZ_APP_FOLDER, subghz->file_path, SUBGHZ_APP_EXTENSION); + strncpy(subghz->file_path, string_get_cstr(file_path), SUBGHZ_MAX_LEN_NAME); + res = subghz_key_load(subghz, subghz->file_path); } string_clear(file_path); @@ -441,9 +439,9 @@ bool subghz_rename_file(SubGhz* subghz) { Storage* storage = furi_record_open("storage"); - if(string_cmp(subghz->file_path_tmp, subghz->file_path)) { - FS_Error fs_result = storage_common_rename( - storage, string_get_cstr(subghz->file_path_tmp), string_get_cstr(subghz->file_path)); + if(strcmp(subghz->file_path_tmp, subghz->file_path)) { + FS_Error fs_result = + storage_common_rename(storage, subghz->file_path_tmp, subghz->file_path); if(fs_result != FSE_OK) { dialog_message_show_storage_error(subghz->dialogs, "Cannot rename\n file/directory"); @@ -459,7 +457,7 @@ bool subghz_delete_file(SubGhz* subghz) { furi_assert(subghz); Storage* storage = furi_record_open("storage"); - bool result = storage_simply_remove(storage, string_get_cstr(subghz->file_path_tmp)); + bool result = storage_simply_remove(storage, subghz->file_path_tmp); furi_record_close("storage"); subghz_file_name_clear(subghz); @@ -469,12 +467,8 @@ bool subghz_delete_file(SubGhz* subghz) { void subghz_file_name_clear(SubGhz* subghz) { furi_assert(subghz); - string_set_str(subghz->file_path, SUBGHZ_APP_FOLDER); - string_reset(subghz->file_path_tmp); -} - -bool subghz_path_is_file(string_t path) { - return string_end_with_str_p(path, SUBGHZ_APP_EXTENSION); + memset(subghz->file_path, 0, sizeof(subghz->file_path)); + memset(subghz->file_path_tmp, 0, sizeof(subghz->file_path_tmp)); } uint32_t subghz_random_serial(void) { diff --git a/applications/subghz/views/receiver.c b/applications/subghz/views/receiver.c index 866d82726..7b19cbcf2 100644 --- a/applications/subghz/views/receiver.c +++ b/applications/subghz/views/receiver.c @@ -111,9 +111,9 @@ void subghz_view_receiver_add_data_statusbar( furi_assert(subghz_receiver); with_view_model( subghz_receiver->view, (SubGhzViewReceiverModel * model) { - string_set_str(model->frequency_str, frequency_str); - string_set_str(model->preset_str, preset_str); - string_set_str(model->history_stat_str, history_stat_str); + string_set(model->frequency_str, frequency_str); + string_set(model->preset_str, preset_str); + string_set(model->history_stat_str, history_stat_str); return true; }); } diff --git a/applications/subghz/views/subghz_read_raw.c b/applications/subghz/views/subghz_read_raw.c index a4807d775..ff3ba45a3 100644 --- a/applications/subghz/views/subghz_read_raw.c +++ b/applications/subghz/views/subghz_read_raw.c @@ -46,8 +46,8 @@ void subghz_read_raw_add_data_statusbar( furi_assert(instance); with_view_model( instance->view, (SubGhzReadRAWModel * model) { - string_set_str(model->frequency_str, frequency_str); - string_set_str(model->preset_str, preset_str); + string_set(model->frequency_str, frequency_str); + string_set(model->preset_str, preset_str); return true; }); } @@ -372,7 +372,7 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { model->satus = SubGhzReadRAWStatusStart; model->rssi_history_end = false; model->ind_write = 0; - string_set_str(model->sample_write, "0 spl."); + string_set(model->sample_write, "0 spl."); string_reset(model->file_name); instance->callback(SubGhzCustomEventViewReadRAWErase, instance->context); } @@ -424,7 +424,7 @@ void subghz_read_raw_set_status( model->rssi_history_end = false; model->ind_write = 0; string_reset(model->file_name); - string_set_str(model->sample_write, "0 spl."); + string_set(model->sample_write, "0 spl."); return true; }); break; @@ -441,8 +441,8 @@ void subghz_read_raw_set_status( model->satus = SubGhzReadRAWStatusLoadKeyIDLE; model->rssi_history_end = false; model->ind_write = 0; - string_set_str(model->file_name, file_name); - string_set_str(model->sample_write, "RAW"); + string_set(model->file_name, file_name); + string_set(model->sample_write, "RAW"); return true; }); break; @@ -451,8 +451,8 @@ void subghz_read_raw_set_status( instance->view, (SubGhzReadRAWModel * model) { model->satus = SubGhzReadRAWStatusLoadKeyIDLE; if(!model->ind_write) { - string_set_str(model->file_name, file_name); - string_set_str(model->sample_write, "RAW"); + string_set(model->file_name, file_name); + string_set(model->sample_write, "RAW"); } else { string_reset(model->file_name); } diff --git a/applications/subghz/views/transmitter.c b/applications/subghz/views/transmitter.c index 3cbcf098a..3113e31f6 100644 --- a/applications/subghz/views/transmitter.c +++ b/applications/subghz/views/transmitter.c @@ -36,9 +36,9 @@ void subghz_view_transmitter_add_data_to_show( furi_assert(subghz_transmitter); with_view_model( subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { - string_set_str(model->key_str, key_str); - string_set_str(model->frequency_str, frequency_str); - string_set_str(model->preset_str, preset_str); + string_set(model->key_str, key_str); + string_set(model->frequency_str, frequency_str); + string_set(model->preset_str, preset_str); model->show_button = show_button; return true; }); diff --git a/assets/icons/Archive/music_10px.png b/assets/icons/Archive/music_10px.png deleted file mode 100644 index d41eb0db8..000000000 Binary files a/assets/icons/Archive/music_10px.png and /dev/null differ diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk index 8e58a71c9..4b019cae8 100644 --- a/firmware/targets/f7/target.mk +++ b/firmware/targets/f7/target.mk @@ -19,9 +19,8 @@ endif MCU_FLAGS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard # Warnings configuration -CFLAGS += -Wall -Wextra -Wredundant-decls -Wdouble-promotion +CFLAGS += $(MCU_FLAGS) -DSTM32WB55xx -Wall -fdata-sections -ffunction-sections -CFLAGS += $(MCU_FLAGS) -DSTM32WB55xx -fdata-sections -ffunction-sections -fsingle-precision-constant LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions diff --git a/lib/one_wire/ibutton/ibutton_key.c b/lib/one_wire/ibutton/ibutton_key.c index 2c0f7fa26..c6d4466f0 100644 --- a/lib/one_wire/ibutton/ibutton_key.c +++ b/lib/one_wire/ibutton/ibutton_key.c @@ -4,6 +4,7 @@ struct iButtonKey { uint8_t data[IBUTTON_KEY_DATA_SIZE]; + char name[IBUTTON_KEY_NAME_SIZE]; iButtonKeyType type; }; @@ -41,6 +42,14 @@ uint8_t ibutton_key_get_data_size(iButtonKey* key) { return ibutton_key_get_size_by_type(key->type); } +void ibutton_key_set_name(iButtonKey* key, const char* name) { + strlcpy(key->name, name, IBUTTON_KEY_NAME_SIZE); +} + +const char* ibutton_key_get_name_p(iButtonKey* key) { + return key->name; +} + void ibutton_key_set_type(iButtonKey* key, iButtonKeyType key_type) { key->type = key_type; } diff --git a/lib/one_wire/ibutton/ibutton_key.h b/lib/one_wire/ibutton/ibutton_key.h index f66537d7e..8d6732bcb 100644 --- a/lib/one_wire/ibutton/ibutton_key.h +++ b/lib/one_wire/ibutton/ibutton_key.h @@ -68,6 +68,20 @@ const uint8_t* ibutton_key_get_data_p(iButtonKey* key); */ uint8_t ibutton_key_get_data_size(iButtonKey* key); +/** + * Set key name + * @param key + * @param name + */ +void ibutton_key_set_name(iButtonKey* key, const char* name); + +/** + * Get pointer to key name + * @param key + * @return const char* + */ +const char* ibutton_key_get_name_p(iButtonKey* key); + /** * Set key type * @param key diff --git a/lib/subghz/subghz_keystore.c b/lib/subghz/subghz_keystore.c index d3903bc51..d64e1fda2 100644 --- a/lib/subghz/subghz_keystore.c +++ b/lib/subghz/subghz_keystore.c @@ -334,6 +334,7 @@ bool subghz_keystore_save(SubGhzKeystore* instance, const char* file_name, uint8 SubGhzKeyArray_t* subghz_keystore_get_data(SubGhzKeystore* instance) { furi_assert(instance); return &instance->data; + FURI_LOG_I(TAG, "array: \n", &instance->data); } bool subghz_keystore_raw_encrypted_save( diff --git a/lib/toolbox/path.c b/lib/toolbox/path.c index a99e57d1f..4fd042e41 100644 --- a/lib/toolbox/path.c +++ b/lib/toolbox/path.c @@ -19,20 +19,6 @@ void path_extract_filename_no_ext(const char* path, string_t filename) { string_mid(filename, start_position, end_position - start_position); } -void path_extract_filename(string_t path, string_t name, bool trim_ext) { - size_t filename_start = string_search_rchar(path, '/'); - if(filename_start > 0) { - filename_start++; - string_set_n(name, path, filename_start, string_size(path) - filename_start); - } - if(trim_ext) { - size_t dot = string_search_rchar(name, '.'); - if(dot > 0) { - string_left(name, dot); - } - } -} - static inline void path_cleanup(string_t path) { string_strim(path); while(string_end_with_str_p(path, "/")) { diff --git a/lib/toolbox/path.h b/lib/toolbox/path.h index 76e501cc1..0de63bb2b 100644 --- a/lib/toolbox/path.h +++ b/lib/toolbox/path.h @@ -14,15 +14,6 @@ extern "C" { */ void path_extract_filename_no_ext(const char* path, string_t filename); -/** - * @brief Extract filename string from path. - * - * @param path path string - * @param filename output filename string. Must be initialized before. - * @param trim_ext true - get filename without extension - */ -void path_extract_filename(string_t path, string_t filename, bool trim_ext); - /** * @brief Extract last path component *