Пример #1
0
def main(config):

    handler_class = None
    try:
        if sys.platform.startswith('linux'):
            from plover.oslayer.log_dbus import DbusNotificationHandler
            handler_class = DbusNotificationHandler
        elif sys.platform.startswith('darwin'):
            from plover.oslayer.log_osx import OSXNotificationHandler
            handler_class = OSXNotificationHandler
    except Exception:
        log.info('could not import platform gui log', exc_info=True)
    if handler_class is not None:
        try:
            handler = handler_class()
        except Exception:
            log.info('could not initialize platform gui log', exc_info=True)
        else:
            log.add_handler(handler)

    engine = Engine(config, KeyboardEmulation())
    if not engine.load_config():
        return 3
    quitting = Event()
    engine.hook_connect('quit', quitting.set)
    engine.start()
    try:
        quitting.wait()
    except KeyboardInterrupt:
        pass
    engine.quit()
    engine.join()

    return 0
Пример #2
0
def main(config):

    use_qt_notifications = True
    handler_class = None
    try:
        if sys.platform.startswith('linux'):
            from plover.oslayer.log_dbus import DbusNotificationHandler
            handler_class = DbusNotificationHandler
        elif sys.platform.startswith('darwin'):
            from plover.oslayer.log_osx import OSXNotificationHandler
            handler_class = OSXNotificationHandler
    except Exception:
        log.info('could not import platform gui log', exc_info=True)
    if handler_class is not None:
        try:
            handler = handler_class()
        except Exception:
            log.info('could not initialize platform gui log', exc_info=True)
        else:
            log.add_handler(handler)
            use_qt_notifications = False

    # Setup internationalization support.
    install_gettext()

    app = Application(config, use_qt_notifications)
    app.run()
    del app

    return 0
Пример #3
0
def main(config: Config, controller=None):
    # this screws things up
    # hax tho
    log.remove_handler(__logger._print_handler)

    # mor hax ... I don't wanna see QT notifications
    log.remove_handler(__logger._platform_handler)
    __logger._platform_handler = None

    for option in console_ui_options:
        config._OPTIONS[option.name] = option

    engine = ConsoleEngine(config, KeyboardEmulation(), layout, controller)

    if not engine.load_config():
        return 3

    engine.hook_connect(
        "config_changed",
        partial(config_saver, config, layout.output_to_console),
    )

    notification_handler.set_output(layout.output_to_console)
    notification_handler.setLevel(engine.config["console_ui_loglevel"])
    log.add_handler(notification_handler)

    if engine.config["show_suggestions_display"]:
        layout.toggle_suggestions()

    if engine.config["show_stroke_display"]:
        layout.toggle_tape()

    fg = engine.config["console_ui_fg"]
    bg = engine.config["console_ui_bg"]

    application.style = create_style(fg, bg)

    quitting = Event()
    engine.hook_connect("quit", quitting.set)

    engine.start()
    code = application.run()

    engine.quit()
    quitting.wait()
    engine.join()
    return code
