[FL-3001] File browser base folder (#2091)
* File browser base folder * Format sources * FuriHal: bump api version Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									741ad34b2c
								
							
						
					
					
						commit
						2daf39018b
					
				| @ -48,7 +48,7 @@ FileBrowserApp* file_browser_app_alloc(char* arg) { | |||||||
| 
 | 
 | ||||||
|     app->file_path = furi_string_alloc(); |     app->file_path = furi_string_alloc(); | ||||||
|     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); |     file_browser_configure(app->file_browser, "*", NULL, true, &I_badusb_10px, true); | ||||||
| 
 | 
 | ||||||
|     view_dispatcher_add_view( |     view_dispatcher_add_view( | ||||||
|         app->view_dispatcher, FileBrowserAppViewStart, widget_get_view(app->widget)); |         app->view_dispatcher, FileBrowserAppViewStart, widget_get_view(app->widget)); | ||||||
|  | |||||||
| @ -84,7 +84,8 @@ static void archive_file_browser_set_path( | |||||||
|     bool hide_dot_files) { |     bool hide_dot_files) { | ||||||
|     furi_assert(browser); |     furi_assert(browser); | ||||||
|     if(!browser->worker_running) { |     if(!browser->worker_running) { | ||||||
|         browser->worker = file_browser_worker_alloc(path, filter_ext, skip_assets, hide_dot_files); |         browser->worker = | ||||||
|  |             file_browser_worker_alloc(path, NULL, filter_ext, skip_assets, hide_dot_files); | ||||||
|         file_browser_worker_set_callback_context(browser->worker, browser); |         file_browser_worker_set_callback_context(browser->worker, browser); | ||||||
|         file_browser_worker_set_folder_callback(browser->worker, archive_folder_open_cb); |         file_browser_worker_set_folder_callback(browser->worker, archive_folder_open_cb); | ||||||
|         file_browser_worker_set_list_callback(browser->worker, archive_list_load_cb); |         file_browser_worker_set_list_callback(browser->worker, archive_list_load_cb); | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| #include "../bad_usb_app_i.h" | #include "../bad_usb_app_i.h" | ||||||
| #include "furi_hal_power.h" | #include "furi_hal_power.h" | ||||||
| #include "furi_hal_usb.h" | #include "furi_hal_usb.h" | ||||||
|  | #include <storage/storage.h> | ||||||
| 
 | 
 | ||||||
| static bool bad_usb_file_select(BadUsbApp* bad_usb) { | static bool bad_usb_file_select(BadUsbApp* bad_usb) { | ||||||
|     furi_assert(bad_usb); |     furi_assert(bad_usb); | ||||||
| 
 | 
 | ||||||
|     DialogsFileBrowserOptions browser_options; |     DialogsFileBrowserOptions browser_options; | ||||||
|     dialog_file_browser_set_basic_options(&browser_options, BAD_USB_APP_EXTENSION, &I_badusb_10px); |     dialog_file_browser_set_basic_options(&browser_options, BAD_USB_APP_EXTENSION, &I_badusb_10px); | ||||||
|  |     browser_options.base_path = BAD_USB_APP_PATH_FOLDER; | ||||||
| 
 | 
 | ||||||
|     // Input events and views are managed by file_browser
 |     // Input events and views are managed by file_browser
 | ||||||
|     bool res = dialog_file_browser_show( |     bool res = dialog_file_browser_show( | ||||||
|  | |||||||
| @ -148,6 +148,7 @@ static bool fap_loader_select_app(FapLoader* loader) { | |||||||
|         .hide_ext = true, |         .hide_ext = true, | ||||||
|         .item_loader_callback = fap_loader_item_callback, |         .item_loader_callback = fap_loader_item_callback, | ||||||
|         .item_loader_context = loader, |         .item_loader_context = loader, | ||||||
|  |         .base_path = EXT_PATH("apps"), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     return dialog_file_browser_show( |     return dialog_file_browser_show( | ||||||
|  | |||||||
| @ -218,6 +218,7 @@ void ibutton_free(iButton* ibutton) { | |||||||
| bool ibutton_file_select(iButton* ibutton) { | bool ibutton_file_select(iButton* ibutton) { | ||||||
|     DialogsFileBrowserOptions browser_options; |     DialogsFileBrowserOptions browser_options; | ||||||
|     dialog_file_browser_set_basic_options(&browser_options, IBUTTON_APP_EXTENSION, &I_ibutt_10px); |     dialog_file_browser_set_basic_options(&browser_options, IBUTTON_APP_EXTENSION, &I_ibutt_10px); | ||||||
|  |     browser_options.base_path = IBUTTON_APP_FOLDER; | ||||||
| 
 | 
 | ||||||
|     bool success = dialog_file_browser_show( |     bool success = dialog_file_browser_show( | ||||||
|         ibutton->dialogs, ibutton->file_path, ibutton->file_path, &browser_options); |         ibutton->dialogs, ibutton->file_path, ibutton->file_path, &browser_options); | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ void infrared_scene_remote_list_on_enter(void* context) { | |||||||
| 
 | 
 | ||||||
|     DialogsFileBrowserOptions browser_options; |     DialogsFileBrowserOptions browser_options; | ||||||
|     dialog_file_browser_set_basic_options(&browser_options, INFRARED_APP_EXTENSION, &I_ir_10px); |     dialog_file_browser_set_basic_options(&browser_options, INFRARED_APP_EXTENSION, &I_ir_10px); | ||||||
|  |     browser_options.base_path = INFRARED_APP_FOLDER; | ||||||
| 
 | 
 | ||||||
|     bool success = dialog_file_browser_show( |     bool success = dialog_file_browser_show( | ||||||
|         infrared->dialogs, infrared->file_path, infrared->file_path, &browser_options); |         infrared->dialogs, infrared->file_path, infrared->file_path, &browser_options); | ||||||
|  | |||||||
| @ -230,6 +230,7 @@ bool lfrfid_load_key_from_file_select(LfRfid* app) { | |||||||
| 
 | 
 | ||||||
|     DialogsFileBrowserOptions browser_options; |     DialogsFileBrowserOptions browser_options; | ||||||
|     dialog_file_browser_set_basic_options(&browser_options, LFRFID_APP_EXTENSION, &I_125_10px); |     dialog_file_browser_set_basic_options(&browser_options, LFRFID_APP_EXTENSION, &I_125_10px); | ||||||
|  |     browser_options.base_path = LFRFID_APP_FOLDER; | ||||||
| 
 | 
 | ||||||
|     // Input events and views are managed by file_browser
 |     // Input events and views are managed by file_browser
 | ||||||
|     bool result = |     bool result = | ||||||
|  | |||||||
| @ -454,6 +454,7 @@ bool subghz_load_protocol_from_file(SubGhz* subghz) { | |||||||
| 
 | 
 | ||||||
|     DialogsFileBrowserOptions browser_options; |     DialogsFileBrowserOptions browser_options; | ||||||
|     dialog_file_browser_set_basic_options(&browser_options, SUBGHZ_APP_EXTENSION, &I_sub1_10px); |     dialog_file_browser_set_basic_options(&browser_options, SUBGHZ_APP_EXTENSION, &I_sub1_10px); | ||||||
|  |     browser_options.base_path = SUBGHZ_APP_FOLDER; | ||||||
| 
 | 
 | ||||||
|     // Input events and views are managed by file_select
 |     // Input events and views are managed by file_select
 | ||||||
|     bool res = dialog_file_browser_show( |     bool res = dialog_file_browser_show( | ||||||
|  | |||||||
| @ -313,6 +313,7 @@ int32_t music_player_app(void* p) { | |||||||
|             dialog_file_browser_set_basic_options( |             dialog_file_browser_set_basic_options( | ||||||
|                 &browser_options, MUSIC_PLAYER_APP_EXTENSION, &I_music_10px); |                 &browser_options, MUSIC_PLAYER_APP_EXTENSION, &I_music_10px); | ||||||
|             browser_options.hide_ext = false; |             browser_options.hide_ext = false; | ||||||
|  |             browser_options.base_path = MUSIC_PLAYER_APP_PATH_FOLDER; | ||||||
| 
 | 
 | ||||||
|             DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); |             DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); | ||||||
|             bool res = dialog_file_browser_show(dialogs, file_path, file_path, &browser_options); |             bool res = dialog_file_browser_show(dialogs, file_path, file_path, &browser_options); | ||||||
|  | |||||||
| @ -231,6 +231,7 @@ bool picopass_file_select(PicopassDevice* dev) { | |||||||
| 
 | 
 | ||||||
|     DialogsFileBrowserOptions browser_options; |     DialogsFileBrowserOptions browser_options; | ||||||
|     dialog_file_browser_set_basic_options(&browser_options, PICOPASS_APP_EXTENSION, &I_Nfc_10px); |     dialog_file_browser_set_basic_options(&browser_options, PICOPASS_APP_EXTENSION, &I_Nfc_10px); | ||||||
|  |     browser_options.base_path = PICOPASS_APP_FOLDER; | ||||||
| 
 | 
 | ||||||
|     bool res = dialog_file_browser_show( |     bool res = dialog_file_browser_show( | ||||||
|         dev->dialogs, dev->load_path, picopass_app_folder, &browser_options); |         dev->dialogs, dev->load_path, picopass_app_folder, &browser_options); | ||||||
|  | |||||||
| @ -14,6 +14,7 @@ void dialog_file_browser_set_basic_options( | |||||||
|     options->hide_ext = true; |     options->hide_ext = true; | ||||||
|     options->item_loader_callback = NULL; |     options->item_loader_callback = NULL; | ||||||
|     options->item_loader_context = NULL; |     options->item_loader_context = NULL; | ||||||
|  |     options->base_path = NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static DialogsApp* dialogs_app_alloc() { | static DialogsApp* dialogs_app_alloc() { | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ typedef struct DialogsApp DialogsApp; | |||||||
| /**
 | /**
 | ||||||
|  * File browser dialog extra options |  * File browser dialog extra options | ||||||
|  * @param extension file extension to be offered for selection |  * @param extension file extension to be offered for selection | ||||||
|  |  * @param base_path root folder path for navigation with back key | ||||||
|  * @param skip_assets true - do not show assets folders |  * @param skip_assets true - do not show assets folders | ||||||
|  * @param hide_dot_files true - hide dot files |  * @param hide_dot_files true - hide dot files | ||||||
|  * @param icon file icon pointer, NULL for default icon |  * @param icon file icon pointer, NULL for default icon | ||||||
| @ -27,6 +28,7 @@ typedef struct DialogsApp DialogsApp; | |||||||
|  */ |  */ | ||||||
| typedef struct { | typedef struct { | ||||||
|     const char* extension; |     const char* extension; | ||||||
|  |     const char* base_path; | ||||||
|     bool skip_assets; |     bool skip_assets; | ||||||
|     bool hide_dot_files; |     bool hide_dot_files; | ||||||
|     const Icon* icon; |     const Icon* icon; | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ bool dialog_file_browser_show( | |||||||
|             .preselected_filename = path, |             .preselected_filename = path, | ||||||
|             .item_callback = options ? options->item_loader_callback : NULL, |             .item_callback = options ? options->item_loader_callback : NULL, | ||||||
|             .item_callback_context = options ? options->item_loader_context : NULL, |             .item_callback_context = options ? options->item_loader_context : NULL, | ||||||
|  |             .base_path = options ? options->base_path : NULL, | ||||||
|         }}; |         }}; | ||||||
| 
 | 
 | ||||||
|     DialogsAppReturn return_data; |     DialogsAppReturn return_data; | ||||||
|  | |||||||
| @ -17,6 +17,7 @@ typedef struct { | |||||||
|     FuriString* preselected_filename; |     FuriString* preselected_filename; | ||||||
|     FileBrowserLoadItemCallback item_callback; |     FileBrowserLoadItemCallback item_callback; | ||||||
|     void* item_callback_context; |     void* item_callback_context; | ||||||
|  |     const char* base_path; | ||||||
| } DialogsAppMessageDataFileBrowser; | } DialogsAppMessageDataFileBrowser; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|  | |||||||
| @ -40,6 +40,7 @@ bool dialogs_app_process_module_file_browser(const DialogsAppMessageDataFileBrow | |||||||
|     file_browser_configure( |     file_browser_configure( | ||||||
|         file_browser, |         file_browser, | ||||||
|         data->extension, |         data->extension, | ||||||
|  |         data->base_path, | ||||||
|         data->skip_assets, |         data->skip_assets, | ||||||
|         data->hide_dot_files, |         data->hide_dot_files, | ||||||
|         data->file_icon, |         data->file_icon, | ||||||
|  | |||||||
| @ -83,6 +83,7 @@ struct FileBrowser { | |||||||
|     View* view; |     View* view; | ||||||
|     BrowserWorker* worker; |     BrowserWorker* worker; | ||||||
|     const char* ext_filter; |     const char* ext_filter; | ||||||
|  |     const char* base_path; | ||||||
|     bool skip_assets; |     bool skip_assets; | ||||||
|     bool hide_dot_files; |     bool hide_dot_files; | ||||||
|     bool hide_ext; |     bool hide_ext; | ||||||
| @ -163,6 +164,7 @@ View* file_browser_get_view(FileBrowser* browser) { | |||||||
| void file_browser_configure( | void file_browser_configure( | ||||||
|     FileBrowser* browser, |     FileBrowser* browser, | ||||||
|     const char* extension, |     const char* extension, | ||||||
|  |     const char* base_path, | ||||||
|     bool skip_assets, |     bool skip_assets, | ||||||
|     bool hide_dot_files, |     bool hide_dot_files, | ||||||
|     const Icon* file_icon, |     const Icon* file_icon, | ||||||
| @ -172,6 +174,7 @@ void file_browser_configure( | |||||||
|     browser->ext_filter = extension; |     browser->ext_filter = extension; | ||||||
|     browser->skip_assets = skip_assets; |     browser->skip_assets = skip_assets; | ||||||
|     browser->hide_ext = hide_ext; |     browser->hide_ext = hide_ext; | ||||||
|  |     browser->base_path = base_path; | ||||||
|     browser->hide_dot_files = hide_dot_files; |     browser->hide_dot_files = hide_dot_files; | ||||||
| 
 | 
 | ||||||
|     with_view_model( |     with_view_model( | ||||||
| @ -187,7 +190,11 @@ void file_browser_configure( | |||||||
| void file_browser_start(FileBrowser* browser, FuriString* path) { | void file_browser_start(FileBrowser* browser, FuriString* path) { | ||||||
|     furi_assert(browser); |     furi_assert(browser); | ||||||
|     browser->worker = file_browser_worker_alloc( |     browser->worker = file_browser_worker_alloc( | ||||||
|         path, browser->ext_filter, browser->skip_assets, browser->hide_dot_files); |         path, | ||||||
|  |         browser->base_path, | ||||||
|  |         browser->ext_filter, | ||||||
|  |         browser->skip_assets, | ||||||
|  |         browser->hide_dot_files); | ||||||
|     file_browser_worker_set_callback_context(browser->worker, browser); |     file_browser_worker_set_callback_context(browser->worker, browser); | ||||||
|     file_browser_worker_set_folder_callback(browser->worker, browser_folder_open_cb); |     file_browser_worker_set_folder_callback(browser->worker, browser_folder_open_cb); | ||||||
|     file_browser_worker_set_list_callback(browser->worker, browser_list_load_cb); |     file_browser_worker_set_list_callback(browser->worker, browser_list_load_cb); | ||||||
|  | |||||||
| @ -29,6 +29,7 @@ View* file_browser_get_view(FileBrowser* browser); | |||||||
| void file_browser_configure( | void file_browser_configure( | ||||||
|     FileBrowser* browser, |     FileBrowser* browser, | ||||||
|     const char* extension, |     const char* extension, | ||||||
|  |     const char* base_path, | ||||||
|     bool skip_assets, |     bool skip_assets, | ||||||
|     bool hide_dot_files, |     bool hide_dot_files, | ||||||
|     const Icon* file_icon, |     const Icon* file_icon, | ||||||
|  | |||||||
| @ -371,6 +371,7 @@ static int32_t browser_worker(void* context) { | |||||||
| 
 | 
 | ||||||
| BrowserWorker* file_browser_worker_alloc( | BrowserWorker* file_browser_worker_alloc( | ||||||
|     FuriString* path, |     FuriString* path, | ||||||
|  |     const char* base_path, | ||||||
|     const char* filter_ext, |     const char* filter_ext, | ||||||
|     bool skip_assets, |     bool skip_assets, | ||||||
|     bool hide_dot_files) { |     bool hide_dot_files) { | ||||||
| @ -381,12 +382,13 @@ BrowserWorker* file_browser_worker_alloc( | |||||||
|     browser->filter_extension = furi_string_alloc_set(filter_ext); |     browser->filter_extension = furi_string_alloc_set(filter_ext); | ||||||
|     browser->skip_assets = skip_assets; |     browser->skip_assets = skip_assets; | ||||||
|     browser->hide_dot_files = hide_dot_files; |     browser->hide_dot_files = hide_dot_files; | ||||||
|     browser->path_start = furi_string_alloc_set(path); | 
 | ||||||
|     browser->path_current = furi_string_alloc_set(path); |     browser->path_current = furi_string_alloc_set(path); | ||||||
|     browser->path_next = furi_string_alloc_set(path); |     browser->path_next = furi_string_alloc_set(path); | ||||||
| 
 | 
 | ||||||
|     if(browser_path_is_file(browser->path_start)) { |     browser->path_start = furi_string_alloc(); | ||||||
|         browser_path_trim(browser->path_start); |     if(base_path) { | ||||||
|  |         furi_string_set_str(browser->path_start, base_path); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     browser->thread = furi_thread_alloc_ex("BrowserWorker", 2048, browser_worker, browser); |     browser->thread = furi_thread_alloc_ex("BrowserWorker", 2048, browser_worker, browser); | ||||||
|  | |||||||
| @ -23,6 +23,7 @@ typedef void (*BrowserWorkerLongLoadCallback)(void* context); | |||||||
| 
 | 
 | ||||||
| BrowserWorker* file_browser_worker_alloc( | BrowserWorker* file_browser_worker_alloc( | ||||||
|     FuriString* path, |     FuriString* path, | ||||||
|  |     const char* base_path, | ||||||
|     const char* filter_ext, |     const char* filter_ext, | ||||||
|     bool skip_assets, |     bool skip_assets, | ||||||
|     bool hide_dot_files); |     bool hide_dot_files); | ||||||
|  | |||||||
| @ -106,6 +106,7 @@ bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent e | |||||||
|                 .hide_ext = true, |                 .hide_ext = true, | ||||||
|                 .item_loader_callback = favorite_fap_selector_item_callback, |                 .item_loader_callback = favorite_fap_selector_item_callback, | ||||||
|                 .item_loader_context = app, |                 .item_loader_context = app, | ||||||
|  |                 .base_path = EXT_PATH("apps"), | ||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|             if(primary_favorite) { // Select favorite fap in file browser
 |             if(primary_favorite) { // Select favorite fap in file browser
 | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| entry,status,name,type,params | entry,status,name,type,params | ||||||
| Version,+,9.0,, | Version,+,10.0,, | ||||||
| Header,+,applications/services/bt/bt_service/bt.h,, | Header,+,applications/services/bt/bt_service/bt.h,, | ||||||
| Header,+,applications/services/cli/cli.h,, | Header,+,applications/services/cli/cli.h,, | ||||||
| Header,+,applications/services/cli/cli_vcp.h,, | Header,+,applications/services/cli/cli_vcp.h,, | ||||||
| @ -806,14 +806,14 @@ Function,-,fgetpos,int,"FILE*, fpos_t*" | |||||||
| Function,-,fgets,char*,"char*, int, FILE*" | Function,-,fgets,char*,"char*, int, FILE*" | ||||||
| Function,-,fgets_unlocked,char*,"char*, int, FILE*" | Function,-,fgets_unlocked,char*,"char*, int, FILE*" | ||||||
| Function,+,file_browser_alloc,FileBrowser*,FuriString* | Function,+,file_browser_alloc,FileBrowser*,FuriString* | ||||||
| Function,+,file_browser_configure,void,"FileBrowser*, const char*, _Bool, _Bool, const Icon*, _Bool" | Function,+,file_browser_configure,void,"FileBrowser*, const char*, const char*, _Bool, _Bool, const Icon*, _Bool" | ||||||
| Function,+,file_browser_free,void,FileBrowser* | Function,+,file_browser_free,void,FileBrowser* | ||||||
| Function,+,file_browser_get_view,View*,FileBrowser* | Function,+,file_browser_get_view,View*,FileBrowser* | ||||||
| Function,+,file_browser_set_callback,void,"FileBrowser*, FileBrowserCallback, void*" | Function,+,file_browser_set_callback,void,"FileBrowser*, FileBrowserCallback, void*" | ||||||
| Function,+,file_browser_set_item_callback,void,"FileBrowser*, FileBrowserLoadItemCallback, void*" | Function,+,file_browser_set_item_callback,void,"FileBrowser*, FileBrowserLoadItemCallback, void*" | ||||||
| Function,+,file_browser_start,void,"FileBrowser*, FuriString*" | Function,+,file_browser_start,void,"FileBrowser*, FuriString*" | ||||||
| Function,+,file_browser_stop,void,FileBrowser* | Function,+,file_browser_stop,void,FileBrowser* | ||||||
| Function,+,file_browser_worker_alloc,BrowserWorker*,"FuriString*, const char*, _Bool, _Bool" | Function,+,file_browser_worker_alloc,BrowserWorker*,"FuriString*, const char*, const char*, _Bool, _Bool" | ||||||
| Function,+,file_browser_worker_folder_enter,void,"BrowserWorker*, FuriString*, int32_t" | Function,+,file_browser_worker_folder_enter,void,"BrowserWorker*, FuriString*, int32_t" | ||||||
| Function,+,file_browser_worker_folder_exit,void,BrowserWorker* | Function,+,file_browser_worker_folder_exit,void,BrowserWorker* | ||||||
| Function,+,file_browser_worker_folder_refresh,void,"BrowserWorker*, int32_t" | Function,+,file_browser_worker_folder_refresh,void,"BrowserWorker*, int32_t" | ||||||
|  | |||||||
| 
 | 
| @ -1212,6 +1212,7 @@ bool nfc_file_select(NfcDevice* dev) { | |||||||
|         .hide_ext = true, |         .hide_ext = true, | ||||||
|         .item_loader_callback = NULL, |         .item_loader_callback = NULL, | ||||||
|         .item_loader_context = NULL, |         .item_loader_context = NULL, | ||||||
|  |         .base_path = NFC_APP_FOLDER, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     bool res = |     bool res = | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Nikolay Minaylov
						Nikolay Minaylov