Skip to content

Commit

Permalink
Merge pull request #11 from rdefeo/ir_all
Browse files Browse the repository at this point in the history
Add Import All for IR files
  • Loading branch information
rdefeo authored Sep 8, 2024
2 parents 91dfcbd + 6f79e18 commit 2fe1ce7
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 36 deletions.
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

0 comments on commit 2fe1ce7

Please sign in to comment.