configure.ac | 2 embeddedobj/source/commonembedding/visobj.cxx | 8 - include/svx/svdoole2.hxx | 16 ++ sc/Library_sc.mk | 1 sc/inc/document.hxx | 8 - sc/inc/documentlinkmgr.hxx | 5 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/interpre.hxx | 5 sc/source/core/inc/webservicelink.hxx | 49 ++++++ sc/source/core/tool/interpr2.cxx | 8 - sc/source/core/tool/interpr4.cxx | 1 sc/source/core/tool/interpr7.cxx | 104 ++++++++++--- 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/docsh.cxx | 7 sc/source/ui/docshell/docsh4.cxx | 14 + sc/source/ui/docshell/documentlinkmgr.cxx | 36 ++++ sc/source/ui/view/tabvwsh4.cxx | 2 sd/source/core/drawdoc.cxx | 6 sd/source/ui/docshell/docshel4.cxx | 4 svx/source/svdraw/svdoole2.cxx | 20 -- svx/source/unodraw/unoshap4.cxx | 4 sw/source/core/doc/DocumentLinksAdministrationManager.cxx | 83 ++++++---- sw/source/uibase/app/docshini.cxx | 3 35 files changed, 452 insertions(+), 106 deletions(-)
New commits: commit b15ef43a1c86c626a52673dad1fe726643fda082 Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Fri Feb 9 13:43:58 2018 +0100 Bump version. Change-Id: Ie119ca00391049bac1835d1f632499a0bf1edaf7 diff --git a/configure.ac b/configure.ac index b9e3b49887b7..f8f03396cc19 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl in order to create a configure script. # several non-alphanumeric characters, those are split off and used only for the # ABOUTBOXPRODUCTVERSIONSUFFIX in openoffice.lst. Why that is necessary, no idea. -AC_INIT([LibreOffice],[5.0.7.0.0+],[],[],[http://documentfoundation.org/]) +AC_INIT([LibreOffice],[5.0.7.1],[],[],[http://documentfoundation.org/]) AC_PREREQ([2.59]) commit e69c24e82ab0ba81c58428e918033da4112c2109 Author: Eike Rathke <er...@redhat.com> Date: Mon Jan 29 18:19:33 2018 +0100 CheckLinkFormulaNeedingCheck() for named expressions This is a combination of 3 commits. CheckLinkFormulaNeedingCheck() for .ods named expressions This is specifically necessary for named expressions that are used in conditional format formulas, for which RPN is generated at a later stage, not during import. (cherry picked from commit eae9648e99be53ba441d9d8207aac6f3ce211ef2) CheckLinkFormulaNeedingCheck() for .xls named expressions (cherry picked from commit 8512f13c42ae3fbb287a555616fe10ff04295616) CheckLinkFormulaNeedingCheck() for .xlsx named expressions (cherry picked from commit a1f933ee2b9e23a505d937035821e9571cf4119c) Conflicts: sc/source/filter/oox/defnamesbuffer.cxx e03cb5767c34f8157a492a6d6c3b0700d065052d 217c89822ab477a6c383d170ae739e44efd10fa3 Change-Id: I54ab8dc14f81d6b18b0d17f448187d19d8e396fc Reviewed-on: https://gerrit.libreoffice.org/48858 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx index 4235ef772f22..f1f8b9d56052 100644 --- a/sc/source/core/tool/rangenam.cxx +++ b/sc/source/core/tool/rangenam.cxx @@ -63,9 +63,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. @@ -198,6 +203,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/filter/excel/xiname.cxx b/sc/source/filter/excel/xiname.cxx index c1bee5af50f6..344ecb6a8787 100644 --- a/sc/source/filter/excel/xiname.cxx +++ b/sc/source/filter/excel/xiname.cxx @@ -264,7 +264,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/defnamesbuffer.cxx b/sc/source/filter/oox/defnamesbuffer.cxx index fa2a0cf6b685..c4cb011d0a54 100644 --- a/sc/source/filter/oox/defnamesbuffer.cxx +++ b/sc/source/filter/oox/defnamesbuffer.cxx @@ -38,6 +38,7 @@ #include "tokenarray.hxx" #include "tokenuno.hxx" #include "compiler.hxx" +#include "document.hxx" namespace oox { namespace xls { @@ -392,6 +393,7 @@ std::unique_ptr<ScTokenArray> DefinedName::getScTokens() // after, a resulting error must be reset. sal_uInt16 nErr = pArray->GetCodeError(); aCompiler.CompileTokenArray(); + getScDocument().CheckLinkFormulaNeedingCheck( *pArray); pArray->DelRPN(); pArray->SetCodeError(nErr); commit 6e7192dd51706101b937156e3de6cfe3264107db Author: Eike Rathke <er...@redhat.com> Date: Thu Jan 25 13:20:27 2018 +0100 CheckLinkFormulaNeedingCheck() for conditional format expressions This is a combination of 4 commits. Prepare CheckLinkFormulaNeedingCheck() to use either RPN or tokenized code Conditional format formulas aren't finally compiled until needed so the check will have to operate on the tokenized expression instead of RPN code. (cherry picked from commit faa0305ba3d0dc698fce4915d4f3a1fb52422380) CheckLinkFormulaNeedingCheck() for .ods conditional format expressions (cherry picked from commit 2930ba2ac5d9423f2848b968edcd8ddc71966186) CheckLinkFormulaNeedingCheck() for .xlsx conditional format expressions (cherry picked from commit fef24d9f999ee54d7936900485d97ff26656f517) CheckLinkFormulaNeedingCheck() for .xls conditional format expressions (cherry picked from commit af2a2a0c72db312902e466c36697b5c198041e82) 45eb1ab5efa0ec9da2663f20427d2474ce300826 31ede1a23223a798141a0891deeabd8cf88fff58 afa112cc591b411d80ead48bf726788d361f6eb3 Change-Id: I68837e9bd33f125ab47b10b1a6fa18175abd1627 Reviewed-on: https://gerrit.libreoffice.org/48719 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx index f087af6efc7a..862736713c25 100644 --- a/sc/source/core/data/conditio.cxx +++ b/sc/source/core/data/conditio.cxx @@ -471,6 +471,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/documen8.cxx b/sc/source/core/data/documen8.cxx index f6a43a1d587e..7391e1cca5b4 100644 --- a/sc/source/core/data/documen8.cxx +++ b/sc/source/core/data/documen8.cxx @@ -1164,8 +1164,21 @@ void ScDocument::CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode ) if (HasLinkFormulaNeedingCheck()) return; - if (rCode.HasOpCodeRPN(ocDde) || rCode.HasOpCodeRPN(ocWebservice)) - SetLinkFormulaNeedingCheck(true); + // 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. diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx index 96130197302b..c63063f5b957 100644 --- a/sc/source/filter/excel/xicontent.cxx +++ b/sc/source/filter/excel/xicontent.cxx @@ -641,7 +641,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() ); + GetDoc().CheckLinkFormulaNeedingCheck( *xTokArr1); + } } ::std::unique_ptr< ScTokenArray > pTokArr2; @@ -652,7 +655,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() ); + GetDoc().CheckLinkFormulaNeedingCheck( *pTokArr2); + } } // *** create the Calc conditional formatting *** diff --git a/sc/source/filter/oox/condformatbuffer.cxx b/sc/source/filter/oox/condformatbuffer.cxx index 955b304c24eb..9ffcf514de6a 100644 --- a/sc/source/filter/oox/condformatbuffer.cxx +++ b/sc/source/filter/oox/condformatbuffer.cxx @@ -882,11 +882,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); commit 7076742b38c41c3877ace5aa12d49b396a5939dc Author: Eike Rathke <er...@redhat.com> Date: Wed Jan 17 22:22:55 2018 +0100 CheckLinkFormulaNeedingCheck() for .xls and .xlsx formula cells This is a combination of 3 commits. Move implementation to CheckLinkFormulaNeedingCheck() for further reuse (cherry picked from commit 55e484c7bcd3ef218e08d3fd93f97bf98fd8cb7f) CheckLinkFormulaNeedingCheck() for .xlsx cell formulas (cherry picked from commit f96dbc3dd9c33202f75e29ef49d962386595995d) CheckLinkFormulaNeedingCheck() for .xls cell formulas (cherry picked from commit 6bc48275558c3f76c4da25eb8af3c48583ac5599) a6dd195f7eb4d43483e87eeca59f651e7bf2dcb8 2587fbc4fec39b6f2c8e733331815a2953dee308 Change-Id: I541d2b6e12a88371c064b901b00e71206ee0c18e Reviewed-on: https://gerrit.libreoffice.org/48143 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index b5d6f3217544..77ff3883889a 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -1795,6 +1795,8 @@ public: 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/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx index 2bdfa30e3160..f6a43a1d587e 100644 --- a/sc/source/core/data/documen8.cxx +++ b/sc/source/core/data/documen8.cxx @@ -88,6 +88,7 @@ #include "stringutil.hxx" #include <documentlinkmgr.hxx> #include <scopetools.hxx> +#include <tokenarray.hxx> #include <boost/scoped_ptr.hpp> @@ -1158,6 +1159,15 @@ void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode, } } +void ScDocument::CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode ) +{ + if (HasLinkFormulaNeedingCheck()) + return; + + if (rCode.HasOpCodeRPN(ocDde) || rCode.HasOpCodeRPN(ocWebservice)) + SetLinkFormulaNeedingCheck(true); +} + // TimerDelays etc. void ScDocument::KeyInput( const KeyEvent& ) { diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index 96316392ffc3..49d3133f42fe 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -1353,8 +1353,7 @@ void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rPr // 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) - if (!pDocument->HasLinkFormulaNeedingCheck() && (pCode->HasOpCodeRPN(ocDde) || pCode->HasOpCodeRPN(ocWebservice))) - pDocument->SetLinkFormulaNeedingCheck(true); + pDocument->CheckLinkFormulaNeedingCheck(*pCode); //volatile cells must be added here for import if( pCode->IsRecalcModeAlways() || pCode->IsRecalcModeForced() || diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx index 08399552c2a3..14be167de85e 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 ebe3b6445e57..c7e56afd1149 100644 --- a/sc/source/filter/excel/excform8.cxx +++ b/sc/source/filter/excel/excform8.cxx @@ -729,6 +729,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 904209d2bb1b..69e536e64ed3 100644 --- a/sc/source/filter/excel/impop.cxx +++ b/sc/source/filter/excel/impop.cxx @@ -866,6 +866,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/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx index 189017d65196..2d20e9d73a53 100644 --- a/sc/source/filter/oox/formulabuffer.cxx +++ b/sc/source/filter/oox/formulabuffer.cxx @@ -229,6 +229,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); commit 4b9aa0c1a0126fce36b9a47e08cbe1f72442a332 Author: Caolán McNamara <caol...@redhat.com> Date: Thu Jan 11 20:43:28 2018 +0000 handle ocWebservice similarly to ocDde might have too much in here seeing as we don't need to worry about ocWebservice calling into itself Reviewed-on: https://gerrit.libreoffice.org/47819 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Eike Rathke <er...@redhat.com> Conflicts: sc/source/core/tool/interpr7.cxx sc/source/ui/docshell/documentlinkmgr.cxx sc/source/core/tool/webservicelink.cxx Change-Id: I0145f38cc1c1f9ff514a496f7101d81cde9e7c67 diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index d2fd5cd345b9..02d3b7db1747 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -282,6 +282,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 f73be94d994b..b5d6f3217544 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -429,7 +429,7 @@ private: bool bDetectiveDirty; sal_uInt8 nMacroCallMode; // Macros per warning dialog disabled? - bool bLinkFormulaNeedingCheck; // valid only after loading, for ocDde + bool bLinkFormulaNeedingCheck; // valid only after loading, for ocDde and ocWebservice sal_uInt8 nVisSpellState; diff --git a/sc/inc/documentlinkmgr.hxx b/sc/inc/documentlinkmgr.hxx index cc42410ca3dc..d7972b14e5f0 100644 --- a/sc/inc/documentlinkmgr.hxx +++ b/sc/inc/documentlinkmgr.hxx @@ -53,9 +53,9 @@ public: bool idleCheckLinks(); bool hasDdeLinks() const; - bool hasDdeOrOleLinks() const; + bool hasDdeOrOleOrWebServiceLinks() const; - bool updateDdeOrOleLinks(vcl::Window* pWin); + bool updateDdeOrOleOrWebServiceLinks(vcl::Window* pWin); bool updateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem ); @@ -63,7 +63,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/formulacell.cxx b/sc/source/core/data/formulacell.cxx index 9a9b5705e5e2..96316392ffc3 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -1351,9 +1351,9 @@ void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rPr bChanged = true; } - // After loading, it must be known if ocDde is in any formula + // 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) - if (!pDocument->HasLinkFormulaNeedingCheck() && pCode->HasOpCodeRPN(ocDde)) + if (!pDocument->HasLinkFormulaNeedingCheck() && (pCode->HasOpCodeRPN(ocDde) || pCode->HasOpCodeRPN(ocWebservice))) pDocument->SetLinkFormulaNeedingCheck(true); //volatile cells must be added here for import diff --git a/sc/source/core/inc/webservicelink.hxx b/sc/source/core/inc/webservicelink.hxx new file mode 100644 index 000000000000..e61ebfdb4347 --- /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 <address.hxx> +#include <sfx2/lnkbase.hxx> +#include <svl/broadcast.hxx> +#include <types.hxx> + +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/interpr7.cxx b/sc/source/core/tool/interpr7.cxx index 66cc47d06606..10178c776e24 100644 --- a/sc/source/core/tool/interpr7.cxx +++ b/sc/source/core/tool/interpr7.cxx @@ -10,6 +10,8 @@ #include "interpre.hxx" #include <rtl/strbuf.hxx> #include <formula/errorcodes.hxx> +#include <sfx2/linkmgr.hxx> +#include <sfx2/bindings.hxx> #include <svtools/miscopt.hxx> #include <tools/urlobj.hxx> @@ -21,6 +23,11 @@ #include <datastreamgettime.hxx> #include <dpobject.hxx> #include <document.hxx> +#include <tokenarray.hxx> +#include <webservicelink.hxx> +#include <formulacell.hxx> + +#include <sc.hrc> #include <boost/shared_ptr.hpp> #include <cstring> @@ -146,6 +153,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; i<nCount; ++i) + { + ::sfx2::SvBaseLink* pBase = *pLinkMgr->GetLinks()[i]; + if (ScWebServiceLink* pLink = dynamic_cast<ScWebServiceLink*>(pBase)) + { + if (pLink->GetURL() == rURL) + return pLink; + } + } + + return nullptr; +} + void ScInterpreter::ScWebservice() { sal_uInt8 nParamCount = GetByte(); @@ -153,7 +176,7 @@ void ScInterpreter::ScWebservice() { OUString aURI = GetString().getString(); - if(aURI.isEmpty()) + if (aURI.isEmpty()) { PushError( errNoValue ); return; @@ -163,52 +186,72 @@ void ScInterpreter::ScWebservice() INetProtocol eProtocol = aObj.GetProtocol(); if (eProtocol != INetProtocol::Http && eProtocol != INetProtocol::Https) { - PushError( FormulaError::NoValue ); - return; - } - - uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY ); - if(!xFileAccess.is()) - { PushError( errNoValue ); return; } - uno::Reference< io::XInputStream > xStream; - try { - xStream = xFileAccess->openFileRead( aURI ); - } - catch (...) - { - // don't let any exceptions pass - PushError( errNoValue ); - return; - } - if ( !xStream.is() ) + if (!mpLinkManager) { PushError( 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(); + + // 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); - sal_Int32 nRead = 0; - while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN ) + bool bWasError = (pMyFormulaCell && pMyFormulaCell->GetRawError() != 0); + + 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() != 0 && !bWasError) + pMyFormulaCell->SetErrCode(0); + + // check the value + if (pLink->HasResult()) + PushString(pLink->GetResult()); + else + PushError(errNoValue); - OUString aContent = OStringToOUString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); - PushString( aContent ); + pDok->EnableIdle(bOldEnabled); + mpLinkManager->CloseCachedComps(); } } diff --git a/sc/source/core/tool/webservicelink.cxx b/sc/source/core/tool/webservicelink.cxx new file mode 100644 index 000000000000..82310f2b1351 --- /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 <comphelper/fileformat.h> +#include <comphelper/string.hxx> +#include <osl/thread.h> +#include <sfx2/linkmgr.hxx> +#include <sfx2/bindings.hxx> + +#include <com/sun/star/ucb/XSimpleFileAccess3.hpp> +#include <com/sun/star/ucb/SimpleFileAccess.hpp> +#include <com/sun/star/io/XInputStream.hpp> + +#include <webservicelink.hxx> +#include <brdcst.hxx> +#include <document.hxx> +#include <scmatrix.hxx> +#include <patattr.hxx> +#include <rechead.hxx> +#include <rangeseq.hxx> +#include <sc.hrc> +#include <hints.hxx> + +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<css::ucb::XSimpleFileAccess3> xFileAccess( + css::ucb::SimpleFileAccess::create(comphelper::getProcessComponentContext()), + css::uno::UNO_QUERY); + if (!xFileAccess.is()) + return ERROR_GENERAL; + + css::uno::Reference<css::io::XInputStream> 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<sal_Int8> buffer(BUF_LEN); + OStringBuffer aBuffer(64000); + + sal_Int32 nRead = 0; + while ((nRead = xStream->readBytes(buffer, BUF_LEN)) == BUF_LEN) + aBuffer.append(reinterpret_cast<const char*>(buffer.getConstArray()), nRead); + + if (nRead > 0) + aBuffer.append(reinterpret_cast<const char*>(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/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index ad8a75a44c58..2645c7f0c119 100644 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -455,7 +455,7 @@ void ScDocShell::Execute( SfxRequest& rReq ) ReloadTabLinks(); aDocument.UpdateExternalRefLinks(GetActiveDialogParent()); - bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleLinks(GetActiveDialogParent()); + bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleOrWebServiceLinks(GetActiveDialogParent()); if (bAnyDde) { diff --git a/sc/source/ui/docshell/documentlinkmgr.cxx b/sc/source/ui/docshell/documentlinkmgr.cxx index 8e5a5c3a02bb..ae8984b6950a 100644 --- a/sc/source/ui/docshell/documentlinkmgr.cxx +++ b/sc/source/ui/docshell/documentlinkmgr.cxx @@ -20,6 +20,7 @@ #include <documentlinkmgr.hxx> #include <datastream.hxx> #include <ddelink.hxx> +#include <webservicelink.hxx> #include <sc.hrc> #include <scresid.hxx> @@ -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<SdrEmbedObjectLink*>(pBase)) return true; + if (bWebService && dynamic_cast<ScWebServiceLink*>(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<ScWebServiceLink*>(pBase); + if (pWebserviceLink) + { + pWebserviceLink->Update(); + continue; + } + ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase); if (!pDdeLink) continue; diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx index 0c9b036863c0..c7209c11aa77 100644 --- a/sc/source/ui/view/tabvwsh4.cxx +++ b/sc/source/ui/view/tabvwsh4.cxx @@ -1584,7 +1584,7 @@ void ScTabViewShell::Construct( TriState nForceDesignMode ) if (!bLink) { const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager(); - if (rMgr.hasDdeOrOleLinks() || rDoc.HasAreaLinks() || rDoc.HasLinkFormulaNeedingCheck()) + if (rDoc.HasLinkFormulaNeedingCheck() || rDoc.HasAreaLinks() || rMgr.hasDdeOrOleOrWebServiceLinks()) bLink = true; } if (bLink) commit e4ddb5f96c39d13b0bdfedcefcb3e3679212a640 Author: Caolán McNamara <caol...@redhat.com> Date: Thu Jan 11 14:16:15 2018 +0000 Better handle ScDde formulas with missing dde-link entries typically each ScDde formula has a matching table:dde-link which results in a ScDdeLink getting inserted during the load. If that dde-link is missing then no ScDdeLink exists and ScDde() will create a new one without cached content. So detect that ScDde is used in the freshing loaded ods and defer fetching new content until the right time. only call GetHasMacroFunc to set SetHasMacroFunc and bHasMacroFunc is not accessed any other way, so this is an oxbow Reviewed-on: https://gerrit.libreoffice.org/47757 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit b0597ba5d745974fce752e1b677451a19350d351) Reviewed-on: https://gerrit.libreoffice.org/47818 Reviewed-by: Eike Rathke <er...@redhat.com> Conflicts: sc/qa/unit/ucalc.cxx sc/source/core/data/documen2.cxx sc/inc/document.hxx Change-Id: I016b53288076d83dd49e92e245346a5f7f560522 diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 69e6f5bd9586..f73be94d994b 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -429,7 +429,7 @@ private: bool bDetectiveDirty; sal_uInt8 nMacroCallMode; // Macros per warning dialog disabled? - bool bHasMacroFunc; // valid only after loading + bool bLinkFormulaNeedingCheck; // valid only after loading, for ocDde sal_uInt8 nVisSpellState; @@ -1793,8 +1793,8 @@ public: sal_uInt8 GetMacroCallMode() const { return nMacroCallMode; } void SetMacroCallMode(sal_uInt8 nNew) { nMacroCallMode = nNew; } - bool GetHasMacroFunc() const { return bHasMacroFunc; } - void SetHasMacroFunc(bool bSet) { bHasMacroFunc = bSet; } + bool HasLinkFormulaNeedingCheck() const { return bLinkFormulaNeedingCheck; } + void SetLinkFormulaNeedingCheck(bool bSet) { bLinkFormulaNeedingCheck = bSet; } static bool CheckMacroWarn(); diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index 8d3e4e3d3b8f..0d494c4c583d 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -202,7 +202,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) : bExpandRefs( false ), bDetectiveDirty( false ), nMacroCallMode( SC_MACROCALL_ALLOWED ), - bHasMacroFunc( false ), + bLinkFormulaNeedingCheck( false ), nVisSpellState( 0 ), nAsianCompression(SC_ASIANCOMPRESSION_INVALID), nAsianKerning(SC_ASIANKERNING_INVALID), diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index ceb7f68d6a6f..9a9b5705e5e2 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -1351,10 +1351,10 @@ 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 is in any formula + // (for external links warning, CompileXML is called at the end of loading XML file) + if (!pDocument->HasLinkFormulaNeedingCheck() && pCode->HasOpCodeRPN(ocDde)) + pDocument->SetLinkFormulaNeedingCheck(true); //volatile cells must be added here for import if( pCode->IsRecalcModeAlways() || pCode->IsRecalcModeForced() || diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index d82bc29eaff9..5f6b5af7d980 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -2421,8 +2421,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/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index 9fcf549c8920..ad8a75a44c58 100644 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -477,6 +477,8 @@ void ScDocShell::Execute( SfxRequest& rReq ) rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); rReq.Ignore(); } + + rDoc.SetLinkFormulaNeedingCheck(false); } break; diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx index ff3a5a1d94f1..0c9b036863c0 100644 --- a/sc/source/ui/view/tabvwsh4.cxx +++ b/sc/source/ui/view/tabvwsh4.cxx @@ -1584,7 +1584,7 @@ void ScTabViewShell::Construct( TriState nForceDesignMode ) if (!bLink) { const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager(); - if (rMgr.hasDdeOrOleLinks() || rDoc.HasAreaLinks()) + if (rMgr.hasDdeOrOleLinks() || rDoc.HasAreaLinks() || rDoc.HasLinkFormulaNeedingCheck()) bLink = true; } if (bLink) commit 598c4b6571ce355e1bed578fa242bf4675e0ae96 Author: Caolán McNamara <caol...@redhat.com> Date: Wed Jan 10 14:27:35 2018 +0000 limit WEBSERVICE to http[s] protocols 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 <c...@libreoffice.org> Reviewed-by: Markus Mohrhard <markus.mohrh...@googlemail.com> diff --git a/sc/source/core/tool/interpr7.cxx b/sc/source/core/tool/interpr7.cxx index ce69848d6f99..66cc47d06606 100644 --- a/sc/source/core/tool/interpr7.cxx +++ b/sc/source/core/tool/interpr7.cxx @@ -11,6 +11,7 @@ #include <rtl/strbuf.hxx> #include <formula/errorcodes.hxx> #include <svtools/miscopt.hxx> +#include <tools/urlobj.hxx> #include <com/sun/star/ucb/XSimpleFileAccess3.hpp> #include <com/sun/star/ucb/SimpleFileAccess.hpp> @@ -158,6 +159,14 @@ void ScInterpreter::ScWebservice() return; } + INetURLObject aObj(aURI, INetProtocol::File); + INetProtocol eProtocol = aObj.GetProtocol(); + if (eProtocol != INetProtocol::Http && eProtocol != INetProtocol::Https) + { + PushError( FormulaError::NoValue ); + return; + } + uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY ); if(!xFileAccess.is()) { commit 44c0bf472c736a4f94bea7046c7556377930d9b1 Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Fri Feb 9 09:43:12 2018 +0100 parts of: tdf#99371 fix for DDE link update via Function Wizard Need this for the LinkManager usage. (cherry picked from commit 6a92ada1f624b3d37976845517595e15ed5a73f6) Change-Id: If00aa50fe48f067c92eac1c9c6afdf3462bab99b diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 1a2481ee72e2..227d7d62dd53 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -25,6 +25,7 @@ #include <rtl/ustring.hxx> #include <formula/errorcodes.hxx> #include <formula/tokenarray.hxx> +#include <sfx2/linkmgr.hxx> #include "scdll.hxx" #include "scdllapi.h" #include "types.hxx" @@ -156,6 +157,7 @@ private: ScAddress aPos; ScTokenArray& rArr; ScDocument* pDok; + sfx2::LinkManager* mpLinkManager; svl::SharedStringPool& mrStrPool; formula::FormulaTokenRef xResult; ScJumpMatrix* pJumpMatrix; // currently active array condition, if any @@ -897,6 +899,9 @@ public: void SetError(sal_uInt16 nError) { if (nError && !nGlobalError) nGlobalError = nError; } + void SetLinkManager(sfx2::LinkManager* pLinkMgr) + { mpLinkManager = pLinkMgr; } + sal_uInt16 GetError() const { return nGlobalError; } formula::StackVar GetResultType() const { return xResult->GetType(); } svl::SharedString GetStringResult() const; diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 6ed55dd2fb12..9bd079878ef3 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -3457,6 +3457,7 @@ ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, , aPos(rPos) , rArr(r) , pDok(pDoc) + , mpLinkManager(pDok->GetLinkManager()) , mrStrPool(pDoc->GetSharedStringPool()) , pJumpMatrix(NULL) , pTokenMatrixMap(NULL) commit 990b132745a86ada89bedf86565c0eb05c461d39 Author: Caolán McNamara <caol...@redhat.com> Date: Tue Sep 13 12:32:04 2016 +0100 disable generation of ole previews in ODF format until after load so the user update links dialog can control their generation SdrEmbedObjectLink becomes exposed to calc so it can detect if the link dialog needs to be used to update ole links. Reviewed-on: https://gerrit.libreoffice.org/28879 Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit 74844277cc2194c9e43f5bd7a6f78a9603da32f3) Change-Id: Id1dd7ea17342140eab9307d546528747e3a98090 detangle gadzillion checks into something readable no logic change intended Change-Id: Ib6af93afc1f80b7fc36239c96d5e0a71fcbcb789 (cherry picked from commit fad9786b06d188ba6e354620f57176f3d94a6637) Unmodified default SdrOle2Obj size is 101x101 svx/source/unodraw/unoshape.cxx sets a css::awt::Size maSize to 100, 100 svx/source/unodraw/unopage.cxx increases that by 1, 1 awt::Size aSize = xShape->getSize(); aSize.Width += 1; aSize.Height += 1; to call SdrObjFactory::MakeNewObject with 101, 101 so default size is 101x101 (getWidth() vs GetWidth() confusion ?) Change-Id: I4d4375dff64d7b8e236d1a24322e749e04ee530f Reviewed-on: https://gerrit.libreoffice.org/28895 Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit 7f0a219c9ad38ae33b51ff69d545f69659691c1e) Reviewed-on: https://gerrit.libreoffice.org/28926 Reviewed-by: Michael Stahl <mst...@redhat.com> Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Eike Rathke <er...@redhat.com> Tested-by: Eike Rathke <er...@redhat.com> diff --git a/embeddedobj/source/commonembedding/visobj.cxx b/embeddedobj/source/commonembedding/visobj.cxx index fea7c3a2cf0a..918836753cbc 100644 --- a/embeddedobj/source/commonembedding/visobj.cxx +++ b/embeddedobj/source/commonembedding/visobj.cxx @@ -174,7 +174,13 @@ embed::VisualRepresentation SAL_CALL OCommonEmbeddedObject::getPreferredVisualRe bool bBackToLoaded = false; if ( m_nObjectState == embed::EmbedStates::LOADED ) { - changeState( embed::EmbedStates::RUNNING ); + awt::Size aOrigSize = getVisualAreaSize(nAspect); + changeState(embed::EmbedStates::RUNNING); + if (aOrigSize.Width != getVisualAreaSize(nAspect).Width || + aOrigSize.Height != getVisualAreaSize(nAspect).Height) + { + setVisualAreaSize(nAspect, aOrigSize); + } // the links should be switched back to loaded state for now to avoid locking problems bBackToLoaded = m_bIsLink; diff --git a/include/svx/svdoole2.hxx b/include/svx/svdoole2.hxx index f14646b20428..252a3df0c510 100644 --- a/include/svx/svdoole2.hxx +++ b/include/svx/svdoole2.hxx @@ -22,6 +22,7 @@ #include <svx/svdorect.hxx> #include <svx/svxdllapi.h> +#include <sfx2/linkmgr.hxx> #include <com/sun/star/uno/Reference.h> @@ -179,6 +180,21 @@ public: virtual SdrObject* DoConvertToPolyObj(bool bBezier, bool bAddText) const SAL_OVERRIDE; }; +class SVX_DLLPUBLIC SdrEmbedObjectLink : public sfx2::SvBaseLink +{ + SdrOle2Obj* pObj; + +public: + SdrEmbedObjectLink(SdrOle2Obj* pObj); + virtual ~SdrEmbedObjectLink(); + + virtual void Closed() SAL_OVERRIDE; + virtual ::sfx2::SvBaseLink::UpdateResult DataChanged( + const OUString& rMimeType, const css::uno::Any & rValue ) SAL_OVERRIDE; + + bool Connect() { return GetRealObject() != NULL; } +}; + #endif // INCLUDED_SVX_SVDOOLE2_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/documentlinkmgr.hxx b/sc/inc/documentlinkmgr.hxx index 0af5cf896c63..cc42410ca3dc 100644 --- a/sc/inc/documentlinkmgr.hxx +++ b/sc/inc/documentlinkmgr.hxx @@ -53,14 +53,17 @@ public: bool idleCheckLinks(); bool hasDdeLinks() const; + bool hasDdeOrOleLinks() const; - bool updateDdeLinks( vcl::Window* pWin ); + bool updateDdeOrOleLinks(vcl::Window* pWin); bool updateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem ); size_t getDdeLinkCount() const; void disconnectDdeLinks(); +private: + bool hasDdeOrOleLinks(bool bDde, bool bOle) const; }; } diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index d0c083625465..25dab86e5ca0 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -561,9 +561,12 @@ bool ScDocShell::Load( SfxMedium& rMedium ) GetUndoManager()->Clear(); - bool bRet = SfxObjectShell::Load( rMedium ); - if( bRet ) + bool bRet = SfxObjectShell::Load(rMedium); + if (bRet) { + comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer(); + rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); + if (GetMedium()) { SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, false); diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index 969c678e4ce1..9fcf549c8920 100644 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -29,6 +29,7 @@ using namespace ::com::sun::star; #include "scitems.hxx" #include <sfx2/fcontnr.hxx> +#include <sfx2/linkmgr.hxx> #include <sfx2/objface.hxx> #include <sfx2/docfile.hxx> #include <svtools/ehdl.hxx> @@ -42,6 +43,7 @@ using namespace ::com::sun::star; #include <svx/drawitem.hxx> #include <svx/fmshell.hxx> #include <svtools/xwindowitem.hxx> +#include <svx/svdoole2.hxx> #include <sfx2/passwd.hxx> #include <sfx2/filedlghelper.hxx> #include <sfx2/dispatch.hxx> @@ -407,6 +409,9 @@ void ScDocShell::Execute( SfxRequest& rReq ) break; case SID_UPDATETABLINKS: { + comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer(); + rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true); + ScDocument& rDoc = GetDocument(); ScLkUpdMode nSet = rDoc.GetLinkMode(); @@ -450,9 +455,9 @@ void ScDocShell::Execute( SfxRequest& rReq ) ReloadTabLinks(); aDocument.UpdateExternalRefLinks(GetActiveDialogParent()); - bool bAny = aDocument.GetDocLinkManager().updateDdeLinks(GetActiveDialogParent()); + bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleLinks(GetActiveDialogParent()); - if (bAny) + if (bAnyDde) { // Formeln berechnen und painten wie im TrackTimeHdl aDocument.TrackFormulas(); @@ -468,7 +473,10 @@ void ScDocShell::Execute( SfxRequest& rReq ) rReq.Done(); } else + { + rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); rReq.Ignore(); + } } break; diff --git a/sc/source/ui/docshell/documentlinkmgr.cxx b/sc/source/ui/docshell/documentlinkmgr.cxx index 42745eb3f344..8e5a5c3a02bb 100644 --- a/sc/source/ui/docshell/documentlinkmgr.cxx +++ b/sc/source/ui/docshell/documentlinkmgr.cxx @@ -23,7 +23,7 @@ #include <sc.hrc> #include <scresid.hxx> -#include <sfx2/linkmgr.hxx> +#include <svx/svdoole2.hxx> #include <vcl/layout.hxx> #include <boost/noncopyable.hpp> @@ -115,6 +115,16 @@ bool DocumentLinkManager::idleCheckLinks() bool DocumentLinkManager::hasDdeLinks() const { + return hasDdeOrOleLinks(true, false); +} + +bool DocumentLinkManager::hasDdeOrOleLinks() const +{ + return hasDdeOrOleLinks(true, true); +} + +bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const +{ if (!mpImpl->mpLinkManager) return false; @@ -122,14 +132,16 @@ bool DocumentLinkManager::hasDdeLinks() const for (size_t i = 0, n = rLinks.size(); i < n; ++i) { sfx2::SvBaseLink* pBase = *rLinks[i]; - if (dynamic_cast<ScDdeLink*>(pBase)) + if (bDde && dynamic_cast<ScDdeLink*>(pBase)) + return true; + if (bOle && dynamic_cast<SdrEmbedObjectLink*>(pBase)) return true; } return false; } -bool DocumentLinkManager::updateDdeLinks( vcl::Window* pWin ) +bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin ) { if (!mpImpl->mpLinkManager) return false; @@ -143,6 +155,14 @@ bool DocumentLinkManager::updateDdeLinks( vcl::Window* pWin ) for (size_t i = 0, n = rLinks.size(); i < n; ++i) { sfx2::SvBaseLink* pBase = *rLinks[i]; + + SdrEmbedObjectLink* pOleLink = dynamic_cast<SdrEmbedObjectLink*>(pBase); + if (pOleLink) + { + pOleLink->Update(); + continue; + } + ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase); if (!pDdeLink) continue; diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx index 64a6e9f0f063..ff3a5a1d94f1 100644 --- a/sc/source/ui/view/tabvwsh4.cxx +++ b/sc/source/ui/view/tabvwsh4.cxx @@ -1584,7 +1584,7 @@ void ScTabViewShell::Construct( TriState nForceDesignMode ) if (!bLink) { const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager(); - if (rMgr.hasDdeLinks() || rDoc.HasAreaLinks()) + if (rMgr.hasDdeOrOleLinks() || rDoc.HasAreaLinks()) bLink = true; } if (bLink) diff --git a/sd/source/core/drawdoc.cxx b/sd/source/core/drawdoc.cxx index fcf678ec669f..c216cc7b4ab6 100644 --- a/sd/source/core/drawdoc.cxx +++ b/sd/source/core/drawdoc.cxx @@ -692,6 +692,12 @@ void SdDrawDocument::UpdateAllLinks() { pDocLockedInsertingLinks = this; // lock inserting links. only links in this document should by resolved + if (mpDocSh) + { + comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = mpDocSh->getEmbeddedObjectContainer(); + rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true); + } + pLinkManager->UpdateAllLinks(); // query box: update all links? if( pDocLockedInsertingLinks == this ) diff --git a/sd/source/ui/docshell/docshel4.cxx b/sd/source/ui/docshell/docshel4.cxx index bed2fd7b4e97..06df8055e958 100644 --- a/sd/source/ui/docshell/docshel4.cxx +++ b/sd/source/ui/docshell/docshel4.cxx @@ -285,8 +285,10 @@ bool DrawDocShell::Load( SfxMedium& rMedium ) } bRet = SfxObjectShell::Load( rMedium ); - if( bRet ) + if (bRet) { + comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer(); + rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); bRet = SdXMLFilter( rMedium, *this, true, SDXMLMODE_Normal, SotStorage::GetVersion( rMedium.GetStorage() ) ).Import( nError ); } diff --git a/svx/source/svdraw/svdoole2.cxx b/svx/source/svdraw/svdoole2.cxx index 403646b6f10e..8985a3bb8a60 100644 --- a/svx/source/svdraw/svdoole2.cxx +++ b/svx/source/svdraw/svdoole2.cxx @@ -58,7 +58,6 @@ #include <comphelper/classids.hxx> #include <sot/formats.hxx> -#include <sfx2/linkmgr.hxx> #include <svtools/transfer.hxx> #include <cppuhelper/implbase5.hxx> @@ -588,25 +587,6 @@ void SdrLightEmbeddedClient_Impl::setWindow(const uno::Reference< awt::XWindow > m_xWindow = _xWindow; } - - -class SdrEmbedObjectLink : public sfx2::SvBaseLink -{ - SdrOle2Obj* pObj; - -public: - SdrEmbedObjectLink(SdrOle2Obj* pObj); - virtual ~SdrEmbedObjectLink(); - - virtual void Closed() SAL_OVERRIDE; - virtual ::sfx2::SvBaseLink::UpdateResult DataChanged( - const OUString& rMimeType, const ::com::sun::star::uno::Any & rValue ) SAL_OVERRIDE; - - bool Connect() { return GetRealObject() != NULL; } -}; - - - SdrEmbedObjectLink::SdrEmbedObjectLink(SdrOle2Obj* pObject): ::sfx2::SvBaseLink( ::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SVXB ), pObj(pObject) diff --git a/svx/source/unodraw/unoshap4.cxx b/svx/source/unodraw/unoshap4.cxx index ac463ffe9155..b31399d5a80d 100644 --- a/svx/source/unodraw/unoshap4.cxx +++ b/svx/source/unodraw/unoshap4.cxx @@ -418,7 +418,7 @@ bool SvxOle2Shape::createObject( const SvGlobalName &aClassName ) if( xObj.is() ) { Rectangle aRect = pOle2Obj->GetLogicRect(); - if ( aRect.GetWidth() == 100 && aRect.GetHeight() == 100 ) + if ( aRect.GetWidth() == 101 && aRect.GetHeight() == 101 ) { // TODO/LATER: is it possible that this method is used to create an iconified object? // default size @@ -486,7 +486,7 @@ bool SvxOle2Shape::createLink( const OUString& aLinkURL ) if( xObj.is() ) { Rectangle aRect = pOle2Obj->GetLogicRect(); - if ( aRect.GetWidth() == 100 && aRect.GetHeight() == 100 ) + if ( aRect.GetWidth() == 101 && aRect.GetHeight() == 101 ) { // default size try diff --git a/sw/source/core/doc/DocumentLinksAdministrationManager.cxx b/sw/source/core/doc/DocumentLinksAdministrationManager.cxx index 989a85240f58..082d81b78bcc 100644 --- a/sw/source/core/doc/DocumentLinksAdministrationManager.cxx +++ b/sw/source/core/doc/DocumentLinksAdministrationManager.cxx @@ -201,45 +201,56 @@ const sfx2::LinkManager& DocumentLinksAdministrationManager::GetLinkManager() co // to new SwDoc::UpdateLinks(): void DocumentLinksAdministrationManager::UpdateLinks( bool bUI ) { - SfxObjectCreateMode eMode; - sal_uInt16 nLinkMode = m_rDoc.GetDocumentSettingManager().getLinkUpdateMode( true ); - if ( m_rDoc.GetDocShell()) { - sal_uInt16 nUpdateDocMode = m_rDoc.GetDocShell()->GetUpdateDocMode(); - if( (nLinkMode != NEVER || document::UpdateDocMode::FULL_UPDATE == nUpdateDocMode) && - !GetLinkManager().GetLinks().empty() && - SfxObjectCreateMode::INTERNAL != - ( eMode = m_rDoc.GetDocShell()->GetCreateMode()) && - SfxObjectCreateMode::ORGANIZER != eMode && - SfxObjectCreateMode::PREVIEW != eMode && - !m_rDoc.GetDocShell()->IsPreview() ) + if (!m_rDoc.GetDocShell()) + return; + SfxObjectCreateMode eMode = m_rDoc.GetDocShell()->GetCreateMode(); + if (eMode == SfxObjectCreateMode::INTERNAL) + return; + if (eMode == SfxObjectCreateMode::ORGANIZER) + return; + if (eMode == SfxObjectCreateMode::PREVIEW) + return; + if (m_rDoc.GetDocShell()->IsPreview()) + return; + if (GetLinkManager().GetLinks().empty()) + return; + sal_uInt16 nLinkMode = m_rDoc.GetDocumentSettingManager().getLinkUpdateMode(true); + sal_uInt16 nUpdateDocMode = m_rDoc.GetDocShell()->GetUpdateDocMode(); + if (nLinkMode == NEVER && nUpdateDocMode != document::UpdateDocMode::FULL_UPDATE) + return; + + bool bAskUpdate = nLinkMode == MANUAL; + bool bUpdate = true; + switch(nUpdateDocMode) + { + case document::UpdateDocMode::NO_UPDATE: bUpdate = false;break; + case document::UpdateDocMode::QUIET_UPDATE:bAskUpdate = false; break; + case document::UpdateDocMode::FULL_UPDATE: bAskUpdate = true; break; + } + if (nLinkMode == AUTOMATIC && !bAskUpdate) + { + SfxMedium * medium = m_rDoc.GetDocShell()->GetMedium(); + if (!SvtSecurityOptions().isTrustedLocationUriForUpdatingLinks( + medium == nullptr ? OUString() : medium->GetName())) { - bool bAskUpdate = nLinkMode == MANUAL; - bool bUpdate = true; - switch(nUpdateDocMode) - { - case document::UpdateDocMode::NO_UPDATE: bUpdate = false;break; - case document::UpdateDocMode::QUIET_UPDATE:bAskUpdate = false; break; - case document::UpdateDocMode::FULL_UPDATE: bAskUpdate = true; break; - } - if (nLinkMode == AUTOMATIC && !bAskUpdate) - { - SfxMedium * medium = m_rDoc.GetDocShell()->GetMedium(); - if (!SvtSecurityOptions().isTrustedLocationUriForUpdatingLinks( - medium == nullptr ? OUString() : medium->GetName())) - { - bAskUpdate = true; - } - } - if( bUpdate && (bUI || !bAskUpdate) ) - { - SfxMedium* pMedium = m_rDoc.GetDocShell()->GetMedium(); - SfxFrame* pFrm = pMedium ? pMedium->GetLoadTargetFrame() : 0; - vcl::Window* pDlgParent = pFrm ? &pFrm->GetWindow() : 0; - - GetLinkManager().UpdateAllLinks( bAskUpdate, true, false, pDlgParent ); - } + bAskUpdate = true; } } + comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = m_rDoc.GetDocShell()->getEmbeddedObjectContainer(); + if (bUpdate) + { + rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true); + + SfxMedium* pMedium = m_rDoc.GetDocShell()->GetMedium(); + SfxFrame* pFrame = pMedium ? pMedium->GetLoadTargetFrame() : nullptr; + vcl::Window* pDlgParent = pFrame ? &pFrame->GetWindow() : nullptr; + + GetLinkManager().UpdateAllLinks( bAskUpdate, true, false, pDlgParent ); + } + else + { + rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); + } } bool DocumentLinksAdministrationManager::GetData( const OUString& rItem, const OUString& rMimeType, diff --git a/sw/source/uibase/app/docshini.cxx b/sw/source/uibase/app/docshini.cxx index fca4e2e44657..faefa968d26c 100644 --- a/sw/source/uibase/app/docshini.cxx +++ b/sw/source/uibase/app/docshini.cxx @@ -486,6 +486,9 @@ bool SwDocShell::Load( SfxMedium& rMedium ) bool bRet = false; if( SfxObjectShell::Load( rMedium )) { + comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer(); + rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); + SAL_INFO( "sw.ui", "after SfxInPlaceObject::Load" ); if (m_pDoc) // for last version!! RemoveLink(); // release the existing _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits