%PDF- %PDF-
| Direktori : /lib/python3/dist-packages/orca/ |
| Current File : //lib/python3/dist-packages/orca/spellcheck.py |
# Orca
#
# Copyright 2014 Igalia, S.L.
#
# Author: Joanmarie Diggs <jdiggs@igalia.com>
#
# 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.
"""Script-customizable support for application spellcheckers."""
__id__ = "$Id$"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2014 Igalia, S.L."
__license__ = "LGPL"
import re
from orca import debug
from orca import focus_manager
from orca import guilabels
from orca import messages
from orca import object_properties
from orca import settings_manager
from orca.ax_object import AXObject
from orca.ax_text import AXText
from orca.ax_utilities import AXUtilities
class SpellCheck:
def __init__(self, script, hasChangeToEntry=True):
self._script = script
self._hasChangeToEntry = hasChangeToEntry
self._window = None
self._errorWidget = None
self._changeToEntry = None
self._suggestionsList = None
self._activated = False
self._documentPosition = None, -1
self.spellErrorCheckButton = None
self.spellSuggestionCheckButton = None
self.presentContextCheckButton = None
def activate(self, window):
tokens = ["SPELL CHECK: Attempting activation for", window]
debug.printTokens(debug.LEVEL_INFO, tokens, True)
if not self._isCandidateWindow(window):
tokens = ["SPELL CHECK:", window, "is not spellcheck window"]
debug.printTokens(debug.LEVEL_INFO, tokens, True)
return False
if self._hasChangeToEntry:
self._changeToEntry = self._findChangeToEntry(window)
if not self._changeToEntry:
msg = 'SPELL CHECK: Change-to entry not found'
debug.printMessage(debug.LEVEL_INFO, msg, True)
return False
self._errorWidget = self._findErrorWidget(window)
if not self._errorWidget:
msg = 'SPELL CHECK: Error widget not found'
debug.printMessage(debug.LEVEL_INFO, msg, True)
return False
self._suggestionsList = self._findSuggestionsList(window)
if not self._suggestionsList:
msg = 'SPELL CHECK: Suggestions list not found'
debug.printMessage(debug.LEVEL_INFO, msg, True)
return False
self._window = window
self._activated = True
msg = 'SPELL CHECK: Activation complete'
debug.printMessage(debug.LEVEL_INFO, msg, True)
return True
def deactivate(self):
self._clearState()
def getDocumentPosition(self):
return self._documentPosition
def setDocumentPosition(self, obj, offset):
self._documentPosition = obj, offset
def getErrorWidget(self):
return self._errorWidget
def getMisspelledWord(self):
if not self._errorWidget:
return ""
return self._script.utilities.displayedText(self._errorWidget)
def getCompletionMessage(self):
if not self._errorWidget:
return ""
return self._script.utilities.displayedText(self._errorWidget)
def getChangeToEntry(self):
return self._changeToEntry
def getSuggestionsList(self):
return self._suggestionsList
def isActive(self):
return self._activated
def isCheckWindow(self, window):
if window and window == self._window:
return True
return self.activate(window)
def isComplete(self):
return not AXUtilities.is_sensitive(self._changeToEntry)
def isAutoFocusEvent(self, event):
return False
def isSuggestionsItem(self, obj):
if not self._suggestionsList:
return False
return obj and AXObject.get_parent(obj) == self._suggestionsList
def presentContext(self):
if not self.isActive():
return False
obj, offset = self._documentPosition
if not (obj and offset >= 0):
return False
# This should work, but some toolkits are broken.
string = AXText.get_sentence_at_offset(obj, offset)[0]
if not string:
string = AXText.get_line_at_offset(obj, offset)[0]
sentences = re.split(r'(?:\.|\!|\?)', string)
word = self.getMisspelledWord()
if string.count(word) == 1:
match = list(filter(lambda x: x.count(word), sentences))
string = match[0]
if not string:
return False
msg = messages.MISSPELLED_WORD_CONTEXT % string
voice = self._script.speechGenerator.voice(string=msg)
self._script.speakMessage(msg, voice=voice)
return True
def presentCompletionMessage(self):
if not (self.isActive() and self.isComplete()):
return False
self._script.clearBraille()
msg = self.getCompletionMessage()
voice = self._script.speechGenerator.voice(string=msg)
self._script.presentMessage(msg, voice=voice)
return True
def presentErrorDetails(self, detailed=False):
if self.isComplete():
return False
if self.presentMistake(detailed):
self.presentSuggestion(detailed)
if detailed or settings_manager.getManager().getSetting('spellcheckPresentContext'):
self.presentContext()
return True
return False
def presentMistake(self, detailed=False):
if not self.isActive():
return False
word = self.getMisspelledWord()
if not word:
return False
msg = messages.MISSPELLED_WORD % word
voice = self._script.speechGenerator.voice(string=msg)
self._script.speakMessage(msg, voice=voice)
if detailed or settings_manager.getManager().getSetting('spellcheckSpellError'):
self._script.spellCurrentItem(word)
return True
def presentSuggestion(self, detailed=False):
if not self._hasChangeToEntry:
return self.presentSuggestionListItem(detailed, includeLabel=True)
if not self.isActive():
return False
entry = self._changeToEntry
if not entry:
return False
label = self._script.utilities.displayedLabel(entry) or AXObject.get_name(entry)
string = self._script.utilities.substring(entry, 0, -1)
msg = f"{label} {string}"
voice = self._script.speechGenerator.voice(string=msg)
self._script.speakMessage(msg, voice=voice)
if detailed or settings_manager.getManager().getSetting('spellcheckSpellSuggestion'):
self._script.spellCurrentItem(string)
return True
def presentSuggestionListItem(self, detailed=False, includeLabel=False):
if not self.isActive():
return False
suggestions = self._suggestionsList
if not suggestions:
return False
items = self._script.utilities.selectedChildren(suggestions)
if not len(items) == 1:
return False
if includeLabel:
label = self._script.utilities.displayedLabel(suggestions) \
or AXObject.get_name(suggestions)
else:
label = ""
string = AXObject.get_name(items[0])
msg = f"{label} {string}"
voice = self._script.speechGenerator.voice(string=msg)
self._script.speakMessage(msg.strip(), voice=voice)
if detailed or settings_manager.getManager().getSetting('spellcheckSpellSuggestion'):
self._script.spellCurrentItem(string)
if settings_manager.getManager().getSetting('enablePositionSpeaking') \
and items[0] == focus_manager.getManager().get_locus_of_focus():
index, total = self._getSuggestionIndexAndPosition(items[0])
msg = object_properties.GROUP_INDEX_SPEECH % {"index": index, "total": total}
self._script.speakMessage(msg)
return True
def _clearState(self):
self._window = None
self._errorWidget = None
self._changeToEntry = None
self._suggestionsList = None
self._activated = False
def _isCandidateWindow(self, window):
return False
def _findChangeToEntry(self, root):
return None
def _findErrorWidget(self, root):
return None
def _findSuggestionsList(self, root):
return None
def _getSuggestionIndexAndPosition(self, suggestion):
return -1, -1
def getAppPreferencesGUI(self):
from gi.repository import Gtk
frame = Gtk.Frame()
label = Gtk.Label(label=f"<b>{guilabels.SPELL_CHECK}</b>")
label.set_use_markup(True)
frame.set_label_widget(label)
alignment = Gtk.Alignment.new(0.5, 0.5, 1, 1)
alignment.set_padding(0, 0, 12, 0)
frame.add(alignment)
grid = Gtk.Grid()
alignment.add(grid)
label = guilabels.SPELL_CHECK_SPELL_ERROR
value = settings_manager.getManager().getSetting('spellcheckSpellError')
self.spellErrorCheckButton = Gtk.CheckButton.new_with_mnemonic(label)
self.spellErrorCheckButton.set_active(value)
grid.attach(self.spellErrorCheckButton, 0, 0, 1, 1)
label = guilabels.SPELL_CHECK_SPELL_SUGGESTION
value = settings_manager.getManager().getSetting('spellcheckSpellSuggestion')
self.spellSuggestionCheckButton = Gtk.CheckButton.new_with_mnemonic(label)
self.spellSuggestionCheckButton.set_active(value)
grid.attach(self.spellSuggestionCheckButton, 0, 1, 1, 1)
label = guilabels.SPELL_CHECK_PRESENT_CONTEXT
value = settings_manager.getManager().getSetting('spellcheckPresentContext')
self.presentContextCheckButton = Gtk.CheckButton.new_with_mnemonic(label)
self.presentContextCheckButton.set_active(value)
grid.attach(self.presentContextCheckButton, 0, 2, 1, 1)
return frame
def getPreferencesFromGUI(self):
"""Returns a dictionary with the app-specific preferences."""
return {
'spellcheckSpellError': self.spellErrorCheckButton.get_active(),
'spellcheckSpellSuggestion': self.spellSuggestionCheckButton.get_active(),
'spellcheckPresentContext': self.presentContextCheckButton.get_active()
}