[FL-2212] File validators and archive fixes #972
Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									84410c83b5
								
							
						
					
					
						commit
						6264ee8c3b
					
				| @ -25,4 +25,5 @@ struct ArchiveApp { | |||||||
|     ArchiveBrowserView* browser; |     ArchiveBrowserView* browser; | ||||||
|     TextInput* text_input; |     TextInput* text_input; | ||||||
|     char text_store[MAX_NAME_LEN]; |     char text_store[MAX_NAME_LEN]; | ||||||
|  |     char file_extension[MAX_EXT_LEN + 1]; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -272,7 +272,6 @@ void archive_enter_dir(ArchiveBrowserView* browser, string_t name) { | |||||||
|     with_view_model( |     with_view_model( | ||||||
|         browser->view, (ArchiveBrowserViewModel * model) { |         browser->view, (ArchiveBrowserViewModel * model) { | ||||||
|             model->last_idx = model->idx; |             model->last_idx = model->idx; | ||||||
|             model->last_offset = model->list_offset; |  | ||||||
|             model->idx = 0; |             model->idx = 0; | ||||||
|             model->depth = CLAMP(model->depth + 1, MAX_DEPTH, 0); |             model->depth = CLAMP(model->depth + 1, MAX_DEPTH, 0); | ||||||
|             return false; |             return false; | ||||||
|  | |||||||
| @ -31,6 +31,40 @@ uint16_t archive_favorites_count(void* context) { | |||||||
|     return lines; |     return lines; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static bool archive_favourites_rescan() { | ||||||
|  |     string_t buffer; | ||||||
|  |     string_init(buffer); | ||||||
|  |     FileWorker* file_worker = file_worker_alloc(true); | ||||||
|  | 
 | ||||||
|  |     bool result = file_worker_open(file_worker, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); | ||||||
|  |     if(result) { | ||||||
|  |         while(1) { | ||||||
|  |             if(!file_worker_read_until(file_worker, buffer, '\n')) { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             if(!string_size(buffer)) { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool file_exists = false; | ||||||
|  |             file_worker_is_file_exist(file_worker, string_get_cstr(buffer), &file_exists); | ||||||
|  |             if(file_exists) { | ||||||
|  |                 archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     string_clear(buffer); | ||||||
|  | 
 | ||||||
|  |     file_worker_close(file_worker); | ||||||
|  |     file_worker_remove(file_worker, ARCHIVE_FAV_PATH); | ||||||
|  |     file_worker_rename(file_worker, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH); | ||||||
|  | 
 | ||||||
|  |     file_worker_free(file_worker); | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool archive_favorites_read(void* context) { | bool archive_favorites_read(void* context) { | ||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
| 
 | 
 | ||||||
| @ -41,6 +75,8 @@ bool archive_favorites_read(void* context) { | |||||||
|     FileInfo file_info; |     FileInfo file_info; | ||||||
|     string_init(buffer); |     string_init(buffer); | ||||||
| 
 | 
 | ||||||
|  |     bool need_refresh = false; | ||||||
|  | 
 | ||||||
|     bool result = file_worker_open(file_worker, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); |     bool result = file_worker_open(file_worker, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); | ||||||
| 
 | 
 | ||||||
|     if(result) { |     if(result) { | ||||||
| @ -52,13 +88,24 @@ bool archive_favorites_read(void* context) { | |||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             archive_add_item(browser, &file_info, string_get_cstr(buffer)); |             bool file_exists = false; | ||||||
|  |             file_worker_is_file_exist(file_worker, string_get_cstr(buffer), &file_exists); | ||||||
|  | 
 | ||||||
|  |             if(file_exists) | ||||||
|  |                 archive_add_item(browser, &file_info, string_get_cstr(buffer)); | ||||||
|  |             else | ||||||
|  |                 need_refresh = true; | ||||||
|             string_reset(buffer); |             string_reset(buffer); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     string_clear(buffer); |     string_clear(buffer); | ||||||
|     file_worker_close(file_worker); |     file_worker_close(file_worker); | ||||||
|     file_worker_free(file_worker); |     file_worker_free(file_worker); | ||||||
|  | 
 | ||||||
|  |     if(need_refresh) { | ||||||
|  |         archive_favourites_rescan(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -30,6 +30,14 @@ void archive_trim_file_path(char* name, bool ext) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void archive_get_file_extension(char* name, char* ext) { | ||||||
|  |     char* dot = strrchr(name, '.'); | ||||||
|  |     if(dot == NULL) | ||||||
|  |         *ext = '\0'; | ||||||
|  |     else | ||||||
|  |         strncpy(ext, dot, MAX_EXT_LEN); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void set_file_type(ArchiveFile_t* file, FileInfo* file_info) { | void set_file_type(ArchiveFile_t* file, FileInfo* file_info) { | ||||||
|     furi_assert(file); |     furi_assert(file); | ||||||
|     furi_assert(file_info); |     furi_assert(file_info); | ||||||
|  | |||||||
| @ -50,6 +50,7 @@ ARRAY_DEF( | |||||||
| bool filter_by_extension(FileInfo* file_info, const char* tab_ext, const char* name); | bool filter_by_extension(FileInfo* file_info, const char* tab_ext, const char* name); | ||||||
| void set_file_type(ArchiveFile_t* file, FileInfo* file_info); | void set_file_type(ArchiveFile_t* file, FileInfo* file_info); | ||||||
| void archive_trim_file_path(char* name, bool ext); | void archive_trim_file_path(char* name, bool ext); | ||||||
|  | void archive_get_file_extension(char* name, char* ext); | ||||||
| bool archive_get_filenames(void* context, const char* path); | bool archive_get_filenames(void* context, const char* path); | ||||||
| bool archive_dir_empty(void* context, const char* path); | bool archive_dir_empty(void* context, const char* path); | ||||||
| bool archive_read_dir(void* context, const char* path); | bool archive_read_dir(void* context, const char* path); | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ void archive_scene_rename_on_enter(void* context) { | |||||||
|     ArchiveFile_t* current = archive_get_current_file(archive->browser); |     ArchiveFile_t* current = archive_get_current_file(archive->browser); | ||||||
|     strlcpy(archive->text_store, string_get_cstr(current->name), MAX_NAME_LEN); |     strlcpy(archive->text_store, string_get_cstr(current->name), MAX_NAME_LEN); | ||||||
| 
 | 
 | ||||||
|  |     archive_get_file_extension(archive->text_store, archive->file_extension); | ||||||
|     archive_trim_file_path(archive->text_store, true); |     archive_trim_file_path(archive->text_store, true); | ||||||
| 
 | 
 | ||||||
|     text_input_set_header_text(text_input, "Rename:"); |     text_input_set_header_text(text_input, "Rename:"); | ||||||
| @ -30,6 +31,10 @@ void archive_scene_rename_on_enter(void* context) { | |||||||
|         MAX_TEXT_INPUT_LEN, |         MAX_TEXT_INPUT_LEN, | ||||||
|         false); |         false); | ||||||
| 
 | 
 | ||||||
|  |     ValidatorIsFile* validator_is_file = | ||||||
|  |         validator_is_file_alloc_init(archive_get_path(archive->browser), archive->file_extension); | ||||||
|  |     text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); | ||||||
|  | 
 | ||||||
|     view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewTextInput); |     view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewTextInput); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -74,6 +79,11 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { | |||||||
| 
 | 
 | ||||||
| void archive_scene_rename_on_exit(void* context) { | void archive_scene_rename_on_exit(void* context) { | ||||||
|     ArchiveApp* archive = (ArchiveApp*)context; |     ArchiveApp* archive = (ArchiveApp*)context; | ||||||
|  | 
 | ||||||
|     // Clear view
 |     // Clear view
 | ||||||
|  |     void* validator_context = text_input_get_validator_callback_context(archive->text_input); | ||||||
|  |     text_input_set_validator(archive->text_input, NULL, NULL); | ||||||
|  |     validator_is_file_free(validator_context); | ||||||
|  | 
 | ||||||
|     text_input_reset(archive->text_input); |     text_input_reset(archive->text_input); | ||||||
| } | } | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ | |||||||
| 
 | 
 | ||||||
| #define MAX_LEN_PX 110 | #define MAX_LEN_PX 110 | ||||||
| #define MAX_NAME_LEN 255 | #define MAX_NAME_LEN 255 | ||||||
|  | #define MAX_EXT_LEN 6 | ||||||
| #define FRAME_HEIGHT 12 | #define FRAME_HEIGHT 12 | ||||||
| #define MENU_ITEMS 4 | #define MENU_ITEMS 4 | ||||||
| #define MAX_DEPTH 32 | #define MAX_DEPTH 32 | ||||||
|  | |||||||
| @ -18,6 +18,9 @@ void desktop_scene_lock_menu_on_enter(void* context) { | |||||||
| 
 | 
 | ||||||
|     desktop_lock_menu_set_callback(desktop->lock_menu, desktop_scene_lock_menu_callback, desktop); |     desktop_lock_menu_set_callback(desktop->lock_menu, desktop_scene_lock_menu_callback, desktop); | ||||||
|     desktop_lock_menu_pin_set(desktop->lock_menu, desktop->settings.pincode.length > 0); |     desktop_lock_menu_pin_set(desktop->lock_menu, desktop->settings.pincode.length > 0); | ||||||
|  | 
 | ||||||
|  |     uint8_t idx = scene_manager_get_scene_state(desktop->scene_manager, DesktopSceneLockMenu); | ||||||
|  |     desktop_lock_menu_set_idx(desktop->lock_menu, idx); | ||||||
|     view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewLockMenu); |     view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewLockMenu); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -30,6 +33,7 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) { | |||||||
|         case DesktopLockMenuEventLock: |         case DesktopLockMenuEventLock: | ||||||
|             scene_manager_set_scene_state( |             scene_manager_set_scene_state( | ||||||
|                 desktop->scene_manager, DesktopSceneMain, DesktopMainSceneStateLockedNoPin); |                 desktop->scene_manager, DesktopSceneMain, DesktopMainSceneStateLockedNoPin); | ||||||
|  |             scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 0); | ||||||
|             scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain); |             scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain); | ||||||
|             consumed = true; |             consumed = true; | ||||||
|             break; |             break; | ||||||
| @ -39,12 +43,14 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) { | |||||||
|                     desktop->scene_manager, DesktopSceneMain, DesktopMainSceneStateLockedWithPin); |                     desktop->scene_manager, DesktopSceneMain, DesktopMainSceneStateLockedWithPin); | ||||||
|                 scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain); |                 scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain); | ||||||
|             } else { |             } else { | ||||||
|  |                 scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 1); | ||||||
|                 scene_manager_next_scene(desktop->scene_manager, DesktopScenePinSetup); |                 scene_manager_next_scene(desktop->scene_manager, DesktopScenePinSetup); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             consumed = true; |             consumed = true; | ||||||
|             break; |             break; | ||||||
|         case DesktopLockMenuEventExit: |         case DesktopLockMenuEventExit: | ||||||
|  |             scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 0); | ||||||
|             scene_manager_search_and_switch_to_previous_scene( |             scene_manager_search_and_switch_to_previous_scene( | ||||||
|                 desktop->scene_manager, DesktopSceneMain); |                 desktop->scene_manager, DesktopSceneMain); | ||||||
|             consumed = true; |             consumed = true; | ||||||
| @ -57,6 +63,4 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void desktop_scene_lock_menu_on_exit(void* context) { | void desktop_scene_lock_menu_on_exit(void* context) { | ||||||
|     Desktop* desktop = (Desktop*)context; |  | ||||||
|     desktop_lock_menu_reset_idx(desktop->lock_menu); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -4,6 +4,8 @@ | |||||||
| #include "../desktop_i.h" | #include "../desktop_i.h" | ||||||
| #include "desktop_lock_menu.h" | #include "desktop_lock_menu.h" | ||||||
| 
 | 
 | ||||||
|  | #define LOCK_MENU_ITEMS_NB 3 | ||||||
|  | 
 | ||||||
| void desktop_lock_menu_set_callback( | void desktop_lock_menu_set_callback( | ||||||
|     DesktopLockMenuView* lock_menu, |     DesktopLockMenuView* lock_menu, | ||||||
|     DesktopLockMenuViewCallback callback, |     DesktopLockMenuViewCallback callback, | ||||||
| @ -22,10 +24,11 @@ void desktop_lock_menu_pin_set(DesktopLockMenuView* lock_menu, bool pin_is_set) | |||||||
|         }); |         }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void desktop_lock_menu_reset_idx(DesktopLockMenuView* lock_menu) { | void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx) { | ||||||
|  |     furi_assert(idx < LOCK_MENU_ITEMS_NB); | ||||||
|     with_view_model( |     with_view_model( | ||||||
|         lock_menu->view, (DesktopLockMenuViewModel * model) { |         lock_menu->view, (DesktopLockMenuViewModel * model) { | ||||||
|             model->idx = 0; |             model->idx = idx; | ||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
| } | } | ||||||
| @ -51,7 +54,7 @@ static void lock_menu_callback(void* context, uint8_t index) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void desktop_lock_menu_render(Canvas* canvas, void* model) { | void desktop_lock_menu_render(Canvas* canvas, void* model) { | ||||||
|     const char* Lockmenu_Items[3] = {"Lock", "Lock with PIN", "DUMB mode"}; |     const char* Lockmenu_Items[LOCK_MENU_ITEMS_NB] = {"Lock", "Lock with PIN", "DUMB mode"}; | ||||||
| 
 | 
 | ||||||
|     DesktopLockMenuViewModel* m = model; |     DesktopLockMenuViewModel* m = model; | ||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
| @ -60,14 +63,15 @@ void desktop_lock_menu_render(Canvas* canvas, void* model) { | |||||||
|     canvas_draw_icon(canvas, 116, 0 + STATUS_BAR_Y_SHIFT, &I_DoorRight_70x55); |     canvas_draw_icon(canvas, 116, 0 + STATUS_BAR_Y_SHIFT, &I_DoorRight_70x55); | ||||||
|     canvas_set_font(canvas, FontSecondary); |     canvas_set_font(canvas, FontSecondary); | ||||||
| 
 | 
 | ||||||
|     for(uint8_t i = 0; i < 3; ++i) { |     for(uint8_t i = 0; i < LOCK_MENU_ITEMS_NB; ++i) { | ||||||
|         const char* str = Lockmenu_Items[i]; |         const char* str = Lockmenu_Items[i]; | ||||||
| 
 | 
 | ||||||
|         if(i == 1 && !m->pin_set) str = "Set PIN"; |         if(i == 1 && !m->pin_set) str = "Set PIN"; | ||||||
|         if(m->hint_timeout && m->idx == 2 && m->idx == i) str = "Not implemented"; |         if(m->hint_timeout && m->idx == 2 && m->idx == i) str = "Not implemented"; | ||||||
| 
 | 
 | ||||||
|         canvas_draw_str_aligned( |         if(str != NULL) | ||||||
|             canvas, 64, 9 + (i * 17) + STATUS_BAR_Y_SHIFT, AlignCenter, AlignCenter, str); |             canvas_draw_str_aligned( | ||||||
|  |                 canvas, 64, 9 + (i * 17) + STATUS_BAR_Y_SHIFT, AlignCenter, AlignCenter, str); | ||||||
| 
 | 
 | ||||||
|         if(m->idx == i) elements_frame(canvas, 15, 1 + (i * 17) + STATUS_BAR_Y_SHIFT, 98, 15); |         if(m->idx == i) elements_frame(canvas, 15, 1 + (i * 17) + STATUS_BAR_Y_SHIFT, 98, 15); | ||||||
|     } |     } | ||||||
| @ -90,9 +94,9 @@ bool desktop_lock_menu_input(InputEvent* event, void* context) { | |||||||
|         lock_menu->view, (DesktopLockMenuViewModel * model) { |         lock_menu->view, (DesktopLockMenuViewModel * model) { | ||||||
|             model->hint_timeout = 0; // clear hint timeout
 |             model->hint_timeout = 0; // clear hint timeout
 | ||||||
|             if(event->key == InputKeyUp) { |             if(event->key == InputKeyUp) { | ||||||
|                 model->idx = CLAMP(model->idx - 1, 2, 0); |                 model->idx = CLAMP(model->idx - 1, LOCK_MENU_ITEMS_NB - 1, 0); | ||||||
|             } else if(event->key == InputKeyDown) { |             } else if(event->key == InputKeyDown) { | ||||||
|                 model->idx = CLAMP(model->idx + 1, 2, 0); |                 model->idx = CLAMP(model->idx + 1, LOCK_MENU_ITEMS_NB - 1, 0); | ||||||
|             } |             } | ||||||
|             idx = model->idx; |             idx = model->idx; | ||||||
|             return true; |             return true; | ||||||
|  | |||||||
| @ -28,6 +28,6 @@ void desktop_lock_menu_set_callback( | |||||||
| 
 | 
 | ||||||
| View* desktop_lock_menu_get_view(DesktopLockMenuView* lock_menu); | View* desktop_lock_menu_get_view(DesktopLockMenuView* lock_menu); | ||||||
| void desktop_lock_menu_pin_set(DesktopLockMenuView* lock_menu, bool pin_is_set); | void desktop_lock_menu_pin_set(DesktopLockMenuView* lock_menu, bool pin_is_set); | ||||||
| void desktop_lock_menu_reset_idx(DesktopLockMenuView* lock_menu); | void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx); | ||||||
| DesktopLockMenuView* desktop_lock_menu_alloc(); | DesktopLockMenuView* desktop_lock_menu_alloc(); | ||||||
| void desktop_lock_menu_free(DesktopLockMenuView* lock_menu); | void desktop_lock_menu_free(DesktopLockMenuView* lock_menu); | ||||||
|  | |||||||
| @ -64,6 +64,10 @@ public: | |||||||
|         SceneAddValue, |         SceneAddValue, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     static const char* app_folder; | ||||||
|  |     static const char* app_extension; | ||||||
|  |     static const char* app_filetype; | ||||||
|  | 
 | ||||||
|     iButtonAppViewManager* get_view_manager(); |     iButtonAppViewManager* get_view_manager(); | ||||||
|     void switch_to_next_scene(Scene index); |     void switch_to_next_scene(Scene index); | ||||||
|     void search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list); |     void search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list); | ||||||
| @ -137,10 +141,6 @@ private: | |||||||
|     static const uint8_t text_store_size = 128; |     static const uint8_t text_store_size = 128; | ||||||
|     char text_store[text_store_size + 1]; |     char text_store[text_store_size + 1]; | ||||||
| 
 | 
 | ||||||
|     static const char* app_folder; |  | ||||||
|     static const char* app_extension; |  | ||||||
|     static const char* app_filetype; |  | ||||||
| 
 |  | ||||||
|     bool load_key_data(string_t key_path); |     bool load_key_data(string_t key_path); | ||||||
|     void make_app_folder(); |     void make_app_folder(); | ||||||
| }; | }; | ||||||
| @ -25,6 +25,10 @@ void iButtonSceneSaveName::on_enter(iButtonApp* app) { | |||||||
|     text_input_set_result_callback( |     text_input_set_result_callback( | ||||||
|         text_input, callback, app, app->get_text_store(), IBUTTON_KEY_NAME_SIZE, key_name_empty); |         text_input, callback, app, app->get_text_store(), IBUTTON_KEY_NAME_SIZE, key_name_empty); | ||||||
| 
 | 
 | ||||||
|  |     ValidatorIsFile* validator_is_file = | ||||||
|  |         validator_is_file_alloc_init(app->app_folder, app->app_extension); | ||||||
|  |     text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); | ||||||
|  | 
 | ||||||
|     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewTextInput); |     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewTextInput); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -48,6 +52,11 @@ bool iButtonSceneSaveName::on_event(iButtonApp* app, iButtonEvent* event) { | |||||||
| 
 | 
 | ||||||
| void iButtonSceneSaveName::on_exit(iButtonApp* app) { | void iButtonSceneSaveName::on_exit(iButtonApp* app) { | ||||||
|     TextInput* text_input = app->get_view_manager()->get_text_input(); |     TextInput* text_input = app->get_view_manager()->get_text_input(); | ||||||
|  | 
 | ||||||
|  |     void* validator_context = text_input_get_validator_callback_context(text_input); | ||||||
|  |     text_input_set_validator(text_input, NULL, NULL); | ||||||
|  |     validator_is_file_free((ValidatorIsFile*)validator_context); | ||||||
|  | 
 | ||||||
|     text_input_reset(text_input); |     text_input_reset(text_input); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -20,6 +20,10 @@ void IrdaAppSceneEditRename::on_enter(IrdaApp* app) { | |||||||
|         strncpy(app->get_text_store(0), remote_name.c_str(), app->get_text_store_size()); |         strncpy(app->get_text_store(0), remote_name.c_str(), app->get_text_store_size()); | ||||||
|         enter_name_length = IrdaAppRemoteManager::max_remote_name_length; |         enter_name_length = IrdaAppRemoteManager::max_remote_name_length; | ||||||
|         text_input_set_header_text(text_input, "Name the remote"); |         text_input_set_header_text(text_input, "Name the remote"); | ||||||
|  | 
 | ||||||
|  |         ValidatorIsFile* validator_is_file = | ||||||
|  |             validator_is_file_alloc_init(app->irda_directory, app->irda_extension); | ||||||
|  |         text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     text_input_set_result_callback( |     text_input_set_result_callback( | ||||||
| @ -59,4 +63,10 @@ bool IrdaAppSceneEditRename::on_event(IrdaApp* app, IrdaAppEvent* event) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void IrdaAppSceneEditRename::on_exit(IrdaApp* app) { | void IrdaAppSceneEditRename::on_exit(IrdaApp* app) { | ||||||
|  |     TextInput* text_input = app->get_view_manager()->get_text_input(); | ||||||
|  | 
 | ||||||
|  |     void* validator_context = text_input_get_validator_callback_context(text_input); | ||||||
|  |     text_input_set_validator(text_input, NULL, NULL); | ||||||
|  | 
 | ||||||
|  |     if(validator_context != NULL) validator_is_file_free((ValidatorIsFile*)validator_context); | ||||||
| } | } | ||||||
|  | |||||||
| @ -35,9 +35,9 @@ void LfRfidAppSceneDeleteConfirm::on_enter(LfRfidApp* app, bool need_restore) { | |||||||
| 
 | 
 | ||||||
|     string_printf(string_header, "Delete %s?", key.get_name()); |     string_printf(string_header, "Delete %s?", key.get_name()); | ||||||
|     line_1->set_text( |     line_1->set_text( | ||||||
|         string_get_cstr(string_header), 64, 19, AlignCenter, AlignBottom, FontPrimary); |         string_get_cstr(string_header), 64, 19, 128 - 2, AlignCenter, AlignBottom, FontPrimary); | ||||||
|     line_2->set_text( |     line_2->set_text( | ||||||
|         string_get_cstr(string_data), 64, 29, AlignCenter, AlignBottom, FontSecondary); |         string_get_cstr(string_data), 64, 29, 0, AlignCenter, AlignBottom, FontSecondary); | ||||||
| 
 | 
 | ||||||
|     switch(key.get_type()) { |     switch(key.get_type()) { | ||||||
|     case LfrfidKeyType::KeyEM4100: |     case LfrfidKeyType::KeyEM4100: | ||||||
| @ -52,12 +52,13 @@ void LfRfidAppSceneDeleteConfirm::on_enter(LfRfidApp* app, bool need_restore) { | |||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     line_3->set_text( |     line_3->set_text( | ||||||
|         string_get_cstr(string_decrypted), 64, 39, AlignCenter, AlignBottom, FontSecondary); |         string_get_cstr(string_decrypted), 64, 39, 0, AlignCenter, AlignBottom, FontSecondary); | ||||||
| 
 | 
 | ||||||
|     line_4->set_text( |     line_4->set_text( | ||||||
|         lfrfid_key_get_type_string(key.get_type()), |         lfrfid_key_get_type_string(key.get_type()), | ||||||
|         64, |         64, | ||||||
|         49, |         49, | ||||||
|  |         0, | ||||||
|         AlignCenter, |         AlignCenter, | ||||||
|         AlignBottom, |         AlignBottom, | ||||||
|         FontSecondary); |         FontSecondary); | ||||||
|  | |||||||
| @ -36,9 +36,9 @@ void LfRfidAppSceneReadSuccess::on_enter(LfRfidApp* app, bool need_restore) { | |||||||
| 
 | 
 | ||||||
|     switch(app->worker.key.get_type()) { |     switch(app->worker.key.get_type()) { | ||||||
|     case LfrfidKeyType::KeyEM4100: |     case LfrfidKeyType::KeyEM4100: | ||||||
|         line_1_text->set_text("HEX:", 65, 23, AlignRight, AlignBottom, FontSecondary); |         line_1_text->set_text("HEX:", 65, 23, 0, AlignRight, AlignBottom, FontSecondary); | ||||||
|         line_2_text->set_text("Mod:", 65, 35, AlignRight, AlignBottom, FontSecondary); |         line_2_text->set_text("Mod:", 65, 35, 0, AlignRight, AlignBottom, FontSecondary); | ||||||
|         line_3_text->set_text("ID:", 65, 47, AlignRight, AlignBottom, FontSecondary); |         line_3_text->set_text("ID:", 65, 47, 0, AlignRight, AlignBottom, FontSecondary); | ||||||
| 
 | 
 | ||||||
|         for(uint8_t i = 0; i < app->worker.key.get_type_data_count(); i++) { |         for(uint8_t i = 0; i < app->worker.key.get_type_data_count(); i++) { | ||||||
|             string_cat_printf(string[0], "%02X", data[i]); |             string_cat_printf(string[0], "%02X", data[i]); | ||||||
| @ -48,17 +48,17 @@ void LfRfidAppSceneReadSuccess::on_enter(LfRfidApp* app, bool need_restore) { | |||||||
|         string_printf(string[2], "%03u,%05u", data[2], (uint16_t)((data[3] << 8) | (data[4]))); |         string_printf(string[2], "%03u,%05u", data[2], (uint16_t)((data[3] << 8) | (data[4]))); | ||||||
| 
 | 
 | ||||||
|         line_1_value->set_text( |         line_1_value->set_text( | ||||||
|             string_get_cstr(string[0]), 68, 23, AlignLeft, AlignBottom, FontSecondary); |             string_get_cstr(string[0]), 68, 23, 0, AlignLeft, AlignBottom, FontSecondary); | ||||||
|         line_2_value->set_text( |         line_2_value->set_text( | ||||||
|             string_get_cstr(string[1]), 68, 35, AlignLeft, AlignBottom, FontSecondary); |             string_get_cstr(string[1]), 68, 35, 0, AlignLeft, AlignBottom, FontSecondary); | ||||||
|         line_3_value->set_text( |         line_3_value->set_text( | ||||||
|             string_get_cstr(string[2]), 68, 47, AlignLeft, AlignBottom, FontSecondary); |             string_get_cstr(string[2]), 68, 47, 0, AlignLeft, AlignBottom, FontSecondary); | ||||||
|         break; |         break; | ||||||
|     case LfrfidKeyType::KeyH10301: |     case LfrfidKeyType::KeyH10301: | ||||||
|     case LfrfidKeyType::KeyI40134: |     case LfrfidKeyType::KeyI40134: | ||||||
|         line_1_text->set_text("HEX:", 65, 23, AlignRight, AlignBottom, FontSecondary); |         line_1_text->set_text("HEX:", 65, 23, 0, AlignRight, AlignBottom, FontSecondary); | ||||||
|         line_2_text->set_text("FC:", 65, 35, AlignRight, AlignBottom, FontSecondary); |         line_2_text->set_text("FC:", 65, 35, 0, AlignRight, AlignBottom, FontSecondary); | ||||||
|         line_3_text->set_text("Card:", 65, 47, AlignRight, AlignBottom, FontSecondary); |         line_3_text->set_text("Card:", 65, 47, 0, AlignRight, AlignBottom, FontSecondary); | ||||||
| 
 | 
 | ||||||
|         for(uint8_t i = 0; i < app->worker.key.get_type_data_count(); i++) { |         for(uint8_t i = 0; i < app->worker.key.get_type_data_count(); i++) { | ||||||
|             string_cat_printf(string[0], "%02X", data[i]); |             string_cat_printf(string[0], "%02X", data[i]); | ||||||
| @ -68,11 +68,11 @@ void LfRfidAppSceneReadSuccess::on_enter(LfRfidApp* app, bool need_restore) { | |||||||
|         string_printf(string[2], "%u", (uint16_t)((data[1] << 8) | (data[2]))); |         string_printf(string[2], "%u", (uint16_t)((data[1] << 8) | (data[2]))); | ||||||
| 
 | 
 | ||||||
|         line_1_value->set_text( |         line_1_value->set_text( | ||||||
|             string_get_cstr(string[0]), 68, 23, AlignLeft, AlignBottom, FontSecondary); |             string_get_cstr(string[0]), 68, 23, 0, AlignLeft, AlignBottom, FontSecondary); | ||||||
|         line_2_value->set_text( |         line_2_value->set_text( | ||||||
|             string_get_cstr(string[1]), 68, 35, AlignLeft, AlignBottom, FontSecondary); |             string_get_cstr(string[1]), 68, 35, 0, AlignLeft, AlignBottom, FontSecondary); | ||||||
|         line_3_value->set_text( |         line_3_value->set_text( | ||||||
|             string_get_cstr(string[2]), 68, 47, AlignLeft, AlignBottom, FontSecondary); |             string_get_cstr(string[2]), 68, 47, 0, AlignLeft, AlignBottom, FontSecondary); | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										9
									
								
								applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										9
									
								
								applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| @ -21,6 +21,10 @@ void LfRfidAppSceneSaveName::on_enter(LfRfidApp* app, bool need_restore) { | |||||||
|         app->worker.key.get_name_length(), |         app->worker.key.get_name_length(), | ||||||
|         key_name_empty); |         key_name_empty); | ||||||
| 
 | 
 | ||||||
|  |     ValidatorIsFile* validator_is_file = | ||||||
|  |         validator_is_file_alloc_init(app->app_folder, app->app_extension); | ||||||
|  |     text_input->set_validator(validator_is_file_callback, validator_is_file); | ||||||
|  | 
 | ||||||
|     app->view_controller.switch_to<TextInputVM>(); |     app->view_controller.switch_to<TextInputVM>(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -46,6 +50,11 @@ bool LfRfidAppSceneSaveName::on_event(LfRfidApp* app, LfRfidApp::Event* event) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LfRfidAppSceneSaveName::on_exit(LfRfidApp* app) { | void LfRfidAppSceneSaveName::on_exit(LfRfidApp* app) { | ||||||
|  |     void* validator_context = | ||||||
|  |         app->view_controller.get<TextInputVM>()->get_validator_callback_context(); | ||||||
|  |     app->view_controller.get<TextInputVM>()->set_validator(NULL, NULL); | ||||||
|  |     validator_is_file_free((ValidatorIsFile*)validator_context); | ||||||
|  | 
 | ||||||
|     app->view_controller.get<TextInputVM>()->clean(); |     app->view_controller.get<TextInputVM>()->clean(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -28,8 +28,9 @@ void LfRfidAppSceneSavedInfo::on_enter(LfRfidApp* app, bool need_restore) { | |||||||
|         string_cat_printf(string_data, "%02X", data[i]); |         string_cat_printf(string_data, "%02X", data[i]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     line_1->set_text(key.get_name(), 64, 17, AlignCenter, AlignBottom, FontSecondary); |     line_1->set_text(key.get_name(), 64, 17, 128 - 2, AlignCenter, AlignBottom, FontSecondary); | ||||||
|     line_2->set_text(string_get_cstr(string_data), 64, 29, AlignCenter, AlignBottom, FontPrimary); |     line_2->set_text( | ||||||
|  |         string_get_cstr(string_data), 64, 29, 0, AlignCenter, AlignBottom, FontPrimary); | ||||||
| 
 | 
 | ||||||
|     switch(key.get_type()) { |     switch(key.get_type()) { | ||||||
|     case LfrfidKeyType::KeyEM4100: |     case LfrfidKeyType::KeyEM4100: | ||||||
| @ -44,12 +45,13 @@ void LfRfidAppSceneSavedInfo::on_enter(LfRfidApp* app, bool need_restore) { | |||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     line_3->set_text( |     line_3->set_text( | ||||||
|         string_get_cstr(string_decrypted), 64, 39, AlignCenter, AlignBottom, FontSecondary); |         string_get_cstr(string_decrypted), 64, 39, 0, AlignCenter, AlignBottom, FontSecondary); | ||||||
| 
 | 
 | ||||||
|     line_4->set_text( |     line_4->set_text( | ||||||
|         lfrfid_key_get_type_string(key.get_type()), |         lfrfid_key_get_type_string(key.get_type()), | ||||||
|         64, |         64, | ||||||
|         49, |         49, | ||||||
|  |         0, | ||||||
|         AlignCenter, |         AlignCenter, | ||||||
|         AlignBottom, |         AlignBottom, | ||||||
|         FontSecondary); |         FontSecondary); | ||||||
|  | |||||||
| @ -9,8 +9,17 @@ StringElement::~StringElement() { | |||||||
| 
 | 
 | ||||||
| void StringElement::draw(Canvas* canvas) { | void StringElement::draw(Canvas* canvas) { | ||||||
|     if(text) { |     if(text) { | ||||||
|  |         string_t line; | ||||||
|  |         string_init(line); | ||||||
|  |         string_set_str(line, text); | ||||||
|  | 
 | ||||||
|         canvas_set_font(canvas, font); |         canvas_set_font(canvas, font); | ||||||
|         elements_multiline_text_aligned(canvas, x, y, horizontal, vertical, text); |         if(fit_width != 0) { | ||||||
|  |             elements_string_fit_width(canvas, line, fit_width); | ||||||
|  |         } | ||||||
|  |         elements_multiline_text_aligned(canvas, x, y, horizontal, vertical, string_get_cstr(line)); | ||||||
|  | 
 | ||||||
|  |         string_clear(line); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -22,6 +31,7 @@ void StringElement::set_text( | |||||||
|     const char* _text, |     const char* _text, | ||||||
|     uint8_t _x, |     uint8_t _x, | ||||||
|     uint8_t _y, |     uint8_t _y, | ||||||
|  |     uint8_t _fit_w, | ||||||
|     Align _horizontal, |     Align _horizontal, | ||||||
|     Align _vertical, |     Align _vertical, | ||||||
|     Font _font) { |     Font _font) { | ||||||
| @ -29,6 +39,7 @@ void StringElement::set_text( | |||||||
|     text = _text; |     text = _text; | ||||||
|     x = _x; |     x = _x; | ||||||
|     y = _y; |     y = _y; | ||||||
|  |     fit_width = _fit_w; | ||||||
|     horizontal = _horizontal; |     horizontal = _horizontal; | ||||||
|     vertical = _vertical; |     vertical = _vertical; | ||||||
|     font = _font; |     font = _font; | ||||||
|  | |||||||
| @ -12,6 +12,7 @@ public: | |||||||
|         const char* text = NULL, |         const char* text = NULL, | ||||||
|         uint8_t x = 0, |         uint8_t x = 0, | ||||||
|         uint8_t y = 0, |         uint8_t y = 0, | ||||||
|  |         uint8_t fit_width = 0, | ||||||
|         Align horizontal = AlignLeft, |         Align horizontal = AlignLeft, | ||||||
|         Align vertical = AlignTop, |         Align vertical = AlignTop, | ||||||
|         Font font = FontPrimary); |         Font font = FontPrimary); | ||||||
| @ -20,6 +21,7 @@ private: | |||||||
|     const char* text = NULL; |     const char* text = NULL; | ||||||
|     uint8_t x = 0; |     uint8_t x = 0; | ||||||
|     uint8_t y = 0; |     uint8_t y = 0; | ||||||
|  |     uint8_t fit_width = 0; | ||||||
|     Align horizontal = AlignLeft; |     Align horizontal = AlignLeft; | ||||||
|     Align vertical = AlignTop; |     Align vertical = AlignTop; | ||||||
|     Font font = FontPrimary; |     Font font = FontPrimary; | ||||||
|  | |||||||
| @ -4,9 +4,6 @@ | |||||||
| #include <lib/toolbox/path.h> | #include <lib/toolbox/path.h> | ||||||
| #include <lib/flipper_file/flipper_file.h> | #include <lib/flipper_file/flipper_file.h> | ||||||
| 
 | 
 | ||||||
| static const char* nfc_app_folder = "/any/nfc"; |  | ||||||
| static const char* nfc_app_extension = ".nfc"; |  | ||||||
| static const char* nfc_app_shadow_extension = ".shd"; |  | ||||||
| static const char* nfc_file_header = "Flipper NFC device"; | static const char* nfc_file_header = "Flipper NFC device"; | ||||||
| static const uint32_t nfc_file_version = 2; | static const uint32_t nfc_file_version = 2; | ||||||
| 
 | 
 | ||||||
| @ -243,7 +240,7 @@ static bool nfc_device_save_file( | |||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
|         // Create nfc directory if necessary
 |         // Create nfc directory if necessary
 | ||||||
|         if(!storage_simply_mkdir(dev->storage, nfc_app_folder)) break; |         if(!storage_simply_mkdir(dev->storage, NFC_APP_FOLDER)) break; | ||||||
|         // First remove nfc device file if it was saved
 |         // First remove nfc device file if it was saved
 | ||||||
|         string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); |         string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); | ||||||
|         // Open file
 |         // Open file
 | ||||||
| @ -281,12 +278,12 @@ static bool nfc_device_save_file( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool nfc_device_save(NfcDevice* dev, const char* dev_name) { | bool nfc_device_save(NfcDevice* dev, const char* dev_name) { | ||||||
|     return nfc_device_save_file(dev, dev_name, nfc_app_folder, nfc_app_extension); |     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) { | bool nfc_device_save_shadow(NfcDevice* dev, const char* dev_name) { | ||||||
|     dev->shadow_file_exist = true; |     dev->shadow_file_exist = true; | ||||||
|     return nfc_device_save_file(dev, dev_name, nfc_app_folder, nfc_app_shadow_extension); |     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) { | static bool nfc_device_load_data(NfcDevice* dev, string_t path) { | ||||||
| @ -300,9 +297,9 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path) { | |||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
|         // Check existance of shadow file
 |         // Check existance of shadow file
 | ||||||
|         size_t ext_start = string_search_str(path, nfc_app_extension); |         size_t ext_start = string_search_str(path, NFC_APP_EXTENSION); | ||||||
|         string_set_n(temp_str, path, 0, ext_start); |         string_set_n(temp_str, path, 0, ext_start); | ||||||
|         string_cat_printf(temp_str, "%s", nfc_app_shadow_extension); |         string_cat_printf(temp_str, "%s", NFC_APP_SHADOW_EXTENSION); | ||||||
|         dev->shadow_file_exist = |         dev->shadow_file_exist = | ||||||
|             storage_common_stat(dev->storage, string_get_cstr(temp_str), NULL) == FSE_OK; |             storage_common_stat(dev->storage, string_get_cstr(temp_str), NULL) == FSE_OK; | ||||||
|         // Open shadow file if it exists. If not - open original
 |         // Open shadow file if it exists. If not - open original
 | ||||||
| @ -374,15 +371,15 @@ bool nfc_file_select(NfcDevice* dev) { | |||||||
|     // Input events and views are managed by file_select
 |     // Input events and views are managed by file_select
 | ||||||
|     bool res = dialog_file_select_show( |     bool res = dialog_file_select_show( | ||||||
|         dev->dialogs, |         dev->dialogs, | ||||||
|         nfc_app_folder, |         NFC_APP_FOLDER, | ||||||
|         nfc_app_extension, |         NFC_APP_EXTENSION, | ||||||
|         dev->file_name, |         dev->file_name, | ||||||
|         sizeof(dev->file_name), |         sizeof(dev->file_name), | ||||||
|         dev->dev_name); |         dev->dev_name); | ||||||
|     if(res) { |     if(res) { | ||||||
|         string_t dev_str; |         string_t dev_str; | ||||||
|         // Get key file path
 |         // Get key file path
 | ||||||
|         string_init_printf(dev_str, "%s/%s%s", nfc_app_folder, dev->file_name, nfc_app_extension); |         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); |         res = nfc_device_load_data(dev, dev_str); | ||||||
|         if(res) { |         if(res) { | ||||||
|             nfc_device_set_name(dev, dev->file_name); |             nfc_device_set_name(dev, dev->file_name); | ||||||
| @ -409,12 +406,12 @@ bool nfc_device_delete(NfcDevice* dev) { | |||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
|         // Delete original file
 |         // Delete original file
 | ||||||
|         string_init_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; |         if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break; | ||||||
|         // Delete shadow file if it exists
 |         // Delete shadow file if it exists
 | ||||||
|         if(dev->shadow_file_exist) { |         if(dev->shadow_file_exist) { | ||||||
|             string_printf( |             string_printf( | ||||||
|                 file_path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_shadow_extension); |                 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; |             if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break; | ||||||
|         } |         } | ||||||
|         deleted = true; |         deleted = true; | ||||||
| @ -437,10 +434,10 @@ bool nfc_device_restore(NfcDevice* dev) { | |||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
|         string_init_printf( |         string_init_printf( | ||||||
|             path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_shadow_extension); |             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; |         if(!storage_simply_remove(dev->storage, string_get_cstr(path))) break; | ||||||
|         dev->shadow_file_exist = false; |         dev->shadow_file_exist = false; | ||||||
|         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; |         if(!nfc_device_load_data(dev, path)) break; | ||||||
|         restored = true; |         restored = true; | ||||||
|     } while(0); |     } while(0); | ||||||
|  | |||||||
| @ -10,6 +10,10 @@ | |||||||
| #define NFC_DEV_NAME_MAX_LEN 22 | #define NFC_DEV_NAME_MAX_LEN 22 | ||||||
| #define NFC_FILE_NAME_MAX_LEN 120 | #define NFC_FILE_NAME_MAX_LEN 120 | ||||||
| 
 | 
 | ||||||
|  | #define NFC_APP_FOLDER "/any/nfc" | ||||||
|  | #define NFC_APP_EXTENSION ".nfc" | ||||||
|  | #define NFC_APP_SHADOW_EXTENSION ".shd" | ||||||
|  | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|     NfcDeviceNfca, |     NfcDeviceNfca, | ||||||
|     NfcDeviceNfcb, |     NfcDeviceNfcb, | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| #include "../nfc_i.h" | #include "../nfc_i.h" | ||||||
| #include <lib/toolbox/random_name.h> | #include <lib/toolbox/random_name.h> | ||||||
|  | #include <gui/modules/validators.h> | ||||||
| 
 | 
 | ||||||
| #define SCENE_SAVE_NAME_CUSTOM_EVENT (0UL) | #define SCENE_SAVE_NAME_CUSTOM_EVENT (0UL) | ||||||
| 
 | 
 | ||||||
| @ -29,6 +30,11 @@ void nfc_scene_save_name_on_enter(void* context) { | |||||||
|         nfc->text_store, |         nfc->text_store, | ||||||
|         NFC_DEV_NAME_MAX_LEN, |         NFC_DEV_NAME_MAX_LEN, | ||||||
|         dev_name_empty); |         dev_name_empty); | ||||||
|  | 
 | ||||||
|  |     ValidatorIsFile* validator_is_file = | ||||||
|  |         validator_is_file_alloc_init(NFC_APP_FOLDER, NFC_APP_EXTENSION); | ||||||
|  |     text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); | ||||||
|  | 
 | ||||||
|     view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextInput); |     view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextInput); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -60,5 +66,9 @@ void nfc_scene_save_name_on_exit(void* context) { | |||||||
|     Nfc* nfc = (Nfc*)context; |     Nfc* nfc = (Nfc*)context; | ||||||
| 
 | 
 | ||||||
|     // Clear view
 |     // Clear view
 | ||||||
|  |     void* validator_context = text_input_get_validator_callback_context(nfc->text_input); | ||||||
|  |     text_input_set_validator(nfc->text_input, NULL, NULL); | ||||||
|  |     validator_is_file_free(validator_context); | ||||||
|  | 
 | ||||||
|     text_input_reset(nfc->text_input); |     text_input_reset(nfc->text_input); | ||||||
| } | } | ||||||
|  | |||||||
| @ -29,3 +29,11 @@ void TextInputVM::set_result_callback( | |||||||
| void TextInputVM::set_header_text(const char* text) { | void TextInputVM::set_header_text(const char* text) { | ||||||
|     text_input_set_header_text(text_input, text); |     text_input_set_header_text(text_input, text); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void TextInputVM::set_validator(TextInputValidatorCallback callback, void* callback_context) { | ||||||
|  |     text_input_set_validator(text_input, callback, callback_context); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void* TextInputVM::get_validator_callback_context() { | ||||||
|  |     return text_input_get_validator_callback_context(text_input); | ||||||
|  | } | ||||||
|  | |||||||
| @ -32,6 +32,10 @@ public: | |||||||
|      */ |      */ | ||||||
|     void set_header_text(const char* text); |     void set_header_text(const char* text); | ||||||
| 
 | 
 | ||||||
|  |     void set_validator(TextInputValidatorCallback callback, void* callback_context); | ||||||
|  | 
 | ||||||
|  |     void* get_validator_callback_context(); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     TextInput* text_input; |     TextInput* text_input; | ||||||
| }; | }; | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Nikolay Minaylov
						Nikolay Minaylov