[nvda-addons] Re: commit/nvda: josephsl: Merge branch 'master' into t4354

  • From: Bhavya shah <bhavya.shah125@xxxxxxxxx>
  • To: nvda-addons@xxxxxxxxxxxxx
  • Date: Mon, 27 Oct 2014 11:41:39 +0530

Thanks for that!

On 10/27/14, Noelia <nrm1977@xxxxxxxxx> wrote:
> Hi, thanks Joseph.
> I am not a NVDA commiter, that is, I can't modify the repo maintainer by
> NVAccess.
> However, I'm a member of NVDA add-on team, and can write to the NVDA
> repo forked at
> https://bitbucket.org/nvdaaddonteam/nvda
> I feel that your ticket (4354) is very interesting, and I recently
> started reading a book: Story of mathematics, writen by Boyer. I know
> that I will find symbols there (it's digitalized in Word), and I wanted
> to experiment with a branch for this ticket.
> So, if I can continue, the commits will be send to add-ons commits list,
> and the answers, to the add-on list.
> Thanks.
>
>
> El 27/10/2014 6:53, Bhavya shah escribió:
>> Hmm.
>> Interesting, I understood, thanks for the clarification.
>>
>> On 10/27/14, Joseph Lee <joseph.lee22590@xxxxxxxxx> wrote:
>>> Hi,
>>> Here's the story:
>>> As you pointed out, the below message would have been good for
>>> development
>>> list. However, I sent the below notice here, seeing that Noelia forked
>>> this
>>> branch from an older version of the master branch. You see, NV Access
>>> isn't
>>> the only one which hosts complete NVDA repository - there exists another
>>> repository at Bitbucket under the add-ons team account which mirrors the
>>> NV
>>> Access repository and is meant for developers with Bitbucket account to
>>> experiment with new features, like what Noelia is doing with ticket
>>> 4354.
>>> Besides this branch, we have other branches at the Bitbucket repo, and
>>> NV
>>> Access and other developers maintain NVDA repos at Bitbucket (I have one
>>> at
>>> Bitbucket which has additional branches such as post Windows XP builds
>>> and
>>> a
>>> branch with missing translator comments added).
>>> Unlike the NV Access repo, the Bitbucket NVDA add-ons team repo is
>>> updated
>>> on a semi-regular basis. Until a few weeks ago, when Mesar integrated
>>> various localizations into NVDA snapshots, he updated Bitbucket repo as
>>> well
>>> (he hasn't done that for a while). Thus after noticing that Noelia was
>>> using
>>> an older code, I updated the NVDA add-ons team repo to reflect latest
>>> changes from NV Access repo so Noelia can have a more recent code from
>>> which
>>> she can work on her branch (this affects my post Windows XP builds as
>>> well,
>>> as it was sort of forked from the add-ons team repo), hence the notice
>>> came
>>> to this list.
>>> Hope this helps (I hope I didn't confuse you; I'll answer other repo
>>> questions after the Tek Talk event).
>>> Cheers,
>>> Joseph
>>>
>>> -----Original Message-----
>>> From: nvda-addons-bounce@xxxxxxxxxxxxx
>>> [mailto:nvda-addons-bounce@xxxxxxxxxxxxx] On Behalf Of Bhavya shah
>>> Sent: Sunday, October 26, 2014 10:34 PM
>>> To: nvda-addons@xxxxxxxxxxxxx
>>> Subject: [nvda-addons] Re: commit/nvda: josephsl: Merge branch 'master'
>>> into
>>> t4354
>>>
>>> Hi,
>>> I am the original creator of the ticket, and have been following it.
>>> So, was this e-mail sent to the NVDA Addons list by mistake, I think
>>> it should have been sent to NVDA Devel.
>>> Or is #4354 being implemented as an addon and will not be implementd
>>> in NVDA itself?
>>> Am I missing anything?
>>>
>>> On 10/27/14, Joseph Lee <joseph.lee22590@xxxxxxxxx> wrote:
>>>> Hi Noelia,
>>>> I've merged latest master branch code from NV Access server, so you can
>>> work
>>>> from latest revisions.
>>>> Cheers,
>>>> Joseph
>>>>
>>>> -----Original Message-----
>>>> From: nvda-addons-commits-bounce@xxxxxxxxxxxxx
>>>> [mailto:nvda-addons-commits-bounce@xxxxxxxxxxxxx] On Behalf Of
>>>> commits-noreply@xxxxxxxxxxxxx
>>>> Sent: Sunday, October 26, 2014 3:28 PM
>>>> To: nvda-addons-commits@xxxxxxxxxxxxx
>>>> Subject: commit/nvda: josephsl: Merge branch 'master' into t4354
>>>>
>>>> 1 new commit in nvda:
>>>>
>>>> https://bitbucket.org/nvdaaddonteam/nvda/commits/ddd4982e4dfe/
>>>> Changeset:   ddd4982e4dfe
>>>> Branch:      t4354
>>>> User:        josephsl
>>>> Date:        2014-10-26 22:27:58+00:00
>>>> Summary:     Merge branch 'master' into t4354
>>>>
>>>> Affected #:  34 files
>>>>
>>>> diff --git a/contributors.txt b/contributors.txt
>>>> index 615b079..51d90a1 100644
>>>> --- a/contributors.txt
>>>> +++ b/contributors.txt
>>>> @@ -146,3 +146,6 @@ Dr. Mireia Ribera
>>>>   Ruben Alcaraz
>>>>   Nikos Demetriou
>>>>   Daniel Johansson
>>>> +Manish Agrawal
>>>> +Aaron Cannon
>>>> +derek riemer
>>>>
>>>> diff --git a/include/liblouis b/include/liblouis
>>>> index 1e1e758..5f9c03f 160000
>>>> --- a/include/liblouis
>>>> +++ b/include/liblouis
>>>> @@ -1 +1 @@
>>>> -Subproject commit 1e1e7587cfbc263b351644e52fdaf2684103d6c8
>>>> +Subproject commit 5f9c03f2a3478561deb6ae4798175094be8a26c2
>>>>
>>>> diff --git a/include/minhook b/include/minhook
>>>> index e21b54a..ed5b511 160000
>>>> --- a/include/minhook
>>>> +++ b/include/minhook
>>>> @@ -1 +1 @@
>>>> -Subproject commit e21b54a88190ca477ed73fb7ab24203dfaef28a0
>>>> +Subproject commit ed5b5119afb4127dd66905e2899c3265d8040aea
>>>>
>>>> diff --git a/miscDeps b/miscDeps
>>>> index 6fbd449..eee6560 160000
>>>> --- a/miscDeps
>>>> +++ b/miscDeps
>>>> @@ -1 +1 @@
>>>> -Subproject commit 6fbd44904c8debe4cf5a73e62a91ac8a00d1860c
>>>> +Subproject commit eee6560e4ae4de5455e94dfb99ba596f36bb21f5
>>>>
>>>> diff --git a/nvdaHelper/archBuild_sconscript
>>>> b/nvdaHelper/archBuild_sconscript
>>>> index 1c63dcc..fd45e07 100644
>>>> --- a/nvdaHelper/archBuild_sconscript
>>>> +++ b/nvdaHelper/archBuild_sconscript
>>>> @@ -26,6 +26,7 @@ Import(
>>>>   TARGET_ARCH=env['TARGET_ARCH']
>>>>   debug=env['nvdaHelperDebugFlags']
>>>>   release=env['release']
>>>> +signExec=env['signExec'] if env['certFile'] else None
>>>>
>>>>   #Some defines and includes for the environment
>>>>
>>> env.Append(CPPDEFINES=['UNICODE','_CRT_SECURE_NO_DEPRECATE',('LOGLEVEL','${n
>>> vdaHelperLogLevel}'),('_WIN32_WINNT','_WIN32_WINNT_WINXP')])
>>>> @@ -66,6 +67,8 @@ if TARGET_ARCH=='x86':
>>>>
>>>>   ia2RPCStubs=env.SConscript('ia2_sconscript')
>>>>   Export('ia2RPCStubs')
>>>> +if signExec:
>>>> +  env.AddPostAction(ia2RPCStubs[0],[signExec])
>>>>   env.Install(libInstallDir,ia2RPCStubs[0]) #proxy dll
>>>>   if TARGET_ARCH=='x86':
>>>>    env.Install(sourceTypelibDir,ia2RPCStubs[1]) #typelib
>>>> @@ -73,43 +76,65 @@ if TARGET_ARCH=='x86':
>>>>   if TARGET_ARCH=='x86':
>>>>    localLib=env.SConscript('local/sconscript')
>>>>    Export('localLib')
>>>> +  if signExec:
>>>> +          env.AddPostAction(localLib[0],[signExec])
>>>>    env.Install(libInstallDir,localLib)
>>>>
>>>>   clientLib=env.SConscript('client/sconscript')
>>>>   Export('clientLib')
>>>> +if signExec:
>>>> +  env.AddPostAction(clientLib[0],[signExec])
>>>>   env.Install(clientInstallDir,clientLib)
>>>>
>>>>   minHookLib=env.SConscript('minHook/sconscript')
>>>>   Export('minHookLib')
>>>> +if signExec:
>>>> +  env.AddPostAction(minHookLib[0],[signExec])
>>>>   env.Install(libInstallDir,minHookLib)
>>>>
>>>>   remoteLib=env.SConscript('remote/sconscript')
>>>>   Export('remoteLib')
>>>> +if signExec:
>>>> +  env.AddPostAction(remoteLib[0],[signExec])
>>>>   env.Install(libInstallDir,remoteLib)
>>>>
>>>>   if TARGET_ARCH=='x86_64':
>>>>    remoteLoaderProgram=env.SConscript('remoteLoader/sconscript')
>>>> +  if signExec:
>>>> +          env.AddPostAction(remoteLoaderProgram,[signExec])
>>>>    env.Install(libInstallDir,remoteLoaderProgram)
>>>>
>>>>   vbufBaseStaticLib=env.SConscript('vbufBase/sconscript')
>>>>   Export('vbufBaseStaticLib')
>>>>
>>>>
>>> adobeAcrobatVBufBackend=env.SConscript('vbufBackends/adobeAcrobat/sconscript
>>> ')
>>>> +if signExec:
>>>> +  env.AddPostAction(adobeAcrobatVBufBackend[0],[signExec])
>>>>   env.Install(libInstallDir,adobeAcrobatVBufBackend)
>>>>
>>>>
>>> adobeFlashVBufBackend=env.SConscript('vbufBackends/adobeFlash/sconscript')
>>>> +if signExec:
>>>> +  env.AddPostAction(adobeFlashVBufBackend[0],[signExec])
>>>>   env.Install(libInstallDir,adobeFlashVBufBackend)
>>>>
>>>>
>>> lotusNotesRichTextVBufBackend=env.SConscript('vbufBackends/lotusNotesRichTex
>>> t/sconscript')
>>>> +if signExec:
>>>> +  env.AddPostAction(lotusNotesRichTextVBufBackend[0],[signExec])
>>>>   env.Install(libInstallDir,lotusNotesRichTextVBufBackend)
>>>>
>>>>   geckoVBufBackend=env.SConscript('vbufBackends/gecko_ia2/sconscript')
>>>> +if signExec:
>>>> +  env.AddPostAction(geckoVBufBackend[0],[signExec])
>>>>   env.Install(libInstallDir,geckoVBufBackend)
>>>>
>>>>   mshtmlVBufBackend=env.SConscript('vbufBackends/mshtml/sconscript')
>>>> +if signExec:
>>>> +  env.AddPostAction(mshtmlVBufBackend[0],[signExec])
>>>>   env.Install(libInstallDir,mshtmlVBufBackend)
>>>>
>>>>   webKitVBufBackend=env.SConscript('vbufBackends/webKit/sconscript')
>>>> +if signExec:
>>>> +  env.AddPostAction(webKitVBufBackend[0],[signExec])
>>>>   env.Install(libInstallDir,webKitVBufBackend)
>>>>
>>>>   if TARGET_ARCH=='x86':
>>>>
>>>> diff --git a/nvdaHelper/building.txt b/nvdaHelper/building.txt
>>>> deleted file mode 100644
>>>> index 09cc81f..0000000
>>>> --- a/nvdaHelper/building.txt
>>>> +++ /dev/null
>>>> @@ -1,45 +0,0 @@
>>>> -Build Instructions
>>>> -
>>>> -Prerequisites:
>>>> -
>>>> -NVDAHelper needs The Microsoft Windows SDK, version 6.1 or later. You
>>>> can
>>>> find it here:
>>>> -http://msdn.microsoft.com/en-us/windows/bb980924.aspx
>>>> -
>>>> - The gecko_ia2 virtual buffer backend requires the IAccessible2 IDL,
>>>> version 1.2 or later. You can obtain it here:
>>>> -http://www.linuxfoundation.org/en/Accessibility/IAccessible2
>>>> -Download the merged IDL and copy it to ..\include\ia2\ia2.idl.
>>>> -
>>>> -The adobeAcrobat virtual buffer backend requires the Adobe Acrobat
>>>> accessibility IDL, version 9.1 or later. This can be found in the
>>>> client
>>>> files archive available from
>>>> http://www.adobe.com/devnet/acrobat/interapplication_communication.html
>>>> -The archive is named something like Acrobat_Accessibility_9.1.zip.
>>>> -Extract the AcrobatAccess.idl file into ..\include\AcrobatAccess.
>>>> -
>>>> -The apiHook module requires MinHook 1.1.0 or later:
>>>> http://www.codeproject.com/KB/winsdk/LibMinHook.aspx
>>>> -  * Download the source archive. The file name is something like
>>>> MinHook_110_src.zip depending on exact version.
>>>> -  * You will need an account on CodeProject to download from there.
>>>> -  * extract the source archive, and from it copy the libMinHook
>>> directory to
>>>> NVDA's source/include directory.
>>>> -
>>>> -minHook (and possibly in future nvdaHelper) depends on the Boost c++
>>>> library 1.42 or later:
>>>> -  * you can download the latest Windows installer from
>>>> http://www.boostpro.com/download
>>>> -  * On the components page of the installer, make sure to install all
>>> the
>>>> defaults (what ever is already checked), along with anything else you
>>>> may
>>>> wish to have for other projects.
>>>> -  * So far only boost headers are used, none of the pre-compiled
>>> libraries
>>>> are necessary for nvda/minHook.
>>>> -
>>>> -The NVDAHelper build is managed by the SCons build system, version
>>>> 1.3.0
>>> or
>>>> later: http://www.scons.org/
>>>> -
>>>> -Building the library:
>>>> -
>>>> -There is no need to use the MSVC environment command prompt when
>>> building,
>>>> as scons will locate what it needs automatically in any standard
>>>> environment.
>>>> -
>>>> -To build and install the library and all virtual buffer backends, open
>>>> a
>>>> command prompt, cd to the top-level directory of nvdaHelper and run the
>>>> command:
>>>> -scons install
>>>> -By default a version with debugging symbols will be generated. To
>>>> build
>>>> a
>>>> release version, provide release=1 on the command line when running
>>>> scons:
>>>> -scons install release=1
>>>> -
>>>> -Note that now both x86 and x64 versions of the libraries are
>>> automatically
>>>> built, there is no need to supply any target arch variables by default.
>>>> -
>>>> -However, if you specifically only want to build certain architectures,
>>> you
>>>> can provide a comma separated list of the required architectures to the
>>>> targetArchitectures variable on the commandline, like so:
>>>> -scons targetArchitectures=x86
>>>> -or
>>>> -scons targetArchitectures=x86_64
>>>> -or
>>>> -scons targetArchitectures=x86,x86_64
>>>> -
>>>> \ No newline at end of file
>>>>
>>>> diff --git a/nvdaHelper/contributors.txt b/nvdaHelper/contributors.txt
>>>> deleted file mode 100755
>>>> index 5c0a415..0000000
>>>> --- a/nvdaHelper/contributors.txt
>>>> +++ /dev/null
>>>> @@ -1,3 +0,0 @@
>>>> -Michael Curran <mick@xxxxxxxxxx>
>>>> -James Teh <jamie@xxxxxxxxxxx>
>>>> -Aleksey Sadovoy <lex@xxxxxx>
>>>>
>>>> diff --git a/nvdaHelper/liblouis/sconscript
>>>> b/nvdaHelper/liblouis/sconscript
>>>> index 72cdef4..1050407 100644
>>>> --- a/nvdaHelper/liblouis/sconscript
>>>> +++ b/nvdaHelper/liblouis/sconscript
>>>> @@ -24,7 +24,7 @@ louisRootDir = env.Dir("#include/liblouis")
>>>>   louisSourceDir = louisRootDir.Dir("liblouis")
>>>>   outDir = sourceDir.Dir("louis")
>>>>
>>>> -RE_AC_INIT = re.compile(r"^AC_INIT\((?P<name>.*), (?P<version>.*),
>>>> (?P<maintainer>.*)\)")
>>>> +RE_AC_INIT = re.compile(r"^AC_INIT\(\[(?P<package>.*)\],
>>>> \[(?P<version>.*)\], \[(?P<bugReport>.*)\], \[(?P<tarName>.*)\],
>>>> \[(?P<url>.*)\]\)")
>>>>   def getLouisVersion():
>>>>    # Get the version from configure.ac.
>>>>    with file(louisRootDir.File("configure.ac").abspath) as f:
>>>> @@ -50,6 +50,7 @@ sourceFiles = [
>>>>    "lou_translateString.c",
>>>>    "lou_backTranslateString.c",
>>>>    "wrappers.c",
>>>> +  "logging.c",
>>>>   ]
>>>>   objs = [env.Object("%s.obj" % f, louisSourceDir.File(f)) for f in
>>>> sourceFiles]
>>>>   louisLib = env.SharedLibrary("liblouis", objs + ["liblouis.def"])
>>>>
>>>> diff --git a/nvdaHelper/minHook/dllmain.cpp
>>>> b/nvdaHelper/minHook/dllmain.cpp
>>>> index 25d6823..07a9e41 100644
>>>> --- a/nvdaHelper/minHook/dllmain.cpp
>>>> +++ b/nvdaHelper/minHook/dllmain.cpp
>>>> @@ -18,7 +18,7 @@ http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
>>>>   BOOL WINAPI DllMain(HINSTANCE hModule,DWORD reason,LPVOID lpReserved)
>>>> {
>>>>    //Process exiting, we must clean up any pending hooks
>>>>    if(reason==DLL_PROCESS_DETACH&&lpReserved) {
>>>> -          if(MH_DisableAllHooks()!=MH_ERROR_NOT_INITIALIZED) {
>>>> +          if(MH_DisableHook(MH_ALL_HOOKS)!=MH_ERROR_NOT_INITIALIZED) {
>>>>                    //Give enough time for all hook functions to
>>> complete.
>>>>                    Sleep(250);
>>>>                    MH_Uninitialize();
>>>>
>>>> diff --git a/nvdaHelper/minHook/sconscript
>>>> b/nvdaHelper/minHook/sconscript
>>>> index 497a242..886b606 100644
>>>> --- a/nvdaHelper/minHook/sconscript
>>>> +++ b/nvdaHelper/minHook/sconscript
>>>> @@ -19,10 +19,11 @@ sourceFiles=[
>>>>
>>>>
>>> objFiles=[env.Object('_minHook_%s.obj'%x.replace('/','_'),minhookPath.File('
>>> src/%s'%x))
>>>> for x in sourceFiles]
>>>>   objFiles.append('dllmain.cpp')
>>>> +resFile=env.RES('_minHook',minhookPath.File('dll_resources/minHook.rc'))
>>>>
>>>>   minHookLib=env.SharedLibrary(
>>>>    target='minHook',
>>>> -  source=objFiles+[minhookPath.File('dll_resources/minHook.def')],
>>>> +
>>> source=objFiles+[resFile,minhookPath.File('dll_resources/minHook.def')],
>>>>   )
>>>>
>>>>   Return('minHookLib')
>>>>
>>>> diff --git a/nvdaHelper/remote/apiHook.cpp
>>>> b/nvdaHelper/remote/apiHook.cpp
>>>> index 0a3430b..4c9848e 100644
>>>> --- a/nvdaHelper/remote/apiHook.cpp
>>>> +++ b/nvdaHelper/remote/apiHook.cpp
>>>> @@ -39,8 +39,6 @@ typedef MH_STATUS(WINAPI
>>>> *MH_Uninitialize_funcType)();
>>>>   typedef MH_STATUS(WINAPI
>>>> *MH_CreateHook_funcType)(void*,void*,void**);
>>>>   typedef MH_STATUS(WINAPI *MH_EnableHook_funcType)(void*);
>>>>   typedef MH_STATUS(WINAPI *MH_DisableHook_funcType)(void*);
>>>> -typedef MH_STATUS(*MH_EnableAllHooks_funcType)();
>>>> -typedef MH_STATUS(*MH_DisableAllHooks_funcType)();
>>>>
>>>>   #define defMHFP(funcName) funcName##_funcType funcName##_fp=NULL
>>>>
>>>> @@ -55,8 +53,8 @@ typedef MH_STATUS(*MH_DisableAllHooks_funcType)();
>>>>   defMHFP(MH_Initialize);
>>>>   defMHFP(MH_Uninitialize);
>>>>   defMHFP(MH_CreateHook);
>>>> -defMHFP(MH_EnableAllHooks);
>>>> -defMHFP(MH_DisableAllHooks);
>>>> +defMHFP(MH_EnableHook);
>>>> +defMHFP(MH_DisableHook);
>>>>
>>>>    bool apiHook_initialize() {
>>>>    LOG_DEBUG("calling MH_Initialize");
>>>> @@ -71,8 +69,8 @@ defMHFP(MH_DisableAllHooks);
>>>>    setMHFP(MH_Initialize);
>>>>    setMHFP(MH_Uninitialize);
>>>>    setMHFP(MH_CreateHook);
>>>> -  setMHFP(MH_EnableAllHooks);
>>>> -  setMHFP(MH_DisableAllHooks);
>>>> +  setMHFP(MH_EnableHook);
>>>> +  setMHFP(MH_DisableHook);
>>>>    if(error_setNHFP) {
>>>>            LOG_ERROR(L"Error setting minHook function pointers");
>>>>            FreeLibrary(minhookLibHandle);
>>>> @@ -124,7 +122,7 @@ bool apiHook_enableHooks() {
>>>>            LOG_ERROR(L"apiHooks not initialized");
>>>>            return false;
>>>>    }
>>>> -  res=MH_EnableAllHooks_fp();
>>>> +  res=MH_EnableHook_fp(MH_ALL_HOOKS);
>>>>    nhAssert(res==MH_OK);
>>>>    return TRUE;
>>>>   }
>>>> @@ -137,7 +135,7 @@ bool apiHook_terminate() {
>>>>            LOG_ERROR(L"apiHooks not initialized");
>>>>            return false;
>>>>    }
>>>> -  res=MH_DisableAllHooks_fp();
>>>> +  res=MH_DisableHook_fp(MH_ALL_HOOKS);
>>>>    nhAssert(res==MH_OK);
>>>>    g_hookedFunctions.clear();
>>>>    //Give enough time for all hook functions to complete.
>>>>
>>>> diff --git a/nvdaHelper/remote/ia2LiveRegions.cpp
>>>> b/nvdaHelper/remote/ia2LiveRegions.cpp
>>>> index a3c584d..df389fe 100644
>>>> --- a/nvdaHelper/remote/ia2LiveRegions.cpp
>>>> +++ b/nvdaHelper/remote/ia2LiveRegions.cpp
>>>> @@ -23,6 +23,17 @@
>>>> http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
>>>>
>>>>   using namespace std;
>>>>
>>>> +bool fetchIA2Attributes(IAccessible2* pacc2, map<wstring,wstring>&
>>>> attribsMap) {
>>>> +  BSTR attribs=NULL;
>>>> +  pacc2->get_attributes(&attribs);
>>>> +  if(!attribs) {
>>>> +          return false;
>>>> +  }
>>>> +  IA2AttribsToMap(attribs,attribsMap);
>>>> +  SysFreeString(attribs);
>>>> +  return true;
>>>> +}
>>>> +
>>>>   IAccessible2* findAriaAtomic(IAccessible2*
>>>> pacc2,map<wstring,wstring>&
>>>> attribsMap) {
>>>>    map<wstring,wstring>::iterator i=attribsMap.find(L"atomic");
>>>>    bool atomic=(i!=attribsMap.end()&&i->second.compare(L"true")==0);
>>>> @@ -38,12 +49,8 @@ IAccessible2* findAriaAtomic(IAccessible2*
>>>> pacc2,map<wstring,wstring>& attribsMa
>>>>                    if(pdispParent) {
>>>>                            IAccessible2* pacc2Parent=NULL;
>>>>
>>> if(pdispParent->QueryInterface(IID_IAccessible2,(void**)&pacc2Parent)==S_OK&
>>> &pacc2Parent)
>>>> {
>>>> -                                  BSTR parentAttribs=NULL;
>>>> -
>>> pacc2Parent->get_attributes(&parentAttribs);
>>>> -                                  if(parentAttribs) {
>>>> -                                          map<wstring,wstring>
>>> parentAttribsMap;
>>>> -
>>> IA2AttribsToMap(parentAttribs,parentAttribsMap);
>>>> -
>>> SysFreeString(parentAttribs);
>>>> +                                  map<wstring,wstring>
>>> parentAttribsMap;
>>>> +
>>> if(fetchIA2Attributes(pacc2Parent,parentAttribsMap)) {
>>>>
>>> pacc2Atomic=findAriaAtomic(pacc2Parent,parentAttribsMap);
>>>>                                    }
>>>>                                    pacc2Parent->Release();
>>>> @@ -71,8 +78,13 @@ bool getTextFromIAccessible(wstring& textBuf,
>>>> IAccessible2* pacc2, bool useNewTe
>>>>                            if(varChildren[i].vt==VT_DISPATCH) {
>>>>                                    IAccessible2* pacc2Child=NULL;
>>>>
>>> if(varChildren[i].pdispVal&&varChildren[i].pdispVal->QueryInterface(IID_IAcc
>>> essible2,(void**)&pacc2Child)==S_OK)
>>>> {
>>>> -
>>> if(getTextFromIAccessible(textBuf,pacc2Child)) {
>>>> -                                                  gotText=true;
>>>> +                                          map<wstring,wstring>
>>> childAttribsMap;
>>>> +
>>> fetchIA2Attributes(pacc2Child,childAttribsMap);
>>>> +                                          auto
>>> i=childAttribsMap.find(L"live");
>>>> +
>>> if(i==childAttribsMap.end()||i->second.compare(L"off")!=0) {
>>>> +
>>> if(getTextFromIAccessible(textBuf,pacc2Child)) {
>>>> +
>>> gotText=true;
>>>> +                                                  }
>>>>                                            }
>>>>                                            pacc2Child->Release();
>>>>                                    }
>>>> @@ -110,8 +122,13 @@ bool getTextFromIAccessible(wstring& textBuf,
>>>> IAccessible2* pacc2, bool useNewTe
>>>>
>>> if(paccHypertext->get_hyperlink(hyperlinkIndex,&paccHyperlink)==S_OK)
>>>> {
>>>>                                                    IAccessible2*
>>> pacc2Child=NULL;
>>>>
>>> if(paccHyperlink->QueryInterface(IID_IAccessible2,(void**)&pacc2Child)==S_OK
>>> )
>>>> {
>>>> -
>>> if(getTextFromIAccessible(textBuf,pacc2Child)) {
>>>> -
>>> gotText=true;
>>>> +
>>> map<wstring,wstring> childAttribsMap;
>>>> +
>>> fetchIA2Attributes(pacc2Child,childAttribsMap);
>>>> +                                                          auto
>>> i=childAttribsMap.find(L"live");
>>>> +
>>> if(i==childAttribsMap.end()||i->second.compare(L"off")!=0) {
>>>> +
>>> if(getTextFromIAccessible(textBuf,pacc2Child)) {
>>>> +
>>> gotText=true;
>>>> +                                                                  }
>>>>                                                            }
>>>>
>>> charAdded=true;
>>>>
>>> pacc2Child->Release();
>>>> @@ -217,19 +234,12 @@ void CALLBACK winEventProcHook(HWINEVENTHOOK
>>>> hookID,
>>>> DWORD eventID, HWND hwnd, l
>>>>    pserv->Release();
>>>>    if(!pacc2) return;
>>>>    //Retreave the IAccessible2 attributes, and if the object is not a
>>> live
>>>> region then ignore the event.
>>>> -  BSTR attribs=NULL;
>>>> -  pacc2->get_attributes(&attribs);
>>>> -  if(!attribs) {
>>>> +  map<wstring,wstring> attribsMap;
>>>> +  if(!fetchIA2Attributes(pacc2,attribsMap)) {
>>>>            pacc2->Release();
>>>>            return;
>>>>    }
>>>> -  map<wstring,wstring> attribsMap;
>>>> -  IA2AttribsToMap(attribs,attribsMap);
>>>> -  SysFreeString(attribs);
>>>> -  map<wstring,wstring>::iterator i;
>>>> -  i=attribsMap.find(L"live");
>>>> -  bool isRegionRoot=(i!=attribsMap.end());
>>>> -  i=attribsMap.find(L"container-live");
>>>> +  auto i=attribsMap.find(L"container-live");
>>>>    bool
>>>>
>>> live=(i!=attribsMap.end()&&(i->second.compare(L"polite")==0||i->second.compa
>>> re(L"assertive")==0||i->second.compare(L"rude")==0));
>>>>    if(!live) {
>>>>            pacc2->Release();
>>>> @@ -251,23 +261,41 @@ void CALLBACK winEventProcHook(HWINEVENTHOOK
>>>> hookID,
>>>> DWORD eventID, HWND hwnd, l
>>>>            allowText=(i->second.find(L"text",0)!=wstring::npos);
>>>>
>>> allowAdditions=(i->second.find(L"additions",0)!=wstring::npos);
>>>>    }
>>>> -  //Only handle show events if additions are allowed and this is not
>>> the
>>>> root of a region.
>>>> -  if(eventID==EVENT_OBJECT_SHOW&&(!allowAdditions||isRegionRoot)) {
>>>> +  attribsMap.clear();
>>>> +  //Only handle show events if additions are allowed
>>>> +  if(eventID==EVENT_OBJECT_SHOW&&!allowAdditions) {
>>>>            pacc2->Release();
>>>>            return;
>>>>    }
>>>>    // If this is a show event and this is not the root of the region
>>> and
>>>> there is a text parent,
>>>>    // We can ignore this event as there will be text events which can
>>> handle
>>>> this better
>>>>    if(eventID==EVENT_OBJECT_SHOW) {
>>>> -  bool ignoreShowEvent=false;
>>>> +          bool ignoreShowEvent=false;
>>>>            IDispatch* pdispParent=NULL;
>>>>            pacc2->get_accParent(&pdispParent);
>>>>            if(pdispParent) {
>>>> +                  // check for text on parent
>>>>                    IAccessibleText* paccTextParent=NULL;
>>>>
>>> if(pdispParent->QueryInterface(IID_IAccessibleText,(void**)&paccTextParent)=
>>> =S_OK&&paccTextParent)
>>>> {
>>>>                            ignoreShowEvent=true;
>>>>                            paccTextParent->Release();
>>>>                    }
>>>> +                  if(!ignoreShowEvent) {
>>>> +                          // Check for useful container-live on
>>> parent, as if missing or off,
>>>> then child must be the root
>>>> +                          // Firstly, we assume we are the root of the
>>> region and therefore
>>>> should ignore the event
>>>> +                          ignoreShowEvent=true;
>>>> +                          IAccessible2* pacc2Parent=NULL;
>>>> +
>>> if(pdispParent->QueryInterface(IID_IAccessible2,(void**)&pacc2Parent)==S_OK)
>>>> {
>>>> +
>>> if(fetchIA2Attributes(pacc2Parent,attribsMap)) {
>>>> +
>>> i=attribsMap.find(L"container-live");
>>>> +
>>> if(i!=attribsMap.end()&&(i->second.compare(L"polite")==0||i->second.compare(
>>> L"assertive")==0||i->second.compare(L"rude")==0))
>>>> {
>>>> +                                                  // There is a valid
>>> container-live that is not off, so therefore the
>>>> child is definitly not the root
>>>> +
>>> ignoreShowEvent=false;
>>>> +                                          }
>>>> +                                  }
>>>> +                                  pacc2Parent->Release();
>>>> +                          }
>>>> +                  }
>>>>                    pdispParent->Release();
>>>>            }
>>>>            if(ignoreShowEvent) {
>>>>
>>>> diff --git a/nvdaHelper/vbufBackends/mshtml/node.cpp
>>>> b/nvdaHelper/vbufBackends/mshtml/node.cpp
>>>> index 7bd5a9a..3e42b09 100755
>>>> --- a/nvdaHelper/vbufBackends/mshtml/node.cpp
>>>> +++ b/nvdaHelper/vbufBackends/mshtml/node.cpp
>>>> @@ -385,9 +385,17 @@ void
>>>> MshtmlVBufStorage_controlFieldNode_t::reportLiveText(wstring& text) {
>>>>    }
>>>>   }
>>>>
>>>> +bool isNodeInLiveRegion(VBufStorage_fieldNode_t* node) {
>>>> +  if(!node) return false;
>>>> +  if(node->getFirstChild()) {
>>>> +          return
>>>> ((MshtmlVBufStorage_controlFieldNode_t*)node)->ariaLiveNode!=NULL;
>>>> +  }
>>>> +  return true;
>>>> +}
>>>> +
>>>>   void MshtmlVBufStorage_controlFieldNode_t::reportLiveAddition() {
>>>>    wstring text; //=(this->ariaLiveAtomicNode==this)?L"atomic:
>>> ":L"additions:
>>>> ";
>>>> -  this->getTextInRange(0,this->getLength(),text,false);
>>>> +
>>> this->getTextInRange(0,this->getLength(),text,false,isNodeInLiveRegion);
>>>>    this->reportLiveText(text);
>>>>   }
>>>>
>>>>
>>>> diff --git a/nvdaHelper/vbufBase/storage.cpp
>>>> b/nvdaHelper/vbufBase/storage.cpp
>>>> index ed7fbd3..d99dfb8 100644
>>>> --- a/nvdaHelper/vbufBase/storage.cpp
>>>> +++ b/nvdaHelper/vbufBase/storage.cpp
>>>> @@ -239,7 +239,7 @@ void
>>>> VBufStorage_fieldNode_t::generateMarkupClosingTag(std::wstring& text) {
>>>>    text+=L">";
>>>>   }
>>>>
>>>> -void VBufStorage_fieldNode_t::getTextInRange(int startOffset, int
>>>> endOffset, std::wstring& text, bool useMarkup) {
>>>> +void VBufStorage_fieldNode_t::getTextInRange(int startOffset, int
>>>> endOffset, std::wstring& text, bool useMarkup,
>>>> bool(*filter)(VBufStorage_fieldNode_t*)) {
>>>>    if(this->length==0) {
>>>>            LOG_DEBUG(L"node has 0 length, not collecting text");
>>>>            return;
>>>> @@ -260,9 +260,9 @@ void VBufStorage_fieldNode_t::getTextInRange(int
>>>> startOffset, int endOffset, std
>>>>            nhAssert(childLength>=0); //length can't be negative
>>>>            childEnd+=childLength;
>>>>            LOG_DEBUG(L"child with offsets of "<<childStart<<L" and
>>> "<<childEnd);
>>>> -          if(childEnd>startOffset&&endOffset>childStart) {
>>>> +
>>> if(childEnd>startOffset&&endOffset>childStart&&(!filter||filter(child)))
>>>> {
>>>>                    LOG_DEBUG(L"child offsets overlap requested
>>> offsets");
>>>> -
>>> child->getTextInRange(max(startOffset,childStart)-childStart,min(endOffset-c
>>> hildStart,childLength),text,useMarkup);
>>>> +
>>> child->getTextInRange(max(startOffset,childStart)-childStart,min(endOffset-c
>>> hildStart,childLength),text,useMarkup,filter);
>>>>            }
>>>>            childStart+=childLength;
>>>>            LOG_DEBUG(L"childStart is now "<<childStart);
>>>> @@ -358,7 +358,7 @@ void
>>>> VBufStorage_textFieldNode_t::generateMarkupTagName(std::wstring& text)
>>>> {
>>>>    text+=L"text";
>>>>   }
>>>>
>>>> -void VBufStorage_textFieldNode_t::getTextInRange(int startOffset, int
>>>> endOffset, std::wstring& text, bool useMarkup) {
>>>> +void VBufStorage_textFieldNode_t::getTextInRange(int startOffset, int
>>>> endOffset, std::wstring& text, bool useMarkup,
>>>> bool(*filter)(VBufStorage_fieldNode_t*)) {
>>>>    LOG_DEBUG(L"getting text between offsets "<<startOffset<<L" and
>>>> "<<endOffset);
>>>>    if(useMarkup) {
>>>>            this->generateMarkupOpeningTag(text,startOffset,endOffset);
>>>>
>>>> diff --git a/nvdaHelper/vbufBase/storage.h
>>>> b/nvdaHelper/vbufBase/storage.h
>>>> index 3456584..795d9f4 100644
>>>> --- a/nvdaHelper/vbufBase/storage.h
>>>> +++ b/nvdaHelper/vbufBase/storage.h
>>>> @@ -286,9 +286,10 @@ class VBufStorage_fieldNode_t {
>>>>    * @param endOffset the offset to end at. Use -1 to mean node's end
>>> offset.
>>>>
>>>>    * @param text a string in whish to append the text.
>>>>    * @param useMarkup if true then markup indicating opening and
>>>> closing
>>>> of
>>>> fields will be included.
>>>> + * @param filter: a function that takes the current recursive node and
>>>> returns true if text should be fetched and false if it should be
>>>> skipped.
>>>>    * @return true if successfull, false otherwize.
>>>>    */
>>>> -  virtual void getTextInRange(int startOffset, int endOffset,
>>> std::wstring&
>>>> text, bool useMarkup=false);
>>>> +  virtual void getTextInRange(int startOffset, int endOffset,
>>> std::wstring&
>>>> text, bool
>>>> useMarkup=false,bool(*filter)(VBufStorage_fieldNode_t*)=NULL);
>>>>
>>>>   /**
>>>>    * @return a string providing information about this node's type, and
>>>> its
>>>> state.
>>>> @@ -359,7 +360,7 @@ class VBufStorage_textFieldNode_t : public
>>>> VBufStorage_fieldNode_t {
>>>>
>>>>    virtual void generateMarkupTagName(std::wstring& text);
>>>>
>>>> -  virtual void getTextInRange(int startOffset, int endOffset,
>>> std::wstring&
>>>> text, bool useMarkup=false);
>>>> +  virtual void getTextInRange(int startOffset, int endOffset,
>>> std::wstring&
>>>> text, bool
>>>> useMarkup=false,bool(*filter)(VBufStorage_fieldNode_t*)=NULL);
>>>>
>>>>   /**
>>>>    * constructor.
>>>>
>>>> diff --git a/readme.txt b/readme.txt
>>>> index e667fe3..d5b79d3 100644
>>>> --- a/readme.txt
>>>> +++ b/readme.txt
>>>> @@ -27,18 +27,19 @@ The following dependencies are included in Git
>>>> submodules:
>>>>   * eSpeak, version 1.48.03: http://espeak.sourceforge.net/
>>>>   * IAccessible2, version 1.3:
>>>>
>>> http://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessi
>>> ble2
>>>>   * ConfigObj, version 4.6.0:
>>>> http://www.voidspace.org.uk/python/configobj.html
>>>> -* liblouis, version 2.5.4: http://www.liblouis.org/
>>>> +* liblouis, version 2.6.0: 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
>>>>   * Adobe FlashAccessibility interface typelib
>>>>   * txt2tags, version 2.5: http://txt2tags.sourceforge.net/
>>>> -* MinHook, rev e21b54a: https://github.com/RaMMicHaeL/minhook
>>>> -* SCons, version 2.3.0: http://www.scons.org/
>>>> +* MinHook, tagged version 1.2.2: https://github.com/RaMMicHaeL/minhook
>>>> +* SCons, version 2.3.2: http://www.scons.org/
>>>>   * brlapi Python bindings, version 0.5.7 or later, distributed with
>>>> BRLTTY
>>>> for Windows, version 4.2-2: http://brl.thefreecat.org/brltty/
>>>>   * ALVA BC6 generic dll, version 3.0.4.1
>>>>   * lilli.dll, version 2.1.0.0
>>>>   * Handy Tech Braille SDK, version 1.4.2.0:
>>>>
>>> ftp://ftp.handytech.de/public/Software/BrailleDriver/HTBrailleSDK_1420a.zip
>>>> +* Updated Handy Tech sbsupport.dll and dealers.dat received on
>>>> 2014-09-09
>>>>   * pyserial, version 2.5: http://pypi.python.org/pypi/pyserial
>>>>   * HanSoneConnect.dll, version 2.0.0.1
>>>>   * SyncBraille.dll, version 1.0.0.1
>>>>
>>>> diff --git a/sconstruct b/sconstruct
>>>> index c79a5e0..87d9934 100755
>>>> --- a/sconstruct
>>>> +++ b/sconstruct
>>>> @@ -14,6 +14,7 @@
>>>>
>>>>   import sys
>>>>   import os
>>>> +import time
>>>>   import _winreg
>>>>   from glob import glob
>>>>
>>>> @@ -112,12 +113,35 @@ outFilePrefix =
>>> "nvda{type}_{version}".format(type=""
>>>> if release else "_snapshot
>>>>   outputDir=Dir(env['outputDir'])
>>>>   devDocsOutputDir=outputDir.Dir('devDocs')
>>>>
>>>> +# An action to sign an executable with certFile.
>>>> +signExecCmd = ["signtool", "sign", "/f", certFile]
>>>> +if certPassword:
>>>> +  signExecCmd.extend(("/p", certPassword))
>>>> +if certTimestampServer:
>>>> +  signExecCmd.extend(("/t", certTimestampServer))
>>>> +def signExec(target,source,env):
>>>> +  print [str(x) for x in target]
>>>> +  #sys.exit(1)
>>>> +  # #3795: signtool can quite commonly fail with timestamping, so
>>> allow it
>>>> to try up to 3 times with a 1 second delay between each try.
>>>> +  res=0
>>>> +  for count in xrange(3):
>>>> +          res=env.Execute([signExecCmd+[target[0].abspath]])
>>>> +          if not res:
>>>> +                  return 0 # success
>>>> +          time.sleep(1)
>>>> +  return res # failed
>>>> +#Export via scons environment so other libraries can be signed
>>>> +env['signExec']=signExec
>>>> +
>>>>   #architecture-specific environments
>>>>   archTools=['default','windowsSdk','midl','msrpc']
>>>>   env32=env.Clone(TARGET_ARCH='x86',tools=archTools)
>>>>   env64=env.Clone(TARGET_ARCH='x86_64',tools=archTools)
>>>> -env=env32
>>>> +# Hack around odd bug where some tool [after] msvc states that static
>>>> and
>>>> shared objects are different
>>>> +env32['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
>>>> +env64['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
>>>>
>>>> +env=env32
>>>>
>>>>   #Fill sourceDir with anything provided for it by miscDeps
>>>>   env.recursiveCopy(sourceDir,Dir('miscdeps/source'))
>>>> @@ -195,8 +219,8 @@ def NVDADistGenerator(target, source, env,
>>>> for_signature):
>>>>    if env.get("uiAccess"):
>>>>            buildCmd.append("--enable-uiAccess")
>>>>    if certFile:
>>>> -          for prog in "nvda_noUIAccess", "nvda_uiAccess",
>>> "nvda_slave",
>>>> "nvda_service":
>>>> -                  action.append(signExec[:-1] +
>>> [os.path.join(target[0].path, "%s.exe" %
>>>> prog)])
>>>> +          for prog in "nvda_noUIAccess.exe", "nvda_uiAccess.exe",
>>> "nvda_slave.exe",
>>>> "nvda_service.exe":
>>>> +                  action.append(lambda target,source,env,
>>> progByVal=prog:
>>>> signExec([target[0].File(progByVal)],source,env))
>>>>
>>>>    for ext in "", "c", "o":
>>>>            action.append(Delete(buildVersionFn + ext))
>>>> @@ -247,14 +271,6 @@ def ZipArchiveAction(target, source, env):
>>>>
>>>>   env["BUILDERS"]["ZipArchive"] = Builder(action=ZipArchiveAction)
>>>>
>>>> -# An action to sign an executable with certFile.
>>>> -signExec = ["signtool", "sign", "/f", certFile]
>>>> -if certPassword:
>>>> -  signExec.extend(("/p", certPassword))
>>>> -if certTimestampServer:
>>>> -  signExec.extend(("/t", certTimestampServer))
>>>> -signExec.append("$TARGET")
>>>> -
>>>>   uninstFile=File("dist/uninstall.exe")
>>>>   uninstGen = env.Command(File("uninstaller/uninstGen.exe"),
>>>> "uninstaller/uninst.nsi",
>>>>    [[makensis, "/V2",
>>>>
>>>> diff --git a/source/NVDAObjects/IAccessible/MSHTML.py
>>>> b/source/NVDAObjects/IAccessible/MSHTML.py
>>>> index a6bf4ee..a8e6ffb 100644
>>>> --- a/source/NVDAObjects/IAccessible/MSHTML.py
>>>> +++ b/source/NVDAObjects/IAccessible/MSHTML.py
>>>> @@ -386,7 +386,12 @@ class MSHTML(IAccessible):
>>>>                    if nodeName=="SELECT" and
>>> self.windowStyle&winUser.WS_POPUP:
>>>>                            clsList.append(PopupList)
>>>>                    elif nodeNamesToNVDARoles.get(nodeName) ==
>>> controlTypes.ROLE_DOCUMENT:
>>>> -                          clsList.append(Body)
>>>> +                          try:
>>>> +
>>> isBodyNode=self.HTMLNodeUniqueNumber==self.HTMLNode.document.body.uniqueNumb
>>> er
>>>> +                          except (COMError,NameError):
>>>> +                                  isBodyNode=False
>>>> +                          if isBodyNode:
>>>> +                                  clsList.append(Body)
>>>>                    elif nodeName == "OBJECT":
>>>>                            clsList.append(Object)
>>>>                    elif nodeName=="FIELDSET":
>>>> @@ -879,11 +884,12 @@ class Fieldset(MSHTML):
>>>>   class Body(MSHTML):
>>>>
>>>>    def _get_parent(self):
>>>> -          # The parent of the body accessible is an irrelevant client
>>> object
>>>> (description: MSAAHTML Registered Handler).
>>>> +          # The parent of the body accessible may be an irrelevant
>>> client object
>>>> (description: MSAAHTML Registered Handler).
>>>>            # This object isn't returned when requesting OBJID_CLIENT,
>>> nor is it
>>>> returned as a child of its parent.
>>>>            # Therefore, eliminate it from the ancestry completely.
>>>> +          # However it is possible that this body is a child document
>>> of a parent
>>>> frame. In this case don't skip it.
>>>>            parent = super(Body, self).parent
>>>> -          if parent:
>>>> +          if parent and not isinstance(parent,MSHTML):
>>>>                    return parent.parent
>>>>            else:
>>>>                    return parent
>>>>
>>>> diff --git a/source/NVDAObjects/IAccessible/__init__.py
>>>> b/source/NVDAObjects/IAccessible/__init__.py
>>>> index 7214a75..4826b01 100644
>>>> --- a/source/NVDAObjects/IAccessible/__init__.py
>>>> +++ b/source/NVDAObjects/IAccessible/__init__.py
>>>> @@ -511,14 +511,15 @@ the NVDAObject for IAccessible
>>>>
>>>>            clsList.append(IAccessible)
>>>>
>>>> -
>>>> -          if self.event_objectID==winUser.OBJID_CLIENT and
>>> self.event_childID==0:
>>>> +          if self.event_objectID==winUser.OBJID_CLIENT and
>>> self.event_childID==0
>>>> and not
>>> isinstance(self.IAccessibleObject,IAccessibleHandler.IAccessible2):
>>>>                    # This is the main (client) area of the window, so
>>> we can use other
>>>> classes at the window level.
>>>> +                  # #3872: However, don't do this for IAccessible2
>>> because
>>>> +                  # IA2 supersedes window level APIs and might
>>> conflict with them.
>>>>                    super(IAccessible,self).findOverlayClasses(clsList)
>>>>                    #Generic client IAccessibles with no children should
>>> be classed as
>>>> content and should use displayModel
>>>>                    if clsList[0]==IAccessible and len(clsList)==3 and
>>>> self.IAccessibleRole==oleacc.ROLE_SYSTEM_CLIENT and self.childCount==0:
>>>>                            clsList.insert(0,ContentGenericClient)
>>>> -
>>>> +
>>>>    def
>>>>
>>> __init__(self,windowHandle=None,IAccessibleObject=None,IAccessibleChildID=No
>>> ne,event_windowHandle=None,event_objectID=None,event_childID=None):
>>>>            """
>>>>   @param pacc: a pointer to an IAccessible object
>>>>
>>>> diff --git a/source/NVDAObjects/window/__init__.py
>>>> b/source/NVDAObjects/window/__init__.py
>>>> index 1b95c3d..e7afcee 100644
>>>> --- a/source/NVDAObjects/window/__init__.py
>>>> +++ b/source/NVDAObjects/window/__init__.py
>>>> @@ -114,7 +114,7 @@ An NVDAObject for a window
>>>>                    from .edit import Edit as newCls
>>>>            elif windowClassName=="RichEdit":
>>>>                    from .edit import RichEdit as newCls
>>>> -          elif windowClassName=="RichEdit20":
>>>> +          elif windowClassName in ("RichEdit20","REComboBox20W"):
>>>>                    from .edit import RichEdit20 as newCls
>>>>            elif windowClassName=="RICHEDIT50W":
>>>>                    from .edit import RichEdit50 as newCls
>>>>
>>>> diff --git a/source/NVDAObjects/window/winword.py
>>>> b/source/NVDAObjects/window/winword.py
>>>> index 61078f2..c66e7ef 100755
>>>> --- a/source/NVDAObjects/window/winword.py
>>>> +++ b/source/NVDAObjects/window/winword.py
>>>> @@ -477,7 +477,6 @@ class WordDocumentTextInfo(textInfos.TextInfo):
>>>>            elif which=="startToEnd":
>>>>                    self._rangeObj.Start=other._rangeObj.End
>>>>            elif which=="endToStart":
>>>> -                  print "start %s, end %s, otherStart %s, otherEnd
>>>>
>>> %s"%(self._rangeObj.start,self._rangeObj.end,other._rangeObj.start,other._ra
>>> ngeObj.end)
>>>>                    self._rangeObj.End=other._rangeObj.Start
>>>>            elif which=="endToEnd":
>>>>                    self._rangeObj.End=other._rangeObj.End
>>>>
>>>> diff --git a/source/addonHandler.py b/source/addonHandler.py
>>>> index 8f4fc17..0c135a3 100644
>>>> --- a/source/addonHandler.py
>>>> +++ b/source/addonHandler.py
>>>> @@ -155,7 +155,7 @@ def getAvailableAddons(refresh=False):
>>>>    return _availableAddons.itervalues()
>>>>
>>>>   def installAddonBundle(bundle):
>>>> -  """Extracts an Addon bundle in to a unique subdirectory of the user
>>> addons
>>>> directory, marking the addon as needing install completion on NVDA
>>>> restart."""
>>>> +  """Extracts an Addon bundle in to a unique subdirectory of the user
>>> addons
>>>> directory, marking the addon as needing install completion on NVDA
>>>> restart."""
>>>>    addonPath = os.path.join(globalVars.appArgs.configPath,
>>>> "addons",bundle.manifest['name']+ADDON_PENDINGINSTALL_SUFFIX)
>>>>    bundle.extract(addonPath)
>>>>    addon=Addon(addonPath)
>>>> @@ -391,7 +391,7 @@ def _translatedManifestPaths(lang=None,
>>>> forBundle=False):
>>>>
>>>>
>>>>   class AddonBundle(object):
>>>> -  """ Represents the contents of an NVDA addon in a for suitable for
>>>> distribution.
>>>> +  """ Represents the contents of an NVDA addon suitable for
>>> distribution.
>>>>    The bundle is compressed using the zip file format. Manifest
>>> information
>>>>    is available without the need for extraction."""
>>>>    def __init__(self, bundlePath):
>>>>
>>>> diff --git a/source/api.py b/source/api.py
>>>> index c829f3b..77eb33e 100644
>>>> --- a/source/api.py
>>>> +++ b/source/api.py
>>>> @@ -218,19 +218,12 @@ def setNavigatorObject(obj,isFocus=False):
>>>>    # #3320: If in document review yet there is no document to review
>>> the mode
>>>> should be forced to object.
>>>>    if reviewMode=='document' and (not obj.treeInterceptor or not
>>>> obj.treeInterceptor.isReady or obj.treeInterceptor.passThrough):
>>>>            review.setCurrentMode('object',False)
>>>> -  elif isFocus and reviewMode=='object' and obj.treeInterceptor and
>>>> obj.treeInterceptor.isReady and not obj.treeInterceptor.passThrough:
>>>> -          review.setCurrentMode('document',False)
>>>> -  #Specifically handle when the navigator object is set due to a focus
>>>> change in a virtualBuffer
>>>> -  #The focus change may have been becaus the caret was moved, which
>>> caused
>>>> the focus change.
>>>> -  #If so, don't clober the review position as it will have been
>>> already set
>>>> to a more accurate position.
>>>> -  if isFocus and oldPos and oldPos.obj is obj.treeInterceptor and
>>>> isinstance(obj.treeInterceptor,virtualBuffers.VirtualBuffer):
>>>> -          try:
>>>> -                  objPos=obj.treeInterceptor.makeTextInfo(obj)
>>>> -          except LookupError:
>>>> -                  objPos=None
>>>> -          if objPos and objPos.isOverlapping(oldPos):
>>>> -                  globalVars.reviewPosition=oldPos
>>>> -                  globalVars.reviewPositionObj=oldPosObj
>>>> +  elif obj.treeInterceptor and obj.treeInterceptor.isReady and not
>>>> obj.treeInterceptor.passThrough:
>>>> +          if reviewMode=='object':
>>>> +                  review.setCurrentMode('document',False)
>>>> +          if isFocus:
>>>> +
>>> globalVars.reviewPosition=obj.treeInterceptor.makeTextInfo(textInfos.POSITIO
>>> N_CARET)
>>>> +
>>> globalVars.reviewPositionObj=globalVars.reviewPosition
>>>>    eventHandler.executeEvent("becomeNavigatorObject",obj)
>>>>
>>>>   def isTypingProtected():
>>>> @@ -341,9 +334,9 @@ def getStatusBarText(obj):
>>>>    @return: The status bar text.
>>>>    @rtype: str
>>>>    """
>>>> -  text = obj.name
>>>> -  if text is None:
>>>> -          text = ""
>>>> +  text = obj.name or ""
>>>> +  if text:
>>>> +          text += " "
>>>>    return text + " ".join(chunk for child in obj.children for chunk in
>>>> (child.name, child.value) if chunk and isinstance(chunk, basestring)
>>>> and
>>> not
>>>> chunk.isspace())
>>>>
>>>>   def filterFileName(name):
>>>>
>>>> diff --git a/source/appModules/eclipse.py
>>>> b/source/appModules/eclipse.py
>>>> index fb258e7..49d02ff 100644
>>>> --- a/source/appModules/eclipse.py
>>>> +++ b/source/appModules/eclipse.py
>>>> @@ -2,10 +2,20 @@
>>>>   #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 James Teh <jamie@xxxxxxxxxxx>
>>>> +#Copyright (C) 2010-2014 NV Access Limited
>>>>
>>>>   import controlTypes
>>>>   import appModuleHandler
>>>> +from NVDAObjects.IAccessible import IAccessible
>>>> +
>>>> +class EclipseTextArea(IAccessible):
>>>> +
>>>> +  def event_valueChange(self):
>>>> +          # #2314: Eclipse incorrectly fires valueChange when the
>>> selection
>>>> changes.
>>>> +          # Unfortunately, this causes us to speak the entire
>>> selection
>>>> +          # instead of just the changed selection.
>>>> +          # Therefore, just drop this event.
>>>> +          pass
>>>>
>>>>   class AppModule(appModuleHandler.AppModule):
>>>>
>>>> @@ -14,3 +24,7 @@ class AppModule(appModuleHandler.AppModule):
>>>>                    # Eclipse tree views seem to fire a focus event on
>>> the previously
>>>> focused item before firing focus on the new item (EclipseBug:315339).
>>>>                    # Try to filter this out.
>>>>                    obj.shouldAllowIAccessibleFocusEvent = False
>>>> +
>>>> +  def chooseNVDAObjectOverlayClasses(self, obj, clsList):
>>>> +          if obj.windowClassName == "SWT_Window0" and obj.role ==
>>>> controlTypes.ROLE_EDITABLETEXT:
>>>> +                  clsList.insert(0, EclipseTextArea)
>>>>
>>>> diff --git a/source/appModules/outlook.py
>>>> b/source/appModules/outlook.py
>>>> index f0dabc0..09f3e75 100644
>>>> --- a/source/appModules/outlook.py
>>>> +++ b/source/appModules/outlook.py
>>>> @@ -433,6 +433,8 @@ class UIAGridRow(RowWithFakeNavigation,UIA):
>>>>            role=super(UIAGridRow,self).role
>>>>            if role==controlTypes.ROLE_TREEVIEW:
>>>>                    role=controlTypes.ROLE_TREEVIEWITEM
>>>> +          elif role==controlTypes.ROLE_DATAITEM:
>>>> +                  role=controlTypes.ROLE_LISTITEM
>>>>            return role
>>>>
>>>>    def setFocus(self):
>>>>
>>>> diff --git a/source/braille.py b/source/braille.py
>>>> index 6971d81..e845eaa 100644
>>>> --- a/source/braille.py
>>>> +++ b/source/braille.py
>>>> @@ -309,6 +309,8 @@ def _getDisplayDriver(name):
>>>>
>>>>   def getDisplayList():
>>>>    displayList = []
>>>> +  # The display that should be placed at the end of the list.
>>>> +  lastDisplay = None
>>>>    for loader, name, isPkg in
>>>> pkgutil.iter_modules(brailleDisplayDrivers.__path__):
>>>>            if name.startswith('_'):
>>>>                    continue
>>>> @@ -320,11 +322,17 @@ def getDisplayList():
>>>>                    continue
>>>>            try:
>>>>                    if display.check():
>>>> -                          displayList.append((display.name,
>>> display.description))
>>>> +                          if display.name == "noBraille":
>>>> +                                  lastDisplay = (display.name,
>>> display.description)
>>>> +                          else:
>>>> +                                  displayList.append((display.name,
>>> display.description))
>>>>                    else:
>>>>                            log.debugWarning("Braille display driver %s
>>> reports as unavailable,
>>>> excluding" % name)
>>>>            except:
>>>>                    log.error("", exc_info=True)
>>>> +  displayList.sort(key=lambda d : d[1].lower())
>>>> +  if lastDisplay:
>>>> +          displayList.append(lastDisplay)
>>>>    return displayList
>>>>
>>>>   class Region(object):
>>>>
>>>> diff --git a/source/cursorManager.py b/source/cursorManager.py
>>>> index 492b36c..d4aae44 100644
>>>> --- a/source/cursorManager.py
>>>> +++ b/source/cursorManager.py
>>>> @@ -13,6 +13,7 @@ import wx
>>>>   import baseObject
>>>>   import gui
>>>>   import sayAllHandler
>>>> +import review
>>>>   from scriptHandler import willSayAllResume
>>>>   import textInfos
>>>>   import api
>>>> @@ -343,4 +344,5 @@ class ReviewCursorManager(CursorManager):
>>>>
>>>>    def _set_selection(self, info):
>>>>            self._selection = info.copy()
>>>> +          review.handleCaretMove(info)
>>>>            braille.handler.handleCaretMove(self)
>>>>
>>>> diff --git a/source/gui/__init__.py b/source/gui/__init__.py
>>>> index 5929f08..fc8271b 100644
>>>> --- a/source/gui/__init__.py
>>>> +++ b/source/gui/__init__.py
>>>> @@ -458,6 +458,7 @@ class SysTrayIcon(wx.TaskBarIcon):
>>>>            item = self.menu.Append(wx.ID_EXIT, _("E&xit"),_("Exit
>>> NVDA"))
>>>>            self.Bind(wx.EVT_MENU, frame.onExitCommand, item)
>>>>
>>>> +          self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.onActivate)
>>>>            self.Bind(wx.EVT_TASKBAR_RIGHT_DOWN, self.onActivate)
>>>>
>>>>    def Destroy(self):
>>>>
>>>> diff --git a/source/installer.py b/source/installer.py
>>>> index 47a963d..8f67787 100644
>>>> --- a/source/installer.py
>>>> +++ b/source/installer.py
>>>> @@ -144,6 +144,12 @@ def removeOldProgramFiles(destPath):
>>>>                    else:
>>>>                            os.remove(fn)
>>>>
>>>> +  # #4235: mpr.dll is a Windows system dll accidentally included with
>>>> +  # earlier versions of NVDA. Its presence causes problems in Windows
>>>> Vista.
>>>> +  fn = os.path.join(destPath, "mpr.dll")
>>>> +  if os.path.isfile(fn):
>>>> +          tryRemoveFile(fn)
>>>> +
>>>>   uninstallerRegInfo={
>>>>    "DisplayName":versionInfo.name,
>>>>    "DisplayVersion":versionInfo.version,
>>>>
>>>> diff --git a/source/setup.py b/source/setup.py
>>>> index 752d1cb..b27e129 100755
>>>> --- a/source/setup.py
>>>> +++ b/source/setup.py
>>>> @@ -1,7 +1,7 @@
>>>>   # -*- coding: UTF-8 -*-
>>>>   #setup.py
>>>>   #A part of NonVisual Desktop Access (NVDA)
>>>> -#Copyright (C) 2006-2013 NV Access Limited, Peter Vágner
>>>> +#Copyright (C) 2006-2014 NV Access Limited, Peter Vágner
>>>>   #This file is covered by the GNU General Public License.
>>>>   #See the file COPYING for more details.
>>>>
>>>> @@ -71,7 +71,7 @@ def isSystemDLL(pathname):
>>>>    if dll in ("msvcp71.dll", "msvcp90.dll", "gdiplus.dll","mfc71.dll",
>>>> "mfc90.dll"):
>>>>            # These dlls don't exist on many systems, so make sure
>>> they're included.
>>>>            return 0
>>>> -  elif dll.startswith("api-ms-win-") or dll == "powrprof.dll":
>>>> +  elif dll.startswith("api-ms-win-") or dll in ("powrprof.dll",
>>> "mpr.dll"):
>>>>            # These are definitely system dlls available on all systems
>>> and must be
>>>> excluded.
>>>>            # Including them can cause serious problems when a binary
>>> build is run on
>>>> a different version of Windows.
>>>>            return 1
>>>>
>>>> diff --git a/source/speech.py b/source/speech.py
>>>> index add2bbb..a201cd4 100755
>>>> --- a/source/speech.py
>>>> +++ b/source/speech.py
>>>> @@ -536,7 +536,8 @@ def
>>>>
>>> speakSelectionChange(oldInfo,newInfo,speakSelected=True,speakUnselected=True
>>>>
>>>>   def speakTypedCharacters(ch):
>>>>    global curWordChars;
>>>> -  if api.isTypingProtected():
>>>> +  typingIsProtected=api.isTypingProtected()
>>>> +  if typingIsProtected:
>>>>            realChar="*"
>>>>    else:
>>>>            realChar=ch
>>>> @@ -553,7 +554,7 @@ def speakTypedCharacters(ch):
>>>>            curWordChars=[]
>>>>            if log.isEnabledFor(log.IO):
>>>>                    log.io("typed word: %s"%typedWord)
>>>> -          if config.conf["keyboard"]["speakTypedWords"]:
>>>> +          if config.conf["keyboard"]["speakTypedWords"] and not
>>> typingIsProtected:
>>>>                    speakText(typedWord)
>>>>    if config.conf["keyboard"]["speakTypedCharacters"] and ord(ch)>=32:
>>>>            speakSpelling(realChar)
>>>>
>>>> diff --git a/source/synthDriverHandler.py
>>>> b/source/synthDriverHandler.py
>>>> index 7c2ed9d..417c114 100644
>>>> --- a/source/synthDriverHandler.py
>>>> +++ b/source/synthDriverHandler.py
>>>> @@ -39,6 +39,8 @@ def _getSynthDriver(name):
>>>>
>>>>   def getSynthList():
>>>>    synthList=[]
>>>> +  # The synth that should be placed at the end of the list.
>>>> +  lastSynth = None
>>>>    for loader, name, isPkg in
>>> pkgutil.iter_modules(synthDrivers.__path__):
>>>>            if name.startswith('_'):
>>>>                    continue
>>>> @@ -49,11 +51,17 @@ def getSynthList():
>>>>                    continue
>>>>            try:
>>>>                    if synth.check():
>>>> -
>>> synthList.append((synth.name,synth.description))
>>>> +                          if synth.name == "silence":
>>>> +                                  lastSynth =
>>> (synth.name,synth.description)
>>>> +                          else:
>>>> +
>>> synthList.append((synth.name,synth.description))
>>>>                    else:
>>>>                            log.debugWarning("Synthesizer '%s' doesn't
>>> pass the check, excluding
>>>> from list"%name)
>>>>            except:
>>>>                    log.error("",exc_info=True)
>>>> +  synthList.sort(key=lambda s : s[1].lower())
>>>> +  if lastSynth:
>>>> +          synthList.append(lastSynth)
>>>>    return synthList
>>>>
>>>>   def getSynth():
>>>>
>>>> diff --git a/source/versionInfo.py b/source/versionInfo.py
>>>> index de3b859..428e54a 100644
>>>> --- a/source/versionInfo.py
>>>> +++ b/source/versionInfo.py
>>>> @@ -29,7 +29,7 @@ def _updateVersionFromVCS():
>>>>
>>>>   name="NVDA"
>>>>   longName=_("NonVisual Desktop Access")
>>>> -version="2014.3dev"
>>>> +version="2014.4dev"
>>>>   publisher="unknown"
>>>>   updateVersionType=None
>>>>   try:
>>>>
>>>> diff --git a/source/virtualBuffers/MSHTML.py
>>>> b/source/virtualBuffers/MSHTML.py
>>>> index d35ff64..afd6d92 100644
>>>> --- a/source/virtualBuffers/MSHTML.py
>>>> +++ b/source/virtualBuffers/MSHTML.py
>>>> @@ -238,7 +238,7 @@ class MSHTML(VirtualBuffer):
>>>>            elif nodeType=="button":
>>>>
>>> attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_PUSHBUTTON]}
>>>>            elif nodeType=="edit":
>>>> -
>>> attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_TEXT],"IAccessible::state_%s"
>>> %oleacc.STATE_SYSTEM_READONLY:[None],"IAccessible::state_%s"%oleacc.STATE_SY
>>> STEM_FOCUSABLE:[1]}
>>>> +
>>> attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_TEXT,oleacc.ROLE_SYSTEM_COMBO
>>> BOX],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_READONLY:[None],"IAccessibl
>>> e::state_%s"%oleacc.STATE_SYSTEM_FOCUSABLE:[1],"IHTMLElement::%s"%"isContent
>>> Editable":[1]}
>>>>            elif nodeType=="radioButton":
>>>>
>>> attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_RADIOBUTTON],"IAccessible::st
>>> ate_%s"%oleacc.STATE_SYSTEM_FOCUSABLE:[1]}
>>>>            elif nodeType=="comboBox":
>>>>
>>>> diff --git a/source/virtualBuffers/gecko_ia2.py
>>>> b/source/virtualBuffers/gecko_ia2.py
>>>> index 31f8c57..f61007f 100755
>>>> --- a/source/virtualBuffers/gecko_ia2.py
>>>> +++ b/source/virtualBuffers/gecko_ia2.py
>>>> @@ -209,7 +209,7 @@ class Gecko_ia2(VirtualBuffer):
>>>>            elif nodeType=="button":
>>>>
>>> attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_PUSHBUTTON,oleacc.ROLE_SYSTEM
>>> _BUTTONMENU,IAccessibleHandler.IA2_ROLE_TOGGLE_BUTTON]}
>>>>            elif nodeType=="edit":
>>>> -
>>> attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_TEXT],"IAccessible::state_%s"
>>> %oleacc.STATE_SYSTEM_READONLY:[None]}
>>>> +
>>> attrs={"IAccessible::role":[oleacc.ROLE_SYSTEM_TEXT,oleacc.ROLE_SYSTEM_COMBO
>>> BOX],"IAccessible::state_%s"%oleacc.STATE_SYSTEM_READONLY:[None],"IAccessibl
>>> e2::state_%s"%IAccessibleHandler.IA2_STATE_EDITABLE:[1]}
>>>>            elif nodeType=="frame":
>>>>
>>> attrs={"IAccessible::role":[IAccessibleHandler.IA2_ROLE_INTERNAL_FRAME]}
>>>>            elif nodeType=="separator":
>>>>
>>>> diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t
>>>> index d07340e..a677322 100644
>>>> --- a/user_docs/en/changes.t2t
>>>> +++ b/user_docs/en/changes.t2t
>>>> @@ -3,6 +3,32 @@
>>>>
>>>>   %!includeconf: ../changes.t2tconf
>>>>
>>>> += 2014.4 =
>>>> +
>>>> +== Changes ==
>>>> +- If an object you have moved to with object navigation is inside a
>>> browse
>>>> mode document, but the object you were on previously was not, the
>>>> review
>>>> mode is automatically set to document. Previously this only happened if
>>> the
>>>> navigator object was moved due to the focus changing. (#4369)
>>>> +- The Braille display and Synthesizer lists in the respective settings
>>>> dialogs are now alphabetically sorted except for No braille/No speech,
>>> which
>>>> are now at the bottom. (#2724)
>>>> +- Updated liblouis braille translator to 2.6.0. (#4434, #3835)
>>>> +- In browse mode, pressing e and shift+e to navigate to edit fields
>>>> now
>>>> includes editable combo boxes. This includes the search box in the
>>>> latest
>>>> versionn of Google Search. (#4436)
>>>> +- Clicking the NVDA icon in the Notification Area with the left mouse
>>>> button now opens the NVDA menu instead of doing nothing. (#4459)
>>>> +
>>>> +
>>>> +== Bug Fixes ==
>>>> +- When moving focus back to a browse mode document (e.g. alt tabbing
>>>> to
>>> an
>>>> already opened web page) the review cursor is properly positioned at
>>>> the
>>>> virtual caret, rather than the focused control (e.g. a near by link).
>>>> (#4369)
>>>> +- In Powerpoint slide shows, the review cursor correctly follows the
>>>> virtual caret. (#4370)
>>>> +- In Mozilla Firefox and other Gecko-based browsers, new content
>>>> within
>>>> a
>>>> live region will be announced even if the new content has a usable ARIA
>>> live
>>>> type different to the parent live region. E.g. Content marked as
>>>> assertive
>>>> is added to a live region marked as polite. (#4169).
>>>> +- In Internet Explorer and other MSHTML controls, some cases where a
>>>> document is contained within another document no longer prevent the
>>>> user
>>>> from accessing some of the content (specifically, framesets inside
>>>> framesets). (#4418)
>>>> +- NVDA no longer crashes when attempting to use a Handy Tech braille
>>>> display in some cases. (#3709)
>>>> +- In Windows Vista, a spurious "Entry Point Not Found" dialog is no
>>> longer
>>>> displayed in several cases such as when starting NVDA from the Desktop
>>>> shortcut or via the shortcut key. (#4235)
>>>> +- Serious problems with editable text controls in dialogs in recent
>>>> versions of Eclipse have been fixed. (#3872)
>>>> +- In Outlook 2010, moving the caret now works as expected in the
>>>> location
>>>> field of appointments and meeting requests. (#4126)
>>>> +- Inside a live region, content which is marked as not being live
>>>> (e.g.
>>>> aria-live="off") is now correctly ignored. (#4405)
>>>> +- When reporting the text of a status bar that has a name, the name is
>>> now
>>>> correctly separated from the first word of the status bar text. (#4430)
>>>> +- In password entry fields with speaking of typed words enabled,
>>>> multiple
>>>> asterisks are no longer pointlessly reported when beginning new words.
>>>> (#4402)
>>>> +- In the Microsoft Outlook message list, items are no longer
>>>> pointlessly
>>>> announced as Data Items. (#4439)
>>>> +- When selecting text in the code editing control in the Eclipse IDE,
>>>> the
>>>> entire selection is no longer announced every time the selection
>>>> changes.
>>>> (#2314)
>>>> +
>>>> +
>>>>   = 2014.3 =
>>>>
>>>>   == New Features ==
>>>>
>>>> diff --git a/user_docs/en/userGuide.t2t b/user_docs/en/userGuide.t2t
>>>> index 77966c9..0560398 100644
>>>> --- a/user_docs/en/userGuide.t2t
>>>> +++ b/user_docs/en/userGuide.t2t
>>>> @@ -84,7 +84,7 @@ Running the portable version directly from read-only
>>> media
>>>> is not supported at t
>>>>   Using the temporary copy of NVDA is also an option (e.g. for
>>> demonstration
>>>> purposes), though  starting NVDA in this way each time can become very
>>> time
>>>> consuming.
>>>>
>>>>   ++ Portable and Temporary Copy Restrictions ++
>>>> -Apart from the  inability to automatically start during and or after
>>>> log-on, the portable and temporary copies of NVDA also have the
>>>> following
>>>> restrictions:
>>>> +Apart from the  inability to automatically start during and/or after
>>>> log-on, the portable and temporary copies of NVDA also have the
>>>> following
>>>> restrictions:
>>>>   - The inability to interact with applications running with
>>>> administrative
>>>> privileges, unless of course NVDA itself has been run also with these
>>>> privileges (not recommended).
>>>>   - The inability to read User Account Control (UAC) screens when
>>>> trying
>>>> to
>>>> start an application with administrative privileges.
>>>>   - Windows 8: the inability to support input from a touch screen.
>>>> @@ -107,7 +107,7 @@ This also includes UAC control and other secure
>>>> screens.
>>>>
>>>>   +++ Create Desktop Shortcut (ctrl+alt+n) +++
>>>>   This option allows you to choose whether or not NVDA should create a
>>>> shortcut on the desktop to start NVDA.
>>>> -This shortcut if created will also be assigned a  shortcut key of
>>>> control+alt+n allowing you to start NVDA at any time with this key
>>>> stroke.
>>>> +If created, this shortcut will also be assigned a  shortcut key of
>>>> control+alt+n, allowing you to start NVDA at any time with this key
>>> stroke.
>>>>
>>>>   +++ Copy Portable Configuration to Current User Account +++
>>>>   This option allows you to choose whether or not NVDA should copy the
>>>> user
>>>> configuration from the currently running NVDA into the configuration
>>>> for
>>> the
>>>> currently logged on  user, for the installed copy of NVDA.
>>>> @@ -152,22 +152,20 @@ The third lets you control if this Welcome dialog
>>>> should appear each time NVDA s
>>>>
>>>>   +++ The NVDA Modifier Key +++
>>>>   Most NVDA-specific keyboard commands consist of pressing a particular
>>>> key
>>>> called the NVDA modifier key in conjunction with one or more other
>>>> keys.
>>>> -Notable exceptions to this are the text review commands for desktop
>>>> keyboards which just use the numpad keys by themselves, but there are
>>>> some
>>>> other exceptions as well.
>>>> -
>>>> -NVDA can be configured so that either the numpad Insert, Extended
>>>> Insert,
>>>> or capslock key can be used as the NVDA modifier key.
>>>> +Notable exceptions to this are the text review commands for the
>>>> desktop
>>>> keyboard layout which just use the numpad keys by themselves, but there
>>> are
>>>> some other exceptions as well.
>>>>
>>>> +NVDA can be configured so that the numpad Insert, Extended Insert
>>>> and/or
>>>> capslock key can be used as the NVDA modifier key.
>>>>   By default, both the numpad Insert and Extended Insert keys are set
>>>> as
>>> NVDA
>>>> modifier keys.
>>>>
>>>> -If you wish to cause one of the NVDA modifier keys to act like its
>>> original
>>>> key (for instance you wish to turn capslock on when you have set
>>>> capslock
>>> to
>>>> be an NVDA modifier key) you can press the key twice in quick
>>>> succession.
>>>> +If you wish to cause one of the NVDA modifier keys to behave as it
>>> usually
>>>> would if NVDA were not running (e.g. you wish to turn capslock on when
>>>> you
>>>> have set capslock to be an NVDA modifier key), you can press the key
>>>> twice
>>>> in quick succession.
>>>>
>>>>   +++ Keyboard Layouts +++
>>>> -NVDA currently comes with two sets of key commands.
>>>> -There is a layout for Desktops and a layout for Laptops.
>>>> -NVDA by default is set to use the Desktop layout, though you can
>>>> switch
>>> to
>>>> the Laptop layout in the Keyboard Settings, found under Preferences in
>>>> the
>>>> NVDA menu.
>>>> +NVDA currently comes with two sets of key commands (known as keyboard
>>>> layouts): the desktop layout and the laptop layout.
>>>> +By default, NVDA  is set to use the Desktop layout, though you can
>>>> switch
>>>> to the Laptop layout in the Keyboard Settings, found under Preferences
>>>> in
>>>> the NVDA menu.
>>>>
>>>> -The Desktop layout makes heavy use of the numberpad (with numlock
>>>> off).
>>>> -Although most laptops do not have a physical numberpad, some laptops
>>>> can
>>>> emulate one by holding down the FN key and pressing letters and numbers
>>>> on
>>>> the right-hand side of the keyboard (7 8 9 u i o j k l etc).
>>>> -If your laptop can not do this, or does not allow you to turn numlock
>>> off,
>>>> you may want to switch to the Laptop layout instead.
>>>> +The Desktop layout makes heavy use of the numpad (with numlock off).
>>>> +Although most laptops do not have a physical numpad, some laptops can
>>>> emulate one by holding down the FN key and pressing letters and numbers
>>>> on
>>>> the right-hand side of the keyboard (7, 8, 9, u, i, o, j, k, l, etc.).
>>>> +If your laptop cannot do this or does not allow you to turn numlock
>>>> off,
>>>> you may want to switch to the Laptop layout instead.
>>>>
>>>>   ++ NVDA Touch Gestures ++
>>>>   If you are running NVDA on a device with a touch screen and running
>>> Windows
>>>> 8 or higher, you can also control NVDA directly via the touch screen.
>>>> @@ -234,7 +232,7 @@ When the menu comes up, You can use the arrow keys
>>>> to
>>>> navigate the menu, and the
>>>>   || Name | Desktop key | Laptop key | Touch | Description |
>>>>   | Stop speech | Control | control | 2-finger tap | Instantly stops
>>> speaking
>>>> |
>>>>   | Pause Speech | shift | shift | none | Instantly pauses speech.
>>>> Pressing
>>>> it again will continue speaking where it left off (if pausing is
>>>> supported
>>>> by the current synthesizer) |
>>>> -| NVDA Menu | NVDA+n | NVDA+n | 2-finger double tap | Pops up the NVDA
>>> menu
>>>> to allow you to access preferences, tools and help etc |
>>>> +| NVDA Menu | NVDA+n | NVDA+n | 2-finger double tap | Pops up the NVDA
>>> menu
>>>> to allow you to access preferences, tools, help, etc. |
>>>>   | Toggle Speech Mode | NVDA+s | NVDA+s | none | Toggles speech mode
>>> between
>>>> speech, beeps and off. |
>>>>   | Toggle Input Help Mode | NVDA+1 | NVDA+1 | none | Pressing any key
>>>> in
>>>> this mode will report the key, and the description of any NVDA command
>>>> associated with it |
>>>>   | Quit NVDA | NVDA+q | NVDA+q | none | Exits NVDA |
>>>> @@ -669,12 +667,13 @@ This option is a slider which goes from 0 to 100,
>>>> (0
>>>> being the lowest volume and
>>>>   This option is a slider that lets you choose how much inflection
>>>> (rise
>>> and
>>>> fall in pitch) the synthesizer should use to speak with. (The only
>>>> synthesizer that provides this option at the present time is eSpeak).
>>>>
>>>>   ==== Automatic Language switching ====
>>>> -This checkbox allows you to toggle whether or not NVDA should switch
>>> speech
>>>> synthesizer languages on the fly, if language markup is available in
>>>> the
>>>> text being read.
>>>> +This checkbox allows you to toggle whether NVDA should switch speech
>>>> synthesizer languages automatically if the text being read specifies
>>>> its
>>>> language.
>>>>   This option is enabled by default.
>>>>   Currently only the eSpeak synthesizer supports automatic language
>>>> switching.
>>>>
>>>>   ==== Automatic Dialect switching ====
>>>> -If automatic language switching is turned on, this checkbox allows you
>>>> to
>>>> toggle whether or not dialect changes should be made, rather than just
>>>> actual language changes. E.g. If reading in an English U.S. voice but a
>>>> document states some text is in English U.K. then if this feature is
>>> enabled
>>>> the synthesizer will switch accents.
>>>> +This checkbox allows you to toggle whether or not dialect changes
>>>> should
>>> be
>>>> made, rather than just actual language changes.
>>>> +For example, if reading in an English U.S. voice but a document
>>>> specifies
>>>> that some text is in English U.K., then the synthesizer will switch
>>> accents
>>>> if this option is enabled.
>>>>   This option is disabled by default.
>>>>
>>>>   %kc:setting
>>>> @@ -880,7 +879,7 @@ Key: NVDA+6
>>>>
>>>>   When enabled, the review cursor will automatically be moved to the
>>> position
>>>> of the System caret each time it moves.
>>>>
>>>> -==== Follow mouse ====
>>>> +==== Follow mouse cursor ====
>>>>   When enabled, the review cursor will follow the mouse as it moves.
>>>>
>>>>   ==== Simple Review mode ====
>>>> @@ -1718,8 +1717,8 @@ These are (ordered from left to right):
>>>>   Currently, the right thumb key is not in use.
>>>>   The inner keys are both mapped to space.
>>>>
>>>> -%kc:beginInclude
>>>>   || Name | Key |
>>>> +%kc:beginInclude
>>>>   | backspace key | dot 7 |
>>>>   | enter key | dot 8 |
>>>>   | escape key | space with dot 7 |
>>>> @@ -1882,6 +1881,43 @@ Please see the [BRLTTY key tables documentation
>>>> http://mielke.cc/brltty/doc/driv
>>>>   | Route to braille cell | route (bring cursor to character) |
>>>>   %kc:endInclude
>>>>
>>>> ++ Braille control type and state abbreviations +
>>>> +In order to fit as much information as possible on a braille display,
>>>> The
>>>> folowing abbreviations have been defined to indicate control type and
>>>> state.
>>>> +
>>>> +|| Abbreviation | Control type |
>>>> +| btn | button |
>>>> +| cbo | combo box |
>>>> +| chk | check box |
>>>> +| dlg | dialog |
>>>> +| edt | editable text field |
>>>> +| gra | graphic |
>>>> +| cN | table column number n, e.g. c1, c2. |
>>>> +| rN | table row number n, e.g. r1, r2. |
>>>> +| hN | heading at level n, e.g. h1, h2. |
>>>> +| lnk | link |
>>>> +| lst | list |
>>>> +| vlnk | visited link |
>>>> +| mnu | menu |
>>>> +| mnubar | menu bar |
>>>> +| rbtn | radio button |
>>>> +| tb | table |
>>>> +| tv | treeview |
>>>> +| lv N | a tree view item has a hierarchical level N|
>>>> +| ``-----`` | seperator |
>>>> +
>>>> +The following state indicators are also defined:
>>>> +|| Abbreviation | Control state |
>>>> +| ... | displayed when an object supports autocompletion |
>>>> +| ( ) | displayed when an object (e.g. a check box) is not checked |
>>>> +| (x) | displayed when an object (e.g. a check box) is checked |
>>>> +| (-) | displayed when an object (e.g. a check box) is half checked |
>>>> +| - | displayed when an object (e.g. a tree view item) is collapsible
>>>> |
>>>> +| + | displayed when an object (e.g. a tree view item) is Expandable |
>>>> +| clk | displayed when an object is clickable |
>>>> +| ro | displayed when an object (e.g. an editable text field) is
>>> read-only
>>>> |
>>>> +| sel | displayed when an object is selected |
>>>> +| submnu | displayed when an object has a popup (usually a sub-menu) |
>>>> +
>>>>   + Advanced Topics +
>>>>
>>>>   ++ Advanced Customization of Symbol Pronunciation ++
>>>>
>>>> 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.
>>>>
>>>> ----------------------------------------------------------------
>>>>
>>>> NVDA add-ons Central: A list for discussing NVDA add-ons
>>>>
>>>> To post a message, send an email to nvda-addons@xxxxxxxxxxxxx.
>>>>
>>>> To unsubscribe, send an email with the subject line of "unsubscribe"
>>>> (without quotes) to nvda-addons-request@xxxxxxxxxxxxx.
>>>>
>>>> If you have questions for list moderators, please send a message to
>>>> nvda-addons-moderators@xxxxxxxxxxxxx.
>>>>
>>>> Community addons can be found here: http://addons.nvda-project.org
>>>>
>>> ----------------------------------------------------------------
>>>
>>> NVDA add-ons Central: A list for discussing NVDA add-ons
>>>
>>> To post a message, send an email to nvda-addons@xxxxxxxxxxxxx.
>>>
>>> To unsubscribe, send an email with the subject line of "unsubscribe"
>>> (without quotes) to nvda-addons-request@xxxxxxxxxxxxx.
>>>
>>> If you have questions for list moderators, please send a message to
>>> nvda-addons-moderators@xxxxxxxxxxxxx.
>>>
>>> Community addons can be found here: http://addons.nvda-project.org
>>>
>>> ----------------------------------------------------------------
>>>
>>> NVDA add-ons Central: A list for discussing NVDA add-ons
>>>
>>> To post a message, send an email to nvda-addons@xxxxxxxxxxxxx.
>>>
>>> To unsubscribe, send an email with the subject line of "unsubscribe"
>>> (without quotes) to nvda-addons-request@xxxxxxxxxxxxx.
>>>
>>> If you have questions for list moderators, please send a message to
>>> nvda-addons-moderators@xxxxxxxxxxxxx.
>>>
>>> Community addons can be found here: http://addons.nvda-project.org
>>>
>> ----------------------------------------------------------------
>>
>> NVDA add-ons Central: A list for discussing NVDA add-ons
>>
>> To post a message, send an email to nvda-addons@xxxxxxxxxxxxx.
>>
>> To unsubscribe, send an email with the subject line of "unsubscribe"
>> (without quotes) to nvda-addons-request@xxxxxxxxxxxxx.
>>
>> If you have questions for list moderators, please send a message to
>> nvda-addons-moderators@xxxxxxxxxxxxx.
>>
>> Community addons can be found here: http://addons.nvda-project.org
>>
> ----------------------------------------------------------------
>
> NVDA add-ons Central: A list for discussing NVDA add-ons
>
> To post a message, send an email to nvda-addons@xxxxxxxxxxxxx.
>
> To unsubscribe, send an email with the subject line of "unsubscribe"
> (without quotes) to nvda-addons-request@xxxxxxxxxxxxx.
>
> If you have questions for list moderators, please send a message to
> nvda-addons-moderators@xxxxxxxxxxxxx.
>
> Community addons can be found here: http://addons.nvda-project.org
>
----------------------------------------------------------------

NVDA add-ons Central: A list for discussing NVDA add-ons

To post a message, send an email to nvda-addons@xxxxxxxxxxxxx.

To unsubscribe, send an email with the subject line of "unsubscribe" (without 
quotes) to nvda-addons-request@xxxxxxxxxxxxx.

If you have questions for list moderators, please send a message to 
nvda-addons-moderators@xxxxxxxxxxxxx.

Community addons can be found here: http://addons.nvda-project.org

Other related posts: