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

Excel: for selection covering more than one cell, announce the active cell when pressing Enter or Tab rather than the whole selection range #17733

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Changes from all 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
40 changes: 36 additions & 4 deletions source/NVDAObjects/window/excel.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2006-2023 NV Access Limited, Dinesh Kaushal, Siddhartha Gupta, Accessolutions, Julien Cochuyt,
# Copyright (C) 2006-2025 NV Access Limited, Dinesh Kaushal, Siddhartha Gupta, Accessolutions, Julien Cochuyt,
# Cyrille Bougot, Leonard de Ruijter
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.

from __future__ import annotations
import abc
import ctypes
import enum
from typing import (
Any,
Dict,
Optional,
Callable,
)

from comtypes import COMError, BSTR
Expand Down Expand Up @@ -795,6 +797,15 @@ def _getDropdown(self, selection=None):
obj.parent = selection
return obj

def _getActiveCell(self) -> "ExcelCell":
cell = self.excelWindowObject.ActiveCell
obj = ExcelCell(
windowHandle=self.windowHandle,
excelWindowObject=self.excelWindowObject,
excelCellObject=cell,
)
return obj

def _getSelection(self):
selection = self.excelWindowObject.Selection
try:
Expand Down Expand Up @@ -1094,6 +1105,17 @@ def _get_states(self):
"kb:numpadEnter",
"kb:shift+enter",
"kb:shift+numpadEnter",
),
canPropagate=True,
)
def script_changeActiveCell(self, gesture: inputCore.InputGesture) -> None:
self.changeSelectionOrActiveCell(
gesture=gesture,
objGetter=self._getActiveCell,
)

@scriptHandler.script(
gestures=(
"kb:upArrow",
"kb:downArrow",
"kb:leftArrow",
Expand Down Expand Up @@ -1140,8 +1162,18 @@ def _get_states(self):
),
canPropagate=True,
)
def script_changeSelection(self, gesture):
oldSelection = self._getSelection()
def script_changeSelection(self, gesture: inputCore.InputGesture) -> None:
self.changeSelectionOrActiveCell(
gesture=gesture,
objGetter=self._getSelection,
)

def changeSelectionOrActiveCell(
self,
gesture: inputCore.InputGesture,
objGetter: Callable[[], ExcelCell | ExcelSelection | _msOfficeChart.OfficeChart],
):
oldSelection = objGetter()
gesture.send()
newSelection = None
start = time.time()
Expand All @@ -1157,7 +1189,7 @@ def script_changeSelection(self, gesture):
if eventHandler.isPendingEvents("gainFocus"):
# This object is no longer focused.
return
newSelection = self._getSelection()
newSelection = objGetter()
if newSelection and newSelection != oldSelection:
log.debug(f"Detected new selection after {elapsed} sec")
break
Expand Down