Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Import All for IR files #11

Merged
merged 3 commits into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
dist/*
.vscode
.clang-format
.clangd
.editorconfig
.env
.ufbt
12 changes: 8 additions & 4 deletions quac.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "views/action_menu.h"
#include "item.h"

#define QUAC_NAME "Quac!"
#define QUAC_NAME "Quac!"
#define QUAC_VERSION "v0.6.3"
#define QUAC_ABOUT \
"Quick Action remote control\n" QUAC_VERSION "\n" \
Expand All @@ -25,9 +25,12 @@

// Location of our actions and folders
#define QUAC_SETTINGS_FILENAME ".quac.conf"
#define QUAC_SETTINGS_PATH APP_DATA_PATH(QUAC_SETTINGS_FILENAME)
#define QUAC_SETTINGS_PATH APP_DATA_PATH(QUAC_SETTINGS_FILENAME)

typedef enum { QUAC_APP_PORTRAIT, QUAC_APP_LANDSCAPE } QuacAppLayout;
typedef enum {
QUAC_APP_PORTRAIT,
QUAC_APP_LANDSCAPE
} QuacAppLayout;

typedef struct App {
SceneManager* scene_manager;
Expand All @@ -49,6 +52,7 @@ typedef struct App {

FuriString* temp_str; // used for renames/etc
char temp_cstr[MAX_NAME_LEN]; // used for renames/etc
uint32_t temp_u32;

struct {
QuacAppLayout layout; // Defaults to Portrait
Expand All @@ -65,4 +69,4 @@ typedef struct App {
} App;

App* app_alloc();
void app_free(App* app);
void app_free(App* app);
92 changes: 60 additions & 32 deletions scenes/scene_action_ir_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@ void scene_action_ir_list_on_enter(void* context) {
// Our selected IR File is app->temp_str
submenu_set_header(menu, "Select IR Command");

uint32_t index = 0;

// Add an entry for IMPORT ALL
submenu_add_item(menu, "* IMPORT ALL *", index++, scene_action_ir_list_callback, app);

// read the IR file and load the names of all of the commands
FuriString* name = furi_string_alloc();

uint32_t index = 0;
FlipperFormat* fff_data_file = flipper_format_file_alloc(app->storage);
if(flipper_format_file_open_existing(fff_data_file, furi_string_get_cstr(app->temp_str))) {
while(flipper_format_read_string(fff_data_file, "name", name)) {
Expand All @@ -40,8 +44,11 @@ void scene_action_ir_list_on_enter(void* context) {
}
}

if(index == 0) {
FURI_LOG_E(TAG, "Failed to get commands from %s", furi_string_get_cstr(app->temp_str));
// Number of IR Commands in file
app->temp_u32 = index - 1;
if(app->temp_u32 == 0) {
FURI_LOG_E(TAG, "Failed to get ANY commands from %s", furi_string_get_cstr(app->temp_str));
submenu_change_item_label(menu, 0, "No IR cmds!");
}

flipper_format_file_close(fff_data_file);
Expand All @@ -66,42 +73,63 @@ bool scene_action_ir_list_on_event(void* context, SceneManagerEvent event) {
FuriString* file_name = furi_string_alloc(); // new IR file name

do {
if(!flipper_format_file_open_existing(
fff_data_file, furi_string_get_cstr(app->temp_str))) {
FURI_LOG_E(TAG, "Failed to open %s", furi_string_get_cstr(app->temp_str));
break;
uint32_t num_imported = 0;
uint32_t start = index - 1;
uint32_t end = index;
if(index == 0) {
start = 0;
end = app->temp_u32; // Number of IR Commands in file
}
if(!infrared_utils_read_signal_at_index(fff_data_file, index, signal, name)) {
FURI_LOG_E(TAG, "Failed to read signal at %lu", index);
break;
for(uint32_t ir_index = start; ir_index < end; ir_index++) {
if(!flipper_format_file_open_existing(
fff_data_file, furi_string_get_cstr(app->temp_str))) {
FURI_LOG_E(TAG, "Failed to open %s", furi_string_get_cstr(app->temp_str));
break;
}

if(!infrared_utils_read_signal_at_index(fff_data_file, ir_index, signal, name)) {
FURI_LOG_E(TAG, "Failed to read signal at %lu", index);
break;
}
FURI_LOG_I(TAG, "Read IR signal: %s", furi_string_get_cstr(name));
flipper_format_file_close(fff_data_file);

// generate the new path, based on current item's dir and new command name
if(app->selected_item != EMPTY_ACTION_INDEX) {
Item* item = ItemArray_get(app->items_view->items, app->selected_item);
path_extract_dirname(furi_string_get_cstr(item->path), file_name);
} else {
furi_string_set(file_name, app->items_view->path);
}
furi_string_cat_printf(file_name, "/%s.ir", furi_string_get_cstr(name));

FURI_LOG_I(TAG, "Writing new IR file: %s", furi_string_get_cstr(file_name));
if(!flipper_format_file_open_new(fff_data_file, furi_string_get_cstr(file_name))) {
FURI_LOG_E(
TAG, "Error creating new file: %s", furi_string_get_cstr(file_name));
break;
}
if(!infrared_utils_write_signal(fff_data_file, signal, name)) {
FURI_LOG_E(TAG, "Failed to write signal!");
break;
}
flipper_format_file_close(fff_data_file);
FURI_LOG_I(TAG, "Imported %s", furi_string_get_cstr(name));
num_imported++;
}
FURI_LOG_I(TAG, "Read IR signal: %s", furi_string_get_cstr(name));
flipper_format_file_close(fff_data_file);

// generate the new path, based on current item's dir and new command name
if(app->selected_item != EMPTY_ACTION_INDEX) {
Item* item = ItemArray_get(app->items_view->items, app->selected_item);
path_extract_dirname(furi_string_get_cstr(item->path), file_name);
if(num_imported == (end - start)) {
// Import successful!
notification_message(app->notifications, &sequence_success);
} else {
furi_string_set(file_name, app->items_view->path);
FURI_LOG_E(
TAG,
"Error importing IR command(s) from %s",
furi_string_get_cstr(app->temp_str));
notification_message(app->notifications, &sequence_error);
}
furi_string_cat_printf(file_name, "/%s.ir", furi_string_get_cstr(name));

FURI_LOG_I(TAG, "Writing new IR file: %s", furi_string_get_cstr(file_name));
if(!flipper_format_file_open_new(fff_data_file, furi_string_get_cstr(file_name))) {
FURI_LOG_E(TAG, "Error creating new file: %s", furi_string_get_cstr(file_name));
break;
}
if(!infrared_utils_write_signal(fff_data_file, signal, name)) {
FURI_LOG_E(TAG, "Failed to write signal!");
break;
}

// Import successful!
// Leave the user on this scene, in case they want to import
// more commands from this IR file
notification_message(app->notifications, &sequence_success);

} while(false);

// cleanup
Expand Down
Loading