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