Example #1
0
 def test_save(self):
     down = ActionDown([KC_A, KC_B])
     self.assertEqual(down.save(), ["down", "KC_A", "KC_B"])
     tap = ActionTap([KC_B, KC_A])
     self.assertEqual(tap.save(), ["tap", "KC_B", "KC_A"])
     text = ActionText("Hello world")
     self.assertEqual(text.save(), ["text", "Hello world"])
     delay = ActionDelay(123)
     self.assertEqual(delay.save(), ["delay", 123])
Example #2
0
 def test_deserialize_v1(self):
     kb = DummyKeyboard(None)
     kb.vial_protocol = 1
     macro = kb.macro_deserialize(
         b"Hello\x01\x04\x01\x05\x01\x06World\x02\x06\x02\x05\x02\x04")
     self.assertEqual(macro, [
         ActionText("Hello"),
         ActionTap([KC_A, KC_B, KC_C]),
         ActionText("World"),
         ActionDown([KC_C, KC_B, KC_A])
     ])
Example #3
0
 def test_restore(self):
     down = ActionDown()
     down.restore(["down", "KC_A", "KC_B"])
     self.assertEqual(down, ActionDown([KC_A, KC_B]))
     tap = ActionTap()
     tap.restore(["tap", "KC_B", "KC_A"])
     self.assertEqual(tap, ActionTap([KC_B, KC_A]))
     text = ActionText()
     text.restore(["text", "Hello world"])
     self.assertEqual(text, ActionText("Hello world"))
     delay = ActionDelay()
     delay.restore(["delay", 123])
     self.assertEqual(delay, ActionDelay(123))
Example #4
0
    def on_stop(self):
        for x in range(self.keyboard.macro_count):
            self.tabs.tabBar().setTabEnabled(x, True)

        if not self.recording_append:
            self.recording_tab.clear()

        self.recording_tab.post_record()

        self.keystrokes = macro_optimize(self.keystrokes)
        actions = []
        for k in self.keystrokes:
            if isinstance(k, KeyString):
                actions.append(ActionText(k.string))
            else:
                cls = {
                    KeyDown: ActionDown,
                    KeyUp: ActionUp,
                    KeyTap: ActionTap
                }[type(k)]
                actions.append(cls([k.keycode]))

        # merge: i.e. replace multiple instances of KeyDown with a single multi-key ActionDown, etc
        actions = self.keyboard.macro_deserialize(
            self.keyboard.macro_serialize(actions))
        self.recording_tab.clear()
        for act in actions:
            self.recording_tab.add_action(ui_action[type(act)](
                self.recording_tab.container, act))
Example #5
0
def macro_deserialize_v2(data):
    """
    Deserialize a single macro, protocol version 2
    """

    out = []
    sequence = []
    data = bytearray(data)
    while len(data) > 0:
        if data[0] == SS_QMK_PREFIX:
            if data[1] in [SS_TAP_CODE, SS_DOWN_CODE, SS_UP_CODE]:
                # append to previous *_CODE if it's the same type, otherwise create a new entry
                if len(sequence) > 0 and isinstance(
                        sequence[-1], list) and sequence[-1][0] == data[1]:
                    sequence[-1][1].append(data[2])
                else:
                    sequence.append([data[1], [data[2]]])

                for x in range(3):
                    data.pop(0)
            elif data[1] == SS_DELAY_CODE:
                # decode the delay
                delay = (data[2] - 1) + (data[3] - 1) * 255
                sequence.append([SS_DELAY_CODE, delay])

                for x in range(4):
                    data.pop(0)
        else:
            # append to previous string if it is a string, otherwise create a new entry
            ch = chr(data[0])
            if len(sequence) > 0 and isinstance(sequence[-1], str):
                sequence[-1] += ch
            else:
                sequence.append(ch)
            data.pop(0)
    for s in sequence:
        if isinstance(s, str):
            out.append(ActionText(s))
        else:
            args = None
            if s[0] in [SS_TAP_CODE, SS_DOWN_CODE, SS_UP_CODE]:
                # map integer values to qmk keycodes
                args = []
                for code in s[1]:
                    keycode = Keycode.find_outer_keycode(code)
                    if keycode:
                        args.append(keycode)
            elif s[0] == SS_DELAY_CODE:
                args = s[1]

            if args is not None:
                cls = {
                    SS_TAP_CODE: ActionTap,
                    SS_DOWN_CODE: ActionDown,
                    SS_UP_CODE: ActionUp,
                    SS_DELAY_CODE: ActionDelay
                }[s[0]]
                out.append(cls(args))
    return out
