Keymap conflict detection operator.
authorMartin Poirier <theeth@yahoo.com>
Thu, 17 Dec 2009 22:14:43 +0000 (22:14 +0000)
committerMartin Poirier <theeth@yahoo.com>
Thu, 17 Dec 2009 22:14:43 +0000 (22:14 +0000)
Takes into account the hierarchical structures of keymaps as well as wildcards (KM_ANY) in event definitions, user remaps (emulate numpad, action/select mouse buttons, ...) and event values that overlap (click, press and release)

For now, doesn't do anything other than print conflicts in the console.

As a result, I cleaned up a lot of keymaps that had double definitions, moved some keymap items in more appropriate places, fixed wrong definitions and removed kmi that were added for testing a long long time ago.

Out of all the remaining conflicts, after removing obvious non-issues, here's what remains: http://www.pasteall.org/9898

15 files changed:
release/scripts/ui/space_userpref.py
source/blender/editors/curve/curve_ops.c
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/object/object_ops.c
source/blender/editors/space_file/space_file.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_text/space_text.c
source/blender/editors/space_view3d/view3d_ops.c
source/blender/editors/transform/transform_ops.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_wm.c
source/blender/makesrna/intern/rna_wm_api.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_keymap.c

index d50c38f0e201414e0ad39e00e2d39c5b4d89c260..e33ac91435deb53bf8104e7e93c60b6ae0d856b4 100644 (file)
@@ -1467,9 +1467,10 @@ class USERPREF_PT_input(bpy.types.Panel):
         row.separator()
 
     def draw_filtered(self, kc, layout):
+        filter = kc.filter.lower()
 
         for km in kc.keymaps:
-            filtered_items = [kmi for kmi in km.items if kmi.name.lower().find(kc.filter.lower()) != -1]
+            filtered_items = [kmi for kmi in km.items if filter in kmi.name.lower()]
 
             if len(filtered_items) != 0:
                 km = km.active()
@@ -1539,7 +1540,133 @@ bpy.types.register(USERPREF_PT_input)
 
 from bpy.props import *
 
+class WM_OT_keyconfig_test(bpy.types.Operator):
+    "Test keyconfig for conflicts."
+    bl_idname = "wm.keyconfig_test"
+    bl_label = "Test Key Configuration for Conflicts"
+    
+    def testEntry(self, kc, entry, src = None, parent = None):
+        result = False
+        def kmistr(kmi):
+            if km.modal:
+                s = ["kmi = km.add_modal_item(\'%s\', \'%s\', \'%s\'" % (kmi.propvalue, kmi.type, kmi.value)]
+            else:
+                s = ["kmi = km.add_item(\'%s\', \'%s\', \'%s\'" % (kmi.idname, kmi.type, kmi.value)]
+
+            if kmi.any:
+                s.append(", any=True")
+            else:
+                if kmi.shift:
+                    s.append(", shift=True")
+                if kmi.ctrl:
+                    s.append(", ctrl=True")
+                if kmi.alt:
+                    s.append(", alt=True")
+                if kmi.oskey:
+                    s.append(", oskey=True")
+            if kmi.key_modifier and kmi.key_modifier != 'NONE':
+                s.append(", key_modifier=\'%s\'" % kmi.key_modifier)
+            
+            s.append(")\n")
+            
+            props = kmi.properties
+
+            if props is not None:
+                for pname in dir(props):
+                    if props.is_property_set(pname) and not props.is_property_hidden(pname):
+                        value = eval("props.%s" % pname)
+                        value = _string_value(value)
+                        if value != "":
+                            s.append("kmi.properties.%s = %s\n" % (pname, value))
+                            
+            return "".join(s).strip()
+                        
+        idname, spaceid, regionid, children = entry
 
