Esempio n. 1
0
 def get_option_info():
     bool_converter = lambda s: s == 'True'
     keymap_converter = lambda s: Keymap.from_string(s)
     return {
         'arpeggiate': (False, bool_converter),
         'keymap': (Keymap.default(), keymap_converter),
     }
Esempio n. 2
0
 def get_system_keymap(self, machine_type=None):
     if machine_type is None:
         machine_type = self.get_machine_type()
     try:
         machine_class = machine_registry.get(machine_type)
     except:
         log.error("invalid machine type: %s", machine_type, exc_info=True)
         return None
     section = SYSTEM_CONFIG_SECTION % DEFAULT_SYSTEM
     option = SYSTEM_KEYMAP_OPTION % machine_type
     mappings = self._get(section, option, None)
     if mappings is None:
         mappings = system.KEYMAPS.get(machine_type)
     else:
         try:
             mappings = dict(json.loads(mappings))
         except ValueError as e:
             log.error("invalid machine keymap, resetting to default",
                       exc_info=True)
             mappings = system.KEYMAPS.get(machine_type)
             self.set_system_keymap(mappings, machine_type)
     keymap = Keymap(machine_class.get_keys(),
                     system.KEYS + machine_class.get_actions())
     keymap.set_mappings(mappings)
     return keymap
Esempio n. 3
0
def machine(request, capture):
    machine = Keyboard({'arpeggiate': request.param})
    keymap = Keymap(Keyboard.KEYS_LAYOUT.split(),
                    system.KEYS + Keyboard.ACTIONS)
    keymap.set_mappings(system.KEYMAPS['Keyboard'])
    machine.set_keymap(keymap)
    return machine
Esempio n. 4
0
 def get_option_info():
     bool_converter = lambda s: s == 'True'
     keymap_converter = lambda s: Keymap.from_string(s)
     return {
         'arpeggiate': (False, bool_converter),
         'keymap':     (Keymap.default(), keymap_converter),
     }
Esempio n. 5
0
def machine(request, capture):
    machine = Keyboard({'arpeggiate': request.param})
    keymap = Keymap(Keyboard.KEYS_LAYOUT.split(),
                    system.KEYS + Keyboard.ACTIONS)
    keymap.set_mappings(system.KEYMAPS['Keyboard'])
    machine.set_keymap(keymap)
    return machine
Esempio n. 6
0
 def __init__(self):
     # Setup default keymap with no translation of keys.
     keys = self.get_keys()
     self.keymap = Keymap(keys, keys)
     self.keymap.set_mappings(zip(keys, keys))
     self.stroke_subscribers = []
     self.state_subscribers = []
     self.state = STATE_STOPPED
 def __init__(self, _):
   super(TinyMod4Machine, self).__init__()
   keys = self.get_keys()
   self.keymap = Keymap(keys, keys)
   self.keymap.set_mappings(zip(keys, keys))
   self._pressed = False
   self._stack = ForthStack(8, 7)
   self._modeSelectPin = 12
Esempio n. 8
0
def test_engine(engine):
    # Config load.
    assert engine.load_config()
    assert engine.events == []
    # Startup.
    engine.start()
    assert engine.events == [
        ('machine_state_changed', ('Fake', 'initializing'), {}),
        ('machine_state_changed', ('Fake', 'connected'), {}),
        ('config_changed', (engine.config, ), {}),
    ]
    assert FakeMachine.instance is not None
    assert not FakeMachine.instance.is_suppressed
    # Output enabled.
    engine.events.clear()
    engine.output = True
    assert engine.events == [
        ('output_changed', (True, ), {}),
    ]
    assert FakeMachine.instance.is_suppressed
    # Machine reconnection.
    engine.events.clear()
    engine.reset_machine()
    assert engine.events == [
        ('machine_state_changed', ('Fake', 'stopped'), {}),
        ('machine_state_changed', ('Fake', 'initializing'), {}),
        ('machine_state_changed', ('Fake', 'connected'), {}),
    ]
    assert FakeMachine.instance is not None
    assert FakeMachine.instance.is_suppressed
    # No machine reset on keymap change.
    engine.events.clear()
    new_keymap = Keymap(system.KEYS, system.KEYS)
    new_keymap.set_mappings(zip(system.KEYS, reversed(system.KEYS)))
    config_update = {'system_keymap': new_keymap}
    assert FakeMachine.instance.keymap != new_keymap
    engine.config = config_update
    assert engine.events == [
        ('config_changed', (config_update, ), {}),
    ]
    assert FakeMachine.instance.keymap == new_keymap
    # Output disabled
    engine.events.clear()
    engine.output = False
    assert engine.events == [
        ('output_changed', (False, ), {}),
    ]
    assert not FakeMachine.instance.is_suppressed
    # Stopped.
    engine.events.clear()
    engine.quit(42)
    assert engine.join() == 42
    assert engine.events == [
        ('machine_state_changed', ('Fake', 'stopped'), {}),
        ('quit', (), {}),
    ]
    assert FakeMachine.instance is None
Esempio n. 9
0
 def build_keymap(config, key, mappings=None):
     system = registry.get_plugin('system', key[1]).obj
     machine_class = registry.get_plugin('machine', key[2]).obj
     keymap = Keymap(machine_class.get_keys(), system.KEYS + machine_class.get_actions())
     if mappings is None:
         mappings = system.KEYMAPS.get(key[2])
     if mappings is None:
         if machine_class.KEYMAP_MACHINE_TYPE is not None:
             # Try fallback.
             return build_keymap(config, (key[0], key[1], machine_class.KEYMAP_MACHINE_TYPE))
         # No fallback...
         mappings = {}
     keymap.set_mappings(mappings)
     return keymap
