Repository: nvaccess/nvda

Issue:
include a list of supported UIA patterns into the developer info
hi guys,

inspired by the jaws touch cursor's object properies dialog, I wrote some code to generate a list of supported UIA patterns for the current navigator object. IMHO it would make sense to include such a patterns list into the developer info generated by nvda+f1. 

To use my global plugin, press nvda+shift+f1. If the navigator is placed on a uia object, the patterns list is displayed as a flash message and it's also written to the nvda log (as an info istring). If the navigator isn't placed onto a uia object, an error message is displayed.

I've tested the global plugin with various (non)UIA objects in Windows 7 x64 as well as in Kaspersky Internet Security 2016.

You can get the global plugin from my dropbox: https://dl.dropboxusercontent.com/u/67471/uia_patterns.py

happy testing

Dave



Discussion:
Hi, Could you attach the plug-in as a zip file so someone can code review it? Note that UIA patterns wil work well for UIA objects (there are broken UIA objects, so be careful with those). Thanks.

From: dave090679 [mailto:notifications@github.com] 
Sent: Tuesday, January 26, 2016 2:26 AM
To: nvaccess/nvda nvda@noreply.github.com
Subject: [nvda] include a list of supported UIA patterns into the developer info (#5712)

hi guys,

inspired by the jaws touch cursor's object properies dialog, I wrote some code to generate a list of supported UIA patterns for the current navigator object IMHO it would make sense to include such a patterns list into the developer info generated by nvda+f1 

To use my global plugin, press nvda+shift+f1 If the navigator is placed on a uia object, the patterns list is displayed as a flash message and it's also written to the nvda log (as an info istring) If the navigator isn't placed onto a uia object, an error message is displayed

I've tested the global plugin with various (non)UIA objects in Windows 7 x64 as well as in Kaspersky Internet Security 2016

You can get the global plugin from my dropbox: https://dldropboxusercontentcom/u/67471/uia_patternspy

happy testing

Dave

—
Reply to this email directly or view it on GitHub https://github.com/nvaccess/nvda/issues/5712 .

hi all,

This is a first try attaching my code as a blank .py file. I tried this
using the website, but it told me that "this file type is not supported".

happy testing

Dave

import ui
from logHandler import log
from NVDAObjects.UIA import UIA
import globalPluginHandler
import UIAHandler
import api
class GlobalPlugin(globalPluginHandler.GlobalPlugin):
    __gestures = {
        "kb:nvda+shift+f1": "listsupportedpatterns"
    }
    def script_listsupportedpatterns(self, gesture):
        uiapatternstonames = {
            UIAHandler.UIA_IsAnnotationPatternAvailablePropertyId: 'annotation pattern',
            UIAHandler.UIA_IsDockPatternAvailablePropertyId: 'dock pattern',
            UIAHandler.UIA_IsDragPatternAvailablePropertyId: 'drag pattern',
            UIAHandler.UIA_IsDropTargetPatternAvailablePropertyId: 'drop target pattern',
            UIAHandler.UIA_IsExpandCollapsePatternAvailablePropertyId: 'expand and collapse pattern',
            UIAHandler.UIA_IsGridItemPatternAvailablePropertyId: 'grid item pattern',
            UIAHandler.UIA_IsGridPatternAvailablePropertyId: 'grid pattern',
            UIAHandler.UIA_IsInvokePatternAvailablePropertyId: 'invoke pattern',
            UIAHandler.UIA_IsItemContainerPatternAvailablePropertyId: 'item container pattern',
            UIAHandler.UIA_IsLegacyIAccessiblePatternAvailablePropertyId: 'legacy IAccessible pattern',
            UIAHandler.UIA_IsMultipleViewPatternAvailablePropertyId: 'multiple view pattern',
            UIAHandler.UIA_IsObjectModelPatternAvailablePropertyId: 'object model pattern',
            UIAHandler.UIA_IsRangeValuePatternAvailablePropertyId: 'range value pattern',
            UIAHandler.UIA_IsScrollItemPatternAvailablePropertyId: 'scroll item pattern',
            UIAHandler.UIA_IsScrollPatternAvailablePropertyId: 'scroll pattern',
            UIAHandler.UIA_IsSelectionItemPatternAvailablePropertyId: 'selection item pattern',
            UIAHandler.UIA_IsSelectionPatternAvailablePropertyId: 'selection pattern',
            UIAHandler.UIA_IsSpreadsheetItemPatternAvailablePropertyId: 'spread sheet item pattern',
            UIAHandler.UIA_IsSpreadsheetPatternAvailablePropertyId: 'spread sheet pattern',
            UIAHandler.UIA_IsStylesPatternAvailablePropertyId: 'style pattern',
            UIAHandler.UIA_IsSynchronizedInputPatternAvailablePropertyId: 'Synchronized input pattern',
            UIAHandler.UIA_IsTableItemPatternAvailablePropertyId: 'table item patern',
            UIAHandler.UIA_IsTablePatternAvailablePropertyId: 'table pattern',
            UIAHandler.UIA_IsTextChildPatternAvailablePropertyId: 'text child pattern',
            UIAHandler.UIA_IsTextEditPatternAvailablePropertyId: 'text edit pattern',
            UIAHandler.UIA_IsTextPattern2AvailablePropertyId: 'text pattern 2',
            UIAHandler.UIA_IsTextPatternAvailablePropertyId: 'text pattern',
            UIAHandler.UIA_IsTogglePatternAvailablePropertyId: 'toggle pattern',
            UIAHandler.UIA_IsTransformPattern2AvailablePropertyId: 'transform pattern 2',
            UIAHandler.UIA_IsTransformPatternAvailablePropertyId: 'transform pattern',
            UIAHandler.UIA_IsValuePatternAvailablePropertyId: 'value pattern',
            UIAHandler.UIA_IsVirtualizedItemPatternAvailablePropertyId: 'virtualized item pattern',
            UIAHandler.UIA_IsWindowPatternAvailablePropertyId: 'window pattern'
        }
        l = list()
        nav = api.getNavigatorObject()
        if not isinstance(nav, UIA):
            ui.message('the current navigator object is not a uia object.')
            return
        else:
            for p in uiapatternstonames.keys():
                result = False
                try:
                    result = nav.UIAElement.GetCurrentPropertyValue(p)
                except:
                    pass
                if result:
                    l.append(uiapatternstonames[p])
            str = ', '.join(l)
            if str:
                log.info('supported patterns for navigator object: '+str)
                ui.message(str)

hi all,

this is a second try to attach the code as a 7zip compressed zip file.
When I try to do this using the website, it says that it "cannot process
the file".

happy testing

Dave

Simply rename the .py to .py.txt and it should work.
Thanks.

On 1/27/2016 12:21 AM, dave090679 wrote:

> hi all,
> 
> this is a second try to attach the code as a 7zip compressed zip file.
> When I try to do this using the website, it says that it "cannot process
> the file".
> 
> happy testing
> 
> Dave
> 
> —
> Reply to this email directly or view it on GitHub 
> https://github.com/nvaccess/nvda/issues/5712#issuecomment-175459719.

## 

---

```
Derek Riemer
```
- Department of computer science, third year undergraduate student.
- Proud user of the NVDA screen reader.
- Open source enthusiast.
- Member of Bridge Cu
- Avid skiier.

Websites:
Honors portfolio http://derekriemer.com
Awesome little hand built weather app! 
http://django.derekriemer.com/weather/

email me at derek.riemer@colorado.edu mailto:derek.riemer@colorado.edu
Phone: (303) 906-2194

Hi Drek,

Here comes a third (and I hope final) Try to attach a file. This time,
It is a py.txt renames copy of the source code.

happy testing

Dave

import ui
from logHandler import log
from NVDAObjects.UIA import UIA
import globalPluginHandler
import UIAHandler
import api
class GlobalPlugin(globalPluginHandler.GlobalPlugin):
    __gestures = {
        "kb:nvda+shift+f1": "listsupportedpatterns"
    }
    def script_listsupportedpatterns(self, gesture):
        uiapatternstonames = {
            UIAHandler.UIA_IsAnnotationPatternAvailablePropertyId: 'annotation pattern',
            UIAHandler.UIA_IsDockPatternAvailablePropertyId: 'dock pattern',
            UIAHandler.UIA_IsDragPatternAvailablePropertyId: 'drag pattern',
            UIAHandler.UIA_IsDropTargetPatternAvailablePropertyId: 'drop target pattern',
            UIAHandler.UIA_IsExpandCollapsePatternAvailablePropertyId: 'expand and collapse pattern',
            UIAHandler.UIA_IsGridItemPatternAvailablePropertyId: 'grid item pattern',
            UIAHandler.UIA_IsGridPatternAvailablePropertyId: 'grid pattern',
            UIAHandler.UIA_IsInvokePatternAvailablePropertyId: 'invoke pattern',
            UIAHandler.UIA_IsItemContainerPatternAvailablePropertyId: 'item container pattern',
            UIAHandler.UIA_IsLegacyIAccessiblePatternAvailablePropertyId: 'legacy IAccessible pattern',
            UIAHandler.UIA_IsMultipleViewPatternAvailablePropertyId: 'multiple view pattern',
            UIAHandler.UIA_IsObjectModelPatternAvailablePropertyId: 'object model pattern',
            UIAHandler.UIA_IsRangeValuePatternAvailablePropertyId: 'range value pattern',
            UIAHandler.UIA_IsScrollItemPatternAvailablePropertyId: 'scroll item pattern',
            UIAHandler.UIA_IsScrollPatternAvailablePropertyId: 'scroll pattern',
            UIAHandler.UIA_IsSelectionItemPatternAvailablePropertyId: 'selection item pattern',
            UIAHandler.UIA_IsSelectionPatternAvailablePropertyId: 'selection pattern',
            UIAHandler.UIA_IsSpreadsheetItemPatternAvailablePropertyId: 'spread sheet item pattern',
            UIAHandler.UIA_IsSpreadsheetPatternAvailablePropertyId: 'spread sheet pattern',
            UIAHandler.UIA_IsStylesPatternAvailablePropertyId: 'style pattern',
            UIAHandler.UIA_IsSynchronizedInputPatternAvailablePropertyId: 'Synchronized input pattern',
            UIAHandler.UIA_IsTableItemPatternAvailablePropertyId: 'table item patern',
            UIAHandler.UIA_IsTablePatternAvailablePropertyId: 'table pattern',
            UIAHandler.UIA_IsTextChildPatternAvailablePropertyId: 'text child pattern',
            UIAHandler.UIA_IsTextEditPatternAvailablePropertyId: 'text edit pattern',
            UIAHandler.UIA_IsTextPattern2AvailablePropertyId: 'text pattern 2',
            UIAHandler.UIA_IsTextPatternAvailablePropertyId: 'text pattern',
            UIAHandler.UIA_IsTogglePatternAvailablePropertyId: 'toggle pattern',
            UIAHandler.UIA_IsTransformPattern2AvailablePropertyId: 'transform pattern 2',
            UIAHandler.UIA_IsTransformPatternAvailablePropertyId: 'transform pattern',
            UIAHandler.UIA_IsValuePatternAvailablePropertyId: 'value pattern',
            UIAHandler.UIA_IsVirtualizedItemPatternAvailablePropertyId: 'virtualized item pattern',
            UIAHandler.UIA_IsWindowPatternAvailablePropertyId: 'window pattern'
        }
        l = list()
        nav = api.getNavigatorObject()
        if not isinstance(nav, UIA):
            ui.message('the current navigator object is not a uia object.')
            return
        else:
            for p in uiapatternstonames.keys():
                result = False
                try:
                    result = nav.UIAElement.GetCurrentPropertyValue(p)
                except:
                    pass
                if result:
                    l.append(uiapatternstonames[p])
            str = ', '.join(l)
            if str:
                log.info('supported patterns for navigator object: '+str)
                ui.message(str)

I came across this and really find this interesting. @michaeldcurran, @dkager, @josephsl: What do you think? If you agree with the approach used here, I'd be happy to create a pr with this functionality integrated into the developer info.
Hi, don’t forget to keep this info updated with new Windows 10 releases. Thanks.

 

From: Leonard de Ruijter [mailto:notifications@github.com] 
Sent: Friday, February 9, 2018 12:34 PM
To: nvaccess/nvda <nvda@noreply.github.com>
Cc: Joseph Lee <joseph.lee22590@gmail.com>; Mention <mention@noreply.github.com>
Subject: Re: [nvaccess/nvda] include a list of supported UIA patterns into the developer info (#5712)

 

I came across this and really find this interesting. @michaelDCurran <https://github.com/michaeldcurran> , @dkager <https://github.com/dkager> , @josephsl <https://github.com/josephsl> : What do you think? If you agree with the approach used here, I'd be happy to create a pr with this functionality integrated into the developer info.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <https://github.com/nvaccess/nvda/issues/5712#issuecomment-364557488> , or mute the thread <https://github.com/notifications/unsubscribe-auth/AHgLkJTcPkOtTIonW0i31ThYMRVw62hpks5tTKurgaJpZM4HMXyu> .


I'd like to have an implementation based on the AutoProperty getters that are available on an object.


Resolving patch:
diff --git a/source/NVDAObjects/UIA/__init__.py b/source/NVDAObjects/UIA/__init__.py
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -2,7 +2,7 @@
 #A part of NonVisual Desktop Access (NVDA)
 #This file is covered by the GNU General Public License.
 #See the file COPYING for more details.
-#Copyright (C) 2009-2017 NV Access Limited, Joseph Lee, Mohammad Suliman
+#Copyright (C) 2009-2018 NV Access Limited, Joseph Lee, Mohammad Suliman, Babbage B.V.
 
 """Support for UI Automation (UIA) controls."""
 
@@ -712,7 +712,10 @@ def _prefetchUIACacheForPropertyIDs(self,IDs):
 			return
 		cacheRequest=UIAHandler.handler.clientObject.createCacheRequest()
 		for ID in IDs:
-			cacheRequest.addProperty(ID)
+			try:
+				cacheRequest.addProperty(ID)
+			except COMError:
+				log.debug("Couldn't add property ID %d to cache request, most likely unsupported on this version of Windows"%ID)
 		cacheElement=self.UIAElement.buildUpdatedCache(cacheRequest)
 		for ID in IDs:
 			elementCache[ID]=cacheElement
@@ -964,6 +967,21 @@ def _get_devInfo(self):
 		except Exception as e:
 			ret="Exception: %s"%e
 		info.append("UIA className: %s"%ret)
+		patternsAvailable = []
+		patternAvailableConsts = dict(
+			(const, name) for name, const in UIAHandler.__dict__.iteritems()
+			if name.startswith("UIA_Is") and name.endswith("PatternAvailablePropertyId")
+		)
+		self._prefetchUIACacheForPropertyIDs(list(patternAvailableConsts))
+		for const, name in patternAvailableConsts.iteritems():
+			try:
+				res = self._getUIACacheablePropertyValue(const)
+			except COMError:
+				res = False
+			if res:
+				# Every name has the same format, so the string indexes can be safely hardcoded here.
+				patternsAvailable.append(name[6:-19])
+		info.append("UIA patterns available: %s"%", ".join(patternsAvailable))
 		return info
 
 	def _get_name(self):


Test patch: