69cc7b
From a3f5d838d091df6c1582b0fb6d539292edf536a0 Mon Sep 17 00:00:00 2001
560625
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
560625
Date: Wed, 10 Jan 2018 14:27:35 +0000
560625
Subject: [PATCH] limit WEBSERVICE to http[s] protocols
560625
MIME-Version: 1.0
560625
Content-Type: text/plain; charset=UTF-8
560625
Content-Transfer-Encoding: 8bit
560625
560625
and like excel...
560625
560625
'For protocols that aren’t supported, such as ftp:// or file://, WEBSERVICE
560625
returns the #VALUE! error value.'
560625
560625
Reviewed-on: https://gerrit.libreoffice.org/47776
560625
Tested-by: Jenkins <ci@libreoffice.org>
560625
Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
560625
560625
Better handle ScDde formulas with missing dde-link entries
560625
560625
typically each ScDde formula has a matching table:dde-link which
560625
results in a ScDdeLink getting inserted during the load. If that dde-link
560625
is missing then no ScDdeLink exists and ScDde() will create a new one without
560625
cached content. So detect that ScDde is used in the freshing loaded ods
560625
and defer fetching new content until the right time.
560625
560625
only call GetHasMacroFunc to set SetHasMacroFunc
560625
560625
and bHasMacroFunc is not accessed any other way, so this is an oxbow
560625
560625
Reviewed-on: https://gerrit.libreoffice.org/47757
560625
Tested-by: Jenkins <ci@libreoffice.org>
560625
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
560625
Tested-by: Caolán McNamara <caolanm@redhat.com>
560625
(cherry picked from commit b0597ba5d745974fce752e1b677451a19350d351)
560625
Reviewed-on: https://gerrit.libreoffice.org/47818
560625
Reviewed-by: Eike Rathke <erack@redhat.com>
560625
560625
handle ocWebservice similarly to ocDde
560625
560625
might have too much in here seeing as we don't need to worry about
560625
ocWebservice calling into itself
560625
560625
Reviewed-on: https://gerrit.libreoffice.org/47819
560625
Tested-by: Jenkins <ci@libreoffice.org>
560625
Reviewed-by: Eike Rathke <erack@redhat.com>
560625
560625
CheckLinkFormulaNeedingCheck() for .xls and .xlsx formula cells
560625
560625
 This is a combination of 3 commits.
560625
560625
Move implementation to CheckLinkFormulaNeedingCheck() for further reuse
560625
560625
(cherry picked from commit 55e484c7bcd3ef218e08d3fd93f97bf98fd8cb7f)
560625
560625
CheckLinkFormulaNeedingCheck() for .xlsx cell formulas
560625
560625
(cherry picked from commit f96dbc3dd9c33202f75e29ef49d962386595995d)
560625
560625
CheckLinkFormulaNeedingCheck() for .xls cell formulas
560625
560625
(cherry picked from commit 6bc48275558c3f76c4da25eb8af3c48583ac5599)
560625
560625
a6dd195f7eb4d43483e87eeca59f651e7bf2dcb8
560625
2587fbc4fec39b6f2c8e733331815a2953dee308
560625
560625
Reviewed-on: https://gerrit.libreoffice.org/48143
560625
Tested-by: Jenkins <ci@libreoffice.org>
560625
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
560625
Tested-by: Caolán McNamara <caolanm@redhat.com>
560625
560625
CheckLinkFormulaNeedingCheck() for conditional format expressions
560625
560625
 This is a combination of 4 commits.
560625
560625
Prepare CheckLinkFormulaNeedingCheck() to use either RPN or tokenized code
560625
560625
Conditional format formulas aren't finally compiled until needed
560625
so the check will have to operate on the tokenized expression
560625
instead of RPN code.
560625
560625
(cherry picked from commit faa0305ba3d0dc698fce4915d4f3a1fb52422380)
560625
560625
CheckLinkFormulaNeedingCheck() for .ods conditional format expressions
560625
560625
(cherry picked from commit 2930ba2ac5d9423f2848b968edcd8ddc71966186)
560625
560625
CheckLinkFormulaNeedingCheck() for .xlsx conditional format expressions
560625
560625
(cherry picked from commit fef24d9f999ee54d7936900485d97ff26656f517)
560625
560625
CheckLinkFormulaNeedingCheck() for .xls conditional format expressions
560625
560625
(cherry picked from commit af2a2a0c72db312902e466c36697b5c198041e82)
560625
560625
45eb1ab5efa0ec9da2663f20427d2474ce300826
560625
31ede1a23223a798141a0891deeabd8cf88fff58
560625
afa112cc591b411d80ead48bf726788d361f6eb3
560625
560625
Reviewed-on: https://gerrit.libreoffice.org/48719
560625
Tested-by: Jenkins <ci@libreoffice.org>
560625
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
560625
Tested-by: Caolán McNamara <caolanm@redhat.com>
560625
560625
CheckLinkFormulaNeedingCheck() for named expressions
560625
560625
 This is a combination of 3 commits.
560625
560625
CheckLinkFormulaNeedingCheck() for .ods named expressions
560625
560625
This is specifically necessary for named expressions that are used
560625
in conditional format formulas, for which RPN is generated at a
560625
later stage, not during import.
560625
560625
(cherry picked from commit eae9648e99be53ba441d9d8207aac6f3ce211ef2)
560625
560625
CheckLinkFormulaNeedingCheck() for .xls named expressions
560625
560625
(cherry picked from commit 8512f13c42ae3fbb287a555616fe10ff04295616)
560625
560625
CheckLinkFormulaNeedingCheck() for .xlsx named expressions
560625
560625
(cherry picked from commit a1f933ee2b9e23a505d937035821e9571cf4119c)
560625
560625
 Conflicts:
560625
	sc/source/filter/oox/defnamesbuffer.cxx
