1- # A part of NonVisual Desktop Access (NVDA)
21# This file is covered by the GNU General Public License.
2+ # A part of NonVisual Desktop Access (NVDA)
33# See the file COPYING for more details.
4- # Copyright (C) 2016-2020 NV Access Limited, Joseph Lee
4+ # Copyright (C) 2016-2021 NV Access Limited, Joseph Lee, Jakub Lukowicz
55
66from comtypes import COMError
77from collections import defaultdict
1818from UIAUtils import *
1919from . import UIA , UIATextInfo
2020from NVDAObjects .window .winword import WordDocument as WordDocumentBase
21+ from scriptHandler import script
22+
2123
2224"""Support for Microsoft Word via UI Automation."""
2325
@@ -67,15 +69,37 @@ def getCommentInfoFromPosition(position):
6769 for index in range (UIAElementArray .length ):
6870 UIAElement = UIAElementArray .getElement (index )
6971 UIAElement = UIAElement .buildUpdatedCache (UIAHandler .handler .baseCacheRequest )
70- obj = UIA (UIAElement = UIAElement )
71- if not obj .parent or obj .parent .name != 'Comment' :
72- continue
73- comment = obj .makeTextInfo (textInfos .POSITION_ALL ).text
74- dateObj = obj .previous
75- date = dateObj .name
76- authorObj = dateObj .previous
77- author = authorObj .name
78- return dict (comment = comment ,author = author ,date = date )
72+ typeID = UIAElement .GetCurrentPropertyValue (UIAHandler .UIA_AnnotationAnnotationTypeIdPropertyId )
73+ # Use Annotation Type Comment if available
74+ if typeID == UIAHandler .AnnotationType_Comment :
75+ comment = UIAElement .GetCurrentPropertyValue (UIAHandler .UIA_NamePropertyId )
76+ author = UIAElement .GetCurrentPropertyValue (UIAHandler .UIA_AnnotationAuthorPropertyId )
77+ date = UIAElement .GetCurrentPropertyValue (UIAHandler .UIA_AnnotationDateTimePropertyId )
78+ return dict (comment = comment ,author = author ,date = date )
79+ else :
80+ obj = UIA (UIAElement = UIAElement )
81+ if (
82+ not obj .parent
83+ # Because the name of this object is language sensetive check if it has UIA Annotation Pattern
84+ or not obj .parent .UIAElement .getCurrentPropertyValue (UIAHandler .UIA_IsAnnotationPatternAvailablePropertyId )
85+ ):
86+ continue
87+ comment = obj .makeTextInfo (textInfos .POSITION_ALL ).text
88+ tempObj = obj .previous .previous
89+ authorObj = tempObj or obj .previous
90+ author = authorObj .name
91+ if not tempObj :
92+ return dict (comment = comment , author = author )
93+ dateObj = obj .previous
94+ date = dateObj .name
95+ return dict (comment = comment ,author = author ,date = date )
96+
97+ def getPresentableCommentInfoFromPosition (commentInfo ):
98+ if "date" not in commentInfo :
99+ # Translators: The message reported for a comment in Microsoft Word
100+ return _ ("Comment: {comment} by {author}" ).format (** commentInfo )
101+ # Translators: The message reported for a comment in Microsoft Word
102+ return _ ("Comment: {comment} by {author} on {date}" ).format (** commentInfo )
79103
80104class CommentUIATextInfoQuickNavItem (TextAttribUIATextInfoQuickNavItem ):
81105 attribID = UIAHandler .UIA_AnnotationTypesAttributeId
@@ -84,8 +108,7 @@ class CommentUIATextInfoQuickNavItem(TextAttribUIATextInfoQuickNavItem):
84108 @property
85109 def label (self ):
86110 commentInfo = getCommentInfoFromPosition (self .textInfo )
87- # Translators: The message reported for a comment in Microsoft Word
88- return _ ("Comment: {comment} by {author} on {date}" ).format (** commentInfo )
111+ return getPresentableCommentInfoFromPosition (commentInfo )
89112
90113class WordDocumentTextInfo (UIATextInfo ):
91114
@@ -329,31 +352,17 @@ def event_UIA_notification(self, activityId=None, **kwargs):
329352 return
330353 super (WordDocument , self ).event_UIA_notification (** kwargs )
331354
355+ @script (
356+ gesture = "kb:NVDA+alt+c" ,
357+ # Translators: a description for a script that reports the comment at the caret.
358+ description = _ ("Reports the text of the comment where the System caret is located." )
359+ )
332360 def script_reportCurrentComment (self ,gesture ):
333361 caretInfo = self .makeTextInfo (textInfos .POSITION_CARET )
334- caretInfo .expand (textInfos .UNIT_CHARACTER )
335- val = caretInfo ._rangeObj .getAttributeValue (UIAHandler .UIA_AnnotationObjectsAttributeId )
336- if not val :
337- return
338- try :
339- UIAElementArray = val .QueryInterface (UIAHandler .IUIAutomationElementArray )
340- except COMError :
341- return
342- for index in range (UIAElementArray .length ):
343- UIAElement = UIAElementArray .getElement (index )
344- UIAElement = UIAElement .buildUpdatedCache (UIAHandler .handler .baseCacheRequest )
345- obj = UIA (UIAElement = UIAElement )
346- if not obj .parent or obj .parent .name != 'Comment' :
347- continue
348- comment = obj .makeTextInfo (textInfos .POSITION_ALL ).text
349- dateObj = obj .previous
350- date = dateObj .name
351- authorObj = dateObj .previous
352- author = authorObj .name
353- # Translators: The message reported for a comment in Microsoft Word
354- ui .message (_ ("{comment} by {author} on {date}" ).format (comment = comment ,date = date ,author = author ))
355- return
356-
357- __gestures = {
358- "kb:NVDA+alt+c" :"reportCurrentComment" ,
359- }
362+ commentInfo = getCommentInfoFromPosition (caretInfo )
363+ if commentInfo is not None :
364+ ui .message (getPresentableCommentInfoFromPosition (commentInfo ))
365+ else :
366+ # Translators: a message when there is no comment to report in Microsoft Word
367+ ui .message (_ ("No comments" ))
368+ return
0 commit comments