Esempio n. 10
0
 def build_keymap(config, key, mappings=None):
     system = registry.get_plugin('system', key[1]).obj
     machine_class = registry.get_plugin('machine', key[2]).obj
     keymap = Keymap(machine_class.get_keys(), system.KEYS + machine_class.get_actions())
     if mappings is None:
         mappings = system.KEYMAPS.get(key[2])
     if mappings is None:
         if machine_class.KEYMAP_MACHINE_TYPE is not None:
             # Try fallback.
             return build_keymap(config, (key[0], key[1], machine_class.KEYMAP_MACHINE_TYPE))
         # No fallback...
         mappings = {}
     keymap.set_mappings(mappings)
     return keymap
Esempio n. 11
0
    def __init__(self, options, parent, config):
        self.config = config
        self.options = options

        pos = (config.get_keyboard_config_frame_x(),
               config.get_keyboard_config_frame_y())
        wx.Dialog.__init__(self, parent, title=DIALOG_TITLE, pos=pos)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer_flags = wx.SizerFlags().Border(wx.ALL, UI_BORDER).Align(
            wx.ALIGN_CENTER_HORIZONTAL)

        instructions = wx.StaticText(self, label=ARPEGGIATE_INSTRUCTIONS)
        sizer.AddF(instructions, sizer_flags.Align(wx.LEFT))
        self.arpeggiate_option = wx.CheckBox(self, label=ARPEGGIATE_LABEL)
        self.arpeggiate_option.SetValue(options.arpeggiate)
        sizer.AddF(self.arpeggiate_option, sizer_flags)

        # editable list for keymap bindings
        self.keymap = Keymap(KeyboardMachine.KEYS_LAYOUT.split(),
                             KeyboardMachine.ACTIONS)
        mappings = config.get_system_keymap('Keyboard')
        if mappings is not None:
            self.keymap.set_mappings(mappings)
        self.keymap_widget = EditKeymapWidget(self)
        self.keymap_widget.set_mappings(self.keymap.get_mappings())
        sizer.AddF(self.keymap_widget, sizer_flags.Expand())

        ok_button = wx.Button(self, id=wx.ID_OK)
        ok_button.SetDefault()
        cancel_button = wx.Button(self, id=wx.ID_CANCEL, label='Cancel')
        reset_button = wx.Button(self,
                                 id=wx.ID_RESET,
                                 label='Reset to default')

        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_sizer.AddF(ok_button, sizer_flags)
        button_sizer.AddF(cancel_button, sizer_flags)
        button_sizer.AddF(reset_button, sizer_flags)
        sizer.AddF(button_sizer, sizer_flags)

        self.SetSizerAndFit(sizer)
        self.SetRect(AdjustRectToScreen(self.GetRect()))

        self.Bind(wx.EVT_MOVE, self.on_move)
        ok_button.Bind(wx.EVT_BUTTON, lambda e: self.EndModal(wx.ID_OK))
        cancel_button.Bind(wx.EVT_BUTTON,
                           lambda e: self.EndModal(wx.ID_CANCEL))
        reset_button.Bind(wx.EVT_BUTTON, self.on_reset)
Esempio n. 12
0
 def __init__(self):
     # Setup default keymap with no translation of keys.
     keys = self.get_keys()
     self.keymap = Keymap(keys, keys)
     self.keymap.set_mappings(zip(keys, keys))
     self.stroke_subscribers = []
     self.state_subscribers = []
     self.state = STATE_STOPPED
Esempio n. 13
0
 def get_system_keymap(self, machine_type=None, system_name=None):
     if machine_type is None:
         machine_type = self.get_machine_type()
     try:
         machine_class = registry.get_plugin('machine',
                                             machine_type).resolve()
     except:
         log.error("invalid machine type: %s", machine_type, exc_info=True)
         return None
     if system_name is None:
         system_name = self.get_system_name()
     try:
         system = registry.get_plugin('system', system_name).resolve()
     except:
         log.error("invalid system name: %s", system_name, exc_info=True)
         return None
     section = SYSTEM_CONFIG_SECTION % system_name
     option = SYSTEM_KEYMAP_OPTION % machine_type
     mappings = self._get(section, option, None)
     if mappings is None:
         # No user mappings, use system default.
         mappings = system.KEYMAPS.get(machine_type)
     else:
         try:
             mappings = dict(json.loads(mappings))
         except ValueError as e:
             log.error("invalid machine keymap, resetting to default",
                       exc_info=True)
             self.set_system_keymap(None, machine_type)
             mappings = system.KEYMAPS.get(machine_type)
     if mappings is None:
         if machine_class.KEYMAP_MACHINE_TYPE is not None:
             # Try fallback.
             return self.get_system_keymap(
                 machine_type=machine_class.KEYMAP_MACHINE_TYPE,
                 system_name=system_name)
         # No fallback...
         mappings = {}
     keymap = Keymap(machine_class.get_keys(),
                     system.KEYS + machine_class.get_actions())
     keymap.set_mappings(mappings)
     return keymap
