commit/nvda: 157 new changesets

  • From: commits-noreply@xxxxxxxxxxxxx
  • To: nvda-addons-commits@xxxxxxxxxxxxx
  • Date: Tue, 04 Aug 2015 18:21:55 -0000

157 new commits in nvda:

https://bitbucket.org/nvdaaddonteam/nvda/commits/673468d638ec/
Changeset: 673468d638ec
Branch: None
User: mdcurran
Date: 2015-05-29 02:41:29+00:00
Summary: Explorer appModule: suppress focus events on the Win 10 Task
switch window as they are redundant and confuse focus ancestry reporting.

Affected #: 1 file

diff --git a/source/appModules/explorer.py b/source/appModules/explorer.py
index 1ff91bb..a606376 100644
--- a/source/appModules/explorer.py
+++ b/source/appModules/explorer.py
@@ -17,6 +17,10 @@ from NVDAObjects.window import Window
from NVDAObjects.IAccessible import sysListView32, IAccessible
from NVDAObjects.UIA import UIA

+# Suppress incorrect Win 10 Task switching window focus
+class MultitaskingViewFrameWindow(UIA):
+ shouldAllowUIAFocusEvent=False
+
# support for Win8 start screen search suggestions.
class SuggestionListItem(UIA):

@@ -175,6 +179,8 @@ class AppModule(appModuleHandler.AppModule):
clsList.insert(0, ImmersiveLauncher)
elif uiaClassName=="ListViewItem" and
obj.UIAElement.cachedAutomationId.startswith('Suggestion_'):
clsList.insert(0,SuggestionListItem)
+ elif uiaClassName=="MultitaskingViewFrame" and
role==controlTypes.ROLE_WINDOW:
+ clsList.insert(0,MultitaskingViewFrameWindow)

def event_NVDAObject_init(self, obj):
windowClass = obj.windowClassName


https://bitbucket.org/nvdaaddonteam/nvda/commits/76468b9e89f7/
Changeset: 76468b9e89f7
Branch: None
User: mdcurran
Date: 2015-05-31 04:10:16+00:00
Summary: Add a new treeInterceptorHandler.RootProxyTextInfo which redirects
its methods to the associated TreeInterceptor's TextInfo. Make MS Word
browseMode use this instead of its own version. Also move some review handling
code out of MS Word's treeInterceptor into cursorManager to help other
implementations.

Affected #: 3 files

diff --git a/source/NVDAObjects/window/winword.py
b/source/NVDAObjects/window/winword.py
index de03364..e1dc598 100755
--- a/source/NVDAObjects/window/winword.py
+++ b/source/NVDAObjects/window/winword.py
@@ -796,66 +796,18 @@ class
WordDocumentTextInfoForTreeInterceptor(WordDocumentTextInfo):
def _get_shouldIncludeLayoutTables(self):
return config.conf['documentFormatting']['includeLayoutTables']

-class BrowseModeWordDocumentTextInfo(textInfos.TextInfo):
+class BrowseModeWordDocumentTextInfo(treeInterceptorHandler.RootProxyTextInfo):

def __init__(self,obj,position,_rangeObj=None):
if isinstance(position,WordDocument):
position=textInfos.POSITION_CARET
-
super(BrowseModeWordDocumentTextInfo,self).__init__(obj,position)
-
self.innerTextInfo=WordDocumentTextInfoForTreeInterceptor(obj.rootNVDAObject,position,_rangeObj=_rangeObj)
+
super(BrowseModeWordDocumentTextInfo,self).__init__(obj,position,_rangeObj=_rangeObj)

- def _get__rangeObj(self):
- return self.innerTextInfo._rangeObj
-
- def find(self,text,caseSensitive=False,reverse=False):
- return self.innerTextInfo.find(text,caseSensitive,reverse)
-
- def copy(self):
- return
BrowseModeWordDocumentTextInfo(self.obj,None,_rangeObj=self.innerTextInfo._rangeObj)
-
- def activate(self):
- return self.innerTextInfo.activate()
-
- def compareEndPoints(self,other,which):
- return
self.innerTextInfo.compareEndPoints(other.innerTextInfo,which)
-
- def setEndPoint(self,other,which):
- return self.innerTextInfo.setEndPoint(other.innerTextInfo,which)
-
- def _get_isCollapsed(self):
- return self.innerTextInfo.isCollapsed
-
- def collapse(self,end=False):
- return self.innerTextInfo.collapse(end=end)
-
- def move(self,unit,direction,endPoint=None):
- return self.innerTextInfo.move(unit,direction,endPoint=endPoint)
-
- def _get_bookmark(self):
- return self.innerTextInfo.bookmark
-
- def updateCaret(self):
- return self.innerTextInfo.updateCaret()
-
- def updateSelection(self):
- return self.innerTextInfo.updateSelection()
-
- def _get_text(self):
- return self.innerTextInfo.text
-
- def getTextWithFields(self,formatConfig=None):
- return
self.innerTextInfo.getTextWithFields(formatConfig=formatConfig)
-
- def expand(self,unit):
- return self.innerTextInfo.expand(unit)
-
- def getMathMl(self, field):
- return self.innerTextInfo.getMathMl(field)
+ InnerTextInfoClass=WordDocumentTextInfoForTreeInterceptor

class
WordDocumentTreeInterceptor(CursorManager,browseMode.BrowseModeTreeInterceptor,treeInterceptorHandler.DocumentTreeInterceptor):

TextInfo=BrowseModeWordDocumentTextInfo
- needsReviewCursorTextInfoWrapper=False

def _get_isAlive(self):
return winUser.isWindow(self.rootNVDAObject.windowHandle)
@@ -863,10 +815,6 @@ class
WordDocumentTreeInterceptor(CursorManager,browseMode.BrowseModeTreeInterce
def __contains__(self,obj):
return obj==self.rootNVDAObject

- def _set_selection(self,info):
- super(WordDocumentTreeInterceptor,self)._set_selection(info)
- review.handleCaretMove(info)
-
def _get_ElementsListDialog(self):
return ElementsListDialog

@@ -911,10 +859,6 @@ class
WordDocumentTreeInterceptor(CursorManager,browseMode.BrowseModeTreeInterce
else:
raise NotImplementedError

- def event_gainFocus(self,obj,nextHandler):
- obj.reportFocus()
- braille.handler.handleGainFocus(self)
-
def script_nextRow(self,gesture):
self.rootNVDAObject._moveInTable(row=True,forward=True)
braille.handler.handleCaretMove(self)

diff --git a/source/cursorManager.py b/source/cursorManager.py
index 8d681e3..1387ffd 100644
--- a/source/cursorManager.py
+++ b/source/cursorManager.py
@@ -102,6 +102,7 @@ class CursorManager(baseObject.ScriptableObject):

def _set_selection(self, info):
info.updateSelection()
+ review.handleCaretMove(info)
braille.handler.handleCaretMove(self)

def
_caretMovementScriptHelper(self,gesture,unit,direction=None,posConstant=textInfos.POSITION_SELECTION,posUnit=None,posUnitEnd=False,extraDetail=False,handleSymbols=False):

diff --git a/source/treeInterceptorHandler.py b/source/treeInterceptorHandler.py
index 55b2b19..af2a0f7 100644
--- a/source/treeInterceptorHandler.py
+++ b/source/treeInterceptorHandler.py
@@ -8,6 +8,7 @@ from logHandler import log
import baseObject
import api
import review
+import textInfos
import config
import braille

@@ -132,6 +133,10 @@ class TreeInterceptor(baseObject.ScriptableObject):
"""Prepares this treeInterceptor so that it becomes ready to
accept event/script input."""
raise NotImplementedError

+ def event_gainFocus(self,obj,nextHandler):
+ obj.reportFocus()
+ braille.handler.handleGainFocus(self)
+
class DocumentTreeInterceptor(TreeInterceptor):
"""A TreeInterceptor that supports document review."""

@@ -141,3 +146,62 @@ class DocumentTreeInterceptor(TreeInterceptor):
def makeTextInfo(self,position):
return self.TextInfo(self,position)

+class RootProxyTextInfo(textInfos.TextInfo):
+
+ def __init__(self,obj,position,_rangeObj=None):
+ super(RootProxyTextInfo,self).__init__(obj,position)
+
self.innerTextInfo=self.InnerTextInfoClass(obj.rootNVDAObject,position,_rangeObj=_rangeObj)
+
+ def _get_InnerTextInfoClass(self):
+ return self.obj.rootNVDAObject.TextInfo
+
+ def copy(self):
+ return
self.__class__(self.obj,None,_rangeObj=self.innerTextInfo._rangeObj)
+
+ def _get__rangeObj(self):
+ return self.innerTextInfo._rangeObj
+
+ def find(self,text,caseSensitive=False,reverse=False):
+ return self.innerTextInfo.find(text,caseSensitive,reverse)
+
+ def activate(self):
+ return self.innerTextInfo.activate()
+
+ def compareEndPoints(self,other,which):
+ return
self.innerTextInfo.compareEndPoints(other.innerTextInfo,which)
+
+ def setEndPoint(self,other,which):
+ return self.innerTextInfo.setEndPoint(other.innerTextInfo,which)
+
+ def _get_isCollapsed(self):
+ return self.innerTextInfo.isCollapsed
+
+ def collapse(self,end=False):
+ return self.innerTextInfo.collapse(end=end)
+
+ def move(self,unit,direction,endPoint=None):
+ return self.innerTextInfo.move(unit,direction,endPoint=endPoint)
+
+ def _get_bookmark(self):
+ return self.innerTextInfo.bookmark
+
+ def updateCaret(self):
+ return self.innerTextInfo.updateCaret()
+
+ def updateSelection(self):
+ return self.innerTextInfo.updateSelection()
+
+ def _get_text(self):
+ return self.innerTextInfo.text
+
+ def getTextWithFields(self,formatConfig=None):
+ return
self.innerTextInfo.getTextWithFields(formatConfig=formatConfig)
+
+ def expand(self,unit):
+ return self.innerTextInfo.expand(unit)
+
+ def getMathMl(self, field):
+ return self.innerTextInfo.getMathMl(field)
+
+ def _get_NVDAObjectAtStart(self):
+ return self.innerTextInfo.NVDAObjectAtStart


https://bitbucket.org/nvdaaddonteam/nvda/commits/d0307b317850/
Changeset: d0307b317850
Branch: None
User: mdcurran
Date: 2015-05-31 04:15:57+00:00
Summary: Make UIATextInfo more compatible with MS Word TextInfo and
RootProxyTextInfo so that the native range can be passed in in instantiation
with a _rangeObj keyword argument.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 68a12dd..451a89a 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -49,10 +49,10 @@ class UIATextInfo(textInfos.TextInfo):

formatField["heading-level"]=(styleIDValue-UIAHandler.StyleId_Heading1)+1
return textInfos.FieldCommand("formatChange",formatField)

- def __init__(self,obj,position):
+ def __init__(self,obj,position,_rangeObj=None):
super(UIATextInfo,self).__init__(obj,position)
- if isinstance(position,UIAHandler.IUIAutomationTextRange):
- self._rangeObj=position
+ if _rangeObj:
+ self._rangeObj=_rangeObj.clone()
elif position in
(textInfos.POSITION_CARET,textInfos.POSITION_SELECTION):
sel=self.obj.UIATextPattern.GetSelection()
if sel.length>0:
@@ -72,7 +72,10 @@ class UIATextInfo(textInfos.TextInfo):
elif position==textInfos.POSITION_ALL:
self._rangeObj=self.obj.UIATextPattern.documentRange
elif isinstance(position,UIA):
-
self._rangeObj=self.obj.UIATextPattern.rangeFromChild(position.UIAElement)
+ try:
+
self._rangeObj=self.obj.UIATextPattern.rangeFromChild(position.UIAElement)
+ except COMError:
+ raise LookupError
elif isinstance(position,textInfos.Point):
#rangeFromPoint causes a freeze in UIA client library!
#p=POINT(position.x,position.y)
@@ -88,10 +91,9 @@ class UIATextInfo(textInfos.TextInfo):

def _get_NVDAObjectAtStart(self):
tempRange=self._rangeObj.clone()
-
tempRange.moveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_End,tempRange,UIAHandler.TextPatternRangeEndpoint_Start)
- e=tempRange.getEnclosingElement()
-
obj=UIA(UIAElement=e.buildUpdatedCache(UIAHandler.handler.baseCacheRequest))
- return obj if obj else self.obj
+
tempRange.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_End,tempRange,UIAHandler.TextPatternRangeEndpoint_Start)
+ child=tempRange.getEnclosingElement()
+ return
UIA(UIAElement=child.buildUpdatedCache(UIAHandler.handler.baseCacheRequest)) or
self.obj

def _get_bookmark(self):
return self.copy()
@@ -249,7 +251,7 @@ class UIATextInfo(textInfos.TextInfo):
return res

def copy(self):
- return self.__class__(self.obj,self._rangeObj.clone())
+ return self.__class__(self.obj,None,_rangeObj=self._rangeObj)

def collapse(self,end=False):
if end:


https://bitbucket.org/nvdaaddonteam/nvda/commits/d487460b1e0c/
Changeset: d487460b1e0c
Branch: None
User: mdcurran
Date: 2015-05-31 04:19:19+00:00
Summary: UIA: do not check currentHasKeyboardFocus in UIA's focus event
handler, rather check this in shouldAllowUIAFocusEvent. this allows UIA classes
to override this. Also if this property causes a COMError (its broken / not
implemented) do not disallow the focus; possible odd focuses are better than
nothing at all in this case.

Affected #: 2 files

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 451a89a..0163fb4 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -376,7 +376,11 @@ class UIA(Window):
except:
return False

- shouldAllowUIAFocusEvent=True #: UIA focus events can be completely
ignored on this object if set to false.
+ def _get_shouldAllowUIAFocusEvent(self):
+ try:
+ return bool(self.UIAElement.currentHasKeyboardFocus)
+ except COMError:
+ return True

def _getUIAPattern(self,ID,interface):
punk=self.UIAElement.GetCurrentPattern(ID)

diff --git a/source/_UIAHandler.py b/source/_UIAHandler.py
index 066b804..72a9cbe 100644
--- a/source/_UIAHandler.py
+++ b/source/_UIAHandler.py
@@ -203,12 +203,6 @@ class UIAHandler(COMObject):
return
if not self.isNativeUIAElement(sender):
return
- try:
- hasFocus=sender.currentHasKeyboardFocus
- except COMError:
- return
- if not hasFocus:
- return
import NVDAObjects.UIA
if
isinstance(eventHandler.lastQueuedFocusObject,NVDAObjects.UIA.UIA):
lastFocus=eventHandler.lastQueuedFocusObject.UIAElement


https://bitbucket.org/nvdaaddonteam/nvda/commits/cee7ca402fdc/
Changeset: cee7ca402fdc
Branch: None
User: mdcurran
Date: 2015-05-31 04:21:23+00:00
Summary: UIA: add initial support for Edge HTML. It is so far possible to
navigate documents with the arrow keys in Project Spartan and other places. No
quick nav, or clean up of control presentation done yet.

Affected #: 2 files

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 0163fb4..f686cc8 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -294,8 +294,13 @@ class UIA(Window):

UIAControlType=self.UIAElement.cachedControlType
UIAClassName=self.UIAElement.cachedClassName
+ import edge
if UIAClassName=="WpfTextView":
clsList.append(WpfTextView)
+ elif UIAClassName=="Internet Explorer_Server" and
self.role==controlTypes.ROLE_PANE:
+ clsList.append(edge.EdgeHTMLRootContainer)
+ elif isinstance(self.parent,edge.EdgeHTMLRootContainer) and
self.role==controlTypes.ROLE_PANE:
+ clsList.append(edge.EdgeHTMLRoot)
elif UIAClassName=="ToastContentHost" and
UIAControlType==UIAHandler.UIA_ToolTipControlTypeId:
clsList.append(Toast)
if UIAControlType==UIAHandler.UIA_ProgressBarControlTypeId:
@@ -824,3 +829,4 @@ class WpfTextView(UIA):

def event_stateChange(self):
return
+

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
new file mode 100644
index 0000000..5435adc
--- /dev/null
+++ b/source/NVDAObjects/UIA/edge.py
@@ -0,0 +1,56 @@
+#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) 2015 NV Access Limited
+
+from comtypes import COMError
+import eventHandler
+import controlTypes
+import winUser
+import browseMode
+import treeInterceptorHandler
+import cursorManager
+from . import UIA
+
+class EdgeHTMLRootContainer(UIA):
+
+ shouldAllowUIAFocusEvent=True
+
+ def event_gainFocus(self):
+ firstChild=self.firstChild
+ if isinstance(firstChild,UIA):
+ eventHandler.executeEvent("gainFocus",firstChild)
+ return
+ return super(EdgeHTML,self).event_gainFocus()
+
+class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.BrowseModeTreeInterceptor,treeInterceptorHandler.DocumentTreeInterceptor):
+
+ TextInfo=treeInterceptorHandler.RootProxyTextInfo
+
+ def _get_isAlive(self):
+ if not winUser.isWindow(self.rootNVDAObject.windowHandle):
+ return False
+ try:
+
self.rootNVDAObject.UIAElement.currentProviderDescription
+ except COMError:
+ return False
+ return True
+
+ def __contains__(self,obj):
+ if not isinstance(obj,UIA):
+ return False
+ try:
+ self.rootNVDAObject.makeTextInfo(obj)
+ except LookupError:
+ return False
+ return True
+
+ def event_gainFocus(self,obj,nextHandler):
+ info=self.makeTextInfo(obj)
+ info.updateCaret()
+ nextHandler()
+
+class EdgeHTMLRoot(UIA):
+
+ treeInterceptorClass=EdgeHTMLTreeInterceptor
+ role=controlTypes.ROLE_DOCUMENT


https://bitbucket.org/nvdaaddonteam/nvda/commits/c938ef0418b3/
Changeset: c938ef0418b3
Branch: None
User: mdcurran
Date: 2015-06-02 08:50:11+00:00
Summary: ReviewCursorManager TextInfo's updateCaret method: only save a
collapsed TextInfo.

Affected #: 1 file