560625
560625
e03cb5767c34f8157a492a6d6c3b0700d065052d
560625
217c89822ab477a6c383d170ae739e44efd10fa3
560625
560625
Change-Id: I0e9c6fd3426fad56a199eafac48de9b0f23914b3
560625
016b53288076d83dd49e92e245346a5f7f560522
560625
0145f38cc1c1f9ff514a496f7101d81cde9e7c67
560625
541d2b6e12a88371c064b901b00e71206ee0c18e
560625
68837e9bd33f125ab47b10b1a6fa18175abd1627
560625
54ab8dc14f81d6b18b0d17f448187d19d8e396fc
560625
Reviewed-on: https://gerrit.libreoffice.org/48858
560625
Tested-by: Jenkins <ci@libreoffice.org>
560625
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
560625
Tested-by: Caolán McNamara <caolanm@redhat.com>
560625
---
560625
 sc/Library_sc.mk                          |   1 +
560625
 sc/inc/document.hxx                       |   8 ++-
560625
 sc/inc/documentlinkmgr.hxx                |   6 +-
69cc7b
 sc/qa/unit/ucalc.cxx                      |   2 +-
560625
 sc/source/core/data/conditio.cxx          |   6 ++
560625
 sc/source/core/data/documen2.cxx          |   2 +-
560625
 sc/source/core/data/documen8.cxx          |  23 +++++++
560625
 sc/source/core/data/formulacell.cxx       |   7 +-
560625
 sc/source/core/inc/webservicelink.hxx     |  49 ++++++++++++++
560625
 sc/source/core/tool/interpr2.cxx          |   8 ++-
560625
 sc/source/core/tool/interpr7.cxx          | 106 ++++++++++++++++++++++--------
560625
 sc/source/core/tool/rangenam.cxx          |   8 ++-
560625
 sc/source/core/tool/webservicelink.cxx    | 106 ++++++++++++++++++++++++++++++
560625
 sc/source/filter/excel/excform.cxx        |   1 +
560625
 sc/source/filter/excel/excform8.cxx       |   1 +
560625
 sc/source/filter/excel/impop.cxx          |   1 +
560625
 sc/source/filter/excel/xicontent.cxx      |   6 ++
560625
 sc/source/filter/excel/xiname.cxx         |   3 +
560625
 sc/source/filter/oox/condformatbuffer.cxx |   2 +
560625
 sc/source/filter/oox/defnamesbuffer.cxx   |   2 +
560625
 sc/source/filter/oox/formulabuffer.cxx    |   4 ++
560625
 sc/source/ui/docshell/docsh4.cxx          |   4 +-
560625
 sc/source/ui/docshell/documentlinkmgr.cxx |  20 ++++--
560625
 sc/source/ui/view/tabvwsh4.cxx            |   2 +-
69cc7b
 24 files changed, 329 insertions(+), 49 deletions(-)
560625
 create mode 100644 sc/source/core/inc/webservicelink.hxx
560625
 create mode 100644 sc/source/core/tool/webservicelink.cxx
560625
560625
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
69cc7b
index 3714c966a62e..05a3ee49a32c 100644
560625
--- a/sc/Library_sc.mk
560625
+++ b/sc/Library_sc.mk
69cc7b
@@ -285,6 +285,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
560625
     sc/source/core/tool/unitconv \
560625
     sc/source/core/tool/userlist \
560625
     sc/source/core/tool/viewopti \
560625
+    sc/source/core/tool/webservicelink \
560625
     sc/source/core/tool/zforauto \
560625
     sc/source/filter/xml/datastreamimport \
560625
     sc/source/filter/xml/XMLCalculationSettingsContext \
560625
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
69cc7b
index f5f9f0387174..d25ca0b913a8 100644
560625
--- a/sc/inc/document.hxx
560625
+++ b/sc/inc/document.hxx
69cc7b
@@ -448,7 +448,7 @@ private:
69cc7b
     // for detective update, is set for each change of a formula
560625
     bool                bDetectiveDirty;
560625
 
560625
-    bool                bHasMacroFunc;      // valid only after loading
560625
+    bool                bLinkFormulaNeedingCheck; // valid only after loading, for ocDde and ocWebservice
560625
 
69cc7b
     sal_uInt8               nAsianCompression;
69cc7b
     sal_uInt8               nAsianKerning;
69cc7b
@@ -1928,8 +1928,10 @@ public:
69cc7b
     bool            IsDetectiveDirty() const     { return bDetectiveDirty; }
69cc7b
     void            SetDetectiveDirty(bool bSet) { bDetectiveDirty = bSet; }
560625
 
560625
-    bool            GetHasMacroFunc() const      { return bHasMacroFunc; }
560625
-    void            SetHasMacroFunc(bool bSet)   { bHasMacroFunc = bSet; }
560625
+    bool            HasLinkFormulaNeedingCheck() const      { return bLinkFormulaNeedingCheck; }
560625
+    void            SetLinkFormulaNeedingCheck(bool bSet)   { bLinkFormulaNeedingCheck = bSet; }
560625
+    /** Check token array and set link check if ocDde/ocWebservice is contained. */
560625
+    SC_DLLPUBLIC void CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode );
560625
 
69cc7b
     void            SetRangeOverflowType(sal_uInt32 nType)  { nRangeOverflowType = nType; }
69cc7b
     bool            HasRangeOverflow() const                { return nRangeOverflowType != 0; }
560625
diff --git a/sc/inc/documentlinkmgr.hxx b/sc/inc/documentlinkmgr.hxx
69cc7b
index d5d801a4aeb2..86dba66f2d3d 100644
560625
--- a/sc/inc/documentlinkmgr.hxx
560625
+++ b/sc/inc/documentlinkmgr.hxx
69cc7b
@@ -55,9 +55,9 @@ public:
560625
     bool idleCheckLinks();