Esempio n. 14
0
 def get_system_keymap(self, machine_type=None, system_name=None):
     if machine_type is None:
         machine_type = self.get_machine_type()
     try:
         machine_class = registry.get_plugin('machine', machine_type).obj
     except:
         log.error("invalid machine type: %s", machine_type, exc_info=True)
         return None
     if system_name is None:
         system_name = self.get_system_name()
     try:
         system = registry.get_plugin('system', system_name).obj
     except:
         log.error("invalid system name: %s", system_name, exc_info=True)
         return None
     section = SYSTEM_CONFIG_SECTION % system_name
     option = SYSTEM_KEYMAP_OPTION % machine_type
     mappings = self._get(section, option, None)
     if mappings is None:
         # No user mappings, use system default.
         mappings = system.KEYMAPS.get(machine_type)
     else:
         try:
             mappings = dict(json.loads(mappings))
         except ValueError:
             log.error("invalid machine keymap, resetting to default",
                       exc_info=True)
             self.set_system_keymap(None, machine_type)
             mappings = system.KEYMAPS.get(machine_type)
     if mappings is None:
         if machine_class.KEYMAP_MACHINE_TYPE is not None:
             # Try fallback.
             return self.get_system_keymap(
                 machine_type=machine_class.KEYMAP_MACHINE_TYPE,
                 system_name=system_name
             )
         # No fallback...
         mappings = {}
     keymap = Keymap(machine_class.get_keys(), system.KEYS + machine_class.get_actions())
     keymap.set_mappings(mappings)
     return keymap
Esempio n. 15
0
 def get_system_keymap(self, machine_type=None):
     if machine_type is None:
         machine_type = self.get_machine_type()
     try:
         machine_class = machine_registry.get(machine_type)
     except:
         log.error("invalid machine type: %s", machine_type, exc_info=True)
         return None
     section = SYSTEM_CONFIG_SECTION % DEFAULT_SYSTEM
     option = SYSTEM_KEYMAP_OPTION % machine_type
     mappings = self._get(section, option, None)
     if mappings is None:
         mappings = system.KEYMAPS.get(machine_type)
     else:
         try:
             mappings = dict(json.loads(mappings))
         except ValueError as e:
             log.error("invalid machine keymap, resetting to default",
                       exc_info=True)
             mappings = system.KEYMAPS.get(machine_type)
             self.set_system_keymap(mappings, machine_type)
     keymap = Keymap(machine_class.get_keys(), system.KEYS + machine_class.get_actions())
     keymap.set_mappings(mappings)
     return keymap
Esempio n. 16
0
    def __init__(self, options, parent, config):
        self.config = config
        self.options = options
        
        pos = (config.get_keyboard_config_frame_x(), 
               config.get_keyboard_config_frame_y())
        wx.Dialog.__init__(self, parent, title=DIALOG_TITLE, pos=pos)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer_flags = wx.SizerFlags().Border(wx.ALL, UI_BORDER).Align(wx.ALIGN_CENTER_HORIZONTAL)

        instructions = wx.StaticText(self, label=ARPEGGIATE_INSTRUCTIONS)
        sizer.AddF(instructions, sizer_flags.Align(wx.LEFT))
        self.arpeggiate_option = wx.CheckBox(self, label=ARPEGGIATE_LABEL)
        self.arpeggiate_option.SetValue(options.arpeggiate)
        sizer.AddF(self.arpeggiate_option, sizer_flags)

        # editable list for keymap bindings
        self.keymap = Keymap(Keyboard.KEYS_LAYOUT.split(), Keyboard.ACTIONS)
        mappings = config.get_system_keymap('Keyboard')
        if mappings is not None:
            self.keymap.set_mappings(mappings)
        self.keymap_widget = EditKeymapWidget(self)
        self.keymap_widget.set_mappings(self.keymap.get_mappings())
        sizer.AddF(self.keymap_widget, sizer_flags.Expand())

        ok_button = wx.Button(self, id=wx.ID_OK)
        ok_button.SetDefault()
        cancel_button = wx.Button(self, id=wx.ID_CANCEL, label='Cancel')
        reset_button = wx.Button(self, id=wx.ID_RESET, label='Reset to default')

        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_sizer.AddF(ok_button, sizer_flags)
        button_sizer.AddF(cancel_button, sizer_flags)
        button_sizer.AddF(reset_button, sizer_flags)
        sizer.AddF(button_sizer, sizer_flags)

        self.SetSizerAndFit(sizer)
        self.SetRect(AdjustRectToScreen(self.GetRect()))

        self.Bind(wx.EVT_MOVE, self.on_move)
        ok_button.Bind(wx.EVT_BUTTON, lambda e: self.EndModal(wx.ID_OK))
        cancel_button.Bind(wx.EVT_BUTTON, lambda e: self.EndModal(wx.ID_CANCEL))
        reset_button.Bind(wx.EVT_BUTTON, self.on_reset)
Esempio n. 17
0
            {'path': short_path, 'enabled': True}
    assert DictionaryConfig(short_path, False).to_dict() == \
            {'path': short_path, 'enabled': False}
    # Test from_dict creation helper.
    assert DictionaryConfig.from_dict({'path': short_path}) == \
            DictionaryConfig(short_path)
    assert DictionaryConfig.from_dict({'path': full_path, 'enabled': False}) == \
            DictionaryConfig(short_path, False)


if sys.platform.startswith('win32'):
    ABS_PATH = os.path.normcase(r'c:/foo/bar')
else:
    ABS_PATH = '/foo/bar'

DEFAULT_KEYMAP = Keymap(Keyboard.get_keys(), english_stenotype.KEYS + Keyboard.get_actions())
DEFAULT_KEYMAP.set_mappings(english_stenotype.KEYMAPS['Keyboard'])

