Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolay Minaylov <nm29719@gmail.com>2022-01-29 12:39:10 +0300
committerGitHub <noreply@github.com>2022-01-29 12:39:10 +0300
commit6264ee8c3b2c13a215fdcf643a8d1541dad1f990 (patch)
tree742940626c121e387379732a65967c97a7444cbd
parent84410c83b54a26efbd6e7d248de8d96bdef78725 (diff)
[FL-2212] File validators and archive fixes #972
Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
-rw-r--r--applications/archive/archive_i.h1
-rw-r--r--applications/archive/helpers/archive_browser.c1
-rw-r--r--applications/archive/helpers/archive_favorites.c49
-rw-r--r--applications/archive/helpers/archive_files.c8
-rw-r--r--applications/archive/helpers/archive_files.h1
-rw-r--r--applications/archive/scenes/archive_scene_rename.c10
-rw-r--r--applications/archive/views/archive_browser_view.h1
-rw-r--r--applications/desktop/scenes/desktop_scene_lock_menu.c8
-rw-r--r--applications/desktop/views/desktop_lock_menu.c20
-rw-r--r--applications/desktop/views/desktop_lock_menu.h2
-rw-r--r--applications/ibutton/ibutton_app.h8
-rw-r--r--applications/ibutton/scene/ibutton_scene_save_name.cpp9
-rw-r--r--applications/irda/scene/irda_app_scene_edit_rename.cpp10
-rw-r--r--applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp7
-rw-r--r--applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp24
-rw-r--r--[-rwxr-xr-x]applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp9
-rw-r--r--applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp8
-rw-r--r--applications/lfrfid/view/elements/string_element.cpp15
-rw-r--r--applications/lfrfid/view/elements/string_element.h2
-rwxr-xr-xapplications/nfc/nfc_device.c27
-rw-r--r--applications/nfc/nfc_device.h4
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_save_name.c10
-rw-r--r--lib/app-scened-template/view_modules/text_input_vm.cpp8
-rw-r--r--lib/app-scened-template/view_modules/text_input_vm.h4
24 files changed, 194 insertions, 52 deletions
diff --git a/applications/archive/archive_i.h b/applications/archive/archive_i.h
index ba95ac4b..b450bb9c 100644
--- a/applications/archive/archive_i.h
+++ b/applications/archive/archive_i.h
@@ -25,4 +25,5 @@ struct ArchiveApp {
ArchiveBrowserView* browser;
TextInput* text_input;
char text_store[MAX_NAME_LEN];
+ char file_extension[MAX_EXT_LEN + 1];
};
diff --git a/applications/archive/helpers/archive_browser.c b/applications/archive/helpers/archive_browser.c
index d52475cc..eb316c1e 100644
--- a/applications/archive/helpers/archive_browser.c
+++ b/applications/archive/helpers/archive_browser.c
@@ -272,7 +272,6 @@ void archive_enter_dir(ArchiveBrowserView* browser, string_t name) {
with_view_model(
browser->view, (ArchiveBrowserViewModel * model) {
model->last_idx = model->idx;
- model->last_offset = model->list_offset;
model->idx = 0;
model->depth = CLAMP(model->depth + 1, MAX_DEPTH, 0);
return false;
diff --git a/applications/archive/helpers/archive_favorites.c b/applications/archive/helpers/archive_favorites.c
index 1e581502..b622e76f 100644
--- a/applications/archive/helpers/archive_favorites.c
+++ b/applications/archive/helpers/archive_favorites.c
@@ -31,6 +31,40 @@ uint16_t archive_favorites_count(void* context) {
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) {
furi_assert(context);
@@ -41,6 +75,8 @@ bool archive_favorites_read(void* context) {
FileInfo file_info;
string_init(buffer);
+ bool need_refresh = false;
+
bool result = file_worker_open(file_worker, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
if(result) {
@@ -52,13 +88,24 @@ bool archive_favorites_read(void* context) {
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_clear(buffer);
file_worker_close(file_worker);
file_worker_free(file_worker);
+
+ if(need_refresh) {
+ archive_favourites_rescan();
+ }
+
return result;
}
diff --git a/applications/archive/helpers/archive_files.c b/applications/archive/helpers/archive_files.c
index 83b67a5b..a5bd2eb9 100644
--- a/applications/archive/helpers/archive_files.c
+++ b/applications/archive/helpers/archive_files.c
@@ -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) {
furi_assert(file);
furi_assert(file_info);
diff --git a/applications/archive/helpers/archive_files.h b/applications/archive/helpers/archive_files.h
index dd86a201..12fde2fb 100644
--- a/applications/archive/helpers/archive_files.h
+++ b/applications/archive/helpers/archive_files.h
@@ -50,6 +50,7 @@ ARRAY_DEF(
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 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_dir_empty(void* context, const char* path);
bool archive_read_dir(void* context, const char* path);
diff --git a/applications/archive/scenes/archive_scene_rename.c b/applications/archive/scenes/archive_scene_rename.c
index 99ae8be4..8f32eb8a 100644
--- a/applications/archive/scenes/archive_scene_rename.c
+++ b/applications/archive/scenes/archive_scene_rename.c
@@ -18,6 +18,7 @@ void archive_scene_rename_on_enter(void* context) {
ArchiveFile_t* current = archive_get_current_file(archive->browser);
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);
text_input_set_header_text(text_input, "Rename:");
@@ -30,6 +31,10 @@ void archive_scene_rename_on_enter(void* context) {
MAX_TEXT_INPUT_LEN,
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);
}
@@ -74,6 +79,11 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) {
void archive_scene_rename_on_exit(void* context) {
ArchiveApp* archive = (ArchiveApp*)context;
+
// 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);
}
diff --git a/applications/archive/views/archive_browser_view.h b/applications/archive/views/archive_browser_view.h
index 91ce9ccc..634dec44 100644
--- a/applications/archive/views/archive_browser_view.h
+++ b/applications/archive/views/archive_browser_view.h
@@ -11,6 +11,7 @@
#define MAX_LEN_PX 110
#define MAX_NAME_LEN 255
+#define MAX_EXT_LEN 6
#define FRAME_HEIGHT 12
#define MENU_ITEMS 4
#define MAX_DEPTH 32
diff --git a/applications/desktop/scenes/desktop_scene_lock_menu.c b/applications/desktop/scenes/desktop_scene_lock_menu.c
index 1c94b83e..7a3d51bb 100644
--- a/applications/desktop/scenes/desktop_scene_lock_menu.c
+++ b/applications/desktop/scenes/desktop_scene_lock_menu.c
@@ -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_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);
}
@@ -30,6 +33,7 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) {
case DesktopLockMenuEventLock:
scene_manager_set_scene_state(
desktop->scene_manager, DesktopSceneMain, DesktopMainSceneStateLockedNoPin);
+ scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 0);
scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain);
consumed = true;
break;
@@ -39,12 +43,14 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) {
desktop->scene_manager, DesktopSceneMain, DesktopMainSceneStateLockedWithPin);
scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain);
} else {
+ scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 1);
scene_manager_next_scene(desktop->scene_manager, DesktopScenePinSetup);
}
consumed = true;
break;
case DesktopLockMenuEventExit:
+ scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 0);
scene_manager_search_and_switch_to_previous_scene(
desktop->scene_manager, DesktopSceneMain);
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) {
- Desktop* desktop = (Desktop*)context;
- desktop_lock_menu_reset_idx(desktop->lock_menu);
}
diff --git a/applications/desktop/views/desktop_lock_menu.c b/applications/desktop/views/desktop_lock_menu.c
index ad8a0a3f..d65aa30d 100644
--- a/applications/desktop/views/desktop_lock_menu.c
+++ b/applications/desktop/views/desktop_lock_menu.c
@@ -4,6 +4,8 @@
#include "../desktop_i.h"
#include "desktop_lock_menu.h"
+#define LOCK_MENU_ITEMS_NB 3
+
void desktop_lock_menu_set_callback(
DesktopLockMenuView* lock_menu,
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(
lock_menu->view, (DesktopLockMenuViewModel * model) {
- model->idx = 0;
+ model->idx = idx;
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) {
- 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;
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_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];
if(i == 1 && !m->pin_set) str = "Set PIN";
if(m->hint_timeout && m->idx == 2 && m->idx == i) str = "Not implemented";
- canvas_draw_str_aligned(
- canvas, 64, 9 + (i * 17) + STATUS_BAR_Y_SHIFT, AlignCenter, AlignCenter, str);
+ if(str != NULL)
+ 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);
}
@@ -90,9 +94,9 @@ bool desktop_lock_menu_input(InputEvent* event, void* context) {
lock_menu->view, (DesktopLockMenuViewModel * model) {
model->hint_timeout = 0; // clear hint timeout
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) {
- model->idx = CLAMP(model->idx + 1, 2, 0);
+ model->idx = CLAMP(model->idx + 1, LOCK_MENU_ITEMS_NB - 1, 0);
}
idx = model->idx;
return true;
diff --git a/applications/desktop/views/desktop_lock_menu.h b/applications/desktop/views/desktop_lock_menu.h
index 80854520..e9928a38 100644
--- a/applications/desktop/views/desktop_lock_menu.h
+++ b/applications/desktop/views/desktop_lock_menu.h
@@ -28,6 +28,6 @@ void desktop_lock_menu_set_callback(
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_reset_idx(DesktopLockMenuView* lock_menu);
+void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx);
DesktopLockMenuView* desktop_lock_menu_alloc();
void desktop_lock_menu_free(DesktopLockMenuView* lock_menu);
diff --git a/applications/ibutton/ibutton_app.h b/applications/ibutton/ibutton_app.h
index 402d4cdf..fc2a32e7 100644
--- a/applications/ibutton/ibutton_app.h
+++ b/applications/ibutton/ibutton_app.h
@@ -64,6 +64,10 @@ public:
SceneAddValue,
};
+ static const char* app_folder;
+ static const char* app_extension;
+ static const char* app_filetype;
+
iButtonAppViewManager* get_view_manager();
void switch_to_next_scene(Scene index);
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;
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);
void make_app_folder();
}; \ No newline at end of file
diff --git a/applications/ibutton/scene/ibutton_scene_save_name.cpp b/applications/ibutton/scene/ibutton_scene_save_name.cpp
index 5b85d409..0d5c5900 100644
--- a/applications/ibutton/scene/ibutton_scene_save_name.cpp
+++ b/applications/ibutton/scene/ibutton_scene_save_name.cpp
@@ -25,6 +25,10 @@ void iButtonSceneSaveName::on_enter(iButtonApp* app) {
text_input_set_result_callback(
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);
}
@@ -48,6 +52,11 @@ bool iButtonSceneSaveName::on_event(iButtonApp* app, iButtonEvent* event) {
void iButtonSceneSaveName::on_exit(iButtonApp* 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);
+ validator_is_file_free((ValidatorIsFile*)validator_context);
+
text_input_reset(text_input);
}
diff --git a/applications/irda/scene/irda_app_scene_edit_rename.cpp b/applications/irda/scene/irda_app_scene_edit_rename.cpp
index f9253eaf..db6b8e4d 100644
--- a/applications/irda/scene/irda_app_scene_edit_rename.cpp
+++ b/applications/irda/scene/irda_app_scene_edit_rename.cpp
@@ -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());
enter_name_length = IrdaAppRemoteManager::max_remote_name_length;
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(
@@ -59,4 +63,10 @@ bool IrdaAppSceneEditRename::on_event(IrdaApp* app, IrdaAppEvent* event) {
}
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);
}
diff --git a/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp b/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp
index c3d2621f..8f8fe9af 100644
--- a/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp
+++ b/applications/lfrfid/scene/lfrfid_app_scene_delete_confirm.cpp
@@ -35,9 +35,9 @@ void LfRfidAppSceneDeleteConfirm::on_enter(LfRfidApp* app, bool need_restore) {
string_printf(string_header, "Delete %s?", key.get_name());
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(
- 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()) {
case LfrfidKeyType::KeyEM4100:
@@ -52,12 +52,13 @@ void LfRfidAppSceneDeleteConfirm::on_enter(LfRfidApp* app, bool need_restore) {
break;
}
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(
lfrfid_key_get_type_string(key.get_type()),
64,
49,
+ 0,
AlignCenter,
AlignBottom,
FontSecondary);
diff --git a/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp b/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp
index 70dc208c..46ff90ef 100644
--- a/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp
+++ b/applications/lfrfid/scene/lfrfid_app_scene_read_success.cpp
@@ -36,9 +36,9 @@ void LfRfidAppSceneReadSuccess::on_enter(LfRfidApp* app, bool need_restore) {
switch(app->worker.key.get_type()) {
case LfrfidKeyType::KeyEM4100:
- line_1_text->set_text("HEX:", 65, 23, AlignRight, AlignBottom, FontSecondary);
- line_2_text->set_text("Mod:", 65, 35, AlignRight, AlignBottom, FontSecondary);
- line_3_text->set_text("ID:", 65, 47, AlignRight, AlignBottom, FontSecondary);
+ line_1_text->set_text("HEX:", 65, 23, 0, AlignRight, AlignBottom, FontSecondary);
+ line_2_text->set_text("Mod:", 65, 35, 0, 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++) {
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])));
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(
- 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(
- string_get_cstr(string[2]), 68, 47, AlignLeft, AlignBottom, FontSecondary);
+ string_get_cstr(string[2]), 68, 47, 0, AlignLeft, AlignBottom, FontSecondary);
break;
case LfrfidKeyType::KeyH10301:
case LfrfidKeyType::KeyI40134:
- line_1_text->set_text("HEX:", 65, 23, AlignRight, AlignBottom, FontSecondary);
- line_2_text->set_text("FC:", 65, 35, AlignRight, AlignBottom, FontSecondary);
- line_3_text->set_text("Card:", 65, 47, AlignRight, AlignBottom, FontSecondary);
+ line_1_text->set_text("HEX:", 65, 23, 0, AlignRight, AlignBottom, FontSecondary);
+ line_2_text->set_text("FC:", 65, 35, 0, 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++) {
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])));
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(
- 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(
- string_get_cstr(string[2]), 68, 47, AlignLeft, AlignBottom, FontSecondary);
+ string_get_cstr(string[2]), 68, 47, 0, AlignLeft, AlignBottom, FontSecondary);
break;
}
diff --git a/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp b/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp
index 76165941..e5fee4fe 100755..100644
--- a/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp
+++ b/applications/lfrfid/scene/lfrfid_app_scene_save_name.cpp
@@ -21,6 +21,10 @@ void LfRfidAppSceneSaveName::on_enter(LfRfidApp* app, bool need_restore) {
app->worker.key.get_name_length(),
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>();
}
@@ -46,6 +50,11 @@ bool LfRfidAppSceneSaveName::on_event(LfRfidApp* app, LfRfidApp::Event* event) {
}
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();
}
diff --git a/applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp b/applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp
index 45463d46..b054e141 100644
--- a/applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp
+++ b/applications/lfrfid/scene/lfrfid_app_scene_saved_info.cpp
@@ -28,8 +28,9 @@ void LfRfidAppSceneSavedInfo::on_enter(LfRfidApp* app, bool need_restore) {
string_cat_printf(string_data, "%02X", data[i]);
}
- line_1->set_text(key.get_name(), 64, 17, AlignCenter, AlignBottom, FontSecondary);
- line_2->set_text(string_get_cstr(string_data), 64, 29, AlignCenter, AlignBottom, FontPrimary);
+ 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, 0, AlignCenter, AlignBottom, FontPrimary);
switch(key.get_type()) {
case LfrfidKeyType::KeyEM4100:
@@ -44,12 +45,13 @@ void LfRfidAppSceneSavedInfo::on_enter(LfRfidApp* app, bool need_restore) {
break;
}
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(
lfrfid_key_get_type_string(key.get_type()),
64,
49,
+ 0,
AlignCenter,
AlignBottom,
FontSecondary);
diff --git a/applications/lfrfid/view/elements/string_element.cpp b/applications/lfrfid/view/elements/string_element.cpp
index 92bb7abd..028bd7fd 100644
--- a/applications/lfrfid/view/elements/string_element.cpp
+++ b/applications/lfrfid/view/elements/string_element.cpp
@@ -9,8 +9,17 @@ StringElement::~StringElement() {
void StringElement::draw(Canvas* canvas) {
if(text) {
+ string_t line;
+ string_init(line);
+ string_set_str(line, text);
+
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,
uint8_t _x,
uint8_t _y,
+ uint8_t _fit_w,
Align _horizontal,
Align _vertical,
Font _font) {
@@ -29,8 +39,9 @@ void StringElement::set_text(
text = _text;
x = _x;
y = _y;
+ fit_width = _fit_w;
horizontal = _horizontal;
vertical = _vertical;
font = _font;
unlock_model(true);
-}
+} \ No newline at end of file
diff --git a/applications/lfrfid/view/elements/string_element.h b/applications/lfrfid/view/elements/string_element.h
index 4bc5364d..173fdd60 100644
--- a/applications/lfrfid/view/elements/string_element.h
+++ b/applications/lfrfid/view/elements/string_element.h
@@ -12,6 +12,7 @@ public:
const char* text = NULL,
uint8_t x = 0,
uint8_t y = 0,
+ uint8_t fit_width = 0,
Align horizontal = AlignLeft,
Align vertical = AlignTop,
Font font = FontPrimary);
@@ -20,6 +21,7 @@ private:
const char* text = NULL;
uint8_t x = 0;
uint8_t y = 0;
+ uint8_t fit_width = 0;
Align horizontal = AlignLeft;
Align vertical = AlignTop;
Font font = FontPrimary;
diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c
index cfd0db2d..d6996b3f 100755
--- a/applications/nfc/nfc_device.c
+++ b/applications/nfc/nfc_device.c
@@ -4,9 +4,6 @@
#include <lib/toolbox/path.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 uint32_t nfc_file_version = 2;
@@ -243,7 +240,7 @@ static bool nfc_device_save_file(
do {
// 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
string_printf(temp_str, "%s/%s%s", folder, dev_name, extension);
// Open file
@@ -281,12 +278,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);
+ 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);
+ 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) {
@@ -300,9 +297,9 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path) {
do {
// 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_cat_printf(temp_str, "%s", nfc_app_shadow_extension);
+ 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
@@ -374,15 +371,15 @@ bool nfc_file_select(NfcDevice* dev) {
// Input events and views are managed by file_select
bool res = dialog_file_select_show(
dev->dialogs,
- nfc_app_folder,
- nfc_app_extension,
+ NFC_APP_FOLDER,
+ NFC_APP_EXTENSION,
dev->file_name,
sizeof(dev->file_name),
dev->dev_name);
if(res) {
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);
+ 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->file_name);
@@ -409,12 +406,12 @@ bool nfc_device_delete(NfcDevice* dev) {
do {
// 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;
// Delete shadow file if it exists
if(dev->shadow_file_exist) {
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;
}
deleted = true;
@@ -437,10 +434,10 @@ bool nfc_device_restore(NfcDevice* dev) {
do {
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;
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;
restored = true;
} while(0);
diff --git a/applications/nfc/nfc_device.h b/applications/nfc/nfc_device.h
index 888f0c2f..cf0c389c 100644
--- a/applications/nfc/nfc_device.h
+++ b/applications/nfc/nfc_device.h
@@ -10,6 +10,10 @@
#define NFC_DEV_NAME_MAX_LEN 22
#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 {
NfcDeviceNfca,
NfcDeviceNfcb,
diff --git a/applications/nfc/scenes/nfc_scene_save_name.c b/applications/nfc/scenes/nfc_scene_save_name.c
index 83a60e38..c66484ff 100755
--- a/applications/nfc/scenes/nfc_scene_save_name.c
+++ b/applications/nfc/scenes/nfc_scene_save_name.c
@@ -1,5 +1,6 @@
#include "../nfc_i.h"
#include <lib/toolbox/random_name.h>
+#include <gui/modules/validators.h>
#define SCENE_SAVE_NAME_CUSTOM_EVENT (0UL)
@@ -29,6 +30,11 @@ void nfc_scene_save_name_on_enter(void* context) {
nfc->text_store,
NFC_DEV_NAME_MAX_LEN,
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);
}
@@ -60,5 +66,9 @@ void nfc_scene_save_name_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
// 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);
}
diff --git a/lib/app-scened-template/view_modules/text_input_vm.cpp b/lib/app-scened-template/view_modules/text_input_vm.cpp
index 06f243de..05e5ed1d 100644
--- a/lib/app-scened-template/view_modules/text_input_vm.cpp
+++ b/lib/app-scened-template/view_modules/text_input_vm.cpp
@@ -29,3 +29,11 @@ void TextInputVM::set_result_callback(
void TextInputVM::set_header_text(const char* 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);
+}
diff --git a/lib/app-scened-template/view_modules/text_input_vm.h b/lib/app-scened-template/view_modules/text_input_vm.h
index 3aedc9be..8fafe861 100644
--- a/lib/app-scened-template/view_modules/text_input_vm.h
+++ b/lib/app-scened-template/view_modules/text_input_vm.h
@@ -32,6 +32,10 @@ public:
*/
void set_header_text(const char* text);
+ void set_validator(TextInputValidatorCallback callback, void* callback_context);
+
+ void* get_validator_callback_context();
+
private:
TextInput* text_input;
}; \ No newline at end of file