[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51798] trunk/blender/source/blender: fix [#30910] Problems: Add Shortcut(s) for "Ctrl Tab" menu

Campbell Barton ideasman42 at gmail.com
Wed Oct 31 21:29:35 CET 2012


Revision: 51798
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51798
Author:   campbellbarton
Date:     2012-10-31 20:29:32 +0000 (Wed, 31 Oct 2012)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_idprop.h
    trunk/blender/source/blender/blenkernel/intern/idprop.c
    trunk/blender/source/blender/python/generic/idprop_py_api.c
    trunk/blender/source/blender/windowmanager/WM_api.h
    trunk/blender/source/blender/windowmanager/intern/wm_keymap.c
    trunk/blender/source/blender/windowmanager/intern/wm_operators.c

Modified: trunk/blender/source/blender/blenkernel/BKE_idprop.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_idprop.h	2012-10-31 19:42:02 UTC (rev 51797)
+++ trunk/blender/source/blender/blenkernel/BKE_idprop.h	2012-10-31 20:29:32 UTC (rev 51798)
@@ -266,6 +266,12 @@
 #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 @@
 #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__ */

Modified: trunk/blender/source/blender/blenkernel/intern/idprop.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/idprop.c	2012-10-31 19:42:02 UTC (rev 51797)
+++ trunk/blender/source/blender/blenkernel/intern/idprop.c	2012-10-31 20:29:32 UTC (rev 51798)
@@ -632,12 +632,14 @@
 	}
 }
 
-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 @@
 		{
 			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 @@
 	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)
 {

Modified: trunk/blender/source/blender/python/generic/idprop_py_api.c
===================================================================
--- trunk/blender/source/blender/python/generic/idprop_py_api.c	2012-10-31 19:42:02 UTC (rev 51797)
+++ trunk/blender/source/blender/python/generic/idprop_py_api.c	2012-10-31 20:29:32 UTC (rev 51798)
@@ -1497,3 +1497,40 @@
 
 	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

Modified: trunk/blender/source/blender/windowmanager/WM_api.h
===================================================================
--- trunk/blender/source/blender/windowmanager/WM_api.h	2012-10-31 19:42:02 UTC (rev 51797)
+++ trunk/blender/source/blender/windowmanager/WM_api.h	2012-10-31 20:29:32 UTC (rev 51798)
@@ -214,6 +214,7 @@
 
 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);

Modified: trunk/blender/source/blender/windowmanager/intern/wm_keymap.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_keymap.c	2012-10-31 19:42:02 UTC (rev 51797)
+++ trunk/blender/source/blender/windowmanager/intern/wm_keymap.c	2012-10-31 20:29:32 UTC (rev 51798)
@@ -816,7 +816,7 @@
 
 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 @@
 					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_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 @@
 
 	/* 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 @@
 					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 @@
 				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,13 +919,29 @@
 
 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;
 }
 

Modified: trunk/blender/source/blender/windowmanager/intern/wm_operators.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_operators.c	2012-10-31 19:42:02 UTC (rev 51797)
+++ trunk/blender/source/blender/windowmanager/intern/wm_operators.c	2012-10-31 20:29:32 UTC (rev 51798)
@@ -619,6 +619,42 @@
 	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)
+	{

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list