560625
 
560625
     bool hasDdeLinks() const;
560625
-    bool hasDdeOrOleLinks() const;
560625
+    bool hasDdeOrOleOrWebServiceLinks() const;
560625
 
560625
-    bool updateDdeOrOleLinks(vcl::Window* pWin);
560625
+    bool updateDdeOrOleOrWebServiceLinks(vcl::Window* pWin);
560625
 
69cc7b
     void updateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem );
560625
 
69cc7b
@@ -65,7 +65,7 @@ public:
560625
 
560625
     void disconnectDdeLinks();
560625
 private:
560625
-    bool hasDdeOrOleLinks(bool bDde, bool bOle) const;
560625
+    bool hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const;
560625
 };
560625
 
560625
 }
69cc7b
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
69cc7b
index ea44ff7d4f3d..90ca51f47073 100644
69cc7b
--- a/sc/qa/unit/ucalc.cxx
69cc7b
+++ b/sc/qa/unit/ucalc.cxx
69cc7b
@@ -6215,7 +6215,7 @@ void Test::testEmptyCalcDocDefaults()
69cc7b
     CPPUNIT_ASSERT_EQUAL( false, m_pDoc->IdleCalcTextWidth() );
69cc7b
     CPPUNIT_ASSERT_EQUAL( true, m_pDoc->IsIdleEnabled() );
69cc7b
     CPPUNIT_ASSERT_EQUAL( false, m_pDoc->IsDetectiveDirty() );
69cc7b
-    CPPUNIT_ASSERT_EQUAL( false, m_pDoc->GetHasMacroFunc() );
69cc7b
+    CPPUNIT_ASSERT_EQUAL( false, m_pDoc->HasLinkFormulaNeedingCheck() );
69cc7b
     CPPUNIT_ASSERT_EQUAL( false, m_pDoc->IsChartListenerCollectionNeedsUpdate() );
69cc7b
 
69cc7b
     CPPUNIT_ASSERT_EQUAL( false, m_pDoc->HasRangeOverflow() );
560625
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
69cc7b
index c970520f3377..1fc8ee34b60b 100644
560625
--- a/sc/source/core/data/conditio.cxx
560625
+++ b/sc/source/core/data/conditio.cxx
69cc7b
@@ -522,6 +522,12 @@ void ScConditionEntry::CompileXML()
560625
     Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar1),
560625
              GetExpression(aSrcPos, 1, 0, eTempGrammar2),
560625
              aStrNmsp1, aStrNmsp2, eTempGrammar1, eTempGrammar2, true );
560625
+
560625
+    // Importing ocDde/ocWebservice?
560625
+    if (pFormula1)
560625
+        mpDoc->CheckLinkFormulaNeedingCheck(*pFormula1);
560625
+    if (pFormula2)
560625
+        mpDoc->CheckLinkFormulaNeedingCheck(*pFormula2);
560625
 }
560625
 
560625
 void ScConditionEntry::SetSrcString( const OUString& rNew )
560625
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
69cc7b
index 7a41f14c01c2..017f8629c910 100644
560625
--- a/sc/source/core/data/documen2.cxx
560625
+++ b/sc/source/core/data/documen2.cxx
69cc7b
@@ -200,7 +200,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
69cc7b
         bInDtorClear( false ),
560625
         bExpandRefs( false ),
560625
         bDetectiveDirty( false ),
560625
-        bHasMacroFunc( false ),
560625
+        bLinkFormulaNeedingCheck( false ),
560625
         nAsianCompression(SC_ASIANCOMPRESSION_INVALID),
560625
         nAsianKerning(SC_ASIANKERNING_INVALID),
69cc7b
         bPastingDrawFromOtherDoc( false ),
560625
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
69cc7b
index 572d594b3697..49985b4cd93d 100644
560625
--- a/sc/source/core/data/documen8.cxx
560625
+++ b/sc/source/core/data/documen8.cxx
560625
@@ -88,6 +88,7 @@
560625
 #include "stringutil.hxx"
560625
 #include <documentlinkmgr.hxx>
560625
 #include <scopetools.hxx>
560625
+#include <tokenarray.hxx>
560625
 
69cc7b
 #include <memory>
560625
 
69cc7b
@@ -1153,6 +1154,28 @@ void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode,
560625
     }
560625
 }
560625
 
560625
+void ScDocument::CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode )
560625
+{
560625
+    if (HasLinkFormulaNeedingCheck())
560625
+        return;
560625
+
560625
+    // Prefer RPN over tokenized formula if available.
560625
+    if (rCode.GetCodeLen())
560625
+    {
560625
+        if (rCode.HasOpCodeRPN(ocDde) || rCode.HasOpCodeRPN(ocWebservice))
560625
+            SetLinkFormulaNeedingCheck(true);
560625
+    }
560625
+    else if (rCode.GetLen())
560625
+    {
560625
+        if (rCode.HasOpCode(ocDde) || rCode.HasOpCode(ocWebservice))
560625
+            SetLinkFormulaNeedingCheck(true);
560625
+    }
560625
+    else
560625
+    {
560625
+        assert(!"called with empty ScTokenArray");
560625
+    }
560625
+}
560625
+
560625
 // TimerDelays etc.
560625
 void ScDocument::KeyInput( const KeyEvent& )
560625
 {
560625
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
69cc7b
index 381fb173d4b7..8eb4f9f23400 100644
560625
--- a/sc/source/core/data/formulacell.cxx
560625
+++ b/sc/source/core/data/formulacell.cxx
69cc7b
@@ -1379,10 +1379,9 @@ void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rPr
560625
             bChanged = true;
560625
     }
560625
 
