Skip to content

Commit f166fe8

Browse files
authored
Merge d6e6c6c into 64b6074
2 parents 64b6074 + d6e6c6c commit f166fe8

3 files changed

Lines changed: 109 additions & 1 deletion

File tree

source/NVDAObjects/UIA/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,10 @@ def findOverlayClasses(self,clsList):
12161216
else:
12171217
clsList.append(winConsoleUIA._DiffBasedWinTerminalUIA)
12181218

1219+
elif "SysListView32" in self.windowClassName:
1220+
from . import sysListView32
1221+
sysListView32.findExtraOverlayClasses(self, clsList)
1222+
12191223
# Add editableText support if UIA supports a text pattern
12201224
if self.TextInfo==UIATextInfo:
12211225
if UIAHandler.autoSelectDetectionAvailable:
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# A part of NonVisual Desktop Access (NVDA)
2+
# Copyright (C) 2023 NV Access Limited, Leonard de Ruijter
3+
# This file is covered by the GNU General Public License.
4+
# See the file COPYING for more details.
5+
6+
7+
"""Module for native UIA implementations of SysListView32, e.g. in Windows Forms."""
8+
9+
from comtypes import COMError
10+
import config
11+
from config.configFlags import ReportTableHeaders
12+
import UIAHandler
13+
from ..behaviors import RowWithFakeNavigation
14+
from . import ListItem, UIA
15+
16+
17+
def findExtraOverlayClasses(obj, clsList):
18+
UIAControlType = obj.UIAElement.cachedControlType
19+
if UIAControlType == UIAHandler.UIA.UIA_ListItemControlTypeId:
20+
clsList.insert(0, SysListViewItem)
21+
if UIAControlType == UIAHandler.UIA.UIA_ListControlTypeId:
22+
clsList.insert(0, SysListViewList)
23+
24+
25+
class SysListViewList(UIA):
26+
...
27+
28+
29+
class SysListViewItem(RowWithFakeNavigation, ListItem):
30+
31+
def _get_name(self):
32+
parent = self.parent
33+
if not isinstance(parent, SysListViewList) or self.childCount <= 1:
34+
return super().name
35+
childrenCacheRequest = UIAHandler.handler.baseCacheRequest.clone()
36+
childrenCacheRequest.addProperty(UIAHandler.UIA.UIA_NamePropertyId)
37+
childrenCacheRequest.addProperty(UIAHandler.UIA.UIA_TableItemColumnHeaderItemsPropertyId)
38+
childrenCacheRequest.TreeScope = UIAHandler.TreeScope_Children
39+
cachedChildren = self.UIAElement.buildUpdatedCache(childrenCacheRequest).getCachedChildren()
40+
if not cachedChildren:
41+
# There are no children
42+
return super().name
43+
textList = []
44+
for index in range(cachedChildren.length):
45+
e = cachedChildren.getElement(index)
46+
name = e.cachedName
47+
columnHeaderTextList = []
48+
if name and config.conf['documentFormatting']['reportTableHeaders'] in (
49+
ReportTableHeaders.ROWS_AND_COLUMNS,
50+
ReportTableHeaders.COLUMNS,
51+
) and index > 0:
52+
columnHeaderItems = e.getCachedPropertyValueEx(
53+
UIAHandler.UIA.UIA_TableItemColumnHeaderItemsPropertyId,
54+
True
55+
)
56+
else:
57+
columnHeaderItems = None
58+
if columnHeaderItems:
59+
columnHeaderItems = columnHeaderItems.QueryInterface(UIAHandler.IUIAutomationElementArray)
60+
for innerIndex in range(columnHeaderItems.length):
61+
columnHeaderItem = columnHeaderItems.getElement(innerIndex)
62+
columnHeaderTextList.append(columnHeaderItem.currentName)
63+
columnHeaderText = " ".join(columnHeaderTextList)
64+
if columnHeaderText:
65+
text = f"{columnHeaderText} {name}"
66+
else:
67+
text = name
68+
textList.append(text)
69+
return "; ".join(textList)
70+
71+
def _get_indexInParent(self):
72+
parent = self.parent
73+
if not isinstance(parent, SysListViewList) or self.childCount == 0:
74+
return super().rowNumber
75+
childCacheRequest = UIAHandler.handler.baseCacheRequest.clone()
76+
childCacheRequest.addProperty(UIAHandler.UIA.UIA_GridItemRowPropertyId)
77+
element = UIAHandler.handler.baseTreeWalker.GetFirstChildElementBuildCache(
78+
self.UIAElement,
79+
childCacheRequest
80+
)
81+
val = element.getCachedPropertyValueEx(
82+
UIAHandler.UIA.UIA_GridItemRowPropertyId,
83+
True
84+
)
85+
if val == UIAHandler.handler.reservedNotSupportedValue:
86+
return super().indexInParent
87+
return val
88+
89+
def _get_positionInfo(self):
90+
info = super().positionInfo or {}
91+
itemIndex = 0
92+
try:
93+
itemIndex = self.indexInParent + 1
94+
except (COMError, NotImplementedError):
95+
pass
96+
if itemIndex > 0:
97+
info['indexInGroup'] = itemIndex
98+
itemCount = 0
99+
try:
100+
itemCount = self.parent.rowCount
101+
except (COMError, NotImplementedError):
102+
pass
103+
if itemCount > 0:
104+
info['similarItemsInGroup'] = itemCount
105+
return info

source/UIAHandler/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@
9797
"RichEdit",
9898
"RichEdit20",
9999
"RICHEDIT50W",
100-
"SysListView32",
101100
"Button",
102101
# #8944: The Foxit UIA implementation is incomplete and should not be used for now.
103102
"FoxitDocWnd",

0 commit comments

Comments
 (0)