Fix crashes when deleting signals in Read mode

This commit is contained in:
MX
2023-05-17 17:24:14 +03:00
parent 90f18075cb
commit 88e47e9251
3 changed files with 81 additions and 49 deletions

View File

@@ -230,9 +230,13 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
subghz->state_notifications = SubGhzNotificationStateRx;
subghz->idx_menu_chosen = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver);
subghz_view_receiver_disable_draw_callback(subghz->subghz_receiver);
subghz_history_delete_item(subghz->history, subghz->idx_menu_chosen);
subghz_view_receiver_delete_element_callback(subghz->subghz_receiver);
subghz_view_receiver_enable_draw_callback(subghz->subghz_receiver);
subghz_scene_receiver_update_statusbar(subghz);
consumed = true;
break;

View File

@@ -71,6 +71,7 @@ typedef struct {
SubGhzViewReceiverMode mode;
uint8_t u_rssi;
size_t scroll_counter;
bool nodraw;
} SubGhzViewReceiverModel;
void subghz_view_receiver_set_mode(
@@ -241,11 +242,18 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
bool scrollbar = model->history_item > 4;
FuriString* str_buff = furi_string_alloc();
if(!model->nodraw) {
SubGhzReceiverMenuItem* item_menu;
for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) {
size_t idx = CLAMP((uint16_t)(i + model->list_offset), model->history_item, 0);
item_menu = SubGhzReceiverMenuItemArray_get(model->history->data, idx);
if(item_menu == NULL) {
break;
}
if(item_menu->type == 0) {
break;
}
furi_string_set(str_buff, item_menu->item_str);
size_t scroll_counter = model->scroll_counter;
if(model->idx == idx) {
@@ -275,6 +283,7 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
if(scrollbar) {
elements_scrollbar_pos(canvas, 128, 0, 49, model->idx, model->history_item);
}
}
furi_string_free(str_buff);
canvas_set_color(canvas, ColorBlack);
@@ -464,29 +473,12 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) {
SubGhzViewReceiverModel * model,
{
if(model->history_item != 0) {
SubGhzReceiverMenuItemArray_it_t it;
// SubGhzReceiverMenuItem* target_item =
// SubGhzReceiverMenuItemArray_get(model->history->data, model->idx);
SubGhzReceiverMenuItemArray_it_last(it, model->history->data);
while(!SubGhzReceiverMenuItemArray_end_p(it)) {
SubGhzReceiverMenuItem* item = SubGhzReceiverMenuItemArray_ref(it);
if(it->index == (size_t)(model->idx)) {
furi_string_free(item->item_str);
furi_string_free(item->time);
item->type = 0;
SubGhzReceiverMenuItemArray_remove(model->history->data, it);
}
SubGhzReceiverMenuItemArray_previous(it);
}
// Callback
subghz_receiver->callback(
SubGhzCustomEventViewReceiverDeleteItem, subghz_receiver->context);
}
},
true);
false);
} else if(event->key == InputKeyOk && event->type == InputTypeShort) {
with_view_model(
subghz_receiver->view,
@@ -537,6 +529,7 @@ void subghz_view_receiver_exit(void* context) {
model->idx = 0;
model->list_offset = 0;
model->history_item = 0;
model->nodraw = false;
},
false);
furi_timer_stop(subghz_receiver->timer);
@@ -571,6 +564,7 @@ SubGhzViewReceiver* subghz_view_receiver_alloc() {
model->history_stat_str = furi_string_alloc();
model->progress_str = furi_string_alloc();
model->bar_show = SubGhzViewReceiverBarShowDefault;
model->nodraw = false;
model->history = malloc(sizeof(SubGhzReceiverHistory));
SubGhzReceiverMenuItemArray_init(model->history->data);
},
@@ -628,6 +622,23 @@ void subghz_view_receiver_delete_element_callback(SubGhzViewReceiver* subghz_rec
subghz_receiver->view,
SubGhzViewReceiverModel * model,
{
SubGhzReceiverMenuItemArray_it_t it;
// SubGhzReceiverMenuItem* target_item =
// SubGhzReceiverMenuItemArray_get(model->history->data, model->idx);
SubGhzReceiverMenuItemArray_it_last(it, model->history->data);
while(!SubGhzReceiverMenuItemArray_end_p(it)) {
SubGhzReceiverMenuItem* item = SubGhzReceiverMenuItemArray_ref(it);
if(it->index == (size_t)(model->idx)) {
furi_string_free(item->item_str);
furi_string_free(item->time);
item->type = 0;
SubGhzReceiverMenuItemArray_remove(model->history->data, it);
}
SubGhzReceiverMenuItemArray_previous(it);
}
if(model->history_item == 5) {
if(model->idx >= 2) {
model->idx = model->history_item - 1;
@@ -640,7 +651,20 @@ void subghz_view_receiver_delete_element_callback(SubGhzViewReceiver* subghz_rec
}
},
true);
furi_delay_ms(200);
}
void subghz_view_receiver_enable_draw_callback(SubGhzViewReceiver* subghz_receiver) {
furi_assert(subghz_receiver);
with_view_model(
subghz_receiver->view, SubGhzViewReceiverModel * model, { model->nodraw = false; }, true);
}
void subghz_view_receiver_disable_draw_callback(SubGhzViewReceiver* subghz_receiver) {
furi_assert(subghz_receiver);
with_view_model(
subghz_receiver->view, SubGhzViewReceiverModel * model, { model->nodraw = true; }, true);
}
void subghz_view_receiver_set_idx_menu(SubGhzViewReceiver* subghz_receiver, uint16_t idx) {

View File

@@ -49,4 +49,8 @@ void subghz_view_receiver_set_idx_menu(SubGhzViewReceiver* subghz_receiver, uint
void subghz_view_receiver_delete_element_callback(SubGhzViewReceiver* subghz_receiver);
void subghz_view_receiver_enable_draw_callback(SubGhzViewReceiver* subghz_receiver);
void subghz_view_receiver_disable_draw_callback(SubGhzViewReceiver* subghz_receiver);
void subghz_view_receiver_exit(void* context);