Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix PowerPoint caret reporting when text contains wide characters, and overall improvement of TextInfo implementation #17015

Merged
merged 17 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions source/appModules/powerpnt.py
Original file line number Diff line number Diff line change
Expand Up @@ -1054,9 +1054,23 @@ def _getSelectionOffsets(self):
end = start + sel.length
return start, end

def _getPptTextRange(self, start: int, end: int, clamp: bool = False):
def _getPptTextRange(
self,
start: int,
end: int,
clamp: bool = False,
) -> comtypes.client.lazybind.Dispatch:
"""
Retrieves a text range from the PowerPoint object, with optional clamping of the start and end indices.
:param start: The starting character index of the text range (zero based).
:param end: The ending character index of the text range(zero based).
:param clamp: If True, the start and end indices will be clamped to valid values within the text range. Defaults to False.
:returns: The text range object as a comtypes.client.lazybind.Dispatch object.
:raises ValueError: If the start index is greater than the end index.
:note: For more information about text ranges, see https://learn.microsoft.com/en-us/office/vba/api/powerpoint.textrange
SaschaCowley marked this conversation as resolved.
Show resolved Hide resolved
"""
if not start <= end:
LeonarddeR marked this conversation as resolved.
Show resolved Hide resolved
raise RuntimeError(
raise ValueError(
f"start must be less than or equal to end. Got {start=}, {end=}.",
stack_info=True,
)
Expand All @@ -1076,6 +1090,12 @@ def _getPptTextRange(self, start: int, end: int, clamp: bool = False):
return self.obj.ppObject.textRange.characters(start + 1, end - start)

def _getTextRange(self, start: int, end: int) -> str:
"""
Retrieves the text content of a PowerPoint text range, replacing any newline characters with standard newline characters.
:param start: The starting character index of the text range (zero based).
:param end: The ending character index (zero based) of the text range.
:returns: The text content of the specified text range, with newline characters normalized.
"""
return self._getPptTextRange(start, end).text.replace("\x0b", "\n")

def _getStoryLength(self) -> int:
Expand All @@ -1091,6 +1111,14 @@ def _getCharacterOffsets(self, offset: int) -> tuple[int, int]:

@staticmethod
def _getOffsets(ranges: comtypes.client.lazybind.Dispatch, offset: int) -> tuple[int, int, int]:
"""
Retrieves the start and end offsets of a range of elements
(e.g. words, lines, paragraphs) within a text range, given a specific offset.
:param ranges: The collection of elements (e.g. words, lines, paragraphs) to search.
These are retrieved by calling a method on the text range object, such as textRange.words(), textRange.lines(), or textRange.paragraphs().
:param offset: The zero based character offset to search for within the text range.
:Returns: A tuple containing the index of the element that contains the given offset, the zero based start offset of that element, and the zero based end offset of that element.
"""
for i, chunk in enumerate(ranges):
start = chunk.start - 1
end = start + chunk.length
Expand Down
5 changes: 3 additions & 2 deletions user_docs/en/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ The available options are:
* The timeout to perform a multiple keypress is now configurable; this may be especially useful for people with dexterity impairment. (#11929, @CyrilleB79)
* When performing a braille cursor routing action, NVDA can now automatically speak the character at the cursor. (#8072, @LeonarddeR)
* This option is disabled by default. You can enable "Speak character when routing cursor in text" in NVDA's braille settings.
* Improvements in Microsoft PowerPoint text objects:
* Improvements when editing Microsoft PowerPoint text boxes:
LeonarddeR marked this conversation as resolved.
Show resolved Hide resolved
* It is now possible to use braille display routing keys to move the text cursor. (#9101, #17004)
* It is now possible to use the review cursor selection commands to select text. (#17004)
* Character location reporting is now accurate (e.g. when pressing `NVDA+Delete`. (#9941, @LeonarddeR)
* You can now move per sentence in Text frames. (#17015, @LeonarddeR)
* You can now move per sentence in Text boxes. (#17015, @LeonarddeR)
LeonarddeR marked this conversation as resolved.
Show resolved Hide resolved

### Changes

Expand All @@ -45,6 +45,7 @@ The available options are:
* NVDA no longer occasionally fails to open browsable messages (such as pressing `NVDA+f` twice). (#16806, @LeonarddeR)
* NVDA is no longer unstable after restarting NVDA during an automatic Braille Bluetooth scan. (#16933)
* In Microsoft PowerPoint, caret reporting no longer breaks when text contains wide characters, such as emoji. (#17006 , @LeonarddeR)
* Updating NVDA while add-on updates are pending no longer results in the add-on being removed. (#16837)

### Changes for Developers

Expand Down