Пример #4
0
 def __init__(self, engine, use_qt_notifications):
     super(MainWindow, self).__init__()
     self.setupUi(self)
     if hasattr(self, 'setUnifiedTitleAndToolBarOnMac'):
         self.setUnifiedTitleAndToolBarOnMac(True)
     self._engine = engine
     self._active_dialogs = {}
     self._dialog_class = {
         'about'             : AboutDialog,
         'configuration'     : ConfigWindow,
     }
     all_actions = find_menu_actions(self.menubar)
     # Dictionaries.
     self.dictionaries = DictionariesWidget(engine)
     self.dictionaries.add_translation.connect(self._add_translation)
     self.scroll_area.setWidget(self.dictionaries)
     self.dictionaries.setFocus()
     edit_menu = all_actions['menu_Edit'].menu()
     edit_menu.addAction(self.dictionaries.action_Undo)
     edit_menu.addSeparator()
     edit_menu.addAction(self.dictionaries.action_AddDictionaries)
     edit_menu.addAction(self.dictionaries.action_EditDictionaries)
     edit_menu.addAction(self.dictionaries.action_RemoveDictionaries)
     edit_menu.addSeparator()
     edit_menu.addAction(self.dictionaries.action_MoveDictionariesUp)
     edit_menu.addAction(self.dictionaries.action_MoveDictionariesDown)
     # Tray icon.
     self._trayicon = TrayIcon()
     self._trayicon.enable()
     self._trayicon.clicked.connect(self._engine.toggle_output)
     if use_qt_notifications:
         handler = NotificationHandler()
         handler.emitSignal.connect(self._trayicon.log)
         log.add_handler(handler)
     popup_menu = QMenu()
     for action_name in (
         'action_ToggleOutput',
         'action_Reconnect',
         '',
         'menu_Tools',
         '',
         'action_Configure',
         '',
         'menu_Help',
         '',
         'action_Show',
         'action_Quit',
     ):
         if action_name:
             popup_menu.addAction(all_actions[action_name])
         else:
             popup_menu.addSeparator()
     self._trayicon.set_menu(popup_menu)
     engine.signal_connect('machine_state_changed', self._trayicon.update_machine_state)
     engine.signal_connect('quit', self.on_quit)
     self.action_Quit.triggered.connect(engine.quit)
     # Populate tools bar/menu.
     tools_menu = all_actions['menu_Tools'].menu()
     # Toolbar popup menu for selecting which tools are shown.
     self.toolbar_menu = QMenu()
     self.toolbar.setContextMenuPolicy(Qt.CustomContextMenu)
     self.toolbar.customContextMenuRequested.connect(
         lambda: self.toolbar_menu.popup(QCursor.pos())
     )
     for tool_plugin in registry.list_plugins('gui.qt.tool'):
         tool = tool_plugin.obj
         action_parameters = []
         if tool.ICON is not None:
             icon = tool.ICON
             # Internal QT resources start with a `:`.
             if not icon.startswith(':'):
                 icon = resource_filename(icon)
             action_parameters.append(QIcon(icon))
         action_parameters.append(tool.TITLE)
         toolbar_action = None
         for parent in (tools_menu, self.toolbar, self.toolbar_menu):
             action = parent.addAction(*action_parameters)
             action.setObjectName(tool_plugin.name)
             if tool.__doc__ is not None:
                 action.setToolTip(tool.__doc__)
             if tool.SHORTCUT is not None:
                 action.setShortcut(QKeySequence.fromString(tool.SHORTCUT))
             if parent == self.toolbar_menu:
                 action.setCheckable(True)
                 action.setChecked(True)
                 assert toolbar_action is not None
                 action.toggled.connect(toolbar_action.setVisible)
             else:
                 if parent == self.toolbar:
                     toolbar_action = action
                 action.triggered.connect(partial(self._activate_dialog,
                                                  tool_plugin.name,
                                                  args=()))
         self._dialog_class[tool_plugin.name] = tool
     engine.signal_connect('output_changed', self.on_output_changed)
     # Machine.
     self.machine_type.addItems(
         _(plugin.name)
         for plugin in registry.list_plugins('machine')
     )
     engine.signal_connect('config_changed', self.on_config_changed)
     engine.signal_connect('machine_state_changed',
         lambda machine, state:
         self.machine_state.setText(_(state.capitalize()))
     )
     self.restore_state()
     # Commands.
     engine.signal_connect('add_translation', partial(self._add_translation, manage_windows=True))
     engine.signal_connect('focus', self._focus)
     engine.signal_connect('configure', partial(self._configure, manage_windows=True))
     engine.signal_connect('lookup', partial(self._activate_dialog, 'lookup',
                                             manage_windows=True))
     # Load the configuration (but do not start the engine yet).
     if not engine.load_config():
         self.on_configure()
     # Apply configuration settings.
     config = self._engine.config
     self.machine_type.setCurrentText(config['machine_type'])
     self._configured = False
     self.dictionaries.on_config_changed(config)
     self.set_visible(not config['start_minimized'])
     # Start the engine.
     engine.start()
Пример #5
0
import sys
from plover import log

handler = None