diff --git a/source/cursorManager.py b/source/cursorManager.py
index 1387ffd..6bf030f 100644
--- a/source/cursorManager.py
+++ b/source/cursorManager.py
@@ -354,7 +354,9 @@ class _ReviewCursorManagerTextInfo(textInfos.TextInfo):
"""

def updateCaret(self):
- self.obj.selection = self
+ info=self.copy()
+ info.collapse()
+ self.obj.selection = info

def updateSelection(self):
self.obj.selection = self


https://bitbucket.org/nvdaaddonteam/nvda/commits/6b8f1cc5b984/
Changeset: 6b8f1cc5b984
Branch: None
User: mdcurran
Date: 2015-06-02 08:50:52+00:00
Summary: EdgeHTML browseMode: support links in quick nav and elements list.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index 5435adc..0808689 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -7,6 +7,8 @@ from comtypes import COMError
import eventHandler
import controlTypes
import winUser
+import textInfos
+import UIAHandler
import browseMode
import treeInterceptorHandler
import cursorManager
@@ -23,10 +25,235 @@ class EdgeHTMLRootContainer(UIA):
return
return super(EdgeHTML,self).event_gainFocus()

+def
UIATextAttributeQuickNavIterator(itemType,document,position,attributeID,attributeValue,direction="next"):
+ includeCurrent=False
+ if not position:
+ position=document.makeTextInfo(textInfos.POSITION_ALL)
+ includeCurrent=True
+ elif direction=="previous":
+ position.expand(textInfos.UNIT_CHARACTER)
+ # Hack: IUIAutomationTextRange::FindAttribute breaks after
expand. copy to fix.
+ position=position.copy()
+
position.setEndPoint(document.TextInfo(document,textInfos.POSITION_ALL),"startToStart")
+ else:
+
position.setEndPoint(document.TextInfo(document,textInfos.POSITION_ALL),"endToEnd")
+ while True:
+ try:
+
newRange=position._rangeObj.findAttribute(attributeID,attributeValue,direction=="previous")
+ except COMError:
+ newRange=None
+ if not newRange:
+ return
+ curPosition=document.TextInfo(document,None,_rangeObj=newRange)
+ if includeCurrent or
curPosition.compareEndPoints(position,"startToStart")>0:
+ yield
browseMode.TextInfoQuickNavItem(itemType,document,curPosition)
+ includeCurrent=True
+ position.setEndPoint(curPosition,"endToStart" if
direction=="previous" else "startToEnd")
+
+def UIATextRangeFromElement(documentTextPattern,element):
+ try:
+ childRange=documentTextPattern.rangeFromChild(element)
+ except COMError:
+ childRange=None
+ return childRange
+
+def isUIAElementInWalker(element,walker):
+ try:
+ newElement=walker.normalizeElement(element)
+ except COMError:
+ newElement=None
+ return newElement and
UIAHandler.handler.clientObject.compareElements(element,newElement)
+
+def getDeepestLastChildUIAElementInWalker(element,walker):
+ descended=False
+ while True:
+ lastChild=walker.getLastChildElement(element)
+ if lastChild:
+ descended=True
+ element=lastChild
+ else:
+ break
+ return element if descended else None
+
+def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction="next"):
+ if not position:
+ # All items are request (such as for elements list)
+
elements=document.rootNVDAObject.UIAElement.findAll(UIAHandler.TreeScope_Descendants,UIACondition)
+ for index in xrange(elements.length):
+ element=elements.getElement(index)
+ try:
+
elementRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(element)
+ except COMError:
+ elementRange=None
+ if elementRange:
+
info=document.TextInfo(document,None,_rangeObj=elementRange)
+ yield
browseMode.TextInfoQuickNavItem(itemType,document,info)
+ return
+ if direction=="previous":
+ # Fetching items previous to the given position.
+ toPosition=position.copy()
+ # When getting children of a UIA text range, Edge will
incorrectly include a child that starts at the end of the range.
+ # Therefore move back by one character to stop this.
+ toPosition.move(textInfos.UNIT_CHARACTER,-1)
+ # Extend the start of the range back to the start of the
document so that we will be able to fetch children all the way up to this point.
+
toPosition.setEndPoint(document.TextInfo(document,textInfos.POSITION_ALL),"startToStart")
+ # Fetch the last child of this text range.
+ # But if its own range extends beyond the end of our position:
+ # We know that the child is not the deepest descendant,
+ # And therefore we Limit our children fetching range to the
start of this child,
+ # And fetch the last child again.
+ child=None
+ zoomedOnce=False
+ while True:
+ children=toPosition._rangeObj.getChildren()
+ length=children.length
+ if length==0:
+ break
+ child=children.getElement(length-1)
+ try:
+
childRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(child)
+ except COMError:
+ return
+ if
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_End,position._rangeObj,UIAHandler.TextPatternRangeEndpoint_End)>0
and
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,toPosition._rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)>0:
+
toPosition._rangeObj.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_Start,childRange,UIAHandler.TextPatternRangeEndpoint_Start)
+ zoomedOnce=True
+ continue
+ break
+ if not child:
+ if not zoomedOnce:
+ return
+ # If we have zoomed in at all, yet this level has no
children,
+ # Then we can use the element enclosing this range as
that will be the deepest.
+ child=toPosition._rangeObj.getEnclosingElement()
+ # Work out if this child is previous to our position or not.
+ # If it isn't, then we know we still need to move parent or
previous before it is safe to emit an item.
+ try:
+
childRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(child)
+ except COMError:
+ return
+
gonePreviousOnce=childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_End,position._rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)<=0
+
walker=UIAHandler.handler.clientObject.createTreeWalker(UIACondition)
+ curElement=child
+ # Start traversing from this child backward through the
document, emitting items for valid elements.
+ curElementMatchedCondition=False
+ goneParent=False
+ while curElement:
+ if gonePreviousOnce and not goneParent:
+
lastChild=getDeepestLastChildUIAElementInWalker(curElement,walker)
+ if lastChild:
+ curElement=lastChild
+ curElementMatchedCondition=True
+ elif not curElementMatchedCondition and
isUIAElementInWalker(curElement,walker):
+ curElementMatchedCondition=True
+ if curElementMatchedCondition:
+ yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))
+
previousSibling=walker.getPreviousSiblingElement(curElement)
+ if previousSibling:
+ gonePreviousOnce=True
+ goneParent=False
+ curElement=previousSibling
+ curElementMatchedCondition=True
+ continue
+ parent=walker.getParentElement(curElement)
+ if parent and not
UIAHandler.handler.clientObject.compareElements(document.rootNVDAObject.UIAElement,parent):
+ curElement=parent
+ goneParent=True
+ curElementMatchedCondition=True
+ if gonePreviousOnce:
+ yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))
+ continue
+ curElement=None
+ elif True:
+ # Fetching items after the given position.
+ toPosition=position.copy()
+ # Extend the end of the range forward to the end of the
document so that we will be able to fetch children from this point onwards.
+
toPosition.setEndPoint(document.TextInfo(document,textInfos.POSITION_ALL),"endToEnd")
+ # Fetch the first child of this text range.
+ # But if its own range extends before the start of our position:
+ # We know that the child is not the deepest descendant,
+ # And therefore we Limit our children fetching range to the end
of this child,
+ # And fetch the first child again.
+ child=None
+ zoomedOnce=False
+ while True:
+ children=toPosition._rangeObj.getChildren()
+ length=children.length
+ if length==0:
+ break
+ child=children.getElement(0)
+ try:
+
childRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(child)
+ except COMError:
+ return
+ print "childRange text: %s"%childRange.getText(-1)
+ if
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,position._rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)<0
and
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_End,toPosition._rangeObj,UIAHandler.TextPatternRangeEndpoint_End)<0:
+
toPosition._rangeObj.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_End,childRange,UIAHandler.TextPatternRangeEndpoint_End)
+ zoomedOnce=True
+ continue
+ break
+ if not child:
+ if not zoomedOnce:
+ return
+ # If we have zoomed in at all, yet this level has no
children,
+ # Then we can use the element enclosing this range as
that will be the deepest.
+ child=toPosition._rangeObj.getEnclosingElement()
+ if
UIAHandler.handler.clientObject.comareElements(child,document.rootNVDAObject.UIAElement):
+ import tones; tones.beep(550,50)
+ return
+ # Work out if this child is after our position or not.
+ try:
+
childRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(child)
+ except COMError:
+ return
+ print "childRange text: %s"%childRange.getText(-1)
+
goneNextOnce=childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,position._rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)>0
+ print "goneNextOnce: %s"%goneNextOnce
+
walker=UIAHandler.handler.clientObject.createTreeWalker(UIACondition)
+ curElement=child
+ # If we are already past our position, and this is a valid child
+ # Then we can emmit an item already
+ if goneNextOnce and isUIAElementInWalker(curElement,walker):
+ yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))
+ # Start traversing from this child forwards through the
document, emitting items for valid elements.
+ while curElement:
+ # Ensure this element is really represented in the
document's text.
+ if not
UIATextRangeFromElement(document.rootNVDAObject.UIATextPattern,curElement):
+ return
+ firstChild=walker.getFirstChildElement(curElement)
+ if firstChild:
+ curElement=firstChild
+ yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))
+ continue
+ nextSibling=None
+ while curElement:
+
nextSibling=walker.getNextSiblingElement(curElement)
+ if not nextSibling:
+
parent=walker.getParentElement(curElement)
+ if not parent or not
UIATextRangeFromElement(document.rootNVDAObject.UIATextPattern,parent):
+ return
+ curElement=parent
+ else:
+ break
+ if nextSibling:
+ curElement=nextSibling
+
childRange=UIATextRangeFromElement(document.rootNVDAObject.UIATextPattern,curElement)
+ if not childRange:
+ return
+ yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=childRange))
+ curElement=None
+
class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.BrowseModeTreeInterceptor,treeInterceptorHandler.DocumentTreeInterceptor):

TextInfo=treeInterceptorHandler.RootProxyTextInfo

+ def _iterNodesByType(self,nodeType,direction="next",pos=None):
+ if nodeType=="heading":
+ return
browseMode.mergeQuickNavItemIterators([UIATextAttributeQuickNavIterator("heading",self,pos,UIAHandler.UIA_StyleIdAttributeId,value,direction)
for value in
xrange(UIAHandler.StyleId_Heading1,UIAHandler.StyleId_Heading7)],direction)
+ elif nodeType=="link":
+
condition=UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_ControlTypePropertyId,UIAHandler.UIA_HyperlinkControlTypeId)
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ raise NotImplementedError
+
def _get_isAlive(self):
if not winUser.isWindow(self.rootNVDAObject.windowHandle):
return False


https://bitbucket.org/nvdaaddonteam/nvda/commits/a7eeb4065365/
Changeset: a7eeb4065365
Branch: None
User: mdcurran
Date: 2015-06-03 23:34:25+00:00
Summary: UIA: when sometimes row count and column count are not implemented
on tables -- handle these exceptions.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index f686cc8..6f41e79 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -113,8 +113,11 @@ class UIATextInfo(textInfos.TextInfo):
field["level"] = obj.positionInfo.get("level")
if role == controlTypes.ROLE_TABLE:
field["table-id"] = 1 # FIXME
- field["table-rowcount"] = obj.rowCount
- field["table-columncount"] = obj.columnCount
+ try:
+ field["table-rowcount"] = obj.rowCount
+ field["table-columncount"] = obj.columnCount
+ except NotImplementedError:
+ pass
if role in (controlTypes.ROLE_TABLECELL,
controlTypes.ROLE_TABLECOLUMNHEADER, controlTypes.ROLE_TABLEROWHEADER):
field["table-id"] = 1 # FIXME
field["table-rownumber"] = obj.rowNumber


https://bitbucket.org/nvdaaddonteam/nvda/commits/8b49255851db/
Changeset: 8b49255851db
Branch: None
User: mdcurran
Date: 2015-06-03 23:36:25+00:00
Summary: UIA EdgeHTML browse mode: improve quick nav to controls (so far
just links) to majorly increase performance by ensuring the UIA tree walker
does not walk outside the document, and ensuring we don't collect too many
children when we don't have to.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index 0808689..d4d8ae3 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -4,6 +4,8 @@
#Copyright (C) 2015 NV Access Limited

from comtypes import COMError
+from comtypes.automation import VARIANT
+from ctypes import byref
import eventHandler
import controlTypes
import winUser
@@ -76,8 +78,12 @@ def getDeepestLastChildUIAElementInWalker(element,walker):
return element if descended else None

def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction="next"):
+ # A part from the condition given, we must always match on the root of
the document so we know when to stop walking
+ runtimeID=VARIANT()
+
document.rootNVDAObject.UIAElement._IUIAutomationElement__com_GetCurrentPropertyValue(UIAHandler.UIA_RuntimeIdPropertyId,byref(runtimeID))
+
UIACondition=UIAHandler.handler.clientObject.createOrCondition(UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_RuntimeIdPropertyId,runtimeID),UIACondition)
if not position:
- # All items are request (such as for elements list)
+ # All items are requested (such as for elements list)

elements=document.rootNVDAObject.UIAElement.findAll(UIAHandler.TreeScope_Descendants,UIACondition)
for index in xrange(elements.length):
element=elements.getElement(index)
@@ -91,40 +97,39 @@ def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction
return
if direction=="previous":
# Fetching items previous to the given position.
- toPosition=position.copy()
# When getting children of a UIA text range, Edge will
incorrectly include a child that starts at the end of the range.
# Therefore move back by one character to stop this.
- toPosition.move(textInfos.UNIT_CHARACTER,-1)
- # Extend the start of the range back to the start of the
document so that we will be able to fetch children all the way up to this point.
-
toPosition.setEndPoint(document.TextInfo(document,textInfos.POSITION_ALL),"startToStart")
+ toPosition=position._rangeObj.clone()
+ toPosition.move(UIAHandler.TextUnit_Character,-1)
+ child=toPosition.getEnclosingElement()
+
childRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(child)
+
toPosition.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_Start,childRange,UIAHandler.TextPatternRangeEndpoint_Start)
# Fetch the last child of this text range.
# But if its own range extends beyond the end of our position:
# We know that the child is not the deepest descendant,
# And therefore we Limit our children fetching range to the
start of this child,
# And fetch the last child again.
- child=None
zoomedOnce=False
while True:
- children=toPosition._rangeObj.getChildren()
+ children=toPosition.getChildren()
length=children.length
if length==0:
+ if zoomedOnce:
+ child=toPosition.getEnclosingElement()
break
child=children.getElement(length-1)
try:

childRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(child)
except COMError:
return
- if
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_End,position._rangeObj,UIAHandler.TextPatternRangeEndpoint_End)>0
and
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,toPosition._rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)>0:
-
toPosition._rangeObj.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_Start,childRange,UIAHandler.TextPatternRangeEndpoint_Start)
+ if
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_End,position._rangeObj,UIAHandler.TextPatternRangeEndpoint_End)>0
and
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,toPosition,UIAHandler.TextPatternRangeEndpoint_Start)>0:
+
toPosition.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_Start,childRange,UIAHandler.TextPatternRangeEndpoint_Start)
zoomedOnce=True
continue
break
- if not child:
- if not zoomedOnce:
- return
- # If we have zoomed in at all, yet this level has no
children,
- # Then we can use the element enclosing this range as
that will be the deepest.
- child=toPosition._rangeObj.getEnclosingElement()
+ if not child or
UIAHandler.handler.clientObject.compareElements(child,document.rootNVDAObject.UIAElement):
+ # We're on the document itself -- probably nothing in
it.
+ return
# Work out if this child is previous to our position or not.
# If it isn't, then we know we still need to move parent or
previous before it is safe to emit an item.
try:
@@ -163,84 +168,70 @@ def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction
yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))
continue
curElement=None
- elif True:
- # Fetching items after the given position.
- toPosition=position.copy()
+ else: # direction is next
+ # Fetching items after the given position.
# Extend the end of the range forward to the end of the
document so that we will be able to fetch children from this point onwards.
-
toPosition.setEndPoint(document.TextInfo(document,textInfos.POSITION_ALL),"endToEnd")
# Fetch the first child of this text range.
# But if its own range extends before the start of our position:
# We know that the child is not the deepest descendant,
# And therefore we Limit our children fetching range to the end
of this child,
# And fetch the first child again.
- child=None
+ child=position._rangeObj.getEnclosingElement()
+
childRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(child)
+ toPosition=position._rangeObj.clone()
+
toPosition.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_End,childRange,UIAHandler.TextPatternRangeEndpoint_End)
zoomedOnce=False
while True:
- children=toPosition._rangeObj.getChildren()
+ children=toPosition.getChildren()
length=children.length
if length==0:
+ if zoomedOnce:
+ child=toPosition.getEnclosingElement()
break
child=children.getElement(0)
try:

childRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(child)
except COMError:
return
- print "childRange text: %s"%childRange.getText(-1)
- if
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,position._rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)<0
and
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_End,toPosition._rangeObj,UIAHandler.TextPatternRangeEndpoint_End)<0:
-
toPosition._rangeObj.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_End,childRange,UIAHandler.TextPatternRangeEndpoint_End)
+ if
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,position._rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)<0
and
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_End,toPosition,UIAHandler.TextPatternRangeEndpoint_End)<0:
+
toPosition.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_End,childRange,UIAHandler.TextPatternRangeEndpoint_End)
zoomedOnce=True
continue
break
- if not child:
- if not zoomedOnce:
- return
- # If we have zoomed in at all, yet this level has no
children,
- # Then we can use the element enclosing this range as
that will be the deepest.
- child=toPosition._rangeObj.getEnclosingElement()
- if
UIAHandler.handler.clientObject.comareElements(child,document.rootNVDAObject.UIAElement):
- import tones; tones.beep(550,50)
- return
# Work out if this child is after our position or not.
+ if not child or
UIAHandler.handler.clientObject.compareElements(child,document.rootNVDAObject.UIAElement):
+ # We're on the document itself -- probably nothing in
it.
+ return
try:

childRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(child)
except COMError:
return
- print "childRange text: %s"%childRange.getText(-1)

goneNextOnce=childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,position._rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)>0
- print "goneNextOnce: %s"%goneNextOnce

walker=UIAHandler.handler.clientObject.createTreeWalker(UIACondition)
curElement=child
# If we are already past our position, and this is a valid child
- # Then we can emmit an item already
+ # Then we can emit an item already
if goneNextOnce and isUIAElementInWalker(curElement,walker):
yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))
# Start traversing from this child forwards through the
document, emitting items for valid elements.
while curElement:
- # Ensure this element is really represented in the
document's text.
- if not
UIATextRangeFromElement(document.rootNVDAObject.UIATextPattern,curElement):
- return
- firstChild=walker.getFirstChildElement(curElement)
+ firstChild=walker.getFirstChildElement(curElement) if
goneNextOnce else None
if firstChild:
curElement=firstChild
yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))
- continue
- nextSibling=None
- while curElement:
-
nextSibling=walker.getNextSiblingElement(curElement)
- if not nextSibling:
-
parent=walker.getParentElement(curElement)
- if not parent or not
UIATextRangeFromElement(document.rootNVDAObject.UIATextPattern,parent):
- return
- curElement=parent
- else:
- break
- if nextSibling:
+ else:
+ nextSibling=None
+ while not nextSibling:
+
nextSibling=walker.getNextSiblingElement(curElement)
+ if not nextSibling:
+
parent=walker.getParentElement(curElement)
+ if parent and not
UIAHandler.handler.clientObject.compareElements(document.rootNVDAObject.UIAElement,parent):
+ curElement=parent
+ else:
+ return
curElement=nextSibling
-
childRange=UIATextRangeFromElement(document.rootNVDAObject.UIATextPattern,curElement)
- if not childRange:
- return
- yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=childRange))
- curElement=None
+ goneNextOnce=True
+ yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))

class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.BrowseModeTreeInterceptor,treeInterceptorHandler.DocumentTreeInterceptor):



https://bitbucket.org/nvdaaddonteam/nvda/commits/eb6bd3f86124/
Changeset: eb6bd3f86124
Branch: None
User: mdcurran
Date: 2015-06-04 01:14:18+00:00
Summary: When speaking read-only lists in documents, only give an item
count if it is not 0.

Affected #: 1 file

diff --git a/source/speech.py b/source/speech.py
index 6d13846..5ce221c 100755
--- a/source/speech.py
+++ b/source/speech.py
@@ -1057,7 +1057,7 @@ def
getControlFieldSpeech(attrs,ancestorAttrs,fieldType,formatConfig=None,extraD

# Determine what text to speak.
# Special cases
- if speakEntry and fieldType=="start_addedToControlFieldStack" and
role==controlTypes.ROLE_LIST and controlTypes.STATE_READONLY in states:
+ if speakEntry and childControlCount and
fieldType=="start_addedToControlFieldStack" and role==controlTypes.ROLE_LIST
and controlTypes.STATE_READONLY in states:
# List.
# Translators: Speaks number of items in a list (example
output: list with 5 items).
return roleText+" "+_("with %s items")%childControlCount


https://bitbucket.org/nvdaaddonteam/nvda/commits/daf116572035/
Changeset: daf116572035
Branch: None
User: mdcurran
Date: 2015-06-04 01:15:16+00:00
Summary: UIA Edge: ensure that non-interactive lists are announced
correctly in documents (i.e. list out of list).

Affected #: 3 files

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 6f41e79..4704d47 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -304,6 +304,8 @@ class UIA(Window):
clsList.append(edge.EdgeHTMLRootContainer)
elif isinstance(self.parent,edge.EdgeHTMLRootContainer) and
self.role==controlTypes.ROLE_PANE:
clsList.append(edge.EdgeHTMLRoot)
+ elif self.role==controlTypes.ROLE_LIST and
self.UIAElement.cachedFrameworkId=="InternetExplorer":
+ clsList.append(edge.EdgeList)
elif UIAClassName=="ToastContentHost" and
UIAControlType==UIAHandler.UIA_ToolTipControlTypeId:
clsList.append(Toast)
if UIAControlType==UIAHandler.UIA_ProgressBarControlTypeId:

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index d4d8ae3..39b75c9 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -16,6 +16,16 @@ import treeInterceptorHandler
import cursorManager
from . import UIA

+class EdgeList(UIA):
+
+ # non-focusable lists are readonly lists (ensures correct NVDA
presentation category)
+ def _get_states(self):
+ states=super(EdgeList,self).states
+ if controlTypes.STATE_FOCUSABLE not in states:
+ states.add(controlTypes.STATE_READONLY)
+ return states
+
+
class EdgeHTMLRootContainer(UIA):

shouldAllowUIAFocusEvent=True

diff --git a/source/_UIAHandler.py b/source/_UIAHandler.py
index 72a9cbe..cb2a32f 100644
--- a/source/_UIAHandler.py
+++ b/source/_UIAHandler.py
@@ -159,7 +159,7 @@ class UIAHandler(COMObject):
import UIAHandler

self.ItemIndex_PropertyId=NVDAHelper.localLib.registerUIAProperty(byref(ItemIndex_Property_GUID),u"ItemIndex",1)

self.ItemCount_PropertyId=NVDAHelper.localLib.registerUIAProperty(byref(ItemCount_Property_GUID),u"ItemCount",1)
- for propertyId in
(UIA_AutomationIdPropertyId,UIA_ClassNamePropertyId,UIA_ControlTypePropertyId,UIA_IsKeyboardFocusablePropertyId,UIA_IsPasswordPropertyId,UIA_ProviderDescriptionPropertyId,UIA_ProcessIdPropertyId,UIA_IsSelectionItemPatternAvailablePropertyId,UIA_IsTextPatternAvailablePropertyId):
+ for propertyId in
(UIA_FrameworkIdPropertyId,UIA_AutomationIdPropertyId,UIA_ClassNamePropertyId,UIA_ControlTypePropertyId,UIA_IsKeyboardFocusablePropertyId,UIA_IsPasswordPropertyId,UIA_ProviderDescriptionPropertyId,UIA_ProcessIdPropertyId,UIA_IsSelectionItemPatternAvailablePropertyId,UIA_IsTextPatternAvailablePropertyId):
self.baseCacheRequest.addProperty(propertyId)

self.rootElement=self.clientObject.getRootElementBuildCache(self.baseCacheRequest)

self.reservedNotSupportedValue=self.clientObject.ReservedNotSupportedValue


https://bitbucket.org/nvdaaddonteam/nvda/commits/f0726eadfb9b/
Changeset: f0726eadfb9b
Branch: None
User: mdcurran
Date: 2015-06-04 02:25:00+00:00
Summary: UIA NVDAObject: add support for the new posInSet, sizeOfSet and
level UIA properties, mapping them into the positionInfo property.

Affected #: 2 files

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 4704d47..d18142a 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -689,24 +689,43 @@ class UIA(Window):

def _get_positionInfo(self):
info=super(UIA,self).positionInfo or {}
+ itemIndex=0
try:
-
itemIndex=self.UIAElement.getCurrentPropertyValue(UIAHandler.handler.ItemIndex_PropertyId)
+
itemIndex=self.UIAElement.getCurrentPropertyValue(UIAHandler.UIA_PositionInSetPropertyId)
except COMError:
- itemIndex=0
- if itemIndex>0:
- info['indexInGroup']=itemIndex
- parent=self.parent
- parentCount=1
- while parentCount<3 and isinstance(parent,UIA):
+ pass
+ if itemIndex==0:
try:
-
itemCount=parent.UIAElement.getCurrentPropertyValue(UIAHandler.handler.ItemCount_PropertyId)
+
itemIndex=self.UIAElement.getCurrentPropertyValue(UIAHandler.handler.ItemIndex_PropertyId)
except COMError:
- itemCount=0
- if itemCount>0:
- info['similarItemsInGroup']=itemCount
- break
- parent=parent.parent
- parentCount+=1
+ pass
+ if itemIndex>0:
+ info['indexInGroup']=itemIndex
+ itemCount=0
+ try:
+
itemCount=self.UIAElement.getCurrentPropertyValue(UIAHandler.UIA_SizeOfSetPropertyId)
+ except COMError:
+ pass
+ if itemCount==0:
+ parent=self.parent
+ parentCount=1
+ while parentCount<3 and isinstance(parent,UIA):
+ try:
+
itemCount=parent.UIAElement.getCurrentPropertyValue(UIAHandler.handler.ItemCount_PropertyId)
+ except COMError:
+ pass
+ if itemCount>0:
+ break
+ parent=parent.parent
+ parentCount+=1
+ if itemCount>0:
+ info['similarItemsInGroup']=itemCount
+ try:
+
level=self.UIAElement.getCurrentPropertyValue(UIAHandler.UIA_LevelPropertyId)
+ except COMError:
+ level=None
+ if level is not None and level>0:
+ info["level"]=level
return info

def event_UIA_elementSelected(self):

diff --git a/source/_UIAHandler.py b/source/_UIAHandler.py
index cb2a32f..b3be3c3 100644
--- a/source/_UIAHandler.py
+++ b/source/_UIAHandler.py
@@ -28,7 +28,9 @@ StyleId_Heading1=70001
StyleId_Heading9=70009
ItemIndex_Property_GUID=GUID("{92A053DA-2969-4021-BF27-514CFC2E4A69}")
ItemCount_Property_GUID=GUID("{ABBF5C45-5CCC-47b7-BB4E-87CB87BBD162}")
-
+UIA_LevelPropertyId=30154
+UIA_PositionInSetPropertyId=30152
+UIA_SizeOfSetPropertyId=30153

badUIAWindowClassNames=[
"SysTreeView32",


https://bitbucket.org/nvdaaddonteam/nvda/commits/cb257e664e39/
Changeset: cb257e664e39
Branch: None
User: mdcurran
Date: 2015-06-04 03:32:31+00:00
Summary: UIA: fix broken combo box value change handling.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index d18142a..c8276ba 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -825,10 +825,11 @@ class ListItem(UIA):
def event_stateChange(self):
if not self.hasFocus:
parent = self.parent
- if parent and isinstance(parent,
ComboBoxWithoutValuePattern):
+ focus=api.getFocusObject()
+ if parent and isinstance(parent,
ComboBoxWithoutValuePattern) and parent==focus:
# This is an item in a combo box without the
Value pattern.
# This item has been selected, so notify the
combo box that its value has changed.
- parent.event_valueChange()
+ focus.event_valueChange()
super(ListItem, self).event_stateChange()

class Dialog(Dialog):


https://bitbucket.org/nvdaaddonteam/nvda/commits/f800e6847038/
Changeset: f800e6847038
Branch: None
User: mdcurran
Date: 2015-06-04 05:26:14+00:00
Summary: UIATextInfo: when recursivly collecting fields and text, use the
child object's own textInfo's getTextWithFields if the child object is
represented by a collapsed range in the document. Allows rendering some kind of
information for graphics, and things such as audio tags which so far do not get
included by Edge's own text representation.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index c8276ba..5f849d4 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -179,8 +179,9 @@ class UIATextInfo(textInfos.TextInfo):

def _getTextWithFieldsForRange(self,obj,rangeObj,formatConfig):
#Graphics usually have no actual text, so render the name
instead
- if obj.role==controlTypes.ROLE_GRAPHIC:
- yield obj.name
+ if
rangeObj.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,rangeObj,UIAHandler.TextPatternRangeEndpoint_End)==0:
+ for x in
obj.makeTextInfo("all").getTextWithFields(formatConfig):
+ yield x
return
tempRange=rangeObj.clone()
children=rangeObj.getChildren()


https://bitbucket.org/nvdaaddonteam/nvda/commits/db939617b082/
Changeset: db939617b082
Branch: None
User: mdcurran
Date: 2015-06-04 05:56:14+00:00
Summary: UIA NVDAObject: make use of UIA's ariaRole property when mapping
to an NVDA role. Make browseMode for Edge documents with a role of application
or dialog etc be optional.

Affected #: 2 files

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 5f849d4..93334dc 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -9,6 +9,7 @@ from ctypes.wintypes import POINT, RECT
from comtypes import COMError
import weakref
import UIAHandler
+import aria
import globalVars
import eventHandler
import controlTypes
@@ -303,7 +304,7 @@ class UIA(Window):
clsList.append(WpfTextView)
elif UIAClassName=="Internet Explorer_Server" and
self.role==controlTypes.ROLE_PANE:
clsList.append(edge.EdgeHTMLRootContainer)
- elif isinstance(self.parent,edge.EdgeHTMLRootContainer) and
self.role==controlTypes.ROLE_PANE:
+ elif isinstance(self.parent,edge.EdgeHTMLRootContainer):
clsList.append(edge.EdgeHTMLRoot)
elif self.role==controlTypes.ROLE_LIST and
self.UIAElement.cachedFrameworkId=="InternetExplorer":
clsList.append(edge.EdgeList)
@@ -462,7 +463,13 @@ class UIA(Window):
if role in
(controlTypes.ROLE_UNKNOWN,controlTypes.ROLE_PANE,controlTypes.ROLE_WINDOW) and
self.windowHandle:
superRole=super(UIA,self).role
if superRole!=controlTypes.ROLE_WINDOW:
- return superRole
+ role=superRole
+ ariaRole=self.UIAElement.currentAriaRole
+ for ariaRole in ariaRole.split():
+ newRole=aria.ariaRolesToNVDARoles.get(ariaRole)
+ if newRole:
+ role=newRole
+ break
return role

def _get_description(self):

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index 39b75c9..8341062 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -35,7 +35,7 @@ class EdgeHTMLRootContainer(UIA):
if isinstance(firstChild,UIA):
eventHandler.executeEvent("gainFocus",firstChild)
return
- return super(EdgeHTML,self).event_gainFocus()
+ return super(EdgeHTMLRootContainer,self).event_gainFocus()

def
UIATextAttributeQuickNavIterator(itemType,document,position,attributeID,attributeValue,direction="next"):
includeCurrent=False
@@ -281,4 +281,13 @@ class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.Brows
class EdgeHTMLRoot(UIA):

treeInterceptorClass=EdgeHTMLTreeInterceptor
- role=controlTypes.ROLE_DOCUMENT
+
+ def _get_shouldCreateTreeInterceptor(self):
+ return self.role==controlTypes.ROLE_DOCUMENT
+
+ def _get_role(self):
+ role=super(EdgeHTMLRoot,self).role
+ if role==controlTypes.ROLE_PANE:
+ role=controlTypes.ROLE_DOCUMENT
+ return role
+


https://bitbucket.org/nvdaaddonteam/nvda/commits/1f184689334e/
Changeset: 1f184689334e
Branch: None
User: mdcurran
Date: 2015-06-04 06:02:55+00:00
Summary: UIATextInfo: when falling back to a child object's own text when
recursivly getting text, ensure that the child object isn't the original
document.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 93334dc..f4291c4 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -180,7 +180,7 @@ class UIATextInfo(textInfos.TextInfo):

def _getTextWithFieldsForRange(self,obj,rangeObj,formatConfig):
#Graphics usually have no actual text, so render the name
instead
- if
rangeObj.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,rangeObj,UIAHandler.TextPatternRangeEndpoint_End)==0:
+ if
rangeObj.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,rangeObj,UIAHandler.TextPatternRangeEndpoint_End)==0
and obj!=self.obj:
for x in
obj.makeTextInfo("all").getTextWithFields(formatConfig):
yield x
return


https://bitbucket.org/nvdaaddonteam/nvda/commits/7672bfcdc7e0/
Changeset: 7672bfcdc7e0
Branch: None
User: mdcurran
Date: 2015-06-04 07:04:25+00:00
Summary: UIA NVDAObject: support the readonly and required states.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index f4291c4..1e3ff87 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -503,6 +503,10 @@ class UIA(Window):
states.add(controlTypes.STATE_CHECKABLE if
role==controlTypes.ROLE_RADIOBUTTON else controlTypes.STATE_SELECTABLE)
if
self.UIAElement.getCurrentPropertyValue(UIAHandler.UIA_SelectionItemIsSelectedPropertyId):
states.add(controlTypes.STATE_CHECKED if
role==controlTypes.ROLE_RADIOBUTTON else controlTypes.STATE_SELECTED)
+ if
self.UIAElement.getCurrentPropertyValue(UIAHandler.UIA_IsRequiredForFormPropertyId):
+ states.add(controlTypes.STATE_REQUIRED)
+ if
self.UIAElement.getCurrentPropertyValue(UIAHandler.UIA_ValueIsReadOnlyPropertyId):
+ states.add(controlTypes.STATE_READONLY)
try:

s=self.UIAElement.getCurrentPropertyValueEx(UIAHandler.UIA_ExpandCollapseExpandCollapseStatePropertyId,True)
except COMError:


https://bitbucket.org/nvdaaddonteam/nvda/commits/92630a4fa1f7/
Changeset: 92630a4fa1f7
Branch: None
User: mdcurran
Date: 2015-06-04 07:04:49+00:00
Summary: UIA EdgeHTML: only automatically create a browseMode for readonly
documents.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index 8341062..e9c1ef8 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -283,7 +283,8 @@ class EdgeHTMLRoot(UIA):
treeInterceptorClass=EdgeHTMLTreeInterceptor

def _get_shouldCreateTreeInterceptor(self):
- return self.role==controlTypes.ROLE_DOCUMENT
+ return self.role==controlTypes.ROLE_DOCUMENT and
controlTypes.STATE_READONLY in self.states
+

def _get_role(self):
role=super(EdgeHTMLRoot,self).role


https://bitbucket.org/nvdaaddonteam/nvda/commits/438c39ad5658/
Changeset: 438c39ad5658
Branch: None
User: mdcurran
Date: 2015-06-05 00:29:32+00:00
Summary: UIATextInfo: enable reporting of table row and column numbers and
row and column headers when available.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 1e3ff87..3582dee 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -119,10 +119,16 @@ class UIATextInfo(textInfos.TextInfo):
field["table-columncount"] = obj.columnCount
except NotImplementedError:
pass
- if role in (controlTypes.ROLE_TABLECELL,
controlTypes.ROLE_TABLECOLUMNHEADER, controlTypes.ROLE_TABLEROWHEADER):
- field["table-id"] = 1 # FIXME
- field["table-rownumber"] = obj.rowNumber
- field["table-columnnumber"] = obj.columnNumber
+ if role in (controlTypes.ROLE_TABLECELL,
controlTypes.ROLE_DATAITEM,controlTypes.ROLE_TABLECOLUMNHEADER,
controlTypes.ROLE_TABLEROWHEADER,controlTypes.ROLE_HEADERITEM):
+ try:
+ field["table-rownumber"] = obj.rowNumber
+ field["table-columnnumber"] = obj.columnNumber
+ field["table-id"] = 1 # FIXME
+ field['role']=controlTypes.ROLE_TABLECELL
+
field['table-columnheadertext']=obj.columnHeaderText
+ field['table-rowheadertext']=obj.rowHeaderText
+ except NotImplementedError:
+ pass
return field

def _iterUIARangeByUnit(self,rangeObj,unit):


https://bitbucket.org/nvdaaddonteam/nvda/commits/0d87a4a74152/
Changeset: 0d87a4a74152
Branch: None
User: mdcurran
Date: 2015-06-05 03:23:28+00:00
Summary: UIA NVDAObject: support the invalid entry state.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 3582dee..184b711 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -509,6 +509,12 @@ class UIA(Window):
states.add(controlTypes.STATE_CHECKABLE if
role==controlTypes.ROLE_RADIOBUTTON else controlTypes.STATE_SELECTABLE)
if
self.UIAElement.getCurrentPropertyValue(UIAHandler.UIA_SelectionItemIsSelectedPropertyId):
states.add(controlTypes.STATE_CHECKED if
role==controlTypes.ROLE_RADIOBUTTON else controlTypes.STATE_SELECTED)
+ try:
+
isDataValid=self.UIAElement.getCurrentPropertyValueEx(UIAHandler.UIA_IsDataValidForFormPropertyId,True)
+ except COMError:
+ isDataValid=UIAHandler.handler.reservedNotSupportedValue
+ if not isDataValid:
+ states.add(controlTypes.STATE_INVALID_ENTRY)
if
self.UIAElement.getCurrentPropertyValue(UIAHandler.UIA_IsRequiredForFormPropertyId):
states.add(controlTypes.STATE_REQUIRED)
if
self.UIAElement.getCurrentPropertyValue(UIAHandler.UIA_ValueIsReadOnlyPropertyId):


https://bitbucket.org/nvdaaddonteam/nvda/commits/26bb092a5556/
Changeset: 26bb092a5556
Branch: None
User: mdcurran
Date: 2015-06-06 23:11:46+00:00
Summary: Add new BrowseModeDocumentTreeInterceptor and
BrowseModeDocumentTreeInterceptorTextInfo classes which now provide much of the
base VirtualBuffer implementation. Includes all focus handling and caret
handling. The only things still not moved are handling of table navigation and
moving to start/end of containers. UIA Edge support has been updated to make
use of this, thus it now reports focus the same way as virtual buffers do, and
pass through and tabbing etc all work the same way as well.

Affected #: 6 files

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 184b711..697c868 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -109,7 +109,7 @@ class UIATextInfo(textInfos.TextInfo):
states.discard(controlTypes.STATE_MULTILINE)
states.discard(controlTypes.STATE_FOCUSED)
field["states"] = states
- field["name"] = obj.name
+ #field["name"] = obj.name
#field["_childcount"] = obj.childCount
field["level"] = obj.positionInfo.get("level")
if role == controlTypes.ROLE_TABLE:
@@ -752,6 +752,9 @@ class UIA(Window):
info["level"]=level
return info

+ def scrollIntoView(self):
+ pass
+
def event_UIA_elementSelected(self):
self.event_stateChange()


diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index e9c1ef8..5255314 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -37,6 +37,26 @@ class EdgeHTMLRootContainer(UIA):
return
return super(EdgeHTMLRootContainer,self).event_gainFocus()

+class UIATextRangeQuickNavItem(browseMode.TextInfoQuickNavItem):
+
+ def __init__(self,itemType,document,UIAElementOrRange):
+ if
isinstance(UIAElementOrRange,UIAHandler.IUIAutomationElement):
+
UIATextRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(UIAElementOrRange)
+ self._UIAElement=UIAElementOrRange
+ elif
isinstance(UIAElementOrRange,UIAHandler.IUIAutomationTextRange):
+ UIATextRange=UIAElementOrRange
+ self._UIAElement=None
+ else:
+ raise ValueError("Invalid UIAElementOrRange")
+ textInfo=document.TextInfo(document,None,_rangeObj=UIATextRange)
+
super(UIATextRangeQuickNavItem,self).__init__(itemType,document,textInfo)
+
+ @property
+ def obj(self):
+ UIAElement=self._UIAElement if self._UIAElement else
self.textInfo._rangeObj.getEnclosingElement()
+
UIAElement=UIAElement.buildUpdatedCache(UIAHandler.handler.baseCacheRequest)
+ return UIA(UIAElement=UIAElement)
+
def
UIATextAttributeQuickNavIterator(itemType,document,position,attributeID,attributeValue,direction="next"):
includeCurrent=False
if not position:
@@ -56,11 +76,13 @@ def
UIATextAttributeQuickNavIterator(itemType,document,position,attributeID,attr
newRange=None
if not newRange:
return
- curPosition=document.TextInfo(document,None,_rangeObj=newRange)
- if includeCurrent or
curPosition.compareEndPoints(position,"startToStart")>0:
- yield
browseMode.TextInfoQuickNavItem(itemType,document,curPosition)
+ if includeCurrent or
newRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,position._rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)>0:
+ yield
UIATextRangeQuickNavItem(itemType,document,newRange)
includeCurrent=True
- position.setEndPoint(curPosition,"endToStart" if
direction=="previous" else "startToEnd")
+ if direction=="previous":
+
position._rangeObj.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_End,newRange,UIAHandler.TextPatternRangeEndpoint_Start)
+ else:
+
position._rangeObj.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_Start,newRange,UIAHandler.TextPatternRangeEndpoint_End)

def UIATextRangeFromElement(documentTextPattern,element):
try:
@@ -95,17 +117,24 @@ def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction
if not position:
# All items are requested (such as for elements list)

elements=document.rootNVDAObject.UIAElement.findAll(UIAHandler.TreeScope_Descendants,UIACondition)
- for index in xrange(elements.length):
- element=elements.getElement(index)
- try:
-
elementRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(element)
- except COMError:
- elementRange=None
- if elementRange:
-
info=document.TextInfo(document,None,_rangeObj=elementRange)
- yield
browseMode.TextInfoQuickNavItem(itemType,document,info)
+ if elements:
+ for index in xrange(elements.length):
+ element=elements.getElement(index)
+ try:
+
elementRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(element)
+ except COMError:
+ elementRange=None
+ if elementRange:
+ yield
UIATextRangeQuickNavItem(itemType,document,elementRange)
+ return
+ if direction=="up":
+
walker=UIAHandler.handler.clientObject.createTreeWalker(UIACondition)
+ element=position._rangeObj.getEnclosingElement()
+ element=walker.normalizeElement(element)
+ if element and not
UIAHandler.handler.clientObject.compareElements(element,document.rootNVDAObject.UIAElement)
and not
UIAHandler.handler.clientObject.compareElements(element,UIAHandler.handler.rootElement):
+ yield
UIATextRangeQuickNavItem(itemType,document,element)
return
- if direction=="previous":
+ elif direction=="previous":
# Fetching items previous to the given position.
# When getting children of a UIA text range, Edge will
incorrectly include a child that starts at the end of the range.
# Therefore move back by one character to stop this.
@@ -161,7 +190,7 @@ def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction
elif not curElementMatchedCondition and
isUIAElementInWalker(curElement,walker):
curElementMatchedCondition=True
if curElementMatchedCondition:
- yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))
+ yield
UIATextRangeQuickNavItem(itemType,document,curElement)

previousSibling=walker.getPreviousSiblingElement(curElement)
if previousSibling:
gonePreviousOnce=True
@@ -175,7 +204,7 @@ def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction
goneParent=True
curElementMatchedCondition=True
if gonePreviousOnce:
- yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))
+ yield
UIATextRangeQuickNavItem(itemType,document,curElement)
continue
curElement=None
else: # direction is next
@@ -222,13 +251,13 @@ def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction
# If we are already past our position, and this is a valid child
# Then we can emit an item already
if goneNextOnce and isUIAElementInWalker(curElement,walker):
- yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))
+ yield
UIATextRangeQuickNavItem(itemType,document,curElement)
# Start traversing from this child forwards through the
document, emitting items for valid elements.
while curElement:
firstChild=walker.getFirstChildElement(curElement) if
goneNextOnce else None
if firstChild:
curElement=firstChild
- yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))
+ yield
UIATextRangeQuickNavItem(itemType,document,curElement)
else:
nextSibling=None
while not nextSibling:
@@ -241,11 +270,17 @@ def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction
return
curElement=nextSibling
goneNextOnce=True
- yield
browseMode.TextInfoQuickNavItem(itemType,document,document.TextInfo(document,None,_rangeObj=document.rootNVDAObject.UIATextPattern.rangeFromChild(curElement)))
+ yield
UIATextRangeQuickNavItem(itemType,document,curElement)
+
+class
EdgeHTMLTreeInterceptorTextInfo(browseMode.BrowseModeDocumentTextInfo,treeInterceptorHandler.RootProxyTextInfo):
+ pass
+
+class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.BrowseModeDocumentTreeInterceptor):

-class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.BrowseModeTreeInterceptor,treeInterceptorHandler.DocumentTreeInterceptor):
+ TextInfo=EdgeHTMLTreeInterceptorTextInfo

- TextInfo=treeInterceptorHandler.RootProxyTextInfo
+ def _get_documentConstantIdentifier(self):
+ return self.rootNVDAObject.parent.name

def _iterNodesByType(self,nodeType,direction="next",pos=None):
if nodeType=="heading":
@@ -253,8 +288,17 @@ class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.Brows
elif nodeType=="link":

condition=UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_ControlTypePropertyId,UIAHandler.UIA_HyperlinkControlTypeId)
return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ elif nodeType=="focusable":
+
condition=UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_IsKeyboardFocusablePropertyId,True)
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
raise NotImplementedError

+ def _activateNVDAObject(self,obj):
+ try:
+ obj.doAction()
+ except NotImplementedError:
+ pass
+
def _get_isAlive(self):
if not winUser.isWindow(self.rootNVDAObject.windowHandle):
return False
@@ -273,11 +317,6 @@ class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.Brows
return False
return True

- def event_gainFocus(self,obj,nextHandler):
- info=self.makeTextInfo(obj)
- info.updateCaret()
- nextHandler()
-
class EdgeHTMLRoot(UIA):

treeInterceptorClass=EdgeHTMLTreeInterceptor

diff --git a/source/browseMode.py b/source/browseMode.py
index a071c1e..97630c9 100644
--- a/source/browseMode.py
+++ b/source/browseMode.py
@@ -6,24 +6,34 @@
import itertools
import collections
import winsound
+import time
import wx
+import queueHandler
+from logHandler import log
+import review
+import eventHandler
import nvwave
import queueHandler
import gui
import ui
+import cursorManager
from scriptHandler import isScriptWaiting, willSayAllResume
+import aria
import controlTypes
import config
import textInfos
+import braille
import speech
import sayAllHandler
import treeInterceptorHandler
import inputCore
+import api
+from NVDAObjects import NVDAObject

REASON_QUICKNAV = "quickNav"

def reportPassThrough(treeInterceptor,onlyIfChanged=True):
- """Reports the virtual buffer pass through mode if it has changed.
+ """Reports the pass through mode if it has changed.
@param treeInterceptor: The current Browse Mode treeInterceptor.
@type treeInterceptor: L{BrowseModeTreeInterceptor}
@param onlyIfChanged: if true reporting will not happen if the last
reportPassThrough reported the same thing.
@@ -137,6 +147,10 @@ class TextInfoQuickNavItem(QuickNavItem):
return
self.textInfo.compareEndPoints(other.textInfo,"startToStart")<0

@property
+ def obj(self):
+ return self.textInfo.basePosition if
isinstance(self.textInfo.basePosition,NVDAObject) else None
+
+ @property
def label(self):
return self.textInfo.text.strip()

@@ -238,15 +252,6 @@ class
BrowseModeTreeInterceptor(treeInterceptorHandler.TreeInterceptor):
# Translators: the description for the Elements List command in browse
mode.
script_elementsList.__doc__ = _("Lists various types of elements in
this document")

- def _activatePosition(self,info):
- info.activate()
-
- def script_activatePosition(self,gesture):
- info=self.makeTextInfo(textInfos.POSITION_CARET)
- self._activatePosition(info)
- # Translators: the description for the activatePosition script on
virtualBuffers.
- script_activatePosition.__doc__ = _("activates the current object in
the document")
-
__gestures={
"kb:NVDA+f7": "elementsList",
"kb:enter": "activatePosition",
@@ -764,3 +769,561 @@ class ElementsListDialog(wx.Dialog):
item.moveTo()
item.report()
wx.CallLater(100, move)
+
+class BrowseModeDocumentTextInfo(textInfos.TextInfo):
+
+ def getControlFieldSpeech(self, attrs, ancestorAttrs, fieldType,
formatConfig=None, extraDetail=False, reason=None):
+ textList = []
+ landmark = attrs.get("landmark")
+ if formatConfig["reportLandmarks"] and fieldType ==
"start_addedToControlFieldStack" and landmark:
+ try:
+ textList.append(attrs["name"])
+ except KeyError:
+ pass
+ if landmark == "region":
+ # The word landmark is superfluous for regions.
+ textList.append(aria.landmarkRoles[landmark])
+ else:
+ textList.append(_("%s landmark") %
aria.landmarkRoles[landmark])
+ textList.append(super(BrowseModeDocumentTextInfo,
self).getControlFieldSpeech(attrs, ancestorAttrs, fieldType, formatConfig,
extraDetail, reason))
+ return " ".join(textList)
+
+ def getControlFieldBraille(self, field, ancestors, reportStart,
formatConfig):
+ textList = []
+ landmark = field.get("landmark")
+ if formatConfig["reportLandmarks"] and reportStart and landmark
and field.get("_startOfNode"):
+ try:
+ textList.append(field["name"])
+ except KeyError:
+ pass
+ if landmark == "region":
+ # The word landmark is superfluous for regions.
+ textList.append(aria.landmarkRoles[landmark])
+ else:
+ # Translators: This is spoken and brailled to
indicate a landmark (example output: main landmark).
+ textList.append(_("%s landmark") %
aria.landmarkRoles[landmark])
+ text = super(BrowseModeDocumentTextInfo,
self).getControlFieldBraille(field, ancestors, reportStart, formatConfig)
+ if text:
+ textList.append(text)
+ return " ".join(textList)
+
+ def _get_focusableNVDAObjectAtStart(self):
+ try:
+ item = next(self.obj._iterNodesByType("focusable",
"up", self))
+ except StopIteration:
+ return self.obj.rootNVDAObject
+ if not item:
+ return self.obj.rootNVDAObject
+ return item.obj
+
+class
BrowseModeDocumentTreeInterceptor(cursorManager.CursorManager,BrowseModeTreeInterceptor,treeInterceptorHandler.DocumentTreeInterceptor):
+
+ programmaticScrollMayFireEvent = False
+
+ def __init__(self,obj):
+ super(BrowseModeDocumentTreeInterceptor,self).__init__(obj)
+ self.disableAutoPassThrough = False
+ self._lastProgrammaticScrollTime = None
+ self.documentConstantIdentifier =
self.documentConstantIdentifier
+ self._lastFocusObj = None
+ self._hadFirstGainFocus = False
+ self._enteringFromOutside = True
+ # We need to cache this because it will be unavailable once the
document dies.
+ if not hasattr(self.rootNVDAObject.appModule,
"_browseModeRememberedCaretPositions"):
+
self.rootNVDAObject.appModule._browseModeRememberedCaretPositions = {}
+ self._lastCaretPosition = None
+
+ def terminate(self):
+ if self.shouldRememberCaretPositionAcrossLoads and
self._lastCaretPosition:
+ try:
+
self.rootNVDAObject.appModule._browseModeRememberedCaretPositions[self.documentConstantIdentifier]
= self._lastCaretPosition
+ except AttributeError:
+ # The app module died.
+ pass
+
+ def event_treeInterceptor_gainFocus(self):
+ """Triggered when this browse mode document gains focus.
+ This event is only fired upon entering this treeInterceptor
when it was not the current treeInterceptor before.
+ This is different to L{event_gainFocus}, which is fired when an
object inside this treeInterceptor gains focus, even if that object is in the
same treeInterceptor.
+ """
+ doSayAll=False
+ hadFirstGainFocus=self._hadFirstGainFocus
+ if not hadFirstGainFocus:
+ # This treeInterceptor is gaining focus for the first
time.
+ # Fake a focus event on the focus object, as the
treeInterceptor may have missed the actual focus event.
+ focus = api.getFocusObject()
+ self.event_gainFocus(focus, lambda:
focus.event_gainFocus())
+ if not self.passThrough:
+ # We only set the caret position if in browse
mode.
+ # If in focus mode, the document must have
forced the focus somewhere,
+ # so we don't want to override it.
+ initialPos = self._getInitialCaretPos()
+ if initialPos:
+ self.selection =
self.makeTextInfo(initialPos)
+ reportPassThrough(self)
+
doSayAll=config.conf['virtualBuffers']['autoSayAllOnPageLoad']
+ self._hadFirstGainFocus = True
+
+ if not self.passThrough:
+ if doSayAll:
+
speech.speakObjectProperties(self.rootNVDAObject,name=True,states=True,reason=controlTypes.REASON_FOCUS)
+
sayAllHandler.readText(sayAllHandler.CURSOR_CARET)
+ else:
+ # Speak it like we would speak focus on any
other document object.
+ # This includes when entering the
treeInterceptor for the first time:
+ if not hadFirstGainFocus:
+ speech.speakObject(self.rootNVDAObject,
reason=controlTypes.REASON_FOCUS)
+ else:
+ # And when coming in from an outside
object
+ # #4069 But not when coming up from a
non-rendered descendant.
+ ancestors=api.getFocusAncestors()
+ fdl=api.getFocusDifferenceLevel()
+ try:
+
tl=ancestors.index(self.rootNVDAObject)
+ except ValueError:
+ tl=len(ancestors)
+ if fdl<=tl:
+
speech.speakObject(self.rootNVDAObject, reason=controlTypes.REASON_FOCUS)
+ info = self.selection
+ if not info.isCollapsed:
+
speech.speakSelectionMessage(_("selected %s"), info.text)
+ else:
+ info.expand(textInfos.UNIT_LINE)
+ speech.speakTextInfo(info,
reason=controlTypes.REASON_CARET, unit=textInfos.UNIT_LINE)
+
+ reportPassThrough(self)
+ braille.handler.handleGainFocus(self)
+
+ def _activatePosition(self,info):
+ info.activate()
+
+ def script_activatePosition(self,gesture):
+ info=self.makeTextInfo(textInfos.POSITION_CARET)
+ self._activatePosition(info)
+ # Translators: the description for the activatePosition script on
browseMode documents.
+ script_activatePosition.__doc__ = _("activates the current object in
the document")
+
+ def event_caret(self, obj, nextHandler):
+ if self.passThrough:
+ nextHandler()
+
+ def _activateNVDAObject(self, obj):
+ """Activate an object in response to a user request.
+ This should generally perform the default action or click on
the object.
+ @param obj: The object to activate.
+ @type obj: L{NVDAObjects.NVDAObject}
+ """
+ obj.doAction()
+
+ def _activateLongDesc(self,controlField):
+ """
+ Activates (presents) the long description for a particular
field (usually a graphic).
+ @param controlField: the field who's long description should be
activated. This field is guaranteed to have states containing HASLONGDESC
state.
+ @type controlField: dict
+ """
+ raise NotImplementedError
+
+ def _activatePosition(self, info):
+ obj = info.NVDAObjectAtStart
+ if not obj:
+ return
+ if obj.role == controlTypes.ROLE_MATH:
+ import mathPres
+ try:
+ return mathPres.interactWithMathMl(obj.mathMl)
+ except (NotImplementedError, LookupError):
+ pass
+ return
+ if self.shouldPassThrough(obj):
+ obj.setFocus()
+ self.passThrough = True
+ reportPassThrough(self)
+ elif obj.role == controlTypes.ROLE_EMBEDDEDOBJECT or obj.role
in self.APPLICATION_ROLES:
+ obj.setFocus()
+ speech.speakObject(obj,
reason=controlTypes.REASON_FOCUS)
+ else:
+ self._activateNVDAObject(obj)
+
+ def _set_selection(self, info, reason=controlTypes.REASON_CARET):
+ super(BrowseModeDocumentTreeInterceptor,
self)._set_selection(info)
+ if isScriptWaiting() or not info.isCollapsed:
+ return
+ # Save the last caret position for use in terminate().
+ # This must be done here because the buffer might be cleared
just before terminate() is called,
+ # causing the last caret position to be lost.
+ caret = info.copy()
+ caret.collapse()
+ self._lastCaretPosition = caret.bookmark
+ review.handleCaretMove(caret)
+ if reason == controlTypes.REASON_FOCUS:
+ focusObj = api.getFocusObject()
+ if focusObj==self.rootNVDAObject:
+ return
+ else:
+ focusObj=info.focusableNVDAObjectAtStart
+ obj=info.NVDAObjectAtStart
+ if not obj:
+ log.debugWarning("Invalid NVDAObjectAtStart")
+ return
+ if obj==self.rootNVDAObject:
+ return
+ if focusObj and not
eventHandler.isPendingEvents("gainFocus") and focusObj!=self.rootNVDAObject and
focusObj != api.getFocusObject() and self._shouldSetFocusToObj(focusObj):
+ focusObj.setFocus()
+ obj.scrollIntoView()
+ if self.programmaticScrollMayFireEvent:
+ self._lastProgrammaticScrollTime = time.time()
+ self.passThrough=self.shouldPassThrough(focusObj,reason=reason)
+ # Queue the reporting of pass through mode so that it will be
spoken after the actual content.
+ queueHandler.queueFunction(queueHandler.eventQueue,
reportPassThrough, self)
+
+ def _shouldSetFocusToObj(self, obj):
+ """Determine whether an object should receive focus.
+ Subclasses may extend or override this method.
+ @param obj: The object in question.
+ @type obj: L{NVDAObjects.NVDAObject}
+ """
+ return obj.role not in self.APPLICATION_ROLES and
obj.isFocusable and obj.role!=controlTypes.ROLE_EMBEDDEDOBJECT
+
+ def script_activateLongDesc(self,gesture):
+ info=self.makeTextInfo(textInfos.POSITION_CARET)
+ info.expand("character")
+ for field in reversed(info.getTextWithFields()):
+ if isinstance(field,textInfos.FieldCommand) and
field.command=="controlStart":
+ states=field.field.get('states')
+ if states and controlTypes.STATE_HASLONGDESC in
states:
+ self._activateLongDesc(field.field)
+ break
+ else:
+ # Translators: the message presented when the
activateLongDescription script cannot locate a long description to activate.
+ ui.message(_("No long description"))
+ # Translators: the description for the activateLongDescription script
on browseMode documents.
+ script_activateLongDesc.__doc__=_("Shows the long description at this
position if one is found.")
+
+ def shouldPassThrough(self, obj, reason=None):
+ """Determine whether pass through mode should be enabled or
disabled for a given object.
+ @param obj: The object in question.
+ @type obj: L{NVDAObjects.NVDAObject}
+ @param reason: The reason for this query; one of the output
reasons, L{REASON_QUICKNAV}, or C{None} for manual pass through mode activation
by the user.
+ @return: C{True} if pass through mode should be enabled,
C{False} if it should be disabled.
+ """
+ if reason and (
+ self.disableAutoPassThrough
+ or (reason == controlTypes.REASON_FOCUS and not
config.conf["virtualBuffers"]["autoPassThroughOnFocusChange"])
+ or (reason == controlTypes.REASON_CARET and not
config.conf["virtualBuffers"]["autoPassThroughOnCaretMove"])
+ ):
+ # This check relates to auto pass through and auto pass
through is disabled, so don't change the pass through state.
+ return self.passThrough
+ if reason == REASON_QUICKNAV:
+ return False
+ states = obj.states
+ role = obj.role
+ # Menus sometimes get focus due to menuStart events even though
they don't report as focused/focusable.
+ if not obj.isFocusable and controlTypes.STATE_FOCUSED not in
states and role != controlTypes.ROLE_POPUPMENU:
+ return False
+ if controlTypes.STATE_READONLY in states and role not in
(controlTypes.ROLE_EDITABLETEXT, controlTypes.ROLE_COMBOBOX):
+ return False
+ if reason == controlTypes.REASON_CARET:
+ return role == controlTypes.ROLE_EDITABLETEXT or (role
== controlTypes.ROLE_DOCUMENT and controlTypes.STATE_EDITABLE in states)
+ if reason == controlTypes.REASON_FOCUS and role in
(controlTypes.ROLE_LISTITEM, controlTypes.ROLE_RADIOBUTTON,
controlTypes.ROLE_TAB):
+ return True
+ if role in (controlTypes.ROLE_COMBOBOX,
controlTypes.ROLE_EDITABLETEXT, controlTypes.ROLE_LIST,
controlTypes.ROLE_SLIDER, controlTypes.ROLE_TABCONTROL,
controlTypes.ROLE_MENUBAR, controlTypes.ROLE_POPUPMENU,
controlTypes.ROLE_MENUITEM, controlTypes.ROLE_TREEVIEW,
controlTypes.ROLE_TREEVIEWITEM, controlTypes.ROLE_SPINBUTTON,
controlTypes.ROLE_TABLEROW, controlTypes.ROLE_TABLECELL,
controlTypes.ROLE_TABLEROWHEADER, controlTypes.ROLE_TABLECOLUMNHEADER,
controlTypes.ROLE_CHECKMENUITEM, controlTypes.ROLE_RADIOMENUITEM) or
controlTypes.STATE_EDITABLE in states:
+ return True
+ if reason == controlTypes.REASON_FOCUS:
+ # If this is a focus change, pass through should be
enabled for certain ancestor containers.
+ while obj and obj != self.rootNVDAObject:
+ if obj.role == controlTypes.ROLE_TOOLBAR:
+ return True
+ obj = obj.parent
+ return False
+
+ def event_caretMovementFailed(self, obj, nextHandler, gesture=None):
+ if not self.passThrough or not gesture or not
config.conf["virtualBuffers"]["autoPassThroughOnCaretMove"]:
+ return nextHandler()
+ if gesture.mainKeyName in ("home", "end"):
+ # Home, end, control+home and control+end should not
disable pass through.
+ return nextHandler()
+ script = self.getScript(gesture)
+ if not script:
+ return nextHandler()
+
+ # We've hit the edge of the focused control.
+ # Therefore, move the virtual caret to the same edge of the
field.
+ info = self.makeTextInfo(textInfos.POSITION_CARET)
+ info.expand(info.UNIT_CONTROLFIELD)
+ if gesture.mainKeyName in ("leftArrow", "upArrow", "pageUp"):
+ info.collapse()
+ else:
+ info.collapse(end=True)
+ info.move(textInfos.UNIT_CHARACTER, -1)
+ info.updateCaret()
+
+ scriptHandler.queueScript(script, gesture)
+
+ def script_disablePassThrough(self, gesture):
+ if not self.passThrough or self.disableAutoPassThrough:
+ return gesture.send()
+ self.passThrough = False
+ self.disableAutoPassThrough = False
+ reportPassThrough(self)
+ script_disablePassThrough.ignoreTreeInterceptorPassThrough = True
+
+ def script_collapseOrExpandControl(self, gesture):
+ oldFocus = api.getFocusObject()
+ oldFocusStates = oldFocus.states
+ gesture.send()
+ if controlTypes.STATE_COLLAPSED in oldFocusStates:
+ self.passThrough = True
+ elif not self.disableAutoPassThrough:
+ self.passThrough = False
+ reportPassThrough(self)
+ script_collapseOrExpandControl.ignoreTreeInterceptorPassThrough = True
+
+ def _tabOverride(self, direction):
+ """Override the tab order if the virtual caret is not within
the currently focused node.
+ This is done because many nodes are not focusable and it is
thus possible for the virtual caret to be unsynchronised with the focus.
+ In this case, we want tab/shift+tab to move to the
next/previous focusable node relative to the virtual caret.
+ If the virtual caret is within the focused node, the
tab/shift+tab key should be passed through to allow normal tab order navigation.
+ Note that this method does not pass the key through itself if
it is not overridden. This should be done by the calling script if C{False} is
returned.
+ @param direction: The direction in which to move.
+ @type direction: str
+ @return: C{True} if the tab order was overridden, C{False} if
not.
+ @rtype: bool
+ """
+ focus = api.getFocusObject()
+ try:
+ focusInfo = self.makeTextInfo(focus)
+ except:
+ return False
+ # We only want to override the tab order if the caret is not
within the focused node.
+ caretInfo=self.makeTextInfo(textInfos.POSITION_CARET)
+ #Only check that the caret is within the focus for things that
ar not documents
+ #As for documents we should always override
+ if focus.role!=controlTypes.ROLE_DOCUMENT or
controlTypes.STATE_EDITABLE in focus.states:
+ # Expand to one character, as isOverlapping() doesn't
yield the desired results with collapsed ranges.
+ caretInfo.expand(textInfos.UNIT_CHARACTER)
+ if focusInfo.isOverlapping(caretInfo):
+ return False
+ # If we reach here, we do want to override tab/shift+tab if
possible.
+ # Find the next/previous focusable node.
+ try:
+ item = next(self._iterNodesByType("focusable",
direction, caretInfo))
+ except StopIteration:
+ return False
+ obj=item.obj
+ newInfo=item.textInfo
+ if obj == api.getFocusObject():
+ # This node is already focused, so we need to move to
and speak this node here.
+ newCaret = newInfo.copy()
+ newCaret.collapse()
+
self._set_selection(newCaret,reason=controlTypes.REASON_FOCUS)
+ if self.passThrough:
+ obj.event_gainFocus()
+ else:
+
speech.speakTextInfo(newInfo,reason=controlTypes.REASON_FOCUS)
+ else:
+ # This node doesn't have the focus, so just set focus
to it. The gainFocus event will handle the rest.
+ obj.setFocus()
+ return True
+
+ def script_tab(self, gesture):
+ if not self._tabOverride("next"):
+ gesture.send()
+
+ def script_shiftTab(self, gesture):
+ if not self._tabOverride("previous"):
+ gesture.send()
+
+ def event_focusEntered(self,obj,nextHandler):
+ if obj==self.rootNVDAObject:
+ self._enteringFromOutside = True
+ if self.passThrough:
+ nextHandler()
+
+ def _shouldIgnoreFocus(self, obj):
+ """Determines whether focus on a given object should be ignored.
+ @param obj: The object in question.
+ @type obj: L{NVDAObjects.NVDAObject}
+ @return: C{True} if focus on L{obj} should be ignored, C{False}
otherwise.
+ @rtype: bool
+ """
+ return False
+
+ def _postGainFocus(self, obj):
+ """Executed after a gainFocus within the browseMode document.
+ This will not be executed if L{event_gainFocus} determined that
it should abort and call nextHandler.
+ @param obj: The object that gained focus.
+ @type obj: L{NVDAObjects.NVDAObject}
+ """
+
+ def _replayFocusEnteredEvents(self):
+ # We blocked the focusEntered events because we were in browse
mode,
+ # but now that we've switched to focus mode, we need to fire
them.
+ for parent in
api.getFocusAncestors()[api.getFocusDifferenceLevel():]:
+ try:
+ parent.event_focusEntered()
+ except:
+ log.exception("Error executing focusEntered
event: %s" % parent)
+
+ def event_gainFocus(self, obj, nextHandler):
+ enteringFromOutside=self._enteringFromOutside
+ self._enteringFromOutside=False
+ if not self.isReady:
+ if self.passThrough:
+ nextHandler()
+ return
+ if enteringFromOutside and not self.passThrough and
self._lastFocusObj==obj:
+ # We're entering the document from outside (not
returning from an inside object/application; #3145)
+ # and this was the last non-root node with focus, so
ignore this focus event.
+ # Otherwise, if the user switches away and back to this
document, the cursor will jump to this node.
+ # This is not ideal if the user was positioned over a
node which cannot receive focus.
+ return
+ if obj==self.rootNVDAObject:
+ if self.passThrough:
+ return nextHandler()
+ return
+ if not self.passThrough and self._shouldIgnoreFocus(obj):
+ return
+ self._lastFocusObj=obj
+
+ try:
+ focusInfo = self.makeTextInfo(obj)
+ except:
+ # This object is not in the treeInterceptor, even
though it resides beneath the document.
+ # Automatic pass through should be enabled in certain
circumstances where this occurs.
+ if not self.passThrough and
self.shouldPassThrough(obj,reason=controlTypes.REASON_FOCUS):
+ self.passThrough=True
+ reportPassThrough(self)
+ self._replayFocusEnteredEvents()
+ return nextHandler()
+
+ #We only want to update the caret and speak the field if we're
not in the same one as before
+ caretInfo=self.makeTextInfo(textInfos.POSITION_CARET)
+ # Expand to one character, as isOverlapping() doesn't treat,
for example, (4,4) and (4,5) as overlapping.
+ caretInfo.expand(textInfos.UNIT_CHARACTER)
+ if not self._hadFirstGainFocus or not
focusInfo.isOverlapping(caretInfo):
+ # The virtual caret is not within the focus node.
+ oldPassThrough=self.passThrough
+
passThrough=self.shouldPassThrough(obj,reason=controlTypes.REASON_FOCUS)
+ if not oldPassThrough and (passThrough or
sayAllHandler.isRunning()):
+ # If pass-through is disabled, cancel speech,
as a focus change should cause page reading to stop.
+ # This must be done before auto-pass-through
occurs, as we want to stop page reading even if pass-through will be
automatically enabled by this focus change.
+ speech.cancelSpeech()
+ self.passThrough=passThrough
+ if not self.passThrough:
+ # We read the info from the browseMode document
instead of the control itself.
+
speech.speakTextInfo(focusInfo,reason=controlTypes.REASON_FOCUS)
+ # However, we still want to update the speech
property cache so that property changes will be spoken properly.
+
speech.speakObject(obj,controlTypes.REASON_ONLYCACHE)
+ else:
+ if not oldPassThrough:
+ self._replayFocusEnteredEvents()
+ nextHandler()
+ focusInfo.collapse()
+
self._set_selection(focusInfo,reason=controlTypes.REASON_FOCUS)
+ else:
+ # The virtual caret was already at the focused node.
+ if not self.passThrough:
+ # This focus change was caused by a virtual
caret movement, so don't speak the focused node to avoid double speaking.
+ # However, we still want to update the speech
property cache so that property changes will be spoken properly.
+
speech.speakObject(obj,controlTypes.REASON_ONLYCACHE)
+ else:
+ return nextHandler()
+
+ self._postGainFocus(obj)
+
+ event_gainFocus.ignoreIsReady=True
+
+ def _handleScrollTo(self, obj):
+ """Handle scrolling the browseMode document to a given object
in response to an event.
+ Subclasses should call this from an event which indicates that
the document has scrolled.
+ @postcondition: The virtual caret is moved to L{obj} and the
buffer content for L{obj} is reported.
+ @param obj: The object to which the document should scroll.
+ @type obj: L{NVDAObjects.NVDAObject}
+ @return: C{True} if the document was scrolled, C{False} if not.
+ @rtype: bool
+ @note: If C{False} is returned, calling events should probably
call their nextHandler.
+ """
+ if self.programmaticScrollMayFireEvent and
self._lastProgrammaticScrollTime and time.time() -
self._lastProgrammaticScrollTime < 0.4:
+ # This event was probably caused by this browseMode
document's call to scrollIntoView().
+ # Therefore, ignore it. Otherwise, the cursor may
bounce back to the scroll point.
+ # However, pretend we handled it, as we don't want it
to be passed on to the object either.
+ return True
+
+ try:
+ scrollInfo = self.makeTextInfo(obj)
+ except:
+ return False
+
+ #We only want to update the caret and speak the field if we're
not in the same one as before
+ caretInfo=self.makeTextInfo(textInfos.POSITION_CARET)
+ # Expand to one character, as isOverlapping() doesn't treat,
for example, (4,4) and (4,5) as overlapping.
+ caretInfo.expand(textInfos.UNIT_CHARACTER)
+ if not scrollInfo.isOverlapping(caretInfo):
+ if scrollInfo.isCollapsed:
+ scrollInfo.expand(textInfos.UNIT_LINE)
+
speech.speakTextInfo(scrollInfo,reason=controlTypes.REASON_CARET)
+ scrollInfo.collapse()
+ self.selection = scrollInfo
+ return True
+
+ return False
+
+ APPLICATION_ROLES = (controlTypes.ROLE_APPLICATION,
controlTypes.ROLE_DIALOG)
+ def _isNVDAObjectInApplication(self, obj):
+ """Determine whether a given object is within an application.
+ The object is considered to be within an application if it or
one of its ancestors has an application role.
+ This should only be called on objects beneath the
treeInterceptor's root NVDAObject.
+ @param obj: The object in question.
+ @type obj: L{NVDAObjects.NVDAObject}
+ @return: C{True} if L{obj} is within an application, C{False}
otherwise.
+ @rtype: bool
+ """
+ while obj and obj != self.rootNVDAObject:
+ if obj.role in self.APPLICATION_ROLES:
+ return True
+ obj = obj.parent
+ return False
+
+ def _get_documentConstantIdentifier(self):
+ """Get the constant identifier for this document.
+ This identifier should uniquely identify all instances (not
just one instance) of a document for at least the current session of the
hosting application.
+ Generally, the document URL should be used.
+ @return: The constant identifier for this document, C{None} if
there is none.
+ """
+ return None
+
+ def _get_shouldRememberCaretPositionAcrossLoads(self):
+ """Specifies whether the position of the caret should be
remembered when this document is loaded again.
+ This is useful when the browser remembers the scroll position
for the document,
+ but does not communicate this information via APIs.
+ The remembered caret position is associated with this document
using L{documentConstantIdentifier}.
+ @return: C{True} if the caret position should be remembered,
C{False} if not.
+ @rtype: bool
+ """
+ docConstId = self.documentConstantIdentifier
+ # Return True if the URL indicates that this is probably a web
browser document.
+ # We do this check because we don't want to remember caret
positions for email messages, etc.
+ return isinstance(docConstId, basestring) and
docConstId.split("://", 1)[0] in ("http", "https", "ftp", "ftps", "file")
+
+ def _getInitialCaretPos(self):
+ """Retrieve the initial position of the caret after the buffer
has been loaded.
+ This position, if any, will be passed to L{makeTextInfo}.
+ Subclasses should extend this method.
+ @return: The initial position of the caret, C{None} if there
isn't one.
+ @rtype: TextInfo position
+ """
+ if self.shouldRememberCaretPositionAcrossLoads:
+ try:
+ return
self.rootNVDAObject.appModule._browseModeRememberedCaretPositions[self.documentConstantIdentifier]
+ except KeyError:
+ pass
+ return None
+
+ __gestures={
+ "kb:NVDA+d": "activateLongDesc",
+ "kb:escape": "disablePassThrough",
+ "kb:alt+upArrow": "collapseOrExpandControl",
+ "kb:alt+downArrow": "collapseOrExpandControl",
+ "kb:tab": "tab",
+ "kb:shift+tab": "shiftTab",
+ }

diff --git a/source/cursorManager.py b/source/cursorManager.py
index 6bf030f..3b407cd 100644
--- a/source/cursorManager.py
+++ b/source/cursorManager.py
@@ -356,10 +356,10 @@ class _ReviewCursorManagerTextInfo(textInfos.TextInfo):
def updateCaret(self):
info=self.copy()
info.collapse()
- self.obj.selection = info
+ self.obj._selection = info

def updateSelection(self):
- self.obj.selection = self
+ self.obj._selection = self.copy()

class ReviewCursorManager(CursorManager):
"""
@@ -376,17 +376,9 @@ class ReviewCursorManager(CursorManager):

