Skip to content

Commit eef331f

Browse files
authored
Merge 91cb815 into d7bc6b1
2 parents d7bc6b1 + 91cb815 commit eef331f

6 files changed

Lines changed: 64 additions & 43 deletions

File tree

source/appModules/kindle.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import api
1313
from scriptHandler import willSayAllResume, isScriptWaiting
1414
import controlTypes
15+
from controlTypes import OutputReason
1516
import treeInterceptorHandler
1617
from cursorManager import ReviewCursorManager
1718
import browseMode
@@ -277,7 +278,7 @@ def getFormatFieldSpeech(
277278
attrs: textInfos.Field,
278279
attrsCache: Optional[textInfos.Field] = None,
279280
formatConfig: Optional[Dict[str, bool]] = None,
280-
reason: Optional[str] = None,
281+
reason: Optional[OutputReason] = None,
281282
unit: Optional[str] = None,
282283
extraDetail: bool = False,
283284
initialFormat: bool = False

source/browseMode.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from scriptHandler import isScriptWaiting, willSayAllResume
2626
import aria
2727
import controlTypes
28+
from controlTypes import OutputReason
2829
import config
2930
import textInfos
3031
import braille
@@ -39,7 +40,7 @@
3940
from abc import ABCMeta, abstractmethod
4041
from typing import Optional
4142

42-
REASON_QUICKNAV = "quickNav"
43+
REASON_QUICKNAV = OutputReason.QUICKNAV
4344

4445
def reportPassThrough(treeInterceptor,onlyIfChanged=True):
4546
"""Reports the pass through mode if it has changed.
@@ -304,7 +305,7 @@ def event_treeInterceptor_gainFocus(self):
304305
controlTypes.ROLE_CHECKMENUITEM,
305306
})
306307

307-
def shouldPassThrough(self, obj, reason=None):
308+
def shouldPassThrough(self, obj, reason: Optional[OutputReason] = None):
308309
"""Determine whether pass through mode should be enabled (focus mode) or disabled (browse mode) for a given object.
309310
@param obj: The object in question.
310311
@type obj: L{NVDAObjects.NVDAObject}

source/controlTypes.py

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#See the file COPYING for more details.
55
#Copyright (C) 2007-2016 NV Access Limited, Babbage B.V.
66
from typing import Dict, Union, Set, Any, Optional, List
7+
from enum import Enum, auto
78

89
ROLE_UNKNOWN=0
910
ROLE_WINDOW=1
@@ -622,27 +623,44 @@
622623
ROLE_APPLICATION,
623624
}
624625

625-
#{ Output reasons
626-
# These constants are used to specify the reason that a given piece of output was generated.
627-
#: An object to be reported due to a focus change or similar.
628-
REASON_FOCUS="focus"
629-
#: An ancestor of the focus object to be reported due to a focus change or similar.
630-
REASON_FOCUSENTERED="focusEntered"
631-
#: An item under the mouse.
632-
REASON_MOUSE="mouse"
633-
#: A response to a user query.
634-
REASON_QUERY="query"
635-
#: Reporting a change to an object.
636-
REASON_CHANGE="change"
637-
#: A generic, screen reader specific message.
638-
REASON_MESSAGE="message"
639-
#: Text reported as part of a say all.
640-
REASON_SAYALL="sayAll"
641-
#: Content reported due to caret movement or similar.
642-
REASON_CARET="caret"
643-
#: No output, but any state should be cached as if output had occurred.
644-
REASON_ONLYCACHE="onlyCache"
645-
#}
626+
627+
class OutputReason(Enum):
628+
"""Specify the reason that a given piece of output was generated.
629+
"""
630+
#: An object to be reported due to a focus change or similar.
631+
FOCUS = auto()
632+
#: An ancestor of the focus object to be reported due to a focus change or similar.
633+
FOCUSENTERED = auto()
634+
#: An item under the mouse.
635+
MOUSE = auto()
636+
#: A response to a user query.
637+
QUERY = auto()
638+
#: Reporting a change to an object.
639+
CHANGE = auto()
640+
#: A generic, screen reader specific message.
641+
MESSAGE = auto()
642+
#: Text reported as part of a say all.
643+
SAYALL = auto()
644+
#: Content reported due to caret movement or similar.
645+
CARET = auto()
646+
#: No output, but any state should be cached as if output had occurred.
647+
ONLYCACHE = auto()
648+
649+
QUICKNAV = auto()
650+
651+
# The following constants are kept for backwards compatibility.
652+
# In future, OutputReason should be used directly
653+
654+
655+
REASON_FOCUS = OutputReason.FOCUS
656+
REASON_FOCUSENTERED = OutputReason.FOCUSENTERED
657+
REASON_MOUSE = OutputReason.MOUSE
658+
REASON_QUERY = OutputReason.QUERY
659+
REASON_CHANGE = OutputReason.CHANGE
660+
REASON_MESSAGE = OutputReason.MESSAGE
661+
REASON_SAYALL = OutputReason.SAYALL
662+
REASON_CARET = OutputReason.CARET
663+
REASON_ONLYCACHE = OutputReason.ONLYCACHE
646664