try:
    if sys.platform.startswith('linux'):
        from plover.oslayer.log_dbus import DbusNotificationHandler
        handler_class = DbusNotificationHandler
    elif sys.platform.startswith('darwin'):
        from plover.oslayer.log_osx import OSXNotificationHandler
        handler_class = OSXNotificationHandler
except Exception:
    log.warning('could not import platform gui log', exc_info=True)
else:
    try:
        handler = handler_class()
    except Exception:
        log.error('could not initialize platform gui log', exc_info=True)

if handler is None:
    from plover.gui.log_wx import WxNotificationHandler
    handler = WxNotificationHandler()

log.add_handler(handler)
Пример #6
0
import sys
from plover import log


handler = None

try:
    if sys.platform.startswith('linux'):
        from plover.oslayer.log_dbus import DbusNotificationHandler
        handler_class = DbusNotificationHandler
    elif sys.platform.startswith('darwin'):
        from plover.oslayer.log_osx import OSXNotificationHandler
        handler_class = OSXNotificationHandler
except Exception:
    log.warning('could not import platform gui log', exc_info=True)
else:
    try:
        handler = handler_class()
    except Exception:
        log.error('could not initialize platform gui log', exc_info=True)

if handler is None:
    from plover.gui.log_wx import WxNotificationHandler
    handler = WxNotificationHandler()

log.add_handler(handler)
Пример #7
0
import sys
from plover import log


handler = None

try:
    if sys.platform.startswith('linux'):
        from plover.oslayer.log_dbus import DbusNotificationHandler
        handler = DbusNotificationHandler
    elif sys.platform.startswith('darwin'):
        from plover.oslayer.log_osx import OSXNotificationHandler
        handler = OSXNotificationHandler
except Exception as e:
    log.info('could not import platform gui log', exc_info=e)

if handler is None:
    from plover.gui.log_wx import WxNotificationHandler
    handler = WxNotificationHandler

