Putting all the code from the current master branch of TWBlue

This commit is contained in:
2014-10-27 16:29:04 -06:00
parent 58c82e5486
commit 1af4a8b291
284 changed files with 58760 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
from main import KeyboardHandler, KeyboardHandlerError
#from wx_handler import WXKeyboardHandler
__all__ = ["KeyboardHandler", "KeyboardHandlerError", "WXKeyboardHandler", "WXPanelKeyboardHandler"]

View File

@@ -0,0 +1,7 @@
import platform
if platform.system() == 'Linux':
from linux import LinuxKeyboardHandler as GlobalKeyboardHandler
elif platform.system() == 'Windows':
from wx_handler import WXKeyboardHandler as GlobalKeyboardHandler
elif platform.system() == 'Darwin':
from osx import OSXKeyboardHandler as GlobalKeyboardHandler

View File

@@ -0,0 +1,58 @@
from main import KeyboardHandler
import threading
import thread
import pyatspi
def parse(s):
"""parse a string like control+f into (modifier, key).
Unknown modifiers will return ValueError."""
m = 0
lst = s.split('+')
if not len(lst): return (0, s)
#Are these right?
d = {
"shift": 1<<pyatspi.MODIFIER_SHIFT,
"control": 1<<pyatspi.MODIFIER_CONTROL,
"alt": 1<<pyatspi.MODIFIER_ALT,
"win":1<<pyatspi.MODIFIER_META3,
}
for item in lst:
if item in d:
m|=d[item]
lst.remove(item)
#end if
if len(lst) > 1: #more than one key, parse error
raise ValueError, 'unknown modifier %s' % lst[0]
return (m, lst[0].lower())
class AtspiThread(threading.Thread):
def run(self):
pyatspi.Registry.registerKeystrokeListener(handler, kind=(pyatspi.KEY_PRESSED_EVENT,),
mask=pyatspi.allModifiers())
pyatspi.Registry.start()
#the keys we registered
keys = {}
def handler(e):
m,k = e.modifiers,e.event_string.lower()
#not sure why we can't catch control+f. Try to fix it.
if (not e.is_text) and e.id >= 97 <= 126:
k = chr(e.id)
if (m,k) not in keys: return False
thread.start_new(keys[(m,k)], ())
return True #don't pass it on
class LinuxKeyboardHandler(KeyboardHandler):
def __init__(self, *args, **kwargs):
KeyboardHandler.__init__(self, *args, **kwargs)
t = AtspiThread()
t.start()
def register_key(self, key, function):
"""key will be a string, such as control+shift+f.
We need to convert that, using parse_key,
into modifier and key to put into our dictionary."""
#register key so we know if we have it on event receive.
t = parse(key)
keys[t] = function
#if we got this far, the key is valid.
KeyboardHandler.register_key(self, key, function)
def unregister_key (self, key, function):
KeyboardHandler.unregister_key(self, key, function)
del keys[parse(key)]

View File

@@ -0,0 +1,88 @@
import platform
import time
class KeyboardHandlerError (Exception): pass
class KeyboardHandler(object):
def __init__(self, repeat_rate=0.0, *args, **kwargs):
self.repeat_rate = repeat_rate #How long between accepting the same keystroke?
self._last_key = None
self._last_keypress_time = 0
super(KeyboardHandler, self).__init__(*args, **kwargs)
self.active_keys = {}
if not hasattr(self, 'replacement_mods'):
self.replacement_mods = {}
if not hasattr(self, 'replacement_keys'):
self.replacement_keys = {}
def register_key (self, key, function):
if key in self.active_keys:
raise KeyboardHandlerError, "Key %s is already registered to a function" % key
if not callable(function):
raise TypeError, "Must provide a callable to be invoked upon keypress"
self.active_keys[key] = function
def unregister_key (self, key, function):
try:
if self.active_keys[key] != function:
raise KeyboardHandlerError, "key %s is not registered to that function" % key
except KeyError:
raise KeyboardHandlerError, "Key %s not currently registered"
del(self.active_keys[key])
def unregister_all_keys(self):
for key in list(self.active_keys):
self.unregister_key(key, self.active_keys[key])
def handle_key (self, key):
if self.repeat_rate and key == self._last_key and time.time() - self._last_keypress_time < self.repeat_rate:
return
try:
function = self.active_keys[key]
except KeyError:
return
self._last_key = key
self._last_keypress_time = time.time()
return function()
def register_keys(self, keys):
"""Given a mapping of keystrokes to functions, registers all keystrokes"""
for k in keys:
self.register_key(k, keys[k])
def unregister_keys(self, keys):
"""Given a mapping of keys to their functions, unregisters all provided keys."""
for k in keys:
self.unregister_key(k, keys[k])
def standardize_key(self, key):
"""Takes a keystroke and places it in a standard case and order in a list."""
working = key.split('+')
working = [i.lower() for i in working]
answer = []
if "control" in working:
answer.append("control")
if "win" in working:
answer.append("win")
if "alt" in working:
answer.append("alt")
if "shift" in working:
answer.append("shift")
if working[-1] not in answer:
answer.append(working[-1])
return answer
def standardize_keymap(self, keymap):
"""Given a keymap, returns the keymap standardized."""
full = {}
for i in keymap:
answer = ""
new = self.standardize_key(keymap[i])
for (c, j) in enumerate(new):
if c < len(new)-1:
answer = "%s%s+" % (answer, j)
else:
answer = "%s%s" % (answer, j)
full[i] = answer
return full