560625
-    //  Same as in Load: after loading, it must be known if ocMacro is in any formula
560625
-    //  (for macro warning, CompileXML is called at the end of loading XML file)
560625
-    if ( !pDocument->GetHasMacroFunc() && pCode->HasOpCodeRPN( ocMacro ) )
560625
-        pDocument->SetHasMacroFunc( true );
560625
+    //  After loading, it must be known if ocDde/ocWebservice is in any formula
560625
+    //  (for external links warning, CompileXML is called at the end of loading XML file)
560625
+    pDocument->CheckLinkFormulaNeedingCheck(*pCode);
560625
 
560625
     //volatile cells must be added here for import
560625
     if( pCode->IsRecalcModeAlways() || pCode->IsRecalcModeForced() ||
560625
diff --git a/sc/source/core/inc/webservicelink.hxx b/sc/source/core/inc/webservicelink.hxx
560625
new file mode 100644
69cc7b
index 000000000000..e61ebfdb4347
560625
--- /dev/null
560625
+++ b/sc/source/core/inc/webservicelink.hxx
560625
@@ -0,0 +1,49 @@
560625
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
560625
+/*
560625
+ * This file is part of the LibreOffice project.
560625
+ *
560625
+ * This Source Code Form is subject to the terms of the Mozilla Public
560625
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
560625
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
560625
+ */
560625
+
560625
+#ifndef INCLUDED_SC_SOURCE_CORE_INC_WEBSERVICE_HXX
560625
+#define INCLUDED_SC_SOURCE_CORE_INC_WEBSERVICE_HXX
560625
+
560625
+#include <address.hxx>
560625
+#include <sfx2/lnkbase.hxx>
560625
+#include <svl/broadcast.hxx>
560625
+#include <types.hxx>
560625
+
560625
+class ScDocument;
560625
+
560625
+class ScWebServiceLink : public ::sfx2::SvBaseLink, public SvtBroadcaster
560625
+{
560625
+private:
560625
+    ScDocument* pDoc;
560625
+    OUString aURL; // connection/ link data
560625
+    bool bHasResult; // is set aResult is useful
560625
+    OUString aResult;
560625
+
560625
+public:
560625
+    ScWebServiceLink(ScDocument* pD, const OUString& rURL);
560625
+    virtual ~ScWebServiceLink() override;
560625
+
560625
+    // SvBaseLink override:
560625
+    virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(const OUString& rMimeType,
560625
+                                                         const css::uno::Any& rValue) override;
560625
+
560625
+    // SvtBroadcaster override:
560625
+    virtual void ListenersGone() override;
560625
+
560625
+    // for interpreter:
560625
+
560625
+    const OUString& GetResult() const { return aResult; }
560625
+    bool HasResult() const { return bHasResult; }
560625
+
560625
+    const OUString& GetURL() const { return aURL; }
560625
+};
560625
+
560625
+#endif
560625
+
560625
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
560625
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
69cc7b
index c40623320b3d..7f215495538b 100644
560625
--- a/sc/source/core/tool/interpr2.cxx
560625
+++ b/sc/source/core/tool/interpr2.cxx
69cc7b
@@ -2742,8 +2742,14 @@ void ScInterpreter::ScDde()
560625
                     pBindings->Invalidate( SID_LINKS );             // Link-Manager enablen
560625
             }
560625
 
560625
+            //if the document was just loaded, but the ScDdeLink entry was missing, then
560625
+            //don't update this link until the links are updated in response to the users
560625
+            //decision
560625
+            if (!pDok->HasLinkFormulaNeedingCheck())
560625
+            {
560625
                                     //TODO: evaluate asynchron ???
560625
-            pLink->TryUpdate();     //  TryUpdate doesn't call Update multiple times
560625
+                pLink->TryUpdate(); //  TryUpdate doesn't call Update multiple times
560625
+            }
560625
 
560625
             if (pMyFormulaCell)
560625
             {
560625
diff --git a/sc/source/core/tool/interpr7.cxx b/sc/source/core/tool/interpr7.cxx
69cc7b
index 48a34b3ece36..e2f562848a31 100644
560625
--- a/sc/source/core/tool/interpr7.cxx
560625
+++ b/sc/source/core/tool/interpr7.cxx
69cc7b
@@ -13,7 +13,9 @@
69cc7b
 #include "scmatrix.hxx"
560625
 #include <rtl/strbuf.hxx>
560625
 #include <formula/errorcodes.hxx>
560625
+#include <sfx2/bindings.hxx>
560625
 #include <svtools/miscopt.hxx>
560625
+#include <tools/urlobj.hxx>
560625
 
560625
 #include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
560625
 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
69cc7b
@@ -23,6 +25,10 @@
560625
 #include <datastreamgettime.hxx>
560625
 #include <dpobject.hxx>
560625
 #include <document.hxx>
560625
+#include <tokenarray.hxx>
560625
+#include <webservicelink.hxx>
560625
+
560625
+#include <sc.hrc>
560625
 
560625
 #include <cstring>
69cc7b
 #include <memory>
69cc7b
@@ -234,6 +240,22 @@ void ScInterpreter::ScFilterXML()
560625
     }
560625
 }
560625
 