def makeTextInfo(self, position):
if position == textInfos.POSITION_SELECTION:
- return self.selection
+ return self._selection.copy()
elif position == textInfos.POSITION_CARET:
- sel = self.selection
+ sel = self._selection.copy()
sel.collapse()
return sel
return super(ReviewCursorManager, self).makeTextInfo(position)
-
- def _get_selection(self):
- return self._selection.copy()
-
- def _set_selection(self, info):
- self._selection = info.copy()
- review.handleCaretMove(info)
- braille.handler.handleCaretMove(self)

diff --git a/source/treeInterceptorHandler.py b/source/treeInterceptorHandler.py
index af2a0f7..5b26e0e 100644
--- a/source/treeInterceptorHandler.py
+++ b/source/treeInterceptorHandler.py
@@ -205,3 +205,6 @@ class RootProxyTextInfo(textInfos.TextInfo):

def _get_NVDAObjectAtStart(self):
return self.innerTextInfo.NVDAObjectAtStart
+
+ def _get_focusableNVDAObjectAtStart(self):
+ return self.innerTextInfo.focusableNVDAObjectAtStart

diff --git a/source/virtualBuffers/__init__.py
b/source/virtualBuffers/__init__.py
index f9966eb..db15de7 100644
--- a/source/virtualBuffers/__init__.py
+++ b/source/virtualBuffers/__init__.py
@@ -107,6 +107,10 @@ class
VirtualBufferQuickNavItem(browseMode.TextInfoQuickNavItem):
self.vbufNode=vbufNode

@property
+ def obj(self):
+ return
self.document.getNVDAObjectFromIdentifier(*self.vbufFieldIdentifier)
+
+ @property
def label(self):
if self.itemType == "landmark":
attrs =
self.textInfo._getControlFieldAttribs(self.vbufFieldIdentifier[0],
self.vbufFieldIdentifier[1])
@@ -136,7 +140,7 @@ class
VirtualBufferQuickNavItem(browseMode.TextInfoQuickNavItem):
info.collapse()

self.document._set_selection(info,reason=browseMode.REASON_QUICKNAV)

-class VirtualBufferTextInfo(textInfos.offsets.OffsetsTextInfo):
+class
VirtualBufferTextInfo(browseMode.BrowseModeDocumentTextInfo,textInfos.offsets.OffsetsTextInfo):

allowMoveToOffsetPastEnd=False #: no need for end insertion point as
vbuf is not editable.

@@ -327,50 +331,6 @@ class
VirtualBufferTextInfo(textInfos.offsets.OffsetsTextInfo):
blocks = (block.strip("\r\n") for block in
self.getTextInChunks(textInfos.UNIT_PARAGRAPH))
return "\r\n".join(blocks)

- def getControlFieldSpeech(self, attrs, ancestorAttrs, fieldType,
formatConfig=None, extraDetail=False, reason=None):
- textList = []
- landmark = attrs.get("landmark")
- if formatConfig["reportLandmarks"] and fieldType ==
"start_addedToControlFieldStack" and landmark:
- try:
- textList.append(attrs["name"])
- except KeyError:
- pass
- if landmark == "region":
- # The word landmark is superfluous for regions.
- textList.append(aria.landmarkRoles[landmark])
- else:
- textList.append(_("%s landmark") %
aria.landmarkRoles[landmark])
- textList.append(super(VirtualBufferTextInfo,
self).getControlFieldSpeech(attrs, ancestorAttrs, fieldType, formatConfig,
extraDetail, reason))
- return " ".join(textList)
-
- def getControlFieldBraille(self, field, ancestors, reportStart,
formatConfig):
- textList = []
- landmark = field.get("landmark")
- if formatConfig["reportLandmarks"] and reportStart and landmark
and field.get("_startOfNode"):
- try:
- textList.append(field["name"])
- except KeyError:
- pass
- if landmark == "region":
- # The word landmark is superfluous for regions.
- textList.append(aria.landmarkRoles[landmark])
- else:
- # Translators: This is spoken and brailled to
indicate a landmark (example output: main landmark).
- textList.append(_("%s landmark") %
aria.landmarkRoles[landmark])
- text = super(VirtualBufferTextInfo,
self).getControlFieldBraille(field, ancestors, reportStart, formatConfig)
- if text:
- textList.append(text)
- return " ".join(textList)
-
- def _get_focusableNVDAObjectAtStart(self):
- try:
- item = next(self.obj._iterNodesByType("focusable",
"up", self))
- except StopIteration:
- return self.obj.rootNVDAObject
- if not item:
- return self.obj.rootNVDAObject
- return
self.obj.getNVDAObjectFromIdentifier(*item.vbufFieldIdentifier)
-
def activate(self):
self.obj._activatePosition(self)

@@ -380,10 +340,9 @@ class
VirtualBufferTextInfo(textInfos.offsets.OffsetsTextInfo):
obj = self.obj.getNVDAObjectFromIdentifier(docHandle, nodeId)
return obj.mathMl

-class VirtualBuffer(cursorManager.CursorManager,
browseMode.BrowseModeTreeInterceptor,
treeInterceptorHandler.DocumentTreeInterceptor):
+class VirtualBuffer(browseMode.BrowseModeDocumentTreeInterceptor):

TextInfo=VirtualBufferTextInfo
- programmaticScrollMayFireEvent = False

