Skip to content

Commit cfb0578

Browse files
soffice: Make selected cell announcement more efficient
Link to issue number: Fixes nvaccess#13232 Summary of the issue: Since commit 32bf54e ("Improve selection and merged cell announcements in LibreOffice Calc 7.3 and above (nvaccess#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.
1 parent 20d5a25 commit cfb0578

1 file changed

Lines changed: 11 additions & 3 deletions

File tree

‎source/appModules/soffice.py‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# Copyright (C) 2006-2021 NV Access Limited, Bill Dengler, Leonard de Ruijter
55

66
from comtypes import COMError
7+
import oleacc
78
from IAccessibleHandler import IA2, splitIA2Attribs
89
import appModuleHandler
910
import controlTypes
@@ -208,11 +209,18 @@ def announceSelectionChange(self):
208209

209210
def _get_cellCoordsText(self):
210211
if self.hasSelection and controlTypes.State.FOCUSED in self.states:
211-
selected, count = self.table.IAccessibleTable2Object.selectedCells
212-
firstAccessible = selected[0].QueryInterface(IA2.IAccessible2)
212+
count = self.table.IAccessibleTable2Object.nSelectedCells
213+
selection = self.table.IAccessibleObject.accSelection
214+
enumObj = selection.QueryInterface(oleacc.IEnumVARIANT)
215+
tableAccessible = self.table.IAccessibleTable2Object.QueryInterface(IA2.IAccessible2)
216+
firstChildId, _retrievedCount = enumObj.Next(1)
217+
firstAccessible = tableAccessible.accChild(firstChildId).QueryInterface(IA2.IAccessible2)
213218
firstAddress = firstAccessible.accName(0)
214219
firstValue = firstAccessible.accValue(0) or ''
215-
lastAccessible = selected[count - 1].QueryInterface(IA2.IAccessible2)
220+
# skip over all except the last element
221+
enumObj.Skip(count - 2)
222+
lastChildId, _retrievedCount = enumObj.Next(1)
223+
lastAccessible = tableAccessible.accChild(lastChildId).QueryInterface(IA2.IAccessible2)
216224
lastAddress = lastAccessible.accName(0)
217225
lastValue = lastAccessible.accValue(0) or ''
218226
# Translators: LibreOffice, report selected range of cell coordinates with their values

0 commit comments

Comments
 (0)