560625
+static ScWebServiceLink* lcl_GetWebServiceLink(const sfx2::LinkManager* pLinkMgr, const OUString& rURL)
560625
+{
560625
+    size_t nCount = pLinkMgr->GetLinks().size();
560625
+    for (size_t i=0; i
560625
+    {
69cc7b
+        ::sfx2::SvBaseLink* pBase = pLinkMgr->GetLinks()[i].get();
560625
+        if (ScWebServiceLink* pLink = dynamic_cast<ScWebServiceLink*>(pBase))
560625
+        {
560625
+            if (pLink->GetURL() == rURL)
560625
+                return pLink;
560625
+        }
560625
+    }
560625
+
560625
+    return nullptr;
560625
+}
560625
+
560625
 void ScInterpreter::ScWebservice()
560625
 {
560625
     sal_uInt8 nParamCount = GetByte();
69cc7b
@@ -241,54 +263,82 @@ void ScInterpreter::ScWebservice()
560625
     {
560625
         OUString aURI = GetString().getString();
560625
 
560625
-        if(aURI.isEmpty())
560625
+        if (aURI.isEmpty())
560625
         {
69cc7b
             PushError( FormulaError::NoValue );
560625
             return;
560625
         }
560625
 
560625
-        uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY );
560625
-        if(!xFileAccess.is())
560625
+        INetURLObject aObj(aURI, INetProtocol::File);
560625
+        INetProtocol eProtocol = aObj.GetProtocol();
560625
+        if (eProtocol != INetProtocol::Http && eProtocol != INetProtocol::Https)
560625
         {
69cc7b
-            PushError( FormulaError::NoValue );
69cc7b
+            PushError(FormulaError::NoValue);
560625
             return;
560625
         }
560625
 
560625
-        uno::Reference< io::XInputStream > xStream;
560625
-        try {
560625
-            xStream = xFileAccess->openFileRead( aURI );
560625
-        }
560625
-        catch (...)
69cc7b
+        if (!mpLinkManager)
560625
         {
560625
-            // don't let any exceptions pass
69cc7b
-            PushError( FormulaError::NoValue );
560625
-            return;
560625
-        }
560625
-        if ( !xStream.is() )
560625
-        {
69cc7b
-            PushError( FormulaError::NoValue );
69cc7b
+            PushError(FormulaError::NoValue);
560625
             return;
560625
         }
560625
 
560625
-        const sal_Int32 BUF_LEN = 8000;
560625
-        uno::Sequence< sal_Int8 > buffer( BUF_LEN );
560625
-        OStringBuffer aBuffer( 64000 );
560625
+        // Need to reinterpret after loading (build links)
560625
+        if (rArr.IsRecalcModeNormal())
560625
+            rArr.SetExclusiveRecalcModeOnLoad();
69cc7b
+
560625
+        //  while the link is not evaluated, idle must be disabled (to avoid circular references)
560625
+        bool bOldEnabled = pDok->IsIdleEnabled();
560625
+        pDok->EnableIdle(false);
560625
+
560625
+        // Get/ Create link object
69cc7b
+        ScWebServiceLink* pLink = lcl_GetWebServiceLink(mpLinkManager, aURI);
560625
+
69cc7b
+        bool bWasError = (pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE);
69cc7b
 
69cc7b
-        sal_Int32 nRead = 0;
69cc7b
-        while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN )
560625
+        if (!pLink)
560625
         {
560625
-            aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
69cc7b
-        }
560625
+            pLink = new ScWebServiceLink(pDok, aURI);
69cc7b
+            mpLinkManager->InsertFileLink(*pLink, OBJECT_CLIENT_FILE, aURI);
69cc7b
+            if ( mpLinkManager->GetLinks().size() == 1 )                    // the first one?
560625
+            {
560625
+                SfxBindings* pBindings = pDok->GetViewBindings();
560625
+                if (pBindings)
560625
+                    pBindings->Invalidate( SID_LINKS );             // Link-Manager enabled
560625
+            }
69cc7b
 
69cc7b
-        if ( nRead > 0 )
560625
+            //if the document was just loaded, but the ScDdeLink entry was missing, then
560625
+            //don't update this link until the links are updated in response to the users
560625
+            //decision
560625
+            if (!pDok->HasLinkFormulaNeedingCheck())
560625
+            {
560625
+                pLink->Update();
560625
+            }
560625
+
560625
+            if (pMyFormulaCell)
560625
+            {
560625
+                // StartListening after the Update to avoid circular references
560625
+                pMyFormulaCell->StartListening(*pLink);
560625
+            }
69cc7b
+        }
69cc7b
+        else
69cc7b
         {
69cc7b
-            aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
69cc7b
+            if (pMyFormulaCell)
69cc7b
+                pMyFormulaCell->StartListening(*pLink);
560625
         }
560625
 
560625
-        xStream->closeInput();
560625
+        //  If an new Error from Reschedule appears when the link is executed then reset the errorflag
69cc7b
+        if (pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE && !bWasError)
69cc7b
+            pMyFormulaCell->SetErrCode(FormulaError::NONE);
560625
+
560625
+        //  check the value
560625
+        if (pLink->HasResult())
560625
+            PushString(pLink->GetResult());
560625
+        else
69cc7b
+            PushError(FormulaError::NoValue);
560625
 
560625
-        OUString aContent = OStringToOUString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
560625
-        PushString( aContent );
560625
+        pDok->EnableIdle(bOldEnabled);
69cc7b
+        mpLinkManager->CloseCachedComps();
560625
     }
560625
 }
560625
 
