From f77de9beabdef8c23d216792ff194c30cdd1270d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Caol=C3=A1n=20McNamara?= Date: Wed, 10 Jan 2018 14:27:35 +0000 Subject: [PATCH] limit WEBSERVICE to http[s] protocols MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit and like excel... 'For protocols that aren’t supported, such as ftp:// or file://, WEBSERVICE returns the #VALUE! error value.' Change-Id: I0e9c6fd3426fad56a199eafac48de9b0f23914b3 Reviewed-on: https://gerrit.libreoffice.org/47776 Tested-by: Jenkins Reviewed-by: Markus Mohrhard (cherry picked from commit a916fc0c0e0e8b10cb4158fa0fa173fe205d434a) Gbp-Pq: Name WEBSERVICE-DDE.diff --- sc/Library_sc.mk | 1 + sc/inc/document.hxx | 8 +- sc/inc/documentlinkmgr.hxx | 6 +- sc/source/core/data/conditio.cxx | 6 ++ sc/source/core/data/documen2.cxx | 2 +- sc/source/core/data/documen8.cxx | 23 +++++ sc/source/core/data/formulacell.cxx | 7 +- sc/source/core/inc/webservicelink.hxx | 49 ++++++++++ sc/source/core/tool/interpr2.cxx | 8 +- sc/source/core/tool/interpr7.cxx | 100 +++++++++++++++----- sc/source/core/tool/rangenam.cxx | 8 +- sc/source/core/tool/webservicelink.cxx | 106 ++++++++++++++++++++++ sc/source/filter/excel/excform.cxx | 1 + sc/source/filter/excel/excform8.cxx | 1 + sc/source/filter/excel/impop.cxx | 1 + sc/source/filter/excel/xicontent.cxx | 6 ++ sc/source/filter/excel/xiname.cxx | 3 + sc/source/filter/oox/condformatbuffer.cxx | 2 + sc/source/filter/oox/defnamesbuffer.cxx | 2 + sc/source/filter/oox/formulabuffer.cxx | 4 + sc/source/ui/docshell/docsh4.cxx | 4 +- sc/source/ui/docshell/documentlinkmgr.cxx | 20 +++- sc/source/ui/view/tabvwsh4.cxx | 2 +- 23 files changed, 325 insertions(+), 45 deletions(-) create mode 100644 sc/source/core/inc/webservicelink.hxx create mode 100644 sc/source/core/tool/webservicelink.cxx diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 0ef50c3b6b0..22f316031e0 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -285,6 +285,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/tool/unitconv \ sc/source/core/tool/userlist \ sc/source/core/tool/viewopti \ + sc/source/core/tool/webservicelink \ sc/source/core/tool/zforauto \ sc/source/filter/xml/datastreamimport \ sc/source/filter/xml/XMLCalculationSettingsContext \ diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index b17296e539f..ec1bf3cb176 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -447,7 +447,7 @@ private: // for detective update, is set for each change of a formula bool bDetectiveDirty; - bool bHasMacroFunc; // valid only after loading + bool bLinkFormulaNeedingCheck; // valid only after loading, for ocDde and ocWebservice sal_uInt8 nAsianCompression; sal_uInt8 nAsianKerning; @@ -1910,8 +1910,10 @@ public: bool IsDetectiveDirty() const { return bDetectiveDirty; } void SetDetectiveDirty(bool bSet) { bDetectiveDirty = bSet; } - bool GetHasMacroFunc() const { return bHasMacroFunc; } - void SetHasMacroFunc(bool bSet) { bHasMacroFunc = bSet; } + bool HasLinkFormulaNeedingCheck() const { return bLinkFormulaNeedingCheck; } + void SetLinkFormulaNeedingCheck(bool bSet) { bLinkFormulaNeedingCheck = bSet; } + /** Check token array and set link check if ocDde/ocWebservice is contained. */ + SC_DLLPUBLIC void CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode ); static bool CheckMacroWarn(); diff --git a/sc/inc/documentlinkmgr.hxx b/sc/inc/documentlinkmgr.hxx index d5d801a4aeb..86dba66f2d3 100644 --- a/sc/inc/documentlinkmgr.hxx +++ b/sc/inc/documentlinkmgr.hxx @@ -55,9 +55,9 @@ public: bool idleCheckLinks(); bool hasDdeLinks() const; - bool hasDdeOrOleLinks() const; + bool hasDdeOrOleOrWebServiceLinks() const; - bool updateDdeOrOleLinks(vcl::Window* pWin); + bool updateDdeOrOleOrWebServiceLinks(vcl::Window* pWin); void updateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem ); @@ -65,7 +65,7 @@ public: void disconnectDdeLinks(); private: - bool hasDdeOrOleLinks(bool bDde, bool bOle) const; + bool hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const; }; } diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx index 7fd1ef53ac6..ba2767c2798 100644 --- a/sc/source/core/data/conditio.cxx +++ b/sc/source/core/data/conditio.cxx @@ -521,6 +521,12 @@ void ScConditionEntry::CompileXML() Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar1), GetExpression(aSrcPos, 1, 0, eTempGrammar2), aStrNmsp1, aStrNmsp2, eTempGrammar1, eTempGrammar2, true ); + + // Importing ocDde/ocWebservice? + if (pFormula1) + mpDoc->CheckLinkFormulaNeedingCheck(*pFormula1); + if (pFormula2) + mpDoc->CheckLinkFormulaNeedingCheck(*pFormula2); } void ScConditionEntry::SetSrcString( const OUString& rNew ) diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index 28e24681335..ef1f8cc29c3 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -200,7 +200,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) : bInDtorClear( false ), bExpandRefs( false ), bDetectiveDirty( false ), - bHasMacroFunc( false ), + bLinkFormulaNeedingCheck( false ), nAsianCompression(SC_ASIANCOMPRESSION_INVALID), nAsianKerning(SC_ASIANKERNING_INVALID), bPastingDrawFromOtherDoc( false ), diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx index a84c2d09a01..deb908f5f49 100644 --- a/sc/source/core/data/documen8.cxx +++ b/sc/source/core/data/documen8.cxx @@ -88,6 +88,7 @@ #include "stringutil.hxx" #include #include +#include #include @@ -1153,6 +1154,28 @@ void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode, } } +void ScDocument::CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode ) +{ + if (HasLinkFormulaNeedingCheck()) + return; + + // Prefer RPN over tokenized formula if available. + if (rCode.GetCodeLen()) + { + if (rCode.HasOpCodeRPN(ocDde) || rCode.HasOpCodeRPN(ocWebservice)) + SetLinkFormulaNeedingCheck(true); + } + else if (rCode.GetLen()) + { + if (rCode.HasOpCode(ocDde) || rCode.HasOpCode(ocWebservice)) + SetLinkFormulaNeedingCheck(true); + } + else + { + assert(!"called with empty ScTokenArray"); + } +} + // TimerDelays etc. void ScDocument::KeyInput( const KeyEvent& ) { diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index a9cfdec8f7f..b7d8031c6c6 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -1363,10 +1363,9 @@ void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rPr bChanged = true; } - // Same as in Load: after loading, it must be known if ocMacro is in any formula - // (for macro warning, CompileXML is called at the end of loading XML file) - if ( !pDocument->GetHasMacroFunc() && pCode->HasOpCodeRPN( ocMacro ) ) - pDocument->SetHasMacroFunc( true ); + // After loading, it must be known if ocDde/ocWebservice is in any formula + // (for external links warning, CompileXML is called at the end of loading XML file) + pDocument->CheckLinkFormulaNeedingCheck(*pCode); //volatile cells must be added here for import if( pCode->IsRecalcModeAlways() || pCode->IsRecalcModeForced() || diff --git a/sc/source/core/inc/webservicelink.hxx b/sc/source/core/inc/webservicelink.hxx new file mode 100644 index 00000000000..e61ebfdb434 --- /dev/null +++ b/sc/source/core/inc/webservicelink.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_SC_SOURCE_CORE_INC_WEBSERVICE_HXX +#define INCLUDED_SC_SOURCE_CORE_INC_WEBSERVICE_HXX + +#include +#include +#include +#include + +class ScDocument; + +class ScWebServiceLink : public ::sfx2::SvBaseLink, public SvtBroadcaster +{ +private: + ScDocument* pDoc; + OUString aURL; // connection/ link data + bool bHasResult; // is set aResult is useful + OUString aResult; + +public: + ScWebServiceLink(ScDocument* pD, const OUString& rURL); + virtual ~ScWebServiceLink() override; + + // SvBaseLink override: + virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(const OUString& rMimeType, + const css::uno::Any& rValue) override; + + // SvtBroadcaster override: + virtual void ListenersGone() override; + + // for interpreter: + + const OUString& GetResult() const { return aResult; } + bool HasResult() const { return bHasResult; } + + const OUString& GetURL() const { return aURL; } +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index 38523e5e7e5..6dc86605534 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -2520,8 +2520,14 @@ void ScInterpreter::ScDde() pBindings->Invalidate( SID_LINKS ); // Link-Manager enablen } + //if the document was just loaded, but the ScDdeLink entry was missing, then + //don't update this link until the links are updated in response to the users + //decision + if (!pDok->HasLinkFormulaNeedingCheck()) + { //TODO: evaluate asynchron ??? - pLink->TryUpdate(); // TryUpdate doesn't call Update multiple times + pLink->TryUpdate(); // TryUpdate doesn't call Update multiple times + } if (pMyFormulaCell) { diff --git a/sc/source/core/tool/interpr7.cxx b/sc/source/core/tool/interpr7.cxx index 2d48c6b74ad..b475b1c99e3 100644 --- a/sc/source/core/tool/interpr7.cxx +++ b/sc/source/core/tool/interpr7.cxx @@ -13,7 +13,9 @@ #include "scmatrix.hxx" #include #include +#include #include +#include #include #include @@ -23,6 +25,10 @@ #include #include #include +#include +#include + +#include #include #include @@ -228,6 +234,22 @@ void ScInterpreter::ScFilterXML() } } +static ScWebServiceLink* lcl_GetWebServiceLink(const sfx2::LinkManager* pLinkMgr, const OUString& rURL) +{ + size_t nCount = pLinkMgr->GetLinks().size(); + for (size_t i=0; iGetLinks()[i].get(); + if (ScWebServiceLink* pLink = dynamic_cast(pBase)) + { + if (pLink->GetURL() == rURL) + return pLink; + } + } + + return nullptr; +} + void ScInterpreter::ScWebservice() { sal_uInt8 nParamCount = GetByte(); @@ -241,48 +263,76 @@ void ScInterpreter::ScWebservice() return; } - uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY ); - if(!xFileAccess.is()) + INetURLObject aObj(aURI, INetProtocol::File); + INetProtocol eProtocol = aObj.GetProtocol(); + if (eProtocol != INetProtocol::Http && eProtocol != INetProtocol::Https) { PushError( formula::errNoValue ); return; } - uno::Reference< io::XInputStream > xStream; - try { - xStream = xFileAccess->openFileRead( aURI ); - } - catch (...) - { - // don't let any exceptions pass - PushError( formula::errNoValue ); - return; - } - if ( !xStream.is() ) + if (!mpLinkManager) { PushError( formula::errNoValue ); return; } - const sal_Int32 BUF_LEN = 8000; - uno::Sequence< sal_Int8 > buffer( BUF_LEN ); - OStringBuffer aBuffer( 64000 ); + // Need to reinterpret after loading (build links) + if (rArr.IsRecalcModeNormal()) + rArr.SetExclusiveRecalcModeOnLoad(); - sal_Int32 nRead = 0; - while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN ) + // while the link is not evaluated, idle must be disabled (to avoid circular references) + bool bOldEnabled = pDok->IsIdleEnabled(); + pDok->EnableIdle(false); + + // Get/ Create link object + ScWebServiceLink* pLink = lcl_GetWebServiceLink(mpLinkManager, aURI); + + bool bWasError = (pMyFormulaCell && pMyFormulaCell->GetRawError() != formula::errNoCode); + + if (!pLink) { - aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead ); - } + pLink = new ScWebServiceLink(pDok, aURI); + mpLinkManager->InsertFileLink(*pLink, OBJECT_CLIENT_FILE, aURI); + if ( mpLinkManager->GetLinks().size() == 1 ) // the first one? + { + SfxBindings* pBindings = pDok->GetViewBindings(); + if (pBindings) + pBindings->Invalidate( SID_LINKS ); // Link-Manager enabled + } - if ( nRead > 0 ) + //if the document was just loaded, but the ScDdeLink entry was missing, then + //don't update this link until the links are updated in response to the users + //decision + if (!pDok->HasLinkFormulaNeedingCheck()) + { + pLink->Update(); + } + + if (pMyFormulaCell) + { + // StartListening after the Update to avoid circular references + pMyFormulaCell->StartListening(*pLink); + } + } + else { - aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead ); + if (pMyFormulaCell) + pMyFormulaCell->StartListening(*pLink); } - xStream->closeInput(); + // If an new Error from Reschedule appears when the link is executed then reset the errorflag + if (pMyFormulaCell && pMyFormulaCell->GetRawError() != formula::errNoCode && !bWasError) + pMyFormulaCell->SetErrCode(formula::errNoCode); + + // check the value + if (pLink->HasResult()) + PushString(pLink->GetResult()); + else + PushError(formula::errNoValue); - OUString aContent = OStringToOUString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); - PushString( aContent ); + pDok->EnableIdle(bOldEnabled); + mpLinkManager->CloseCachedComps(); } } diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx index 7626e16ae5f..d147b101de6 100644 --- a/sc/source/core/tool/rangenam.cxx +++ b/sc/source/core/tool/rangenam.cxx @@ -64,9 +64,14 @@ ScRangeData::ScRangeData( ScDocument* pDok, mnMaxCol (-1) { if (!rSymbol.isEmpty()) - CompileRangeData( rSymbol, pDoc->IsImportingXML()); + { // Let the compiler set an error on unknown names for a subsequent // CompileUnresolvedXML(). + const bool bImporting = pDoc->IsImportingXML(); + CompileRangeData( rSymbol, bImporting); + if (bImporting) + pDoc->CheckLinkFormulaNeedingCheck( *pCode); + } else { // #i63513#/#i65690# don't leave pCode as NULL. @@ -199,6 +204,7 @@ void ScRangeData::CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ) // Don't let the compiler set an error for unknown names on final // compile, errors are handled by the interpreter thereafter. CompileRangeData( aSymbol, false); + rCxt.getDoc()->CheckLinkFormulaNeedingCheck( *pCode); } } diff --git a/sc/source/core/tool/webservicelink.cxx b/sc/source/core/tool/webservicelink.cxx new file mode 100644 index 00000000000..82310f2b135 --- /dev/null +++ b/sc/source/core/tool/webservicelink.cxx @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ScWebServiceLink::ScWebServiceLink(ScDocument* pD, const OUString& rURL) + : ::sfx2::SvBaseLink(SfxLinkUpdateMode::ALWAYS, SotClipboardFormatId::STRING) + , pDoc(pD) + , aURL(rURL) + , bHasResult(false) +{ +} + +ScWebServiceLink::~ScWebServiceLink() {} + +sfx2::SvBaseLink::UpdateResult ScWebServiceLink::DataChanged(const OUString&, const css::uno::Any&) +{ + aResult.clear(); + bHasResult = false; + + css::uno::Reference xFileAccess( + css::ucb::SimpleFileAccess::create(comphelper::getProcessComponentContext()), + css::uno::UNO_QUERY); + if (!xFileAccess.is()) + return ERROR_GENERAL; + + css::uno::Reference xStream; + try + { + xStream = xFileAccess->openFileRead(aURL); + } + catch (...) + { + // don't let any exceptions pass + return ERROR_GENERAL; + } + if (!xStream.is()) + return ERROR_GENERAL; + + const sal_Int32 BUF_LEN = 8000; + css::uno::Sequence buffer(BUF_LEN); + OStringBuffer aBuffer(64000); + + sal_Int32 nRead = 0; + while ((nRead = xStream->readBytes(buffer, BUF_LEN)) == BUF_LEN) + aBuffer.append(reinterpret_cast(buffer.getConstArray()), nRead); + + if (nRead > 0) + aBuffer.append(reinterpret_cast(buffer.getConstArray()), nRead); + + xStream->closeInput(); + + aResult = OStringToOUString(aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8); + bHasResult = true; + + // Something happened... + if (HasListeners()) + { + Broadcast(ScHint(SC_HINT_DATACHANGED, ScAddress())); + pDoc->TrackFormulas(); // must happen immediately + pDoc->StartTrackTimer(); + } + + return SUCCESS; +} + +void ScWebServiceLink::ListenersGone() +{ + ScDocument* pStackDoc = pDoc; // member pDoc can't be used after removing the link + + sfx2::LinkManager* pLinkMgr = pDoc->GetLinkManager(); + pLinkMgr->Remove(this); // deletes this + + if (pLinkMgr->GetLinks().empty()) // deleted the last one ? + { + SfxBindings* pBindings = pStackDoc->GetViewBindings(); // don't use member pDoc! + if (pBindings) + pBindings->Invalidate(SID_LINKS); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx index c3190550a68..7fa06662194 100644 --- a/sc/source/filter/excel/excform.cxx +++ b/sc/source/filter/excel/excform.cxx @@ -157,6 +157,7 @@ void ImportExcel::Formula( { pCell = new ScFormulaCell(&rDoc.getDoc(), aScPos, *pResult); pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8); + rDoc.getDoc().CheckLinkFormulaNeedingCheck( *pCell->GetCode()); rDoc.getDoc().EnsureTable(aScPos.Tab()); rDoc.setFormulaCell(aScPos, pCell); SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, pCell); diff --git a/sc/source/filter/excel/excform8.cxx b/sc/source/filter/excel/excform8.cxx index bea8ba395a8..b5c9fef4686 100644 --- a/sc/source/filter/excel/excform8.cxx +++ b/sc/source/filter/excel/excform8.cxx @@ -730,6 +730,7 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn, << nMerk0 << ocClose; aPool >> aStack; pExtName->CreateDdeData( GetDoc(), aApplic, aTopic ); + GetDoc().SetLinkFormulaNeedingCheck(true); } } break; diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx index 6d27232ffd6..1c25921705c 100644 --- a/sc/source/filter/excel/impop.cxx +++ b/sc/source/filter/excel/impop.cxx @@ -867,6 +867,7 @@ void ImportExcel::Shrfmla() ScFormulaCell* pCell = new ScFormulaCell(pD, aPos, *pErgebnis); pCell->GetCode()->WrapReference(aPos, EXC_MAXCOL8, EXC_MAXROW8); + rDoc.getDoc().CheckLinkFormulaNeedingCheck( *pCell->GetCode()); rDoc.getDoc().EnsureTable(aPos.Tab()); rDoc.setFormulaCell(aPos, pCell); pCell->SetNeedNumberFormat(false); diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx index 05a142d8b1f..a863f9beda0 100644 --- a/sc/source/filter/excel/xicontent.cxx +++ b/sc/source/filter/excel/xicontent.cxx @@ -663,7 +663,10 @@ void XclImpCondFormat::ReadCF( XclImpStream& rStrm ) rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize1, false, FT_CondFormat ); // formula converter owns pTokArr -> create a copy of the token array if( pTokArr ) + { xTokArr1.reset( pTokArr->Clone() ); + GetDocRef().CheckLinkFormulaNeedingCheck( *xTokArr1); + } } ::std::unique_ptr< ScTokenArray > pTokArr2; @@ -674,7 +677,10 @@ void XclImpCondFormat::ReadCF( XclImpStream& rStrm ) rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize2, false, FT_CondFormat ); // formula converter owns pTokArr -> create a copy of the token array if( pTokArr ) + { pTokArr2.reset( pTokArr->Clone() ); + GetDocRef().CheckLinkFormulaNeedingCheck( *pTokArr2); + } } // *** create the Calc conditional formatting *** diff --git a/sc/source/filter/excel/xiname.cxx b/sc/source/filter/excel/xiname.cxx index d09661503c6..8decfc00e8e 100644 --- a/sc/source/filter/excel/xiname.cxx +++ b/sc/source/filter/excel/xiname.cxx @@ -265,7 +265,10 @@ void XclImpName::InsertName(const ScTokenArray* pArray) } } if (pData) + { + GetDoc().CheckLinkFormulaNeedingCheck( *pData->GetCode()); mpScData = pData; // cache for later use + } } XclImpNameManager::XclImpNameManager( const XclImpRoot& rRoot ) : diff --git a/sc/source/filter/oox/condformatbuffer.cxx b/sc/source/filter/oox/condformatbuffer.cxx index 1c1eadd8851..8526d7ffea3 100644 --- a/sc/source/filter/oox/condformatbuffer.cxx +++ b/sc/source/filter/oox/condformatbuffer.cxx @@ -875,11 +875,13 @@ void CondFormatRule::finalizeImport() { pTokenArray2.reset(new ScTokenArray()); ScTokenConversion::ConvertToTokenArray( rDoc, *pTokenArray2.get(), maModel.maFormulas[ 1 ] ); + rDoc.CheckLinkFormulaNeedingCheck( *pTokenArray2.get()); } ScTokenArray aTokenArray; OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId ); ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, maModel.maFormulas[ 0 ] ); + rDoc.CheckLinkFormulaNeedingCheck( aTokenArray); ScCondFormatEntry* pNewEntry = new ScCondFormatEntry(eOperator, &aTokenArray, pTokenArray2.get(), &rDoc, aPos, aStyleName); mpFormat->AddEntry(pNewEntry); diff --git a/sc/source/filter/oox/defnamesbuffer.cxx b/sc/source/filter/oox/defnamesbuffer.cxx index 9de5851e397..586511d1d25 100644 --- a/sc/source/filter/oox/defnamesbuffer.cxx +++ b/sc/source/filter/oox/defnamesbuffer.cxx @@ -39,6 +39,7 @@ #include "tokenarray.hxx" #include "tokenuno.hxx" #include "compiler.hxx" +#include "document.hxx" namespace oox { namespace xls { @@ -339,6 +340,7 @@ std::unique_ptr DefinedName::getScTokens( // after, a resulting error must be reset. sal_uInt16 nErr = pArray->GetCodeError(); aCompiler.CompileTokenArray(); + getScDocument().CheckLinkFormulaNeedingCheck( *pArray); pArray->DelRPN(); pArray->SetCodeError(nErr); diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx index 41c99f80062..b139ac97524 100644 --- a/sc/source/filter/oox/formulabuffer.cxx +++ b/sc/source/filter/oox/formulabuffer.cxx @@ -228,6 +228,10 @@ void applyCellFormulas( continue; aCompiler.CompileTokenArray(); // Generate RPN tokens. + + // Check if ocDde/ocWebservice is in any formula for external links warning. + rDoc.getDoc().CheckLinkFormulaNeedingCheck(*pCode); + ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, pCode); rDoc.setFormulaCell(aPos, pCell); rCache.store(aPos, pCell); diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index 853692cf898..0e7671bdeff 100644 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -448,7 +448,7 @@ void ScDocShell::Execute( SfxRequest& rReq ) ReloadTabLinks(); aDocument.UpdateExternalRefLinks(GetActiveDialogParent()); - bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleLinks(GetActiveDialogParent()); + bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleOrWebServiceLinks(GetActiveDialogParent()); if (bAnyDde) { @@ -470,6 +470,8 @@ void ScDocShell::Execute( SfxRequest& rReq ) rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); rReq.Ignore(); } + + rDoc.SetLinkFormulaNeedingCheck(false); } break; diff --git a/sc/source/ui/docshell/documentlinkmgr.cxx b/sc/source/ui/docshell/documentlinkmgr.cxx index 520b8542afc..b8a9df65cb6 100644 --- a/sc/source/ui/docshell/documentlinkmgr.cxx +++ b/sc/source/ui/docshell/documentlinkmgr.cxx @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -115,15 +116,15 @@ bool DocumentLinkManager::idleCheckLinks() bool DocumentLinkManager::hasDdeLinks() const { - return hasDdeOrOleLinks(true, false); + return hasDdeOrOleOrWebServiceLinks(true, false, false); } -bool DocumentLinkManager::hasDdeOrOleLinks() const +bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks() const { - return hasDdeOrOleLinks(true, true); + return hasDdeOrOleOrWebServiceLinks(true, true, true); } -bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const +bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const { if (!mpImpl->mpLinkManager) return false; @@ -136,12 +137,14 @@ bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const return true; if (bOle && dynamic_cast(pBase)) return true; + if (bWebService && dynamic_cast(pBase)) + return true; } return false; } -bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin ) +bool DocumentLinkManager::updateDdeOrOleOrWebServiceLinks(vcl::Window* pWin) { if (!mpImpl->mpLinkManager) return false; @@ -163,6 +166,13 @@ bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin ) continue; } + ScWebServiceLink* pWebserviceLink = dynamic_cast(pBase); + if (pWebserviceLink) + { + pWebserviceLink->Update(); + continue; + } + ScDdeLink* pDdeLink = dynamic_cast(pBase); if (!pDdeLink) continue; diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx index a8f319708bb..f203b13bbc1 100644 --- a/sc/source/ui/view/tabvwsh4.cxx +++ b/sc/source/ui/view/tabvwsh4.cxx @@ -1564,7 +1564,7 @@ void ScTabViewShell::Construct( TriState nForceDesignMode ) if (!bLink) { const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager(); - if (rMgr.hasDdeOrOleLinks() || rDoc.HasAreaLinks()) + if (rDoc.HasLinkFormulaNeedingCheck() || rDoc.HasAreaLinks() || rMgr.hasDdeOrOleOrWebServiceLinks()) bLink = true; } if (bLink) -- 2.30.2