Example #6
0
 def test_serialize_v2(self):
     kb = DummyKeyboard(None)
     kb.vial_protocol = 2
     data = kb.macro_serialize([
         ActionText("Hello"),
         ActionTap([KC_A, KC_B, KC_C]),
         ActionText("World"),
         ActionDown([KC_C, KC_B, KC_A]),
         ActionDelay(1000)
     ])
     self.assertEqual(
         data,
         b"Hello\x01\x01\x04\x01\x01\x05\x01\x01\x06World\x01\x02\x06\x01\x02\x05\x01\x02\x04"
         b"\x01\x04\xEC\x04")
     data = kb.macro_serialize([
         ActionText("Hello"),
         ActionTap([KC_A, KC_B, KC_C]),
         ActionText("World"),
         ActionDown([KC_C, KC_B, KC_A]),
         ActionDelay(0)
     ])
     self.assertEqual(
         data,
         b"Hello\x01\x01\x04\x01\x01\x05\x01\x01\x06World\x01\x02\x06\x01\x02\x05\x01\x02\x04"
         b"\x01\x04\x01\x01")
     data = kb.macro_serialize([
         ActionText("Hello"),
         ActionTap([KC_A, KC_B, KC_C]),
         ActionText("World"),
         ActionDown([KC_C, KC_B, KC_A]),
         ActionDelay(1)
     ])
     self.assertEqual(
         data,
         b"Hello\x01\x01\x04\x01\x01\x05\x01\x01\x06World\x01\x02\x06\x01\x02\x05\x01\x02\x04"
         b"\x01\x04\x02\x01")
     data = kb.macro_serialize([
         ActionText("Hello"),
         ActionTap([KC_A, KC_B, KC_C]),
         ActionText("World"),
         ActionDown([KC_C, KC_B, KC_A]),
         ActionDelay(256)
     ])
     self.assertEqual(
         data,
         b"Hello\x01\x01\x04\x01\x01\x05\x01\x01\x06World\x01\x02\x06\x01\x02\x05\x01\x02\x04"
         b"\x01\x04\x02\x02")
Example #7
0
def macro_deserialize_v1(data):
    """
    Deserialize a single macro, protocol version 1
    """

    out = []
    sequence = []
    data = bytearray(data)
    while len(data) > 0:
        if data[0] in [SS_TAP_CODE, SS_DOWN_CODE, SS_UP_CODE]:
            if len(data) < 2:
                break

            # append to previous *_CODE if it's the same type, otherwise create a new entry
            if len(sequence) > 0 and isinstance(
                    sequence[-1], list) and sequence[-1][0] == data[0]:
                sequence[-1][1].append(data[1])
            else:
                sequence.append([data[0], [data[1]]])

            data.pop(0)
            data.pop(0)
        else:
            # append to previous string if it is a string, otherwise create a new entry
            ch = chr(data[0])
            if len(sequence) > 0 and isinstance(sequence[-1], str):
                sequence[-1] += ch
            else:
                sequence.append(ch)
            data.pop(0)
    for s in sequence:
        if isinstance(s, str):
            out.append(ActionText(s))
        else:
            # map integer values to qmk keycodes
            keycodes = []
            for code in s[1]:
                keycode = Keycode.find_outer_keycode(code)
                if keycode:
                    keycodes.append(keycode)
            cls = {
                SS_TAP_CODE: ActionTap,
                SS_DOWN_CODE: ActionDown,
                SS_UP_CODE: ActionUp
            }[s[0]]
            out.append(cls(keycodes))
    return out
Example #8
0
    def deserialize(self, data):
        self.clear()

        sequence = []
        data = bytearray(data)
        while len(data) > 0:
            if data[0] in [SS_TAP_CODE, SS_DOWN_CODE, SS_UP_CODE]:
                # append to previous *_CODE if it's the same type, otherwise create a new entry
                if len(sequence) > 0 and isinstance(
                        sequence[-1], list) and sequence[-1][0] == data[0]:
                    sequence[-1][1].append(data[1])
                else:
                    sequence.append([data[0], [data[1]]])

                data.pop(0)
                data.pop(0)
            else:
                # append to previous string if it is a string, otherwise create a new entry
                ch = chr(data[0])
                if len(sequence) > 0 and isinstance(sequence[-1], str):
                    sequence[-1] += ch
                else:
                    sequence.append(ch)
                data.pop(0)
        for s in sequence:
            if isinstance(s, str):
                self.add_action(ActionText(self.container, s))
            else:
                # map integer values to qmk keycodes
                keycodes = []
                for code in s[1]:
                    keycode = find_keycode(code)
                    if keycode:
                        keycodes.append(keycode)
                cls = {
                    SS_TAP_CODE: ActionTap,
                    SS_DOWN_CODE: ActionDown,
                    SS_UP_CODE: ActionUp
                }[s[0]]
                self.add_action(cls(self.container, keycodes))
Example #9
0
 def on_add(self):
     self.add_action(ActionText(self.container))