+        km = kc.find_keymap(idname, space_type = spaceid, region_type = regionid)
+        
+        if km:
+            km = km.active()
+    
+            if src:
+                for item in km.items:
+                    if src.compare(item):
+                        print("===========")
+                        print(parent.name)
+                        print(kmistr(src))
+                        print(km.name)
+                        print(kmistr(item))
+                        result = True
+                
+                for child in children:
+                    if self.testEntry(kc, child, src, parent):
+                        result = True
+            else:
+                for i in range(len(km.items)):
+                    src = km.items[i]
+                    
+                    for child in children:
+                        if self.testEntry(kc, child, src, km):
+                            result = True
+
+                    for j in range(len(km.items) - i - 1):
+                        item = km.items[j + i + 1]
+                        if src.compare(item):
+                            print("===========")
+                            print(km.name)
+                            print(kmistr(src))
+                            print(kmistr(item))
+                            result = True
+    
+                for child in children:
+                    if self.testEntry(kc, child):
+                        result = True
+        
+        return result
+    
+    def testConfig(self, kc):
+        result = False
+        for entry in KM_HIERARCHY:
+            if self.testEntry(kc, entry):
+                result = True
+        return result
+        
+    def execute(self, context):
+        wm = context.manager
+        kc = wm.default_keyconfig
+        
+        if self.testConfig(kc):
+            print("CONFLICT")
+       
+        return ('FINISHED',)
+
+def _string_value(value):
+    result = ""
+    if isinstance(value, str):
+        if value != "":
+            result = "\'%s\'" % value
+    elif isinstance(value, bool):
+        if value:
+            result = "True"
+        else:
+            result = "False"
+    elif isinstance(value, float):
+        result = "%.10f" % value
+    elif isinstance(value, int):
+        result = "%d" % value
+    elif getattr(value, '__len__', False):
+        if len(value):
+            result = "["
+            for i in range(0, len(value)):
+                result += _string_value(value[i])
+                if i != len(value)-1:
+                    result += ", "
+            result += "]"
+    else:
+        print("Export key configuration: can't write ", value)
+
+    return result
+    
 class WM_OT_keyconfig_export(bpy.types.Operator):
     "Export key configuration to a python script."
     bl_idname = "wm.keyconfig_export"
@@ -1547,33 +1674,6 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
 
     path = bpy.props.StringProperty(name="File Path", description="File path to write file to.")
 
-    def _string_value(self, value):
-        result = ""
-        if isinstance(value, str):
-            if value != "":
-                result = "\'%s\'" % value
-        elif isinstance(value, bool):
-            if value:
-                result = "True"
-            else:
-                result = "False"
-        elif isinstance(value, float):
-            result = "%.10f" % value
-        elif isinstance(value, int):
-            result = "%d" % value
-        elif getattr(value, '__len__', False):
-            if len(value):
-                result = "["
-                for i in range(0, len(value)):
-                    result += self._string_value(value[i])
-                    if i != len(value)-1:
-                        result += ", "
-                result += "]"
-        else:
-            print("Export key configuration: can't write ", value)
-
-        return result
-
     def execute(self, context):
         if not self.properties.path:
             raise Exception("File path not set.")
@@ -1620,7 +1720,7 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
                     for pname in dir(props):
                         if props.is_property_set(pname) and not props.is_property_hidden(pname):
                             value = eval("props.%s" % pname)
-                            value = self._string_value(value)
+                            value = _string_value(value)
                             if value != "":
                                 f.write("kmi.properties.%s = %s\n" % (pname, value))
 
@@ -1714,6 +1814,7 @@ class WM_OT_keyitem_remove(bpy.types.Operator):
         return ('FINISHED',)
 
 bpy.ops.add(WM_OT_keyconfig_export)
+bpy.ops.add(WM_OT_keyconfig_test)
 bpy.ops.add(WM_OT_keymap_edit)
 bpy.ops.add(WM_OT_keymap_restore)
 bpy.ops.add(WM_OT_keyitem_add)
index 3f59e295fe43a55741099235d9858ed87cc4c2b1..be52952b474576997181640eceff135bdd2448a6 100644 (file)
@@ -238,7 +238,7 @@ void ED_keymap_curve(wmKeyConfig *keyconf)
        WM_keymap_add_item(keymap, "CURVE_OT_delete", DELKEY, KM_PRESS, 0, 0);
 
        WM_keymap_add_item(keymap, "CURVE_OT_tilt_clear", TKEY, KM_PRESS, KM_ALT, 0);
