diff --git a/source/browseMode.py b/source/browseMode.py index 9f29f8f8837..d46cfe12d2a 100644 --- a/source/browseMode.py +++ b/source/browseMode.py @@ -450,8 +450,6 @@ def _iterNodesByType(self,itemType,direction="next",pos=None): def _iterNotLinkBlock(self, direction="next", pos=None): raise NotImplementedError - MAX_ITERATIONS_FOR_SIMILAR_PARAGRAPH = 100_000 - def _iterSimilarParagraph( self, kind: str, @@ -460,26 +458,7 @@ def _iterSimilarParagraph( direction: _Movement, pos: textInfos.TextInfo, ) -> Generator[TextInfoQuickNavItem, None, None]: - if direction not in [_Movement.NEXT, _Movement.PREVIOUS]: - raise RuntimeError - info = pos.copy() - info.collapse() - info.expand(textInfos.UNIT_PARAGRAPH) - if desiredValue is None: - desiredValue = paragraphFunction(info) - for i in range(self.MAX_ITERATIONS_FOR_SIMILAR_PARAGRAPH): - # move by one paragraph in the desired direction - info.collapse(end=direction == _Movement.NEXT) - if direction == _Movement.PREVIOUS: - if info.move(textInfos.UNIT_CHARACTER, -1) == 0: - return - info.expand(textInfos.UNIT_PARAGRAPH) - if info.isCollapsed: - return - value = paragraphFunction(info) - if value == desiredValue: - yield TextInfoQuickNavItem(kind, self, info.copy(), outputReason=OutputReason.CARET) - + raise NotImplementedError def _quickNavScript(self,gesture, itemType, direction, errorMessage, readUnit): if itemType=="notLinkBlock": @@ -2220,3 +2199,38 @@ def script_toggleNativeAppSelectionMode(self, gesture: inputCore.InputGesture): self._nativeAppSelectionMode = False # Translators: reported when native selection mode is toggled off. ui.message(_("Native app selection mode disabled")) + + MAX_ITERATIONS_FOR_SIMILAR_PARAGRAPH = 100_000 + + def _iterSimilarParagraph( + self, + kind: str, + paragraphFunction: Callable[[textInfos.TextInfo], Optional[Any]], + desiredValue: Optional[Any], + direction: _Movement, + pos: textInfos.TextInfo, + ) -> Generator[TextInfoQuickNavItem, None, None]: + if direction not in [_Movement.NEXT, _Movement.PREVIOUS]: + raise RuntimeError + info = pos.copy() + info.collapse() + info.expand(textInfos.UNIT_PARAGRAPH) + if desiredValue is None: + desiredValue = paragraphFunction(info) + for i in range(self.MAX_ITERATIONS_FOR_SIMILAR_PARAGRAPH): + # move by one paragraph in the desired direction + try: + info.collapse(end=direction == _Movement.NEXT) + except RuntimeError: + # Microsoft Word raises RuntimeError when collapsing textInfo to the last character of the document. + return + + if direction == _Movement.PREVIOUS: + if info.move(textInfos.UNIT_CHARACTER, -1) == 0: + return + info.expand(textInfos.UNIT_PARAGRAPH) + if info.isCollapsed: + return + value = paragraphFunction(info) + if value == desiredValue: + yield TextInfoQuickNavItem(kind, self, info.copy(), outputReason=OutputReason.CARET)