log.add_handler(handler())
Пример #8
0
 def __init__(self, engine, use_qt_notifications):
     super(MainWindow, self).__init__()
     self.setupUi(self)
     if hasattr(self, 'setUnifiedTitleAndToolBarOnMac'):
         self.setUnifiedTitleAndToolBarOnMac(True)
     self._engine = engine
     self._active_dialogs = {}
     self._dialog_class = {
         'about'             : AboutDialog,
         'configuration'     : ConfigWindow,
     }
     all_actions = find_menu_actions(self.menubar)
     # Dictionaries.
     self.dictionaries = self.scroll_area.widget()
     self.dictionaries.add_translation.connect(self._add_translation)
     self.dictionaries.setFocus()
     edit_menu = all_actions['menu_Edit'].menu()
     edit_menu.addAction(self.dictionaries.action_Undo)
     edit_menu.addSeparator()
     edit_menu.addMenu(self.dictionaries.menu_AddDictionaries)
     edit_menu.addAction(self.dictionaries.action_EditDictionaries)
     edit_menu.addAction(self.dictionaries.action_RemoveDictionaries)
     edit_menu.addSeparator()
     edit_menu.addAction(self.dictionaries.action_MoveDictionariesUp)
     edit_menu.addAction(self.dictionaries.action_MoveDictionariesDown)
     # Tray icon.
     self._trayicon = TrayIcon()
     self._trayicon.enable()
     self._trayicon.clicked.connect(self._engine.toggle_output)
     if use_qt_notifications:
         handler = NotificationHandler()
         handler.emitSignal.connect(self._trayicon.log)
         log.add_handler(handler)
     popup_menu = QMenu()
     for action_name in (
         'action_ToggleOutput',
         'action_Reconnect',
         '',
         'menu_Tools',
         '',
         'action_Configure',
         '',
         'menu_Help',
         '',
         'action_Show',
         'action_Quit',
     ):
         if action_name:
             popup_menu.addAction(all_actions[action_name])
         else:
             popup_menu.addSeparator()
     self._trayicon.set_menu(popup_menu)
     engine.signal_connect('machine_state_changed', self._trayicon.update_machine_state)
     engine.signal_connect('quit', self.on_quit)
     self.action_Quit.triggered.connect(engine.quit)
     # Populate tools bar/menu.
     tools_menu = all_actions['menu_Tools'].menu()
     # Toolbar popup menu for selecting which tools are shown.
     self.toolbar_menu = QMenu()
     self.toolbar.setContextMenuPolicy(Qt.CustomContextMenu)
     self.toolbar.customContextMenuRequested.connect(
         lambda: self.toolbar_menu.popup(QCursor.pos())
     )
     for tool_plugin in registry.list_plugins('gui.qt.tool'):
         tool = tool_plugin.obj
         action_parameters = []
         if tool.ICON is not None:
             icon = tool.ICON
             # Internal QT resources start with a `:`.
             if not icon.startswith(':'):
                 icon = resource_filename(icon)
             action_parameters.append(QIcon(icon))
         action_parameters.append(tool.TITLE)
         toolbar_action = None
         for parent in (tools_menu, self.toolbar, self.toolbar_menu):
             action = parent.addAction(*action_parameters)
             action.setObjectName(tool_plugin.name)
             if tool.__doc__ is not None:
                 action.setToolTip(tool.__doc__)
             if tool.SHORTCUT is not None:
                 action.setShortcut(QKeySequence.fromString(tool.SHORTCUT))
             if parent == self.toolbar_menu:
                 action.setCheckable(True)
                 action.setChecked(True)
                 assert toolbar_action is not None
                 action.toggled.connect(toolbar_action.setVisible)
             else:
                 if parent == self.toolbar:
                     toolbar_action = action
                 action.triggered.connect(partial(self._activate_dialog,
                                                  tool_plugin.name,
                                                  args=()))
         self._dialog_class[tool_plugin.name] = tool
     engine.signal_connect('output_changed', self.on_output_changed)
     # Machine.
     self.machine_type.addItems(
         _(plugin.name)
         for plugin in registry.list_plugins('machine')
     )
     engine.signal_connect('config_changed', self.on_config_changed)
     engine.signal_connect('machine_state_changed',
         lambda machine, state:
         self.machine_state.setText(_(state.capitalize()))
     )
     self.restore_state()
     # Commands.
     engine.signal_connect('add_translation', partial(self._add_translation, manage_windows=True))
     engine.signal_connect('focus', self._focus)
     engine.signal_connect('configure', partial(self._configure, manage_windows=True))
     engine.signal_connect('lookup', partial(self._activate_dialog, 'lookup',
                                             manage_windows=True))
     # Load the configuration (but do not start the engine yet).
     if not engine.load_config():
         self.on_configure()
     # Apply configuration settings.
     config = self._engine.config
     self.machine_type.setCurrentText(config['machine_type'])
     self._configured = False
     self.dictionaries.on_config_changed(config)
     self.set_visible(not config['start_minimized'])
     # Start the engine.
     engine.start()
Пример #9
0

def _notify(level, message):
    nm = wx.NotificationMessage()
    nm.SetTitle(__software_name__.capitalize())
    nm.SetMessage(message)
    if level <= log.INFO:
        flags = wx.ICON_INFORMATION
    elif level <= log.WARNING:
        flags = wx.ICON_WARNING
    else:
        flags = wx.ICON_ERROR
    nm.SetFlags(flags)
    nm.Show()

class WxNotificationHandler(logging.Handler):
    """ Handler using wx.NotificationMessage to show messages. """

    def __init__(self):
        super(WxNotificationHandler, self).__init__()
        self.setLevel(log.WARNING)
        self.setFormatter(log.NoExceptionTracebackFormatter('%(levelname)s: %(message)s'))

    def emit(self, record):
        level = record.levelno
        message = self.format(record)
        wx.CallAfter(_notify, level, message)

log.add_handler(WxNotificationHandler())