-       RNA_enum_set(WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", TKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", TFM_TILT);
+       WM_keymap_add_item(keymap, "TRANSFORM_OT_tilt", TKEY, KM_PRESS, KM_CTRL, 0);
        RNA_enum_set(WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", TFM_CURVE_SHRINKFATTEN);
        RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", 1);
        RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", HKEY, KM_PRESS, 0, 0)->ptr, "type", 3);
index b067f894050ec39fd0a15818db9e75bfbb72c976..621e952fb6d30a3dd695dca244720d18f0599903 100644 (file)
@@ -255,7 +255,6 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
        WM_keymap_add_item(keymap, "MESH_OT_extrude_move", EKEY, KM_PRESS, 0, 0);
        
        WM_keymap_add_item(keymap, "MESH_OT_spin", RKEY, KM_PRESS, KM_ALT, 0);
-       WM_keymap_add_item(keymap, "MESH_OT_screw", NINEKEY, KM_PRESS, KM_CTRL, 0);
        
        WM_keymap_add_item(keymap, "MESH_OT_fill", FKEY, KM_PRESS, KM_SHIFT, 0);
        WM_keymap_add_item(keymap, "MESH_OT_beauty_fill", FKEY, KM_PRESS, KM_ALT, 0);
@@ -263,20 +262,11 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
        WM_keymap_add_item(keymap, "MESH_OT_tris_convert_to_quads", JKEY, KM_PRESS, KM_ALT, 0);
        WM_keymap_add_item(keymap, "MESH_OT_edge_flip", FKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
 
-       WM_keymap_add_item(keymap, "MESH_OT_extrude_repeat", FOURKEY, KM_PRESS, KM_ALT, 0);
-       WM_keymap_add_item(keymap, "MESH_OT_edge_rotate", FIVEKEY, KM_PRESS, KM_CTRL, 0);
-       
-       WM_keymap_add_item(keymap, "MESH_OT_loop_to_region",SIXKEY, KM_PRESS, KM_CTRL, 0);
-       WM_keymap_add_item(keymap, "MESH_OT_region_to_loop",SIXKEY, KM_PRESS, KM_ALT, 0);
-       
-       WM_keymap_add_item(keymap, "MESH_OT_uvs_rotate",SEVENKEY, KM_PRESS, KM_CTRL, 0);
-       WM_keymap_add_item(keymap, "MESH_OT_uvs_mirror",SEVENKEY, KM_PRESS, KM_ALT, 0);
-       WM_keymap_add_item(keymap, "MESH_OT_colors_rotate",EIGHTKEY, KM_PRESS, KM_CTRL, 0);
-       WM_keymap_add_item(keymap, "MESH_OT_colors_mirror",EIGHTKEY, KM_PRESS, KM_ALT, 0);
-
        WM_keymap_add_item(keymap, "MESH_OT_rip_move",VKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "MESH_OT_merge", MKEY, KM_PRESS, KM_ALT, 0);
 
+       WM_keymap_add_item(keymap, "TRANSFORM_OT_shrink_fatten", SKEY, KM_PRESS, KM_ALT, 0);
+
        /* add/remove */
        WM_keymap_add_item(keymap, "MESH_OT_edge_face_add", FKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "MESH_OT_skin", FKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); /* python */
index 8def741ed2b02828094a507af54e67b38947264d..dbd03561c20f54d574f4b2ce344fe71552814cce 100644 (file)
@@ -247,9 +247,6 @@ void ED_keymap_object(wmKeyConfig *keyconf)
                RNA_enum_set(kmi->ptr, "mode", OB_MODE_VERTEX_PAINT);
                RNA_boolean_set(kmi->ptr, "toggle", 1);
        
-       kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", VKEY, KM_PRESS, 0, 0);
-               RNA_enum_set(kmi->ptr, "mode", OB_MODE_VERTEX_PAINT);
-               RNA_boolean_set(kmi->ptr, "toggle", 1);
        kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, KM_CTRL, 0);
                RNA_enum_set(kmi->ptr, "mode", OB_MODE_WEIGHT_PAINT);
                RNA_boolean_set(kmi->ptr, "toggle", 1);
@@ -264,6 +261,8 @@ void ED_keymap_object(wmKeyConfig *keyconf)
        /* object mode supports PET now */
        ED_object_generic_keymap(keyconf, keymap, TRUE);
 
+       WM_keymap_add_item(keymap, "VIEW3D_OT_game_start", PKEY, KM_PRESS, 0, 0);
+
        WM_keymap_add_item(keymap, "OBJECT_OT_select_all", AKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "OBJECT_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "OBJECT_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0);
index 8bbdbbeb4fb1086d7e1c77311e6e1b30631a420a..939af53b87da225affb041037be4acaf57b3fcbc 100644 (file)
@@ -405,7 +405,6 @@ void file_keymap(struct wmKeyConfig *keyconf)
        
        /* keys for button area (top) */
        keymap= WM_keymap_find(keyconf, "FileButtons", SPACE_FILE, 0);
-       WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, 0, 0);
        kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, 0, 0);
        RNA_int_set(kmi->ptr, "increment", 1);
        kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, KM_SHIFT, 0);
index cde81ad7cf35dd92ed70757cdb905352927ee820..58f48f6fa071cde689f473cb3878f8466940adc8 100644 (file)
@@ -234,11 +234,7 @@ void image_keymap(struct wmKeyConfig *keyconf)
        RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
        RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f);
 
