From 3c2e4f4cfd57944244bb80b93539af8a9bb98130 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Wed, 15 Sep 2021 08:43:21 +0200 Subject: Fix T91411: Outliner crash using contextmenu operators from a shortcut Oversight in {rBb0741e1dcbc5}. This was guarded by an assert in `get_target_element`, but it can be valid to have these assigned to a shortcut (and then perform the action without an active outliner element). Now remove the assert and let the operator polls check if we really have a target element. note: this basically makes `get_target_element` obsolete, could call `outliner_find_element_with_flag` instead in all cases. Maniphest Tasks: T91411 Differential Revision: https://developer.blender.org/D12495 --- .../editors/space_outliner/outliner_tools.c | 55 ++++++++++++---------- 1 file changed, 29 insertions(+), 26 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 75bdc5dbac6..515fe8fe228 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -197,11 +197,24 @@ static void get_element_operation_type( static TreeElement *get_target_element(SpaceOutliner *space_outliner) { TreeElement *te = outliner_find_element_with_flag(&space_outliner->tree, TSE_ACTIVE); - BLI_assert(te); return te; } +static bool outliner_operation_tree_element_poll(bContext *C) +{ + if (!ED_operator_outliner_active(C)) { + return false; + } + SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); + TreeElement *te = get_target_element(space_outliner); + if (te == NULL) { + return false; + } + + return true; +} + static void unlink_action_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), @@ -1868,6 +1881,10 @@ static bool outliner_id_operation_item_poll(bContext *C, PropertyRNA *UNUSED(prop), const int enum_value) { + if (!outliner_operation_tree_element_poll(C)) { + return false; + } + SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); TreeElement *te = get_target_element(space_outliner); TreeStoreElem *tselem = TREESTORE(te); @@ -2254,7 +2271,7 @@ void OUTLINER_OT_id_operation(wmOperatorType *ot) /* callbacks */ ot->invoke = WM_menu_invoke; ot->exec = outliner_id_operation_exec; - ot->poll = ED_operator_outliner_active; + ot->poll = outliner_operation_tree_element_poll; ot->flag = 0; @@ -2361,7 +2378,7 @@ void OUTLINER_OT_lib_operation(wmOperatorType *ot) /* callbacks */ ot->invoke = WM_menu_invoke; ot->exec = outliner_lib_operation_exec; - ot->poll = ED_operator_outliner_active; + ot->poll = outliner_operation_tree_element_poll; ot->prop = RNA_def_enum( ot->srna, "type", outliner_lib_op_type_items, 0, "Library Operation", ""); @@ -2420,14 +2437,8 @@ static int outliner_action_set_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; - bAction *act; - /* check for invalid states */ - if (space_outliner == NULL) { - return OPERATOR_CANCELLED; - } - TreeElement *te = get_target_element(space_outliner); get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel); @@ -2482,7 +2493,7 @@ void OUTLINER_OT_action_set(wmOperatorType *ot) /* api callbacks */ ot->invoke = WM_enum_search_invoke; ot->exec = outliner_action_set_exec; - ot->poll = ED_operator_outliner_active; + ot->poll = outliner_operation_tree_element_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -2531,12 +2542,6 @@ static int outliner_animdata_operation_exec(bContext *C, wmOperator *op) wmWindowManager *wm = CTX_wm_manager(C); SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; - - /* check for invalid states */ - if (space_outliner == NULL) { - return OPERATOR_CANCELLED; - } - TreeElement *te = get_target_element(space_outliner); get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel); @@ -2722,12 +2727,6 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op) { SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0; - - /* check for invalid states */ - if (space_outliner == NULL) { - return OPERATOR_CANCELLED; - } - TreeElement *te = get_target_element(space_outliner); get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel); @@ -2806,6 +2805,13 @@ static const EnumPropertyItem *outliner_data_op_sets_enum_item_fn(bContext *C, return DummyRNA_DEFAULT_items; } + TreeElement *te = get_target_element(space_outliner); + if (te == NULL) { + return DummyRNA_NULL_items; + } + + TreeStoreElem *tselem = TREESTORE(te); + static const EnumPropertyItem optype_sel_and_hide[] = { {OL_DOP_SELECT, "SELECT", 0, "Select", ""}, {OL_DOP_DESELECT, "DESELECT", 0, "Deselect", ""}, @@ -2816,9 +2822,6 @@ static const EnumPropertyItem *outliner_data_op_sets_enum_item_fn(bContext *C, static const EnumPropertyItem optype_sel_linked[] = { {OL_DOP_SELECT_LINKED, "SELECT_LINKED", 0, "Select Linked", ""}, {0, NULL, 0, NULL, NULL}}; - TreeElement *te = get_target_element(space_outliner); - TreeStoreElem *tselem = TREESTORE(te); - if (tselem->type == TSE_RNA_STRUCT) { return optype_sel_linked; } @@ -2835,7 +2838,7 @@ void OUTLINER_OT_data_operation(wmOperatorType *ot) /* callbacks */ ot->invoke = WM_menu_invoke; ot->exec = outliner_data_operation_exec; - ot->poll = ED_operator_outliner_active; + ot->poll = outliner_operation_tree_element_poll; ot->flag = 0; -- cgit v1.2.3