Пример #10
0
 def __init__(self, engine, use_qt_notifications):
     super().__init__()
     self.setupUi(self)
     if hasattr(self, 'setUnifiedTitleAndToolBarOnMac'):
         self.setUnifiedTitleAndToolBarOnMac(True)
     self._engine = engine
     self._active_dialogs = {}
     self._dialog_class = {
         'about': AboutDialog,
         'configuration': ConfigWindow,
     }
     all_actions = find_menu_actions(self.menubar)
     # Dictionaries.
     self.dictionaries.add_translation.connect(self._add_translation)
     self.dictionaries.setup(engine)
     # Populate edit menu from dictionaries' own.
     edit_menu = all_actions['menu_Edit'].menu()
     for action in self.dictionaries.edit_menu.actions():
         edit_menu.addAction(action)
     # Tray icon.
     self._trayicon = TrayIcon()
     self._trayicon.enable()
     self._trayicon.clicked.connect(self._engine.toggle_output)
     if use_qt_notifications:
         handler = NotificationHandler()
         handler.emitSignal.connect(self._trayicon.log)
         log.add_handler(handler)
     popup_menu = QMenu()
     for action_name in (
             'action_ToggleOutput',
             'action_Reconnect',
             '',
             'menu_Tools',
             '',
             'action_Configure',
             'action_OpenConfigFolder',
             '',
             'menu_Help',
             '',
             'action_Show',
             'action_Quit',
     ):
         if action_name:
             popup_menu.addAction(all_actions[action_name])
         else:
             popup_menu.addSeparator()
     self._trayicon.set_menu(popup_menu)
     engine.signal_connect('machine_state_changed',
                           self._trayicon.update_machine_state)
     engine.signal_connect('quit', self.on_quit)
     self.action_Quit.triggered.connect(engine.quit)
     # Toolbar popup menu for selecting which tools are shown.
     self.toolbar_menu = QMenu()
     self.toolbar.setContextMenuPolicy(Qt.CustomContextMenu)
     self.toolbar.customContextMenuRequested.connect(
         lambda: self.toolbar_menu.popup(QCursor.pos()))
     # Populate tools bar/menu.
     tools_menu = all_actions['menu_Tools'].menu()
     for tool_plugin in registry.list_plugins('gui.qt.tool'):
         tool = tool_plugin.obj
         menu_action = tools_menu.addAction(tool.TITLE)
         if tool.SHORTCUT is not None:
             menu_action.setShortcut(QKeySequence.fromString(tool.SHORTCUT))
         if tool.ICON is not None:
             icon = tool.ICON
             # Internal QT resources start with a `:`.
             if not icon.startswith(':'):
                 icon = resource_filename(icon)
             menu_action.setIcon(QIcon(icon))
         menu_action.triggered.connect(
             partial(self._activate_dialog, tool_plugin.name, args=()))
         toolbar_action = self.toolbar.addAction(menu_action.icon(),
                                                 menu_action.text())
         if tool.__doc__ is not None:
             toolbar_action.setToolTip(tool.__doc__)
         toolbar_action.triggered.connect(menu_action.trigger)
         toggle_action = self.toolbar_menu.addAction(
             menu_action.icon(), menu_action.text())
         toggle_action.setObjectName(tool_plugin.name)
         toggle_action.setCheckable(True)
         toggle_action.setChecked(True)
         toggle_action.toggled.connect(toolbar_action.setVisible)
         self._dialog_class[tool_plugin.name] = tool
     engine.signal_connect('output_changed', self.on_output_changed)
     # Machine.
     for plugin in registry.list_plugins('machine'):
         self.machine_type.addItem(_(plugin.name), plugin.name)
     engine.signal_connect('config_changed', self.on_config_changed)
     engine.signal_connect(
         'machine_state_changed',
         lambda machine, state: self.machine_state.setText(state.capitalize(
         )))
     self.restore_state()
     # Commands.
     engine.signal_connect(
         'add_translation',
         partial(self._add_translation, manage_windows=True))
     engine.signal_connect('focus', self._focus)
     engine.signal_connect('configure',
                           partial(self._configure, manage_windows=True))
     engine.signal_connect(
         'lookup',
         partial(self._activate_dialog, 'lookup', manage_windows=True))
     engine.signal_connect(
         'suggestions',
         partial(self._activate_dialog, 'suggestions', manage_windows=True))
     # Load the configuration (but do not start the engine yet).
     if not engine.load_config():
         self.on_configure()
     # Apply configuration settings.
     config = self._engine.config
     self._warn_on_hide_to_tray = not config['start_minimized']
     self._update_machine(config['machine_type'])
     self._configured = False
     self.set_visible(not config['start_minimized'])
     # Process events before starting the engine
     # (to avoid display lag at window creation).
     QCoreApplication.processEvents()
     # Start the engine.
     engine.start()