560625
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
69cc7b
index eae117c08434..18cbabb1cd93 100644
560625
--- a/sc/source/core/tool/rangenam.cxx
560625
+++ b/sc/source/core/tool/rangenam.cxx
69cc7b
@@ -64,9 +64,14 @@ ScRangeData::ScRangeData( ScDocument* pDok,
560625
                 mnMaxCol    (-1)
560625
 {
560625
     if (!rSymbol.isEmpty())
560625
-        CompileRangeData( rSymbol, pDoc->IsImportingXML());
560625
+    {
560625
         // Let the compiler set an error on unknown names for a subsequent
560625
         // CompileUnresolvedXML().
560625
+        const bool bImporting = pDoc->IsImportingXML();
560625
+        CompileRangeData( rSymbol, bImporting);
560625
+        if (bImporting)
560625
+            pDoc->CheckLinkFormulaNeedingCheck( *pCode);
560625
+    }
560625
     else
560625
     {
560625
         // #i63513#/#i65690# don't leave pCode as NULL.
69cc7b
@@ -199,6 +204,7 @@ void ScRangeData::CompileUnresolvedXML( sc::CompileFormulaContext& rCxt )
560625
         // Don't let the compiler set an error for unknown names on final
560625
         // compile, errors are handled by the interpreter thereafter.
560625
         CompileRangeData( aSymbol, false);
560625
+        rCxt.getDoc()->CheckLinkFormulaNeedingCheck( *pCode);
560625
     }
560625
 }
560625
 
560625
diff --git a/sc/source/core/tool/webservicelink.cxx b/sc/source/core/tool/webservicelink.cxx
560625
new file mode 100644
69cc7b
index 000000000000..82310f2b1351
560625
--- /dev/null
560625
+++ b/sc/source/core/tool/webservicelink.cxx
560625
@@ -0,0 +1,106 @@
560625
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
560625
+/*
560625
+ * This file is part of the LibreOffice project.
560625
+ *
560625
+ * This Source Code Form is subject to the terms of the Mozilla Public
560625
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
560625
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
560625
+ */
560625
+
560625
+#include <comphelper/fileformat.h>
560625
+#include <comphelper/string.hxx>
560625
+#include <osl/thread.h>
560625
+#include <sfx2/linkmgr.hxx>
560625
+#include <sfx2/bindings.hxx>
560625
+
560625
+#include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
560625
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
560625
+#include <com/sun/star/io/XInputStream.hpp>
560625
+
560625
+#include <webservicelink.hxx>
560625
+#include <brdcst.hxx>
560625
+#include <document.hxx>
560625
+#include <scmatrix.hxx>
560625
+#include <patattr.hxx>
560625
+#include <rechead.hxx>
560625
+#include <rangeseq.hxx>
560625
+#include <sc.hrc>
560625
+#include <hints.hxx>
560625
+
560625
+ScWebServiceLink::ScWebServiceLink(ScDocument* pD, const OUString& rURL)
560625
+    : ::sfx2::SvBaseLink(SfxLinkUpdateMode::ALWAYS, SotClipboardFormatId::STRING)
560625
+    , pDoc(pD)
560625
+    , aURL(rURL)
560625
+    , bHasResult(false)
560625
+{
560625
+}
560625
+
560625
+ScWebServiceLink::~ScWebServiceLink() {}
560625
+
560625
+sfx2::SvBaseLink::UpdateResult ScWebServiceLink::DataChanged(const OUString&, const css::uno::Any&)
560625
+{
560625
+    aResult.clear();
560625
+    bHasResult = false;
560625
+
560625
+    css::uno::Reference<css::ucb::XSimpleFileAccess3> xFileAccess(
560625
+        css::ucb::SimpleFileAccess::create(comphelper::getProcessComponentContext()),
560625
+        css::uno::UNO_QUERY);
560625
+    if (!xFileAccess.is())
560625
+        return ERROR_GENERAL;
560625
+
560625
+    css::uno::Reference<css::io::XInputStream> xStream;
560625
+    try
560625
+    {
560625
+        xStream = xFileAccess->openFileRead(aURL);
560625
+    }
560625
+    catch (...)
560625
+    {
560625
+        // don't let any exceptions pass
560625
+        return ERROR_GENERAL;
560625
+    }
560625
+    if (!xStream.is())
560625
+        return ERROR_GENERAL;
560625
+
560625
+    const sal_Int32 BUF_LEN = 8000;
560625
+    css::uno::Sequence<sal_Int8> buffer(BUF_LEN);
560625
+    OStringBuffer aBuffer(64000);
560625
+
560625
+    sal_Int32 nRead = 0;
560625
+    while ((nRead = xStream->readBytes(buffer, BUF_LEN)) == BUF_LEN)
560625
+        aBuffer.append(reinterpret_cast<const char*>(buffer.getConstArray()), nRead);
560625
+
560625
+    if (nRead > 0)
560625
+        aBuffer.append(reinterpret_cast<const char*>(buffer.getConstArray()), nRead);
560625
+
560625
+    xStream->closeInput();
560625
+
560625
+    aResult = OStringToOUString(aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8);
560625
+    bHasResult = true;
560625
+
560625
+    //  Something happened...
560625
+    if (HasListeners())
560625
+    {
560625
+        Broadcast(ScHint(SC_HINT_DATACHANGED, ScAddress()));
560625
+        pDoc->TrackFormulas(); // must happen immediately
560625
+        pDoc->StartTrackTimer();
560625
+    }
560625
+
560625
+    return SUCCESS;
560625
+}
560625
+
560625
+void ScWebServiceLink::ListenersGone()
560625
+{
560625
+    ScDocument* pStackDoc = pDoc; // member pDoc can't be used after removing the link
560625
+
560625
+    sfx2::LinkManager* pLinkMgr = pDoc->GetLinkManager();
560625
+    pLinkMgr->Remove(this); // deletes this
560625
+
560625
+    if (pLinkMgr->GetLinks().empty()) // deleted the last one ?
560625
+    {
560625
+        SfxBindings* pBindings = pStackDoc->GetViewBindings(); // don't use member pDoc!
560625
+        if (pBindings)
560625
+            pBindings->Invalidate(SID_LINKS);
560625
+    }
560625
+}
560625
+
560625
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
560625
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
69cc7b
index 67e7657f3428..889225c364bc 100644
560625
--- a/sc/source/filter/excel/excform.cxx
560625
+++ b/sc/source/filter/excel/excform.cxx
69cc7b
@@ -156,6 +156,7 @@ void ImportExcel::Formula(
560625
     {
560625
         pCell = new ScFormulaCell(&rDoc.getDoc(), aScPos, *pResult);
560625
         pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8);
560625
+        rDoc.getDoc().CheckLinkFormulaNeedingCheck( *pCell->GetCode());
560625
         rDoc.getDoc().EnsureTable(aScPos.Tab());
560625
         rDoc.setFormulaCell(aScPos, pCell);
560625
         SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, pCell);
560625
diff --git a/sc/source/filter/excel/excform8.cxx b/sc/source/filter/excel/excform8.cxx
69cc7b
index ef3d09ae1c8b..ff3387bf916b 100644
560625
--- a/sc/source/filter/excel/excform8.cxx
560625
+++ b/sc/source/filter/excel/excform8.cxx
69cc7b
@@ -730,6 +730,7 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
560625
                                         << nMerk0 << ocClose;
560625
                                 aPool >> aStack;
560625
                                 pExtName->CreateDdeData( GetDoc(), aApplic, aTopic );
560625
+                                GetDoc().SetLinkFormulaNeedingCheck(true);
560625
                             }