-       WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "PAINT_OT_grab_clone", RIGHTMOUSE, KM_PRESS, 0, 0);
-       WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0);
-       RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
-       RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
 
        WM_keymap_add_item(keymap, "IMAGE_OT_sample", ACTIONMOUSE, KM_PRESS, 0, 0);
        RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "point", 0);
index a8d146bb7a883c818563ee1a4659d39f19678331..821eaed16755cfcff9a731d08f0354167724079a 100644 (file)
@@ -261,13 +261,12 @@ static void text_keymap(struct wmKeyConfig *keyconf)
        WM_keymap_add_item(keymap, "TEXT_OT_uncomment", DKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
 
        RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN);
+       RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);
        
        RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_BEGIN);
-       RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);
-       RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_BEGIN);
+       RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END);
        RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", EKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END);
        RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", EKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "type", LINE_END);
-       RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);
        RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_CHAR);
        RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_CHAR);
        RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", PREV_WORD);
@@ -303,8 +302,6 @@ static void text_keymap(struct wmKeyConfig *keyconf)
        RNA_int_set(WM_keymap_add_item(keymap, "TEXT_OT_scroll", WHEELUPMOUSE, KM_PRESS, 0, 0)->ptr, "lines", -1);
        RNA_int_set(WM_keymap_add_item(keymap, "TEXT_OT_scroll", WHEELDOWNMOUSE, KM_PRESS, 0, 0)->ptr, "lines", 1);
 
-       WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_ALT, 0);
-
        WM_keymap_add_item(keymap, "TEXT_OT_line_break", RETKEY, KM_PRESS, 0, 0);
 
        WM_keymap_add_item(keymap, "TEXT_OT_line_number", KM_TEXTINPUT, KM_ANY, KM_ANY, 0);
index bc8d34b407b9a05b9093f1da93d0433240f9f359..27c062fee8c521c59eb35f11de0785af3e8484d7 100644 (file)
@@ -183,8 +183,6 @@ void view3d_keymap(wmKeyConfig *keyconf)
 
        WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0);
        
-       WM_keymap_add_item(keymap, "VIEW3D_OT_game_start", PKEY, KM_PRESS, 0, 0);
-       
        /* layers, shift + alt are properties set in invoke() */
        RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ACCENTGRAVEKEY, KM_PRESS, 0, 0)->ptr, "nr", 0);
        RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ONEKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 1);
index f794d79bdd908a287ab08c9a64c8109ead62ede6..f9dcd6f87f41cd0c847a2c249b5196fbe9ef5496 100644 (file)
@@ -773,10 +773,6 @@ void transform_keymap_for_space(struct wmKeyConfig *keyconf, struct wmKeyMap *ke
 
                        km = WM_keymap_add_item(keymap, "TRANSFORM_OT_shear", SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
 
-                       km = WM_keymap_add_item(keymap, "TRANSFORM_OT_shrink_fatten", SKEY, KM_PRESS, KM_ALT, 0);
-
-                       km = WM_keymap_add_item(keymap, "TRANSFORM_OT_tilt", TKEY, KM_PRESS, 0, 0);
-
                        km = WM_keymap_add_item(keymap, "TRANSFORM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0);
 
                        km = WM_keymap_add_item(keymap, "TRANSFORM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
index f43db74286b0a7693523691b3391429dff7cf1be..1c14d0d4c062e80de8fde83f4a431a7baad45afb 100644 (file)
@@ -211,6 +211,7 @@ void RNA_api_operator(struct StructRNA *srna);
 void RNA_api_keyconfig(struct StructRNA *srna);
 void RNA_api_keyingset(struct StructRNA *srna);
 void RNA_api_keymap(struct StructRNA *srna);
+void RNA_api_keymapitem(struct StructRNA *srna);
 void RNA_api_main(struct StructRNA *srna);
 void RNA_api_material(StructRNA *srna);
 void RNA_api_mesh(struct StructRNA *srna);
index 09adb642e583c2a5fa57d388b56f8521b84e9b10..3d4899a0a5152182f4495fa21b66c679ad2c483f 100644 (file)
@@ -997,6 +997,8 @@ static void rna_def_keyconfig(BlenderRNA *brna)
        RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", KMI_INACTIVE);
        RNA_def_property_ui_text(prop, "Active", "Activate or deactivate item.");
        RNA_def_property_ui_icon(prop, ICON_CHECKBOX_DEHLT, 1);
+
+       RNA_api_keymapitem(srna);
 }
 
 void RNA_def_wm(BlenderRNA *brna)
index 94a689c9f1cac8a4ec0810d8415bd78d5029105d..0cec66fe2641c375432ea4cb57cf2cd5e5f97521 100644 (file)
@@ -288,5 +288,16 @@ void RNA_api_keymap(StructRNA *srna)
        RNA_def_property_flag(parm, PROP_REQUIRED);
 }
 
+void RNA_api_keymapitem(StructRNA *srna)
+{
+       FunctionRNA *func;
+       PropertyRNA *parm;
+
+       func= RNA_def_function(srna, "compare", "WM_keymap_item_compare");
+       parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       parm= RNA_def_boolean(func, "result", 0, "Comparison result", "");
+       RNA_def_function_return(func, parm);
+}
 #endif
 
index c4270fbc8b048763c6bf64893eea77b1b0201b6a..1702149cf8b506a19e129efab3dc31727c4de068 100644 (file)
@@ -115,6 +115,8 @@ wmKeyMap    *WM_keymap_copy_to_user(struct wmKeyMap *keymap);
 void           WM_keymap_restore_to_default(struct wmKeyMap *keymap);
 void           WM_keymap_properties_reset(struct wmKeyMapItem *kmi);
 void           WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
+int                    WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2);
+int                    WM_userdef_event_map(int kmitype);
 
 wmKeyMap       *WM_modalkeymap_add(struct wmKeyConfig *keyconf, char *idname, struct EnumPropertyItem *items);
 wmKeyMap       *WM_modalkeymap_get(struct wmKeyConfig *keyconf, char *idname);
index ccc020827c5c6a8b0ef1e8a98378bb283e413078..ac4c2709688ef3a4086b205b7724d0fce3040019 100644 (file)
@@ -709,7 +709,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
 }
 
 /* do userdef mappings */
