def test_engine_update_no_changes(self): with self._setup(): app.init_engine(self.engine, self.cfg) self.assertEqual(self.state_transitions, [ (None, False), # engine init (None, False), # ])
def test_engine_auto_start(self): with self._setup(auto_start=True): app.init_engine(self.engine, self.cfg) self.assertEqual(self.state_transitions, [ (None, True), # engine init (None, True), # ])
def test_engine_init(self): with self._setup(): app.init_engine(self.engine, self.cfg) self.assertEqual(self.state_transitions, [ (None, False), # engine init (None, False), # ]) self.assertIsInstance(self.engine.machine, FakeMachine)
def test_engine_reconnect(self): with self._setup(): app.init_engine(self.engine, self.cfg) self.engine.machine._ready() self.engine.set_is_running(True) self.engine.machine._error() app.update_engine(self.engine, self.cfg, reset_machine=True) self.engine.machine._ready() self.assertEqual(self.state_transitions, [ (None , False), # engine init (None , False), # ('connected' , False), # machine ready (None , True ), # set_is_running(True) ('disconnected', True ), # machine error (None , True ), # engine update ('connected' , True ), # machine ready ])
def __init__(self, config): self.config = config # Note: don't set position from config, since it's not yet loaded. wx.Frame.__init__( self, None, title=self.TITLE, style=wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.RESIZE_BOX | wx.MAXIMIZE_BOX)) root = wx.Panel(self, style=wx.DEFAULT_FRAME_STYLE) # Menu Bar MenuBar = wx.MenuBar() self.SetMenuBar(MenuBar) # Application icon icon = wx.Icon(self.PLOVER_ICON_FILE, wx.BITMAP_TYPE_ICO) self.SetIcon(icon) # Configure button. self.configure_button = wx.Button(root, label=self.CONFIGURE_BUTTON_LABEL) self.configure_button.Bind(wx.EVT_BUTTON, self._show_config_dialog) # About button. self.about_button = wx.Button(root, label=self.ABOUT_BUTTON_LABEL) self.about_button.Bind(wx.EVT_BUTTON, self._show_about_dialog) # Status radio buttons. self.radio_output_enable = wx.RadioButton( root, label=self.ENABLE_OUTPUT_LABEL) self.radio_output_enable.Bind( wx.EVT_RADIOBUTTON, lambda e: self.steno_engine.set_is_running(True)) self.radio_output_disable = wx.RadioButton( root, label=self.DISABLE_OUTPUT_LABEL) self.radio_output_disable.Bind( wx.EVT_RADIOBUTTON, lambda e: self.steno_engine.set_is_running(False)) # Machine status. # TODO: Figure out why spinner has darker gray background. self.spinner = wx.animate.GIFAnimationCtrl(root, -1, SPINNER_FILE) self.spinner.GetPlayer().UseBackgroundColour(True) # Need to call this so the size of the control is not # messed up (100x100 instead of 16x16) on Linux... self.spinner.InvalidateBestSize() self.spinner.Hide() self.connected_bitmap = wx.Bitmap(self.CONNECTED_IMAGE_FILE, wx.BITMAP_TYPE_PNG) self.disconnected_bitmap = wx.Bitmap(self.DISCONNECTED_IMAGE_FILE, wx.BITMAP_TYPE_PNG) self.connection_ctrl = wx.StaticBitmap(root, bitmap=self.disconnected_bitmap) border_flag = wx.SizerFlags(1).Border(wx.ALL, self.BORDER) # Create Settings Box settings_sizer = wx.BoxSizer(wx.HORIZONTAL) settings_sizer.AddF(self.configure_button, border_flag.Expand()) settings_sizer.AddF(self.about_button, border_flag.Expand()) # Create Output Status Box box = wx.StaticBox(root, label=self.HEADER_OUTPUT) status_sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) status_sizer.AddF(self.radio_output_enable, border_flag) status_sizer.AddF(self.radio_output_disable, border_flag) # Create Machine Status Box machine_sizer = wx.BoxSizer(wx.HORIZONTAL) center_flag =\ wx.SizerFlags()\ .Align(wx.ALIGN_CENTER_VERTICAL)\ .Border(wx.LEFT | wx.RIGHT, self.BORDER) machine_sizer.AddF(self.spinner, center_flag) machine_sizer.AddF(self.connection_ctrl, center_flag) longest_machine = max(machine_registry.get_all_names(), key=len) longest_state = max((STATE_ERROR, STATE_INITIALIZING, STATE_RUNNING), key=len) longest_machine_status = '%s: %s' % (longest_machine, longest_state) self.machine_status_text = wx.StaticText(root, label=longest_machine_status) machine_sizer.AddF(self.machine_status_text, center_flag) refresh_bitmap = wx.Bitmap(self.REFRESH_IMAGE_FILE, wx.BITMAP_TYPE_PNG) self.reconnect_button = wx.BitmapButton(root, bitmap=refresh_bitmap) machine_sizer.AddF(self.reconnect_button, center_flag) # Assemble main UI global_sizer = wx.GridBagSizer(vgap=self.BORDER, hgap=self.BORDER) global_sizer.Add(settings_sizer, flag=wx.EXPAND, pos=(0, 0), span=(1, 2)) global_sizer.Add(status_sizer, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=self.BORDER, pos=(1, 0), span=(1, 2)) global_sizer.Add(machine_sizer, flag=wx.CENTER | wx.ALIGN_CENTER | wx.EXPAND | wx.LEFT, pos=(2, 0), border=self.BORDER, span=(1, 2)) self.machine_sizer = machine_sizer # Add a border around the entire sizer. border = wx.BoxSizer() border.AddF(global_sizer, wx.SizerFlags(1).Border(wx.ALL, self.BORDER).Expand()) root.SetSizerAndFit(border) border.SetSizeHints(self) self.Bind(wx.EVT_CLOSE, self._quit) self.Bind(wx.EVT_MOVE, self.on_move) self.reconnect_button.Bind(wx.EVT_BUTTON, lambda e: self._reconnect()) try: with open(config.target_file, 'rb') as f: self.config.load(f) except Exception: log.error('loading configuration failed, reseting to default', exc_info=True) self.config.clear() rect = wx.Rect(config.get_main_frame_x(), config.get_main_frame_y(), *self.GetSize()) self.SetRect(AdjustRectToScreen(rect)) self.steno_engine = app.StenoEngine() self.steno_engine.add_callback( lambda s: wx.CallAfter(self._update_status, s)) self.steno_engine.set_output( Output(self.consume_command, self.steno_engine)) self.steno_engine.add_stroke_listener( StrokeDisplayDialog.stroke_handler) if self.config.get_show_stroke_display(): StrokeDisplayDialog.display(self, self.config) self.steno_engine.formatter.add_listener( SuggestionsDisplayDialog.stroke_handler) if self.config.get_show_suggestions_display(): SuggestionsDisplayDialog.display(self, self.config, self.steno_engine) try: app.init_engine(self.steno_engine, self.config) except Exception: log.error('engine initialization failed', exc_info=True) self._show_config_dialog()
def __init__(self, config): self.config = config pos = wx.DefaultPosition size = wx.DefaultSize wx.Frame.__init__(self, None, title=self.TITLE, pos=pos, size=size, style=wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.RESIZE_BOX | wx.MAXIMIZE_BOX)) # Status button. self.on_bitmap = wx.Bitmap(self.ON_IMAGE_FILE, wx.BITMAP_TYPE_PNG) self.off_bitmap = wx.Bitmap(self.OFF_IMAGE_FILE, wx.BITMAP_TYPE_PNG) self.status_button = wx.BitmapButton(self, bitmap=self.on_bitmap) self.status_button.Bind(wx.EVT_BUTTON, self._toggle_steno_engine) # Configure button. self.configure_button = wx.Button(self, label=self.CONFIGURE_BUTTON_LABEL) self.configure_button.Bind(wx.EVT_BUTTON, self._show_config_dialog) # About button. self.about_button = wx.Button(self, label=self.ABOUT_BUTTON_LABEL) self.about_button.Bind(wx.EVT_BUTTON, self._show_about_dialog) # Machine status. # TODO: Figure out why spinner has darker gray background. self.spinner = wx.animate.GIFAnimationCtrl(self, -1, SPINNER_FILE) self.spinner.GetPlayer().UseBackgroundColour(True) self.spinner.Hide() self.connected_bitmap = wx.Bitmap(self.CONNECTED_IMAGE_FILE, wx.BITMAP_TYPE_PNG) self.disconnected_bitmap = wx.Bitmap(self.DISCONNECTED_IMAGE_FILE, wx.BITMAP_TYPE_PNG) self.connection_ctrl = wx.StaticBitmap(self, bitmap=self.disconnected_bitmap) # Layout. global_sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.status_button, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=self.BORDER) sizer.Add(self.configure_button, flag=wx.TOP | wx.BOTTOM | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, border=self.BORDER) sizer.Add(self.about_button, flag=wx.TOP | wx.BOTTOM | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, border=self.BORDER) global_sizer.Add(sizer) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.spinner, flag=(wx.LEFT | wx.BOTTOM | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL), border=self.BORDER) sizer.Add(self.connection_ctrl, flag=(wx.LEFT | wx.BOTTOM | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL), border=self.BORDER) longest_machine = max(machine_registry.get_all_names(), key=len) longest_state = max((STATE_ERROR, STATE_INITIALIZING, STATE_RUNNING), key=len) longest_status = '%s: %s' % (longest_machine, longest_state) self.machine_status_text = wx.StaticText(self, label=longest_status) sizer.Add(self.machine_status_text, flag=wx.BOTTOM | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, border=self.BORDER) refresh_bitmap = wx.Bitmap(self.REFRESH_IMAGE_FILE, wx.BITMAP_TYPE_PNG) self.reconnect_button = wx.BitmapButton(self, bitmap=refresh_bitmap) sizer.Add(self.reconnect_button, flag=wx.BOTTOM | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, border=self.BORDER) self.machine_status_sizer = sizer global_sizer.Add(sizer) self.SetSizer(global_sizer) global_sizer.Fit(self) self.SetRect(AdjustRectToScreen(self.GetRect())) self.Bind(wx.EVT_CLOSE, self._quit) self.Bind(wx.EVT_MOVE, self.on_move) self.reconnect_button.Bind(wx.EVT_BUTTON, lambda e: app.reset_machine(self.steno_engine, self.config)) try: with open(config.target_file, 'rb') as f: self.config.load(f) except InvalidConfigurationError as e: self._show_alert(unicode(e)) self.config.clear() self.steno_engine = app.StenoEngine() self.steno_engine.add_callback( lambda s: wx.CallAfter(self._update_status, s)) self.steno_engine.set_output( Output(self.consume_command, self.steno_engine)) while True: try: app.init_engine(self.steno_engine, self.config) break except InvalidConfigurationError as e: self._show_alert(unicode(e)) dlg = ConfigurationDialog(self.steno_engine, self.config, parent=self) ret = dlg.ShowModal() if ret == wx.ID_CANCEL: self._quit() return self.steno_engine.add_stroke_listener( StrokeDisplayDialog.stroke_handler) if self.config.get_show_stroke_display(): StrokeDisplayDialog.display(self, self.config) pos = (config.get_main_frame_x(), config.get_main_frame_y()) self.SetPosition(pos)
def __init__(self, config): self.config = config # Note: don't set position from config, since it's not yet loaded. wx.Frame.__init__(self, None, title=self.TITLE, style=wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.RESIZE_BOX | wx.MAXIMIZE_BOX)) root = wx.Panel(self, style=wx.DEFAULT_FRAME_STYLE) # Menu Bar MenuBar = wx.MenuBar() self.SetMenuBar(MenuBar) # Application icon icon = wx.Icon(self.PLOVER_ICON_FILE, wx.BITMAP_TYPE_ICO) self.SetIcon(icon) # Configure button. self.configure_button = wx.Button(root, label=self.CONFIGURE_BUTTON_LABEL) self.configure_button.Bind(wx.EVT_BUTTON, self._show_config_dialog) # About button. self.about_button = wx.Button(root, label=self.ABOUT_BUTTON_LABEL) self.about_button.Bind(wx.EVT_BUTTON, self._show_about_dialog) # Status radio buttons. self.radio_output_enable = wx.RadioButton(root, label=self.ENABLE_OUTPUT_LABEL) self.radio_output_enable.Bind(wx.EVT_RADIOBUTTON, lambda e: self.steno_engine.set_is_running(True)) self.radio_output_disable = wx.RadioButton(root, label=self.DISABLE_OUTPUT_LABEL) self.radio_output_disable.Bind(wx.EVT_RADIOBUTTON, lambda e: self.steno_engine.set_is_running(False)) # Machine status. # TODO: Figure out why spinner has darker gray background. self.spinner = wx.animate.GIFAnimationCtrl(root, -1, SPINNER_FILE) self.spinner.GetPlayer().UseBackgroundColour(True) # Need to call this so the size of the control is not # messed up (100x100 instead of 16x16) on Linux... self.spinner.InvalidateBestSize() self.spinner.Hide() self.connected_bitmap = wx.Bitmap(self.CONNECTED_IMAGE_FILE, wx.BITMAP_TYPE_PNG) self.disconnected_bitmap = wx.Bitmap(self.DISCONNECTED_IMAGE_FILE, wx.BITMAP_TYPE_PNG) self.connection_ctrl = wx.StaticBitmap(root, bitmap=self.disconnected_bitmap) border_flag = wx.SizerFlags(1).Border(wx.ALL, self.BORDER) # Create Settings Box settings_sizer = wx.BoxSizer(wx.HORIZONTAL) settings_sizer.AddF(self.configure_button, border_flag.Expand()) settings_sizer.AddF(self.about_button, border_flag.Expand()) # Create Output Status Box box = wx.StaticBox(root, label=self.HEADER_OUTPUT) status_sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) status_sizer.AddF(self.radio_output_enable, border_flag) status_sizer.AddF(self.radio_output_disable, border_flag) # Create Machine Status Box machine_sizer = wx.BoxSizer(wx.HORIZONTAL) center_flag =\ wx.SizerFlags()\ .Align(wx.ALIGN_CENTER_VERTICAL)\ .Border(wx.LEFT | wx.RIGHT, self.BORDER) machine_sizer.AddF(self.spinner, center_flag) machine_sizer.AddF(self.connection_ctrl, center_flag) longest_machine = max(machine_registry.get_all_names(), key=len) longest_state = max((STATE_ERROR, STATE_INITIALIZING, STATE_RUNNING), key=len) longest_machine_status = '%s: %s' % (longest_machine, longest_state) self.machine_status_text = wx.StaticText(root, label=longest_machine_status) machine_sizer.AddF(self.machine_status_text, center_flag) refresh_bitmap = wx.Bitmap(self.REFRESH_IMAGE_FILE, wx.BITMAP_TYPE_PNG) self.reconnect_button = wx.BitmapButton(root, bitmap=refresh_bitmap) machine_sizer.AddF(self.reconnect_button, center_flag) # Assemble main UI global_sizer = wx.GridBagSizer(vgap=self.BORDER, hgap=self.BORDER) global_sizer.Add(settings_sizer, flag=wx.EXPAND, pos=(0, 0), span=(1, 2)) global_sizer.Add(status_sizer, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=self.BORDER, pos=(1, 0), span=(1, 2)) global_sizer.Add(machine_sizer, flag=wx.CENTER | wx.ALIGN_CENTER | wx.EXPAND | wx.LEFT, pos=(2, 0), border=self.BORDER, span=(1, 2)) self.machine_sizer = machine_sizer # Add a border around the entire sizer. border = wx.BoxSizer() border.AddF(global_sizer, wx.SizerFlags(1).Border(wx.ALL, self.BORDER).Expand()) root.SetSizerAndFit(border) border.SetSizeHints(self) self.Bind(wx.EVT_CLOSE, self._quit) self.Bind(wx.EVT_MOVE, self.on_move) self.reconnect_button.Bind(wx.EVT_BUTTON, lambda e: self._reconnect()) try: with open(config.target_file, 'rb') as f: self.config.load(f) except Exception: log.error('loading configuration failed, reseting to default', exc_info=True) self.config.clear() rect = wx.Rect(config.get_main_frame_x(), config.get_main_frame_y(), *self.GetSize()) self.SetRect(AdjustRectToScreen(rect)) self.steno_engine = app.StenoEngine() self.steno_engine.add_callback( lambda s: wx.CallAfter(self._update_status, s)) self.steno_engine.set_output( Output(self.consume_command, self.steno_engine)) self.steno_engine.add_stroke_listener( StrokeDisplayDialog.stroke_handler) if self.config.get_show_stroke_display(): StrokeDisplayDialog.display(self, self.config) self.steno_engine.formatter.add_listener( SuggestionsDisplayDialog.stroke_handler) if self.config.get_show_suggestions_display(): SuggestionsDisplayDialog.display(self, self.config, self.steno_engine) try: app.init_engine(self.steno_engine, self.config) except Exception: log.error('engine initialization failed', exc_info=True) self._show_config_dialog()
def test_engine_bad_mappings(self): with self._setup(system_keymap='invalid'): with self.assertRaises(Exception): app.init_engine(self.engine, self.cfg) self.assertEqual(self.engine.machine, None)