DEFAULTS = {
    'space_placement': 'Before Output',
    'start_attached': False,
    'start_capitalized': False,
    'undo_levels': config.DEFAULT_UNDO_LEVELS,
    'log_file_name': expand_path('strokes.log'),
    'enable_stroke_logging': False,
    'enable_translation_logging': False,
    'start_minimized': False,
    'show_stroke_display': False,
    'show_suggestions_display': False,
    'translation_frame_opacity': 100,
    'classic_dictionaries_display_order': False,
Esempio n. 18
0
 def __init__(self):
     self.keymap = Keymap(self.KEYS_LAYOUT.split(), self.ACTIONS)
     self.stroke_subscribers = []
     self.state_subscribers = []
     self.state = STATE_STOPPED
Esempio n. 19
0
class StenotypeBase(object):
    """The base class for all Stenotype classes."""

    # Layout of physical keys.
    KEYS_LAYOUT = ''
    # And possible actions to map to.
    ACTIONS = (
        tuple(sorted(system.KEY_ORDER.keys(),
                     key=lambda k: system.KEY_ORDER[k]))
        + ('no-op',)
    )

    def __init__(self):
        self.keymap = Keymap(self.KEYS_LAYOUT.split(), self.ACTIONS)
        self.stroke_subscribers = []
        self.state_subscribers = []
        self.state = STATE_STOPPED

    def set_mappings(self, mappings):
        """Setup machine keymap: mappings of action to keys."""
        self.keymap.set_mappings(mappings)

    def start_capture(self):
        """Begin listening for output from the stenotype machine."""
        pass

    def stop_capture(self):
        """Stop listening for output from the stenotype machine."""
        pass

    def add_stroke_callback(self, callback):
        """Subscribe to output from the stenotype machine.

        Argument:

        callback -- The function to call whenever there is output from
        the stenotype machine and output is being captured.

        """
        self.stroke_subscribers.append(callback)

    def remove_stroke_callback(self, callback):
        """Unsubscribe from output from the stenotype machine.

        Argument:

        callback -- A function that was previously subscribed.

        """
        self.stroke_subscribers.remove(callback)

    def add_state_callback(self, callback):
        self.state_subscribers.append(callback)
        
    def remove_state_callback(self, callback):
        self.state_subscribers.remove(callback)

    def _notify(self, steno_keys):
        """Invoke the callback of each subscriber with the given argument."""
        for callback in self.stroke_subscribers:
            callback(steno_keys)

    def set_suppression(self, enabled):
        '''Enable keyboard suppression.

        This is only of use for the keyboard machine,
        to suppress the keyboard when then engine is running.
        '''
        pass

    def suppress_last_stroke(self, send_backspaces):
        '''Suppress the last stroke key events after the fact.

        This is only of use for the keyboard machine,
        and the engine is resumed with a command stroke.

        Argument:

        send_backspaces -- The function to use to send backspaces.
        '''
        pass

    def _set_state(self, state):
        self.state = state
        for callback in self.state_subscribers:
            callback(state)

    def _stopped(self):
        self._set_state(STATE_STOPPED)

    def _initializing(self):
        self._set_state(STATE_INITIALIZING)

    def _ready(self):
        self._set_state(STATE_RUNNING)
            
    def _error(self):
        self._set_state(STATE_ERROR)

    @classmethod
    def get_option_info(cls):
        """Get the default options for this machine."""
        return {}
Esempio n. 20
0
class KeyboardConfigDialog(wx.Dialog):
    """Keyboard configuration dialog."""
    def __init__(self, options, parent, config):
        self.config = config
        self.options = options

        pos = (config.get_keyboard_config_frame_x(),
               config.get_keyboard_config_frame_y())
        wx.Dialog.__init__(self, parent, title=DIALOG_TITLE, pos=pos)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer_flags = wx.SizerFlags().Border(wx.ALL, UI_BORDER).Align(
            wx.ALIGN_CENTER_HORIZONTAL)

        instructions = wx.StaticText(self, label=ARPEGGIATE_INSTRUCTIONS)
        sizer.AddF(instructions, sizer_flags.Align(wx.LEFT))
        self.arpeggiate_option = wx.CheckBox(self, label=ARPEGGIATE_LABEL)
        self.arpeggiate_option.SetValue(options.arpeggiate)
        sizer.AddF(self.arpeggiate_option, sizer_flags)

        # editable list for keymap bindings
        self.keymap = Keymap(Keyboard.KEYS_LAYOUT.split(), Keyboard.ACTIONS)
        mappings = config.get_system_keymap('Keyboard')
        if mappings is not None:
            self.keymap.set_mappings(mappings)
        self.keymap_widget = EditKeymapWidget(self)
        self.keymap_widget.set_mappings(self.keymap.get_mappings())
        sizer.AddF(self.keymap_widget, sizer_flags.Expand())

        ok_button = wx.Button(self, id=wx.ID_OK)
        ok_button.SetDefault()
        cancel_button = wx.Button(self, id=wx.ID_CANCEL, label='Cancel')
        reset_button = wx.Button(self,
                                 id=wx.ID_RESET,
                                 label='Reset to default')

        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_sizer.AddF(ok_button, sizer_flags)
        button_sizer.AddF(cancel_button, sizer_flags)
        button_sizer.AddF(reset_button, sizer_flags)
        sizer.AddF(button_sizer, sizer_flags)

        self.SetSizerAndFit(sizer)
        self.SetRect(AdjustRectToScreen(self.GetRect()))

        self.Bind(wx.EVT_MOVE, self.on_move)
        ok_button.Bind(wx.EVT_BUTTON, lambda e: self.EndModal(wx.ID_OK))
        cancel_button.Bind(wx.EVT_BUTTON,
                           lambda e: self.EndModal(wx.ID_CANCEL))
        reset_button.Bind(wx.EVT_BUTTON, self.on_reset)

    def ShowModal(self):
        code = super(KeyboardConfigDialog, self).ShowModal()
        if wx.ID_OK == code:
            self.options.arpeggiate = self.arpeggiate_option.GetValue()
            # Validate mappings by updating the keymap object.
            self.keymap.set_mappings(self.keymap_widget.get_mappings())
            self.config.set_system_keymap('Keyboard',
                                          self.keymap.get_mappings())
        return code

    def on_reset(self, event):
        mappings = self.keymap_widget.get_mappings()
        mappings.update(system.KEYMAPS['Keyboard'])
        self.keymap_widget.set_mappings(mappings)

    def on_move(self, event):
        pos = self.GetScreenPositionTuple()
        self.config.set_keyboard_config_frame_x(pos[0])
        self.config.set_keyboard_config_frame_y(pos[1])
        event.Skip()
Esempio n. 21
0
 def __init__(self):
     self.keymap = Keymap(self.KEYS_LAYOUT.split(), self.ACTIONS)
     self.stroke_subscribers = []
     self.state_subscribers = []
     self.state = STATE_STOPPED
Esempio n. 22
0
class StenotypeBase(object):
    """The base class for all Stenotype classes."""

    # Layout of physical keys.
    KEYS_LAYOUT = ''
    # And possible actions to map to.
    ACTIONS = system.KEYS + ('no-op', )

    def __init__(self):
        self.keymap = Keymap(self.KEYS_LAYOUT.split(), self.ACTIONS)
        self.stroke_subscribers = []
        self.state_subscribers = []
        self.state = STATE_STOPPED

    def set_mappings(self, mappings):
        """Setup machine keymap: mappings of action to keys."""
        self.keymap.set_mappings(mappings)

    def start_capture(self):
        """Begin listening for output from the stenotype machine."""
        pass

    def stop_capture(self):
        """Stop listening for output from the stenotype machine."""
        pass

    def add_stroke_callback(self, callback):
        """Subscribe to output from the stenotype machine.

        Argument:

        callback -- The function to call whenever there is output from
        the stenotype machine and output is being captured.

        """
        self.stroke_subscribers.append(callback)

    def remove_stroke_callback(self, callback):
        """Unsubscribe from output from the stenotype machine.

        Argument:

        callback -- A function that was previously subscribed.

        """
        self.stroke_subscribers.remove(callback)

    def add_state_callback(self, callback):
        self.state_subscribers.append(callback)

    def remove_state_callback(self, callback):
        self.state_subscribers.remove(callback)

    def _notify(self, steno_keys):
        """Invoke the callback of each subscriber with the given argument."""
        for callback in self.stroke_subscribers:
            callback(steno_keys)

    def set_suppression(self, enabled):
        '''Enable keyboard suppression.

        This is only of use for the keyboard machine,
        to suppress the keyboard when then engine is running.
        '''
        pass

    def suppress_last_stroke(self, send_backspaces):
        '''Suppress the last stroke key events after the fact.

        This is only of use for the keyboard machine,
        and the engine is resumed with a command stroke.

        Argument:

        send_backspaces -- The function to use to send backspaces.
        '''
        pass

    def _set_state(self, state):
        self.state = state
        for callback in self.state_subscribers:
            callback(state)

    def _stopped(self):
        self._set_state(STATE_STOPPED)

    def _initializing(self):
        self._set_state(STATE_INITIALIZING)

    def _ready(self):
        self._set_state(STATE_RUNNING)

    def _error(self):
        self._set_state(STATE_ERROR)

    @classmethod
    def get_option_info(cls):
        """Get the default options for this machine."""
        return {}
Esempio n. 23
0
class StenotypeBase(object):
    """The base class for all Stenotype classes."""

    # Layout of physical keys.
    KEYS_LAYOUT = ''
    # And special actions to map to.
    ACTIONS = ()
    # Fallback to use as machine type for finding a compatible keymap
    # if one is not already available for this machine type.
    KEYMAP_MACHINE_TYPE = None

    def __init__(self):
        # Setup default keymap with no translation of keys.
        keys = self.get_keys()
        self.keymap = Keymap(keys, keys)
        self.keymap.set_mappings(zip(keys, keys))
        self.stroke_subscribers = []
        self.state_subscribers = []
        self.state = STATE_STOPPED

    def set_keymap(self, keymap):
        """Setup machine keymap."""
        self.keymap = keymap

    def start_capture(self):
        """Begin listening for output from the stenotype machine."""
        pass

    def stop_capture(self):
        """Stop listening for output from the stenotype machine."""
        pass

    def add_stroke_callback(self, callback):
        """Subscribe to output from the stenotype machine.

        Argument:

        callback -- The function to call whenever there is output from
        the stenotype machine and output is being captured.

        """
        self.stroke_subscribers.append(callback)

    def remove_stroke_callback(self, callback):
        """Unsubscribe from output from the stenotype machine.

        Argument:

        callback -- A function that was previously subscribed.

        """
        self.stroke_subscribers.remove(callback)

    def add_state_callback(self, callback):
        self.state_subscribers.append(callback)
        
    def remove_state_callback(self, callback):
        self.state_subscribers.remove(callback)

    def _notify(self, steno_keys):
        """Invoke the callback of each subscriber with the given argument."""
        for callback in self.stroke_subscribers:
            callback(steno_keys)

    def set_suppression(self, enabled):
        '''Enable keyboard suppression.

        This is only of use for the keyboard machine,
        to suppress the keyboard when then engine is running.
        '''
        pass

    def suppress_last_stroke(self, send_backspaces):
        '''Suppress the last stroke key events after the fact.

        This is only of use for the keyboard machine,
        and the engine is resumed with a command stroke.

        Argument:

        send_backspaces -- The function to use to send backspaces.
        '''
        pass

    def _set_state(self, state):
        self.state = state
        for callback in self.state_subscribers:
            callback(state)

    def _stopped(self):
        self._set_state(STATE_STOPPED)

    def _initializing(self):
        self._set_state(STATE_INITIALIZING)

    def _ready(self):
        self._set_state(STATE_RUNNING)
            
    def _error(self):
        self._set_state(STATE_ERROR)

    @classmethod
    def get_actions(cls):
        """List of supported actions to map to."""
        return cls.ACTIONS

    @classmethod
    def get_keys(cls):
        return tuple(set(cls.KEYS_LAYOUT.split()))

    @classmethod
    def get_option_info(cls):
        """Get the default options for this machine."""
        return {}
Esempio n. 24
0
 def on_ok(self, event):
     self.options.arpeggiate = self.arpeggiate_option.GetValue()
     self.options.keymap = Keymap.from_rows(
         self.keymap_list_ctrl.get_all_rows())
     self.EndModal(wx.ID_OK)
Esempio n. 25
0
class StenotypeBase:
    """The base class for all Stenotype classes."""

    # Layout of physical keys.
    KEYS_LAYOUT = ''
    # And special actions to map to.
    ACTIONS = ()
    # Fallback to use as machine type for finding a compatible keymap
    # if one is not already available for this machine type.
    KEYMAP_MACHINE_TYPE = None

    def __init__(self):
        # Setup default keymap with no translation of keys.
        keys = self.get_keys()
        self.keymap = Keymap(keys, keys)
        self.keymap.set_mappings(zip(keys, keys))
        self.stroke_subscribers = []
        self.state_subscribers = []
        self.state = STATE_STOPPED

    def set_keymap(self, keymap):
        """Setup machine keymap."""
        self.keymap = keymap

    def start_capture(self):
        """Begin listening for output from the stenotype machine."""
        pass

    def stop_capture(self):
        """Stop listening for output from the stenotype machine."""
        pass

    def add_stroke_callback(self, callback):
        """Subscribe to output from the stenotype machine.

        Argument:

        callback -- The function to call whenever there is output from
        the stenotype machine and output is being captured.

        """
        self.stroke_subscribers.append(callback)

    def remove_stroke_callback(self, callback):
        """Unsubscribe from output from the stenotype machine.

        Argument:

        callback -- A function that was previously subscribed.

        """
        self.stroke_subscribers.remove(callback)

    def add_state_callback(self, callback):
        self.state_subscribers.append(callback)

    def remove_state_callback(self, callback):
        self.state_subscribers.remove(callback)

    def _notify(self, steno_keys):
        """Invoke the callback of each subscriber with the given argument."""
        for callback in self.stroke_subscribers:
            callback(steno_keys)

    def set_suppression(self, enabled):
        '''Enable keyboard suppression.

        This is only of use for the keyboard machine,
        to suppress the keyboard when then engine is running.
        '''
        pass

    def suppress_last_stroke(self, send_backspaces):
        '''Suppress the last stroke key events after the fact.

        This is only of use for the keyboard machine,
        and the engine is resumed with a command stroke.

        Argument:

        send_backspaces -- The function to use to send backspaces.
        '''
        pass

    def _set_state(self, state):
        self.state = state
        for callback in self.state_subscribers:
            callback(state)

    def _stopped(self):
        self._set_state(STATE_STOPPED)

    def _initializing(self):
        self._set_state(STATE_INITIALIZING)

    def _ready(self):
        self._set_state(STATE_RUNNING)

    def _error(self):
        self._set_state(STATE_ERROR)

    @classmethod
    def get_actions(cls):
        """List of supported actions to map to."""
        return cls.ACTIONS

    @classmethod
    def get_keys(cls):
        return tuple(cls.KEYS_LAYOUT.split())

    @classmethod
    def get_option_info(cls):
        """Get the default options for this machine."""
        return {}
Esempio n. 26
0
class KeyboardConfigDialog(wx.Dialog):
    """Keyboard configuration dialog."""

    def __init__(self, options, parent, config):
        self.config = config
        self.options = options
        
        pos = (config.get_keyboard_config_frame_x(), 
               config.get_keyboard_config_frame_y())
        wx.Dialog.__init__(self, parent, title=DIALOG_TITLE, pos=pos)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer_flags = wx.SizerFlags().Border(wx.ALL, UI_BORDER).Align(wx.ALIGN_CENTER_HORIZONTAL)

        instructions = wx.StaticText(self, label=ARPEGGIATE_INSTRUCTIONS)
        sizer.AddF(instructions, sizer_flags.Align(wx.LEFT))
        self.arpeggiate_option = wx.CheckBox(self, label=ARPEGGIATE_LABEL)
        self.arpeggiate_option.SetValue(options.arpeggiate)
        sizer.AddF(self.arpeggiate_option, sizer_flags)

        # editable list for keymap bindings
        self.keymap = Keymap(Keyboard.KEYS_LAYOUT.split(), Keyboard.ACTIONS)
        mappings = config.get_system_keymap('Keyboard')
        if mappings is not None:
            self.keymap.set_mappings(mappings)
        self.keymap_widget = EditKeymapWidget(self)
        self.keymap_widget.set_mappings(self.keymap.get_mappings())
        sizer.AddF(self.keymap_widget, sizer_flags.Expand())

        ok_button = wx.Button(self, id=wx.ID_OK)
        ok_button.SetDefault()
        cancel_button = wx.Button(self, id=wx.ID_CANCEL, label='Cancel')
        reset_button = wx.Button(self, id=wx.ID_RESET, label='Reset to default')

        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_sizer.AddF(ok_button, sizer_flags)
        button_sizer.AddF(cancel_button, sizer_flags)
        button_sizer.AddF(reset_button, sizer_flags)
        sizer.AddF(button_sizer, sizer_flags)

        self.SetSizerAndFit(sizer)
        self.SetRect(AdjustRectToScreen(self.GetRect()))

        self.Bind(wx.EVT_MOVE, self.on_move)
        ok_button.Bind(wx.EVT_BUTTON, lambda e: self.EndModal(wx.ID_OK))
        cancel_button.Bind(wx.EVT_BUTTON, lambda e: self.EndModal(wx.ID_CANCEL))
        reset_button.Bind(wx.EVT_BUTTON, self.on_reset)

    def ShowModal(self):
        code = super(KeyboardConfigDialog, self).ShowModal()
        if wx.ID_OK == code:
            self.options.arpeggiate = self.arpeggiate_option.GetValue()
            # Validate mappings by updating the keymap object.
            self.keymap.set_mappings(self.keymap_widget.get_mappings())
            self.config.set_system_keymap('Keyboard', self.keymap.get_mappings())
        return code

    def on_reset(self, event):
        mappings = self.keymap_widget.get_mappings()
        mappings.update(system.KEYMAPS['Keyboard'])
        self.keymap_widget.set_mappings(mappings)

    def on_move(self, event):
        pos = self.GetScreenPositionTuple()
        self.config.set_keyboard_config_frame_x(pos[0]) 
        self.config.set_keyboard_config_frame_y(pos[1])
        event.Skip()
Esempio n. 27
0
            {'path': short_path, 'enabled': True}
    assert DictionaryConfig(short_path, False).to_dict() == \
            {'path': short_path, 'enabled': False}
    # Test from_dict creation helper.
    assert DictionaryConfig.from_dict({'path': short_path}) == \
            DictionaryConfig(short_path)
    assert DictionaryConfig.from_dict({'path': full_path, 'enabled': False}) == \
            DictionaryConfig(short_path, False)


if sys.platform.startswith('win32'):
    ABS_PATH = os.path.normcase(r'c:/foo/bar')
else:
    ABS_PATH = '/foo/bar'

DEFAULT_KEYMAP = Keymap(Keyboard.get_keys(),
                        english_stenotype.KEYS + Keyboard.get_actions())
DEFAULT_KEYMAP.set_mappings(english_stenotype.KEYMAPS['Keyboard'])

DEFAULTS = {
    'space_placement':
    'Before Output',
    'start_attached':
    False,
    'start_capitalized':
    False,
    'undo_levels':
    config.DEFAULT_UNDO_LEVELS,
    'log_file_name':
    expand_path('strokes.log'),
    'enable_stroke_logging':
    False,
Esempio n. 28
0
    def test_decoding(self):
        inputs = [
            binascii.unhexlify(packet) for packet in '''
                  A90020
                  00

                  05464000

                  A904
                  0400

                  0D065000

                  A1008000

                  05
                  820400

                  17
                  00
                  8000

                  05
                  08
                  00
                  00
                  '''.split()
        ]
        # Mi piace mangiare la pizza.
        expected = 'CHRi/PIAce/CHRAh/PCIAre/HRa/PIsh/SPTa/P*'.split('/')
        keymap_mappings = {
            '#': '#',
            'S': 'S-',
            'P': 'T-',
            'C': 'K-',
            'T': 'P-',
            'H': 'W-',
            'V': 'H-',
            'R': 'R-',
            'I': 'A-',
            'A': 'O-',
            '*': '*',
            'E': '-E',
            'O': '-U',
            'c': '-F',
            's': '-R',
            't': '-P',
            'h': '-B',
            'p': '-L',
            'r': '-G',
            'i': '-T',
            'e': '-S',
            'a': '-D',
            'o': '-Z',
        }
        serial_params = {
            name: value[0]
            for name, value in ItalianStentura.get_option_info().items()
        }
        keymap = Keymap(ItalianStentura.KEYS_LAYOUT.split(),
                        keymap_mappings.keys())
        keymap.set_mappings(keymap_mappings)
        with patch('plover.machine.base.serial.Serial', MockSerial) as mock:
            machine = ItalianStentura(serial_params)

            def stroke_callbak(steno_keys):
                self.assertEqual(''.join(steno_keys), expected.pop(0))
                if not expected:
                    machine.stop_capture()

            machine.add_stroke_callback(stroke_callbak)
            machine.set_keymap(keymap)
            mock.inputs = inputs
            mock.machine = machine
            machine.start_capture()
            machine.finished.wait()
        self.assertFalse(bool(expected))
class TinyMod4Machine(ThreadedStenotypeBase):

  # Layout of keys on board; used by plover in making of self.keymap
  KEYS_LAYOUT = '''
    S1- T- P- H- *1 -F -P -L -T -D
    S2- K- W- R- *2 -R -B -G -S -Z
           A- O- #1 -E -U
  '''

  def __init__(self, _):
    super(TinyMod4Machine, self).__init__()
    keys = self.get_keys()
    self.keymap = Keymap(keys, keys)
    self.keymap.set_mappings(zip(keys, keys))
    self._pressed = False
    self._stack = ForthStack(8, 7)
    self._modeSelectPin = 12

  # Set up and connect to harware
  def _connect(self):
    connected = False

    # Set plover mode to initializing
    self._initializing()

    try:
      # Init the raw pins
      io.setup(self._modeSelectPin, io.IN, pull_up_down = io.PUD_UP)
      io.setup(16, io.IN, pull_up_down = io.PUD_UP)
      io.setup(20, io.IN, pull_up_down = io.PUD_UP)
      io.setup(21, io.IN, pull_up_down = io.PUD_UP)
      io.setup(1, io.IN, pull_up_down = io.PUD_UP)
      io.setup(26, io.IN, pull_up_down = io.PUD_UP)
      io.setup(19, io.IN, pull_up_down = io.PUD_UP)
      io.setup(13, io.IN, pull_up_down = io.PUD_UP)
      io.setup(6, io.IN, pull_up_down = io.PUD_UP)
      io.setup(0, io.IN, pull_up_down = io.PUD_UP)

      # Init the port expander pins
      self._bus = smbus.SMBus(1)
      self._bus.write_byte_data(0x20, 0x0c, 0xff)
      self._bus.write_byte_data(0x20, 0x0d, 0xff)

      # Check if switch on board is set to NKRO
      if io.input(self._modeSelectPin):
        log.warning("NKRO not selected on board. TinyMod4 plugin Disabled.")
        self._error()
        return connected

      self._ready()
      connected = True
      return connected
    except:
      log.warning("Error setting up TinyMod4")
      self._error()

    return connected

  # Reconnect if disconnected
  def _reconnect(self):
    connected = self._connect()

    while not self.finished.isSet() and not connected:
      time.sleep(0.5)
      connected = self._connect()
      return connected


  # Stop listening for strokes
  def stop_capture(self):
    super(TinyMod4Machine, self).stop_capture()
    self._stopped()
  
  # Covert keys to stroke and send to plover for translation
  def _on_stroke(self, keys):
    steno_keys = self.keymap.keys_to_actions(keys)
    if steno_keys:
      self._notify(steno_keys)

  # Read keys from raw pins
  def _read_raw_keys(self):
    a = 0
    a |=  io.input(16)        # 1
    a |= (io.input(20) << 1)  # 2
    a |= (io.input(21) << 2)  # 4
    a |= (io.input(1) << 3)   # 8
    a |= (io.input(26) << 4)  # 10
    a |= (io.input(19) << 5)  # 20
    a |= (io.input(13) << 6)  # 40
    a |= (io.input(6) << 7)   # 80
    a |= (io.input(0) << 8)   # 100
    a ^= 0x01ff
    self._stack.push(a)

  # Read keys from port expander pins
  def _read_ab(self):
    a = self._bus.read_byte_data(0x20, 0x12)
    b = self._bus.read_byte_data(0x20, 0x13)
    a |= b << 8
    a ^= 0xffff
    self._stack.push(a)

  # Read all keys combined
  def _read_all(self):
    self._pressed = True
    self._read_raw_keys()
    self._read_ab()
    self._stack.over()
    self._stack.over()
    self._stack.or_()
    a = self._stack.pop()
    if a == 0:
      self._pressed = False

  # Scan for keys
  def _scan(self):
    while not self._pressed:
      while not self._pressed:
        self._read_all()
      time.sleep(0.03)
      self._read_all()
    a = 0
    b = 0
    while self._pressed:
      self._read_all()
      b |= self._stack.pop()
      a |= self._stack.pop()
    self._stack.push(a)
    self._stack.push(b)

  # Convert and send keys
  def _send(self):
    b = self._stack.pop()
    a = self._stack.pop()

    keys = []

    # Steno order: STKPWHRAO*EUFRPBLGTSDZ
    if a & 0x10:   keys.append('S1-')
    if a & 0x08:   keys.append('S2-')
    if a & 0x20:   keys.append('T-')
    if a & 0x04:   keys.append('K-')
    if a & 0x40:   keys.append('P-')
    if a & 0x02:   keys.append('W-')
    if a & 0x80:   keys.append('H-')
    if a & 0x01:   keys.append('R-')
    if b & 0x08:   keys.append('A-')
    if b & 0x10:   keys.append('O-')
    if a & 0x100:  keys.append('*1')
    if b & 0x200:  keys.append('*2')
    if b & 0x20:   keys.append('#1')
    if b & 0x40:   keys.append('-E')
    if b & 0x80:   keys.append('-U')
    if b & 0x8000: keys.append('-F')
    if b & 0x01:   keys.append('-R')
    if b & 0x4000: keys.append('-P')
    if b & 0x02:   keys.append('-B')
    if b & 0x2000: keys.append('-L')
    if b & 0x04:   keys.append('-G')
    if b & 0x1000: keys.append('-T')
    if b & 0x800:  keys.append('-S')
    if b & 0x100:  keys.append('-D')
    if b & 0x400:  keys.append('-Z')

    if keys:
      self._on_stroke(keys)

  # Start the thread
  def run(self):
    self._ready()
    while not self.finished.isSet():
      self._scan()
      self._send()
Esempio n. 30
0
 def on_ok(self, event):
     self.options.arpeggiate = self.arpeggiate_option.GetValue()
     self.options.keymap = Keymap.from_rows(self.keymap_list_ctrl.get_all_rows())
     self.EndModal(wx.ID_OK)
Esempio n. 31
0
def new_keymap():
    return Keymap(('k%u' % n for n in range(8)), ('a%u' % n for n in range(4)))