Пример #11
0
 def __init__(self, engine, use_qt_notifications):
     super(MainWindow, self).__init__()
     self.setupUi(self)
     if hasattr(self, 'setUnifiedTitleAndToolBarOnMac'):
         self.setUnifiedTitleAndToolBarOnMac(True)
     self._engine = engine
     self._active_dialogs = {}
     self._dialog_class = {
         'about': AboutDialog,
         'add_translation': AddTranslation,
         'configuration': ConfigWindow,
         'lookup': LookupDialog,
         'paper_tape': PaperTape,
         'suggestions': SuggestionsDialog,
     }
     self.action_Quit.triggered.connect(QCoreApplication.quit)
     all_actions = find_menu_actions(self.menubar)
     # Dictionaries.
     self.dictionaries = DictionariesWidget(engine)
     self.dictionaries.add_translation.connect(self._add_translation)
     self.scroll_area.setWidget(self.dictionaries)
     self.dictionaries.setFocus()
     edit_menu = all_actions['menu_Edit'].menu()
     edit_menu.addAction(self.dictionaries.action_Undo)
     edit_menu.addSeparator()
     edit_menu.addAction(self.dictionaries.action_AddDictionaries)
     edit_menu.addAction(self.dictionaries.action_EditDictionaries)
     edit_menu.addAction(self.dictionaries.action_RemoveDictionaries)
     edit_menu.addSeparator()
     edit_menu.addAction(self.dictionaries.action_MoveDictionariesUp)
     edit_menu.addAction(self.dictionaries.action_MoveDictionariesDown)
     # Tray icon.
     self._trayicon = TrayIcon()
     self._trayicon.enable()
     self._trayicon.clicked.connect(self._engine.toggle_output)
     if use_qt_notifications:
         handler = NotificationHandler()
         handler.emitSignal.connect(self._trayicon.log)
         log.add_handler(handler)
     popup_menu = QMenu()
     for action_name in (
             'action_ToggleOutput',
             'action_Reconnect',
             '',
             'menu_Tools',
             '',
             'action_Configure',
             '',
             'menu_Help',
             '',
             'action_ShowHide',
             'action_Quit',
     ):
         if action_name:
             popup_menu.addAction(all_actions[action_name])
         else:
             popup_menu.addSeparator()
     self._trayicon.set_menu(popup_menu)
     engine.signal_connect('machine_state_changed',
                           self._trayicon.update_machine_state)
     engine.signal_connect('output_changed', self.on_output_changed)
     # Machine.
     self.machine_type.addItems(
         _(machine) for machine in engine.list_plugins('machine'))
     engine.signal_connect('config_changed', self.on_config_changed)
     engine.signal_connect(
         'machine_state_changed',
         lambda machine, state: self.machine_state.setText(
             _(state.capitalize())))
     self.restore_state()
     # Commands.
     engine.signal_connect(
         'add_translation',
         partial(self._add_translation, manage_windows=True))
     engine.signal_connect('focus', self._focus)
     engine.signal_connect('configure',
                           partial(self._configure, manage_windows=True))
     engine.signal_connect('lookup',
                           partial(self._lookup, manage_windows=True))
     # Load the configuration (but do not start the engine yet).
     if not engine.load_config():
         self.on_configure()
     # Apply configuration settings.
     config = self._engine.config
     self.on_config_changed(config)
     self.dictionaries.on_config_changed(config)
     self.set_visible(not config['start_minimized'])
     if config['show_suggestions_display']:
         self.on_suggestions()
     if config['show_stroke_display']:
         self.on_paper_tape()
     # Start the engine.
     engine.start()
Пример #12
0
import sys
from plover import log

handler = None

