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