Skip to content

Commit 3a1705b

Browse files
authored
Merge pull request #68 from derskythe/fixed-archive-app
Fixed archive app
2 parents e23dbb9 + df87b04 commit 3a1705b

13 files changed

+496
-131
lines changed

applications/main/archive/archive.c

+70-27
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,122 @@
11
#include "archive_i.h"
2-
#include "m-string.h"
32

4-
bool archive_custom_event_callback(void* context, uint32_t event) {
3+
static bool archive_custom_event_callback(void* context, uint32_t event) {
54
furi_assert(context);
6-
ArchiveApp* archive = (ArchiveApp*)context;
5+
ArchiveApp* archive = context;
76
return scene_manager_handle_custom_event(archive->scene_manager, event);
87
}
98

10-
bool archive_back_event_callback(void* context) {
9+
static bool archive_back_event_callback(void* context) {
1110
furi_assert(context);
12-
ArchiveApp* archive = (ArchiveApp*)context;
11+
ArchiveApp* archive = context;
1312
return scene_manager_handle_back_event(archive->scene_manager);
1413
}
1514

16-
ArchiveApp* archive_alloc() {
15+
static void archive_tick_event_callback(void* context) {
16+
furi_assert(context);
17+
ArchiveApp* archive = context;
18+
scene_manager_handle_tick_event(archive->scene_manager);
19+
}
20+
21+
static ArchiveApp* archive_alloc() {
1722
ArchiveApp* archive = malloc(sizeof(ArchiveApp));
1823

19-
archive->gui = furi_record_open(RECORD_GUI);
20-
archive->text_input = text_input_alloc();
2124
string_init(archive->fav_move_str);
2225

23-
archive->view_dispatcher = view_dispatcher_alloc();
2426
archive->scene_manager = scene_manager_alloc(&archive_scene_handlers, archive);
27+
archive->view_dispatcher = view_dispatcher_alloc();
2528

26-
view_dispatcher_enable_queue(archive->view_dispatcher);
27-
view_dispatcher_attach_to_gui(
28-
archive->view_dispatcher, archive->gui, ViewDispatcherTypeFullscreen);
29-
30-
view_dispatcher_set_event_callback_context(archive->view_dispatcher, archive);
31-
view_dispatcher_set_custom_event_callback(
32-
archive->view_dispatcher, archive_custom_event_callback);
33-
view_dispatcher_set_navigation_event_callback(
34-
archive->view_dispatcher, archive_back_event_callback);
29+
archive->gui = furi_record_open(RECORD_GUI);
3530

36-
archive->browser = browser_alloc();
31+
ViewDispatcher* view_dispatcher = archive->view_dispatcher;
32+
view_dispatcher_enable_queue(view_dispatcher);
33+
view_dispatcher_set_event_callback_context(view_dispatcher, archive);
34+
view_dispatcher_set_custom_event_callback(view_dispatcher, archive_custom_event_callback);
35+
view_dispatcher_set_navigation_event_callback(view_dispatcher, archive_back_event_callback);
36+
view_dispatcher_set_tick_event_callback(view_dispatcher, archive_tick_event_callback, 100);
3737

38-
view_dispatcher_add_view(
39-
archive->view_dispatcher, ArchiveViewBrowser, archive_browser_get_view(archive->browser));
38+
archive->dialogs = furi_record_open(RECORD_DIALOGS);
4039

40+
archive->text_input = text_input_alloc();
4141
view_dispatcher_add_view(
42-
archive->view_dispatcher, ArchiveViewTextInput, text_input_get_view(archive->text_input));
42+
view_dispatcher, ArchiveViewTextInput, text_input_get_view(archive->text_input));
4343

4444
archive->widget = widget_alloc();
4545
view_dispatcher_add_view(
4646
archive->view_dispatcher, ArchiveViewWidget, widget_get_view(archive->widget));
4747

48+
archive->view_stack = view_stack_alloc();
49+
view_dispatcher_add_view(
50+
view_dispatcher, ArchiveViewStack, view_stack_get_view(archive->view_stack));
51+
52+
archive->browser = browser_alloc();
53+
view_dispatcher_add_view(
54+
archive->view_dispatcher, ArchiveViewBrowser, archive_browser_get_view(archive->browser));
55+
56+
// Loading
57+
archive->loading = loading_alloc();
58+
4859
return archive;
4960
}
5061

5162
void archive_free(ArchiveApp* archive) {
5263
furi_assert(archive);
64+
ViewDispatcher* view_dispatcher = archive->view_dispatcher;
5365

54-
view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewBrowser);
55-
view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewTextInput);
56-
view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewWidget);
66+
// Loading
67+
loading_free(archive->loading);
68+
69+
view_dispatcher_remove_view(view_dispatcher, ArchiveViewTextInput);
70+
text_input_free(archive->text_input);
71+
72+
view_dispatcher_remove_view(view_dispatcher, ArchiveViewWidget);
5773
widget_free(archive->widget);
74+
75+
view_dispatcher_remove_view(view_dispatcher, ArchiveViewStack);
76+
view_stack_free(archive->view_stack);
77+
78+
view_dispatcher_remove_view(view_dispatcher, ArchiveViewBrowser);
79+
5880
view_dispatcher_free(archive->view_dispatcher);
5981
scene_manager_free(archive->scene_manager);
82+
6083
browser_free(archive->browser);
6184
string_clear(archive->fav_move_str);
6285

