Skip to content
Permalink
Browse files

Merge tag 'release-2019.1.1'

Update master branch with changes from Release 2019.1.1
  • Loading branch information...
feerrenrut committed Apr 10, 2019
2 parents 4d2e7f2 + c611652 commit db34329b8cc9d47de6d12109f16d57fcbec3d3d3
@@ -83,6 +83,6 @@ interface NvdaInProcUtils {
*/
error_status_t outlook_getMAPIProp(const long threadID, [in] IUnknown* mapiObject, const unsigned long mapiPropTag, [out] VARIANT* val);

error_status_t excel_getCellInfos([in] const unsigned long windowHandle,[in] IDispatch* rangeObj, [in] long cellInfoFlags, [in] long cellCount, [out,size_is(cellCount)] EXCEL_CELLINFO* cellInfos, [out] long* numCellsFetched);
error_status_t excel_getCellInfos([in] const unsigned long windowHandle,[in] BSTR rangeAddress, [in] long cellInfoFlags, [in] long cellCount, [out,size_is(cellCount)] EXCEL_CELLINFO* cellInfos, [out] long* numCellsFetched);

}
@@ -16,8 +16,8 @@ This license can be found at:
#include <comdef.h>
#include <atlcomcli.h>
#include <windows.h>
#include <oleacc.h>
#include <common/log.h>
#include <common/COMUtils.h>
#include "inProcess.h"
#include "nvdaInProcUtils.h"
#include "excel/constants.h"
@@ -450,21 +450,32 @@ HRESULT getCellInfo(HWND hwnd, IDispatch* pDispatchRange, long cellInfoFlags, EX
return RPC_S_OK;
}

