Selaa lähdekoodia

Implement file selection

TollyH 2 vuotta sitten
vanhempi
commit
544d010a66

BIN
assets/Nfc_10px.png


+ 94 - 0
mfc_editor_app.c

@@ -36,7 +36,12 @@ MfcEditorApp* mfc_editor_app_alloc() {
     view_dispatcher_attach_to_gui(
     view_dispatcher_attach_to_gui(
         instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen);
         instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen);
 
 
+    instance->storage = furi_record_open(RECORD_STORAGE);
+
+    instance->dialogs = furi_record_open(RECORD_DIALOGS);
+
     instance->nfc_device = nfc_device_alloc();
     instance->nfc_device = nfc_device_alloc();
+    instance->file_path = furi_string_alloc_set(NFC_APP_FOLDER);
 
 
     instance->submenu = submenu_alloc();
     instance->submenu = submenu_alloc();
     view_dispatcher_add_view(
     view_dispatcher_add_view(
@@ -57,11 +62,100 @@ void mfc_editor_app_free(MfcEditorApp* instance) {
     furi_record_close(RECORD_GUI);
     furi_record_close(RECORD_GUI);
     instance->gui = NULL;
     instance->gui = NULL;
 
 
+    furi_record_close(RECORD_STORAGE);
+    instance->storage = NULL;
+
+    furi_record_close(RECORD_DIALOGS);
+    instance->dialogs = NULL;
+
     nfc_device_free(instance->nfc_device);
     nfc_device_free(instance->nfc_device);
+    furi_string_free(instance->file_path);
 
 
     free(instance);
     free(instance);
 }
 }
 
 
+bool mfc_editor_load_file(MfcEditorApp* instance, FuriString* file_path, bool show_dialog) {
+    furi_assert(instance);
+    furi_assert(file_path);
+    bool result = false;
+
+    result = nfc_device_load(instance->nfc_device, furi_string_get_cstr(file_path));
+
+    if(!result && show_dialog) {
+        dialog_message_show_storage_error(instance->dialogs, "Cannot load\nkey file");
+    }
+
+    return result;
+}
+
+static DialogMessageButton mfc_editor_prompt_should_load_shadow(MfcEditorApp* instance) {
+    DialogMessage* message = dialog_message_alloc();
+    dialog_message_set_header(message, "File has modifications", 63, 0, AlignCenter, AlignTop);
+    dialog_message_set_text(
+        message,
+        "Would you like to load the\nmodified file (recommended)\nor the original file?",
+        63,
+        30,
+        AlignCenter,
+        AlignCenter);
+    dialog_message_set_buttons(message, "Original", NULL, "Modified");
+
+    DialogMessageButton message_button = dialog_message_show(instance->dialogs, message);
+
+    dialog_message_free(message);
+
+    return message_button;
+}
+
+static void mfc_editor_get_shadow_file_path(FuriString* file_path, FuriString* shadow_file_path) {
+    furi_assert(file_path);
+    furi_assert(shadow_file_path);
+
+    // Remove NFC extension from end of string then append shadow extension
+    furi_string_set_n(shadow_file_path, file_path, 0, furi_string_size(file_path) - 4);
+    furi_string_cat_printf(shadow_file_path, "%s", NFC_APP_SHADOW_EXTENSION);
+}
+
+static bool mfc_editor_file_has_shadow_file(MfcEditorApp* instance, FuriString* file_path) {
+    furi_assert(instance);
+    furi_assert(file_path);
+
+    FuriString* shadow_file_path = furi_string_alloc();
+    mfc_editor_get_shadow_file_path(file_path, shadow_file_path);
+    bool has_shadow_file =
+        storage_common_exists(instance->storage, furi_string_get_cstr(shadow_file_path));
+
+    furi_string_free(shadow_file_path);
+
+    return has_shadow_file;
+}
+
+bool mfc_editor_prompt_load_file(MfcEditorApp* instance) {
+    furi_assert(instance);
+
+    DialogsFileBrowserOptions browser_options;
+    dialog_file_browser_set_basic_options(&browser_options, NFC_APP_EXTENSION, &I_Nfc_10px);
+    browser_options.base_path = NFC_APP_FOLDER;
+    browser_options.hide_dot_files = true;
+
+    bool result = dialog_file_browser_show(
+        instance->dialogs, instance->file_path, instance->file_path, &browser_options);
+
+    if(result) {
+        if(mfc_editor_file_has_shadow_file(instance, instance->file_path) &&
+           mfc_editor_prompt_should_load_shadow(instance) == DialogMessageButtonRight) {
+            FuriString* shadow_file_path = furi_string_alloc();
+            mfc_editor_get_shadow_file_path(instance->file_path, shadow_file_path);
+            furi_string_set(instance->file_path, shadow_file_path);
+            furi_string_free(shadow_file_path);
+        }
+
+        result = mfc_editor_load_file(instance, instance->file_path, true);
+    }
+
+    return result;
+}
+
 int32_t mfc_editor_app(void* p) {
 int32_t mfc_editor_app(void* p) {
     UNUSED(p);
     UNUSED(p);
 
 

+ 15 - 1
mfc_editor_app_i.h

@@ -2,6 +2,8 @@
 
 
 #include <furi.h>
 #include <furi.h>
 
 
+#include <dialogs/dialogs.h>
+
 #include <gui/gui.h>
 #include <gui/gui.h>
 #include <gui/scene_manager.h>
 #include <gui/scene_manager.h>
 #include <gui/view_dispatcher.h>
 #include <gui/view_dispatcher.h>
@@ -11,7 +13,10 @@
 #include <nfc/nfc.h>
 #include <nfc/nfc.h>
 #include <nfc/nfc_device.h>
 #include <nfc/nfc_device.h>
 
 
+#include <storage/storage.h>
+
 #include "mfc_editor_app.h"
 #include "mfc_editor_app.h"
+#include "mfc_editor_icons.h"
 #include "scenes/mfc_editor_scene.h"
 #include "scenes/mfc_editor_scene.h"
 
 
 #define TAG "MFCEditor"
 #define TAG "MFCEditor"
@@ -23,13 +28,22 @@
 struct MfcEditorApp {
 struct MfcEditorApp {
     ViewDispatcher* view_dispatcher;
     ViewDispatcher* view_dispatcher;
     SceneManager* scene_manager;
     SceneManager* scene_manager;
+
     Gui* gui;
     Gui* gui;
+    Storage* storage;
+    DialogsApp* dialogs;
+
+    Submenu* submenu;
 
 
     NfcDevice* nfc_device;
     NfcDevice* nfc_device;
 
 
-    Submenu* submenu;
+    FuriString* file_path;
 };
 };
 
 
 typedef enum {
 typedef enum {
     MfcEditorAppViewSubmenu,
     MfcEditorAppViewSubmenu,
 } MfcEditorAppView;
 } MfcEditorAppView;
+
+bool mfc_editor_prompt_load_file(MfcEditorApp* instance);
+
+bool mfc_editor_load_file(MfcEditorApp* instance, FuriString* file_path, bool show_dialog);

+ 1 - 0
scenes/mfc_editor_scene_config.h

@@ -1 +1,2 @@
 ADD_SCENE(mfc_editor, start, Start)
 ADD_SCENE(mfc_editor, start, Start)
+ADD_SCENE(mfc_editor, file_select, FileSelect)

+ 28 - 0
scenes/mfc_editor_scene_file_select.c

@@ -0,0 +1,28 @@
+#include "../mfc_editor_app_i.h"
+
+void mfc_editor_scene_file_select_on_enter(void* context) {
+    MfcEditorApp* instance = context;
+
+    if(mfc_editor_prompt_load_file(instance)) {
+        if(nfc_device_get_protocol(instance->nfc_device) == NfcProtocolMfClassic) {
+            FURI_LOG_I(
+                TAG, "Valid MFC file selected at '%s'", furi_string_get_cstr(instance->file_path));
+        } else {
+            FURI_LOG_I(
+                TAG,
+                "Invalid MFC file selected at '%s'",
+                furi_string_get_cstr(instance->file_path));
+        }
+    }
+    scene_manager_previous_scene(instance->scene_manager);
+}
+
+bool mfc_editor_scene_file_select_on_event(void* context, SceneManagerEvent event) {
+    UNUSED(context);
+    UNUSED(event);
+    return false;
+}
+
+void mfc_editor_scene_file_select_on_exit(void* context) {
+    UNUSED(context);
+}

+ 1 - 1
scenes/mfc_editor_scene_start.c

@@ -27,9 +27,9 @@ bool mfc_editor_scene_start_on_event(void* context, SceneManagerEvent event) {
 
 
     if(event.type == SceneManagerEventTypeCustom) {
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == SubmenuIndexOpen) {
         if(event.event == SubmenuIndexOpen) {
-            FURI_LOG_I(TAG, "Open item clicked");
             scene_manager_set_scene_state(
             scene_manager_set_scene_state(
                 instance->scene_manager, MfcEditorSceneStart, SubmenuIndexOpen);
                 instance->scene_manager, MfcEditorSceneStart, SubmenuIndexOpen);
+            scene_manager_next_scene(instance->scene_manager, MfcEditorSceneFileSelect);
             consumed = true;
             consumed = true;
         }
         }
     }
     }