560625
                         }
560625
                         break;
560625
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
69cc7b
index 01b5b736951e..a76a81db3ff8 100644
560625
--- a/sc/source/filter/excel/impop.cxx
560625
+++ b/sc/source/filter/excel/impop.cxx
560625
@@ -866,6 +866,7 @@ void ImportExcel::Shrfmla()
560625
 
560625
     ScFormulaCell* pCell = new ScFormulaCell(pD, aPos, *pErgebnis);
560625
     pCell->GetCode()->WrapReference(aPos, EXC_MAXCOL8, EXC_MAXROW8);
560625
+    rDoc.getDoc().CheckLinkFormulaNeedingCheck( *pCell->GetCode());
560625
     rDoc.getDoc().EnsureTable(aPos.Tab());
560625
     rDoc.setFormulaCell(aPos, pCell);
560625
     pCell->SetNeedNumberFormat(false);
560625
diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx
69cc7b
index bb80a929b35f..d2418806da53 100644
560625
--- a/sc/source/filter/excel/xicontent.cxx
560625
+++ b/sc/source/filter/excel/xicontent.cxx
69cc7b
@@ -662,7 +662,10 @@ void XclImpCondFormat::ReadCF( XclImpStream& rStrm )
560625
         rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize1, false, FT_CondFormat );
560625
         // formula converter owns pTokArr -> create a copy of the token array
560625
         if( pTokArr )
560625
+        {
560625
             xTokArr1.reset( pTokArr->Clone() );
69cc7b
+            GetDocRef().CheckLinkFormulaNeedingCheck( *xTokArr1);
560625
+        }
560625
     }
560625
 
560625
     ::std::unique_ptr< ScTokenArray > pTokArr2;
69cc7b
@@ -673,7 +676,10 @@ void XclImpCondFormat::ReadCF( XclImpStream& rStrm )
560625
         rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize2, false, FT_CondFormat );
560625
         // formula converter owns pTokArr -> create a copy of the token array
560625
         if( pTokArr )
560625
+        {
560625
             pTokArr2.reset( pTokArr->Clone() );
69cc7b
+            GetDocRef().CheckLinkFormulaNeedingCheck( *pTokArr2);
560625
+        }
560625
     }
560625
 
560625
     // *** create the Calc conditional formatting ***
560625
diff --git a/sc/source/filter/excel/xiname.cxx b/sc/source/filter/excel/xiname.cxx
69cc7b
index 7189c2a0a2f2..efc181921091 100644
560625
--- a/sc/source/filter/excel/xiname.cxx
560625
+++ b/sc/source/filter/excel/xiname.cxx
69cc7b
@@ -265,7 +265,10 @@ void XclImpName::InsertName(const ScTokenArray* pArray)
560625
         }
560625
     }
560625
     if (pData)
560625
+    {
560625
+        GetDoc().CheckLinkFormulaNeedingCheck( *pData->GetCode());
560625
         mpScData = pData;               // cache for later use
560625
+    }
560625
 }
560625
 
560625
 XclImpNameManager::XclImpNameManager( const XclImpRoot& rRoot ) :
560625
diff --git a/sc/source/filter/oox/condformatbuffer.cxx b/sc/source/filter/oox/condformatbuffer.cxx
69cc7b
index 1d0dd13fd773..aa8fbbaa4d96 100644
560625
--- a/sc/source/filter/oox/condformatbuffer.cxx
560625
+++ b/sc/source/filter/oox/condformatbuffer.cxx
69cc7b
@@ -874,11 +874,13 @@ void CondFormatRule::finalizeImport()
560625
         {
560625
             pTokenArray2.reset(new ScTokenArray());
560625
             ScTokenConversion::ConvertToTokenArray( rDoc, *pTokenArray2.get(), maModel.maFormulas[ 1 ] );
560625
+            rDoc.CheckLinkFormulaNeedingCheck( *pTokenArray2.get());
560625
         }
560625
 
560625
         ScTokenArray aTokenArray;
560625
         OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId );
560625
         ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, maModel.maFormulas[ 0 ] );
560625
+        rDoc.CheckLinkFormulaNeedingCheck( aTokenArray);
560625
         ScCondFormatEntry* pNewEntry = new ScCondFormatEntry(eOperator,
560625
                                             &aTokenArray, pTokenArray2.get(), &rDoc, aPos, aStyleName);
560625
         mpFormat->AddEntry(pNewEntry);
560625
diff --git a/sc/source/filter/oox/defnamesbuffer.cxx b/sc/source/filter/oox/defnamesbuffer.cxx
69cc7b
index 79457ab57e5f..a1d10906c687 100644
560625
--- a/sc/source/filter/oox/defnamesbuffer.cxx
560625
+++ b/sc/source/filter/oox/defnamesbuffer.cxx
560625
@@ -38,6 +38,7 @@
560625
 #include "tokenarray.hxx"
560625
 #include "tokenuno.hxx"
560625
 #include "compiler.hxx"