View File

@@ -0,0 +1,56 @@
from AppKit import *
from PyObjCTools import AppHelper
from Carbon.CarbonEvt import RegisterEventHotKey, GetApplicationEventTarget
from Carbon.Events import cmdKey, controlKey
import struct
from threading import Thread
from main import KeyboardHandler
kEventHotKeyPressedSubtype = 6
kEventHotKeyReleasedSubtype = 9
class OSXKeyboardHandler(KeyboardHandler):
def __init__(self):
super(OSXKeyboardHandler, self).__init__()
self.replacement_keys = dict()
self.app = KeyboardCapturingNSApplication.alloc().init()
self._event_thread = Thread(target=AppHelper.runEventLoop)
self._event_thread.start()
def register_key (self, key, function):
super(OSXKeyboardHandler, self).register_key(key, function)
k, m = self.parse_key(key)
key_id = RegisterEventHotKey(k, m, (0, 0), GetApplicationEventTarget(), 0)
self.key_ids[key] = key_id
def unregister_key (self, key, function):
super(OSXKeyboardHandler, self).unregister_key(key, function)
key_id = self.key_ids[key]
raise NotImplementedError
def parse_key (self, key):
key=key.split("+")
#replacements
#Modifier keys:
for index, item in enumerate(key[0:-1]):
if self.replacement_mods.has_key(item):
key[index] = self.replacement_mods[item]
if self.replacement_keys.has_key(key[-1]):
key[-1] = self.replacement_keys[key[-1]]
elif len(key[-1])==1:
key[-1] = ord(str(key[-1]))-36
mods = 0
for i in key[:-1]:
mods = mods|i
return [key[-1], mods]
class KeyboardCapturingNSApplication(NSApplication):
def sendEvent_(self, theEvent):
if theEvent.type() == NSSystemDefined and theEvent.subtype() == kEventHotKeyPressedSubtype:
self.activateIgnoringOtherApps_(True)
NSRunAlertPanel(u'Hot Key Pressed', u'Hot Key Pressed', None, None, None)
super(NSApplication, self).sendEvent_(theEvent)

View File

@@ -0,0 +1,40 @@
import win32api
import win32con
from main import KeyboardHandler
class WindowsKeyboardHandler(KeyboardHandler):
def __init__ (self, *args, **kwargs):
super(WindowsKeyboardHandler, self).__init__(*args, **kwargs)
#Setup the replacement dictionaries.
for i in dir(win32con):
if i.startswith("VK_"):
key = i[3:].lower()
self.replacement_keys[key] = getattr(win32con, i)
elif i.startswith("MOD_"):
key = i[4:].lower()
self.replacement_mods[key] = getattr(win32con, i)
self.replacement_keys .update(dict(pageup=win32con.VK_PRIOR, pagedown=win32con.VK_NEXT))
def parse_key (self, keystroke, separator="+"):
keystroke = str(keystroke) #We don't want unicode
keystroke = [self.keycode_from_key(i) for i in keystroke.split(separator)]
mods = 0
for i in keystroke[:-1]:
mods = mods | i #or everything together
return (mods, keystroke[-1])
def keycode_from_key(self, key):
if key in self.replacement_mods:
return self.replacement_mods[key]
if key in self.replacement_keys:
return self.replacement_keys[key]
if len(key) == 1:
return win32api.VkKeyScanEx(key, win32api.GetKeyboardLayout())
def is_key_pressed(self, key):
"""Returns if the given key was pressed. Requires an active message loop or will simply give if the key was pressed recently."""
key = self.keycode_from_key(key)
return win32api.GetAsyncKeyState(key)