647665
#: Text to use for 'current' values. These describe if an item is the current item
648666
#: within a particular kind of selection.
@@ -661,15 +679,14 @@
661679
"time":_("current time"),
662680
}
663681

664-
def processPositiveStates(role, states, reason, positiveStates=None):
682+
def processPositiveStates(role, states, reason: OutputReason, positiveStates=None):
665683
"""Processes the states for an object and returns the positive states to output for a specified reason.
666684
For example, if C{STATE_CHECKED} is in the returned states, it means that the processed object is checked.
667685
@param role: The role of the object to process states for (e.g. C{ROLE_CHECKBOX}.
668686
@type role: int
669687
@param states: The raw states for an object to process.
670688
@type states: set
671689
@param reason: The reason to process the states (e.g. C{REASON_FOCUS}.
672-
@type reason: str
673690
@param positiveStates: Used for C{REASON_CHANGE}, specifies states changed from negative to positive;
674691
@type positiveStates: set
675692
@return: The processed positive states.
@@ -719,15 +736,14 @@ def processPositiveStates(role, states, reason, positiveStates=None):
719736
positiveStates.discard(STATE_EDITABLE)
720737
return positiveStates
721738

722-
def processNegativeStates(role, states, reason, negativeStates=None):
739+
def processNegativeStates(role, states, reason: OutputReason, negativeStates=None):
723740
"""Processes the states for an object and returns the negative states to output for a specified reason.
724741
For example, if C{STATE_CHECKED} is in the returned states, it means that the processed object is not checked.
725742
@param role: The role of the object to process states for (e.g. C{ROLE_CHECKBOX}.
726743
@type role: int
727744
@param states: The raw states for an object to process.
728745
@type states: set
729746
@param reason: The reason to process the states (e.g. C{REASON_FOCUS}.
730-
@type reason: str
731747
@param negativeStates: Used for C{REASON_CHANGE}, specifies states changed from positive to negative;
732748
@type negativeStates: set
733749
@return: The processed negative states.
@@ -787,7 +803,7 @@ def processNegativeStates(role, states, reason, negativeStates=None):
787803
def processAndLabelStates(
788804
role: int,
789805
states: Set[Any],
790-
reason: str,
806+
reason: OutputReason,
791807
positiveStates: Optional[Set[Any]] = None,
792808
negativeStates: Optional[Set[Any]] = None,
793809
positiveStateLabelDict: Dict[int, str] = {},

source/speech/__init__.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import colors
1515
import api
1616
import controlTypes
17+
from controlTypes import OutputReason
1718
import tones
1819
import synthDriverHandler
1920
from synthDriverHandler import getSynth, setSynth
@@ -302,7 +303,7 @@ def getCharDescListFromText(text,locale):
302303

303304
def speakObjectProperties( # noqa: C901
304305
obj,
305-
reason: str = controlTypes.REASON_QUERY,
306+
reason: OutputReason = controlTypes.REASON_QUERY,
306307
_prefixSpeechCommand: Optional[SpeechCommand] = None,
307308
priority: Optional[Spri] = None,
308309
**allowedProperties
@@ -322,7 +323,7 @@ def speakObjectProperties( # noqa: C901
322323
# and move logic out into smaller helper functions.
323324
def getObjectPropertiesSpeech( # noqa: C901
324325
obj,
325-
reason: str = controlTypes.REASON_QUERY,
326+
reason: OutputReason = controlTypes.REASON_QUERY,
326327
_prefixSpeechCommand: Optional[SpeechCommand] = None,
327328
**allowedProperties
328329
) -> SpeechSequence:
@@ -423,7 +424,7 @@ def getObjectPropertiesSpeech( # noqa: C901
423424

424425
def _getPlaceholderSpeechIfTextEmpty(
425426
obj,
426-
reason: str,
427+
reason: OutputReason,
427428
) -> Tuple[bool, SpeechSequence]:
428429
""" Attempt to get speech for placeholder attribute if text for 'obj' is empty. Don't report the placeholder
429430
value unless the text is empty, because it is confusing to hear the current value (presumably typed by the
@@ -439,7 +440,7 @@ def _getPlaceholderSpeechIfTextEmpty(
439440

440441
def speakObject(
441442
obj,
442-
reason: str = controlTypes.REASON_QUERY,
443+
reason: OutputReason = controlTypes.REASON_QUERY,
443444
_prefixSpeechCommand: Optional[SpeechCommand] = None,
444445
priority: Optional[Spri] = None
445446
):
@@ -461,7 +462,7 @@ def _flattenNestedSequences(nestedSequences: Iterator[SpeechSequence]) -> Iterat
461462
# and move logic out into smaller helper functions.
462463
def getObjectSpeech( # noqa: C901
463464
obj,
464-
reason: str = controlTypes.REASON_QUERY,
465+
reason: OutputReason = controlTypes.REASON_QUERY,
465466
_prefixSpeechCommand: Optional[SpeechCommand] = None,
466467
):
467468
from NVDAObjects import NVDAObjectTextInfo
@@ -598,7 +599,7 @@ def _objectSpeech_calculateAllowedProps(reason, shouldReportTextContent):
598599

599600
def speakText(
600601
text: str,
601-
reason: str = controlTypes.REASON_MESSAGE,
602+
reason: OutputReason = controlTypes.REASON_MESSAGE,
602603
symbolLevel: Optional[int] = None,
603604
priority: Optional[Spri] = None
604605
):
@@ -1044,7 +1045,7 @@ def speakTextInfo(
10441045
useCache: Union[bool, SpeakTextInfoState] = True,
10451046
formatConfig: Dict[str, bool] = None,
10461047
unit: Optional[str] = None,
1047-
reason: str = controlTypes.REASON_QUERY,
1048+
reason: OutputReason = controlTypes.REASON_QUERY,
10481049
_prefixSpeechCommand: Optional[SpeechCommand] = None,
10491050
onlyInitialFields: bool = False,
10501051
suppressBlanks: bool = False,
@@ -1074,7 +1075,7 @@ def getTextInfoSpeech( # noqa: C901
10741075
useCache: Union[bool, SpeakTextInfoState] = True,
10751076
formatConfig: Dict[str, bool] = None,
10761077
unit: Optional[str] = None,
1077-
reason: str = controlTypes.REASON_QUERY,
1078+
reason: OutputReason = controlTypes.REASON_QUERY,
10781079
_prefixSpeechCommand: Optional[SpeechCommand] = None,
10791080
onlyInitialFields: bool = False,
10801081
suppressBlanks: bool = False
@@ -1444,7 +1445,7 @@ def isControlEndFieldCommand(x):
14441445
# Note: when working on getPropertiesSpeech, look for opportunities to simplify
14451446
# and move logic out into smaller helper functions.
14461447
def getPropertiesSpeech( # noqa: C901
1447-
reason: str = controlTypes.REASON_QUERY,
1448+
reason: OutputReason = controlTypes.REASON_QUERY,
14481449
**propertyValues
14491450
) -> SpeechSequence:
14501451
global oldTreeLevel, oldTableID, oldRowNumber, oldRowSpan, oldColumnNumber, oldColumnSpan
@@ -1629,7 +1630,7 @@ def getControlFieldSpeech( # noqa: C901
16291630
fieldType: str,
16301631
formatConfig: Optional[Dict[str, bool]] = None,
16311632
extraDetail: bool = False,
1632-
reason: Optional[str] = None
1633+
reason: Optional[OutputReason] = None
16331634
) -> SpeechSequence:
16341635
if attrs.get('isHidden'):
16351636
return []
@@ -1894,7 +1895,7 @@ def getFormatFieldSpeech( # noqa: C901
18941895
attrs: textInfos.Field,
18951896
attrsCache: Optional[textInfos.Field] = None,
18961897
formatConfig: Optional[Dict[str, bool]] = None,
1897-
reason: Optional[str] = None,
1898+
reason: Optional[OutputReason] = None,
18981899
unit: Optional[str] = None,
18991900
extraDetail: bool = False,
19001901
initialFormat: bool = False,

source/textInfos/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import baseObject
1818
import config
1919
import controlTypes
20+
from controlTypes import OutputReason
2021
import locationHelper
2122

2223

@@ -521,7 +522,7 @@ def getControlFieldSpeech(
521522
fieldType: str,
522523
formatConfig: Optional[Dict[str, bool]] = None,
523524
extraDetail: bool = False,
524-
reason: Optional[str] = None
525+
reason: Optional[OutputReason] = None
525526
) -> SpeechSequence:
526527
# Import late to avoid circular import.
527528
import speech
@@ -541,7 +542,7 @@ def getFormatFieldSpeech(
541542
attrs: Field,
542543
attrsCache: Optional[Field] = None,
543544
formatConfig: Optional[Dict[str, bool]] = None,
544-
reason: Optional[str] = None,
545+
reason: Optional[OutputReason] = None,
545546
unit: Optional[str] = None,
546547
extraDetail: bool = False,
547548
initialFormat: bool = False,

source/treeInterceptorHandler.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import braille
1616
import vision
1717
from speech.types import SpeechSequence
18+
from controlTypes import OutputReason
1819

1920
runningTable=set()
2021

@@ -246,7 +247,7 @@ def getFormatFieldSpeech(
246247
attrs: textInfos.Field,
247248
attrsCache: Optional[textInfos.Field] = None,
248249
formatConfig: Optional[Dict[str, bool]] = None,
249-
reason: Optional[str] = None,
250+
reason: Optional[OutputReason] = None,
250251
unit: Optional[str] = None,
251252
extraDetail: bool = False,
252253
initialFormat: bool = False,

0 commit comments

Comments
 (0)