Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-11-01 00:29:32 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-11-01 00:29:32 +0400
commit1bcadda46b96e3e557aad1b0d2d53a0b4743b413 (patch)
tree3f749a30df330ced48905860da40b1ed21254f6e /source/blender
parent26541afc8b9bfa0b11ecd2dcdab120cfcfff5d92 (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')
-rw-r--r--source/blender/blenkernel/BKE_idprop.h11
-rw-r--r--source/blender/blenkernel/intern/idprop.c15
-rw-r--r--source/blender/python/generic/idprop_py_api.c37
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c57
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c36
6 files changed, 139 insertions, 18 deletions
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 027f06ef84f..2dd1bfc2a51 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -266,6 +266,12 @@ __attribute__((nonnull))
#endif
;
+int IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const int is_strict)
+#ifdef __GNUC__
+__attribute__((warn_unused_result))
+#endif
+;
+
int IDP_EqualsProperties(struct IDProperty *prop1, struct IDProperty *prop2)
#ifdef __GNUC__
__attribute__((warn_unused_result))
@@ -319,4 +325,9 @@ void IDP_UnlinkProperty(struct IDProperty *prop);
#define IDP_IDPArray(prop) ((IDProperty *)(prop)->data.pointer)
#define IDP_Double(prop) (*(double *)&(prop)->data.val)
+#ifdef DEBUG
+/* for printout only */
+void IDP_spit(IDProperty *prop);
+#endif
+
#endif /* __BKE_IDPROP_H__ */
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 584de4cd982..5dd0f08dc71 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -632,12 +632,14 @@ IDProperty *IDP_GetProperties(ID *id, int create_if_needed)
}
}
-int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
+/**
+ * \param is_strict When FALSE treat missing items as a match */
+int IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const int is_strict)
{
if (prop1 == NULL && prop2 == NULL)
return 1;
else if (prop1 == NULL || prop2 == NULL)
- return 0;
+ return is_strict ? 0 : 1;
else if (prop1->type != prop2->type)
return 0;
@@ -661,13 +663,13 @@ int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
{
IDProperty *link1, *link2;
- if (BLI_countlist(&prop1->data.group) != BLI_countlist(&prop2->data.group))
+ if (is_strict && BLI_countlist(&prop1->data.group) != BLI_countlist(&prop2->data.group))
return 0;
for (link1 = prop1->data.group.first; link1; link1 = link1->next) {
link2 = IDP_GetPropertyFromGroup(prop2, link1->name);
- if (!IDP_EqualsProperties(link1, link2))
+ if (!IDP_EqualsProperties_ex(link1, link2, is_strict))
return 0;
}
@@ -696,6 +698,11 @@ int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
return 1;
}
+int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
+{
+ return IDP_EqualsProperties_ex(prop1, prop2, TRUE);
+}
+
/* 'val' is never NULL, don't check */
IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *name)
{
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index 05b37514e20..34210ace884 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -1497,3 +1497,40 @@ PyObject *BPyInit_idprop(void)
return mod;
}
+
+
+#ifdef DEBUG
+/* -------------------------------------------------------------------- */
+/* debug only function */
+
+void IDP_spit(IDProperty *prop)
+{
+ if (prop) {
+ PyGILState_STATE gilstate;
+ int use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */
+ PyObject *ret_dict;
+ PyObject *ret_str;
+
+ if (use_gil) {
+ gilstate = PyGILState_Ensure();
+ }
+
+ /* to_dict() */
+ ret_dict = BPy_IDGroup_MapDataToPy(prop);
+ ret_str = PyObject_Repr(ret_dict);
+ Py_DECREF(ret_dict);
+
+ printf("IDProperty: %s\n", _PyUnicode_AsString(ret_str));
+
+ Py_DECREF(ret_str);
+
+ if (use_gil) {
+ PyGILState_Release(gilstate);
+ }
+ }
+ else {
+ printf("IDProperty: <NIL>\n");
+ }
+}
+
+#endif
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)
{