Getting very close to final refactor push. I think one more after this one will do it.

This commit is contained in:
Storm Dragon
2026-01-16 11:14:32 -05:00
parent fde43df2d0
commit 1862de64ee
12 changed files with 232 additions and 113 deletions
+2 -1
View File
@@ -40,6 +40,7 @@ from gi.repository import Atspi
from . import debug
from . import object_properties
from . import role_keys
from .ax_object import AXObject
from .ax_utilities_state import AXUtilitiesState
@@ -386,7 +387,7 @@ class AXUtilitiesRole:
return object_properties.ROLE_PROLOGUE
if AXUtilitiesRole.is_dpub_toc(obj, role):
return object_properties.ROLE_TOC
elif role == "ROLE_DPUB_SECTION":
elif role == role_keys.ROLE_DPUB_SECTION:
if AXUtilitiesRole.is_dpub_abstract(obj, role):
return object_properties.ROLE_ABSTRACT
if AXUtilitiesRole.is_dpub_colophon(obj, role):
+2 -1
View File
@@ -40,6 +40,7 @@ from . import debug
from . import generator
from . import messages
from . import object_properties
from . import role_keys
from . import cthulhu_state
from . import settings
from . import settings_manager
@@ -453,7 +454,7 @@ class BrailleGenerator(generator.Generator):
# We will provide the support for someone to override this,
# however, so we use REAL_ROLE_SCROLL_PANE here.
#
oldRole = self._overrideRole('REAL_ROLE_SCROLL_PANE', args)
oldRole = self._overrideRole(role_keys.REAL_ROLE_SCROLL_PANE, args)
result.extend(self.generate(obj, **args))
self._restoreRole(oldRole, args)
return result
+24 -23
View File
@@ -44,6 +44,7 @@ gi.require_version("Atspi", "2.0")
from gi.repository import Atspi
from . import object_properties
from . import role_keys
TUTORIAL = '(tutorial and (pause + tutorial) or [])'
MNEMONIC = '(mnemonic and (pause + mnemonic + lineBreak) or [])'
@@ -153,7 +154,7 @@ formatting = {
'focused': 'labelOrName + roleName',
'unfocused': 'labelOrName + roleName + pause + currentLineText + allTextSelection',
},
'ROLE_ARTICLE_IN_FEED' : {
role_keys.ROLE_ARTICLE_IN_FEED: {
'unfocused': '(labelOrName or currentLineText or roleName) + pause + positionInList',
},
Atspi.Role.BLOCK_QUOTE: {
@@ -197,25 +198,25 @@ formatting = {
'unfocused': 'labelOrName + roleName + pause + currentLineText + allTextSelection',
},
# TODO - JD: When we bump dependencies to 2.34, remove this fake role and use the real one.
'ROLE_CONTENT_DELETION': {
role_keys.ROLE_CONTENT_DELETION: {
'focused': 'leaving or deletionStart',
'unfocused': 'deletionStart + pause + displayedText + pause + deletionEnd',
},
'ROLE_CONTENT_ERROR': {
role_keys.ROLE_CONTENT_ERROR: {
'unfocused': 'displayedText + pause + invalid',
},
# TODO - JD: When we bump dependencies to 2.34, remove this fake role and use the real one.
'ROLE_CONTENT_INSERTION': {
role_keys.ROLE_CONTENT_INSERTION: {
'focused': 'leaving or insertionStart',
'unfocused': 'insertionStart + pause + displayedText + pause + insertionEnd',
},
# TODO - JD: When we bump dependencies to 2.36, remove this fake role and use the real one.
'ROLE_CONTENT_MARK': {
role_keys.ROLE_CONTENT_MARK: {
'focused': 'leaving or markStart',
'unfocused': 'markStart + pause + displayedText + pause + markEnd',
},
# TODO - JD: When we bump dependencies to 2.36, remove this fake role and use the real one.
'ROLE_CONTENT_SUGGESTION': {
role_keys.ROLE_CONTENT_SUGGESTION: {
'focused': 'leaving or roleName',
},
Atspi.Role.DESCRIPTION_LIST: {
@@ -247,11 +248,11 @@ formatting = {
'basicWhereAmI': 'labelOrName + readOnly + textRole + textContent + anyTextSelection + ' + MNEMONIC,
'detailedWhereAmI': 'labelorName + readOnly + textRole + textContentWithAttributes + anyTextSelection + ' + MNEMONIC
},
'ROLE_DPUB_LANDMARK': {
role_keys.ROLE_DPUB_LANDMARK: {
'focused': 'leaving or labelOrName',
'unfocused': 'labelOrName + currentLineText + allTextSelection'
},
'ROLE_DPUB_SECTION': {
role_keys.ROLE_DPUB_SECTION: {
'focused': 'leaving or (labelOrName + roleName)',
'unfocused': 'labelOrName + currentLineText + allTextSelection'
},
@@ -265,7 +266,7 @@ formatting = {
'basicWhereAmI': 'labelOrName + readOnly + textRole + (textContent or placeholderText) + anyTextSelection + required + pause + invalid + ' + MNEMONIC,
'detailedWhereAmI': 'labelOrName + readOnly + textRole + (textContentWithAttributes or placeholderText) + anyTextSelection + required + pause + invalid + ' + MNEMONIC,
},
'ROLE_FEED': {
role_keys.ROLE_FEED: {
'focused': 'leaving or (labelOrName + pause + (numberOfChildren or roleName))',
'unfocused': 'labelOrName + pause + (numberOfChildren or roleName)',
},
@@ -341,11 +342,11 @@ formatting = {
'unfocused': 'math',
},
# TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one.
'ROLE_MATH_ENCLOSED': {
role_keys.ROLE_MATH_ENCLOSED: {
'unfocused': 'enclosedBase + enclosedEnclosures',
},
# TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one.
'ROLE_MATH_FENCED': {
role_keys.ROLE_MATH_FENCED: {
'unfocused': 'fencedStart + pause + fencedContents + pause + fencedEnd',
},
Atspi.Role.MATH_FRACTION: {
@@ -355,23 +356,23 @@ formatting = {
'unfocused': 'rootStart + rootBase + pause + rootEnd + pause',
},
# TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one.
'ROLE_MATH_MULTISCRIPT': {
role_keys.ROLE_MATH_MULTISCRIPT: {
'unfocused': 'scriptBase + pause + scriptPrescripts + pause + scriptPostscripts + pause',
},
# TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one.
'ROLE_MATH_SCRIPT_SUBSUPER': {
role_keys.ROLE_MATH_SCRIPT_SUBSUPER: {
'unfocused': 'scriptBase + pause + scriptSubscript + pause + scriptSuperscript + pause',
},
# TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one.
'ROLE_MATH_SCRIPT_UNDEROVER': {
role_keys.ROLE_MATH_SCRIPT_UNDEROVER: {
'unfocused': 'scriptBase + pause + scriptUnderscript + pause + scriptOverscript + pause',
},
# TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one.
'ROLE_MATH_TABLE': {
role_keys.ROLE_MATH_TABLE: {
'unfocused': 'mathTableStart + pause + mathTableRows + pause + mathTableEnd + pause',
},
# TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one.
'ROLE_MATH_TABLE_ROW': {
role_keys.ROLE_MATH_TABLE_ROW: {
'unfocused': 'mathRow',
},
Atspi.Role.MENU: {
@@ -440,7 +441,7 @@ formatting = {
'unfocused': 'labelOrName + radioState + roleName + availability + ' + MNEMONIC + ' + accelerator + positionInList',
'basicWhereAmI': 'ancestors + labelOrName + roleName + radioState + accelerator + positionInList + ' + MNEMONIC
},
'ROLE_REGION': {
role_keys.ROLE_REGION: {
'focused': 'leaving or (roleName + labelOrName)',
'unfocused': 'labelOrName + roleName + currentLineText + allTextSelection'
},
@@ -492,7 +493,7 @@ formatting = {
Atspi.Role.SUPERSCRIPT: {
'unfocused': 'roleName + currentLineText + allTextSelection',
},
'ROLE_SWITCH': {
role_keys.ROLE_SWITCH: {
'focused': 'switchState',
'unfocused': 'labelOrName + roleName + switchState + availability + ' + MNEMONIC + ' + accelerator',
'basicWhereAmI': 'labelOrName + roleName + switchState'
@@ -509,7 +510,7 @@ formatting = {
'basicWhereAmI': 'parentRoleName + pause + columnHeader + pause + rowHeader + pause + roleName + pause + cellCheckedState + pause + (realActiveDescendantDisplayedText or imageDescription + image) + pause + columnAndRow + pause + expandableState + pause + nodeLevel + pause',
'detailedWhereAmI': 'parentRoleName + pause + columnHeader + pause + rowHeader + pause + roleName + pause + cellCheckedState + pause + (realActiveDescendantDisplayedText or imageDescription + image) + pause + columnAndRow + pause + tableCellRow + pause + expandableState + pause + nodeLevel + pause',
},
'REAL_ROLE_TABLE_CELL': {
role_keys.REAL_ROLE_TABLE_CELL: {
# the real cell information
# note that Atspi.Role.TABLE_CELL is used to work out if we need to
# read a whole row. It calls REAL_ROLE_TABLE_CELL internally.
@@ -630,7 +631,7 @@ formatting = {
or ([Component(obj, asString(labelAndName + roleName))]\
+ (childWidget and ([Region(" ")] + childWidget))))'
},
'ROLE_ARTICLE_IN_FEED': {
role_keys.ROLE_ARTICLE_IN_FEED: {
'unfocused': '((substring and ' + BRAILLE_TEXT + ')\
or ([Component(obj, asString(labelOrName + roleName))]))'
},
@@ -830,7 +831,7 @@ formatting = {
'unfocused': '[Component(obj, asString(labelOrName + roleName))]\
+ [Region(" ")] + statusBar',
},
'ROLE_SWITCH' : {
role_keys.ROLE_SWITCH: {
'unfocused': '[Component(obj,\
asString((labelOrName or description) + roleName),\
indicator=asString(switchState))]'
@@ -840,7 +841,7 @@ formatting = {
Atspi.Role.TABLE_CELL: {
'unfocused': '((substring and ' + BRAILLE_TEXT + ') or tableCellRow)',
},
'REAL_ROLE_TABLE_CELL': {
role_keys.REAL_ROLE_TABLE_CELL: {
'unfocused': '((tableCell2ChildToggle + tableCell2ChildLabel)\
or (substring and ' + BRAILLE_TEXT + ') \
or (cellCheckedState\
@@ -992,7 +993,7 @@ formatting = {
'focused': 'percentage',
'unfocused': 'roleName + percentage + availability',
},
'ROLE_SWITCH': {
role_keys.ROLE_SWITCH: {
'focused': 'switchState',
'unfocused': 'switchState + availability',
},
+91 -39
View File
@@ -48,6 +48,7 @@ from . import braille
from . import debug
from . import messages
from . import object_properties
from . import role_keys
from . import settings
from . import settings_manager
from .ax_object import AXObject
@@ -954,7 +955,7 @@ class Generator:
cells.
"""
result = []
oldRole = self._overrideRole('REAL_ROLE_TABLE_CELL', args)
oldRole = self._overrideRole(role_keys.REAL_ROLE_TABLE_CELL, args)
result.extend(self.generate(obj, **args))
self._restoreRole(oldRole, args)
return result
@@ -1299,62 +1300,113 @@ class Generator:
self._activeProgressBars[obj] = lastTime, lastValue
def _getAlternativeRole(self, obj, **args):
if self._script.utilities.isMath(obj):
if self._script.utilities.isMathSubOrSuperScript(obj):
return 'ROLE_MATH_SCRIPT_SUBSUPER'
if self._script.utilities.isMathUnderOrOverScript(obj):
return 'ROLE_MATH_SCRIPT_UNDEROVER'
if self._script.utilities.isMathMultiScript(obj):
return 'ROLE_MATH_MULTISCRIPT'
if self._script.utilities.isMathEnclose(obj):
return 'ROLE_MATH_ENCLOSED'
if self._script.utilities.isMathFenced(obj):
return 'ROLE_MATH_FENCED'
if self._script.utilities.isMathTable(obj):
return 'ROLE_MATH_TABLE'
if self._script.utilities.isMathTableRow(obj):
return 'ROLE_MATH_TABLE_ROW'
if self._script.utilities.isDPub(obj):
if self._script.utilities.isLandmark(obj):
return 'ROLE_DPUB_LANDMARK'
if AXUtilities.is_section(obj):
return 'ROLE_DPUB_SECTION'
role = self._getMathAlternativeRole(obj)
if role:
return role
role = self._getDPubAlternativeRole(obj)
if role:
return role
role = self._getSwitchOrSpecialRole(obj)
if role:
return role
role = self._getContentAlternativeRole(obj)
if role:
return role
role = self._getDescriptionListRole(obj)
if role:
return role
role = self._getFeedAlternativeRole(obj)
if role:
return role
role = self._getLandmarkAlternativeRole(obj)
if role:
return role
if self._script.utilities.isDocument(obj) and AXObject.supports_image(obj):
return Atspi.Role.IMAGE
return args.get('role', AXObject.get_role(obj))
def _getMathAlternativeRole(self, obj):
if not self._script.utilities.isMath(obj):
return None
if self._script.utilities.isMathSubOrSuperScript(obj):
return role_keys.ROLE_MATH_SCRIPT_SUBSUPER
if self._script.utilities.isMathUnderOrOverScript(obj):
return role_keys.ROLE_MATH_SCRIPT_UNDEROVER
if self._script.utilities.isMathMultiScript(obj):
return role_keys.ROLE_MATH_MULTISCRIPT
if self._script.utilities.isMathEnclose(obj):
return role_keys.ROLE_MATH_ENCLOSED
if self._script.utilities.isMathFenced(obj):
return role_keys.ROLE_MATH_FENCED
if self._script.utilities.isMathTable(obj):
return role_keys.ROLE_MATH_TABLE
if self._script.utilities.isMathTableRow(obj):
return role_keys.ROLE_MATH_TABLE_ROW
return None
def _getDPubAlternativeRole(self, obj):
if not self._script.utilities.isDPub(obj):
return None
if self._script.utilities.isLandmark(obj):
return role_keys.ROLE_DPUB_LANDMARK
if AXUtilities.is_section(obj):
return role_keys.ROLE_DPUB_SECTION
return None
def _getSwitchOrSpecialRole(self, obj):
if self._script.utilities.isSwitch(obj):
return 'ROLE_SWITCH'
return role_keys.ROLE_SWITCH
if self._script.utilities.isAnchor(obj):
return Atspi.Role.STATIC
if self._script.utilities.isBlockquote(obj):
return Atspi.Role.BLOCK_QUOTE
if self._script.utilities.isComment(obj):
return Atspi.Role.COMMENT
return None
def _getContentAlternativeRole(self, obj):
if self._script.utilities.isContentDeletion(obj):
return 'ROLE_CONTENT_DELETION'
return role_keys.ROLE_CONTENT_DELETION
if self._script.utilities.isContentError(obj):
return 'ROLE_CONTENT_ERROR'
return role_keys.ROLE_CONTENT_ERROR
if self._script.utilities.isContentInsertion(obj):
return 'ROLE_CONTENT_INSERTION'
return role_keys.ROLE_CONTENT_INSERTION
if self._script.utilities.isContentMarked(obj):
return 'ROLE_CONTENT_MARK'
return role_keys.ROLE_CONTENT_MARK
if self._script.utilities.isContentSuggestion(obj):
return 'ROLE_CONTENT_SUGGESTION'
return role_keys.ROLE_CONTENT_SUGGESTION
return None
def _getDescriptionListRole(self, obj):
if self._script.utilities.isDescriptionList(obj):
return Atspi.Role.DESCRIPTION_LIST
if self._script.utilities.isDescriptionListTerm(obj):
return Atspi.Role.DESCRIPTION_TERM
if self._script.utilities.isDescriptionListDescription(obj):
return Atspi.Role.DESCRIPTION_VALUE
if self._script.utilities.isFeedArticle(obj):
return 'ROLE_ARTICLE_IN_FEED'
if self._script.utilities.isFeed(obj):
return 'ROLE_FEED'
if self._script.utilities.isLandmark(obj):
if self._script.utilities.isLandmarkRegion(obj):
return 'ROLE_REGION'
return Atspi.Role.LANDMARK
if self._script.utilities.isDocument(obj) and AXObject.supports_image(obj):
return Atspi.Role.IMAGE
return None
return args.get('role', AXObject.get_role(obj))
def _getFeedAlternativeRole(self, obj):
if self._script.utilities.isFeedArticle(obj):
return role_keys.ROLE_ARTICLE_IN_FEED
if self._script.utilities.isFeed(obj):
return role_keys.ROLE_FEED
return None
def _getLandmarkAlternativeRole(self, obj):
if not self._script.utilities.isLandmark(obj):
return None
if self._script.utilities.isLandmarkRegion(obj):
return role_keys.ROLE_REGION
return Atspi.Role.LANDMARK
def getLocalizedRoleName(self, obj, **args):
role = args.get('role', AXObject.get_role(obj))
@@ -1435,7 +1487,7 @@ class Generator:
return object_properties.ROLE_PROLOGUE
if self._script.utilities.isDPubToc(obj):
return object_properties.ROLE_TOC
elif role == "ROLE_DPUB_SECTION":
elif role == role_keys.ROLE_DPUB_SECTION:
if self._script.utilities.isDPubAbstract(obj):
return object_properties.ROLE_ABSTRACT
if self._script.utilities.isDPubColophon(obj):
+1
View File
@@ -77,6 +77,7 @@ cthulhu_python_sources = files([
'pronunciation_dict.py',
'punctuation_settings.py',
'resource_manager.py',
'role_keys.py',
'script.py',
'script_manager.py',
'script_utilities.py',
+57
View File
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
#
# Copyright (c) 2026 Stormux
# Copyright (c) 2010-2012 The Orca Team
# Copyright (c) 2012 Igalia, S.L.
# Copyright (c) 2005-2010 Sun Microsystems Inc.
#
# 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.
#
# Forked from Orca screen reader.
# Cthulhu project: https://git.stormux.org/storm/cthulhu
"""Shared role key constants for formatting and generators."""
__id__ = "$Id$"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
__license__ = "LGPL"
# Custom role keys used by formatting and role override logic.
ROLE_ARTICLE_IN_FEED = 'ROLE_ARTICLE_IN_FEED'
ROLE_CONTENT_DELETION = 'ROLE_CONTENT_DELETION'
ROLE_CONTENT_ERROR = 'ROLE_CONTENT_ERROR'
ROLE_CONTENT_INSERTION = 'ROLE_CONTENT_INSERTION'
ROLE_CONTENT_MARK = 'ROLE_CONTENT_MARK'
ROLE_CONTENT_SUGGESTION = 'ROLE_CONTENT_SUGGESTION'
ROLE_DPUB_LANDMARK = 'ROLE_DPUB_LANDMARK'
ROLE_DPUB_SECTION = 'ROLE_DPUB_SECTION'
ROLE_FEED = 'ROLE_FEED'
ROLE_MATH_ENCLOSED = 'ROLE_MATH_ENCLOSED'
ROLE_MATH_FENCED = 'ROLE_MATH_FENCED'
ROLE_MATH_MULTISCRIPT = 'ROLE_MATH_MULTISCRIPT'
ROLE_MATH_SCRIPT_SUBSUPER = 'ROLE_MATH_SCRIPT_SUBSUPER'
ROLE_MATH_SCRIPT_UNDEROVER = 'ROLE_MATH_SCRIPT_UNDEROVER'
ROLE_MATH_TABLE = 'ROLE_MATH_TABLE'
ROLE_MATH_TABLE_ROW = 'ROLE_MATH_TABLE_ROW'
ROLE_REGION = 'ROLE_REGION'
ROLE_SWITCH = 'ROLE_SWITCH'
ROLE_SPREADSHEET_CELL = 'ROLE_SPREADSHEET_CELL'
# Formatting override keys (not real Atspi roles).
REAL_ROLE_TABLE_CELL = 'REAL_ROLE_TABLE_CELL'
REAL_ROLE_SCROLL_PANE = 'REAL_ROLE_SCROLL_PANE'
@@ -43,6 +43,7 @@ gi.require_version("Atspi", "2.0")
from gi.repository import Atspi
import cthulhu.formatting
import cthulhu.role_keys
import cthulhu.settings
formatting = {
@@ -53,11 +54,11 @@ formatting = {
'basicWhereAmI': 'parentRoleName + pause + columnHeader + pause + rowHeader + pause + roleName + pause + cellCheckedState + pause + (realActiveDescendantDisplayedText or imageDescription + image) + pause + columnAndRow + pause + expandableState + pause + nodeLevel + pause',
'detailedWhereAmI': 'parentRoleName + pause + columnHeader + pause + rowHeader + pause + roleName + pause + cellCheckedState + pause + (realActiveDescendantDisplayedText or imageDescription + image) + pause + columnAndRow + pause + tableCellRow + pause + expandableState + pause + nodeLevel + pause'
},
'REAL_ROLE_TABLE_CELL': {
cthulhu.role_keys.REAL_ROLE_TABLE_CELL: {
'focused': 'newRowHeader + newColumnHeader + realActiveDescendantDisplayedText',
'unfocused': 'newRowHeader + newColumnHeader + realActiveDescendantDisplayedText',
},
'ROLE_SPREADSHEET_CELL': {
cthulhu.role_keys.ROLE_SPREADSHEET_CELL: {
# We treat spreadsheet cells differently from other table cells in
# whereAmI.
#
@@ -36,6 +36,7 @@ gi.require_version("Atspi", "2.0")
from gi.repository import Atspi
import cthulhu.messages as messages
import cthulhu.role_keys as role_keys
import cthulhu.settings_manager as settings_manager
import cthulhu.speech_generator as speech_generator
from cthulhu.ax_object import AXObject
@@ -75,7 +76,7 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
# Treat a paragraph which is inside of a spreadsheet cell as
# a spreadsheet cell.
#
elif role == 'ROLE_SPREADSHEET_CELL':
elif role == role_keys.ROLE_SPREADSHEET_CELL:
oldRole = self._overrideRole(Atspi.Role.TABLE_CELL, args)
override = True
result.extend(speech_generator.SpeechGenerator._generateRoleName(
@@ -502,7 +503,7 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
result = []
if args.get('formatType', 'unfocused') == 'basicWhereAmI' \
and self._script.utilities.isSpreadSheetCell(obj):
oldRole = self._overrideRole('ROLE_SPREADSHEET_CELL', args)
oldRole = self._overrideRole(role_keys.ROLE_SPREADSHEET_CELL, args)
# In addition, if focus is in a cell being edited, we cannot
# query the accessible table interface for coordinates and the
# like because we're temporarily in an entirely different object
+4 -3
View File
@@ -41,6 +41,7 @@ from cthulhu import debug
from cthulhu import input_event_manager
from cthulhu import messages
from cthulhu import object_properties
from cthulhu import role_keys
from cthulhu import cthulhu_state
from cthulhu import settings
from cthulhu import settings_manager
@@ -491,7 +492,7 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
roles = [Atspi.Role.DESCRIPTION_LIST,
Atspi.Role.LIST,
Atspi.Role.LIST_BOX,
'ROLE_FEED']
role_keys.ROLE_FEED]
role = args.get('role', AXObject.get_role(obj))
if role not in roles:
return super()._generateNumberOfChildren(obj, **args)
@@ -510,7 +511,7 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
if self._script.utilities.isDescriptionList(obj):
result = [messages.descriptionListTermCount(setsize)]
elif role == 'ROLE_FEED':
elif role == role_keys.ROLE_FEED:
result = [messages.feedArticleCount(setsize)]
else:
result = [messages.listItemCount(setsize)]
@@ -597,7 +598,7 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
doNotSpeak.append(Atspi.Role.TEXT)
doNotSpeak.append(Atspi.Role.STATIC)
if args.get('string'):
doNotSpeak.append("ROLE_CONTENT_SUGGESTION")
doNotSpeak.append(role_keys.ROLE_CONTENT_SUGGESTION)
if args.get('formatType', 'unfocused') != 'basicWhereAmI':
doNotSpeak.append(Atspi.Role.LIST_ITEM)
doNotSpeak.append(Atspi.Role.LIST)
+2 -1
View File
@@ -39,6 +39,7 @@ import os
from . import cthulhu # Need access to cthulhuApp
from . import generator
from . import role_keys
from . import settings_manager
from .ax_object import AXObject
from .ax_utilities import AXUtilities
@@ -373,7 +374,7 @@ class SoundGenerator(generator.Generator):
role = args.get('role', AXObject.get_role(obj))
if isinstance(role, str):
if role == "ROLE_SWITCH":
if role == role_keys.ROLE_SWITCH:
role = Atspi.Role.SWITCH
else:
return []
+2 -2
View File
@@ -41,6 +41,7 @@ from gi.repository import GLib
from gi.repository import Atspi
from . import debug
from . import role_keys
from . import sound
from .sound_generator import Icon
@@ -244,7 +245,7 @@ class SoundThemeManager:
def _normalizeRole(self, role):
if isinstance(role, str):
if role == "ROLE_SWITCH":
if role == role_keys.ROLE_SWITCH:
return Atspi.Role.SWITCH
return None
return role
@@ -395,4 +396,3 @@ def getManager():
_manager = SoundThemeManager(cthulhu.cthulhuApp)
return _manager
+41 -39
View File
@@ -48,6 +48,7 @@ from . import debug
from . import generator
from . import messages
from . import object_properties
from . import role_keys
from . import settings
from . import settings_manager
from . import sound_theme_manager
@@ -275,7 +276,7 @@ class SpeechGenerator(generator.Generator):
def _getRoleNameStripCandidates(self, obj, role=None):
normalizedRole = role
if isinstance(normalizedRole, str):
if normalizedRole == "ROLE_SWITCH":
if normalizedRole == role_keys.ROLE_SWITCH:
normalizedRole = Atspi.Role.SWITCH
else:
normalizedRole = None
@@ -1199,7 +1200,7 @@ class SpeechGenerator(generator.Generator):
cell itself. The string, 'blank', is added for empty cells.
"""
result = []
oldRole = self._overrideRole('REAL_ROLE_TABLE_CELL', args)
oldRole = self._overrideRole(role_keys.REAL_ROLE_TABLE_CELL, args)
result.extend(self.generate(obj, **args))
self._restoreRole(oldRole, args)
if not (result and result[0]) \
@@ -1970,19 +1971,19 @@ class SpeechGenerator(generator.Generator):
def _getEnabledAndDisabledContextRoles(self):
allRoles = [Atspi.Role.BLOCK_QUOTE,
'ROLE_CONTENT_DELETION',
'ROLE_CONTENT_INSERTION',
'ROLE_CONTENT_MARK',
'ROLE_CONTENT_SUGGESTION',
'ROLE_DPUB_LANDMARK',
'ROLE_DPUB_SECTION',
role_keys.ROLE_CONTENT_DELETION,
role_keys.ROLE_CONTENT_INSERTION,
role_keys.ROLE_CONTENT_MARK,
role_keys.ROLE_CONTENT_SUGGESTION,
role_keys.ROLE_DPUB_LANDMARK,
role_keys.ROLE_DPUB_SECTION,
Atspi.Role.DESCRIPTION_LIST,
'ROLE_FEED',
role_keys.ROLE_FEED,
Atspi.Role.FORM,
Atspi.Role.LANDMARK,
Atspi.Role.LIST,
Atspi.Role.PANEL,
'ROLE_REGION',
role_keys.ROLE_REGION,
Atspi.Role.TABLE,
Atspi.Role.TOOL_TIP]
@@ -1991,19 +1992,19 @@ class SpeechGenerator(generator.Generator):
if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllContextBlockquote'):
enabled.append(Atspi.Role.BLOCK_QUOTE)
if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllContextLandmark'):
enabled.extend([Atspi.Role.LANDMARK, 'ROLE_DPUB_LANDMARK'])
enabled.extend([Atspi.Role.LANDMARK, role_keys.ROLE_DPUB_LANDMARK])
if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllContextList'):
enabled.append(Atspi.Role.LIST)
enabled.append(Atspi.Role.DESCRIPTION_LIST)
enabled.append('ROLE_FEED')
enabled.append(role_keys.ROLE_FEED)
if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllContextPanel'):
enabled.extend([Atspi.Role.PANEL,
Atspi.Role.TOOL_TIP,
'ROLE_CONTENT_DELETION',
'ROLE_CONTENT_INSERTION',
'ROLE_CONTENT_MARK',
'ROLE_CONTENT_SUGGESTION',
'ROLE_DPUB_SECTION'])
role_keys.ROLE_CONTENT_DELETION,
role_keys.ROLE_CONTENT_INSERTION,
role_keys.ROLE_CONTENT_MARK,
role_keys.ROLE_CONTENT_SUGGESTION,
role_keys.ROLE_DPUB_SECTION])
if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllContextNonLandmarkForm'):
enabled.append(Atspi.Role.FORM)
if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllContextTable'):
@@ -2012,19 +2013,20 @@ class SpeechGenerator(generator.Generator):
if cthulhu.cthulhuApp.settingsManager.getSetting('speakContextBlockquote'):
enabled.append(Atspi.Role.BLOCK_QUOTE)
if cthulhu.cthulhuApp.settingsManager.getSetting('speakContextLandmark'):
enabled.extend([Atspi.Role.LANDMARK, 'ROLE_DPUB_LANDMARK', 'ROLE_REGION'])
enabled.extend([Atspi.Role.LANDMARK, role_keys.ROLE_DPUB_LANDMARK,
role_keys.ROLE_REGION])
if cthulhu.cthulhuApp.settingsManager.getSetting('speakContextList'):
enabled.append(Atspi.Role.LIST)
enabled.append(Atspi.Role.DESCRIPTION_LIST)
enabled.append('ROLE_FEED')
enabled.append(role_keys.ROLE_FEED)
if cthulhu.cthulhuApp.settingsManager.getSetting('speakContextPanel'):
enabled.extend([Atspi.Role.PANEL,
Atspi.Role.TOOL_TIP,
'ROLE_CONTENT_DELETION',
'ROLE_CONTENT_INSERTION',
'ROLE_CONTENT_MARK',
'ROLE_CONTENT_SUGGESTION',
'ROLE_DPUB_SECTION'])
role_keys.ROLE_CONTENT_DELETION,
role_keys.ROLE_CONTENT_INSERTION,
role_keys.ROLE_CONTENT_MARK,
role_keys.ROLE_CONTENT_SUGGESTION,
role_keys.ROLE_DPUB_SECTION])
if cthulhu.cthulhuApp.settingsManager.getSetting('speakContextNonLandmarkForm'):
enabled.append(Atspi.Role.FORM)
if cthulhu.cthulhuApp.settingsManager.getSetting('speakContextTable'):
@@ -2058,7 +2060,7 @@ class SpeechGenerator(generator.Generator):
result.append(messages.leavingNLists(count))
else:
result.append(messages.LEAVING_LIST)
elif role == 'ROLE_FEED':
elif role == role_keys.ROLE_FEED:
result.append(messages.LEAVING_FEED)
elif role == Atspi.Role.PANEL:
if self._script.utilities.isFigure(obj):
@@ -2069,7 +2071,7 @@ class SpeechGenerator(generator.Generator):
result = ['']
elif role == Atspi.Role.TABLE and self._script.utilities.isTextDocumentTable(obj):
result.append(messages.LEAVING_TABLE)
elif role == 'ROLE_DPUB_LANDMARK':
elif role == role_keys.ROLE_DPUB_LANDMARK:
if self._script.utilities.isDPubAcknowledgments(obj):
result.append(messages.LEAVING_ACKNOWLEDGMENTS)
elif self._script.utilities.isDPubAfterword(obj):
@@ -2108,7 +2110,7 @@ class SpeechGenerator(generator.Generator):
result.append(messages.LEAVING_PROLOGUE)
elif self._script.utilities.isDPubToc(obj):
result.append(messages.LEAVING_TOC)
elif role == 'ROLE_DPUB_SECTION':
elif role == role_keys.ROLE_DPUB_SECTION:
if self._script.utilities.isDPubAbstract(obj):
result.append(messages.LEAVING_ABSTRACT)
elif self._script.utilities.isDPubColophon(obj):
@@ -2148,13 +2150,13 @@ class SpeechGenerator(generator.Generator):
result.append(messages.LEAVING_FORM)
elif role == Atspi.Role.TOOL_TIP:
result.append(messages.LEAVING_TOOL_TIP)
elif role == 'ROLE_CONTENT_DELETION':
elif role == role_keys.ROLE_CONTENT_DELETION:
result.append(messages.CONTENT_DELETION_END)
elif role == 'ROLE_CONTENT_INSERTION':
elif role == role_keys.ROLE_CONTENT_INSERTION:
result.append(messages.CONTENT_INSERTION_END)
elif role == 'ROLE_CONTENT_MARK':
elif role == role_keys.ROLE_CONTENT_MARK:
result.append(messages.CONTENT_MARK_END)
elif role == 'ROLE_CONTENT_SUGGESTION' \
elif role == role_keys.ROLE_CONTENT_SUGGESTION \
and not self._script.utilities.isInlineSuggestion(obj):
result.append(messages.LEAVING_SUGGESTION)
else:
@@ -2305,16 +2307,16 @@ class SpeechGenerator(generator.Generator):
Atspi.Role.DESCRIPTION_LIST,
Atspi.Role.FORM,
Atspi.Role.LANDMARK,
'ROLE_CONTENT_DELETION',
'ROLE_CONTENT_INSERTION',
'ROLE_CONTENT_MARK',
'ROLE_CONTENT_SUGGESTION',
'ROLE_DPUB_LANDMARK',
'ROLE_DPUB_SECTION',
'ROLE_FEED',
role_keys.ROLE_CONTENT_DELETION,
role_keys.ROLE_CONTENT_INSERTION,
role_keys.ROLE_CONTENT_MARK,
role_keys.ROLE_CONTENT_SUGGESTION,
role_keys.ROLE_DPUB_LANDMARK,
role_keys.ROLE_DPUB_SECTION,
role_keys.ROLE_FEED,
Atspi.Role.LIST,
Atspi.Role.PANEL,
'ROLE_REGION',
role_keys.ROLE_REGION,
Atspi.Role.TABLE,
Atspi.Role.TOOL_TIP]