-static int wm_userdef_event_map(int kmitype)
+int WM_userdef_event_map(int kmitype)
 {
        switch(kmitype) {
                case SELECTMOUSE:
@@ -754,7 +754,7 @@ static int wm_userdef_event_map(int kmitype)
 
 static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi)
 {
-       int kmitype= wm_userdef_event_map(kmi->type);
+       int kmitype= WM_userdef_event_map(kmi->type);
 
        if(kmi->flag & KMI_INACTIVE) return 0;
 
index e1f812ee45fa3019428dd3f92867036bc250e529..116bc263d715149842560c7b8a8ed6b360058989 100644 (file)
@@ -453,6 +453,48 @@ char *WM_key_event_operator_string(const bContext *C, const char *opname, int op
        return NULL;
 }
 
+int    WM_keymap_item_compare(wmKeyMapItem *k1, wmKeyMapItem *k2)
+{
+       int k1type, k2type;
+
+       if (k1->flag & KMI_INACTIVE || k2->flag & KMI_INACTIVE)
+               return 0;
+
+       /* take event mapping into account */
+       k1type = WM_userdef_event_map(k1->type);
+       k2type = WM_userdef_event_map(k2->type);
+
+       if(k1type != KM_ANY && k2type != KM_ANY && k1type != k2type)
+               return 0;
+
+       if(k1->val != KM_ANY && k2->val != KM_ANY) {
+               /* take click, press, release conflict into account */
+               if (k1->val == KM_CLICK && ELEM3(k2->val, KM_PRESS, KM_RELEASE, KM_CLICK) == 0)
+                       return 0;
+               if (k2->val == KM_CLICK && ELEM3(k1->val, KM_PRESS, KM_RELEASE, KM_CLICK) == 0)
+                       return 0;
+               if (k1->val != k2->val)
+                       return 0;
+       }
+
+       if(k1->shift != KM_ANY && k2->shift != KM_ANY && k1->shift != k2->shift)
+               return 0;
+
+       if(k1->ctrl != KM_ANY && k2->ctrl != KM_ANY && k1->ctrl != k2->ctrl)
+               return 0;
+
+       if(k1->alt != KM_ANY && k2->alt != KM_ANY && k1->alt != k2->alt)
+               return 0;
+
+       if(k1->oskey != KM_ANY && k2->oskey != KM_ANY && k1->oskey != k2->oskey)
+               return 0;
+
+       if(k1->keymodifier != k2->keymodifier)
+               return 0;
+
+       return 1;
+}
+
 /* ***************** user preferences ******************* */
 
 int WM_keymap_user_init(wmWindowManager *wm, wmKeyMap *keymap)