63-
text_input_free(archive->text_input);
86+
furi_record_close(RECORD_DIALOGS);
87+
archive->dialogs = NULL;
6488

6589
furi_record_close(RECORD_GUI);
6690
archive->gui = NULL;
6791

6892
free(archive);
6993
}
7094

95+
void archive_show_loading_popup(ArchiveApp* context, bool show) {
96+
TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME);
97+
ViewStack* view_stack = context->view_stack;
98+
Loading* loading = context->loading;
99+
100+
if(show) {
101+
// Raise timer priority so that animations can play
102+
vTaskPrioritySet(timer_task, configMAX_PRIORITIES - 1);
103+
view_stack_add_view(view_stack, loading_get_view(loading));
104+
} else {
105+
view_stack_remove_view(view_stack, loading_get_view(loading));
106+
// Restore default timer priority
107+
vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY);
108+
}
109+
}
110+
71111
int32_t archive_app(void* p) {
72112
UNUSED(p);
113+
73114
ArchiveApp* archive = archive_alloc();
115+
view_dispatcher_attach_to_gui(
116+
archive->view_dispatcher, archive->gui, ViewDispatcherTypeFullscreen);
74117
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser);
75118
view_dispatcher_run(archive->view_dispatcher);
76-
archive_free(archive);
77119

120+
archive_free(archive);
78121
return 0;
79122
}

applications/main/archive/archive_i.h

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#include <gui/scene_manager.h>
99
#include <gui/modules/text_input.h>
1010
#include <gui/modules/widget.h>
11+
#include <gui/view_stack.h>
12+
#include <dialogs/dialogs.h>
13+
#include <gui/modules/loading.h>
1114
#include <loader/loader.h>
1215

1316
#include "views/archive_browser_view.h"
@@ -18,17 +21,24 @@ typedef enum {
1821
ArchiveViewTextInput,
1922
ArchiveViewWidget,
2023
ArchiveViewTotal,
24+
ArchiveViewStack,
2125
} ArchiveViewEnum;
2226

2327
struct ArchiveApp {
2428
Gui* gui;
2529
ViewDispatcher* view_dispatcher;
30+
ViewStack* view_stack;
2631
SceneManager* scene_manager;
2732
ArchiveBrowserView* browser;
2833
TextInput* text_input;
2934
Widget* widget;
35+
DialogsApp* dialogs;
36+
Loading* loading;
3037
FuriPubSubSubscription* loader_stop_subscription;
38+
3139
string_t fav_move_str;
3240
char text_store[MAX_NAME_LEN];
3341
char file_extension[MAX_EXT_LEN + 1];
3442
};
43+
44+
void archive_show_loading_popup(ArchiveApp* context, bool show);

applications/main/archive/helpers/archive_browser.c

