1import datetime
2import time
3
4from .constants import MODIFIERS
5from ._iomediator import IoMediator
6from .key import Key
7from . import _iomediator
8
9
10class KeyGrabber:
11    """
12    Keygrabber used by the hotkey settings dialog to grab the key pressed
13    """
14
15    def __init__(self, parent):
16        self.targetParent = parent
17
18    def start(self):
19        # In QT version, sometimes the mouseclick event arrives before we finish initialising
20        # sleep slightly to prevent this
21        time.sleep(0.1)
22        IoMediator.listeners.append(self)
23        _iomediator.CURRENT_INTERFACE.grab_keyboard()
24
25    def handle_keypress(self, rawKey, modifiers, key, *args):
26        if rawKey not in MODIFIERS:
27            IoMediator.listeners.remove(self)
28            self.targetParent.set_key(rawKey, modifiers)
29            _iomediator.CURRENT_INTERFACE.ungrab_keyboard()
30
31    def handle_mouseclick(self, rootX, rootY, relX, relY, button, windowInfo):
32        IoMediator.listeners.remove(self)
33        _iomediator.CURRENT_INTERFACE.ungrab_keyboard()
34        self.targetParent.cancel_grab()
35
36
37class Recorder(KeyGrabber):
38    """
39    Recorder used by the record macro functionality
40    """
41
42    def __init__(self, parent):
43        KeyGrabber.__init__(self, parent)
44        self.insideKeys = False
45
46    def start(self, delay):
47        time.sleep(0.1)
48        IoMediator.listeners.append(self)
49        self.targetParent.start_record()
50        self.startTime = time.time()
51        self.delay = delay
52        self.delayFinished = False
53
54    def start_withgrab(self):
55        time.sleep(0.1)
56        IoMediator.listeners.append(self)
57        self.targetParent.start_record()
58        self.startTime = time.time()
59        self.delay = 0
60        self.delayFinished = True
61        _iomediator.CURRENT_INTERFACE.grab_keyboard()
62
63    def stop(self):
64        if self in IoMediator.listeners:
65            IoMediator.listeners.remove(self)
66            if self.insideKeys:
67                self.targetParent.end_key_sequence()
68            self.insideKeys = False
69
70    def stop_withgrab(self):
71        _iomediator.CURRENT_INTERFACE.ungrab_keyboard()
72        if self in IoMediator.listeners:
73            IoMediator.listeners.remove(self)
74            if self.insideKeys:
75                self.targetParent.end_key_sequence()
76            self.insideKeys = False
77
78    def set_record_keyboard(self, doIt):
79        self.recordKeyboard = doIt
80
81    def set_record_mouse(self, doIt):
82        self.recordMouse = doIt
83
84    def __delayPassed(self):
85        if not self.delayFinished:
86            now = time.time()
87            delta = datetime.datetime.utcfromtimestamp(now - self.startTime)
88            self.delayFinished = (delta.second > self.delay)
89
90        return self.delayFinished
91
92    def handle_keypress(self, rawKey, modifiers, key, *args):
93        if self.recordKeyboard and self.__delayPassed():
94            if not self.insideKeys:
95                self.insideKeys = True
96                self.targetParent.start_key_sequence()
97
98            modifierCount = len(modifiers)
99
100            if modifierCount > 1 or (modifierCount == 1 and Key.SHIFT not in modifiers) or \
101                    (Key.SHIFT in modifiers and len(rawKey) > 1):
102                self.targetParent.append_hotkey(rawKey, modifiers)
103
104            elif key not in MODIFIERS:
105                self.targetParent.append_key(key)
106
107    def handle_mouseclick(self, rootX, rootY, relX, relY, button, windowInfo):
108        if self.recordMouse and self.__delayPassed():
109            if self.insideKeys:
110                self.insideKeys = False
111                self.targetParent.end_key_sequence()
112
113            self.targetParent.append_mouseclick(relX, relY, button, windowInfo[0])
114