View File

@@ -0,0 +1,119 @@
import functools
import wx
import platform
from main import KeyboardHandler
__all__ = ['WXKeyboardHandler', 'WXControlKeyboardHandler']
def call_after(func):
def wrapper(*args, **kwargs):
wx.CallAfter(func, *args, **kwargs)
functools.update_wrapper(wrapper, func)
return wrapper
class BaseWXKeyboardHandler(KeyboardHandler):
def __init__(self, *args, **kwargs):
super(BaseWXKeyboardHandler, self).__init__(*args, **kwargs)
#Setup the replacement dictionaries.
for i in dir(wx):
if i.startswith('WXK_'):
key = i[4:].lower()
self.replacement_keys[key] = getattr(wx, i)
elif i.startswith('MOD_'):
key = i[4:].lower()
self.replacement_mods[key] = getattr(wx, i)
def parse_key (self, keystroke, separator="+"):
keystroke = [self.keycode_from_key(i) for i in keystroke.split(separator)]
mods = 0
for i in keystroke[:-1]:
mods = mods | i #or everything together
return (mods, keystroke[-1])
def keycode_from_key(self, key):
if key in self.replacement_mods:
result = self.replacement_mods[key]
elif key in self.replacement_keys:
result = self.replacement_keys[key]
if result >= 277:
result -= 277
elif len(key) == 1:
result = ord(key.upper())
print "result: ", result
return result
#try:
if platform.system() == "Windows":
from windows import WindowsKeyboardHandler as keyboard_handler
elif platform.system() == "Linux":
from linux import LinuxKeyboardHandler as keyboard_handler
elif platform.system() == "Darwin":
from osx import OSXKeyboardHandler as keyboard_handler
class WXKeyboardHandler(keyboard_handler):
def __init__ (self, parent, *args, **kwargs):
super(WXKeyboardHandler, self).__init__(*args, **kwargs)
self.parent = parent
self.key_ids = {}
@call_after
def register_key(self, key, function):
super(WXKeyboardHandler, self).register_key(key, function)
key_id = wx.NewId()
parsed = self.parse_key(key)
self.parent.RegisterHotKey(key_id, *parsed)
self.parent.Bind(wx.EVT_HOTKEY, lambda evt: self.process_key(evt, key_id), id=key_id)
self.key_ids[key] = key_id
@call_after
def unregister_key (self, key, function):
super(WXKeyboardHandler, self).unregister_key(key, function)
if key not in self.key_ids:
return #there's nothing we can do.
key_id = self.key_ids[key]
self.parent.UnregisterHotKey(key_id)
self.parent.Unbind( wx.EVT_HOTKEY, id=key_id)
self.key_ids.pop(key)
def process_key (self, evt, id):
evt.Skip()
key_ids = self.key_ids.keys()
for i in key_ids:
if self.key_ids.get(i) == id:
self.handle_key(i)
class WXControlKeyboardHandler(wx.StaticText, KeyboardHandler):
def __init__(self, parent=None, *a, **k):
wx.StaticText.__init__(self, parent=parent)
KeyboardHandler.__init__(self, *a, **k)
self.wx_replacements = {}
for i in [d for d in dir(wx) if d.startswith('WXK_')]:
self.wx_replacements[getattr(wx, i)] = i[4:].lower()
self.Bind(wx.EVT_KEY_DOWN, self.process_key, self)
self.SetFocus()
def process_key(self, evt):
keycode = evt.GetKeyCode()
keyname = self.wx_replacements.get(keycode, None)
modifiers = ""
replacements = ( (evt.ControlDown(), 'control+'),
(evt.AltDown(), 'alt+'),
(evt.ShiftDown(), 'shift+'),
(evt.MetaDown(), 'win+')
)
for mod, ch in (replacements):
if mod:
modifiers += ch
if keyname is None:
if 27 < keycode < 256:
keyname = chr(keycode).lower()
else:
keyname = "(%s)unknown" % keycode
key = modifiers + keyname
self.handle_key(key)