error_status_t nvdaInProcUtils_excel_getCellInfos(handle_t bindingHandle, const unsigned long windowHandle, IDispatch* arg_pDispatchRange, long cellInfoFlags, long cellCount, EXCEL_CELLINFO* cellInfos, long* numCellsFetched) {
HWND hwnd=static_cast<HWND>(UlongToHandle(windowHandle));
long threadID=GetWindowThreadProcessId(hwnd,nullptr);
nvCOMUtils::InterfaceMarshaller im;
HRESULT res=im.marshal(arg_pDispatchRange);
if(FAILED(res)) {
LOG_ERROR(L"Failed to marshal range object from rpc thread");
error_status_t nvdaInProcUtils_excel_getCellInfos(handle_t bindingHandle, const unsigned long windowHandle, BSTR arg_rangeAddress, long cellInfoFlags, long cellCount, EXCEL_CELLINFO* cellInfos, long* numCellsFetched) {
if(!arg_rangeAddress) {
LOG_ERROR(L"rangeAddress is NULL");
return E_UNEXPECTED;
}
HWND hwnd=static_cast<HWND>(UlongToHandle(windowHandle));
long threadID=GetWindowThreadProcessId(hwnd,nullptr);
// Execute the following code in Excel's GUI thread.
execInThread(threadID,[&](){
// Unmarshal the IDispatch pointer from the COM global interface table.
CComPtr<IDispatch> pDispatchRange=im.unmarshal<IDispatch>();
if(!pDispatchRange) {
LOG_ERROR(L"Failed to unmarshal range object into Excel GUI thread");
// Fetch the Excel object model and create a range object for the given range address.
CComPtr<IDispatch> pDispatchWindow=nullptr;
HRESULT res=AccessibleObjectFromWindow(hwnd,OBJID_NATIVEOM,IID_IDispatch,reinterpret_cast<void**>(&pDispatchWindow));
if(res!=S_OK||!pDispatchWindow) {
LOG_ERROR(L"AccessibleObjectFromWindow failed. Code "<<res);
return;
}
CComPtr<IDispatch> pDispatchApplication=nullptr;
res=_com_dispatch_raw_propget(pDispatchWindow,XLDISPID_WINDOW_APPLICATION,VT_DISPATCH,&pDispatchApplication);
if(res!=S_OK||!pDispatchApplication) {
LOG_ERROR(L"window.application failed. Code "<<res);
return;
}
CComPtr<IDispatch> pDispatchRange=nullptr;
res=_com_dispatch_raw_method(pDispatchApplication,XLDISPID_APPLICATION_RANGE,DISPATCH_PROPERTYGET,VT_DISPATCH,&pDispatchRange,L"\x008",arg_rangeAddress);
if(res!=S_OK||!pDispatchRange) {
LOG_ERROR(L"application.range failed. Code "<<res<<L", rangeAddress "<<arg_rangeAddress);
return;
}
if(cellCount==1) {
@@ -17,6 +17,8 @@ This license can be found at:
const long xlValidateList=3;

// Excel IDispatch IDs
const long XLDISPID_WINDOW_APPLICATION=148;
const long XLDISPID_APPLICATION_RANGE=197;
const long XLDISPID_RANGE__NEWENUM=-4;
const long XLDISPID_RANGE_FORMULA=261;
const long XLDISPID_RANGE_ITEM=170;
@@ -339,15 +339,10 @@ CComPtr<IAccessible2> GeckoVBufBackend_t::getSelectedItem(
IAccessible2* container, const map<wstring, wstring>& attribs
) {
if (this->toolkitName.compare(L"Chrome") == 0) {
const auto attribsIt = attribs.find(L"tag");
if (attribsIt != attribs.end() &&
attribsIt->second.compare(L"select") == 0) {
// In a <select size>1>, Chrome reports that list items are focusable,
// but programmatically focusing them does nothing. Therefore, we don't
// want to render this in Chrome because a user wouldn't be able to focus
// these list boxes in browse mode if we did.
return nullptr;
}
// #9364: Google Chrome crashes when fetching the currently selected item from some listboxes.
// Specifically when calling IEnumVARIANT::next.
// Due to this, and other issues around incorrect focus state setting, it is best to disable fetching of currently selected item in listboxes in Chrome all together.
return nullptr;
}

CComVariant selection;
@@ -7,7 +7,7 @@
import abc
from six import with_metaclass
import ctypes
from comtypes import COMError
from comtypes import COMError, BSTR
import comtypes.automation
import wx
import time
@@ -1118,7 +1118,8 @@ def iterate(self):
count=collectionObject.count
cellInfos=(ExcelCellInfo*count)()
numCellsFetched=ctypes.c_long()
NVDAHelper.localLib.nvdaInProcUtils_excel_getCellInfos(self.document.appModule.helperLocalBindingHandle,self.document.windowHandle,collectionObject._comobj,self.cellInfoFlags,count,cellInfos,ctypes.byref(numCellsFetched))
address=collectionObject.address(True,True,xlA1,True)
NVDAHelper.localLib.nvdaInProcUtils_excel_getCellInfos(self.document.appModule.helperLocalBindingHandle,self.document.windowHandle,BSTR(address),self.cellInfoFlags,count,cellInfos,ctypes.byref(numCellsFetched))
for index in xrange(numCellsFetched.value):
ci=cellInfos[index]
if not ci.address:
@@ -1147,7 +1148,8 @@ def _get_excelCellInfo(self):
return None
ci=ExcelCellInfo()
numCellsFetched=ctypes.c_long()
res=NVDAHelper.localLib.nvdaInProcUtils_excel_getCellInfos(self.appModule.helperLocalBindingHandle,self.windowHandle,self.excelCellObject._comobj,NVCELLINFOFLAG_ALL,1,ctypes.byref(ci),ctypes.byref(numCellsFetched))
address=self.excelCellObject.address(True,True,xlA1,True)
res=NVDAHelper.localLib.nvdaInProcUtils_excel_getCellInfos(self.appModule.helperLocalBindingHandle,self.windowHandle,BSTR(address),NVCELLINFOFLAG_ALL,1,ctypes.byref(ci),ctypes.byref(numCellsFetched))
if res!=0 or numCellsFetched.value==0:
return None
return ci
@@ -1283,7 +1285,8 @@ def _get_cellCoordsText(self):
rawAddress=self.excelCellObject.address(False,False,1,False)
coords=rawAddress.split('!')[-1].split(':')
if len(coords)==2:
return "%s through %s"%(coords[0],coords[1])
# Translators: Used to express an address range in excel.
return _("{start} through {end}").format(start=coords[0], end=coords[1])
else:
return coords[0]

@@ -66,7 +66,7 @@ def formatVersionForGUI(year, major, minor):
name="NVDA"
version_year=2019
version_major=1
version_minor=0
version_minor=1
version_build=0
version=_formatDevVersionString()
publisher="unknown"
@@ -137,13 +137,15 @@ def getSystemConfigPath():
pass
return None

SCRATCH_PAD_ONLY_DIRS = ('appModules','brailleDisplayDrivers','globalPlugins','synthDrivers')

def getScratchpadDir(ensureExists=False):
""" Returns the path where custom appModules, globalPlugins and drivers can be placed while being developed."""
path=os.path.join(globalVars.appArgs.configPath,'scratchpad')
if ensureExists:
if not os.path.isdir(path):
os.makedirs(path)
for subdir in ('appModules','brailleDisplayDrivers','globalPlugins','synthDrivers'):
for subdir in SCRATCH_PAD_ONLY_DIRS:
subpath=os.path.join(path,subdir)
if not os.path.isdir(subpath):
os.makedirs(subpath)
@@ -269,13 +271,20 @@ def setSystemConfigToCurrentConfig():
def _setSystemConfig(fromPath):
import installer
toPath=os.path.join(sys.prefix.decode('mbcs'),'systemConfig')
log.debug("Copying config to systemconfig dir: %s", toPath)
if os.path.isdir(toPath):
installer.tryRemoveFile(toPath)
for curSourceDir,subDirs,files in os.walk(fromPath):
if curSourceDir==fromPath:
curDestDir=toPath
for curSourceDir, subDirs, files in os.walk(fromPath):
if curSourceDir == fromPath:
curDestDir = toPath
# Don't copy from top-level config dirs we know will be ignored due to security risks.
removeSubs = set(SCRATCH_PAD_ONLY_DIRS).intersection(subDirs)
for subPath in removeSubs:
log.debug("Ignored folder that may contain unpackaged addons: %s", subPath)
subDirs.remove(subPath)
else:
curDestDir=os.path.join(toPath,os.path.relpath(curSourceDir,fromPath))
relativePath = os.path.relpath(curSourceDir, fromPath)
curDestDir = os.path.join(toPath, relativePath)
if not os.path.isdir(curDestDir):
os.makedirs(curDestDir)
for f in files:
@@ -726,21 +726,29 @@ def makeSettings(self, settingsSizer):
settingsSizerHelper.addItem(item)

def onCopySettings(self,evt):
for packageType in ('addons','appModules','globalPlugins','brailleDisplayDrivers','synthDrivers'):
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.
_("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:
return
break
progressDialog = gui.IndeterminateProgressDialog(gui.mainFrame,
# Translators: The title of the dialog presented while settings are being copied
_("Copying Settings"),
# Translators: The message displayed while settings are being copied to the system configuration (for use on Windows logon etc)
_("Please wait while settings are copied to the system configuration."))
addonsDirPath = os.path.join(globalVars.appArgs.configPath, 'addons')
if os.path.isdir(addonsDirPath) and 0 < len(os.listdir(addonsDirPath)):
# Translators: A message to warn the user when attempting to copy current
# settings to system settings.
message = _(
"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.
title = _("Warning")
style = wx.YES | wx.NO | wx.ICON_WARNING
if wx.NO == gui.messageBox(message, title, style, self):
return
progressDialog = gui.IndeterminateProgressDialog(
gui.mainFrame,
# Translators: The title of the dialog presented while settings are being copied
_("Copying Settings"),
# Translators: The message displayed while settings are being copied
# to the system configuration (for use on Windows logon etc)
_("Please wait while settings are copied to the system configuration.")
)
while True:
try:
gui.ExecAndPump(config.setSystemConfigToCurrentConfig)
@@ -26,6 +26,14 @@ What's New in NVDA
- You can now set the "disableBrowseModeByDefault" property on app modules to leave browse mode off by default. (#8846)


= 2019.1.1 =
This point release fixes the following bugs:
- NVDA no longer causes Excel 2007 to crash or refuses to report if a cell has a formula. (#9431)
- Google Chrome no longer crashes when interacting with certain listboxes. (#9364)
- An issue has been fixed which prevented copying a users configuration to the system configuration profile. (#9448)
- In Microsoft Excel, NVDA again uses the localized message when reporting the location of merged cells. (#9471)


= 2019.1 =
Highlights of this release include performance improvements when accessing both Microsoft word and Excel, stability and security improvements such as support for add-ons with version compatibility information, and many other bug fixes.

0 comments on commit db34329

Please sign in to comment.
You can’t perform that action at this time.