diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-11-01 00:29:32 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-11-01 00:29:32 +0400 |
commit | 1bcadda46b96e3e557aad1b0d2d53a0b4743b413 (patch) | |
tree | 3f749a30df330ced48905860da40b1ed21254f6e /source/blender/windowmanager | |
parent | 26541afc8b9bfa0b11ecd2dcdab120cfcfff5d92 (diff) |
fix [#30910] Problems: Add Shortcut(s) for "Ctrl Tab" menu
comparing keymaps was too sloppy or too strict, now sloppy keymap comparison works by setting all the operator
properties to their default values if they are not already set, then compare this with the keymap item (ignoring values missing from either one).
... this way any non default keymap setting wont match with an operator menu item which doesnt set this operator at all (a problem sighted in this bug report).
developer notes:
- IDP_EqualsProperties_ex() function adds an argument to treat missing members of either group to act as if there is a match.
- WM_operator_properties_default() function to reset RNA values to their defaults.
- add IDP_spit(), debug only function to print out ID properties.
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_keymap.c | 57 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 36 |
3 files changed, 80 insertions, 14 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 04e8b65a2ef..b9a4e720230 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -214,6 +214,7 @@ int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, short c void WM_operator_properties_alloc(struct PointerRNA **ptr, struct IDProperty **properties, const char *opstring); /* used for keymap and macro items */ void WM_operator_properties_sanitize(struct PointerRNA *ptr, const short no_context); /* make props context sensitive or not */ +int WM_operator_properties_default(struct PointerRNA *ptr, const int do_update); void WM_operator_properties_reset(struct wmOperator *op); void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring); void WM_operator_properties_create_ptr(struct PointerRNA *ptr, struct wmOperatorType *ot); diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index bcddc984ed3..2781ec2d3df 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -816,7 +816,7 @@ char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len) static wmKeyMapItem *wm_keymap_item_find_handlers( const bContext *C, ListBase *handlers, const char *opname, int UNUSED(opcontext), - IDProperty *properties, int compare_props, int hotkey, wmKeyMap **keymap_r) + IDProperty *properties, int is_strict, int hotkey, wmKeyMap **keymap_r) { wmWindowManager *wm = CTX_wm_manager(C); wmEventHandler *handler; @@ -834,9 +834,22 @@ static wmKeyMapItem *wm_keymap_item_find_handlers( if (hotkey) if (!ISHOTKEY(kmi->type)) continue; - - if (compare_props) { - if (kmi->ptr && IDP_EqualsProperties(properties, kmi->ptr->data)) { + + if (properties) { + + /* example of debugging keymaps */ +#if 0 + if (kmi->ptr) { + if (strcmp("MESH_OT_rip_move", opname) == 0) { + printf("OPERATOR\n"); + IDP_spit(properties); + printf("KEYMAP\n"); + IDP_spit(kmi->ptr->data); + } + } +#endif + + if (kmi->ptr && IDP_EqualsProperties_ex(properties, kmi->ptr->data, is_strict)) { if (keymap_r) *keymap_r = keymap; return kmi; } @@ -857,7 +870,7 @@ static wmKeyMapItem *wm_keymap_item_find_handlers( static wmKeyMapItem *wm_keymap_item_find_props( const bContext *C, const char *opname, int opcontext, - IDProperty *properties, int compare_props, int hotkey, wmKeyMap **keymap_r) + IDProperty *properties, int is_strict, int hotkey, wmKeyMap **keymap_r) { wmWindow *win = CTX_wm_window(C); ScrArea *sa = CTX_wm_area(C); @@ -866,10 +879,10 @@ static wmKeyMapItem *wm_keymap_item_find_props( /* look into multiple handler lists to find the item */ if (win) - found = wm_keymap_item_find_handlers(C, &win->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r); + found = wm_keymap_item_find_handlers(C, &win->handlers, opname, opcontext, properties, is_strict, hotkey, keymap_r); if (sa && found == NULL) - found = wm_keymap_item_find_handlers(C, &sa->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r); + found = wm_keymap_item_find_handlers(C, &sa->handlers, opname, opcontext, properties, is_strict, hotkey, keymap_r); if (found == NULL) { if (ELEM(opcontext, WM_OP_EXEC_REGION_WIN, WM_OP_INVOKE_REGION_WIN)) { @@ -878,7 +891,7 @@ static wmKeyMapItem *wm_keymap_item_find_props( ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); if (ar) - found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r); + found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, is_strict, hotkey, keymap_r); } } else if (ELEM(opcontext, WM_OP_EXEC_REGION_CHANNELS, WM_OP_INVOKE_REGION_CHANNELS)) { @@ -886,18 +899,18 @@ static wmKeyMapItem *wm_keymap_item_find_props( ar = BKE_area_find_region_type(sa, RGN_TYPE_CHANNELS); if (ar) - found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r); + found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, is_strict, hotkey, keymap_r); } else if (ELEM(opcontext, WM_OP_EXEC_REGION_PREVIEW, WM_OP_INVOKE_REGION_PREVIEW)) { if (!(ar && ar->regiontype == RGN_TYPE_PREVIEW)) ar = BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW); if (ar) - found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r); + found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, is_strict, hotkey, keymap_r); } else { if (ar) - found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r); + found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, is_strict, hotkey, keymap_r); } } @@ -906,12 +919,28 @@ static wmKeyMapItem *wm_keymap_item_find_props( static wmKeyMapItem *wm_keymap_item_find( const bContext *C, const char *opname, int opcontext, - IDProperty *properties, const short hotkey, const short sloppy, wmKeyMap **keymap_r) + IDProperty *properties, const short hotkey, const short UNUSED(sloppy), wmKeyMap **keymap_r) { wmKeyMapItem *found = wm_keymap_item_find_props(C, opname, opcontext, properties, 1, hotkey, keymap_r); - if (!found && sloppy) - found = wm_keymap_item_find_props(C, opname, opcontext, NULL, 0, hotkey, keymap_r); + if (!found && properties) { + wmOperatorType *ot = WM_operatortype_find(opname, TRUE); + if (ot) { + /* make a copy of the properties and set any unset props + * to their default values, so the ID property compare function succeeds */ + PointerRNA opptr; + IDProperty *properties_default = IDP_CopyProperty(properties); + + RNA_pointer_create(NULL, ot->srna, properties_default, &opptr); + + if (WM_operator_properties_default(&opptr, TRUE)) { + found = wm_keymap_item_find_props(C, opname, opcontext, properties_default, 0, hotkey, keymap_r); + } + + IDP_FreeProperty(properties_default); + MEM_freeN(properties_default); + } + } return found; } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 8d01cdb694d..2ef33aa5964 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -619,6 +619,42 @@ void WM_operator_properties_sanitize(PointerRNA *ptr, const short no_context) RNA_STRUCT_END; } + +/** set all props to their default, + * \param do_update Only update un-initialized props. + * + * \note, theres nothing spesific to operators here. + * this could be made a general function. + */ +int WM_operator_properties_default(PointerRNA *ptr, const int do_update) +{ + int is_change = FALSE; + RNA_STRUCT_BEGIN(ptr, prop) + { + switch (RNA_property_type(prop)) { + case PROP_POINTER: + { + StructRNA *ptype = RNA_property_pointer_type(ptr, prop); + if (ptype != &RNA_Struct) { + PointerRNA opptr = RNA_property_pointer_get(ptr, prop); + is_change |= WM_operator_properties_default(&opptr, do_update); + } + break; + } + default: + if ((do_update == FALSE) || (RNA_property_is_set(ptr, prop) == FALSE)) { + if (RNA_property_reset(ptr, prop, -1)) { + is_change = 1; + } + } + break; + } + } + RNA_STRUCT_END; + + return is_change; +} + /* remove all props without PROP_SKIP_SAVE */ void WM_operator_properties_reset(wmOperator *op) { |