560625
+#include "document.hxx"
560625
 
560625
 namespace oox {
560625
 namespace xls {
69cc7b
@@ -334,6 +335,7 @@ std::unique_ptr<ScTokenArray> DefinedName::getScTokens(
560625
     // after, a resulting error must be reset.
69cc7b
     FormulaError nErr = pArray->GetCodeError();
560625
     aCompiler.CompileTokenArray();
560625
+    getScDocument().CheckLinkFormulaNeedingCheck( *pArray);
560625
     pArray->DelRPN();
560625
     pArray->SetCodeError(nErr);
560625
 
560625
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
69cc7b
index 003d0b96769b..bfa229292775 100644
560625
--- a/sc/source/filter/oox/formulabuffer.cxx
560625
+++ b/sc/source/filter/oox/formulabuffer.cxx
69cc7b
@@ -223,6 +223,10 @@ void applyCellFormulas(
560625
             continue;
560625
 
560625
         aCompiler.CompileTokenArray(); // Generate RPN tokens.
560625
+
560625
+        // Check if ocDde/ocWebservice is in any formula for external links warning.
560625
+        rDoc.getDoc().CheckLinkFormulaNeedingCheck(*pCode);
560625
+
560625
         ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, pCode);
560625
         rDoc.setFormulaCell(aPos, pCell);
560625
         rCache.store(aPos, pCell);
560625
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
69cc7b
index 81dbf194d0c7..a2b1b11ee646 100644
560625
--- a/sc/source/ui/docshell/docsh4.cxx
560625
+++ b/sc/source/ui/docshell/docsh4.cxx
69cc7b
@@ -450,7 +450,7 @@ void ScDocShell::Execute( SfxRequest& rReq )
560625
                     ReloadTabLinks();
560625
                     aDocument.UpdateExternalRefLinks(GetActiveDialogParent());
560625
 
560625
-                    bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleLinks(GetActiveDialogParent());
560625
+                    bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleOrWebServiceLinks(GetActiveDialogParent());
560625
 
560625
                     if (bAnyDde)
560625
                     {
69cc7b
@@ -472,6 +472,8 @@ void ScDocShell::Execute( SfxRequest& rReq )
560625
                     rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false);
560625
                     rReq.Ignore();
560625
                 }
560625
+
560625
+                rDoc.SetLinkFormulaNeedingCheck(false);
560625
             }
560625
             break;
560625
 
560625
diff --git a/sc/source/ui/docshell/documentlinkmgr.cxx b/sc/source/ui/docshell/documentlinkmgr.cxx
69cc7b
index 520b8542afc0..b8a9df65cb6b 100644
560625
--- a/sc/source/ui/docshell/documentlinkmgr.cxx
560625
+++ b/sc/source/ui/docshell/documentlinkmgr.cxx
560625
@@ -20,6 +20,7 @@
560625
 #include <documentlinkmgr.hxx>
560625
 #include <datastream.hxx>
560625
 #include <ddelink.hxx>
560625
+#include <webservicelink.hxx>
560625
 #include <sc.hrc>
560625
 #include <scresid.hxx>
560625
 
560625
@@ -115,15 +116,15 @@ bool DocumentLinkManager::idleCheckLinks()
560625
 
560625
 bool DocumentLinkManager::hasDdeLinks() const
560625
 {
560625
-    return hasDdeOrOleLinks(true, false);
560625
+    return hasDdeOrOleOrWebServiceLinks(true, false, false);
560625
 }
560625
 
560625
-bool DocumentLinkManager::hasDdeOrOleLinks() const
560625
+bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks() const
560625
 {
560625
-    return hasDdeOrOleLinks(true, true);
560625
+    return hasDdeOrOleOrWebServiceLinks(true, true, true);
560625
 }
560625
 
560625
-bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const
560625
+bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const
560625
 {
560625
     if (!mpImpl->mpLinkManager)
560625
         return false;
560625
@@ -136,12 +137,14 @@ bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const
560625
             return true;
560625
         if (bOle && dynamic_cast<SdrEmbedObjectLink*>(pBase))
560625
             return true;
560625
+        if (bWebService && dynamic_cast<ScWebServiceLink*>(pBase))
560625
+            return true;
560625
     }
560625
 
560625
     return false;
560625
 }
560625
 
560625
-bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin )
560625
+bool DocumentLinkManager::updateDdeOrOleOrWebServiceLinks(vcl::Window* pWin)
560625
 {
560625
     if (!mpImpl->mpLinkManager)
560625
         return false;
560625
@@ -163,6 +166,13 @@ bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin )
560625
             continue;
560625
         }
560625
 
560625
+        ScWebServiceLink* pWebserviceLink = dynamic_cast<ScWebServiceLink*>(pBase);
560625
+        if (pWebserviceLink)
560625
+        {
560625
+            pWebserviceLink->Update();
560625
+            continue;
560625
+        }
560625
+
560625
         ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
560625
         if (!pDdeLink)
560625
             continue;
560625
diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx
69cc7b
index e8f4491ae26e..17fb575a162f 100644
560625
--- a/sc/source/ui/view/tabvwsh4.cxx
560625
+++ b/sc/source/ui/view/tabvwsh4.cxx
69cc7b
@@ -1575,7 +1575,7 @@ void ScTabViewShell::Construct( TriState nForceDesignMode )
560625
             if (!bLink)
560625
             {
560625
                 const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager();
560625
-                if (rMgr.hasDdeOrOleLinks() || rDoc.HasAreaLinks())
560625
+                if (rDoc.HasLinkFormulaNeedingCheck() || rDoc.HasAreaLinks() || rMgr.hasDdeOrOleOrWebServiceLinks())
560625
                     bLink = true;
560625
             }
560625
             if (bLink)
560625
-- 
560625
2.14.3
560625