[Bf-blender-cvs] [3e4d720ae48] master: Fix logical error resolving RNA paths

Campbell Barton noreply at git.blender.org
Tue Aug 31 04:08:01 CEST 2021


Commit: 3e4d720ae4836783db978b0a378e97b47dcaca87
Author: Campbell Barton
Date:   Tue Aug 31 11:46:47 2021 +1000
Branches: master
https://developer.blender.org/rB3e4d720ae4836783db978b0a378e97b47dcaca87

Fix logical error resolving RNA paths

Only append RNA_path_from_ID_to_struct to context attributes if those
paths resolve to ID types.

Also simplify creating RNA paths by adding utility functions:

- WM_context_path_resolve_property_full
- WM_context_path_resolve_full

Part of fix for T90723.

===================================================================

M	source/blender/editors/interface/interface_context_menu.c
M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/intern/rna_access.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_operators.c

===================================================================

diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index b953d88c896..e89b8dc7bd7 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -70,26 +70,12 @@ static IDProperty *shortcut_property_from_rna(bContext *C, uiBut *but)
 
   /* If this returns null, we won't be able to bind shortcuts to these RNA properties.
    * Support can be added at #wm_context_member_from_ptr. */
-  const char *member_id = WM_context_member_from_ptr(C, &but->rnapoin);
-  if (member_id == NULL) {
+  char *final_data_path = WM_context_path_resolve_property_full(
+      C, &but->rnapoin, but->rnaprop, -1);
+  if (final_data_path == NULL) {
     return NULL;
   }
 
-  const char *data_path = RNA_path_from_ID_to_struct(&but->rnapoin);
-  const char *member_id_data_path = member_id;
-
-  if (data_path) {
-    member_id_data_path = BLI_sprintfN("%s.%s", member_id, data_path);
-    MEM_freeN((void *)data_path);
-  }
-
-  const char *prop_id = RNA_property_identifier(but->rnaprop);
-  const char *final_data_path = BLI_sprintfN("%s.%s", member_id_data_path, prop_id);
-
-  if (member_id != member_id_data_path) {
-    MEM_freeN((void *)member_id_data_path);
-  }
-
   /* Create ID property of data path, to pass to the operator. */
   const IDPropertyTemplate val = {0};
   IDProperty *prop = IDP_New(IDP_GROUP, &val, __func__);
@@ -329,10 +315,24 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
 
 static bool ui_but_is_user_menu_compatible(bContext *C, uiBut *but)
 {
-  return (but->optype ||
-          (but->rnaprop && (RNA_property_type(but->rnaprop) == PROP_BOOLEAN) &&
-           (WM_context_member_from_ptr(C, &but->rnapoin) != NULL)) ||
-          UI_but_menutype_get(but));
+  bool result = false;
+  if (but->optype) {
+    result = true;
+  }
+  else if (but->rnaprop) {
+    if (RNA_property_type(but->rnaprop) == PROP_BOOLEAN) {
+      char *data_path = WM_context_path_resolve_full(C, &but->rnapoin);
+      if (data_path != NULL) {
+        MEM_freeN(data_path);
+        result = true;
+      }
+    }
+  }
+  else if (UI_but_menutype_get(but)) {
+    result = true;
+  }
+
+  return result;
 }
 
 static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *um)
@@ -343,21 +343,11 @@ static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *
         &um->items, but->optype, prop, but->opcontext);
   }
   if (but->rnaprop) {
-    const char *member_id = WM_context_member_from_ptr(C, &but->rnapoin);
-    const char *data_path = RNA_path_from_ID_to_struct(&but->rnapoin);
-    const char *member_id_data_path = member_id;
-    if (data_path) {
-      member_id_data_path = BLI_sprintfN("%s.%s", member_id, data_path);
-    }
+    char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin);
     const char *prop_id = RNA_property_identifier(but->rnaprop);
     bUserMenuItem *umi = (bUserMenuItem *)ED_screen_user_menu_item_find_prop(
         &um->items, member_id_data_path, prop_id, but->rnaindex);
-    if (data_path) {
-      MEM_freeN((void *)data_path);
-    }
-    if (member_id != member_id_data_path) {
-      MEM_freeN((void *)member_id_data_path);
-    }
+    MEM_freeN(member_id_data_path);
     return umi;
   }
 
@@ -412,21 +402,11 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
   }
   else if (but->rnaprop) {
     /* NOTE: 'member_id' may be a path. */
-    const char *member_id = WM_context_member_from_ptr(C, &but->rnapoin);
-    const char *data_path = RNA_path_from_ID_to_struct(&but->rnapoin);
-    const char *member_id_data_path = member_id;
-    if (data_path) {
-      member_id_data_path = BLI_sprintfN("%s.%s", member_id, data_path);
-    }
+    char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin);
     const char *prop_id = RNA_property_identifier(but->rnaprop);
     /* NOTE: ignore 'drawstr', use property idname always. */
     ED_screen_user_menu_item_add_prop(&um->items, "", member_id_data_path, prop_id, but->rnaindex);
