keyconfig_utils.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. # ##### BEGIN GPL LICENSE BLOCK #####
  2. #
  3. # This program is free software; you can redistribute it and/or
  4. # modify it under the terms of the GNU General Public License
  5. # as published by the Free Software Foundation; either version 2
  6. # of the License, or (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software Foundation,
  15. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. #
  17. # ##### END GPL LICENSE BLOCK #####
  18. # <pep8 compliant>
  19. # -----------------------------------------------------------------------------
  20. # Add-on helpers to properly (un)register their own keymaps.
  21. def addon_keymap_register(keymap_data):
  22. """
  23. Register a set of keymaps for addons using a list of keymaps.
  24. See 'blender_defaults.py' for examples of the format this takes.
  25. """
  26. import bpy
  27. wm = bpy.context.window_manager
  28. from bl_keymap_utils.io import keymap_init_from_data
  29. kconf = wm.keyconfigs.addon
  30. if not kconf:
  31. return # happens in background mode...
  32. for km_name, km_args, km_content in keymap_data:
  33. km_space_type = km_args["space_type"]
  34. km_region_type = km_args["region_type"]
  35. km_modal = km_args.get("modal", False)
  36. kmap = next(iter(
  37. k for k in kconf.keymaps
  38. if k.name == km_name and
  39. k.region_type == km_region_type and
  40. k.space_type == km_space_type and
  41. k.is_modal == km_modal
  42. ), None)
  43. if kmap is None:
  44. kmap = kconf.keymaps.new(km_name, **km_args)
  45. keymap_init_from_data(kmap, km_content["items"], is_modal=km_modal)
  46. def addon_keymap_unregister(keymap_data):
  47. """
  48. Unregister a set of keymaps for addons.
  49. """
  50. # NOTE: We must also clean up user keyconfig, else, if user has customized one of add-on's shortcut, this
  51. # customization remains in memory, and comes back when re-enabling the addon, causing a segfault... :/
  52. import bpy
  53. wm = bpy.context.window_manager
  54. kconfs = wm.keyconfigs
  55. for kconf in (kconfs.user, kconfs.addon):
  56. for km_name, km_args, km_content in keymap_data:
  57. km_space_type = km_args["space_type"]
  58. km_region_type = km_args["region_type"]
  59. km_modal = km_args.get("modal", False)
  60. kmaps = (
  61. k for k in kconf.keymaps
  62. if k.name == km_name and
  63. k.region_type == km_region_type and
  64. k.space_type == km_space_type and
  65. k.is_modal == km_modal
  66. )
  67. for kmap in kmaps:
  68. for kmi_idname, _, _ in km_content["items"]:
  69. for kmi in kmap.keymap_items:
  70. if kmi.idname == kmi_idname:
  71. kmap.keymap_items.remove(kmi)
  72. # NOTE: We won't remove addons keymaps themselves, other addons might also use them!
  73. # -----------------------------------------------------------------------------
  74. # Utility Functions
  75. def keyconfig_test(kc):
  76. def testEntry(kc, entry, src=None, parent=None):
  77. result = False
  78. idname, spaceid, regionid, children = entry
  79. km = kc.keymaps.find(idname, space_type=spaceid, region_type=regionid)
  80. if km:
  81. km = km.active()
  82. is_modal = km.is_modal
  83. if src:
  84. for item in km.keymap_items:
  85. if src.compare(item):
  86. print("===========")
  87. print(parent.name)
  88. print(_kmistr(src, is_modal).strip())
  89. print(km.name)
  90. print(_kmistr(item, is_modal).strip())
  91. result = True
  92. for child in children:
  93. if testEntry(kc, child, src, parent):
  94. result = True
  95. else:
  96. for i in range(len(km.keymap_items)):
  97. src = km.keymap_items[i]
  98. for child in children:
  99. if testEntry(kc, child, src, km):
  100. result = True
  101. for j in range(len(km.keymap_items) - i - 1):
  102. item = km.keymap_items[j + i + 1]
  103. if src.compare(item):
  104. print("===========")
  105. print(km.name)
  106. print(_kmistr(src, is_modal).strip())
  107. print(_kmistr(item, is_modal).strip())
  108. result = True
  109. for child in children:
  110. if testEntry(kc, child):
  111. result = True
  112. return result
  113. # -------------------------------------------------------------------------
  114. # Function body
  115. from bl_keymap_utils import keymap_hierarchy
  116. result = False
  117. for entry in keymap_hierarchy.generate():
  118. if testEntry(kc, entry):
  119. result = True
  120. return result