Cleanup: trailing space
[blender-addons.git] / development_iskeyfree.py
bloba9201ab60923080c5ef14a56caa6e4118b62b635
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # PEP8 compliant (https://www.python.org/dev/peps/pep-0008)
5 bl_info = {
6 "name": "Is key Free",
7 "author": "Antonio Vazquez (antonioya)",
8 "version": (1, 1, 2),
9 "blender": (2, 80, 0),
10 "location": "Text Editor > Sidebar > Dev Tab",
11 "description": "Find free shortcuts, inform about used and print a key list",
12 "doc_url": "{BLENDER_MANUAL_URL}/addons/development/is_key_free.html",
13 "category": "Development",
16 import bpy
17 from bpy.props import (
18 BoolProperty,
19 EnumProperty,
20 StringProperty,
21 PointerProperty,
23 from bpy.types import (
24 Operator,
25 Panel,
26 PropertyGroup,
30 # ------------------------------------------------------
31 # Class to find keymaps
32 # ------------------------------------------------------
34 class MyChecker():
35 lastfind = None
36 lastkey = None
37 mylist = []
39 # Init
40 def __init__(self):
41 self.var = 5
43 # Verify if the key is used
44 @classmethod
45 def check(cls, findkey, ctrl, alt, shift, oskey):
46 if len(findkey) > 0:
47 cmd = ""
48 if ctrl is True:
49 cmd += "Ctrl+"
50 if alt is True:
51 cmd += "Alt+"
52 if shift is True:
53 cmd += "Shift+"
54 if oskey is True:
55 cmd += "OsKey+"
56 cls.lastfind = cmd + findkey.upper()
57 cls.lastkey = findkey.upper()
58 else:
59 cls.lastfind = None
60 cls.lastkey = None
62 wm = bpy.context.window_manager
63 mykeys = []
65 for context, keyboardmap in wm.keyconfigs.user.keymaps.items():
66 for myitem in keyboardmap.keymap_items:
67 if myitem.active is True and myitem.type == findkey:
68 if ctrl is True and myitem.ctrl is not True:
69 continue
70 if alt is True and myitem.alt is not True:
71 continue
72 if shift is True and myitem.shift is not True:
73 continue
74 if oskey is True and myitem.oskey is not True:
75 continue
76 t = (context,
77 myitem.type,
78 "Ctrl" if myitem.ctrl is True else "",
79 "Alt" if myitem.alt is True else "",
80 "Shift" if myitem.shift is True else "",
81 "OsKey" if myitem.oskey is True else "",
82 myitem.name)
84 mykeys.append(t)
86 sortkeys = sorted(mykeys, key=lambda key: (key[0], key[1], key[2], key[3], key[4], key[5]))
88 cls.mylist.clear()
89 for e in sortkeys:
90 cmd = ""
91 if e[2] != "":
92 cmd += e[2] + "+"
93 if e[3] != "":
94 cmd += e[3] + "+"
95 if e[4] != "":
96 cmd += e[4] + "+"
97 if e[5] != "":
98 cmd += e[5] + "+"
100 cmd += e[1]
102 if e[6] != "":
103 cmd += " " + e[6]
104 cls.mylist.append([e[0], cmd])
106 # return context
107 @classmethod
108 def getcontext(cls):
109 return str(bpy.context.screen.name)
111 # return last search
112 @classmethod
113 def getlast(cls):
114 return cls.lastfind
116 # return last key
117 @classmethod
118 def getlastkey(cls):
119 return cls.lastkey
121 # return result of last search
122 @classmethod
123 def getlist(cls):
124 return cls.mylist
126 # verify if key is valid
127 @classmethod
128 def isvalidkey(cls, txt):
129 allkeys = [
130 "LEFTMOUSE", "MIDDLEMOUSE", "RIGHTMOUSE", "BUTTON4MOUSE", "BUTTON5MOUSE", "BUTTON6MOUSE",
131 "BUTTON7MOUSE",
132 "MOUSEMOVE", "INBETWEEN_MOUSEMOVE", "TRACKPADPAN", "TRACKPADZOOM",
133 "MOUSEROTATE", "WHEELUPMOUSE", "WHEELDOWNMOUSE", "WHEELINMOUSE", "WHEELOUTMOUSE", "EVT_TWEAK_L",
134 "EVT_TWEAK_M", "EVT_TWEAK_R", "A", "B", "C", "D", "E", "F", "G", "H",
135 "I", "J",
136 "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "ZERO", "ONE", "TWO",
137 "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "LEFT_CTRL", "LEFT_ALT", "LEFT_SHIFT",
138 "RIGHT_ALT",
139 "RIGHT_CTRL", "RIGHT_SHIFT", "OSKEY", "GRLESS", "ESC", "TAB", "RET", "SPACE", "LINE_FEED",
140 "BACK_SPACE",
141 "DEL", "SEMI_COLON", "PERIOD", "COMMA", "QUOTE", "ACCENT_GRAVE", "MINUS", "SLASH", "BACK_SLASH",
142 "EQUAL",
143 "LEFT_BRACKET", "RIGHT_BRACKET", "LEFT_ARROW", "DOWN_ARROW", "RIGHT_ARROW", "UP_ARROW", "NUMPAD_2",
144 "NUMPAD_4", "NUMPAD_6", "NUMPAD_8", "NUMPAD_1", "NUMPAD_3", "NUMPAD_5", "NUMPAD_7", "NUMPAD_9",
145 "NUMPAD_PERIOD", "NUMPAD_SLASH", "NUMPAD_ASTERIX", "NUMPAD_0", "NUMPAD_MINUS", "NUMPAD_ENTER",
146 "NUMPAD_PLUS",
147 "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15",
148 "F16", "F17",
149 "F18", "F19", "PAUSE", "INSERT", "HOME", "PAGE_UP", "PAGE_DOWN", "END", "MEDIA_PLAY", "MEDIA_STOP",
150 "MEDIA_FIRST", "MEDIA_LAST", "TEXTINPUT", "WINDOW_DEACTIVATE", "TIMER", "TIMER0", "TIMER1", "TIMER2",
151 "TIMER_JOBS", "TIMER_AUTOSAVE", "TIMER_REPORT", "TIMERREGION", "NDOF_MOTION", "NDOF_BUTTON_MENU",
152 "NDOF_BUTTON_FIT", "NDOF_BUTTON_TOP", "NDOF_BUTTON_BOTTOM", "NDOF_BUTTON_LEFT", "NDOF_BUTTON_RIGHT",
153 "NDOF_BUTTON_FRONT", "NDOF_BUTTON_BACK", "NDOF_BUTTON_ISO1", "NDOF_BUTTON_ISO2",
154 "NDOF_BUTTON_ROLL_CW",
155 "NDOF_BUTTON_ROLL_CCW", "NDOF_BUTTON_SPIN_CW", "NDOF_BUTTON_SPIN_CCW", "NDOF_BUTTON_TILT_CW",
156 "NDOF_BUTTON_TILT_CCW", "NDOF_BUTTON_ROTATE", "NDOF_BUTTON_PANZOOM", "NDOF_BUTTON_DOMINANT",
157 "NDOF_BUTTON_PLUS", "NDOF_BUTTON_MINUS", "NDOF_BUTTON_ESC", "NDOF_BUTTON_ALT", "NDOF_BUTTON_SHIFT",
158 "NDOF_BUTTON_CTRL", "NDOF_BUTTON_1", "NDOF_BUTTON_2", "NDOF_BUTTON_3", "NDOF_BUTTON_4",
159 "NDOF_BUTTON_5",
160 "NDOF_BUTTON_6", "NDOF_BUTTON_7", "NDOF_BUTTON_8", "NDOF_BUTTON_9", "NDOF_BUTTON_10",
161 "NDOF_BUTTON_A",
162 "NDOF_BUTTON_B", "NDOF_BUTTON_C"
164 try:
165 allkeys.index(txt)
166 return True
167 except ValueError:
168 return False
171 mychecker = MyChecker() # Global class handler
174 # ------------------------------------------------------
175 # Button: Class for search button
176 # ------------------------------------------------------
177 class RunActionCheck(Operator):
178 bl_idname = "iskeyfree.action_check"
179 bl_label = ""
180 bl_description = "Verify if the selected shortcut is free"
182 # noinspection PyUnusedLocal
183 def execute(self, context):
184 scene = context.scene.is_keyfree
185 txt = scene.data.upper()
186 global mychecker
187 mychecker.check(txt, scene.use_crtl, scene.use_alt, scene.use_shift,
188 scene.use_oskey)
190 return {'FINISHED'}
193 # ------------------------------------------------------
194 # Defines UI panel
195 # ------------------------------------------------------
196 class UIControlPanel(Panel):
197 bl_idname = "DEVISKEYFREE_PT_ui"
198 bl_space_type = "TEXT_EDITOR"
199 bl_region_type = "UI"
200 bl_label = "Is Key Free"
201 bl_category = 'Dev'
202 bl_options = {'DEFAULT_CLOSED'}
204 # noinspection PyUnusedLocal
205 def draw(self, context):
206 layout = self.layout
207 scene = context.scene.is_keyfree
209 row = layout.row(align=True)
210 row.prop(scene, "data")
211 row.operator("iskeyfree.action_check", icon="VIEWZOOM")
213 row = layout.row(align=True)
214 row.prop(scene, "use_crtl", toggle=True)
215 row.prop(scene, "use_alt", toggle=True)
216 row.prop(scene, "use_shift", toggle=True)
217 row.prop(scene, "use_oskey", toggle=True)
219 row = layout.row()
220 row.prop(scene, "numpad")
222 layout.operator("iskeyfree.run_export_keys", icon="FILE_TEXT")
224 global mychecker
225 mylist = mychecker.getlist()
226 oldcontext = None
228 box = None
229 if len(mylist) > 0:
230 cmd = mychecker.getlast()
231 if cmd is not None:
232 row = layout.row()
233 row.label(text="Current uses of " + str(cmd), icon="PARTICLE_DATA")
234 for e in mylist:
235 if oldcontext != e[0]:
236 box = layout.box()
237 box.label(text=e[0], icon="UNPINNED")
238 oldcontext = e[0]
240 row = box.row(align=True)
241 row.label(text=e[1])
242 else:
243 cmd = mychecker.getlast()
244 if cmd is not None:
245 box = layout.box()
246 if mychecker.isvalidkey(mychecker.getlastkey()) is False:
247 box.label(text=str(mychecker.getlastkey()) + " looks not valid key", icon="ERROR")
248 else:
249 box.label(text=str(cmd) + " is free", icon="FILE_TICK")
252 # ------------------------------------------------------
253 # Update key (special values) event handler
254 # ------------------------------------------------------
255 # noinspection PyUnusedLocal
256 def update_data(self, context):
257 scene = context.scene.is_keyfree
258 if scene.numpad != "NONE":
259 scene.data = scene.numpad
262 class IskeyFreeProperties(PropertyGroup):
263 data: StringProperty(
264 name="Key", maxlen=32,
265 description="Shortcut to verify"
267 use_crtl: BoolProperty(
268 name="Ctrl",
269 description="Ctrl key used in shortcut",
270 default=False
272 use_alt: BoolProperty(
273 name="Alt",
274 description="Alt key used in shortcut",
275 default=False
277 use_shift: BoolProperty(
278 name="Shift",
279 description="Shift key used in shortcut",
280 default=False
282 use_oskey: BoolProperty(
283 name="OsKey",
284 description="Operating system key used in shortcut",
285 default=False
287 numpad: EnumProperty(
288 items=(
289 ('NONE', "Select key", ""),
290 ("LEFTMOUSE", "LEFTMOUSE", ""),
291 ("MIDDLEMOUSE", "MIDDLEMOUSE", ""),
292 ("RIGHTMOUSE", "RIGHTMOUSE", ""),
293 ("BUTTON4MOUSE", "BUTTON4MOUSE", ""),
294 ("BUTTON5MOUSE", "BUTTON5MOUSE", ""),
295 ("BUTTON6MOUSE", "BUTTON6MOUSE", ""),
296 ("BUTTON7MOUSE", "BUTTON7MOUSE", ""),
297 ("MOUSEMOVE", "MOUSEMOVE", ""),
298 ("INBETWEEN_MOUSEMOVE", "INBETWEEN_MOUSEMOVE", ""),
299 ("TRACKPADPAN", "TRACKPADPAN", ""),
300 ("TRACKPADZOOM", "TRACKPADZOOM", ""),
301 ("MOUSEROTATE", "MOUSEROTATE", ""),
302 ("WHEELUPMOUSE", "WHEELUPMOUSE", ""),
303 ("WHEELDOWNMOUSE", "WHEELDOWNMOUSE", ""),
304 ("WHEELINMOUSE", "WHEELINMOUSE", ""),
305 ("WHEELOUTMOUSE", "WHEELOUTMOUSE", ""),
306 ("EVT_TWEAK_L", "EVT_TWEAK_L", ""),
307 ("EVT_TWEAK_M", "EVT_TWEAK_M", ""),
308 ("EVT_TWEAK_R", "EVT_TWEAK_R", ""),
309 ("A", "A", ""),
310 ("B", "B", ""),
311 ("C", "C", ""),
312 ("D", "D", ""),
313 ("E", "E", ""),
314 ("F", "F", ""),
315 ("G", "G", ""),
316 ("H", "H", ""),
317 ("I", "I", ""),
318 ("J", "J", ""),
319 ("K", "K", ""),
320 ("L", "L", ""),
321 ("M", "M", ""),
322 ("N", "N", ""),
323 ("O", "O", ""),
324 ("P", "P", ""),
325 ("Q", "Q", ""),
326 ("R", "R", ""),
327 ("S", "S", ""),
328 ("T", "T", ""),
329 ("U", "U", ""),
330 ("V", "V", ""),
331 ("W", "W", ""),
332 ("X", "X", ""),
333 ("Y", "Y", ""),
334 ("Z", "Z", ""),
335 ("ZERO", "ZERO", ""),
336 ("ONE", "ONE", ""),
337 ("TWO", "TWO", ""),
338 ("THREE", "THREE", ""),
339 ("FOUR", "FOUR", ""),
340 ("FIVE", "FIVE", ""),
341 ("SIX", "SIX", ""),
342 ("SEVEN", "SEVEN", ""),
343 ("EIGHT", "EIGHT", ""),
344 ("NINE", "NINE", ""),
345 ("LEFT_CTRL", "LEFT_CTRL", ""),
346 ("LEFT_ALT", "LEFT_ALT", ""),
347 ("LEFT_SHIFT", "LEFT_SHIFT", ""),
348 ("RIGHT_ALT", "RIGHT_ALT", ""),
349 ("RIGHT_CTRL", "RIGHT_CTRL", ""),
350 ("RIGHT_SHIFT", "RIGHT_SHIFT", ""),
351 ("OSKEY", "OSKEY", ""),
352 ("GRLESS", "GRLESS", ""),
353 ("ESC", "ESC", ""),
354 ("TAB", "TAB", ""),
355 ("RET", "RET", ""),
356 ("SPACE", "SPACE", ""),
357 ("LINE_FEED", "LINE_FEED", ""),
358 ("BACK_SPACE", "BACK_SPACE", ""),
359 ("DEL", "DEL", ""),
360 ("SEMI_COLON", "SEMI_COLON", ""),
361 ("PERIOD", "PERIOD", ""),
362 ("COMMA", "COMMA", ""),
363 ("QUOTE", "QUOTE", ""),
364 ("ACCENT_GRAVE", "ACCENT_GRAVE", ""),
365 ("MINUS", "MINUS", ""),
366 ("SLASH", "SLASH", ""),
367 ("BACK_SLASH", "BACK_SLASH", ""),
368 ("EQUAL", "EQUAL", ""),
369 ("LEFT_BRACKET", "LEFT_BRACKET", ""),
370 ("RIGHT_BRACKET", "RIGHT_BRACKET", ""),
371 ("LEFT_ARROW", "LEFT_ARROW", ""),
372 ("DOWN_ARROW", "DOWN_ARROW", ""),
373 ("RIGHT_ARROW", "RIGHT_ARROW", ""),
374 ("UP_ARROW", "UP_ARROW", ""),
375 ("NUMPAD_1", "NUMPAD_1", ""),
376 ("NUMPAD_2", "NUMPAD_2", ""),
377 ("NUMPAD_3", "NUMPAD_3", ""),
378 ("NUMPAD_4", "NUMPAD_4", ""),
379 ("NUMPAD_5", "NUMPAD_5", ""),
380 ("NUMPAD_6", "NUMPAD_6", ""),
381 ("NUMPAD_7", "NUMPAD_7", ""),
382 ("NUMPAD_8", "NUMPAD_8", ""),
383 ("NUMPAD_9", "NUMPAD_9", ""),
384 ("NUMPAD_0", "NUMPAD_0", ""),
385 ("NUMPAD_PERIOD", "NUMPAD_PERIOD", ""),
386 ("NUMPAD_SLASH", "NUMPAD_SLASH", ""),
387 ("NUMPAD_ASTERIX", "NUMPAD_ASTERIX", ""),
388 ("NUMPAD_MINUS", "NUMPAD_MINUS", ""),
389 ("NUMPAD_ENTER", "NUMPAD_ENTER", ""),
390 ("NUMPAD_PLUS", "NUMPAD_PLUS", ""),
391 ("F1", "F1", ""),
392 ("F2", "F2", ""),
393 ("F3", "F3", ""),
394 ("F4", "F4", ""),
395 ("F5", "F5", ""),
396 ("F6", "F6", ""),
397 ("F7", "F7", ""),
398 ("F8", "F8", ""),
399 ("F9", "F9", ""),
400 ("F10", "F10", ""),
401 ("F11", "F11", ""),
402 ("F12", "F12", ""),
403 ("F13", "F13", ""),
404 ("F14", "F14", ""),
405 ("F15", "F15", ""),
406 ("F16", "F16", ""),
407 ("F17", "F17", ""),
408 ("F18", "F18", ""),
409 ("F19", "F19", ""),
410 ("PAUSE", "PAUSE", ""),
411 ("INSERT", "INSERT", ""),
412 ("HOME", "HOME", ""),
413 ("PAGE_UP", "PAGE_UP", ""),
414 ("PAGE_DOWN", "PAGE_DOWN", ""),
415 ("END", "END", ""),
416 ("MEDIA_PLAY", "MEDIA_PLAY", ""),
417 ("MEDIA_STOP", "MEDIA_STOP", ""),
418 ("MEDIA_FIRST", "MEDIA_FIRST", ""),
419 ("MEDIA_LAST", "MEDIA_LAST", ""),
420 ("TEXTINPUT", "TEXTINPUT", ""),
421 ("WINDOW_DEACTIVATE", "WINDOW_DEACTIVATE", ""),
422 ("TIMER", "TIMER", ""),
423 ("TIMER0", "TIMER0", ""),
424 ("TIMER1", "TIMER1", ""),
425 ("TIMER2", "TIMER2", ""),
426 ("TIMER_JOBS", "TIMER_JOBS", ""),
427 ("TIMER_AUTOSAVE", "TIMER_AUTOSAVE", ""),
428 ("TIMER_REPORT", "TIMER_REPORT", ""),
429 ("TIMERREGION", "TIMERREGION", ""),
430 ("NDOF_MOTION", "NDOF_MOTION", ""),
431 ("NDOF_BUTTON_MENU", "NDOF_BUTTON_MENU", ""),
432 ("NDOF_BUTTON_FIT", "NDOF_BUTTON_FIT", ""),
433 ("NDOF_BUTTON_TOP", "NDOF_BUTTON_TOP", ""),
434 ("NDOF_BUTTON_BOTTOM", "NDOF_BUTTON_BOTTOM", ""),
435 ("NDOF_BUTTON_LEFT", "NDOF_BUTTON_LEFT", ""),
436 ("NDOF_BUTTON_RIGHT", "NDOF_BUTTON_RIGHT", ""),
437 ("NDOF_BUTTON_FRONT", "NDOF_BUTTON_FRONT", ""),
438 ("NDOF_BUTTON_BACK", "NDOF_BUTTON_BACK", ""),
439 ("NDOF_BUTTON_ISO1", "NDOF_BUTTON_ISO1", ""),
440 ("NDOF_BUTTON_ISO2", "NDOF_BUTTON_ISO2", ""),
441 ("NDOF_BUTTON_ROLL_CW", "NDOF_BUTTON_ROLL_CW", ""),
442 ("NDOF_BUTTON_ROLL_CCW", "NDOF_BUTTON_ROLL_CCW", ""),
443 ("NDOF_BUTTON_SPIN_CW", "NDOF_BUTTON_SPIN_CW", ""),
444 ("NDOF_BUTTON_SPIN_CCW", "NDOF_BUTTON_SPIN_CCW", ""),
445 ("NDOF_BUTTON_TILT_CW", "NDOF_BUTTON_TILT_CW", ""),
446 ("NDOF_BUTTON_TILT_CCW", "NDOF_BUTTON_TILT_CCW", ""),
447 ("NDOF_BUTTON_ROTATE", "NDOF_BUTTON_ROTATE", ""),
448 ("NDOF_BUTTON_PANZOOM", "NDOF_BUTTON_PANZOOM", ""),
449 ("NDOF_BUTTON_DOMINANT", "NDOF_BUTTON_DOMINANT", ""),
450 ("NDOF_BUTTON_PLUS", "NDOF_BUTTON_PLUS", ""),
451 ("NDOF_BUTTON_MINUS", "NDOF_BUTTON_MINUS", ""),
452 ("NDOF_BUTTON_ESC", "NDOF_BUTTON_ESC", ""),
453 ("NDOF_BUTTON_ALT", "NDOF_BUTTON_ALT", ""),
454 ("NDOF_BUTTON_SHIFT", "NDOF_BUTTON_SHIFT", ""),
455 ("NDOF_BUTTON_CTRL", "NDOF_BUTTON_CTRL", ""),
456 ("NDOF_BUTTON_1", "NDOF_BUTTON_1", ""),
457 ("NDOF_BUTTON_2", "NDOF_BUTTON_2", ""),
458 ("NDOF_BUTTON_3", "NDOF_BUTTON_3", ""),
459 ("NDOF_BUTTON_4", "NDOF_BUTTON_4", ""),
460 ("NDOF_BUTTON_5", "NDOF_BUTTON_5", ""),
461 ("NDOF_BUTTON_6", "NDOF_BUTTON_6", ""),
462 ("NDOF_BUTTON_7", "NDOF_BUTTON_7", ""),
463 ("NDOF_BUTTON_8", "NDOF_BUTTON_8", ""),
464 ("NDOF_BUTTON_9", "NDOF_BUTTON_9", ""),
465 ("NDOF_BUTTON_10", "NDOF_BUTTON_10", ""),
466 ("NDOF_BUTTON_A", "NDOF_BUTTON_A", ""),
467 ("NDOF_BUTTON_B", "NDOF_BUTTON_B", ""),
468 ("NDOF_BUTTON_C", "NDOF_BUTTON_C", "")
470 name="Quick Type",
471 description="Enter key code in find text",
472 update=update_data
476 class IsKeyFreeRunExportKeys(Operator):
477 bl_idname = "iskeyfree.run_export_keys"
478 bl_label = "List all Shortcuts"
479 bl_description = ("List all existing shortcuts in a text block\n"
480 "The newly generated list will be made active in the Text Editor\n"
481 "To access the previous ones, select them from the Header dropdown")
483 def all_shortcuts_name(self, context):
484 new_name, def_name, ext = "", "All_Shortcuts", ".txt"
485 suffix = 1
486 try:
487 # first slap a simple linear count + 1 for numeric suffix, if it fails
488 # harvest for the rightmost numbers and append the max value
489 list_txt = []
490 data_txt = bpy.data.texts
491 list_txt = [txt.name for txt in data_txt if txt.name.startswith("All_Shortcuts")]
492 new_name = "{}_{}{}".format(def_name, len(list_txt) + 1, ext)
494 if new_name in list_txt:
495 from re import findall
496 test_num = [findall(r"\d+", words) for words in list_txt]
497 suffix += max([int(l[-1]) for l in test_num])
498 new_name = "{}_{}{}".format(def_name, suffix, ext)
499 return new_name
500 except:
501 return None
503 def execute(self, context):
504 wm = bpy.context.window_manager
505 from collections import defaultdict
506 mykeys = defaultdict(list)
507 file_name = self.all_shortcuts_name(context) or "All_Shortcut.txt"
508 start_note = "# Note: Some of the shortcuts entries don't have a name. Mostly Modal stuff\n"
509 col_width, col_shortcuts = 2, 2
511 for ctx_type, keyboardmap in wm.keyconfigs.user.keymaps.items():
512 for myitem in keyboardmap.keymap_items:
513 padding = len(myitem.name)
514 col_width = padding + 2 if padding > col_width else col_width
516 short_type = myitem.type if myitem.type else "UNKNOWN"
517 is_ctrl = " Ctrl" if myitem.ctrl is True else ""
518 is_alt = " Alt" if myitem.alt is True else ""
519 is_shift = " Shift" if myitem.shift is True else ""
520 is_oskey = " OsKey" if myitem.oskey is True else ""
521 short_cuts = "{}{}{}{}{}".format(short_type, is_ctrl, is_alt, is_shift, is_oskey)
523 t = (
524 myitem.name if myitem.name else "No Name",
525 short_cuts,
527 mykeys[ctx_type].append(t)
528 padding_s = len(short_cuts) + 2
529 col_shortcuts = padding_s if padding_s > col_shortcuts else col_shortcuts
531 max_line = col_shortcuts + col_width + 4
532 textblock = bpy.data.texts.new(file_name)
533 total = sum([len(mykeys[ctxs]) for ctxs in mykeys])
534 textblock.write('# %d Total Shortcuts\n\n' % total)
535 textblock.write(start_note)
537 for ctx in mykeys:
538 textblock.write("\n[%s]\nEntries: %s\n\n" % (ctx, len(mykeys[ctx])))
539 line_k = sorted(mykeys[ctx])
540 for keys in line_k:
541 add_ticks = "-" * (max_line - (len(keys[0]) + len(keys[1])))
542 entries = "{ticks} {entry}".format(ticks=add_ticks, entry=keys[1])
543 textblock.write("{name} {entry}\n".format(name=keys[0], entry=entries))
545 textblock.write("\n\n")
547 # try to set the created text block to active
548 if context.area.type in {"TEXT_EDITOR"}:
549 bpy.context.space_data.text = bpy.data.texts[file_name]
551 self.report({'INFO'}, "See %s textblock" % file_name)
553 return {"FINISHED"}
556 # -----------------------------------------------------
557 # Registration
558 # ------------------------------------------------------
559 classes = (
560 IskeyFreeProperties,
561 RunActionCheck,
562 UIControlPanel,
563 IsKeyFreeRunExportKeys,
567 def register():
568 for cls in classes:
569 bpy.utils.register_class(cls)
570 bpy.types.Scene.is_keyfree = PointerProperty(type=IskeyFreeProperties)
573 def unregister():
574 for cls in classes:
575 bpy.utils.unregister_class(cls)
576 del bpy.types.Scene.is_keyfree