+1
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ void archive_show_file_menu(ArchiveBrowserView* browser, bool show) {
377377
if(archive_is_item_in_array(model, model->item_idx)) {
378378
model->menu = true;
379379
model->menu_idx = 0;
380+
menu_array_reset(model->context_menu);
380381
ArchiveFile_t* selected =
381382
files_array_get(model->files, model->item_idx - model->array_offset);
382383
selected->fav = archive_is_favorite("%s", string_get_cstr(selected->path));

applications/main/archive/helpers/archive_files.c

+35
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,38 @@ void archive_delete_file(void* context, const char* format, ...) {
109109

110110
string_clear(filename);
111111
}
112+
113+
FS_Error archive_rename_file_or_dir(void* context, const char* src_path, const char* dst_path) {
114+
furi_assert(context);
115+
116+
FURI_LOG_I(TAG, "Rename from %s to %s", src_path, dst_path);
117+
118+
ArchiveBrowserView* browser = context;
119+
Storage* fs_api = furi_record_open(RECORD_STORAGE);
120+
121+
FileInfo fileinfo;
122+
storage_common_stat(fs_api, src_path, &fileinfo);
123+
124+
FS_Error error = FSE_OK;
125+
126+
if(!path_contains_only_ascii(dst_path)) {
127+
error = FSE_INVALID_NAME;
128+
} else {
129+
error = storage_common_rename(fs_api, src_path, dst_path);
130+
}
131+
furi_record_close(RECORD_STORAGE);
132+
133+
if(archive_is_favorite("%s", src_path)) {
134+
archive_favorites_rename(src_path, dst_path);
135+
}
136+
137+
if(error == FSE_OK || error == FSE_EXIST) {
138+
FURI_LOG_I(TAG, "Rename from %s to %s is DONE", src_path, dst_path);
139+
archive_refresh_dir(browser);
140+
} else {
141+
FURI_LOG_E(
142+
TAG, "Rename failed: %s, Code: %d", filesystem_api_error_get_desc(error), error);
143+
}
144+
145+
return error;
146+
}

applications/main/archive/helpers/archive_files.h

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <m-array.h>
44
#include <m-string.h>
55
#include <storage/storage.h>
6+
#include "toolbox/path.h"
67

78
typedef enum {
89
ArchiveFileTypeIButton,
@@ -62,3 +63,4 @@ void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder
6263
bool archive_get_items(void* context, const char* path);
6364
void archive_file_append(const char* path, const char* format, ...);
6465
void archive_delete_file(void* context, const char* format, ...);
66+
FS_Error archive_rename_file_or_dir(void* context, const char* src_path, const char* dst_path);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#pragma once
2+
3+
#include <m-array.h>
4+
#include <m-string.h>
5+
6+
typedef struct {
7+
string_t text;
8+
uint32_t event;
9+
} ArchiveContextMenuItem_t;
10+
11+
static void ArchiveContextMenuItem_t_init(ArchiveContextMenuItem_t* obj) {
12+
string_init(obj->text);
13+
obj->event = 0; // ArchiveBrowserEventFileMenuNone
14+
}
15+
16+
static void ArchiveContextMenuItem_t_init_set(
17+
ArchiveContextMenuItem_t* obj,
18+
const ArchiveContextMenuItem_t* src) {
19+
string_init_set(obj->text, src->text);
20+
obj->event = src->event;
21+
}
22+
23+
static void ArchiveContextMenuItem_t_set(
24+
ArchiveContextMenuItem_t* obj,
25+
const ArchiveContextMenuItem_t* src) {
26+
string_init_set(obj->text, src->text);
27+
obj->event = src->event;
28+
}
29+
30+
static void ArchiveContextMenuItem_t_clear(ArchiveContextMenuItem_t* obj) {
31+
string_clear(obj->text);
32+
}
33+
34+
ARRAY_DEF(
35+
menu_array,
36+
ArchiveContextMenuItem_t,
37+
(INIT(API_2(ArchiveContextMenuItem_t_init)),
38+
SET(API_6(ArchiveContextMenuItem_t_set)),
39+
INIT_SET(API_6(ArchiveContextMenuItem_t_init_set)),
40+
CLEAR(API_2(ArchiveContextMenuItem_t_clear))))
41+
42+
#pragma GCC diagnostic push
43+
#pragma GCC diagnostic ignored "-Wunused-function"
44+
// Using in applications/archive/views/archive_browser_view.c
45+
static void archive_menu_add_item(
46+
ArchiveContextMenuItem_t* obj,
47+
string_t text,
48+
uint32_t event) {
49+
string_init_move(obj->text, text);
50+
obj->event = event;
51+
}
52+
#pragma GCC diagnostic pop

applications/main/archive/scenes/archive_scene_browser.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,23 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
132132
case ArchiveBrowserEventFileMenuRename:
133133
if(favorites) {
134134
browser->callback(ArchiveBrowserEventEnterFavMove, browser->context);
135-
} else if((archive_is_known_app(selected->type)) && (selected->is_app == false)) {
135+
//} else if((archive_is_known_app(selected->type)) && (selected->is_app == false)) {
136+
} else {
137+
// Added ability to rename files and folders
136138
archive_show_file_menu(browser, false);
137139
scene_manager_set_scene_state(
138140
archive->scene_manager, ArchiveAppSceneBrowser, SCENE_STATE_NEED_REFRESH);
139141
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneRename);
140142
}
141143
consumed = true;
142144
break;
145+
case ArchiveBrowserEventFileMenuInfo:
146+
archive_show_file_menu(browser, false);
147+
scene_manager_set_scene_state(
148+
archive->scene_manager, ArchiveAppSceneBrowser, SCENE_STATE_DEFAULT);
149+
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneInfo);
150+
consumed = true;
151+
break;
143152
case ArchiveBrowserEventFileMenuDelete:
144153
if(archive_get_tab(browser) != ArchiveTabFavorites) {
145154
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneDelete);
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
ADD_SCENE(archive, browser, Browser)
22
ADD_SCENE(archive, rename, Rename)
33
ADD_SCENE(archive, delete, Delete)
4+
ADD_SCENE(archive, info, Info)

applications/main/archive/scenes/archive_scene_delete.c

-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
#include "../archive_i.h"
2-
#include "../helpers/archive_favorites.h"
3-
#include "../helpers/archive_files.h"
42
#include "../helpers/archive_apps.h"
53
#include "../helpers/archive_browser.h"
6-
#include "toolbox/path.h"
7-
#include "m-string.h"
84

95
#define SCENE_DELETE_CUSTOM_EVENT (0UL)
106
#define MAX_TEXT_INPUT_LEN 22

0 commit comments

Comments
 (0)