try:
    if sys.platform.startswith('linux'):
        from plover.gui.log_dbus import DbusNotificationHandler
        handler = DbusNotificationHandler
    elif sys.platform.startswith('darwin'):
        from plover.gui.log_osx import OSXNotificationHandler
        handler = OSXNotificationHandler
except Exception as e:
    log.info('could not import platform gui log', exc_info=e)

if handler is None:
    from plover.gui.log_wx import WxNotificationHandler
    handler = WxNotificationHandler

log.add_handler(handler())
Пример #13
0
 def __init__(self, engine, use_qt_notifications):
     super(MainWindow, self).__init__()
     self.setupUi(self)
     if hasattr(self, 'setUnifiedTitleAndToolBarOnMac'):
         self.setUnifiedTitleAndToolBarOnMac(True)
     self._engine = engine
     self._active_dialogs = {}
     self._dialog_class = {
         'about'             : AboutDialog,
         'add_translation'   : AddTranslation,
         'configuration'     : ConfigWindow,
         'lookup'            : LookupDialog,
         'paper_tape'        : PaperTape,
         'suggestions'       : SuggestionsDialog,
     }
     self.action_Quit.triggered.connect(QCoreApplication.quit)
     all_actions = find_menu_actions(self.menubar)
     # Dictionaries.
     self.dictionaries = DictionariesWidget(engine)
     self.dictionaries.add_translation.connect(self._add_translation)
     self.scroll_area.setWidget(self.dictionaries)
     self.dictionaries.setFocus()
     edit_menu = all_actions['menu_Edit'].menu()
     edit_menu.addAction(self.dictionaries.action_Undo)
     edit_menu.addSeparator()
     edit_menu.addAction(self.dictionaries.action_AddDictionaries)
     edit_menu.addAction(self.dictionaries.action_EditDictionaries)
     edit_menu.addAction(self.dictionaries.action_RemoveDictionaries)
     edit_menu.addSeparator()
     edit_menu.addAction(self.dictionaries.action_MoveDictionariesUp)
     edit_menu.addAction(self.dictionaries.action_MoveDictionariesDown)
     # Tray icon.
     self._trayicon = TrayIcon()
     self._trayicon.enable()
     self._trayicon.clicked.connect(self._engine.toggle_output)
     if use_qt_notifications:
         handler = NotificationHandler()
         handler.emitSignal.connect(self._trayicon.log)
         log.add_handler(handler)
     popup_menu = QMenu()
     for action_name in (
         'action_ToggleOutput',
         'action_Reconnect',
         '',
         'menu_Tools',
         '',
         'action_Configure',
         '',
         'menu_Help',
         '',
         'action_ShowHide',
         'action_Quit',
     ):
         if action_name:
             popup_menu.addAction(all_actions[action_name])
         else:
             popup_menu.addSeparator()
     self._trayicon.set_menu(popup_menu)
     engine.signal_connect('machine_state_changed', self._trayicon.update_machine_state)
     engine.signal_connect('output_changed', self.on_output_changed)
     # Machine.
     self.machine_type.addItems(_(machine) for machine in engine.machines)
     engine.signal_connect('config_changed', self.on_config_changed)
     engine.signal_connect('machine_state_changed',
         lambda machine, state:
         self.machine_state.setText(_(state.capitalize()))
     )
     self.restore_state()
     # Commands.
     engine.signal_connect('add_translation', partial(self._add_translation, manage_windows=True))
     engine.signal_connect('focus', self._focus)
     engine.signal_connect('configure', partial(self._configure, manage_windows=True))
     engine.signal_connect('lookup', partial(self._lookup, manage_windows=True))
     # Load the configuration (but do not start the engine yet).
     if not engine.load_config():
         self.on_configure()
     # Apply configuration settings.
     config = self._engine.config
     self.on_config_changed(config)
     self.dictionaries.on_config_changed(config)
     self.set_visible(not config['start_minimized'])
     if config['show_suggestions_display']:
         self.on_suggestions()
     if config['show_stroke_display']:
         self.on_paper_tape()
     # Start the engine.
     engine.start()