-    if (data_path) {
-      MEM_freeN((void *)data_path);
-    }
-    if (member_id != member_id_data_path) {
-      MEM_freeN((void *)member_id_data_path);
-    }
+    MEM_freeN(member_id_data_path);
   }
   else if ((mt = UI_but_menutype_get(but))) {
     ED_screen_user_menu_item_add_menu(&um->items, drawstr, mt);
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index abbe609d0ef..76155973982 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -1162,7 +1162,7 @@ char *RNA_path_from_struct_to_idproperty(PointerRNA *ptr, struct IDProperty *nee
 
 struct ID *RNA_find_real_ID_and_path(struct Main *bmain, struct ID *id, const char **r_path);
 
-char *RNA_path_from_ID_to_struct(PointerRNA *ptr);
+char *RNA_path_from_ID_to_struct(const PointerRNA *ptr);
 
 char *RNA_path_from_real_ID_to_struct(struct Main *bmain, PointerRNA *ptr, struct ID **r_real);
 
@@ -1192,7 +1192,7 @@ char *RNA_path_full_property_py(struct Main *bmain,
                                 struct PropertyRNA *prop,
                                 int index);
 char *RNA_path_struct_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
-char *RNA_path_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
+char *RNA_path_property_py(const struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
 
 /* Quick name based property access
  *
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index a2905018cc7..51e20eb9e7f 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -5690,7 +5690,7 @@ char *RNA_path_from_struct_to_idproperty(PointerRNA *ptr, IDProperty *needle)
   return NULL;
 }
 
-static char *rna_path_from_ID_to_idpgroup(PointerRNA *ptr)
+static char *rna_path_from_ID_to_idpgroup(const PointerRNA *ptr)
 {
   PointerRNA id_ptr;
 
@@ -5775,7 +5775,7 @@ static char *rna_prepend_real_ID_path(Main *bmain, ID *id, char *path, ID **r_re
   return prefix[0] != '\0' ? BLI_strdup(prefix) : NULL;
 }
 
-char *RNA_path_from_ID_to_struct(PointerRNA *ptr)
+char *RNA_path_from_ID_to_struct(const PointerRNA *ptr)
 {
   char *ptrpath = NULL;
 
@@ -5786,7 +5786,7 @@ char *RNA_path_from_ID_to_struct(PointerRNA *ptr)
   if (!RNA_struct_is_ID(ptr->type)) {
     if (ptr->type->path) {
       /* if type has a path to some ID, use it */
-      ptrpath = ptr->type->path(ptr);
+      ptrpath = ptr->type->path((PointerRNA *)ptr);
     }
     else if (ptr->type->nested && RNA_struct_is_ID(ptr->type->nested)) {
       PointerRNA parentptr;
@@ -6156,7 +6156,7 @@ char *RNA_path_struct_property_py(PointerRNA *ptr, PropertyRNA *prop, int index)
  * Get the struct.property as a python representation, eg:
  *   some_prop[10]
  */
-char *RNA_path_property_py(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int index)
+char *RNA_path_property_py(const PointerRNA *UNUSED(ptr), PropertyRNA *prop, int index)
 {
   char *ret;
 
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index ca1610a8101..7ecbcad886d 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -262,8 +262,9 @@ struct wmEventHandler_Keymap *WM_event_add_keymap_handler_priority(ListBase *han
                                                                    wmKeyMap *keymap,
                                                                    int priority);
 
-typedef struct wmKeyMap *(wmEventHandler_KeymapDynamicFn)(
-    wmWindowManager *wm, struct wmEventHandler_Keymap *handler)ATTR_WARN_UNUSED_RESULT;
+typedef struct wmKeyMap *(wmEventHandler_KeymapDynamicFn)(wmWindowManager *wm,
+                                                          struct wmEventHandler_Keymap *handler)
+    ATTR_WARN_UNUSED_RESULT;
 
 struct wmKeyMap *WM_event_get_keymap_from_toolsystem_fallback(
     struct wmWindowManager *wm, struct wmEventHandler_Keymap *handler);
@@ -573,7 +574,11 @@ void WM_operator_py_idname(char *to, const char *from);
 bool WM_operator_py_idname_ok_or_report(struct ReportList *reports,
                                         const char *classname,
                                         const char *idname);
-const char *WM_context_member_from_ptr(struct bContext *C, const struct PointerRNA *ptr);
+char *WM_context_path_resolve_property_full(struct bContext *C,
+                                            const PointerRNA *ptr,
+                                            PropertyRNA *prop,
+                                            int index);
+char *WM_context_path_resolve_full(struct bContext *C, const PointerRNA *ptr);
 
 /* wm_operator_type.c */
 struct wmOperatorType *WM_operatortype_find(const char *idname, bool quiet);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index f1a8f4ffd71..dab3d7525db 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -55,6 +55,7 @@
 #include "BLI_dial_2d.h"
 #include "BLI_dynstr.h" /* For #WM_operator_pystring. */
 #include "BLI_math.h"
+#include "BLI_string_utils.h"
 #include "BLI_utildefines.h"
 
 #include "BKE_brush.h"
@@ -347,7 +348,7 @@ bool WM_operator_pystring_abbreviate(char *str, int str_len_max)
 
 /* return NULL if no match is found */
 #if 0
-static const char *wm_context_member_from_ptr(bContext *C, const PointerRNA *ptr)
+static const char *wm_context_member_from_ptr(bContext *C, const PointerRNA *ptr, bool *r_is_id)
 {
   /* loop over all context items and do 2 checks
    *
@@ -362,6 +363,7 @@ static const char *wm_context_member_from_ptr(bContext *C, const PointerRNA *ptr
 
   const char *member_found = NULL;
   const char *member_id = NULL;
+  bool member_found_is_id = false;
 
   for (link = lb.first; link; link = link->next) {
     const char *identifier = link->data;
@@ -373,14 +375,15 @@ static const char *wm_context_member_from_ptr(bContext *C, c

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list