#: Maps root identifiers (docHandle and ID) to buffers.
rootIdentifiers = weakref.WeakValueDictionary()
@@ -393,18 +352,8 @@ class VirtualBuffer(cursorManager.CursorManager,
browseMode.BrowseModeTreeInterc
self.backendName=backendName
self.VBufHandle=None
self.isLoading=False
- self.disableAutoPassThrough = False

self.rootDocHandle,self.rootID=self.getIdentifierFromNVDAObject(self.rootNVDAObject)
- self._lastFocusObj = None
- self._hadFirstGainFocus = False
- self._lastProgrammaticScrollTime = None
- # We need to cache this because it will be unavailable once the
document dies.
- self.documentConstantIdentifier =
self.documentConstantIdentifier
- if not hasattr(self.rootNVDAObject.appModule,
"_vbufRememberedCaretPositions"):
-
self.rootNVDAObject.appModule._vbufRememberedCaretPositions = {}
- self._lastCaretPosition = None
self.rootIdentifiers[self.rootDocHandle, self.rootID] = self
- self._enteringFromOutside = True

def prepare(self):
self.shouldPrepare=False
@@ -414,16 +363,9 @@ class VirtualBuffer(cursorManager.CursorManager,
browseMode.BrowseModeTreeInterc
return not self.isLoading and not self.VBufHandle

def terminate(self):
+ super(VirtualBuffer,self).terminate()
if not self.VBufHandle:
return
-
- if self.shouldRememberCaretPositionAcrossLoads and
self._lastCaretPosition:
- try:
-
self.rootNVDAObject.appModule._vbufRememberedCaretPositions[self.documentConstantIdentifier]
= self._lastCaretPosition
- except AttributeError:
- # The app module died.
- pass
-
self.unloadBuffer()

def _get_isReady(self):
@@ -518,160 +460,6 @@ class VirtualBuffer(cursorManager.CursorManager,
browseMode.BrowseModeTreeInterc
"""
raise NotImplementedError

- def event_treeInterceptor_gainFocus(self):
- """Triggered when this virtual buffer gains focus.
- This event is only fired upon entering this buffer when it was
not the current buffer before.
- This is different to L{event_gainFocus}, which is fired when an
object inside this buffer gains focus, even if that object is in the same
buffer.
- """
- doSayAll=False
- hadFirstGainFocus=self._hadFirstGainFocus
- if not hadFirstGainFocus:
- # This buffer is gaining focus for the first time.
- # Fake a focus event on the focus object, as the buffer
may have missed the actual focus event.
- focus = api.getFocusObject()
- self.event_gainFocus(focus, lambda:
focus.event_gainFocus())
- if not self.passThrough:
- # We only set the caret position if in browse
mode.
- # If in focus mode, the document must have
forced the focus somewhere,
- # so we don't want to override it.
- initialPos = self._getInitialCaretPos()
- if initialPos:
- self.selection =
self.makeTextInfo(initialPos)
- browseMode.reportPassThrough(self)
-
doSayAll=config.conf['virtualBuffers']['autoSayAllOnPageLoad']
- self._hadFirstGainFocus = True
-
- if not self.passThrough:
- if doSayAll:
-
speech.speakObjectProperties(self.rootNVDAObject,name=True,states=True,reason=controlTypes.REASON_FOCUS)
-
sayAllHandler.readText(sayAllHandler.CURSOR_CARET)
- else:
- # Speak it like we would speak focus on any
other document object.
- # This includes when entering the
treeInterceptor for the first time:
- if not hadFirstGainFocus:
- speech.speakObject(self.rootNVDAObject,
reason=controlTypes.REASON_FOCUS)
- else:
- # And when coming in from an outside
object
- # #4069 But not when coming up from a
non-rendered descendant.
- ancestors=api.getFocusAncestors()
- fdl=api.getFocusDifferenceLevel()
- try:
-
tl=ancestors.index(self.rootNVDAObject)
- except ValueError:
- tl=len(ancestors)
- if fdl<=tl:
-
speech.speakObject(self.rootNVDAObject, reason=controlTypes.REASON_FOCUS)
- info = self.selection
- if not info.isCollapsed:
-
speech.speakSelectionMessage(_("selected %s"), info.text)
- else:
- info.expand(textInfos.UNIT_LINE)
- speech.speakTextInfo(info,
reason=controlTypes.REASON_CARET, unit=textInfos.UNIT_LINE)
-
- browseMode.reportPassThrough(self)
- braille.handler.handleGainFocus(self)
-
- def event_treeInterceptor_loseFocus(self):
- """Triggered when this virtual buffer loses focus.
- This event is only fired when the focus moves to a new object
which is not within this virtual buffer; i.e. upon leaving this virtual buffer.
- """
-
- def event_caret(self, obj, nextHandler):
- if self.passThrough:
- nextHandler()
-
- def _activateNVDAObject(self, obj):
- """Activate an object in response to a user request.
- This should generally perform the default action or click on
the object.
- @param obj: The object to activate.
- @type obj: L{NVDAObjects.NVDAObject}
- """
- obj.doAction()
-
- def _activateLongDesc(self,controlField):
- """
- Activates (presents) the long description for a particular
field (usually a graphic).
- @param controlField: the field who's long description should be
activated. This field is guaranteed to have states containing HASLONGDESC
state.
- @type controlField: dict
- """
- raise NotImplementedError
-
- def _activatePosition(self, info):
- obj = info.NVDAObjectAtStart
- if not obj:
- return
- if obj.role == controlTypes.ROLE_MATH:
- import mathPres
- try:
- return mathPres.interactWithMathMl(obj.mathMl)
- except (NotImplementedError, LookupError):
- pass
- return
- if self.shouldPassThrough(obj):
- obj.setFocus()
- self.passThrough = True
- browseMode.reportPassThrough(self)
- elif obj.role == controlTypes.ROLE_EMBEDDEDOBJECT or obj.role
in self.APPLICATION_ROLES:
- obj.setFocus()
- speech.speakObject(obj,
reason=controlTypes.REASON_FOCUS)
- else:
- self._activateNVDAObject(obj)
-
- def _set_selection(self, info, reason=controlTypes.REASON_CARET):
- super(VirtualBuffer, self)._set_selection(info)
- if isScriptWaiting() or not info.isCollapsed:
- return
- # Save the last caret position for use in terminate().
- # This must be done here because the buffer might be cleared
just before terminate() is called,
- # causing the last caret position to be lost.
- caret = info.copy()
- caret.collapse()
- self._lastCaretPosition = caret.bookmark
- review.handleCaretMove(caret)
- if reason == controlTypes.REASON_FOCUS:
- focusObj = api.getFocusObject()
- if focusObj==self.rootNVDAObject:
- return
- else:
- focusObj=info.focusableNVDAObjectAtStart
- obj=info.NVDAObjectAtStart
- if not obj:
- log.debugWarning("Invalid NVDAObjectAtStart")
- return
- if obj==self.rootNVDAObject:
- return
- if focusObj and not
eventHandler.isPendingEvents("gainFocus") and focusObj!=self.rootNVDAObject and
focusObj != api.getFocusObject() and self._shouldSetFocusToObj(focusObj):
- focusObj.setFocus()
- obj.scrollIntoView()
- if self.programmaticScrollMayFireEvent:
- self._lastProgrammaticScrollTime = time.time()
- self.passThrough=self.shouldPassThrough(focusObj,reason=reason)
- # Queue the reporting of pass through mode so that it will be
spoken after the actual content.
- queueHandler.queueFunction(queueHandler.eventQueue,
browseMode.reportPassThrough, self)
-
- def _shouldSetFocusToObj(self, obj):
- """Determine whether an object should receive focus.
- Subclasses may extend or override this method.
- @param obj: The object in question.
- @type obj: L{NVDAObjects.NVDAObject}
- """
- return obj.role not in self.APPLICATION_ROLES and
obj.isFocusable and obj.role!=controlTypes.ROLE_EMBEDDEDOBJECT
-
- def script_activateLongDesc(self,gesture):
- info=self.makeTextInfo(textInfos.POSITION_CARET)
- info.expand("character")
- for field in reversed(info.getTextWithFields()):
- if isinstance(field,textInfos.FieldCommand) and
field.command=="controlStart":
- states=field.field.get('states')
- if states and controlTypes.STATE_HASLONGDESC in
states:
- self._activateLongDesc(field.field)
- break
- else:
- # Translators: the message presented when the
activateLongDescription script cannot locate a long description to activate.
- ui.message(_("No long description"))
- # Translators: the description for the activateLongDescription script
on virtualBuffers.
- script_activateLongDesc.__doc__=_("Shows the long description at this
position if one is found.")
-
def script_refreshBuffer(self,gesture):
if scriptHandler.isScriptWaiting():
# This script may cause subsequently queued scripts to
fail, so don't execute.
@@ -727,275 +515,6 @@ class VirtualBuffer(cursorManager.CursorManager,
browseMode.BrowseModeTreeInterc
yield
VirtualBufferQuickNavItem(nodeType,self,node,startOffset.value,endOffset.value)
offset=startOffset

- def shouldPassThrough(self, obj, reason=None):
- """Determine whether pass through mode should be enabled or
disabled for a given object.
- @param obj: The object in question.
- @type obj: L{NVDAObjects.NVDAObject}
- @param reason: The reason for this query; one of the output
reasons, L{REASON_QUICKNAV}, or C{None} for manual pass through mode activation
by the user.
- @return: C{True} if pass through mode should be enabled,
C{False} if it should be disabled.
- """
- if reason and (
- self.disableAutoPassThrough
- or (reason == controlTypes.REASON_FOCUS and not
config.conf["virtualBuffers"]["autoPassThroughOnFocusChange"])
- or (reason == controlTypes.REASON_CARET and not
config.conf["virtualBuffers"]["autoPassThroughOnCaretMove"])
- ):
- # This check relates to auto pass through and auto pass
through is disabled, so don't change the pass through state.
- return self.passThrough
- if reason == browseMode.REASON_QUICKNAV:
- return False
- states = obj.states
- role = obj.role
- # Menus sometimes get focus due to menuStart events even though
they don't report as focused/focusable.
- if not obj.isFocusable and controlTypes.STATE_FOCUSED not in
states and role != controlTypes.ROLE_POPUPMENU:
- return False
- if controlTypes.STATE_READONLY in states and role not in
(controlTypes.ROLE_EDITABLETEXT, controlTypes.ROLE_COMBOBOX):
- return False
- if reason == controlTypes.REASON_CARET:
- return role == controlTypes.ROLE_EDITABLETEXT or (role
== controlTypes.ROLE_DOCUMENT and controlTypes.STATE_EDITABLE in states)
- if reason == controlTypes.REASON_FOCUS and role in
(controlTypes.ROLE_LISTITEM, controlTypes.ROLE_RADIOBUTTON,
controlTypes.ROLE_TAB):
- return True
- if role in (controlTypes.ROLE_COMBOBOX,
controlTypes.ROLE_EDITABLETEXT, controlTypes.ROLE_LIST,
controlTypes.ROLE_SLIDER, controlTypes.ROLE_TABCONTROL,
controlTypes.ROLE_MENUBAR, controlTypes.ROLE_POPUPMENU,
controlTypes.ROLE_MENUITEM, controlTypes.ROLE_TREEVIEW,
controlTypes.ROLE_TREEVIEWITEM, controlTypes.ROLE_SPINBUTTON,
controlTypes.ROLE_TABLEROW, controlTypes.ROLE_TABLECELL,
controlTypes.ROLE_TABLEROWHEADER, controlTypes.ROLE_TABLECOLUMNHEADER,
controlTypes.ROLE_CHECKMENUITEM, controlTypes.ROLE_RADIOMENUITEM) or
controlTypes.STATE_EDITABLE in states:
- return True
- if reason == controlTypes.REASON_FOCUS:
- # If this is a focus change, pass through should be
enabled for certain ancestor containers.
- while obj and obj != self.rootNVDAObject:
- if obj.role == controlTypes.ROLE_TOOLBAR:
- return True
- obj = obj.parent
- return False
-
- def event_caretMovementFailed(self, obj, nextHandler, gesture=None):
- if not self.passThrough or not gesture or not
config.conf["virtualBuffers"]["autoPassThroughOnCaretMove"]:
- return nextHandler()
- if gesture.mainKeyName in ("home", "end"):
- # Home, end, control+home and control+end should not
disable pass through.
- return nextHandler()
- script = self.getScript(gesture)
- if not script:
- return nextHandler()
-
- # We've hit the edge of the focused control.
- # Therefore, move the virtual caret to the same edge of the
field.
- info = self.makeTextInfo(textInfos.POSITION_CARET)
- info.expand(info.UNIT_CONTROLFIELD)
- if gesture.mainKeyName in ("leftArrow", "upArrow", "pageUp"):
- info.collapse()
- else:
- info.collapse(end=True)
- info.move(textInfos.UNIT_CHARACTER, -1)
- info.updateCaret()
-
- scriptHandler.queueScript(script, gesture)
-
- def script_disablePassThrough(self, gesture):
- if not self.passThrough or self.disableAutoPassThrough:
- return gesture.send()
- self.passThrough = False
- self.disableAutoPassThrough = False
- browseMode.reportPassThrough(self)
- script_disablePassThrough.ignoreTreeInterceptorPassThrough = True
-
- def script_collapseOrExpandControl(self, gesture):
- oldFocus = api.getFocusObject()
- oldFocusStates = oldFocus.states
- gesture.send()
- if controlTypes.STATE_COLLAPSED in oldFocusStates:
- self.passThrough = True
- elif not self.disableAutoPassThrough:
- self.passThrough = False
- browseMode.reportPassThrough(self)
- script_collapseOrExpandControl.ignoreTreeInterceptorPassThrough = True
-
- def _tabOverride(self, direction):
- """Override the tab order if the virtual buffer caret is not
within the currently focused node.
- This is done because many nodes are not focusable and it is
thus possible for the virtual buffer caret to be unsynchronised with the focus.
- In this case, we want tab/shift+tab to move to the
next/previous focusable node relative to the virtual buffer caret.
- If the virtual buffer caret is within the focused node, the
tab/shift+tab key should be passed through to allow normal tab order navigation.
- Note that this method does not pass the key through itself if
it is not overridden. This should be done by the calling script if C{False} is
returned.
- @param direction: The direction in which to move.
- @type direction: str
- @return: C{True} if the tab order was overridden, C{False} if
not.
- @rtype: bool
- """
- focus = api.getFocusObject()
- try:
- focusInfo = self.makeTextInfo(focus)
- except:
- return False
- # We only want to override the tab order if the caret is not
within the focused node.
- caretInfo=self.makeTextInfo(textInfos.POSITION_CARET)
- #Only check that the caret is within the focus for things that
ar not documents
- #As for documents we should always override
- if focus.role!=controlTypes.ROLE_DOCUMENT or
controlTypes.STATE_EDITABLE in focus.states:
- # Expand to one character, as isOverlapping() doesn't
yield the desired results with collapsed ranges.
- caretInfo.expand(textInfos.UNIT_CHARACTER)
- if focusInfo.isOverlapping(caretInfo):
- return False
- # If we reach here, we do want to override tab/shift+tab if
possible.
- # Find the next/previous focusable node.
- try:
- item = next(self._iterNodesByType("focusable",
direction, caretInfo))
- except StopIteration:
- return False
- obj=self.getNVDAObjectFromIdentifier(*item.vbufFieldIdentifier)
- newInfo=item.textInfo
- if obj == api.getFocusObject():
- # This node is already focused, so we need to move to
and speak this node here.
- newCaret = newInfo.copy()
- newCaret.collapse()
-
self._set_selection(newCaret,reason=controlTypes.REASON_FOCUS)
- if self.passThrough:
- obj.event_gainFocus()
- else:
-
speech.speakTextInfo(newInfo,reason=controlTypes.REASON_FOCUS)
- else:
- # This node doesn't have the focus, so just set focus
to it. The gainFocus event will handle the rest.
- obj.setFocus()
- return True
-
- def script_tab(self, gesture):
- if not self._tabOverride("next"):
- gesture.send()
-
- def script_shiftTab(self, gesture):
- if not self._tabOverride("previous"):
- gesture.send()
-
- def event_focusEntered(self,obj,nextHandler):
- if obj==self.rootNVDAObject:
- self._enteringFromOutside = True
- if self.passThrough:
- nextHandler()
-
- def _shouldIgnoreFocus(self, obj):
- """Determines whether focus on a given object should be ignored.
- @param obj: The object in question.
- @type obj: L{NVDAObjects.NVDAObject}
- @return: C{True} if focus on L{obj} should be ignored, C{False}
otherwise.
- @rtype: bool
- """
- return False
-
- def _postGainFocus(self, obj):
- """Executed after a gainFocus within the virtual buffer.
- This will not be executed if L{event_gainFocus} determined that
it should abort and call nextHandler.
- @param obj: The object that gained focus.
- @type obj: L{NVDAObjects.NVDAObject}
- """
-
- def _replayFocusEnteredEvents(self):
- # We blocked the focusEntered events because we were in browse
mode,
- # but now that we've switched to focus mode, we need to fire
them.
- for parent in
api.getFocusAncestors()[api.getFocusDifferenceLevel():]:
- try:
- parent.event_focusEntered()
- except:
- log.exception("Error executing focusEntered
event: %s" % parent)
-
- def event_gainFocus(self, obj, nextHandler):
- enteringFromOutside=self._enteringFromOutside
- self._enteringFromOutside=False
- if not self.isReady:
- if self.passThrough:
- nextHandler()
- return
- if enteringFromOutside and not self.passThrough and
self._lastFocusObj==obj:
- # We're entering the document from outside (not
returning from an inside object/application; #3145)
- # and this was the last non-root node with focus, so
ignore this focus event.
- # Otherwise, if the user switches away and back to this
document, the cursor will jump to this node.
- # This is not ideal if the user was positioned over a
node which cannot receive focus.
- return
- if obj==self.rootNVDAObject:
- if self.passThrough:
- return nextHandler()
- return
- if not self.passThrough and self._shouldIgnoreFocus(obj):
- return
- self._lastFocusObj=obj
-
- try:
- focusInfo = self.makeTextInfo(obj)
- except:
- # This object is not in the virtual buffer, even though
it resides beneath the document.
- # Automatic pass through should be enabled in certain
circumstances where this occurs.
- if not self.passThrough and
self.shouldPassThrough(obj,reason=controlTypes.REASON_FOCUS):
- self.passThrough=True
- browseMode.reportPassThrough(self)
- self._replayFocusEnteredEvents()
- return nextHandler()
-
- #We only want to update the caret and speak the field if we're
not in the same one as before
- caretInfo=self.makeTextInfo(textInfos.POSITION_CARET)
- # Expand to one character, as isOverlapping() doesn't treat,
for example, (4,4) and (4,5) as overlapping.
- caretInfo.expand(textInfos.UNIT_CHARACTER)
- if not self._hadFirstGainFocus or not
focusInfo.isOverlapping(caretInfo):
- # The virtual buffer caret is not within the focus node.
- oldPassThrough=self.passThrough
-
passThrough=self.shouldPassThrough(obj,reason=controlTypes.REASON_FOCUS)
- if not oldPassThrough and (passThrough or
sayAllHandler.isRunning()):
- # If pass-through is disabled, cancel speech,
as a focus change should cause page reading to stop.
- # This must be done before auto-pass-through
occurs, as we want to stop page reading even if pass-through will be
automatically enabled by this focus change.
- speech.cancelSpeech()
- self.passThrough=passThrough
- if not self.passThrough:
- # We read the info from the buffer instead of
the control itself.
-
speech.speakTextInfo(focusInfo,reason=controlTypes.REASON_FOCUS)
- # However, we still want to update the speech
property cache so that property changes will be spoken properly.
-
speech.speakObject(obj,controlTypes.REASON_ONLYCACHE)
- else:
- if not oldPassThrough:
- self._replayFocusEnteredEvents()
- nextHandler()
- focusInfo.collapse()
-
self._set_selection(focusInfo,reason=controlTypes.REASON_FOCUS)
- else:
- # The virtual buffer caret was already at the focused
node.
- if not self.passThrough:
- # This focus change was caused by a virtual
caret movement, so don't speak the focused node to avoid double speaking.
- # However, we still want to update the speech
property cache so that property changes will be spoken properly.
-
speech.speakObject(obj,controlTypes.REASON_ONLYCACHE)
- else:
- return nextHandler()
-
- self._postGainFocus(obj)
-
- event_gainFocus.ignoreIsReady=True
-
- def _handleScrollTo(self, obj):
- """Handle scrolling the buffer to a given object in response to
an event.
- Subclasses should call this from an event which indicates that
the buffer has scrolled.
- @postcondition: The buffer caret is moved to L{obj} and the
buffer content for L{obj} is reported.
- @param obj: The object to which the buffer should scroll.
- @type obj: L{NVDAObjects.NVDAObject}
- @return: C{True} if the buffer was scrolled, C{False} if not.
- @rtype: bool
- @note: If C{False} is returned, calling events should probably
call their nextHandler.
- """
- if self.programmaticScrollMayFireEvent and
self._lastProgrammaticScrollTime and time.time() -
self._lastProgrammaticScrollTime < 0.4:
- # This event was probably caused by this buffer's call
to scrollIntoView().
- # Therefore, ignore it. Otherwise, the cursor may
bounce back to the scroll point.
- # However, pretend we handled it, as we don't want it
to be passed on to the object either.
- return True
-
- try:
- scrollInfo = self.makeTextInfo(obj)
- except:
- return False
-
- #We only want to update the caret and speak the field if we're
not in the same one as before
- caretInfo=self.makeTextInfo(textInfos.POSITION_CARET)
- # Expand to one character, as isOverlapping() doesn't treat,
for example, (4,4) and (4,5) as overlapping.
- caretInfo.expand(textInfos.UNIT_CHARACTER)
- if not scrollInfo.isOverlapping(caretInfo):
- if scrollInfo.isCollapsed:
- scrollInfo.expand(textInfos.UNIT_LINE)
-
speech.speakTextInfo(scrollInfo,reason=controlTypes.REASON_CARET)
- scrollInfo.collapse()
- self.selection = scrollInfo
- return True
-
- return False
-
def _getTableCellCoords(self, info):
if info.isCollapsed:
info = info.copy()
@@ -1133,22 +652,6 @@ class VirtualBuffer(cursorManager.CursorManager,
browseMode.BrowseModeTreeInterc
# Translators: the description for the previous table column script on
virtualBuffers.
script_previousColumn.__doc__ = _("moves to the previous table column")

- APPLICATION_ROLES = (controlTypes.ROLE_APPLICATION,
controlTypes.ROLE_DIALOG)
- def _isNVDAObjectInApplication(self, obj):
- """Determine whether a given object is within an application.
- The object is considered to be within an application if it or
one of its ancestors has an application role.
- This should only be called on objects beneath the buffer's root
NVDAObject.
- @param obj: The object in question.
- @type obj: L{NVDAObjects.NVDAObject}
- @return: C{True} if L{obj} is within an application, C{False}
otherwise.
- @rtype: bool
- """
- while obj and obj != self.rootNVDAObject:
- if obj.role in self.APPLICATION_ROLES:
- return True
- obj = obj.parent
- return False
-
NOT_LINK_BLOCK_MIN_LEN = 30
def _iterNotLinkBlock(self, direction="next", pos=None):
links = self._iterNodesByType("link", direction=direction,
pos=pos)
@@ -1164,41 +667,6 @@ class VirtualBuffer(cursorManager.CursorManager,
browseMode.BrowseModeTreeInterc
yield
VirtualBufferQuickNavItem("notLinkBlock",self,0,item2.textInfo._endOffset,
item1.textInfo._startOffset)
item1=item2

- def _getInitialCaretPos(self):
- """Retrieve the initial position of the caret after the buffer
has been loaded.
- This position, if any, will be passed to L{makeTextInfo}.
- Subclasses should extend this method.
- @return: The initial position of the caret, C{None} if there
isn't one.
- @rtype: TextInfo position
- """
- if self.shouldRememberCaretPositionAcrossLoads:
- try:
- return
self.rootNVDAObject.appModule._vbufRememberedCaretPositions[self.documentConstantIdentifier]
- except KeyError:
- pass
- return None
-
- def _get_documentConstantIdentifier(self):
- """Get the constant identifier for this document.
- This identifier should uniquely identify all instances (not
just one instance) of a document for at least the current session of the
hosting application.
- Generally, the document URL should be used.
- @return: The constant identifier for this document, C{None} if
there is none.
- """
- return None
-
- def _get_shouldRememberCaretPositionAcrossLoads(self):
- """Specifies whether the position of the caret should be
remembered when this document is loaded again.
- This is useful when the browser remembers the scroll position
for the document,
- but does not communicate this information via APIs.
- The remembered caret position is associated with this document
using L{documentConstantIdentifier}.
- @return: C{True} if the caret position should be remembered,
C{False} if not.
- @rtype: bool
- """
- docConstId = self.documentConstantIdentifier
- # Return True if the URL indicates that this is probably a web
browser document.
- # We do this check because we don't want to remember caret
positions for email messages, etc.
- return isinstance(docConstId, basestring) and
docConstId.split("://", 1)[0] in ("http", "https", "ftp", "ftps", "file")
-
def getEnclosingContainerRange(self,range):
formatConfig=config.conf['documentFormatting'].copy()

formatConfig.update({"reportBlockQuotes":True,"reportTables":True,"reportLists":True,"reportFrames":True})
@@ -1286,14 +754,8 @@ class VirtualBuffer(cursorManager.CursorManager,
browseMode.BrowseModeTreeInterc
raise LookupError

__gestures = {
- "kb:NVDA+d": "activateLongDesc",
"kb:NVDA+f5": "refreshBuffer",
"kb:NVDA+v": "toggleScreenLayout",
- "kb:escape": "disablePassThrough",
- "kb:alt+upArrow": "collapseOrExpandControl",
- "kb:alt+downArrow": "collapseOrExpandControl",
- "kb:tab": "tab",
- "kb:shift+tab": "shiftTab",
"kb:control+alt+downArrow": "nextRow",
"kb:control+alt+upArrow": "previousRow",
"kb:control+alt+rightArrow": "nextColumn",


https://bitbucket.org/nvdaaddonteam/nvda/commits/bd91b6bf74f0/
Changeset: bd91b6bf74f0
Branch: None
User: mdcurran
Date: 2015-06-07 01:16:31+00:00
Summary: UIA Edge treeInterceptor: support quicknav for specific heading
levels and hyerarchical ordering of headings in Elements List.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index 5255314..4efdc5c 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -57,7 +57,18 @@ class
UIATextRangeQuickNavItem(browseMode.TextInfoQuickNavItem):

UIAElement=UIAElement.buildUpdatedCache(UIAHandler.handler.baseCacheRequest)
return UIA(UIAElement=UIAElement)

-def
UIATextAttributeQuickNavIterator(itemType,document,position,attributeID,attributeValue,direction="next"):
+class HeadingUIATextRangeQuickNavItem(UIATextRangeQuickNavItem):
+
+ @property
+ def level(self):
+ return int(self.itemType[7:]) if len(self.itemType)>7 else 0
+
+ def isChild(self,parent):
+ if not isinstance(parent,HeadingUIATextRangeQuickNavItem):
+ return False
+ return self.level>parent.level
+
+def
UIATextAttributeQuickNavIterator(itemType,document,position,attributeID,attributeValue,direction="next",ItemClass=UIATextRangeQuickNavItem):
includeCurrent=False
if not position:
position=document.makeTextInfo(textInfos.POSITION_ALL)
@@ -77,7 +88,7 @@ def
UIATextAttributeQuickNavIterator(itemType,document,position,attributeID,attr
if not newRange:
return
if includeCurrent or
newRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,position._rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)>0:
- yield
UIATextRangeQuickNavItem(itemType,document,newRange)
+ yield ItemClass(itemType,document,newRange)
includeCurrent=True
if direction=="previous":

position._rangeObj.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_End,newRange,UIAHandler.TextPatternRangeEndpoint_Start)
@@ -284,7 +295,10 @@ class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.Brows

def _iterNodesByType(self,nodeType,direction="next",pos=None):
if nodeType=="heading":
- return
browseMode.mergeQuickNavItemIterators([UIATextAttributeQuickNavIterator("heading",self,pos,UIAHandler.UIA_StyleIdAttributeId,value,direction)
for value in
xrange(UIAHandler.StyleId_Heading1,UIAHandler.StyleId_Heading7)],direction)
+ return
browseMode.mergeQuickNavItemIterators([UIATextAttributeQuickNavIterator("heading%d"%level,self,pos,UIAHandler.UIA_StyleIdAttributeId,UIAHandler.StyleId_Heading1+(level-1),direction,HeadingUIATextRangeQuickNavItem)
for level in xrange(1,7)],direction)
+ elif nodeType.startswith("heading"):
+ level=int(nodeType[7:])
+ return
UIATextAttributeQuickNavIterator(nodeType,self,pos,UIAHandler.UIA_StyleIdAttributeId,UIAHandler.StyleId_Heading1+(level-1),direction,HeadingUIATextRangeQuickNavItem)
elif nodeType=="link":

condition=UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_ControlTypePropertyId,UIAHandler.UIA_HyperlinkControlTypeId)
return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)


https://bitbucket.org/nvdaaddonteam/nvda/commits/7cc3f83f9ea0/
Changeset: 7cc3f83f9ea0
Branch: None
User: mdcurran
Date: 2015-06-10 15:32:25+00:00
Summary: UIATextInfo: ensure not to recurse into child objects that are
past the range but incorrectly included, when grabing text and fields.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 697c868..1548cda 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -199,6 +199,8 @@ class UIATextInfo(textInfos.TextInfo):
if childObj==obj:
continue
childRange=self.obj.UIATextPattern.rangeFromChild(child)
+ if
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_End,rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)<=0
or
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,rangeObj,UIAHandler.TextPatternRangeEndpoint_End)>=0:
+ continue
if
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)<0:

childRange.moveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_Start,rangeObj,UIAHandler.TextPatternRangeEndpoint_Start)
if
childRange.CompareEndpoints(UIAHandler.TextPatternRangeEndpoint_End,rangeObj,UIAHandler.TextPatternRangeEndpoint_End)>0:


https://bitbucket.org/nvdaaddonteam/nvda/commits/ea0eabec3256/
Changeset: ea0eabec3256
Branch: None
User: mdcurran
Date: 2015-06-15 20:59:11+00:00
Summary: MSHTML: work properly with the newly updated UIATextInfo.

Affected #: 1 file

diff --git a/source/NVDAObjects/IAccessible/MSHTML.py
b/source/NVDAObjects/IAccessible/MSHTML.py
index a797442..124c0ed 100644
--- a/source/NVDAObjects/IAccessible/MSHTML.py
+++ b/source/NVDAObjects/IAccessible/MSHTML.py
@@ -37,8 +37,8 @@ class UIAMSHTMLTextInfo(UIATextInfo):

_atEndOfStory=False

- def __init__(self,obj,position):
- super(UIAMSHTMLTextInfo,self).__init__(obj,position)
+ def __init__(self,obj,position,_rangeObj=None):
+ super(UIAMSHTMLTextInfo,self).__init__(obj,position,_rangeObj)
if position==textInfos.POSITION_CARET:
tempRange=self._rangeObj.clone()

tempRange.ExpandToEnclosingUnit(UIAHandler.TextUnit_Character)


https://bitbucket.org/nvdaaddonteam/nvda/commits/861add2e18d5/
Changeset: 861add2e18d5
Branch: None
User: mdcurran
Date: 2015-06-15 21:38:59+00:00
Summary: TextInfo.isOverlapping: If the starts of both TextInfos are equal,
this should also be classed as being overlapped.

Affected #: 1 file

diff --git a/source/textInfos/__init__.py b/source/textInfos/__init__.py
index 32e1476..c5d219f 100755
--- a/source/textInfos/__init__.py
+++ b/source/textInfos/__init__.py
@@ -308,7 +308,7 @@ class TextInfo(baseObject.AutoPropertyObject):
@return: C{True} if the objects overlap, C{False} if not.
@rtype: bool
"""
- return self.compareEndPoints(other, "endToStart") > 0 and
other.compareEndPoints(self, "endToStart") > 0
+ return self.compareEndPoints(other,"startToStart") == 0 or
(self.compareEndPoints(other, "endToStart") > 0 and
other.compareEndPoints(self, "endToStart") > 0)

def setEndPoint(self,other,which):
"""Sets one end of this range to one end of another range.


https://bitbucket.org/nvdaaddonteam/nvda/commits/0fc497325821/
Changeset: 0fc497325821
Branch: None
User: mdcurran
Date: 2015-06-15 21:59:57+00:00
Summary: UIATextInfo: ensure not to grab formatting and text for degenerate
ranges.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 1548cda..e1e160e 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -150,6 +150,8 @@ class UIATextInfo(textInfos.TextInfo):
yield tempRange.clone()

def _getFormatFieldsAndText(self,tempRange,formatConfig):
+ if
tempRange.compareEndpoints(UIAHandler.TextPatternRangeEndpoint_Start,tempRange,UIAHandler.TextPatternRangeEndpoint_End)==0:
+ return
formatField=self._getFormatFieldAtRange(tempRange,formatConfig)
if formatConfig["reportSpellingErrors"]:
try:


https://bitbucket.org/nvdaaddonteam/nvda/commits/92610f48d639/
Changeset: 92610f48d639
Branch: None
User: mdcurran
Date: 2015-06-15 23:35:43+00:00
Summary: UIATextInfo.NVDAObjectAtStart: due to some buggy UIA
impelementations, use the first element from
IUIAutomationTextRange::getChildren if it exists, before using the enclosing
element. Picks up checkboxes and graphics etc in Edge.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index e1e160e..52941c2 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -93,7 +93,12 @@ class UIATextInfo(textInfos.TextInfo):
def _get_NVDAObjectAtStart(self):
tempRange=self._rangeObj.clone()

tempRange.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_End,tempRange,UIAHandler.TextPatternRangeEndpoint_Start)
- child=tempRange.getEnclosingElement()
+ tempRange.expandToEnclosingUnit(UIAHandler.TextUnit_Character)
+ children=tempRange.getChildren()
+ if children.length==1:
+ child=children.getElement(0)
+ else:
+ child=tempRange.getEnclosingElement()
return
UIA(UIAElement=child.buildUpdatedCache(UIAHandler.handler.baseCacheRequest)) or
self.obj

def _get_bookmark(self):


https://bitbucket.org/nvdaaddonteam/nvda/commits/232aa4ced06a/
Changeset: 232aa4ced06a
Branch: None
User: mdcurran
Date: 2015-06-15 23:45:34+00:00
Summary: globalCommands.script_toggleVirtualBufferPassThrough: forcably
enabling passThrough should now be supported on all
BrowseModeDocumentTreeInterceptors, not just VirtualBuffers.

Affected #: 1 file

diff --git a/source/globalCommands.py b/source/globalCommands.py
index 7764318..1b942f4 100755
--- a/source/globalCommands.py
+++ b/source/globalCommands.py
@@ -1148,7 +1148,7 @@ class GlobalCommands(ScriptableObject):
return
# Toggle browse mode pass-through.
vbuf.passThrough = not vbuf.passThrough
- if isinstance(vbuf,virtualBuffers.VirtualBuffer):
+ if
isinstance(vbuf,browseMode.BrowseModeDocumentTreeInterceptor):
# If we are enabling pass-through, the user has
explicitly chosen to do so, so disable auto-pass-through.
# If we're disabling pass-through, re-enable
auto-pass-through.
vbuf.disableAutoPassThrough = vbuf.passThrough


https://bitbucket.org/nvdaaddonteam/nvda/commits/9d09b57df3c5/
Changeset: 9d09b57df3c5
Branch: None
User: mdcurran
Date: 2015-06-16 00:12:51+00:00
Summary: UIA NVDAObject's doAction method: try invoke, then toggle, then
select. Allows for handling checkboxes and radio buttons etc.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 52941c2..665ff8f 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -418,6 +418,14 @@ class UIA(Window):

self.UIAInvokePattern=self._getUIAPattern(UIAHandler.UIA_InvokePatternId,UIAHandler.IUIAutomationInvokePattern)
return self.UIAInvokePattern

+ def _get_UIATogglePattern(self):
+
self.UIATogglePattern=self._getUIAPattern(UIAHandler.UIA_TogglePatternId,UIAHandler.IUIAutomationTogglePattern)
+ return self.UIATogglePattern
+
+ def _get_UIASelectionItemPattern(self):
+
self.UIASelectionItemPattern=self._getUIAPattern(UIAHandler.UIA_SelectionItemPatternId,UIAHandler.IUIAutomationSelectionItemPattern)
+ return self.UIASelectionItemPattern
+
def _get_UIATextPattern(self):

self.UIATextPattern=self._getUIAPattern(UIAHandler.UIA_TextPatternId,UIAHandler.IUIAutomationTextPattern)
return self.UIATextPattern
@@ -709,8 +717,13 @@ class UIA(Window):
def doAction(self,index=None):
if not index:
index=self.defaultActionIndex
- if index==0 and self.UIAInvokePattern:
- self.UIAInvokePattern.Invoke()
+ if index==0:
+ if self.UIAInvokePattern:
+ self.UIAInvokePattern.Invoke()
+ elif self.UIATogglePattern:
+ self.UIATogglePattern.toggle()
+ elif self.UIASelectionItemPattern:
+ self.UIASelectionItemPattern.select()
return
raise NotImplementedError



https://bitbucket.org/nvdaaddonteam/nvda/commits/78e13e33d0d4/
Changeset: 78e13e33d0d4
Branch: None
User: jteh
Date: 2015-06-16 07:16:03+00:00
Summary: When using Baum/HumanWare/APH braille displays with a braille
keyboard, braille input no longer stops functioning after pressing another type
of key on the display.

When all keys for a group were released, a 0 was still being set in the
keysDown dict for that group. However, when testing for braille input, we count
the number of groups in keysDown, assuming that groups with no keys down are
not present at all.
To fix this, remove a group altogether when all keys are released.
Re #3541.

Affected #: 1 file

diff --git a/source/brailleDisplayDrivers/baum.py
b/source/brailleDisplayDrivers/baum.py
index 71c15b9..b7028fc 100644
--- a/source/brailleDisplayDrivers/baum.py
+++ b/source/brailleDisplayDrivers/baum.py
@@ -3,7 +3,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) 2010-2013 NV Access Limited
+#Copyright (C) 2010-2015 NV Access Limited

import time
from collections import OrderedDict
@@ -246,7 +246,12 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver):
# Press.
# This begins a new key combination.
self._ignoreKeyReleases = False
- self._keysDown[command] = arg
+ if arg > 0:
+ self._keysDown[command] = arg
+ elif command in self._keysDown:
+ # All keys in this group have been released.
+ # #3541: Remove this group so it doesn't count
as a group with keys down.
+ del self._keysDown[command]

elif command == BAUM_POWERDOWN:
log.debug("Power down")


https://bitbucket.org/nvdaaddonteam/nvda/commits/9f917668f6fa/
Changeset: 9f917668f6fa
Branch: None
User: jteh
Date: 2015-06-17 04:18:38+00:00
Summary: Baum driver: Correctly handle device id for the Refreshabraille
and strip padding for other device ids.

Refreshabraille passes 18 bytes for device id, while other Baum devices only
pass 16. Therefore, special case Refreshabraille so we don't lose the last 2
bytes and don't log a debug warning about ignoring data before escape.
Also, shorter device ids are padded with either nulls or spaces, so strip these.
These are only cosmetic changes and won't affect the user, but it's nice to be
correct.

Affected #: 1 file

diff --git a/source/brailleDisplayDrivers/baum.py
b/source/brailleDisplayDrivers/baum.py
index b7028fc..348af91 100644
--- a/source/brailleDisplayDrivers/baum.py
+++ b/source/brailleDisplayDrivers/baum.py
@@ -227,8 +227,12 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver):
if command == BAUM_CELL_COUNT:
self.numCells = ord(arg)
elif command == BAUM_DEVICE_ID:
- self._deviceID = arg
-
+ if arg == "Refreshabraille ":
+ # For most Baum devices, the argument is 16
bytes,
+ # but it is 18 bytes for the Refreshabraille.
+ arg += self._ser.read(2)
+ # Short ids can be padded with either nulls or spaces.
+ self._deviceID = arg.rstrip("\0 ")
elif command in KEY_NAMES:
arg = sum(ord(byte) << offset * 8 for offset, byte in
enumerate(arg))
if arg < self._keysDown.get(command, 0):


https://bitbucket.org/nvdaaddonteam/nvda/commits/f2ad307fdc99/
Changeset: f2ad307fdc99
Branch: None
User: mdcurran
Date: 2015-06-18 00:01:58+00:00
Summary: UIA EdgeHTML treeInterceptor: when iterating nodes in the up
direction, start either at the textRange's first child if it has one, otherwise
its enclosing element. We must use firrst child if available due to an edge
bug where checkboxes, radio buttons etc do not have a range where the
enclosing element is the checkbox or radio button etc.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index 4efdc5c..50a6a60 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -140,7 +140,13 @@ def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction
return
if direction=="up":

walker=UIAHandler.handler.clientObject.createTreeWalker(UIACondition)
- element=position._rangeObj.getEnclosingElement()
+ tempRange=position._rangeObj.clone()
+ tempRange.expandToEnclosingUnit(UIAHandler.TextUnit_Character)
+ children=tempRange.getChildren()
+ if children.length==1:
+ element=children.getElement(0)
+ else:
+ element=position._rangeObj.getEnclosingElement()
element=walker.normalizeElement(element)
if element and not
UIAHandler.handler.clientObject.compareElements(element,document.rootNVDAObject.UIAElement)
and not
UIAHandler.handler.clientObject.compareElements(element,UIAHandler.handler.rootElement):
yield
UIATextRangeQuickNavItem(itemType,document,element)


https://bitbucket.org/nvdaaddonteam/nvda/commits/a0c10458b1fa/
Changeset: a0c10458b1fa
Branch: None
User: mdcurran
Date: 2015-06-18 03:18:17+00:00
Summary: Explorer: suppress announcement of focus ancestors for the
focuseed task list item when task switching in Windows 10 with alt+tab.

Affected #: 1 file

diff --git a/source/appModules/explorer.py b/source/appModules/explorer.py
index a606376..a3defd9 100644
--- a/source/appModules/explorer.py
+++ b/source/appModules/explorer.py
@@ -21,6 +21,15 @@ from NVDAObjects.UIA import UIA
class MultitaskingViewFrameWindow(UIA):
shouldAllowUIAFocusEvent=False

+# suppress focus ancestry for task switching list items if alt is held down
(alt+tab)
+class MultitaskingViewFrameListItem(UIA):
+
+ def _get_container(self):
+ if winUser.getAsyncKeyState(winUser.VK_MENU)&32768:
+ return api.getDesktopObject()
+ else:
+ return
super(MultitaskingViewFrameListItem,self).container
+
# support for Win8 start screen search suggestions.
class SuggestionListItem(UIA):

@@ -181,6 +190,8 @@ class AppModule(appModuleHandler.AppModule):
clsList.insert(0,SuggestionListItem)
elif uiaClassName=="MultitaskingViewFrame" and
role==controlTypes.ROLE_WINDOW:
clsList.insert(0,MultitaskingViewFrameWindow)
+ elif obj.windowClassName=="MultitaskingViewFrame" and
role==controlTypes.ROLE_LISTITEM:
+ clsList.insert(0,MultitaskingViewFrameListItem)

def event_NVDAObject_init(self, obj):
windowClass = obj.windowClassName


https://bitbucket.org/nvdaaddonteam/nvda/commits/f7026751770f/
Changeset: f7026751770f
Branch: None
User: mdcurran
Date: 2015-06-18 03:25:32+00:00
Summary: UIA: add some comments for work-arounds.

Affected #: 2 files

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 665ff8f..06a53ef 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -93,6 +93,8 @@ class UIATextInfo(textInfos.TextInfo):
def _get_NVDAObjectAtStart(self):
tempRange=self._rangeObj.clone()

tempRange.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_End,tempRange,UIAHandler.TextPatternRangeEndpoint_Start)
+ # some implementations (Edge, Word) do not correctly class
embedded objects (graphics, checkboxes) as being the enclosing element, even
when the range is completely within them. Rather, they still list the object in
getChildren.
+ # Thus we must check getChildren before getEnclosingElement.
tempRange.expandToEnclosingUnit(UIAHandler.TextUnit_Character)
children=tempRange.getChildren()
if children.length==1:
@@ -203,6 +205,7 @@ class UIATextInfo(textInfos.TextInfo):
child=children.getElement(index)

childObj=UIA(UIAElement=child.buildUpdatedCache(UIAHandler.handler.baseCacheRequest))
#Sometimes a child range can contain the same children
as its parent (causing an infinite loop)
+ # Example: checkboxes, graphics, in Edge.
if childObj==obj:
continue
childRange=self.obj.UIATextPattern.rangeFromChild(child)

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index 50a6a60..5c72495 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -140,6 +140,8 @@ def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction
return
if direction=="up":

walker=UIAHandler.handler.clientObject.createTreeWalker(UIACondition)
+ # some implementations (Edge, Word) do not correctly class
embedded objects (graphics, checkboxes) as being the enclosing element, even
when the range is completely within them. Rather, they still list the object in
getChildren.
+ # Thus we must check getChildren before getEnclosingElement.
tempRange=position._rangeObj.clone()
tempRange.expandToEnclosingUnit(UIAHandler.TextUnit_Character)
children=tempRange.getChildren()


https://bitbucket.org/nvdaaddonteam/nvda/commits/b277fd700961/
Changeset: b277fd700961
Branch: None
User: mdcurran
Date: 2015-06-18 04:09:37+00:00
Summary: UIATextInfo-s _getControlFieldForObject: only include name if the
object's text is empty. Currently a little unperformant... we'll have to think
about this one.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 06a53ef..18bdbcb 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -116,7 +116,11 @@ class UIATextInfo(textInfos.TextInfo):
states.discard(controlTypes.STATE_MULTILINE)
states.discard(controlTypes.STATE_FOCUSED)
field["states"] = states
- #field["name"] = obj.name
+ # Only include name if the object's inner text is empty.
+ # could be unperformant.
+ text=self.obj.makeTextInfo(obj).text
+ if not text or text.isspace():
+ field["name"] = obj.name
#field["_childcount"] = obj.childCount
field["level"] = obj.positionInfo.get("level")
if role == controlTypes.ROLE_TABLE:


https://bitbucket.org/nvdaaddonteam/nvda/commits/e77ba3b7b506/
Changeset: e77ba3b7b506
Branch: None
User: mdcurran
Date: 2015-06-19 06:14:33+00:00
Summary: browseMode: move implementations of activate and moveTo from
VirtualBufferQuickNavItem to browseMode.TextInfoQuickNavItem as they are
abstract enough and are needed to update focus on quicknav for Edge etc.

Affected #: 2 files

diff --git a/source/browseMode.py b/source/browseMode.py
index 97630c9..026a5b1 100644
--- a/source/browseMode.py
+++ b/source/browseMode.py
@@ -154,9 +154,6 @@ class TextInfoQuickNavItem(QuickNavItem):
def label(self):
return self.textInfo.text.strip()

- def activate(self):
- self.textInfo.activate()
-
def isChild(self,parent):
if parent.textInfo.isOverlapping(self.textInfo):
return True
@@ -173,8 +170,13 @@ class TextInfoQuickNavItem(QuickNavItem):
info.setEndPoint(fieldInfo, "endToEnd")
speech.speakTextInfo(info, reason=controlTypes.REASON_FOCUS)

+ def activate(self):
+ self.textInfo.obj._activatePosition(self.textInfo)
+
def moveTo(self):
- self.textInfo.updateCaret()
+ info=self.textInfo.copy()
+ info.collapse()
+ self.document._set_selection(info,reason=REASON_QUICKNAV)

@property
def isAfterSelection(self):

diff --git a/source/virtualBuffers/__init__.py
b/source/virtualBuffers/__init__.py
index db15de7..88faa0a 100644
--- a/source/virtualBuffers/__init__.py
+++ b/source/virtualBuffers/__init__.py
@@ -131,15 +131,6 @@ class
VirtualBufferQuickNavItem(browseMode.TextInfoQuickNavItem):
return False
return super(VirtualBufferQuickNavItem,self).isChild(parent)

- canActivate=True
- def activate(self):
- self.textInfo.obj._activatePosition(self.textInfo)
-
- def moveTo(self):
- info=self.textInfo.copy()
- info.collapse()
-
self.document._set_selection(info,reason=browseMode.REASON_QUICKNAV)
-
class
VirtualBufferTextInfo(browseMode.BrowseModeDocumentTextInfo,textInfos.offsets.OffsetsTextInfo):

allowMoveToOffsetPastEnd=False #: no need for end insertion point as
vbuf is not editable.


https://bitbucket.org/nvdaaddonteam/nvda/commits/0d77be97b9bb/
Changeset: 0d77be97b9bb
Branch: None
User: mdcurran
Date: 2015-06-19 08:40:07+00:00
Summary: UIA Edge treeInterceptor: add quickNav for table, separator,
checkBox, radioButton, edit, list and form field. ListItem and button not added
yet due to issues in Edge.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index 5c72495..fa814e6 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -68,6 +68,39 @@ class
HeadingUIATextRangeQuickNavItem(UIATextRangeQuickNavItem):
return False
return self.level>parent.level

+def createUIAMultiPropertyCondition(*dicts):
+ outerOrList=[]
+ for dict in dicts:
+ andList=[]
+ for key,values in dict.iteritems():
+ innerOrList=[]
+ if not isinstance(values,list):
+ values=[values]
+ for value in values:
+
condition=UIAHandler.handler.clientObject.createPropertyCondition(key,value)
+ innerOrList.append(condition)
+ if len(innerOrList)==0:
+ continue
+ elif len(innerOrList)==1:
+ condition=innerOrList[0]
+ else:
+
condition=UIAHandler.handler.clientObject.createOrConditionFromArray(innerOrList)
+ andList.append(condition)
+ if len(andList)==0:
+ continue
+ elif len(andList)==1:
+ condition=andList[0]
+ else:
+
condition=UIAHandler.handler.clientObject.createAndConditionFromArray(andList)
+ outerOrList.append(condition)
+ if len(outerOrList)==0:
+ raise ValueError("no properties")
+ elif len(outerOrList)==1:
+ condition=outerOrList[0]
+ else:
+
condition=UIAHandler.handler.clientObject.createOrConditionFromArray(outerOrList)
+ return condition
+
def
UIATextAttributeQuickNavIterator(itemType,document,position,attributeID,attributeValue,direction="next",ItemClass=UIATextRangeQuickNavItem):
includeCurrent=False
if not position:
@@ -310,9 +343,36 @@ class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.Brows
elif nodeType=="link":

condition=UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_ControlTypePropertyId,UIAHandler.UIA_HyperlinkControlTypeId)
return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ elif nodeType=="checkBox":
+
condition=UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_ControlTypePropertyId,UIAHandler.UIA_CheckBoxControlTypeId)
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ elif nodeType=="radioButton":
+
condition=UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_ControlTypePropertyId,UIAHandler.UIA_RadioButtonControlTypeId)
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ elif nodeType=="comboBox":
+
condition=UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_ControlTypePropertyId,UIAHandler.UIA_ComboBoxControlTypeId)
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ elif nodeType=="graphic":
+
condition=UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_ControlTypePropertyId,UIAHandler.UIA_ImageControlTypeId)
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ elif nodeType=="table":
+
condition=UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_ControlTypePropertyId,UIAHandler.UIA_TableControlTypeId)
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ elif nodeType=="separator":
+
condition=UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_ControlTypePropertyId,UIAHandler.UIA_SeparatorControlTypeId)
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
elif nodeType=="focusable":

condition=UIAHandler.handler.clientObject.createPropertyCondition(UIAHandler.UIA_IsKeyboardFocusablePropertyId,True)
return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ elif nodeType=="list":
+
condition=createUIAMultiPropertyCondition({UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_ListControlTypeId,UIAHandler.UIA_IsKeyboardFocusablePropertyId:False})
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ elif nodeType=="edit":
+
condition=createUIAMultiPropertyCondition({UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_EditControlTypeId,UIAHandler.UIA_ValueIsReadOnlyPropertyId:False})
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ elif nodeType=="formField":
+
condition=createUIAMultiPropertyCondition({UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_EditControlTypeId,UIAHandler.UIA_ValueIsReadOnlyPropertyId:False},{UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_ListControlTypeId,UIAHandler.UIA_IsKeyboardFocusablePropertyId:True},{UIAHandler.UIA_ControlTypePropertyId:[UIAHandler.UIA_CheckBoxControlTypeId,UIAHandler.UIA_RadioButtonControlTypeId,UIAHandler.UIA_ComboBoxControlTypeId,UIAHandler.UIA_ButtonControlTypeId]})
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
raise NotImplementedError

def _activateNVDAObject(self,obj):


https://bitbucket.org/nvdaaddonteam/nvda/commits/e1298a267f02/
Changeset: e1298a267f02
Branch: None
User: mdcurran
Date: 2015-06-19 09:28:58+00:00
Summary: browseMode: move the beginning and end of container quickNav
functionality into browseMode. The base browseMode implementation now uses
_iterNodesbyType with a node type of container. However, virtualBuffers still
override enclosingContainerRange to use their own original code making use of
controlFields and IDs as it is probably faster.

Affected #: 2 files

diff --git a/source/browseMode.py b/source/browseMode.py
index 026a5b1..8e70f5e 100644
--- a/source/browseMode.py
+++ b/source/browseMode.py
@@ -1321,6 +1321,56 @@ class
BrowseModeDocumentTreeInterceptor(cursorManager.CursorManager,BrowseModeTr
pass
return None

+ def getEnclosingContainerRange(self,range):
+ range=range.copy()
+ range.collapse()
+ try:
+ item = next(self._iterNodesByType("container", "up",
range))
+ except (NotImplementedError,StopIteration):
+ return
+ return item.textInfo
+
+ def script_moveToStartOfContainer(self,gesture):
+ info=self.makeTextInfo(textInfos.POSITION_CARET)
+ info.expand(textInfos.UNIT_CHARACTER)
+ container=self.getEnclosingContainerRange(info)
+ if not container:
+ # Translators: Reported when the user attempts to move
to the start or end of a container (list, table, etc.)
+ # But there is no container.
+ ui.message(_("Not in a container"))
+ return
+ container.collapse()
+ self._set_selection(container, reason=REASON_QUICKNAV)
+ if not willSayAllResume(gesture):
+ container.expand(textInfos.UNIT_LINE)
+ speech.speakTextInfo(container,
reason=controlTypes.REASON_FOCUS)
+
script_moveToStartOfContainer.resumeSayAllMode=sayAllHandler.CURSOR_CARET
+ # Translators: Description for the Move to start of container command
in browse mode.
+ script_moveToStartOfContainer.__doc__=_("Moves to the start of the
container element, such as a list or table")
+
+ def script_movePastEndOfContainer(self,gesture):
+ info=self.makeTextInfo(textInfos.POSITION_CARET)
+ info.expand(textInfos.UNIT_CHARACTER)
+ container=self.getEnclosingContainerRange(info)
+ if not container:
+ ui.message(_("Not in a container"))
+ return
+ container.collapse(end=True)
+ docEnd=container.obj.makeTextInfo(textInfos.POSITION_LAST)
+ if container.compareEndPoints(docEnd,"endToEnd")>=0:
+ container=docEnd
+ # Translators: a message reported when:
+ # Review cursor is at the bottom line of the current
navigator object.
+ # Landing at the end of a browse mode document when
trying to jump to the end of the current container.
+ ui.message(_("bottom"))
+ self._set_selection(container, reason=REASON_QUICKNAV)
+ if not willSayAllResume(gesture):
+ container.expand(textInfos.UNIT_LINE)
+ speech.speakTextInfo(container,
reason=controlTypes.REASON_FOCUS)
+
script_movePastEndOfContainer.resumeSayAllMode=sayAllHandler.CURSOR_CARET
+ # Translators: Description for the Move past end of container command
in browse mode.
+ script_movePastEndOfContainer.__doc__=_("Moves past the end of the
container element, such as a list or table")
+
__gestures={
"kb:NVDA+d": "activateLongDesc",
"kb:escape": "disablePassThrough",
@@ -1328,4 +1378,6 @@ class
BrowseModeDocumentTreeInterceptor(cursorManager.CursorManager,BrowseModeTr
"kb:alt+downArrow": "collapseOrExpandControl",
"kb:tab": "tab",
"kb:shift+tab": "shiftTab",
+ "kb:shift+,": "moveToStartOfContainer",
+ "kb:,": "movePastEndOfContainer",
}

diff --git a/source/virtualBuffers/__init__.py
b/source/virtualBuffers/__init__.py
index 88faa0a..9245c72 100644
--- a/source/virtualBuffers/__init__.py
+++ b/source/virtualBuffers/__init__.py
@@ -678,46 +678,6 @@ class
VirtualBuffer(browseMode.BrowseModeDocumentTreeInterceptor):
offsets=range._getOffsetsFromFieldIdentifier(docHandle,ID)
return self.makeTextInfo(textInfos.offsets.Offsets(*offsets))

- def script_moveToStartOfContainer(self,gesture):
- info=self.makeTextInfo(textInfos.POSITION_CARET)
- info.expand(textInfos.UNIT_CHARACTER)
- container=self.getEnclosingContainerRange(info)
- if not container:
- # Translators: Reported when the user attempts to move
to the start or end of a container (list, table, etc.)
- # But there is no container.
- ui.message(_("Not in a container"))
- return
- container.collapse()
- self._set_selection(container,
reason=browseMode.REASON_QUICKNAV)
- if not willSayAllResume(gesture):
- container.expand(textInfos.UNIT_LINE)
- speech.speakTextInfo(container,
reason=controlTypes.REASON_FOCUS)
-
script_moveToStartOfContainer.resumeSayAllMode=sayAllHandler.CURSOR_CARET
- # Translators: Description for the Move to start of container command
in browse mode.
- script_moveToStartOfContainer.__doc__=_("Moves to the start of the
container element, such as a list or table")
-
- def script_movePastEndOfContainer(self,gesture):
- info=self.makeTextInfo(textInfos.POSITION_CARET)
- info.expand(textInfos.UNIT_CHARACTER)
- container=self.getEnclosingContainerRange(info)
- if not container:
- ui.message(_("Not in a container"))
- return
- container.collapse(end=True)
- if container._startOffset>=container._getStoryLength():
- container.move(textInfos.UNIT_CHARACTER,-1)
- # Translators: a message reported when:
- # Review cursor is at the bottom line of the current
navigator object.
- # Landing at the end of a browse mode document when
trying to jump to the end of the current container.
- ui.message(_("bottom"))
- self._set_selection(container,
reason=browseMode.REASON_QUICKNAV)
- if not willSayAllResume(gesture):
- container.expand(textInfos.UNIT_LINE)
- speech.speakTextInfo(container,
reason=controlTypes.REASON_FOCUS)
-
script_movePastEndOfContainer.resumeSayAllMode=sayAllHandler.CURSOR_CARET
- # Translators: Description for the Move past end of container command
in browse mode.
- script_movePastEndOfContainer.__doc__=_("Moves past the end of the
container element, such as a list or table")
-
@classmethod
def changeNotify(cls, rootDocHandle, rootID):
try:
@@ -751,6 +711,4 @@ class
VirtualBuffer(browseMode.BrowseModeDocumentTreeInterceptor):
"kb:control+alt+upArrow": "previousRow",
"kb:control+alt+rightArrow": "nextColumn",
"kb:control+alt+leftArrow": "previousColumn",
- "kb:shift+,": "moveToStartOfContainer",
- "kb:,": "movePastEndOfContainer",
}


https://bitbucket.org/nvdaaddonteam/nvda/commits/e8f8ef0b7bf3/
Changeset: e8f8ef0b7bf3
Branch: None
User: mdcurran
Date: 2015-06-19 09:29:27+00:00
Summary: UIA Edge treeInterceptor's _iterNodesByType: support a node type
of container so as to support container quick nav.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index fa814e6..7413948 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -367,6 +367,9 @@ class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.Brows
elif nodeType=="list":

condition=createUIAMultiPropertyCondition({UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_ListControlTypeId,UIAHandler.UIA_IsKeyboardFocusablePropertyId:False})
return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ elif nodeType=="container":
+
condition=createUIAMultiPropertyCondition({UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_ListControlTypeId,UIAHandler.UIA_IsKeyboardFocusablePropertyId:False},{UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_TableControlTypeId})
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
elif nodeType=="edit":

condition=createUIAMultiPropertyCondition({UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_EditControlTypeId,UIAHandler.UIA_ValueIsReadOnlyPropertyId:False})
return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)


https://bitbucket.org/nvdaaddonteam/nvda/commits/a80fa0e841c8/
Changeset: a80fa0e841c8
Branch: None
User: mdcurran
Date: 2015-06-19 10:12:38+00:00
Summary: browseMode: add base support for quickNav to non-link text.

* quickNavScript calls _iterNotLinkBlock directly now in the case of
"notLinkBlock" so that all implementations don't need to specifically have a
rule in their _iterNodesByType.
* _iterNotLinkBlock now uses TextInfos to create the middle range between two
links, and checks if this is suitable non-linked text by asking a new
_isSuitableNotLinkBlock method on the BrowseMode document. The base
implementation for _isSuitableNotLinkBlock checks the length of the TextInfo's
text to see if it is equal or longer than the min notLinkBlock length.
VirtualBuffers however implement the check just using offsets.

Affected #: 2 files

diff --git a/source/browseMode.py b/source/browseMode.py
index 8e70f5e..caf7433 100644
--- a/source/browseMode.py
+++ b/source/browseMode.py
@@ -208,9 +208,13 @@ class
BrowseModeTreeInterceptor(treeInterceptorHandler.TreeInterceptor):
return iter(())

def _quickNavScript(self,gesture, itemType, direction, errorMessage,
readUnit):
+ if itemType=="notLinkBlock":
+ iterFactory=self._iterNotLinkBlock
+ else:
+ iterFactory=lambda direction,info:
self._iterNodesByType(itemType,direction,info)
info=self.selection
try:
- item = next(self._iterNodesByType(itemType, direction,
info))
+ item = next(iterFactory(direction, info))
except NotImplementedError:
# Translators: a message when a particular quick nav
command is not supported in the current document.
ui.message(_("Not supported in this document"))
@@ -1371,6 +1375,29 @@ class
BrowseModeDocumentTreeInterceptor(cursorManager.CursorManager,BrowseModeTr
# Translators: Description for the Move past end of container command
in browse mode.
script_movePastEndOfContainer.__doc__=_("Moves past the end of the
container element, such as a list or table")

+ NOT_LINK_BLOCK_MIN_LEN = 30
+ def _isSuitableNotLinkBlock(self,range):
+ return len(range.text)>=self.NOT_LINK_BLOCK_MIN_LEN
+
+ def _iterNotLinkBlock(self, direction="next", pos=None):
+ links = self._iterNodesByType("link", direction=direction,
pos=pos)
+ # We want to compare each link against the next link.
+ item1 = next(links)
+ while True:
+ item2 = next(links)
+ # If the distance between the links is small, this is
probably just a piece of non-link text within a block of links; e.g. an
inactive link of a nav bar.
+ if direction=="previous":
+ range=item1.textInfo.copy()
+ range.collapse()
+ range.setEndPoint(item2.textInfo,"startToEnd")
+ else:
+ range=item2.textInfo.copy()
+ range.collapse()
+ range.setEndPoint(item1.textInfo,"startToEnd")
+ if self._isSuitableNotLinkBlock(range):
+ yield
TextInfoQuickNavItem("notLinkBlock",self,range)
+ item1=item2
+
__gestures={
"kb:NVDA+d": "activateLongDesc",
"kb:escape": "disablePassThrough",

diff --git a/source/virtualBuffers/__init__.py
b/source/virtualBuffers/__init__.py
index 9245c72..b2931e9 100644
--- a/source/virtualBuffers/__init__.py
+++ b/source/virtualBuffers/__init__.py
@@ -475,8 +475,6 @@ class
VirtualBuffer(browseMode.BrowseModeDocumentTreeInterceptor):
pass

def _iterNodesByType(self,nodeType,direction="next",pos=None):
- if nodeType == "notLinkBlock":
- return self._iterNotLinkBlock(direction=direction,
pos=pos)
attribs=self._searchableAttribsForNodeType(nodeType)
if not attribs:
return iter(())
@@ -643,20 +641,8 @@ class
VirtualBuffer(browseMode.BrowseModeDocumentTreeInterceptor):
# Translators: the description for the previous table column script on
virtualBuffers.
script_previousColumn.__doc__ = _("moves to the previous table column")

- NOT_LINK_BLOCK_MIN_LEN = 30
- def _iterNotLinkBlock(self, direction="next", pos=None):
- links = self._iterNodesByType("link", direction=direction,
pos=pos)
- # We want to compare each link against the next link.
- item1 = next(links)
- while True:
- item2 = next(links)
- # If the distance between the links is small, this is
probably just a piece of non-link text within a block of links; e.g. an
inactive link of a nav bar.
- if direction == "next" and item2.textInfo._startOffset
- item1.textInfo._endOffset > self.NOT_LINK_BLOCK_MIN_LEN:
- yield
VirtualBufferQuickNavItem("notLinkBlock",self,0,item1.textInfo._endOffset,
item2.textInfo._startOffset)
- # If we're moving backwards, the order of the links in
the document will be reversed.
- elif direction == "previous" and
item1.textInfo._startOffset - item2.textInfo._endOffset >
self.NOT_LINK_BLOCK_MIN_LEN:
- yield
VirtualBufferQuickNavItem("notLinkBlock",self,0,item2.textInfo._endOffset,
item1.textInfo._startOffset)
- item1=item2
+ def _isSuitableNotLinkBlock(self,range):
+ return
(range._endOffset-range._startOffset)>=self.NOT_LINK_BLOCK_MIN_LEN

def getEnclosingContainerRange(self,range):
formatConfig=config.conf['documentFormatting'].copy()


https://bitbucket.org/nvdaaddonteam/nvda/commits/9fe1b672eb69/
Changeset: 9fe1b672eb69
Branch: None
User: mdcurran
Date: 2015-06-19 20:16:38+00:00
Summary: winword browseMode: make use of
browseMode.BrowseModeDocumentTreeInterceptor like Edge and virtualBuffers.

Affected #: 1 file

diff --git a/source/NVDAObjects/window/winword.py
b/source/NVDAObjects/window/winword.py
index e1dc598..90caff6 100755
--- a/source/NVDAObjects/window/winword.py
+++ b/source/NVDAObjects/window/winword.py
@@ -796,7 +796,7 @@ class
WordDocumentTextInfoForTreeInterceptor(WordDocumentTextInfo):
def _get_shouldIncludeLayoutTables(self):
return config.conf['documentFormatting']['includeLayoutTables']

-class BrowseModeWordDocumentTextInfo(treeInterceptorHandler.RootProxyTextInfo):
+class
BrowseModeWordDocumentTextInfo(browseMode.BrowseModeDocumentTextInfo,treeInterceptorHandler.RootProxyTextInfo):

def __init__(self,obj,position,_rangeObj=None):
if isinstance(position,WordDocument):
@@ -805,7 +805,10 @@ class
BrowseModeWordDocumentTextInfo(treeInterceptorHandler.RootProxyTextInfo):

InnerTextInfoClass=WordDocumentTextInfoForTreeInterceptor

-class
WordDocumentTreeInterceptor(CursorManager,browseMode.BrowseModeTreeInterceptor,treeInterceptorHandler.DocumentTreeInterceptor):
+ def _get_focusableNVDAObjectAtStart(self):
+ return self.obj.rootNVDAObject
+
+class
WordDocumentTreeInterceptor(browseMode.BrowseModeDocumentTreeInterceptor):

TextInfo=BrowseModeWordDocumentTextInfo



https://bitbucket.org/nvdaaddonteam/nvda/commits/c24f8adb1a01/
Changeset: c24f8adb1a01
Branch: None
User: mdcurran
Date: 2015-06-22 23:59:28+00:00
Summary: UIA Edge treeInterceptor: get around bugs in edge so moving
forward by line reaches controls such as checkboxes and raido buttons etc.

Affected #: 2 files

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index 7413948..666d4ae 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -325,12 +325,48 @@ def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction
yield
UIATextRangeQuickNavItem(itemType,document,curElement)

class
EdgeHTMLTreeInterceptorTextInfo(browseMode.BrowseModeDocumentTextInfo,treeInterceptorHandler.RootProxyTextInfo):
- pass
+
+ # override move to get around bugs in Edge where moving by line jumps
over checkboxes, radio buttons etc.
+ # Only fixes it for forward atht e moment.
+ def move(self,unit,direction,endPoint=None):
+ origInfo=None
+ if (direction==1 or direction==-1) and not endPoint and
unit==textInfos.UNIT_LINE:
+ origInfo=self.copy()
+ origInfo.expand(unit)
+
res=super(EdgeHTMLTreeInterceptorTextInfo,self).move(unit,direction,endPoint)
+ if res and origInfo:
+ if direction==1 and
self.compareEndPoints(origInfo,"startToEnd")>0:
+ newInfo=origInfo.copy()
+ newInfo.collapse(end=True)
+ newInfo.move(textInfos.UNIT_CHARACTER,-1)
+ newInfo.move(textInfos.UNIT_CHARACTER,1)
+ newInfo.expand(unit)
+ if
newInfo.compareEndPoints(origInfo,"startToEnd")>=0 and
self.compareEndPoints(newInfo,"startToStart")>0:
+ newInfo.collapse()
+ self._rangeObj=newInfo._rangeObj.clone()
+ return res
+
+ # Override expand to get around bugs in Edge where expanding to line on
a checkbox, radio button etc expands the previous line (not containing the
control in question).
+ def expand(self,unit):
+ origInfo=None
+ if unit in (textInfos.UNIT_WORD,textInfos.UNIT_LINE):
+ origInfo=self.copy()
+ super(EdgeHTMLTreeInterceptorTextInfo,self).expand(unit)
+ if origInfo:
+ if self.compareEndPoints(origInfo,"endToEnd")<=0:
+ self._rangeObj=origInfo._rangeObj.clone()
+
super(EdgeHTMLTreeInterceptorTextInfo,self).expand(textInfos.UNIT_CHARACTER)

class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.BrowseModeDocumentTreeInterceptor):

TextInfo=EdgeHTMLTreeInterceptorTextInfo

+ # Ovveride setting selection to get around bugs in Edge where
programmatically setting focus corrupts existing IUIAutomationTextRanges
+ # cloning them seems to fix them
+ def _set_selection(self,info,reason=controlTypes.REASON_CARET):
+
super(EdgeHTMLTreeInterceptor,self)._set_selection(info,reason=reason)
+ info._rangeObj=info._rangeObj.clone()
+
def _get_documentConstantIdentifier(self):
return self.rootNVDAObject.parent.name

@@ -415,4 +451,3 @@ class EdgeHTMLRoot(UIA):
if role==controlTypes.ROLE_PANE:
role=controlTypes.ROLE_DOCUMENT
return role
-

diff --git a/source/treeInterceptorHandler.py b/source/treeInterceptorHandler.py
index 5b26e0e..f60007a 100644
--- a/source/treeInterceptorHandler.py
+++ b/source/treeInterceptorHandler.py
@@ -161,6 +161,9 @@ class RootProxyTextInfo(textInfos.TextInfo):
def _get__rangeObj(self):
return self.innerTextInfo._rangeObj

+ def _set__rangeObj(self,r):
+ self.innerTextInfo._rangeObj=r
+
def find(self,text,caseSensitive=False,reverse=False):
return self.innerTextInfo.find(text,caseSensitive,reverse)



https://bitbucket.org/nvdaaddonteam/nvda/commits/dd72e3934d44/
Changeset: dd72e3934d44
Branch: None
User: mdcurran
Date: 2015-06-23 02:36:01+00:00
Summary: UIA Edge treeInterceptor: improve implementation of move to fix
bugs in Edge when going back by line or word as well.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index 666d4ae..8df9531 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -327,10 +327,9 @@ def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction
class
EdgeHTMLTreeInterceptorTextInfo(browseMode.BrowseModeDocumentTextInfo,treeInterceptorHandler.RootProxyTextInfo):

# override move to get around bugs in Edge where moving by line jumps
over checkboxes, radio buttons etc.
- # Only fixes it for forward atht e moment.
def move(self,unit,direction,endPoint=None):
origInfo=None
- if (direction==1 or direction==-1) and not endPoint and
unit==textInfos.UNIT_LINE:
+ if (direction==1 or direction==-1) and not endPoint and unit in
(textInfos.UNIT_WORD,textInfos.UNIT_LINE):
origInfo=self.copy()
origInfo.expand(unit)

res=super(EdgeHTMLTreeInterceptorTextInfo,self).move(unit,direction,endPoint)
@@ -343,7 +342,23 @@ class
EdgeHTMLTreeInterceptorTextInfo(browseMode.BrowseModeDocumentTextInfo,tree
newInfo.expand(unit)
if
newInfo.compareEndPoints(origInfo,"startToEnd")>=0 and
self.compareEndPoints(newInfo,"startToStart")>0:
newInfo.collapse()
- self._rangeObj=newInfo._rangeObj.clone()
+ charInfo=newInfo.copy()
+
charInfo.expand(textInfos.UNIT_CHARACTER)
+
children=charInfo._rangeObj.getChildren()
+ if children.length==1:
+
childInfo=self.obj.TextInfo(self.obj,None,_rangeObj=self.obj.rootNVDAObject.UIATextPattern.rangeFromChild(children.getElement(0)))
+ if
childInfo.compareEndPoints(charInfo,"startToStart")==0 and
childInfo.compareEndPoints(charInfo,"endToEnd")==0:
+
self._rangeObj=newInfo._rangeObj.clone()
+ elif direction==-1:
+ newInfo=self.copy()
+ count=4
+ while count>0:
+ newInfo.move(unit,1)
+ if
newInfo.compareEndPoints(origInfo,"startToStart")<0:
+
self._rangeObj=newInfo._rangeObj.clone()
+ else:
+ break
+ count-=1
return res

# Override expand to get around bugs in Edge where expanding to line on
a checkbox, radio button etc expands the previous line (not containing the
control in question).


https://bitbucket.org/nvdaaddonteam/nvda/commits/9a157aa00fda/
Changeset: 9a157aa00fda
Branch: None
User: mdcurran
Date: 2015-06-25 09:04:43+00:00
Summary: Merge branch 'master' into win10edge

Affected #: 30 files

diff --git a/source/NVDAObjects/IAccessible/MSHTML.py
b/source/NVDAObjects/IAccessible/MSHTML.py
index 124c0ed..eb46a35 100644
--- a/source/NVDAObjects/IAccessible/MSHTML.py
+++ b/source/NVDAObjects/IAccessible/MSHTML.py
@@ -94,6 +94,7 @@ nodeNamesToNVDARoles={
"A":controlTypes.ROLE_LINK,
"LABEL":controlTypes.ROLE_LABEL,
"#text":controlTypes.ROLE_STATICTEXT,
+ "#TEXT":controlTypes.ROLE_STATICTEXT,
"H1":controlTypes.ROLE_HEADING,
"H2":controlTypes.ROLE_HEADING,
"H3":controlTypes.ROLE_HEADING,
@@ -120,6 +121,9 @@ nodeNamesToNVDARoles={
"OPTION":controlTypes.ROLE_LISTITEM,
"BLOCKQUOTE":controlTypes.ROLE_BLOCKQUOTE,
"MATH":controlTypes.ROLE_MATH,
+ "NAV":controlTypes.ROLE_SECTION,
+ "SECTION":controlTypes.ROLE_SECTION,
+ "ARTICLE":controlTypes.ROLE_DOCUMENT,
}

def getZoomFactorsFromHTMLDocument(HTMLDocument):
@@ -636,7 +640,7 @@ class MSHTML(IAccessible):
if (
self.HTMLNodeHasAncestorIAccessible or
#IE inappropriately generates the name from descendants
on some controls
- self.IAccessibleRole in
(oleacc.ROLE_SYSTEM_MENUBAR,oleacc.ROLE_SYSTEM_TOOLBAR,oleacc.ROLE_SYSTEM_LIST,oleacc.ROLE_SYSTEM_TABLE,oleacc.ROLE_SYSTEM_DOCUMENT)
or
+ self.IAccessibleRole in
(oleacc.ROLE_SYSTEM_MENUBAR,oleacc.ROLE_SYSTEM_TOOLBAR,oleacc.ROLE_SYSTEM_LIST,oleacc.ROLE_SYSTEM_TABLE,oleacc.ROLE_SYSTEM_DOCUMENT,oleacc.ROLE_SYSTEM_DIALOG)
or
#Adding an ARIA landmark or unknown role to a DIV or
NAV node makes an IAccessible with role_system_grouping and a name calculated
from descendants.
# This name should also be ignored, but check NVDA's
role, not accRole as its possible that NVDA chose a better role
# E.g. row (#2780)
@@ -703,8 +707,8 @@ class MSHTML(IAccessible):
if nodeName:
if nodeName in ("OBJECT","EMBED","APPLET"):
return controlTypes.ROLE_EMBEDDEDOBJECT
- if self.HTMLNodeHasAncestorIAccessible or
nodeName in ("BODY","FRAMESET","FRAME","IFRAME","LABEL"):
- return
nodeNamesToNVDARoles.get(nodeName,controlTypes.ROLE_TEXTFRAME)
+ if self.HTMLNodeHasAncestorIAccessible or
nodeName in
("BODY","FRAMESET","FRAME","IFRAME","LABEL","NAV","SECTION","ARTICLE"):
+ return
nodeNamesToNVDARoles.get(nodeName,controlTypes.ROLE_SECTION)
if self.IAccessibleChildID>0:
states=super(MSHTML,self).states
if controlTypes.STATE_LINKED in states:
@@ -929,7 +933,10 @@ class MSHTML(IAccessible):

def _get_HTMLNodeUniqueNumber(self):
if not hasattr(self,'_HTMLNodeUniqueNumber'):
- self._HTMLNodeUniqueNumber=self.HTMLNode.uniqueNumber
+ try:
+
self._HTMLNodeUniqueNumber=self.HTMLNode.uniqueNumber
+ except COMError:
+ return None
return self._HTMLNodeUniqueNumber

def _get_HTMLNodeName(self):

diff --git a/source/NVDAObjects/IAccessible/mozilla.py
b/source/NVDAObjects/IAccessible/mozilla.py
index 8676ab5..21fdd36 100755
--- a/source/NVDAObjects/IAccessible/mozilla.py
+++ b/source/NVDAObjects/IAccessible/mozilla.py
@@ -249,10 +249,11 @@ def findExtraOverlayClasses(obj, clsList):
if ver and ver.full.startswith("1.9"):
clsList.append(Gecko1_9)

- if iaRole == oleacc.ROLE_SYSTEM_DIALOG:
+ if iaRole in
(oleacc.ROLE_SYSTEM_DIALOG,oleacc.ROLE_SYSTEM_PROPERTYPAGE):
xmlRoles = obj.IA2Attributes.get("xml-roles", "").split(" ")
- if "dialog" in xmlRoles:
+ if "dialog" in xmlRoles or "tabpanel" in xmlRoles:
# #2390: Don't try to calculate text for ARIA dialogs.
+ # #4638: Don't try to calculate text for ARIA tab
panels.
try:
clsList.remove(Dialog)
except ValueError:

diff --git a/source/NVDAObjects/UIA/__init__.py
b/source/NVDAObjects/UIA/__init__.py
index 18bdbcb..789884c 100644
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -784,6 +784,20 @@ class UIA(Window):
def scrollIntoView(self):
pass

+ def _get_controllerFor(self):
+
e=self.UIAElement.getCurrentPropertyValue(UIAHandler.UIA_ControllerForPropertyId)
+ if UIAHandler.handler.clientObject.checkNotSupported(e):
+ return None
+ a=e.QueryInterface(UIAHandler.IUIAutomationElementArray)
+ objList=[]
+ for index in xrange(a.length):
+ e=a.getElement(index)
+
e=e.buildUpdatedCache(UIAHandler.handler.baseCacheRequest)
+ obj=UIA(UIAElement=e)
+ if obj:
+ objList.append(obj)
+ return objList
+
def event_UIA_elementSelected(self):
self.event_stateChange()


diff --git a/source/NVDAObjects/__init__.py b/source/NVDAObjects/__init__.py
index 0a46dc0..c84c594 100644
--- a/source/NVDAObjects/__init__.py
+++ b/source/NVDAObjects/__init__.py
@@ -391,6 +391,10 @@ class NVDAObject(baseObject.ScriptableObject):
"""
return ""

+ def _get_controllerFor(self):
+ """Retreaves the object/s that this object controls."""
+ return []
+
def _get_actionCount(self):
"""Retreaves the number of actions supported by this object."""
return 0

diff --git a/source/appModules/searchui.py b/source/appModules/searchui.py
new file mode 100644
index 0000000..a6548d1
--- /dev/null
+++ b/source/appModules/searchui.py
@@ -0,0 +1,28 @@
+#A part of NonVisual Desktop Access (NVDA)
+#Copyright (C) 2015 NV Access Limited
+#This file is covered by the GNU General Public License.
+#See the file COPYING for more details.
+
+import appModuleHandler
+import controlTypes
+import api
+import speech
+from NVDAObjects.UIA import UIA
+
+# Windows 10 Search UI suggestion list item
+class SuggestionListItem(UIA):
+
+ role=controlTypes.ROLE_LISTITEM
+
+ def event_UIA_elementSelected(self):
+ focusControllerFor=api.getFocusObject().controllerFor
+ if len(focusControllerFor)>0 and
focusControllerFor[0].appModule is self.appModule:
+ speech.cancelSpeech()
+ api.setNavigatorObject(self)
+ self.reportFocus()
+
+class AppModule(appModuleHandler.AppModule):
+
+ def chooseNVDAObjectOverlayClasses(self,obj,clsList):
+ if isinstance(obj,UIA) and obj.role==controlTypes.ROLE_DATAITEM
and isinstance(obj.parent,UIA) and obj.parent.role==controlTypes.ROLE_LIST:
+ clsList.insert(0,SuggestionListItem)

diff --git a/source/gui/settingsDialogs.py b/source/gui/settingsDialogs.py
index 30fa917..06a2829 100644
--- a/source/gui/settingsDialogs.py
+++ b/source/gui/settingsDialogs.py
@@ -211,7 +211,7 @@ class GeneralSettingsDialog(SettingsDialog):
if
len(os.listdir(os.path.join(globalVars.appArgs.configPath,packageType)))>0:
if gui.messageBox(
# Translators: A message to warn the
user when attempting to copy current settings to system settings.
- _("Custom plugins were detected in your
user settings directory. Copying these to the system profile could be a
security risk. Do you still wish to copy your settings?"),
+ _("Add-ons were detected in your user
settings directory. Copying these to the system profile could be a security
risk. Do you still wish to copy your settings?"),
# Translators: The title of the warning
dialog displayed when trying to copy settings for use in secure screens.

_("Warning"),wx.YES|wx.NO|wx.ICON_WARNING,self
)==wx.NO:

This diff is so big that we needed to truncate the remainder.

https://bitbucket.org/nvdaaddonteam/nvda/commits/062cb86d8c10/
Changeset: 062cb86d8c10
Branch: None
User: mdcurran
Date: 2015-06-25 23:10:28+00:00
Summary: win10 searchUI appModule: check for listItem as now ariaRole is
used in UIA -- no longer dataItem.

Affected #: 1 file

diff --git a/source/appModules/searchui.py b/source/appModules/searchui.py
index a6548d1..19b5705 100644
--- a/source/appModules/searchui.py
+++ b/source/appModules/searchui.py
@@ -24,5 +24,5 @@ class SuggestionListItem(UIA):
class AppModule(appModuleHandler.AppModule):

def chooseNVDAObjectOverlayClasses(self,obj,clsList):
- if isinstance(obj,UIA) and obj.role==controlTypes.ROLE_DATAITEM
and isinstance(obj.parent,UIA) and obj.parent.role==controlTypes.ROLE_LIST:
+ if isinstance(obj,UIA) and obj.role==controlTypes.ROLE_LISTITEM
and isinstance(obj.parent,UIA) and obj.parent.role==controlTypes.ROLE_LIST:
clsList.insert(0,SuggestionListItem)


https://bitbucket.org/nvdaaddonteam/nvda/commits/d911c5970c82/
Changeset: d911c5970c82
Branch: None
User: jteh
Date: 2015-06-26 06:15:12+00:00
Summary: Update liblouis to version 2.6.3.

Affected #: 1 file

diff --git a/include/liblouis b/include/liblouis
index b4b192b..96a0a8d 160000
--- a/include/liblouis
+++ b/include/liblouis
@@ -1 +1 @@
-Subproject commit b4b192b5ca0485bcbf59744e27cdd9e55bfb71e3
+Subproject commit 96a0a8d1272edd1c80a69bf3b970796d493321ff

diff --git a/readme.txt b/readme.txt
index 078688f..8312537 100644
--- a/readme.txt
+++ b/readme.txt
@@ -27,7 +27,7 @@ The following dependencies are included in Git submodules:
* eSpeak, version 1.48.04: http://espeak.sourceforge.net/
* IAccessible2, version 1.3:
http://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2
* ConfigObj, version 4.6.0: http://www.voidspace.org.uk/python/configobj.html
-* liblouis, version 2.6.2: http://www.liblouis.org/
+* liblouis, version 2.6.3: http://www.liblouis.org/
* NVDA images and sounds
* System dlls not present on many systems: mfc90.dll, msvcp90.dll,
msvcr90.dll, Microsoft.VC90.CRT.manifest
* Adobe Acrobat accessibility interface, version XI:
http://download.macromedia.com/pub/developer/acrobat/AcrobatAccess.zip


https://bitbucket.org/nvdaaddonteam/nvda/commits/eee082bd5d55/
Changeset: eee082bd5d55
Branch: None
User: jteh
Date: 2015-06-26 06:38:36+00:00
Summary: New braille translation tables: Irish grade 1, Irish grade 2,
Korean grade 1 (2006), Korean grade 2 (2006).

Affected #: 1 file

diff --git a/source/braille.py b/source/braille.py
index 70161d6..95a1103 100644
--- a/source/braille.py
+++ b/source/braille.py
@@ -126,6 +126,12 @@ TABLES = (
("Fr-Ca-g2.ctb", _("French (Canada) grade 2"), False),
# Translators: The name of a braille table displayed in the
# braille settings dialog.
+ ("ga-g1.utb", _("Irish grade 1"), False),
+ # Translators: The name of a braille table displayed in the
+ # braille settings dialog.
+ ("ga-g2.ctb", _("Irish grade 2"), False),
+ # Translators: The name of a braille table displayed in the
+ # braille settings dialog.
("gu-in-g1.utb", _("Gujarati grade 1"), False),
# Translators: The name of a braille table displayed in the
# braille settings dialog.
@@ -159,6 +165,12 @@ TABLES = (
("ka-in-g1.utb", _("Kannada grade 1"), False),
# Translators: The name of a braille table displayed in the
# braille settings dialog.
+ ("ko-2006-g1.ctb", _("Korean grade 1 (2006)"), False),
+ # Translators: The name of a braille table displayed in the
+ # braille settings dialog.
+ ("ko-2006-g2.ctb", _("Korean grade 2 (2006)"), False),
+ # Translators: The name of a braille table displayed in the
+ # braille settings dialog.
("ko-g1.ctb", _("Korean grade 1"), False),
# Translators: The name of a braille table displayed in the
# braille settings dialog.


https://bitbucket.org/nvdaaddonteam/nvda/commits/549a2e02e412/
Changeset: 549a2e02e412
Branch: None
User: jteh
Date: 2015-06-26 06:55:17+00:00
Summary: User Guide: Add missing Report title and Report status bar
commands for the BRAILLEX Tiny display.

Fixes #5084.

Affected #: 1 file

diff --git a/user_docs/en/userGuide.t2t b/user_docs/en/userGuide.t2t
index 6bd9dd1..c959e91 100644
--- a/user_docs/en/userGuide.t2t
+++ b/user_docs/en/userGuide.t2t
@@ -1895,6 +1895,8 @@ BRAILLEX Tiny:
| Move to previous object | r1+left |
| Move to next object | r1+right |
| Report text formatting | reportf |
+| Report title | l1+up |
+| Report status bar | l2+down |

BRAILLEX 2D Screen:
|| Name | Key |


https://bitbucket.org/nvdaaddonteam/nvda/commits/da2780fe9b3b/
Changeset: da2780fe9b3b
Branch: None
User: jteh
Date: 2015-06-26 06:58:47+00:00
Summary: Update documentation to note that the next/previous sentence
commands work in Outlook as well.

Fixes #5086.

Affected #: 2 files

diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t
index ef029d5..125c274 100644
--- a/user_docs/en/changes.t2t
+++ b/user_docs/en/changes.t2t
@@ -21,7 +21,7 @@
Highlights of this release include the ability to read charts in Microsoft
Excel and support for reading and interactive navigation of mathematical
content.

== New Features ==
-- Moving forward and backward by sentence in Microsoft Word is now possible
with alt+downArrow and alt+upArrow respectively. (#3288)
+- Moving forward and backward by sentence in Microsoft Word and Outlook is now
possible with alt+downArrow and alt+upArrow respectively. (#3288)
- New braille translation tables for several Indian languages. (#4778)
- In Microsoft Excel, NVDA now reports when a cell has overflowing or cropped
content. (#3040)
- In Microsoft Excel, you can now use the Elements List (NVDA+f7) to allow
listing of charts, comments and formulas. (#1987)

diff --git a/user_docs/en/userGuide.t2t b/user_docs/en/userGuide.t2t
index c959e91..d8b71ff 100644
--- a/user_docs/en/userGuide.t2t
+++ b/user_docs/en/userGuide.t2t
@@ -285,8 +285,8 @@ NVDA provides the following key commands in relation to the
system caret:
| Say all | NVDA+downArrow | NVDA+a | Starts reading from the current position
of the system caret, moving it along as it goes |
| Read current line | NVDA+upArrow | NVDA+l | Reads the line where the system
caret is currently situated. Pressing twice spells the line. |
| Read current text selection | NVDA+Shift+upArrow | NVDA+shift+s | Reads any
currently selected text |
-| Next sentence | alt+downArrow | alt+downArrow | Moves the caret to the next
sentence and announces it. (only supported in Microsoft Word) |
-| Previous sentence | alt+upArrow | alt+upArrow | Moves the caret to the
previous sentence and announces it. (only supported in Microsoft Word) |
+| Next sentence | alt+downArrow | alt+downArrow | Moves the caret to the next
sentence and announces it. (only supported in Microsoft Word and Outlook) |
+| Previous sentence | alt+upArrow | alt+upArrow | Moves the caret to the
previous sentence and announces it. (only supported in Microsoft Word and
Outlook) |


When within a table, the following key commands are also available:


https://bitbucket.org/nvdaaddonteam/nvda/commits/5a71602946fe/
Changeset: 5a71602946fe
Branch: None
User: jteh
Date: 2015-06-26 07:07:29+00:00
Summary: Handle character descriptions for conjunct characters in Tamil.

Fixes #5138.

Affected #: 1 file

diff --git a/source/speech.py b/source/speech.py
index 6d13846..2644df1 100755
--- a/source/speech.py
+++ b/source/speech.py
@@ -38,7 +38,7 @@ isPaused=False
curWordChars=[]

#Set containing locale codes for languages supporting conjunct characters
-LANGS_WITH_CONJUNCT_CHARS = {'hi', 'as', 'bn', 'gu', 'kn', 'kok', 'ml', 'mni',
'mr', 'pa', 'te', 'ur'}
+LANGS_WITH_CONJUNCT_CHARS = {'hi', 'as', 'bn', 'gu', 'kn', 'kok', 'ml', 'mni',
'mr', 'pa', 'te', 'ur', 'ta'}
# The REASON_* constants in this module are deprecated and will be removed in
a future release.
# Use controlTypes.REASON_* instead.
from controlTypes import REASON_FOCUS, REASON_FOCUSENTERED, REASON_MOUSE,
REASON_QUERY, REASON_CHANGE, REASON_MESSAGE, REASON_SAYALL, REASON_CARET,
REASON_ONLYCACHE


https://bitbucket.org/nvdaaddonteam/nvda/commits/798e0a2f1452/
Changeset: 798e0a2f1452
Branch: None
User: jteh
Date: 2015-06-29 02:05:30+00:00
Summary: New braille translation table: Finnish 6 dot.

Affected #: 1 file

diff --git a/source/braille.py b/source/braille.py
index 95a1103..5aff87c 100644
--- a/source/braille.py
+++ b/source/braille.py
@@ -106,8 +106,11 @@ TABLES = (
# Translators: The name of a braille table displayed in the
# braille settings dialog.
("ethio-g1.ctb", _("Ethiopic grade 1"), False),
+ # Translators: The name of a braille table displayed in the
# braille settings dialog.
+ ("fi.utb", _("Finnish 6 dot"), False),
# Translators: The name of a braille table displayed in the
+ # braille settings dialog.
("fi-fi-8dot.ctb", _("Finnish 8 dot computer braille"), True),
# Translators: The name of a braille table displayed in the
# braille settings dialog.


https://bitbucket.org/nvdaaddonteam/nvda/commits/ed97f80e2757/
Changeset: ed97f80e2757
Branch: None
User: jteh
Date: 2015-06-29 03:55:54+00:00
Summary: Update Python to version 2.7.10.

Fixes #5109.

Affected #: 1 file

diff --git a/readme.txt b/readme.txt
index 078688f..1890113 100644
--- a/readme.txt
+++ b/readme.txt
@@ -8,7 +8,7 @@ The NVDA source depends on several other packages to run
correctly.

=== Installed Dependencies ===
The following dependencies need to be installed on your system:
-* Python, version 2.7.9, 32 bit: http://www.python.org/
+* Python, version 2.7.10, 32 bit: http://www.python.org/
* Microsoft Visual Studio 2012 Update 1 or later (Express for Windows Desktop,
or Professional)
* Download for Visual Studio Express 2012 (Windows Desktop):
http://www.microsoft.com/en-au/download/details.aspx?id=34673
* Download for Visual Studio 2012 latest update package:
http://go.microsoft.com/fwlink/?LinkId=301713


https://bitbucket.org/nvdaaddonteam/nvda/commits/ee17394b41bc/
Changeset: ee17394b41bc
Branch: None
User: dkager
Date: 2015-06-30 05:39:24+00:00
Summary: braille: Refactor TextInfoRegion._addFieldText and
TextInfoRegion._addTextWithFields to be more consistent and readable.

Affected #: 1 file

diff --git a/source/braille.py b/source/braille.py
index 70161d6..36a4900 100644
--- a/source/braille.py
+++ b/source/braille.py
@@ -743,7 +743,7 @@ class TextInfoRegion(Region):
typeform |= louis.underline
return typeform

- def _addFieldText(self, text):
+ def _addFieldText(self, text, contentPos):
# Separate this field text from the rest of the text.
if self.rawText:
text = " %s " % text
@@ -752,8 +752,7 @@ class TextInfoRegion(Region):
self.rawText += text
textLen = len(text)
self.rawTextTypeforms.extend((louis.plain_text,) * textLen)
- # Map this field text to the start of the field's content.
- self._rawToContentPos.extend((self._currentContentPos,) *
textLen)
+ self._rawToContentPos.extend((contentPos,) * textLen)

def _addTextWithFields(self, info, formatConfig, isSelection=False):
shouldMoveCursorToFirstContent = not isSelection and
self.cursorPos is not None
@@ -772,8 +771,9 @@ class TextInfoRegion(Region):
self.cursorPos = len(self.rawText)
shouldMoveCursorToFirstContent = False
self.rawText += command
- self.rawTextTypeforms.extend((typeform,) *
len(command))
- endPos = self._currentContentPos + len(command)
+ commandLen = len(command)
+ self.rawTextTypeforms.extend((typeform,) *
commandLen)
+ endPos = self._currentContentPos + commandLen

self._rawToContentPos.extend(xrange(self._currentContentPos, endPos))
self._currentContentPos = endPos
if isSelection:
@@ -787,13 +787,14 @@ class TextInfoRegion(Region):
text = getFormatFieldBraille(field)
if not text:
continue
- self._addFieldText(text)
+ # Map this field text to the start of
the field's content.
+ self._addFieldText(text,
self._currentContentPos)
elif cmd == "controlStart":
- # Place this field on a stack so we can
access it for controlEnd.
if self._skipFieldsNotAtStartOfNode and
not field.get("_startOfNode"):
text = None
else:
text =
info.getControlFieldBraille(field, ctrlFields, True, formatConfig)
+ # Place this field on a stack so we can
access it for controlEnd.
ctrlFields.append(field)
if not text:
continue
@@ -804,23 +805,20 @@ class TextInfoRegion(Region):
if fieldStart > 0:
# There'll be a space
before the field text.
fieldStart += 1
- if
shouldMoveCursorToFirstContent:
-
shouldMoveCursorToFirstContent = False
- self.cursorPos =
fieldStart
- elif isSelection and
self._selectionStart is None:
+ if isSelection and
self._selectionStart is None:
self._selectionStart =
fieldStart
- self._addFieldText(text)
+ elif
shouldMoveCursorToFirstContent:
+ self.cursorPos =
fieldStart
+
shouldMoveCursorToFirstContent = False
+ # Map this field text to the start of
the field's content.
+ self._addFieldText(text,
self._currentContentPos)
elif cmd == "controlEnd":
field = ctrlFields.pop()
text =
info.getControlFieldBraille(field, ctrlFields, False, formatConfig)
if not text:
continue
- # Separate this field text from the
rest of the text.
- self.rawText += " %s " % text
- textLen = len(text)
-
self.rawTextTypeforms.extend((louis.plain_text,) * textLen)
# Map this field text to the end of the
field's content.
-
self._rawToContentPos.extend((self._currentContentPos - 1,) * textLen)
+ self._addFieldText(text,
self._currentContentPos - 1)
if isSelection and self._selectionStart is None:
# There is no selection. This is a cursor.
self.cursorPos = len(self.rawText)


https://bitbucket.org/nvdaaddonteam/nvda/commits/f97517598cd0/
Changeset: f97517598cd0
Branch: None
User: dkager
Date: 2015-06-30 05:50:24+00:00
Summary: In braille, extraneous spaces are no longer displayed between or
after indicators for controls and formatting.

Affected #: 1 file

diff --git a/source/braille.py b/source/braille.py
index 36a4900..3216d48 100644
--- a/source/braille.py
+++ b/source/braille.py
@@ -744,11 +744,9 @@ class TextInfoRegion(Region):
return typeform

def _addFieldText(self, text, contentPos):
- # Separate this field text from the rest of the text.
if self.rawText:
- text = " %s " % text
- else:
- text += " "
+ # Separate this field text from the rest of the text.
+ text = " " + text
self.rawText += text
textLen = len(text)
self.rawTextTypeforms.extend((louis.plain_text,) * textLen)
@@ -762,6 +760,12 @@ class TextInfoRegion(Region):
if isinstance(command, basestring):
if not command:
continue
+ if self._endsWithField:
+ # The last item added was a field,
+ # so add a space before the content.
+ self.rawText += " "
+
self.rawTextTypeforms.append(louis.plain_text)
+
self._rawToContentPos.append(self._currentContentPos)
if isSelection and self._selectionStart is None:
# This is where the content begins.
self._selectionStart = len(self.rawText)
@@ -779,6 +783,7 @@ class TextInfoRegion(Region):
if isSelection:
# The last time this is set will be the
end of the content.
self._selectionEnd = len(self.rawText)
+ self._endsWithField = False
elif isinstance(command, textInfos.FieldCommand):
cmd = command.command
field = command.field
@@ -819,6 +824,7 @@ class TextInfoRegion(Region):
continue
# Map this field text to the end of the
field's content.
self._addFieldText(text,
self._currentContentPos - 1)
+ self._endsWithField = True
if isSelection and self._selectionStart is None:
# There is no selection. This is a cursor.
self.cursorPos = len(self.rawText)
@@ -855,6 +861,7 @@ class TextInfoRegion(Region):
self._currentContentPos = 0
self._selectionStart = self._selectionEnd = None
self._skipFieldsNotAtStartOfNode = False
+ self._endsWithField = False

# Not all text APIs support offsets, so we can't always get the
offset of the selection relative to the start of the reading unit.
# Therefore, grab the reading unit in three parts.
@@ -869,12 +876,24 @@ class TextInfoRegion(Region):
chunk.setEndPoint(readingInfo, "endToEnd")
chunk.setEndPoint(sel, "startToEnd")
self._addTextWithFields(chunk, formatConfig)
- # Strip line ending characters, but add a space in case the
cursor is at the end of the reading unit.
- self.rawText = self.rawText.rstrip("\r\n\0\v\f") + " "
- self._rawToContentPos.append(self._currentContentPos)
+ # Strip line ending characters.
+ self.rawText = self.rawText.rstrip("\r\n\0\v\f")
rawTextLen = len(self.rawText)
- del self.rawTextTypeforms[rawTextLen - 1:]
- self.rawTextTypeforms.append(louis.plain_text)
+ if rawTextLen < len(self._rawToContentPos):
+ # The stripped text is shorter than the original.
+ self._currentContentPos =
self._rawToContentPos[rawTextLen]
+ del self.rawTextTypeforms[rawTextLen:]
+ # Trimming _rawToContentPos doesn't matter,
+ # because we'll only ever ask for indexes valid in
rawText.
+ #del self._rawToContentPos[rawTextLen:]
+ if rawTextLen == 0 or not self._endsWithField:
+ # There is no text left after stripping line ending
characters,
+ # or the last item added can be navigated with a cursor.
+ # Add a space in case the cursor is at the end of the
reading unit.
+ self.rawText += " "
+ rawTextLen += 1
+ self.rawTextTypeforms.append(louis.plain_text)
+ self._rawToContentPos.append(self._currentContentPos)
if self.cursorPos is not None and self.cursorPos >= rawTextLen:
self.cursorPos = rawTextLen - 1



https://bitbucket.org/nvdaaddonteam/nvda/commits/1a69ef81ddd9/
Changeset: 1a69ef81ddd9
Branch: None
User: jteh
Date: 2015-07-01 02:15:57+00:00
Summary: Explain that pressing the report status bar and report current
focus commands twice spells the information in both the User Guide and the
command description in NVDA.

Fixes #5187.

Affected #: 2 files

diff --git a/source/globalCommands.py b/source/globalCommands.py
index 7764318..dcdab08 100755
--- a/source/globalCommands.py
+++ b/source/globalCommands.py
@@ -1227,7 +1227,7 @@ class GlobalCommands(ScriptableObject):
else:
speech.speakMessage(_("no focus"))
# Translators: Input help mode message for report current focus command.
- script_reportCurrentFocus.__doc__ = _("reports the object with focus")
+ script_reportCurrentFocus.__doc__ = _("reports the object with focus.
If pressed twice, spells the information")
script_reportCurrentFocus.category=SCRCAT_FOCUS

def script_reportStatusLine(self,gesture):
@@ -1256,7 +1256,7 @@ class GlobalCommands(ScriptableObject):
else:
speech.speakSpelling(text)
# Translators: Input help mode message for report status line text
command.
- script_reportStatusLine.__doc__ = _("reads the current application
status bar and moves the navigator to it")
+ script_reportStatusLine.__doc__ = _("reads the current application
status bar and moves the navigator to it. If pressed twice, spells the
information")
script_reportStatusLine.category=SCRCAT_FOCUS

def script_toggleMouseTracking(self,gesture):

diff --git a/user_docs/en/userGuide.t2t b/user_docs/en/userGuide.t2t
index d8b71ff..867af64 100644
--- a/user_docs/en/userGuide.t2t
+++ b/user_docs/en/userGuide.t2t
@@ -269,7 +269,7 @@ There are some key commands that are useful when moving
with the System focus:
| Report current focus | NVDA+tab | NVDA+tab | announces the current object or
control that has the System focus. Pressing twice will spell the information |
| Report title | NVDA+t | NVDA+t | Reports the title of the currently active
window. Pressing twice will spell the information. Pressing three times will
copy it to the clipboard |
| Read active window | NVDA+b | NVDA+b | reads all the controls in the
currently active window (useful for dialogs) |
-| Report Status Bar | NVDA+end | NVDA+shift+end | Reports the Status Bar if
NVDA finds one. It also moves the navigator object to this location |
+| Report Status Bar | NVDA+end | NVDA+shift+end | Reports the Status Bar if
NVDA finds one. It also moves the navigator object to this location. Pressing
twice will spell the information |
%kc:endInclude

++ Navigating with the System Caret ++[SystemCaret]


https://bitbucket.org/nvdaaddonteam/nvda/commits/519c8b374beb/
Changeset: 519c8b374beb
Branch: None
User: jteh
Date: 2015-07-01 03:40:24+00:00
Summary: When using Baum/HumanWare/APH braille displays with a braille
keyboard, braille input no longer stops functioning after pressing another type
of key on the display.

Fixes #3541.

Affected #: 2 files

diff --git a/source/brailleDisplayDrivers/baum.py
b/source/brailleDisplayDrivers/baum.py
index 71c15b9..348af91 100644
--- a/source/brailleDisplayDrivers/baum.py
+++ b/source/brailleDisplayDrivers/baum.py
@@ -3,7 +3,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) 2010-2013 NV Access Limited
+#Copyright (C) 2010-2015 NV Access Limited

import time
from collections import OrderedDict
@@ -227,8 +227,12 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver):
if command == BAUM_CELL_COUNT:
self.numCells = ord(arg)
elif command == BAUM_DEVICE_ID:
- self._deviceID = arg
-
+ if arg == "Refreshabraille ":
+ # For most Baum devices, the argument is 16
bytes,
+ # but it is 18 bytes for the Refreshabraille.
+ arg += self._ser.read(2)
+ # Short ids can be padded with either nulls or spaces.
+ self._deviceID = arg.rstrip("\0 ")
elif command in KEY_NAMES:
arg = sum(ord(byte) << offset * 8 for offset, byte in
enumerate(arg))
if arg < self._keysDown.get(command, 0):
@@ -246,7 +250,12 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver):
# Press.
# This begins a new key combination.
self._ignoreKeyReleases = False
- self._keysDown[command] = arg
+ if arg > 0:
+ self._keysDown[command] = arg
+ elif command in self._keysDown:
+ # All keys in this group have been released.
+ # #3541: Remove this group so it doesn't count
as a group with keys down.
+ del self._keysDown[command]

elif command == BAUM_POWERDOWN:
log.debug("Power down")

diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t
index 125c274..b8da43e 100644
--- a/user_docs/en/changes.t2t
+++ b/user_docs/en/changes.t2t
@@ -15,6 +15,7 @@
- In browse mode for Internet Explorer and other MSHTML controls, quick
navigation by form field no longer incorrectly includes presentational list
items. (#4204)
- In Firefox, NVDA no longer tries to create a description for ARIA tab panels
based on all text inside. (#4638)
- In Internet Explorer and other MSHTML controls, tabbing into sections,
articles or dialogs no longer reports all contents of the container as its
name. (#5021, #5025)
+- When using Baum/HumanWare/APH braille displays with a braille keyboard,
braille input no longer stops functioning after pressing another type of key on
the display. (#3541)


= 2015.2 =


https://bitbucket.org/nvdaaddonteam/nvda/commits/8cc16755fa3e/
Changeset: 8cc16755fa3e
Branch: None
User: jteh
Date: 2015-07-10 02:08:20+00:00
Summary: Support for the EcoBraille 20, EcoBraille 40, EcoBraille 80 and
EcoBraille Plus braille displays.

Authors: ONCE-CIDAT <cidat.id@xxxxxxx>, Noelia Ruiz Martínez <nrm1977@xxxxxxxxx>
Fixes #4078.

Affected #: 4 files

diff --git a/contributors.txt b/contributors.txt
index cd59806..526f049 100644
--- a/contributors.txt
+++ b/contributors.txt
@@ -167,3 +167,4 @@ Siddhartha Gupta
Siddharth
Aleksandr Lin'kov
Davy Kager
+Juan Ramón Jiménez García (ONCE-CIDAT)

diff --git a/source/brailleDisplayDrivers/ecoBraille.py
b/source/brailleDisplayDrivers/ecoBraille.py
new file mode 100644
index 0000000..7444fbe
--- /dev/null
+++ b/source/brailleDisplayDrivers/ecoBraille.py
@@ -0,0 +1,266 @@
+# -*- coding: UTF-8 -*-
+#brailleDisplayDrivers/ecoBraille.py
+#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) 2014-2015 ONCE-CIDAT <cidat.id@xxxxxxx>
+
+import inputCore
+import braille
+import hwPortUtils
+from collections import OrderedDict
+from logHandler import log
+import serial
+import struct
+import wx
+
+ECO_KEY_F1 = 0x01
+ECO_KEY_F2 = 0x02
+ECO_KEY_F3 = 0x04
+ECO_KEY_F4 = 0x08
+ECO_KEY_F5 = 0x10
+ECO_KEY_F6 = 0x20
+ECO_KEY_F7 = 0x40
+ECO_KEY_F8 = 0x80
+ECO_KEY_F9 = 0x0100
+ECO_KEY_A = 0x0200
+ECO_KEY_F0 = 0x0400
+ECO_KEY_S = 0x4000
+ECO_KEY_DOWN = 0x10000
+ECO_KEY_RIGHT = 0x20000
+ECO_KEY_POINT = 0x40000
+ECO_KEY_LEFT = 0x80000
+ECO_KEY_UP = 0x100000
+ECO_START_ROUTING = 0x80000000
+ECO_END_ROUTING = 0xD0000000
+ECO_KEY_STATUS1 = 0xD5000000
+ECO_KEY_STATUS2 = 0xD6000000
+ECO_KEY_STATUS3 = 0xD0000000
+ECO_KEY_STATUS4 = 0xD1000000
+
+READ_INTERVAL = 50
+TIMEOUT = 0.1
+
+keyNames = {
+ ECO_KEY_F1: "F1",
+ ECO_KEY_F2: "F2",
+ ECO_KEY_F3: "F3",
+ ECO_KEY_F4: "F4",
+ ECO_KEY_F5: "F5",
+ ECO_KEY_F6: "F6",
+ ECO_KEY_F7: "F7",
+ ECO_KEY_F8: "F8",
+ ECO_KEY_F9: "F9",
+ ECO_KEY_F0: "F0",
+ ECO_KEY_A: "A",
+ ECO_KEY_S: "S",
+ ECO_KEY_UP: "T1",
+ ECO_KEY_DOWN: "T5",
+ ECO_KEY_RIGHT: "T4",
+ ECO_KEY_POINT: "T3",
+ ECO_KEY_LEFT: "T2"
+}
+
+class ecoTypes:
+ TECO_NO_DISPLAY = 0
+ TECO_20 = 20
+ TECO_40 = 40
+ TECO_80 = 80
+
+def eco_in_init(dev):
+ msg = dev.read(9)
+ if (len(msg) < 9):
+ return ecoTypes.TECO_80 # Needed to restart NVDA with Ecoplus
+ msg = struct.unpack('BBBBBBBBB', msg)
+ # Command message from EcoBraille is something like that:
+ # 0x10 0x02 TT AA BB CC DD 0x10 0x03
+ # where TT can be 0xF1 (identification message) or 0x88 (command
pressed in the line)
+ # If TT = 0xF1, then the next byte (AA) give us the type of EcoBraille
line (ECO 80, 40 or 20)
+ if (msg[0] == 0x10) and (msg[1] == 0x02) and (msg[7] == 0x10) and
(msg[8] == 0x03):
+ if msg[2] == 0xf1: # Initial message
+ if (msg[3] == 0x80):
+ return ecoTypes.TECO_80
+ if (msg[3] == 0x40):
+ return ecoTypes.TECO_40
+ if (msg[3] == 0x20):
+ return ecoTypes.TECO_20
+ return ecoTypes.TECO_80 # Needed for changing Braille Settings with
Ecoplus
+
+def eco_in(dev):
+ msg = dev.read(9)
+ try:
+ msg = struct.unpack('BBBBBBBBB', msg)
+ except:
+ return 0
+ # Command message from EcoBraille is something like that:
+ # 0x10 0x02 TT AA BB CC DD 0x10 0x03
+ # where TT can be 0xF1 (identification message) or 0x88 (command
pressed in the line)
+ # If TT = 0x88 then AA, BB, CC and DD give us the command pressed in
the braille line
+ if (msg[0] == 0x10) and (msg[1] == 0x02) and (msg[7] == 0x10) and
(msg[8] == 0x03):
+ if msg[2] == 0x88: # command pressed message
+ return (msg[3] << 24) | (msg[4] << 16) | (msg[5] << 8)
| msg[6]
+ return 0
+
+output_dots_map=[0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
+ 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
+ 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
+ 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
+ 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
+ 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
+ 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
+ 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
+ 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
+ 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
+ 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
+ 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
+ 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
+ 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
+ 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
+ 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
+ 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
+ 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
+ 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
+ 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
+ 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
+ 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
+ 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
+ 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
+ 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
+ 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
+ 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
+ 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
+ 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
+ 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
+ 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
+ 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF]
+
+def eco_out(cells):
+ # Messages sends to EcoBraille display are something like that:
+ # 0x10 0x02 0xBC message 0x10 0x03
+ ret = []
+ ret.append(struct.pack('BBB', 0x10, 0x02, 0xBC))
+ # Leave status cells blank
+ ret.append(struct.pack('BBBBB', 0x00, 0x00, 0x00, 0x00, 0x00))
+ for d in cells:
+ ret.append(struct.pack('B', output_dots_map[d]))
+ ret.append(struct.pack('BB', 0x10, 0x03))
+ return "".join(ret)
+
+class BrailleDisplayDriver(braille.BrailleDisplayDriver):
+ """ EcoBraille display driver.
+ """
+ name = "ecoBraille"
+ # Translators: The name of a braille display.
+ description = _("EcoBraille displays")
+
+ @classmethod
+ def check(cls):
+ return True
+
+ @classmethod
+ def getPossiblePorts(cls):
+ ports = OrderedDict()
+ for p in hwPortUtils.listComPorts():
+ # Translators: Name of a serial communications port.
+ ports[p["port"]] = _("Serial:
{portName}").format(portName=p["friendlyName"])
+ return ports
+
+ def __init__(self, port):
+ super(BrailleDisplayDriver, self).__init__()
+ self._port = (port)
+ # Try to open port
+ self._dev = serial.Serial(self._port, baudrate = 19200,
bytesize = serial.EIGHTBITS, parity = serial.PARITY_NONE, stopbits =
serial.STOPBITS_ONE)
+ # Use a longer timeout when waiting for initialisation.
+ self._dev.timeout = self._dev.writeTimeout = 2.7
+ self._ecoType = eco_in_init(self._dev)
+ # Use a shorter timeout hereafter.
+ self._dev.timeout = self._dev.writeTimeout = TIMEOUT
+ # Always send the protocol answer.
+ self._dev.write("\x61\x10\x02\xf1\x57\x57\x57\x10\x03")
+ self._dev.write("\x10\x02\xbc\x00\x00\x00\x00\x00\x10\x03")
+ # Start keyCheckTimer.
+ self._readTimer = wx.PyTimer(self._handleResponses)
+ self._readTimer.Start(READ_INTERVAL)
+
+ def terminate(self):
+ super(BrailleDisplayDriver, self).terminate()
+ try:
+ self._dev.write("\x61\x10\x02\xf1\x57\x57\x57\x10\x03")
+ self._readTimer.Stop()
+ self._readTimer = None
+ finally:
+ self._dev.close()
+ self._dev = None
+
+ def _get_numCells(self):
+ return self._ecoType
+
+ def display(self, cells):
+ try:
+ self._dev.write(eco_out(cells))
+ except:
+ pass
+
+ def _handleResponses(self):
+ if self._dev.inWaiting():
+ command = eco_in(self._dev)
+ if command:
+ try:
+ self._handleResponse(command)
+ except KeyError:
+ pass
+
+ def _handleResponse(self, command):
+ if command in (ECO_KEY_STATUS1, ECO_KEY_STATUS2,
ECO_KEY_STATUS3, ECO_KEY_STATUS4):
+ # Nothing to do with the status cells
+ return 0
+ if (command < ECO_END_ROUTING) and (command >=
ECO_START_ROUTING):
+ # Routing
+ try:
+
inputCore.manager.executeGesture(InputGestureRouting(((command -
ECO_START_ROUTING) >> 24) + 1))
+ except:
+ log.debug("EcoBraille: No function associated
with this routing key {key}".format(key=command))
+ elif command > 0:
+ # Button
+ try:
+
inputCore.manager.executeGesture(InputGestureKeys(command))
+ except inputCore.NoInputGestureAction:
+ log.debug("EcoBraille: No function associated
with this Braille key {key}".format(key=command))
+ return 0
+
+ gestureMap = inputCore.GlobalGestureMap({
+ "globalCommands.GlobalCommands": {
+ "braille_routeTo": "br(ecoBraille):routing",
+ "braille_previousLine": "br(ecoBraille):T1",
+ "braille_nextLine": "br(ecoBraille):T5",
+ "braille_scrollBack": "br(ecoBraille):T2",
+ "braille_scrollForward": "br(ecoBraille):T4",
+ "review_activate": "br(ecoBraille):T3",
+ "reviewMode_next": "br(ecoBraille):F1",
+ "navigatorObject_parent": "br(ecoBraille):F2",
+ "reviewMode_previous": "br(ecoBraille):F3",
+ "navigatorObject_previous": "br(ecoBraille):F4",
+ "navigatorObject_current": "br(ecoBraille):F5",
+ "navigatorObject_next": "br(ecoBraille):F6",
+ "navigatorObject_toFocus": "br(ecoBraille):F7",
+ "navigatorObject_firstChild": "br(ecoBraille):F8",
+ "navigatorObject_moveFocus": "br(ecoBraille):F9",
+ "navigatorObject_currentDimensions":
"br(ecoBraille):F0",
+ "braille_toggleTether": "br(ecoBraille):A",
+ }
+ })
+
+class InputGestureKeys(braille.BrailleDisplayGesture):
+ source = BrailleDisplayDriver.name
+
+ def __init__(self, keys):
+ super(InputGestureKeys, self).__init__()
+ self.id = keyNames[keys]
+
+class InputGestureRouting(braille.BrailleDisplayGesture):
+ source = BrailleDisplayDriver.name
+
+ def __init__(self, index):
+ super(InputGestureRouting, self).__init__()
+ self.id = "routing"
+ self.routingIndex = index-1

diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t
index b8da43e..182361e 100644
--- a/user_docs/en/changes.t2t
+++ b/user_docs/en/changes.t2t
@@ -9,6 +9,7 @@
- The existance of spelling errors is announced in editable fields for
Internet Explorer and other MSHTML controls. (#4174)
- Many more unicode math symbols are now spoken when they appear in text.
(#3805)
- Search suggestions in the Windows 10 start screen are automatically reported
(#5049)
+- Support for the EcoBraille 20, EcoBraille 40, EcoBraille 80 and EcoBraille
Plus braille displays. (#4078)


== Bug Fixes ==

diff --git a/user_docs/en/userGuide.t2t b/user_docs/en/userGuide.t2t
index 867af64..8eeaba7 100644
--- a/user_docs/en/userGuide.t2t
+++ b/user_docs/en/userGuide.t2t
@@ -1962,6 +1962,41 @@ Please check your BrailleNote's documentation to find
where these keys are locat
| Toggle input help | space+dot2+dot3+dot6 (space+lower h) |
%kc:endInclude

+++ EcoBraille ++
+NVDA supports EcoBraille displays from [ONCE http://www.once.es/].
+The following models are supported:
+- EcoBraille 20
+- EcoBraille 40
+- EcoBraille 80
+- EcoBraille Plus
+-
+
+In NVDA, you can set the serial port to which the display is connected in the
Braille Settings dialog.
+
+Following are the key assignments for EcoBraille displays.
+Please see the [EcoBraille documentation
ftp://ftp.once.es/pub/utt/bibliotecnia/Lineas_Braille/ECO/] for descriptions of
where these keys can be found.
+
+%kc:beginInclude
+|| Name | Key |
+| Scroll braille display back | T2 |
+| Scroll braille display forward | T4 |
+| Move braille display to previous line | T1 |
+| Move braille display to next line | T5 |
+| Route to braille cell | Routing |
+| Activate current navigator object | T3 |
+| Switch to next review mode | F1 |
+| Move to containing object | F2 |
+| Switch to previous review mode | F3 |
+| Move to previous object | F4 |
+| Report current object | F5 |
+| Move to next object | F6 |
+| Move to focus object | F7 |
+| Move to first contained object | F8 |
+| Move System focus or caret to current review position | F9 |
+| Report review cursor location | F0 |
+| Toggle braille tethered to | A |
+%kc:endInclude
+
++ BRLTTY ++
[BRLTTY http://mielke.cc/brltty/] is a separate program which can be used to
support many more braille displays.
In order to use this, you need to install [BRLTTY for Windows
http://brl.thefreecat.org/brltty/].


https://bitbucket.org/nvdaaddonteam/nvda/commits/8d35b807c63c/
Changeset: 8d35b807c63c
Branch: None
User: jteh
Date: 2015-07-10 02:16:49+00:00
Summary: In Windows 10, extraneous information is no longer reported when
pressing alt+tab or alt+shift+tab to switch between applications.

Fixes #5116.

Affected #: 2 files

diff --git a/source/appModules/explorer.py b/source/appModules/explorer.py
index 1ff91bb..a3defd9 100644
--- a/source/appModules/explorer.py
+++ b/source/appModules/explorer.py
@@ -17,6 +17,19 @@ from NVDAObjects.window import Window
from NVDAObjects.IAccessible import sysListView32, IAccessible
from NVDAObjects.UIA import UIA

+# Suppress incorrect Win 10 Task switching window focus
+class MultitaskingViewFrameWindow(UIA):
+ shouldAllowUIAFocusEvent=False
+
+# suppress focus ancestry for task switching list items if alt is held down
(alt+tab)
+class MultitaskingViewFrameListItem(UIA):
+
+ def _get_container(self):
+ if winUser.getAsyncKeyState(winUser.VK_MENU)&32768:
+ return api.getDesktopObject()
+ else:
+ return
super(MultitaskingViewFrameListItem,self).container
+
# support for Win8 start screen search suggestions.
class SuggestionListItem(UIA):

@@ -175,6 +188,10 @@ class AppModule(appModuleHandler.AppModule):
clsList.insert(0, ImmersiveLauncher)
elif uiaClassName=="ListViewItem" and
obj.UIAElement.cachedAutomationId.startswith('Suggestion_'):
clsList.insert(0,SuggestionListItem)
+ elif uiaClassName=="MultitaskingViewFrame" and
role==controlTypes.ROLE_WINDOW:
+ clsList.insert(0,MultitaskingViewFrameWindow)
+ elif obj.windowClassName=="MultitaskingViewFrame" and
role==controlTypes.ROLE_LISTITEM:
+ clsList.insert(0,MultitaskingViewFrameListItem)

def event_NVDAObject_init(self, obj):
windowClass = obj.windowClassName

diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t
index 182361e..537fd08 100644
--- a/user_docs/en/changes.t2t
+++ b/user_docs/en/changes.t2t
@@ -17,6 +17,7 @@
- In Firefox, NVDA no longer tries to create a description for ARIA tab panels
based on all text inside. (#4638)
- In Internet Explorer and other MSHTML controls, tabbing into sections,
articles or dialogs no longer reports all contents of the container as its
name. (#5021, #5025)
- When using Baum/HumanWare/APH braille displays with a braille keyboard,
braille input no longer stops functioning after pressing another type of key on
the display. (#3541)
+- In Windows 10, extraneous information is no longer reported when pressing
alt+tab or alt+shift+tab to switch between applications. (#5116)


= 2015.2 =


https://bitbucket.org/nvdaaddonteam/nvda/commits/7b7823c71f44/
Changeset: 7b7823c71f44
Branch: None
User: mdcurran
Date: 2015-07-10 03:18:45+00:00
Summary: Fix garbled text when typing in Outlook with braille enabled and
with text expansion functionality (e.g. in AutoHotkey).

InputGesture.execute: if an intercepted command script (script that sends the
gesture it intercepts) is queued and or has not yet completed its execution,
queue any further gestures that do not have a script via a fake script that
just sends the gesture. this ensures that input stays in order even if it was
delayed by NVDA.
Fixes #2953, #4499.

Affected #: 3 files

diff --git a/source/inputCore.py b/source/inputCore.py
index 5b62510..f8e4f28 100644
--- a/source/inputCore.py
+++ b/source/inputCore.py
@@ -434,6 +434,12 @@ class InputManager(baseObject.AutoPropertyObject):

gesture.reportExtra()

+ # #2953: if an intercepted command Script (script that sends a
gesture) is queued
+ # then queue all following gestures (that don't have a script)
with a fake script so that they remain in order.
+ if not script and
scriptHandler._numIncompleteInterceptedCommandScripts:
+ script=lambda gesture: gesture.send()
+
+
if script:
scriptHandler.queueScript(script, gesture)
return

diff --git a/source/scriptHandler.py b/source/scriptHandler.py
index 70070e6..ff7f28c 100644
--- a/source/scriptHandler.py
+++ b/source/scriptHandler.py
@@ -19,6 +19,8 @@ import globalPluginHandler
import braille

_numScriptsQueued=0 #Number of scripts that are queued to be executed
+#: Number of scripts that send their gestures on that are queued to be
executed or are currently being executed.
+_numIncompleteInterceptedCommandScripts=0
_lastScriptTime=0 #Time in MS of when the last script was executed
_lastScriptRef=None #Holds a weakref to the last script that was executed
_lastScriptCount=0 #The amount of times the last script was repeated
@@ -132,14 +134,21 @@ def getScriptLocation(script):
if name in cls.__dict__:
return "%s.%s"%(cls.__module__,cls.__name__)

+def _isInterceptedCommandScript(script):
+ return not getattr(script,'__doc__',None)
+
def _queueScriptCallback(script,gesture):
- global _numScriptsQueued
+ global _numScriptsQueued, _numIncompleteInterceptedCommandScripts
_numScriptsQueued-=1
executeScript(script,gesture)
+ if _isInterceptedCommandScript(script):
+ _numIncompleteInterceptedCommandScripts-=1

def queueScript(script,gesture):
- global _numScriptsQueued
+ global _numScriptsQueued, _numIncompleteInterceptedCommandScripts
_numScriptsQueued+=1
+ if _isInterceptedCommandScript(script):
+ _numIncompleteInterceptedCommandScripts+=1

queueHandler.queueFunction(queueHandler.eventQueue,_queueScriptCallback,script,gesture)

def willSayAllResume(gesture):

diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t
index 537fd08..361ddef 100644
--- a/user_docs/en/changes.t2t
+++ b/user_docs/en/changes.t2t
@@ -18,6 +18,8 @@
- In Internet Explorer and other MSHTML controls, tabbing into sections,
articles or dialogs no longer reports all contents of the container as its
name. (#5021, #5025)
- When using Baum/HumanWare/APH braille displays with a braille keyboard,
braille input no longer stops functioning after pressing another type of key on
the display. (#3541)
- In Windows 10, extraneous information is no longer reported when pressing
alt+tab or alt+shift+tab to switch between applications. (#5116)
+- Typed text is no longer garbled when using certain applications such as
Microsoft Outlook with a braille display. (#2953)
+- When using text expansion functionality in software such as AutoHotkey,
expanded text is no longer garbled when NVDA is configured to handle keys from
other applications. (#4499)


= 2015.2 =


https://bitbucket.org/nvdaaddonteam/nvda/commits/b7be7c2fdc30/
Changeset: b7be7c2fdc30
Branch: None
User: mdcurran
Date: 2015-07-10 05:17:39+00:00
Summary: In browse mode, you can now toggle single letter navigation on and
off by pressing NVDA+shift+space. When off, single letter keys are passed to
the application, which is useful for some web applications such as Gmail,
Twitter and Facebook.

Fixes #3203.

Affected #: 4 files

diff --git a/source/browseMode.py b/source/browseMode.py
index a071c1e..05f5f49 100644
--- a/source/browseMode.py
+++ b/source/browseMode.py
@@ -176,6 +176,29 @@ class
BrowseModeTreeInterceptor(treeInterceptorHandler.TreeInterceptor):
def script_trapNonCommandGesture(self,gesture):
winsound.PlaySound("default",1)

+ singleLetterNavEnabled=True #: Whether single letter navigation scripts
should be active (true) or if these letters should fall to the application.
+
+ def getAlternativeScript(self,gesture,script):
+ if self.passThrough or not gesture.isCharacter:
+ return script
+ if not self.singleLetterNavEnabled:
+ return None
+ if not script and self.shouldTrapNonCommandGestures:
+ script=self.script_trapNonCommandGesture
+ return script
+
+ def script_toggleSingleLetterNav(self,gesture):
+ if self.singleLetterNavEnabled:
+ self.singleLetterNavEnabled=False
+ # Translators: Reported when single letter navigation
in browse mode is turned off.
+ ui.message(_("Single letter navigation off"))
+ else:
+ self.singleLetterNavEnabled=True
+ # Translators: Reported when single letter navigation
in browse mode is turned on.
+ ui.message(_("Single letter navigation on"))
+ # Translators: the description for the toggleSingleLetterNavigation
command in browse mode.
+ script_toggleSingleLetterNav.__doc__=_("Toggles single letter
navigation on and off. When on, single letter keys in browse mode jump to
various kinds of elements on the page. When off, these keys are passed to the
application")
+
def _get_ElementsListDialog(self):
return ElementsListDialog

@@ -251,6 +274,7 @@ class
BrowseModeTreeInterceptor(treeInterceptorHandler.TreeInterceptor):
"kb:NVDA+f7": "elementsList",
"kb:enter": "activatePosition",
"kb:space": "activatePosition",
+ "kb:NVDA+shift+space":"toggleSingleLetterNav",
}

# Add quick navigation scripts.

diff --git a/source/scriptHandler.py b/source/scriptHandler.py
index ff7f28c..83ff1c3 100644
--- a/source/scriptHandler.py
+++ b/source/scriptHandler.py
@@ -99,10 +99,11 @@ def findScript(gesture):
treeInterceptor = focus.treeInterceptor
if treeInterceptor and treeInterceptor.isReady:
func = _getObjScript(treeInterceptor, gesture, globalMapScripts)
+ from browseMode import BrowseModeTreeInterceptor
+ if isinstance(treeInterceptor,BrowseModeTreeInterceptor):
+ func=treeInterceptor.getAlternativeScript(gesture,func)
if func and (not treeInterceptor.passThrough or
getattr(func,"ignoreTreeInterceptorPassThrough",False)):
return func
- elif gesture.isCharacter and not treeInterceptor.passThrough
and treeInterceptor.shouldTrapNonCommandGestures:
- return treeInterceptor.script_trapNonCommandGesture

# NVDAObject level.
func = _getObjScript(focus, gesture, globalMapScripts)

diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t
index 361ddef..d268ce8 100644
--- a/user_docs/en/changes.t2t
+++ b/user_docs/en/changes.t2t
@@ -10,6 +10,7 @@
- Many more unicode math symbols are now spoken when they appear in text.
(#3805)
- Search suggestions in the Windows 10 start screen are automatically reported
(#5049)
- Support for the EcoBraille 20, EcoBraille 40, EcoBraille 80 and EcoBraille
Plus braille displays. (#4078)
+- In browse mode, you can now toggle single letter navigation on and off by
pressing NVDA+shift+space. When off, single letter keys are passed to the
application, which is useful for some web applications such as Gmail, Twitter
and Facebook. (#3203)


== Bug Fixes ==

diff --git a/user_docs/en/userGuide.t2t b/user_docs/en/userGuide.t2t
index 8eeaba7..97a4022 100644
--- a/user_docs/en/userGuide.t2t
+++ b/user_docs/en/userGuide.t2t
@@ -503,6 +503,12 @@ To move to the beginning or end of containing elements
such as lists and tables:
|| Name | Key | Description |
| Move to start of container | shift+comma | Moves to the start of the
container (list, table, etc.) where the caret is positioned |
| Move past end of container | comma | Moves past the end of the container
(list, table, etc.) where the caret is positioned |
+
+%kc:endInclude
+Some web applications such as Gmail, Twitter and Facebook use single letters
as shortcut keys.
+If you want to use these while still being able to use your cursor keys to
read in browse mode, you can temporarily disable NVDA's single letter
navigation keys.
+%kc:beginInclude
+To toggle single letter navigation on and off for the current document, press
NVDA+shift+space.
%kc:endInclude

++ The Elements List ++


https://bitbucket.org/nvdaaddonteam/nvda/commits/85bd3c4e78e7/
Changeset: 85bd3c4e78e7
Branch: None
User: jteh
Date: 2015-07-10 05:25:15+00:00
Summary: In browse mode in Internet Explorer and other MSHTML controls, the
correct content is now reported when an element appears or changes and is
immediately focused.

MSHTML vbufBackend: force an instant update of the content for onfocus events
in case the focus moves to something that was newly created/changed.
Fixes #5040.

Affected #: 2 files

diff --git a/nvdaHelper/vbufBackends/mshtml/node.cpp
b/nvdaHelper/vbufBackends/mshtml/node.cpp
index b017901..c8f7bf3 100755
--- a/nvdaHelper/vbufBackends/mshtml/node.cpp
+++ b/nvdaHelper/vbufBackends/mshtml/node.cpp
@@ -127,6 +127,9 @@ class CDispatchChangeSink : public IDispatch {
this->storageNode->backend->forceUpdate();
}
return S_OK;
+ } else if(dispIdMember==DISPID_EVMETH_ONFOCUS) {
+ this->storageNode->backend->forceUpdate();
+ return S_OK;
}
return E_FAIL;
}

diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t
index d268ce8..4ee00a5 100644
--- a/user_docs/en/changes.t2t
+++ b/user_docs/en/changes.t2t
@@ -21,6 +21,7 @@
- In Windows 10, extraneous information is no longer reported when pressing
alt+tab or alt+shift+tab to switch between applications. (#5116)
- Typed text is no longer garbled when using certain applications such as
Microsoft Outlook with a braille display. (#2953)
- When using text expansion functionality in software such as AutoHotkey,
expanded text is no longer garbled when NVDA is configured to handle keys from
other applications. (#4499)
+- In browse mode in Internet Explorer and other MSHTML controls, the correct
content is now reported when an element appears or changes and is immediately
focused. (#5040)


= 2015.2 =


https://bitbucket.org/nvdaaddonteam/nvda/commits/b6a4273112f1/
Changeset: b6a4273112f1
Branch: None
User: jteh
Date: 2015-07-13 02:19:56+00:00
Summary: Actually, the fix for garbled characters with Outlook and braille
(#2953) doesn't fix garble keys with text expansion functionality (#4499) after
all. :(

Affected #: 1 file

diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t
index 4ee00a5..ca61b9b 100644
--- a/user_docs/en/changes.t2t
+++ b/user_docs/en/changes.t2t
@@ -20,7 +20,6 @@
- When using Baum/HumanWare/APH braille displays with a braille keyboard,
braille input no longer stops functioning after pressing another type of key on
the display. (#3541)
- In Windows 10, extraneous information is no longer reported when pressing
alt+tab or alt+shift+tab to switch between applications. (#5116)
- Typed text is no longer garbled when using certain applications such as
Microsoft Outlook with a braille display. (#2953)
-- When using text expansion functionality in software such as AutoHotkey,
expanded text is no longer garbled when NVDA is configured to handle keys from
other applications. (#4499)
- In browse mode in Internet Explorer and other MSHTML controls, the correct
content is now reported when an element appears or changes and is immediately
focused. (#5040)




https://bitbucket.org/nvdaaddonteam/nvda/commits/4049fa69640d/
Changeset: 4049fa69640d
Branch: None
User: mdcurran
Date: 2015-07-13 02:39:20+00:00
Summary: UIA EdgeHTML treeInterceptor textInfo: move and expand now treet
certain containers (comboboxes, itneractive lists) as a single character stop.

Affected #: 1 file

diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py
index 8df9531..565d6ae 100644
--- a/source/NVDAObjects/UIA/edge.py
+++ b/source/NVDAObjects/UIA/edge.py
@@ -326,8 +326,38 @@ def
UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction

class
EdgeHTMLTreeInterceptorTextInfo(browseMode.BrowseModeDocumentTextInfo,treeInterceptorHandler.RootProxyTextInfo):

+ def getTextWithFields(self,formatConfig=None):
+ try:
+
container=next(self.obj._iterNodesByType("nonTextContainer","up",self))
+ except StopIteration:
+ container=None
+ if container:
+
fields=super(EdgeHTMLTreeInterceptorTextInfo,container.textInfo).getTextWithFields(formatConfig)
+ startLen=0
+ for index,field in enumerate(fields):
+ if isinstance(field,textInfos.FieldCommand) and
field.command=="controlStart":
+ startLen=index+1
+ else:
+ break
+ fields[startLen:0-startLen]=[container.obj.value or u""]
+ return fields
+ else:
+ return
super(EdgeHTMLTreeInterceptorTextInfo,self).getTextWithFields(formatConfig)
+
# override move to get around bugs in Edge where moving by line jumps
over checkboxes, radio buttons etc.
def move(self,unit,direction,endPoint=None):
+ try:
+
containerInfo=next(self.obj._iterNodesByType("nonTextContainer","up",self)).textInfo
+ except StopIteration:
+ containerInfo=None
+ if containerInfo:
+ if direction>0:
+ containerInfo.collapse(end=True)
+
super(EdgeHTMLTreeInterceptorTextInfo,containerInfo).move(textInfos.UNIT_CHARACTER,-1)
+ else:
+ containerInfo.collapse()
+ self._rangeObj=containerInfo._rangeObj
+ del containerInfo
origInfo=None
if (direction==1 or direction==-1) and not endPoint and unit in
(textInfos.UNIT_WORD,textInfos.UNIT_LINE):
origInfo=self.copy()
@@ -363,6 +393,13 @@ class
EdgeHTMLTreeInterceptorTextInfo(browseMode.BrowseModeDocumentTextInfo,tree

# Override expand to get around bugs in Edge where expanding to line on
a checkbox, radio button etc expands the previous line (not containing the
control in question).
def expand(self,unit):
+ try:
+ containerInfo=None
#next(self.obj._iterNodesByType("nonTextContainer","up",self)).textInfo
+ except StopIteration:
+ containerInfo=None
+ if containerInfo:
+ self._rangeObj=containerInfo._rangeObj
+ del containerInfo
origInfo=None
if unit in (textInfos.UNIT_WORD,textInfos.UNIT_LINE):
origInfo=self.copy()
@@ -427,6 +464,9 @@ class
EdgeHTMLTreeInterceptor(cursorManager.ReviewCursorManager,browseMode.Brows
elif nodeType=="formField":

condition=createUIAMultiPropertyCondition({UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_EditControlTypeId,UIAHandler.UIA_ValueIsReadOnlyPropertyId:False},{UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_ListControlTypeId,UIAHandler.UIA_IsKeyboardFocusablePropertyId:True},{UIAHandler.UIA_ControlTypePropertyId:[UIAHandler.UIA_CheckBoxControlTypeId,UIAHandler.UIA_RadioButtonControlTypeId,UIAHandler.UIA_ComboBoxControlTypeId,UIAHandler.UIA_ButtonControlTypeId]})
return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
+ elif nodeType=="nonTextContainer":
+
condition=createUIAMultiPropertyCondition({UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_ListControlTypeId,UIAHandler.UIA_IsKeyboardFocusablePropertyId:True},{UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_ComboBoxControlTypeId})
+ return
UIAControlQuicknavIterator(nodeType,self,pos,condition,direction)
raise NotImplementedError

def _activateNVDAObject(self,obj):


https://bitbucket.org/nvdaaddonteam/nvda/commits/35bbef533528/
Changeset: 35bbef533528
Branch: None
User: mdcurran
Date: 2015-07-13 06:14:29+00:00
Summary: searchUI suggestion listItem: only cancel speech and report the
selection if this listeItem actually has a name. Stops random cancel speeches
when sometimes bring up the start screen.

Affected #: 1 file

diff --git a/source/appModules/searchui.py b/source/appModules/searchui.py
index 19b5705..f250693 100644
--- a/source/appModules/searchui.py
+++ b/source/appModules/searchui.py
@@ -16,7 +16,7 @@ class SuggestionListItem(UIA):

def event_UIA_elementSelected(self):
focusControllerFor=api.getFocusObject().controllerFor
- if len(focusControllerFor)>0 and
focusControllerFor[0].appModule is self.appModule:
+ if len(focusControllerFor)>0 and
focusControllerFor[0].appModule is self.appModule and self.name:
speech.cancelSpeech()
api.setNavigatorObject(self)
self.reportFocus()


https://bitbucket.org/nvdaaddonteam/nvda/commits/15c8bd25e90d/
Changeset: 15c8bd25e90d
Branch: None
User: jteh
Date: 2015-07-14 02:46:34+00:00
Summary: In browse mode in Microsoft Word, single letter navigation now
updates the braille display and the review cursor as expected.

Fixes #4968.

Affected #: 2 files

diff --git a/source/browseMode.py b/source/browseMode.py
index 05f5f49..a0db593 100644
--- a/source/browseMode.py
+++ b/source/browseMode.py
@@ -19,6 +19,8 @@ import speech
import sayAllHandler
import treeInterceptorHandler
import inputCore
+import review
+import braille

REASON_QUICKNAV = "quickNav"

@@ -161,6 +163,10 @@ class TextInfoQuickNavItem(QuickNavItem):

def moveTo(self):
self.textInfo.updateCaret()
+ caret = self.textInfo.copy()
+ caret.collapse()
+ review.handleCaretMove(caret)
+ braille.handler.handleCaretMove(self.document)

@property
def isAfterSelection(self):

diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t
index ca61b9b..75a4e5d 100644
--- a/user_docs/en/changes.t2t
+++ b/user_docs/en/changes.t2t
@@ -21,6 +21,7 @@
- In Windows 10, extraneous information is no longer reported when pressing
alt+tab or alt+shift+tab to switch between applications. (#5116)
- Typed text is no longer garbled when using certain applications such as
Microsoft Outlook with a braille display. (#2953)
- In browse mode in Internet Explorer and other MSHTML controls, the correct
content is now reported when an element appears or changes and is immediately
focused. (#5040)
+- In browse mode in Microsoft Word, single letter navigation now updates the
braille display and the review cursor as expected. (#4968)


= 2015.2 =


https://bitbucket.org/nvdaaddonteam/nvda/commits/4a7a8bf22fd1/
Changeset: 4a7a8bf22fd1
Branch: None
User: jteh
Date: 2015-07-14 02:48:32+00:00
Summary: In braille, extraneous spaces are no longer displayed between or
after indicators for controls and formatting.

Fixes #5043.

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/13dfe272ebee/
Changeset: 13dfe272ebee
Branch: None
User: jteh
Date: 2015-07-14 02:57:30+00:00
Summary: Update liblouis to 2.6.3 and add new braille tables.

Fixes #5137, #5074, #5097.

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/1973d3388753/
Changeset: 1973d3388753
Branch: None
User: jteh
Date: 2015-07-14 05:57:01+00:00
Summary: You can now injet raw input from a system keyboard that is not
handled natively by Windows (e.g. a QWERTY keyboard on a braille display) using
the new keyboardHandler.injectRawKeyboardInput function.

Fixes #4576.

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/f52bd5a0680f/
Changeset: f52bd5a0680f
Branch: None
User: Halim Sahin <>
Date: 2015-07-14 05:58:25+00:00
Summary: The QWERTY keyboard on the Papenmeier BRAILLEX Live Plus braille
display is now supported.

Fixes #5181.

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/8e912ec76fab/
Changeset: 8e912ec76fab
Branch: None
User: jteh
Date: 2015-07-15 07:45:04+00:00
Summary: Fix a rare deadlock in watchdog termination, inability to force
quit/restart NVDA if it freezes during exit and another rare watchdog edge case.

See the code comments and/or the ticket for full details.
Fixes #5189.

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/9dce91551bde/
Changeset: 9dce91551bde
Branch: None
User: jteh
Date: 2015-07-16 09:05:24+00:00
Summary: In browse mode in web browsers, tabbing now behaves as expected
after tabbing to a frame document.

To achieve this, if the browse mode caret was last moved due to a focus change,
don't override tab.
Re #5227.

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/c6abba4c7940/
Changeset: c6abba4c7940
Branch: None
User: CommitBot
Date: 2015-07-16 09:17:49+00:00
Summary: L10n updates for: an
From translation svn revision: 22446

Authors:
Jorge Perez <jorgtum@xxxxxxxxx>

Stats:
19 13 source/locale/an/LC_MESSAGES/nvda.po
61 20 source/locale/an/symbols.dic
10 1 user_docs/an/changes.t2t
15 13 user_docs/an/userGuide.t2t
4 files changed, 105 insertions(+), 47 deletions(-)

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/a948a70385a5/
Changeset: a948a70385a5
Branch: None
User: CommitBot
Date: 2015-07-16 09:17:52+00:00
Summary: L10n updates for: ar
From translation svn revision: 22446

Authors:
Fatma Mehanna <fatma.mehanna@xxxxxxxxx>
Shaimaa Ibrahim <shamse1@xxxxxxxxx>

Stats:
345 288 source/locale/ar/LC_MESSAGES/nvda.po
13 0 user_docs/ar/changes.t2t
2 files changed, 358 insertions(+), 288 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/60fa4b179833/
Changeset: 60fa4b179833
Branch: None
User: CommitBot
Date: 2015-07-16 09:17:56+00:00
Summary: L10n updates for: bg
From translation svn revision: 22446

Authors:
Zahari Yurukov <zahari.yurukov@xxxxxxxxx>
Kostadin Kolev <k_kolev1985@xxxxxxx>

Stats:
26 20 source/locale/bg/LC_MESSAGES/nvda.po
1 file changed, 26 insertions(+), 20 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/a191af74eb43/
Changeset: a191af74eb43
Branch: None
User: CommitBot
Date: 2015-07-16 09:17:58+00:00
Summary: L10n updates for: ca
From translation svn revision: 22446

Authors:
Ruben Alcaraz <ruben.hangar1.8@xxxxxxxxx>
Dr. Mireia Ribera <mireia.ribera@xxxxxxxxx>
Santi Moese <santispock@xxxxxxxxx>
Marina Salse Rovira <salse@xxxxxx>

Stats:
16 7 source/locale/ca/LC_MESSAGES/nvda.po
1 file changed, 16 insertions(+), 7 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/69f094327c76/
Changeset: 69f094327c76
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:01+00:00
Summary: L10n updates for: da
From translation svn revision: 22446

Authors:
Daniel K. Gartmann <kontakt@xxxxxxx>
Nicolai Svendsen <chojiro1990@xxxxxxxxx>
bue@xxxxxxxxxxxxxxxxxx

Stats:
18 12 source/locale/da/LC_MESSAGES/nvda.po
1 file changed, 18 insertions(+), 12 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/574b473d8cbc/
Changeset: 574b473d8cbc
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:03+00:00
Summary: L10n updates for: de
From translation svn revision: 22446

Authors:
Bernd Dorer <bernd.dorer@xxxxxxxx>
David Parduhn <xkill85@xxxxxxx>
Rene Linke <rene.linke@xxxxxxxxxx>

Stats:
6765 4703 source/locale/de/LC_MESSAGES/nvda.po
47 1 source/locale/de/symbols.dic
10 2 user_docs/de/changes.t2t
3 3 user_docs/de/userGuide.t2t
4 files changed, 6825 insertions(+), 4709 deletions(-)

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/a1cc8f44ac05/
Changeset: a1cc8f44ac05
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:05+00:00
Summary: L10n updates for: el
From translation svn revision: 22446

Authors:
Irene Nakas <irnakas@xxxxxxxxx>
Nikos Demetriou <nikosdemetriou@xxxxxxxxxxxxxx>
access@xxxxxxxxxxxx

Stats:
17 11 source/locale/el/LC_MESSAGES/nvda.po
1 file changed, 17 insertions(+), 11 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/1d51dbc5b7f3/
Changeset: 1d51dbc5b7f3
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:07+00:00
Summary: L10n updates for: es_CO
From translation svn revision: 22446

Authors:
Jorge Zarache <reydelasmaquinas@xxxxxxxxxxx>

Stats:
20 13 source/locale/es_CO/LC_MESSAGES/nvda.po
1 file changed, 20 insertions(+), 13 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/71734cf41866/
Changeset: 71734cf41866
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:10+00:00
Summary: L10n updates for: es
From translation svn revision: 22446

Authors:
Juan C. buno <oprisniki@xxxxxxxxx>
Noelia Martinez <nrm1977@xxxxxxxxx>

Stats:
19 13 source/locale/es/LC_MESSAGES/nvda.po
47 0 source/locale/es/symbols.dic
10 1 user_docs/es/changes.t2t
5 3 user_docs/es/userGuide.t2t
4 files changed, 81 insertions(+), 17 deletions(-)

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/b0eb47292efc/
Changeset: b0eb47292efc
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:14+00:00
Summary: L10n updates for: fi
From translation svn revision: 22446

Authors:
Jani Kinnunen <jani.kinnunen@xxxxxxxxxx>
Isak Sand <isak.sand@xxxxxxxxx>

Stats:
16 11 source/locale/fi/LC_MESSAGES/nvda.po
10 1 user_docs/fi/changes.t2t
5 3 user_docs/fi/userGuide.t2t
3 files changed, 31 insertions(+), 15 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/b33a141ade45/
Changeset: b33a141ade45
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:16+00:00
Summary: L10n updates for: fr
From translation svn revision: 22446

Authors:
Michel such <michel.such@xxxxxxx>
Patrick ZAJDA <patrick@xxxxxxxx>
Remy Ruiz <remyruiz@xxxxxxxxx>
Bachir Benanou <ben_bach@xxxxxxxx>

Stats:
20 15 source/locale/fr/LC_MESSAGES/nvda.po
10 1 user_docs/fr/changes.t2t
2 files changed, 30 insertions(+), 16 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/1daedcb49e80/
Changeset: 1daedcb49e80
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:21+00:00
Summary: L10n updates for: gl
From translation svn revision: 22446

Authors:
Juan C. buno <oprisniki@xxxxxxxxx>

Stats:
18 12 source/locale/gl/LC_MESSAGES/nvda.po
47 0 source/locale/gl/symbols.dic
9 1 user_docs/gl/changes.t2t
5 3 user_docs/gl/userGuide.t2t
4 files changed, 79 insertions(+), 16 deletions(-)

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/976668777809/
Changeset: 976668777809
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:26+00:00
Summary: L10n updates for: hr
From translation svn revision: 22446

Authors:
Hrvoje Katic <hrvojekatic@xxxxxxxxx>
Zvonimir Stanecic <zvonimirek222@xxxxxxxxxx>
Mario Percinic <mario.percinic@xxxxxxxxx>

Stats:
18 12 source/locale/hr/LC_MESSAGES/nvda.po
47 0 source/locale/hr/symbols.dic
10 0 user_docs/hr/changes.t2t
3 files changed, 75 insertions(+), 12 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/2044b81c7a0c/
Changeset: 2044b81c7a0c
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:31+00:00
Summary: L10n updates for: it
From translation svn revision: 22446

Authors:
Simone Dal Maso <simone.dalmaso@xxxxxxxxx>
Alberto Buffolino <a.buffolino@xxxxxxxxx>

Stats:
17 10 source/locale/it/LC_MESSAGES/nvda.po
12 0 user_docs/it/changes.t2t
2 files changed, 29 insertions(+), 10 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/c871733420b2/
Changeset: c871733420b2
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:34+00:00
Summary: L10n updates for: ja
From translation svn revision: 22446

Authors:
Takuya Nishimoto <nishimotz@xxxxxxxxx>
Minako Nonogaki <minakonono3519@xxxxxxxxx>

Stats:
347 344 source/locale/ja/LC_MESSAGES/nvda.po
92 1 source/locale/ja/symbols.dic
111 111 user_docs/ja/userGuide.t2t
3 files changed, 550 insertions(+), 456 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/d2122fffafec/
Changeset: d2122fffafec
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:35+00:00
Summary: L10n updates for: kn
From translation svn revision: 22446

Authors:
Siddalingeshwar Ingalagi <ingalagisiddu@xxxxxxxxx>

Stats:
52 1 source/locale/kn/characterDescriptions.dic
117 0 source/locale/kn/symbols.dic
2 files changed, 169 insertions(+), 1 deletion(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/98e59cd6954b/
Changeset: 98e59cd6954b
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:37+00:00
Summary: L10n updates for: ko
From translation svn revision: 22446

Authors:
Joseph Lee <joseph.lee22590@xxxxxxxxx>
Chang-Hoan Jang <462356@xxxxxxxxx>

Stats:
69 61 source/locale/ko/LC_MESSAGES/nvda.po
16 1 user_docs/ko/changes.t2t
7 5 user_docs/ko/userGuide.t2t
3 files changed, 92 insertions(+), 67 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/06227d084cbf/
Changeset: 06227d084cbf
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:40+00:00
Summary: L10n updates for: ne
From translation svn revision: 22446

Authors:
him Prasad Gautam <drishtibachak@xxxxxxxxx>

Stats:
23 18 source/locale/ne/LC_MESSAGES/nvda.po
1 1 source/locale/ne/characterDescriptions.dic
78 7 user_docs/ne/userGuide.t2t
3 files changed, 102 insertions(+), 26 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/af27009f26da/
Changeset: af27009f26da
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:43+00:00
Summary: L10n updates for: nl
From translation svn revision: 22446

Authors:
Bram Duvigneau <bram@xxxxxxxx>
Bart Simons <bart@xxxxxxxxxxxxx>
A Campen <a.campen@xxxxxx>
Leonard de Ruijter <mail@xxxxxxxxxxxxx>

Stats:
20 13 source/locale/nl/LC_MESSAGES/nvda.po
6 4 user_docs/nl/userGuide.t2t
2 files changed, 26 insertions(+), 17 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/c27281863d0d/
Changeset: c27281863d0d
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:45+00:00
Summary: L10n updates for: pl
From translation svn revision: 22446

Authors:
Grzegorz Zlotowicz <grzezlo@xxxxx>
Hubert Meyer <killer@xxxxxxxxxxxx>

Stats:
16 10 source/locale/pl/LC_MESSAGES/nvda.po
1 file changed, 16 insertions(+), 10 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/c785e1967c18/
Changeset: c785e1967c18
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:47+00:00
Summary: L10n updates for: pt_BR
From translation svn revision: 22446

Authors:
Cleverson Casarin Uliana <clcaul@xxxxxxxx>
Marlin Rodrigues <marlincgrodrigues@xxxxxxxxxxxx>

Stats:
17 11 source/locale/pt_BR/LC_MESSAGES/nvda.po
1 file changed, 17 insertions(+), 11 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/46ebf82bba10/
Changeset: 46ebf82bba10
Branch: None
User: CommitBot
Date: 2015-07-16 09:18:52+00:00
Summary: L10n updates for: ru
From translation svn revision: 22446

Authors:
Ruslan Kolodyazhni <eye0@xxxxxxxxxx>
Ruslan Shukhanov <ru2020slan@xxxxxxxxx>
Beqa Gozalishvili <beqaprogger@xxxxxxxxx>
Aleksandr Lin'kov <kvark128@xxxxxxxxx>
alexander Yashin <a.jaszyn@xxxxx>

Stats:
97 87 source/locale/ru/LC_MESSAGES/nvda.po
47 6 source/locale/ru/symbols.dic
10 1 user_docs/ru/changes.t2t
15 13 user_docs/ru/userGuide.t2t
4 files changed, 169 insertions(+), 107 deletions(-)

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/ddb481c35a7b/
Changeset: ddb481c35a7b
Branch: None
User: CommitBot
Date: 2015-07-16 09:19:00+00:00
Summary: L10n updates for: ta
From translation svn revision: 22446

Authors:
Dinakar T.D. <td.dinkar@xxxxxxxxx>

Stats:
357 663 source/locale/ta/LC_MESSAGES/nvda.po
1 file changed, 357 insertions(+), 663 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/05cdccdfed0a/
Changeset: 05cdccdfed0a
Branch: None
User: CommitBot
Date: 2015-07-16 09:19:09+00:00
Summary: L10n updates for: zh_TW
From translation svn revision: 22446

Authors:
wangjanli@xxxxxxxxx
maro.zhang@xxxxxxxxx
Aaron Wu <waaron2000@xxxxxxxxx>
Victor Cai <surfer0627@xxxxxxxxx>

Stats:
19 12 source/locale/zh_TW/LC_MESSAGES/nvda.po
409 409 source/locale/zh_TW/characterDescriptions.dic
14 14 source/locale/zh_TW/symbols.dic
1805 160 user_docs/zh_TW/changes.t2t
4 files changed, 2247 insertions(+), 595 deletions(-)

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/5502b7440e46/
Changeset: 5502b7440e46
Branch: None
User: jteh
Date: 2015-07-16 09:21:05+00:00
Summary: Update translations.

From translation svn revision: 22446

Affected #: 57 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/9212d700e722/
Changeset: 9212d700e722
Branch: None
User: mdcurran
Date: 2015-07-19 23:15:02+00:00
Summary: browseMode: add missing import. Allows automatic focus mode on
caret move to work again. Fixes #5228

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/f0a4cb5db7cd/
Changeset: f0a4cb5db7cd
Branch: None
User: jteh
Date: 2015-07-20 07:35:34+00:00
Summary: When an application is responding slowly and you switch away from
that application, NVDA is now much more responsive in other applications in
most cases.

This is done by filtering out events from background windows in most cases to
avoid freezes when a background app is unresponsive. One hard-coded exception
is when background progress bar reporting is enabled, in which case background
valueChange events are allowed.
To facilitate this, eventHandler.shouldAcceptEvent was introduced.
eventHandler.requestEvents was also added to request particular events that are
blocked by default; e.g. show events from a specific control or certain events
even when in the background.
Fixes #3831.

Affected #: 6 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/ba07af3a49ce/
Changeset: ba07af3a49ce
Branch: None
User: jteh
Date: 2015-07-20 07:51:49+00:00
Summary: Windows 10 Toast notifications are now reported as expected.

Fixes #5136.

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/beb693fea4b7/
Changeset: beb693fea4b7
Branch: None
User: mdcurran
Date: 2015-07-23 06:25:50+00:00
Summary: UIA's findOverlayClasses: improve performance in Windows Explorer
etc by tightening up checks for Edge using UIA's frameworkID before checking
parent.

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/27c050e6f7a4/
Changeset: 27c050e6f7a4
Branch: None
User: mdcurran
Date: 2015-07-23 06:27:25+00:00
Summary: Windows 10 searchUI appModule: only automatically announce search
suggestions that are in Edge lists. Stops more accidental canceling speech when
opening the Start Screen.

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/062cd66e5b22/
Changeset: 062cd66e5b22
Branch: None
User: mdcurran
Date: 2015-07-23 07:15:14+00:00
Summary: Several fixes to browseMode and base TreeInterceptor to fix
regressions when focusing an Excel worksheet. Fixes #5238.

* Base TreeInterceptor: remove a possibly accidentally committed implementation
of event_gainFocus. It is simply not needed, and was causing Excel focus not to
work when alt+tabbing back. Fixes #5238
* BrowseModeDocument._activatePosition: make the info argument optional, and if
not provided make it create a TextInfo for position_caret.
* BrowseMode: move script_activatePosition from BrowseModeDocument into base
BrowseMode as that is where it is bound. Also change its implementation to just
call _activatePosition and let that method handle TextInfos etc entirely itself.

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/27f96bda95a5/
Changeset: 27f96bda95a5
Branch: None
User: josephsl
Date: 2015-07-24 06:41:28+00:00
Summary: Rather than a single i18nName attribute,
synthDriverHandler.SynthSetting now has separate displayNameWithAccelerator and
displayName attributes to avoid reporting of the accelerator in the synth
settings ring in some languages.

Fixes #5185.

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/18b1a87d3e77/
Changeset: 18b1a87d3e77
Branch: None
User: jteh
Date: 2015-07-27 01:11:22+00:00
Summary: miscDeps: Make executable files executable in the repository.

This should make life easier for those using Cygwin git.
Fixes #4456.

Affected #: 0 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/9d6ed1372a8f/
Changeset: 9d6ed1372a8f
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:18+00:00
Summary: L10n updates for: ar
From translation svn revision: 22657

Authors:
Fatma Mehanna <fatma.mehanna@xxxxxxxxx>
Shaimaa Ibrahim <shamse1@xxxxxxxxx>

Stats:
19 1 user_docs/ar/changes.t2t
48 6 user_docs/ar/userGuide.t2t
2 files changed, 67 insertions(+), 7 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/5cb2c15d8862/
Changeset: 5cb2c15d8862
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:23+00:00
Summary: L10n updates for: ca
From translation svn revision: 22657

Authors:
Ruben Alcaraz <ruben.hangar1.8@xxxxxxxxx>
Dr. Mireia Ribera <mireia.ribera@xxxxxxxxx>
Santi Moese <santispock@xxxxxxxxx>
Marina Salse Rovira <salse@xxxxxx>

Stats:
58 1 source/locale/ca/LC_MESSAGES/nvda.po
1 file changed, 58 insertions(+), 1 deletion(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/886bbd438ee6/
Changeset: 886bbd438ee6
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:26+00:00
Summary: L10n updates for: da
From translation svn revision: 22657

Authors:
Daniel K. Gartmann <kontakt@xxxxxxx>
Nicolai Svendsen <chojiro1990@xxxxxxxxx>
bue@xxxxxxxxxxxxxxxxxx

Stats:
53 2 source/locale/da/LC_MESSAGES/nvda.po
4 0 source/locale/da/gestures.ini
163 117 source/locale/da/symbols.dic
32 0 user_docs/da/changes.t2t
49 7 user_docs/da/userGuide.t2t
5 files changed, 301 insertions(+), 126 deletions(-)

Affected #: 5 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/fbf564139d85/
Changeset: fbf564139d85
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:28+00:00
Summary: L10n updates for: de
From translation svn revision: 22657

Authors:
Bernd Dorer <bdorer@xxxxxxxxxxx>
David Parduhn <xkill85@xxxxxxx>
Rene Linke <rene.linke@xxxxxxxxxx>

Stats:
89 2 source/locale/de/LC_MESSAGES/nvda.po
23 2 user_docs/de/changes.t2t
42 2 user_docs/de/userGuide.t2t
3 files changed, 154 insertions(+), 6 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/43cb05b9bc94/
Changeset: 43cb05b9bc94
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:33+00:00
Summary: L10n updates for: es
From translation svn revision: 22657

Authors:
Juan C. buno <oprisniki@xxxxxxxxx>
Noelia Martinez <nrm1977@xxxxxxxxx>

Stats:
53 2 source/locale/es/LC_MESSAGES/nvda.po
1 1 source/locale/es/symbols.dic
19 0 user_docs/es/changes.t2t
56 16 user_docs/es/userGuide.t2t
4 files changed, 129 insertions(+), 19 deletions(-)

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/58f3632e9a8f/
Changeset: 58f3632e9a8f
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:35+00:00
Summary: L10n updates for: fa
From translation svn revision: 22657

Authors:
Ali Aslani <aslani.ali@xxxxxxxxx>
Mohammadreza Rashad <mohammadreza5712@xxxxxxxxx>

Stats:
5 3 user_docs/fa/userGuide.t2t
1 file changed, 5 insertions(+), 3 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/fe5116f59fea/
Changeset: fe5116f59fea
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:37+00:00
Summary: L10n updates for: fi
From translation svn revision: 22657

Authors:
Jani Kinnunen <jani.kinnunen@xxxxxxxxxx>
Isak Sand <isak.sand@xxxxxxxxx>

Stats:
55 4 source/locale/fi/LC_MESSAGES/nvda.po
45 2 source/locale/fi/symbols.dic
20 0 user_docs/fi/changes.t2t
46 7 user_docs/fi/userGuide.t2t
4 files changed, 166 insertions(+), 13 deletions(-)

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/38e2fde9464b/
Changeset: 38e2fde9464b
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:39+00:00
Summary: L10n updates for: fr
From translation svn revision: 22657

Authors:
Michel such <michel.such@xxxxxxx>
Patrick ZAJDA <patrick@xxxxxxxx>
Remy Ruiz <remyruiz@xxxxxxxxx>
Bachir Benanou <ben_bach@xxxxxxxx>

Stats:
49 2 source/locale/fr/LC_MESSAGES/nvda.po
16 0 user_docs/fr/changes.t2t
47 5 user_docs/fr/userGuide.t2t
3 files changed, 112 insertions(+), 7 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/829f1cf5d62d/
Changeset: 829f1cf5d62d
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:42+00:00
Summary: L10n updates for: gl
From translation svn revision: 22657

Authors:
Juan C. buno <oprisniki@xxxxxxxxx>

Stats:
53 2 source/locale/gl/LC_MESSAGES/nvda.po
20 0 user_docs/gl/changes.t2t
126 86 user_docs/gl/userGuide.t2t
3 files changed, 199 insertions(+), 88 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/5d1f8b440aa5/
Changeset: 5d1f8b440aa5
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:45+00:00
Summary: L10n updates for: hr
From translation svn revision: 22657

Authors:
Hrvoje Katic <hrvojekatic@xxxxxxxxx>
Zvonimir Stanecic <zvonimirek222@xxxxxxxxxx>
Mario Percinic <mario.percinic@xxxxxxxxx>

Stats:
49 2 source/locale/hr/LC_MESSAGES/nvda.po
26 7 user_docs/hr/changes.t2t
4 2 user_docs/hr/userGuide.t2t
3 files changed, 79 insertions(+), 11 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/0927f2246d5f/
Changeset: 0927f2246d5f
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:47+00:00
Summary: L10n updates for: hu
From translation svn revision: 22657

Authors:
Aron OcsvAri <oaron@xxxxxxx>

Stats:
67 10 source/locale/hu/LC_MESSAGES/nvda.po
50 0 source/locale/hu/symbols.dic
2 files changed, 117 insertions(+), 10 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/31f9f2f3ae48/
Changeset: 31f9f2f3ae48
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:53+00:00
Summary: L10n updates for: ja
From translation svn revision: 22657

Authors:
Takuya Nishimoto <nishimotz@xxxxxxxxx>
Minako Nonogaki <minakonono3519@xxxxxxxxx>

Stats:
53 3 source/locale/ja/LC_MESSAGES/nvda.po
49 7 user_docs/ja/userGuide.t2t
2 files changed, 102 insertions(+), 10 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/e1d64baaf427/
Changeset: e1d64baaf427
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:54+00:00
Summary: L10n updates for: kn
From translation svn revision: 22657

Authors:
Siddalingeshwar Ingalagi <ingalagisiddu@xxxxxxxxx>

Stats:
3486 1689 source/locale/kn/LC_MESSAGES/nvda.po
52 5 source/locale/kn/symbols.dic
2 files changed, 3538 insertions(+), 1694 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/7f953d8fe9d2/
Changeset: 7f953d8fe9d2
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:56+00:00
Summary: L10n updates for: ko
From translation svn revision: 22657

Authors:
Joseph Lee <joseph.lee22590@xxxxxxxxx>
Chang-Hoan Jang <462356@xxxxxxxxx>

Stats:
50 3 source/locale/ko/LC_MESSAGES/nvda.po
14 1 user_docs/ko/changes.t2t
35 0 user_docs/ko/userGuide.t2t
3 files changed, 99 insertions(+), 4 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/1b15288d3246/
Changeset: 1b15288d3246
Branch: None
User: CommitBot
Date: 2015-07-27 01:31:59+00:00
Summary: L10n updates for: ne
From translation svn revision: 22657

Authors:
him Prasad Gautam <drishtibachak@xxxxxxxxx>

Stats:
51 30 source/locale/ne/LC_MESSAGES/nvda.po
48 8 user_docs/ne/userGuide.t2t
2 files changed, 99 insertions(+), 38 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/198152bc0fec/
Changeset: 198152bc0fec
Branch: None
User: CommitBot
Date: 2015-07-27 01:32:00+00:00
Summary: L10n updates for: nl
From translation svn revision: 22657

Authors:
Bram Duvigneau <bram@xxxxxxxx>
Bart Simons <bart@xxxxxxxxxxxxx>
A Campen <a.campen@xxxxxx>
Leonard de Ruijter <mail@xxxxxxxxxxxxx>

Stats:
42 1 user_docs/nl/userGuide.t2t
1 file changed, 42 insertions(+), 1 deletion(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/944eea6a0a42/
Changeset: 944eea6a0a42
Branch: None
User: CommitBot
Date: 2015-07-27 01:32:04+00:00
Summary: L10n updates for: pt_BR
From translation svn revision: 22657

Authors:
Cleverson Casarin Uliana <clcaul@xxxxxxxx>
Marlin Rodrigues <marlincgrodrigues@xxxxxxxxxxxx>

Stats:
109 59 source/locale/pt_BR/LC_MESSAGES/nvda.po
1 file changed, 109 insertions(+), 59 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/f1fa92bc27bd/
Changeset: f1fa92bc27bd
Branch: None
User: CommitBot
Date: 2015-07-27 01:32:09+00:00
Summary: L10n updates for: ru
From translation svn revision: 22657

Authors:
Ruslan Kolodyazhni <eye0@xxxxxxxxxx>
Ruslan Shukhanov <ru2020slan@xxxxxxxxx>
Beqa Gozalishvili <beqaprogger@xxxxxxxxx>
Aleksandr Lin'kov <kvark128@xxxxxxxxx>
alexander Yashin <a.jaszyn@xxxxx>

Stats:
75 267 source/locale/ru/LC_MESSAGES/nvda.po
20 0 user_docs/ru/changes.t2t
43 3 user_docs/ru/userGuide.t2t
3 files changed, 138 insertions(+), 270 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/6e2b2a405d13/
Changeset: 6e2b2a405d13
Branch: None
User: CommitBot
Date: 2015-07-27 01:32:11+00:00
Summary: L10n updates for: sk
From translation svn revision: 22657

Authors:
Ondrej Rosik <ondrej.rosik@xxxxxxxxx>
Peter Vagner <peter.v@xxxxxxxxxxx>

Stats:
68 12 source/locale/sk/LC_MESSAGES/nvda.po
30 0 user_docs/sk/changes.t2t
49 7 user_docs/sk/userGuide.t2t
3 files changed, 147 insertions(+), 19 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/811157469c00/
Changeset: 811157469c00
Branch: None
User: CommitBot
Date: 2015-07-27 01:32:14+00:00
Summary: L10n updates for: sr
From translation svn revision: 22657

Authors:
Nikola Jovic <wwenikola123@xxxxxxxxx>
Janko Valencik <janko.valencik@xxxxxxxxxxxxx>
Zvonimir <zvonimirek222@xxxxxxxxxx>
Danijela Popovic <vlajna95@xxxxxxxxx>

Stats:
75 17 source/locale/sr/LC_MESSAGES/nvda.po
1 file changed, 75 insertions(+), 17 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/9e2d38a3e0cd/
Changeset: 9e2d38a3e0cd
Branch: None
User: CommitBot
Date: 2015-07-27 01:32:17+00:00
Summary: L10n updates for: ta
From translation svn revision: 22657

Authors:
Dinakar T.D. <td.dinkar@xxxxxxxxx>

Stats:
51 2 source/locale/ta/LC_MESSAGES/nvda.po
53 11 user_docs/ta/userGuide.t2t
2 files changed, 104 insertions(+), 13 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/ed8aabdbe234/
Changeset: ed8aabdbe234
Branch: None
User: CommitBot
Date: 2015-07-27 01:32:23+00:00
Summary: L10n updates for: zh_CN
From translation svn revision: 22657

Authors:
vgjh2005@xxxxxxxxx

Stats:
77 34 source/locale/zh_CN/LC_MESSAGES/nvda.po
66 5 user_docs/zh_CN/userGuide.t2t
2 files changed, 143 insertions(+), 39 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/4c5d894bab9d/
Changeset: 4c5d894bab9d
Branch: None
User: CommitBot
Date: 2015-07-27 01:32:26+00:00
Summary: L10n updates for: zh_TW
From translation svn revision: 22657

Authors:
wangjanli@xxxxxxxxx
maro.zhang@xxxxxxxxx
Aaron Wu <waaron2000@xxxxxxxxx>
Victor Cai <surfer0627@xxxxxxxxx>

Stats:
48 49 user_docs/zh_TW/userGuide.t2t
1 file changed, 48 insertions(+), 49 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/6eeb8c78d598/
Changeset: 6eeb8c78d598
Branch: None
User: jteh
Date: 2015-07-27 01:36:04+00:00
Summary: Update translations.

From translation svn revision: 22657

Affected #: 54 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/29595b7f5284/
Changeset: 29595b7f5284
Branch: None
User: jteh
Date: 2015-07-31 02:45:31+00:00
Summary: Merge branch 'win10edge'

Fixes #5212, #5227.

Affected #: 13 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/3f53aef22e2d/
Changeset: 3f53aef22e2d
Branch: None
User: jteh
Date: 2015-07-31 02:54:55+00:00
Summary: Update What's New with changes from win10edge branch.

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/47bca331e9c9/
Changeset: 47bca331e9c9
Branch: None
User: jteh
Date: 2015-07-31 02:59:30+00:00
Summary: When attempting to install an earlier version of NVDA than is
currently installed, you will now be warned that this is not recommended and
that NVDA should be completely uninstalled before proceeding.

Fixes #5037.

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/ebb6eccad735/
Changeset: ebb6eccad735
Branch: None
User: jteh
Date: 2015-07-31 03:01:44+00:00
Summary: Disambiguate/add gettext contexts to some messages.

Specifically:
* Differentiate "column" for the role and the chart type.
* Differentiate "Tools" for the NVDA menu (which requires an accelerator) and
the script category.
* Differentiate "User Guide" for the NVDA menu (which requires an accelerator)
and the Windows Start Menu.

Fixes #5100.

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/4d21ecddc6ce/
Changeset: 4d21ecddc6ce
Branch: None
User: mdcurran
Date: 2015-07-31 03:07:09+00:00
Summary: The Windows 10 lock screen can now be dismissed using a touch
screen.

Add a lockApp appModule for the Win 10 lock screen, so that it is possible to
touch explore to the lock screen container itself thus then allowing dismissal
of the screen with a double tap.
Fixes #5220.

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/89dd4b75289c/
Changeset: 89dd4b75289c
Branch: None
User: jteh
Date: 2015-07-31 03:13:50+00:00
Summary: In Windows 7 and later, text is no longer garbled when typing in
certain applications such as Wordpad and Skype with a braille display.

This is related to Rich Edit controls. It occurred because in order to get
formatting information in these controls, we have to move the selection (and
thus the cursor), which obviously causes problems if typed characters are
arriving during this process.
To fix this, we can use ITextDocument. We previously disabled this due to poor
performance, but it seems this is fixed in Windows 7 and later. Therefore, use
ITextDocument in Windows 7 and later.
Also, the previous code for detecting links in ITextDocument still moved the
selection. However, ITextDocument provides for another way to detect links
which doesn't do this.
Fixes #4291.

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/317b19c5448b/
Changeset: 317b19c5448b
Branch: None
User: mdcurran
Date: 2015-07-31 23:41:52+00:00
Summary: Enable Edge support for WebView (i.e. Cortana content.

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/11fc8d152c3f/
Changeset: 11fc8d152c3f
Branch: None
User: jteh
Date: 2015-08-03 07:18:26+00:00
Summary: What's New: Add release blurb and other minor tweaks.

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/d52047502d89/
Changeset: d52047502d89
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:02+00:00
Summary: L10n updates for: an
From translation svn revision: 22826

Authors:
Jorge Perez <jorgtum@xxxxxxxxx>

Stats:
87 1 source/locale/an/LC_MESSAGES/nvda.po
23 0 user_docs/an/changes.t2t
44 4 user_docs/an/userGuide.t2t
3 files changed, 154 insertions(+), 5 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/21209f206b2f/
Changeset: 21209f206b2f
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:05+00:00
Summary: L10n updates for: ar
From translation svn revision: 22826

Authors:
Fatma Mehanna <fatma.mehanna@xxxxxxxxx>
Shaimaa Ibrahim <shamse1@xxxxxxxxx>

Stats:
375 341 source/locale/ar/LC_MESSAGES/nvda.po
2 0 user_docs/ar/changes.t2t
2 files changed, 377 insertions(+), 341 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/4cddf0e5e98b/
Changeset: 4cddf0e5e98b
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:11+00:00
Summary: L10n updates for: cs
From translation svn revision: 22826

Authors:
Martina Letochova <letochova@xxxxxxxxx>

Stats:
104 12 source/locale/cs/LC_MESSAGES/nvda.po
1 file changed, 104 insertions(+), 12 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/e6a36755b88f/
Changeset: e6a36755b88f
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:16+00:00
Summary: L10n updates for: el
From translation svn revision: 22826

Authors:
Irene Nakas <irnakas@xxxxxxxxx>
Nikos Demetriou <nikosdemetriou@xxxxxxxxxxxxxx>
access@xxxxxxxxxxxx

Stats:
92 4 source/locale/el/LC_MESSAGES/nvda.po
1 file changed, 92 insertions(+), 4 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/5bca17adbce1/
Changeset: 5bca17adbce1
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:20+00:00
Summary: L10n updates for: es
From translation svn revision: 22826

Authors:
Juan C. buno <oprisniki@xxxxxxxxx>
Noelia Martinez <nrm1977@xxxxxxxxx>

Stats:
37 2 source/locale/es/LC_MESSAGES/nvda.po
3 0 user_docs/es/changes.t2t
2 files changed, 40 insertions(+), 2 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/d1b3c11d8b9f/
Changeset: d1b3c11d8b9f
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:21+00:00
Summary: L10n updates for: fa
From translation svn revision: 22826

Authors:
Ali Aslani <aslani.ali@xxxxxxxxx>
Mohammadreza Rashad <mohammadreza5712@xxxxxxxxx>

Stats:
45 5 user_docs/fa/userGuide.t2t
1 file changed, 45 insertions(+), 5 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/00d0fb1ed369/
Changeset: 00d0fb1ed369
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:24+00:00
Summary: L10n updates for: fi
From translation svn revision: 22826

Authors:
Jani Kinnunen <jani.kinnunen@xxxxxxxxxx>
Isak Sand <isak.sand@xxxxxxxxx>

Stats:
42 7 source/locale/fi/LC_MESSAGES/nvda.po
8 8 source/locale/fi/symbols.dic
5 2 user_docs/fi/changes.t2t
2 2 user_docs/fi/userGuide.t2t
4 files changed, 57 insertions(+), 19 deletions(-)

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/e851c63d7dae/
Changeset: e851c63d7dae
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:26+00:00
Summary: L10n updates for: fr
From translation svn revision: 22826

Authors:
Michel such <michel.such@xxxxxxx>
Patrick ZAJDA <patrick@xxxxxxxx>
Remy Ruiz <remyruiz@xxxxxxxxx>
Bachir Benanou <ben_bach@xxxxxxxx>

Stats:
37 2 source/locale/fr/LC_MESSAGES/nvda.po
3 0 user_docs/fr/changes.t2t
2 files changed, 40 insertions(+), 2 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/1cc360c4b02a/
Changeset: 1cc360c4b02a
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:27+00:00
Summary: L10n updates for: ga
From translation svn revision: 22826

Authors:
Cearbhall OMeadhra <cearbhall.omeadhra@xxxxxxx>
Ronan McGuirk <ronan.p.mcguirk@xxxxxxxxx>
Kevin Scannell <kscanne@xxxxxxxxx>

Stats:
88 59 source/locale/ga/LC_MESSAGES/nvda.po
1 file changed, 88 insertions(+), 59 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/59c96c809390/
Changeset: 59c96c809390
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:29+00:00
Summary: L10n updates for: gl
From translation svn revision: 22826

Authors:
Juan C. buno <oprisniki@xxxxxxxxx>

Stats:
37 2 source/locale/gl/LC_MESSAGES/nvda.po
3 0 user_docs/gl/changes.t2t
2 files changed, 40 insertions(+), 2 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/1385e0574237/
Changeset: 1385e0574237
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:32+00:00
Summary: L10n updates for: hr
From translation svn revision: 22826

Authors:
Hrvoje Katic <hrvojekatic@xxxxxxxxx>
Zvonimir Stanecic <zvonimirek222@xxxxxxxxxx>
Mario Percinic <mario.percinic@xxxxxxxxx>

Stats:
36 1 user_docs/hr/userGuide.t2t
1 file changed, 36 insertions(+), 1 deletion(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/fe0e8d36c2f2/
Changeset: fe0e8d36c2f2
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:37+00:00
Summary: L10n updates for: it
From translation svn revision: 22826

Authors:
Simone Dal Maso <simone.dalmaso@xxxxxxxxx>
Alberto Buffolino <a.buffolino@xxxxxxxxx>

Stats:
87 2 source/locale/it/LC_MESSAGES/nvda.po
1 file changed, 87 insertions(+), 2 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/eee5742286d2/
Changeset: eee5742286d2
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:39+00:00
Summary: L10n updates for: ja
From translation svn revision: 22826

Authors:
Takuya Nishimoto <nishimotz@xxxxxxxxx>
Minako Nonogaki <minakonono3519@xxxxxxxxx>

Stats:
37 2 source/locale/ja/LC_MESSAGES/nvda.po
1 file changed, 37 insertions(+), 2 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/f05df5ac3a40/
Changeset: f05df5ac3a40
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:42+00:00
Summary: L10n updates for: ko
From translation svn revision: 22826

Authors:
Joseph Lee <joseph.lee22590@xxxxxxxxx>
Chang-Hoan Jang <462356@xxxxxxxxx>

Stats:
50 6 source/locale/ko/LC_MESSAGES/nvda.po
1 0 user_docs/ko/changes.t2t
7 1 user_docs/ko/userGuide.t2t
3 files changed, 58 insertions(+), 7 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/15ce031dc5c4/
Changeset: 15ce031dc5c4
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:46+00:00
Summary: L10n updates for: nl
From translation svn revision: 22826

Authors:
Bram Duvigneau <bram@xxxxxxxx>
Bart Simons <bart@xxxxxxxxxxxxx>
A Campen <a.campen@xxxxxx>
Leonard de Ruijter <mail@xxxxxxxxxxxxx>

Stats:
90 3 source/locale/nl/LC_MESSAGES/nvda.po
3 4 user_docs/nl/userGuide.t2t
2 files changed, 93 insertions(+), 7 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/6e510c45ad80/
Changeset: 6e510c45ad80
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:48+00:00
Summary: L10n updates for: pl
From translation svn revision: 22826

Authors:
Grzegorz Zlotowicz <grzezlo@xxxxx>
Hubert Meyer <killer@xxxxxxxxxxxx>

Stats:
87 2 source/locale/pl/LC_MESSAGES/nvda.po
46 0 source/locale/pl/symbols.dic
35 1 user_docs/pl/changes.t2t
48 6 user_docs/pl/userGuide.t2t
4 files changed, 216 insertions(+), 9 deletions(-)

Affected #: 4 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/9f2b63db7ac0/
Changeset: 9f2b63db7ac0
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:51+00:00
Summary: L10n updates for: pt_BR
From translation svn revision: 22826

Authors:
Cleverson Casarin Uliana <clcaul@xxxxxxxx>
Marlin Rodrigues <marlincgrodrigues@xxxxxxxxxxxx>

Stats:
39 4 source/locale/pt_BR/LC_MESSAGES/nvda.po
26 0 user_docs/pt_BR/changes.t2t
7 1 user_docs/pt_BR/userGuide.t2t
3 files changed, 72 insertions(+), 5 deletions(-)

Affected #: 3 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/3df483dfe679/
Changeset: 3df483dfe679
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:55+00:00
Summary: L10n updates for: ru
From translation svn revision: 22826

Authors:
Ruslan Kolodyazhni <eye0@xxxxxxxxxx>
Ruslan Shukhanov <ru2020slan@xxxxxxxxx>
Beqa Gozalishvili <beqaprogger@xxxxxxxxx>
Aleksandr Lin'kov <kvark128@xxxxxxxxx>
alexander Yashin <a.jaszyn@xxxxx>

Stats:
37 2 source/locale/ru/LC_MESSAGES/nvda.po
5 2 user_docs/ru/changes.t2t
2 files changed, 42 insertions(+), 4 deletions(-)

Affected #: 2 files
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/dcb8ca5f4d4c/
Changeset: dcb8ca5f4d4c
Branch: None
User: CommitBot
Date: 2015-08-03 07:21:57+00:00
Summary: L10n updates for: sk
From translation svn revision: 22826

Authors:
Ondrej Rosik <ondrej.rosik@xxxxxxxxx>
Peter Vagner <peter.v@xxxxxxxxxxx>

Stats:
37 2 source/locale/sk/LC_MESSAGES/nvda.po
1 file changed, 37 insertions(+), 2 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/5219fea30174/
Changeset: 5219fea30174
Branch: None
User: CommitBot
Date: 2015-08-03 07:22:04+00:00
Summary: L10n updates for: ta
From translation svn revision: 22826

Authors:
Dinakar T.D. <td.dinkar@xxxxxxxxx>

Stats:
397 255 source/locale/ta/LC_MESSAGES/nvda.po
1 file changed, 397 insertions(+), 255 deletions(-)

Affected #: 1 file
Diff not available.

https://bitbucket.org/nvdaaddonteam/nvda/commits/fec692779324/
Changeset: fec692779324
Branch: master
User: jteh
Date: 2015-08-03 07:23:59+00:00
Summary: Update translations.

From translation svn revision: 22826

Affected #: 38 files
Diff not available.

Repository URL: https://bitbucket.org/nvdaaddonteam/nvda/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.

Other related posts: