Skip to content

Commit

Permalink
soffice: Make selected cell announcement more efficient (#13233)
Browse files Browse the repository at this point in the history
Fixes #13232

Summary of the issue:
Since PR #12849, information about selected cells in LibreOffice Calc is queried using the 'IAccessibleTable2' interface which is supported from LibreOffice 7.3 on.
The call to the 'selectedCells' method on that interface requests a list of a11y objects for all currently selected cells, of which only the first and the last one are actually needed for the announcement of selected cells.
Since Calc spreadsheets have more than a billion cells, this is inefficient when many cells are selected and resulted in Calc becoming unresponsive.

Description of how this pull request fixes the issue:
Instead of using the 'selectedCells' method from the 'IAccessibleTable2' interface, the first and last selected cell are now retrieved using the 'accSelection' on the 'IAccessible' object of the table, which avoids that a11y objects for all other selected cells have to be generated as well.

Testing strategy:
use LibreOffice Calc 7.3 or above
select all cells in LO Calc and check that NVDA announces coordinate + content of the first cell (A1) and the last cell (AMJ1048576) in the spreadsheet
test a few other selections in the spreadsheet (use shift + arrow keys to increase/decrease selection)
  • Loading branch information
michaelweghorn committed Jun 30, 2022
1 parent 2e7a5f0 commit 0170323
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
29 changes: 26 additions & 3 deletions source/appModules/soffice.py
Expand Up @@ -3,7 +3,13 @@
# See the file COPYING for more details.
# Copyright (C) 2006-2022 NV Access Limited, Bill Dengler, Leonard de Ruijter

from typing import (
Union
)

from comtypes import COMError
import comtypes.client
import oleacc
from IAccessibleHandler import IA2, splitIA2Attribs
import appModuleHandler
import controlTypes
Expand Down Expand Up @@ -209,11 +215,28 @@ def announceSelectionChange(self):

def _get_cellCoordsText(self):
if self.hasSelection and controlTypes.State.FOCUSED in self.states:
selected, count = self.table.IAccessibleTable2Object.selectedCells
firstAccessible = selected[0].QueryInterface(IA2.IAccessible2)
count = self.table.IAccessibleTable2Object.nSelectedCells
selection = self.table.IAccessibleObject.accSelection
enumObj = selection.QueryInterface(oleacc.IEnumVARIANT)
firstChild: Union[int, comtypes.client.dynamic._Dispatch]
firstChild, _retrievedCount = enumObj.Next(1)
# skip over all except the last element
enumObj.Skip(count - 2)
lastChild: Union[int, comtypes.client.dynamic._Dispatch]
lastChild, _retrieveCount = enumObj.Next(1)
# in LibreOffice 7.3.0, the IEnumVARIANT returns a child ID,
# in LibreOffice >= 7.4, it returns an IDispatch
if isinstance(firstChild, int):
tableAccessible = self.table.IAccessibleTable2Object.QueryInterface(IA2.IAccessible2)
firstAccessible = tableAccessible.accChild(firstChild).QueryInterface(IA2.IAccessible2)
lastAccessible = tableAccessible.accChild(lastChild).QueryInterface(IA2.IAccessible2)
elif isinstance(firstChild, comtypes.client.dynamic._Dispatch):
firstAccessible = firstChild.QueryInterface(IA2.IAccessible2)
lastAccessible = lastChild.QueryInterface(IA2.IAccessible2)
else:
raise RuntimeError(f"Unexpected LibreOffice object {firstChild}, type: {type(firstChild)}")
firstAddress = firstAccessible.accName(0)
firstValue = firstAccessible.accValue(0) or ''
lastAccessible = selected[count - 1].QueryInterface(IA2.IAccessible2)
lastAddress = lastAccessible.accName(0)
lastValue = lastAccessible.accValue(0) or ''
# Translators: LibreOffice, report selected range of cell coordinates with their values
Expand Down
1 change: 1 addition & 0 deletions user_docs/en/changes.t2t
Expand Up @@ -27,6 +27,7 @@ It can be re-enabled in NVDA's advanced settings panel. (#11554)
- Font size measurements are now translatable in NVDA. (#13573)
- Ignore Java Access Bridge events where no window handle can be found for Java applications.
This will improve performance for some Java applications including IntelliJ IDEA. (#13039)
- Announcement of selected cells for LibreOffice Calc is more efficient and no longer results in a Calc freeze when many cells are selected. (#13232)
-


Expand Down

0 comments on commit 0170323

Please sign in to comment.