scene_action_ir_list.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include <furi.h>
  2. #include <gui/view_dispatcher.h>
  3. #include <gui/scene_manager.h>
  4. #include <gui/modules/submenu.h>
  5. #include <lib/toolbox/path.h>
  6. #include "quac.h"
  7. #include "scenes.h"
  8. #include "scene_action_ir_list.h"
  9. #include "../actions/action.h"
  10. #include "../actions/action_ir_utils.h"
  11. #include <flipper_format/flipper_format.h>
  12. // ehhhh
  13. uint32_t num_ir_commands;
  14. void scene_action_ir_list_callback(void* context, uint32_t index) {
  15. App* app = context;
  16. view_dispatcher_send_custom_event(app->view_dispatcher, index);
  17. }
  18. void scene_action_ir_list_on_enter(void* context) {
  19. App* app = context;
  20. Submenu* menu = app->sub_menu;
  21. submenu_reset(menu);
  22. // Our selected IR File is app->temp_str
  23. submenu_set_header(menu, "Select IR Command");
  24. uint32_t index = 0;
  25. // Add an entry for IMPORT ALL
  26. submenu_add_item(menu, "* IMPORT ALL *", index++, scene_action_ir_list_callback, app);
  27. // read the IR file and load the names of all of the commands
  28. FuriString* name = furi_string_alloc();
  29. FlipperFormat* fff_data_file = flipper_format_file_alloc(app->storage);
  30. if(flipper_format_file_open_existing(fff_data_file, furi_string_get_cstr(app->temp_str))) {
  31. while(flipper_format_read_string(fff_data_file, "name", name)) {
  32. submenu_add_item(
  33. menu, furi_string_get_cstr(name), index, scene_action_ir_list_callback, app);
  34. index++;
  35. }
  36. }
  37. num_ir_commands = index - 1;
  38. if(index == 1) { // '1' to account for 'IMPORT ALL'
  39. FURI_LOG_E(TAG, "Failed to get commands from %s", furi_string_get_cstr(app->temp_str));
  40. submenu_change_item_label(menu, 0, "No IR cmds!");
  41. }
  42. flipper_format_file_close(fff_data_file);
  43. flipper_format_free(fff_data_file);
  44. furi_string_free(name);
  45. view_dispatcher_switch_to_view(app->view_dispatcher, QView_SubMenu);
  46. }
  47. bool scene_action_ir_list_on_event(void* context, SceneManagerEvent event) {
  48. App* app = context;
  49. bool consumed = false;
  50. if(event.type == SceneManagerEventTypeCustom) {
  51. consumed = true;
  52. uint32_t index = event.event;
  53. InfraredSignal* signal = infrared_utils_signal_alloc();
  54. // extract that item as it's own file and place it "here", as defined by
  55. // the currently selected_item
  56. FuriString* name = furi_string_alloc(); // IR command name
  57. FlipperFormat* fff_data_file = flipper_format_file_alloc(app->storage);
  58. FuriString* file_name = furi_string_alloc(); // new IR file name
  59. do {
  60. uint32_t start = index - 1;
  61. uint32_t end = index;
  62. if(index == 0) {
  63. start = 0;
  64. end = num_ir_commands;
  65. }
  66. for(uint32_t ir_index = start; ir_index < end; ir_index++) {
  67. if(!flipper_format_file_open_existing(
  68. fff_data_file, furi_string_get_cstr(app->temp_str))) {
  69. FURI_LOG_E(TAG, "Failed to open %s", furi_string_get_cstr(app->temp_str));
  70. break;
  71. }
  72. if(!infrared_utils_read_signal_at_index(fff_data_file, ir_index, signal, name)) {
  73. FURI_LOG_E(TAG, "Failed to read signal at %lu", index);
  74. break;
  75. }
  76. FURI_LOG_I(TAG, "Read IR signal: %s", furi_string_get_cstr(name));
  77. flipper_format_file_close(fff_data_file);
  78. // generate the new path, based on current item's dir and new command name
  79. if(app->selected_item != EMPTY_ACTION_INDEX) {
  80. Item* item = ItemArray_get(app->items_view->items, app->selected_item);
  81. path_extract_dirname(furi_string_get_cstr(item->path), file_name);
  82. } else {
  83. furi_string_set(file_name, app->items_view->path);
  84. }
  85. furi_string_cat_printf(file_name, "/%s.ir", furi_string_get_cstr(name));
  86. FURI_LOG_I(TAG, "Writing new IR file: %s", furi_string_get_cstr(file_name));
  87. if(!flipper_format_file_open_new(fff_data_file, furi_string_get_cstr(file_name))) {
  88. FURI_LOG_E(
  89. TAG, "Error creating new file: %s", furi_string_get_cstr(file_name));
  90. break;
  91. }
  92. if(!infrared_utils_write_signal(fff_data_file, signal, name)) {
  93. FURI_LOG_E(TAG, "Failed to write signal!");
  94. break;
  95. }
  96. flipper_format_file_close(fff_data_file);
  97. FURI_LOG_I(TAG, "Imported %s", furi_string_get_cstr(name));
  98. }
  99. // Import successful!
  100. // Leave the user on this scene, in case they want to import
  101. // more commands from this IR file
  102. notification_message(app->notifications, &sequence_success);
  103. } while(false);
  104. // cleanup
  105. flipper_format_file_close(fff_data_file);
  106. flipper_format_free(fff_data_file);
  107. furi_string_free(name);
  108. furi_string_free(file_name);
  109. infrared_utils_signal_free(signal);
  110. }
  111. return consumed;
  112. }
  113. void scene_action_ir_list_on_exit(void* context) {
  114. App* app = context;
  115. submenu_reset(app->sub_menu);
  116. }