%PDF- %PDF-
Direktori : /usr/lib/python3/dist-packages/orca/ |
Current File : //usr/lib/python3/dist-packages/orca/learn_mode_presenter.py |
# Orca # # Copyright 2005-2008 Sun Microsystems Inc. # Copyright 2016-2023 Igalia, S.L. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., Franklin Street, Fifth Floor, # Boston MA 02110-1301 USA. """Module for learn mode""" __id__ = "$Id$" __version__ = "$Revision$" __date__ = "$Date$" __copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ "Copyright (c) 2016-2023 Igalia, S.L." __license__ = "LGPL" import gi gi.require_version("Atspi", "2.0") gi.require_version("Gdk", "3.0") gi.require_version("Gtk", "3.0") from gi.repository import Atspi from gi.repository import Gdk from gi.repository import GObject from gi.repository import Gtk from . import cmdnames from . import debug from . import guilabels from . import input_event from . import keybindings from . import messages from . import orca_state from . import script_manager from . import settings from . import settings_manager from .ax_object import AXObject class LearnModePresenter: """Provides implementation of learn mode""" def __init__(self): self._handlers = self.get_handlers(True) self._bindings = keybindings.KeyBindings() self._is_active = False self._gui = None def is_active(self): """Returns True if we're in learn mode""" return self._is_active def get_bindings(self, refresh=False, is_desktop=True): """Returns the learn-mode-presenter keybindings.""" if refresh: msg = "LEARN MODE PRESENTER: Refreshing bindings." debug.printMessage(debug.LEVEL_INFO, msg, True) self._setup_bindings() elif self._bindings.isEmpty(): self._setup_bindings() return self._bindings def get_handlers(self, refresh=False): """Returns the learn-mode-presenter handlers.""" if refresh: msg = "LEARN MODE PRESENTER: Refreshing handlers." debug.printMessage(debug.LEVEL_INFO, msg, True) self._setup_handlers() return self._handlers def _setup_handlers(self): """Sets up the learn-mode-presenter input event handlers.""" self._handlers = {} self._handlers["enterLearnModeHandler"] = \ input_event.InputEventHandler( self.start, cmdnames.ENTER_LEARN_MODE) msg = "LEARN MODE PRESENTER: Handlers set up." debug.printMessage(debug.LEVEL_INFO, msg, True) def _setup_bindings(self): """Sets up the learn-mode-presenter key bindings.""" self._bindings = keybindings.KeyBindings() self._bindings.add( keybindings.KeyBinding( "h", keybindings.defaultModifierMask, keybindings.ORCA_MODIFIER_MASK, self._handlers.get("enterLearnModeHandler"))) msg = "LEARN MODE PRESENTER: Bindings set up." debug.printMessage(debug.LEVEL_INFO, msg, True) def start(self, script=None, event=None): """Starts learn mode.""" if self._is_active: msg = "LEARN MODE PRESENTER: Start called when already active" debug.printMessage(debug.LEVEL_INFO, msg, True) return True if script is None: script = script_manager.getManager().getActiveScript() if script is not None: script.presentMessage(messages.VERSION) script.speakMessage(messages.LEARN_MODE_START_SPEECH) script.displayBrailleMessage(messages.LEARN_MODE_START_BRAILLE) msg = "LEARN MODE PRESENTER: Grabbing keyboard" debug.printMessage(debug.LEVEL_INFO, msg, True) Atspi.Device.grab_keyboard(orca_state.device) msg = "LEARN MODE PRESENTER: Is now active" debug.printMessage(debug.LEVEL_INFO, msg, True) self._is_active = True return True def quit(self, script=None, event=None): """Quits learn mode.""" if not self._is_active: msg = "LEARN MODE PRESENTER: Quit called when already inactive" debug.printMessage(debug.LEVEL_INFO, msg, True) return True if script is None: script = script_manager.getManager().getActiveScript() if script is not None: script.presentMessage(messages.LEARN_MODE_STOP) msg = "LEARN MODE PRESENTER: Ungrabbing keyboard" debug.printMessage(debug.LEVEL_INFO, msg, True) Atspi.Device.ungrab_keyboard(orca_state.device) msg = "LEARN MODE PRESENTER: Is now inactive" debug.printMessage(debug.LEVEL_INFO, msg, True) self._is_active = False return True def handle_event(self, event=None): """Handles the event if learn mode is active.""" if not self._is_active: return False if not isinstance(event, input_event.KeyboardEvent): return False script = script_manager.getManager().getActiveScript() script.speakKeyEvent(event) if event.isPrintableKey() and event.getClickCount() == 2 \ and event.getHandler() is None: script.phoneticSpellCurrentItem(event.event_string) if event.event_string == "Escape": self.quit(script=None, event=event) return True if event.event_string == "F1" and not event.modifiers: self.show_help(script, event) return True if event.event_string in ["F2", "F3"] and not event.modifiers: self.list_orca_shortcuts(script, event) return True self.present_command(event) return True def present_command(self, event=None): """Presents the command bound to event.""" if not isinstance(event, input_event.KeyboardEvent): return True handler = event.getHandler() if handler is None: return True if handler.learnModeEnabled and handler.description: script = script_manager.getManager().getActiveScript() script.presentMessage(handler.description) return True def list_orca_shortcuts(self, script, event=None): """Shows a simple gui listing Orca's bound commands.""" if event is None: event = orca_state.lastNonModifierKeyEvent layout = settings_manager.getManager().getSetting("keyboardLayout") is_desktop = layout == settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP items = 0 bindings = {} if event is None or event.event_string == "F2": bound = script.getDefaultKeyBindings().getBoundBindings() bindings[guilabels.KB_GROUP_DEFAULT] = bound items += len(bound) bound = script.getLearnModePresenter().get_bindings( is_desktop=is_desktop).getBoundBindings() bindings[guilabels.KB_GROUP_LEARN_MODE] = bound items += len(bound) bound = script.getWhereAmIPresenter().get_bindings( is_desktop=is_desktop).getBoundBindings() bindings[guilabels.KB_GROUP_WHERE_AM_I] = bound items += len(bound) bound = script.getSpeechAndVerbosityManager().get_bindings( is_desktop=is_desktop).getBoundBindings() bindings[guilabels.KB_GROUP_SPEECH_VERBOSITY] = bound items += len(bound) bound = script.getSleepModeManager().get_bindings( is_desktop=is_desktop).getBoundBindings() bindings[guilabels.KB_GROUP_SLEEP_MODE] = bound items += len(bound) bound = script.getFlatReviewPresenter().get_bindings( is_desktop=is_desktop).getBoundBindings() bindings[guilabels.KB_GROUP_FLAT_REVIEW] = bound items += len(bound) bound = script.getObjectNavigator().get_bindings( is_desktop=is_desktop).getBoundBindings() bindings[guilabels.KB_GROUP_OBJECT_NAVIGATION] = bound items += len(bound) bound = script.getTableNavigator().get_bindings( is_desktop=is_desktop).getBoundBindings() bindings[guilabels.KB_GROUP_TABLE_NAVIGATION] = bound items += len(bound) bound = script.getSystemInformationPresenter().get_bindings( is_desktop=is_desktop).getBoundBindings() bindings[guilabels.KB_GROUP_SYSTEM_INFORMATION] = bound items += len(bound) bound = script.getNotificationPresenter().get_bindings( is_desktop=is_desktop).getBoundBindings() bindings[guilabels.KB_GROUP_NOTIFICATIONS] = bound items += len(bound) bound = script.getBookmarks().get_bindings( is_desktop=is_desktop).getBoundBindings() bindings[guilabels.KB_GROUP_BOOKMARKS] = bound items += len(bound) bound = script.getMouseReviewer().get_bindings( is_desktop=is_desktop).getBoundBindings() bindings[guilabels.KB_GROUP_MOUSE_REVIEW] = bound items += len(bound) bound = script.getActionPresenter().get_bindings( is_desktop=is_desktop).getBoundBindings() bindings[guilabels.KB_GROUP_ACTIONS] = bound items += len(bound) title = messages.shortcutsFoundOrca(items) else: app_name = AXObject.get_name(script.app) or messages.APPLICATION_NO_NAME bound = script.getAppKeyBindings().getBoundBindings() bound.extend(script.getToolkitKeyBindings().getBoundBindings()) if bound: bindings[app_name] = bound title = messages.shortcutsFoundApp(len(bound), app_name) if not bindings: script.presentMessage(title) return True self.quit(script, event) column_headers = [guilabels.KB_HEADER_FUNCTION, guilabels.KB_HEADER_KEY_BINDING] self._gui = CommandListGUI(script, title, column_headers, bindings) self._gui.show_gui() return True def show_help(self, script=None, event=None, page=""): """Displays Orca's documentation.""" self.quit(script, event) uri = "help:orca" if page: uri += f"/{page}" Gtk.show_uri(Gdk.Screen.get_default(), uri, Gtk.get_current_event_time()) return True class CommandListGUI: """Shows a list of commands and their bindings.""" def __init__(self, script, title, column_headers, bindings_dict): self._script = script self._model = None self._gui = self._create_dialog(title, column_headers, bindings_dict) def _create_dialog(self, title, column_headers, bindings_dict): """Creates the commands-list dialog.""" dialog = Gtk.Dialog(title, None, Gtk.DialogFlags.MODAL, (Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)) dialog.set_default_size(1000, 800) grid = Gtk.Grid() content_area = dialog.get_content_area() content_area.add(grid) scrolled_window = Gtk.ScrolledWindow() grid.add(scrolled_window) tree = Gtk.TreeView() tree.set_hexpand(True) tree.set_vexpand(True) scrolled_window.add(tree) cols = len(column_headers) * [GObject.TYPE_STRING] for i, header in enumerate(column_headers): cell = Gtk.CellRendererText() column = Gtk.TreeViewColumn(header, cell, text=i) tree.append_column(column) if header: column.set_sort_column_id(i) self._model = Gtk.TreeStore(*cols) for group, bindings in bindings_dict.items(): if not bindings: continue group_iter = self._model.append(None, [group, ""]) for binding in bindings: self._model.append(group_iter, [binding.handler.description, binding.asString()]) tree.set_model(self._model) tree.expand_all() dialog.connect("response", self.on_response) return dialog def on_response(self, dialog, response): """Handler for the 'response' signal.""" if response == Gtk.ResponseType.CLOSE: self._gui.destroy() return def show_gui(self): """Shows the dialog.""" self._gui.show_all() time_stamp = orca_state.lastInputEvent.timestamp if time_stamp == 0: time_stamp = Gtk.get_current_event_time() self._gui.present_with_time(time_stamp) _presenter = LearnModePresenter() def getPresenter(): """Returns the Learn Mode Presenter""" return _presenter