limit WEBSERVICE to http[s] protocols
authorCaolán McNamara <caolanm@redhat.com>
Wed, 10 Jan 2018 14:27:35 +0000 (14:27 +0000)
committerRene Engelhard <rene@debian.org>
Wed, 23 Jan 2019 17:51:09 +0000 (17:51 +0000)
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 <ci@libreoffice.org>
Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
(cherry picked from commit a916fc0c0e0e8b10cb4158fa0fa173fe205d434a)

Gbp-Pq: Name WEBSERVICE-DDE.diff

25 files changed:
include/formula/errorcodes.hxx
sc/Library_sc.mk
sc/inc/document.hxx
sc/inc/documentlinkmgr.hxx
sc/source/core/data/conditio.cxx
sc/source/core/data/documen2.cxx
sc/source/core/data/documen8.cxx
sc/source/core/data/formulacell.cxx
sc/source/core/inc/webservicelink.hxx [new file with mode: 0644]
sc/source/core/tool/interpr2.cxx
sc/source/core/tool/interpr7.cxx
sc/source/core/tool/rangenam.cxx
sc/source/core/tool/webservicelink.cxx [new file with mode: 0644]
sc/source/filter/excel/excform.cxx
sc/source/filter/excel/excform8.cxx
sc/source/filter/excel/impop.cxx
sc/source/filter/excel/xicontent.cxx
sc/source/filter/excel/xiname.cxx
sc/source/filter/oox/condformatbuffer.cxx
sc/source/filter/oox/defnamesbuffer.cxx
sc/source/filter/oox/formulabuffer.cxx
sc/source/ui/docshell/docsh4.cxx
sc/source/ui/docshell/documentlinkmgr.cxx
sc/source/ui/unoobj/funcuno.cxx
sc/source/ui/view/tabvwsh4.cxx

index 173c7440bbadcb40a45a043b078f1c9a05386daa..5a5a8fd2edf06e8644e7e4c69d22d4ce2ea5f6e7 100644 (file)
@@ -24,6 +24,7 @@
 
 namespace formula {
 
+const sal_uInt16 errNONE                 = 0;
 const sal_uInt16 errIllegalChar          = 501;
 const sal_uInt16 errIllegalArgument      = 502;
 const sal_uInt16 errIllegalFPOperation   = 503; // #NUM!
index 0ef50c3b6b0f92eb34dc3923ecb5b3c93c96e882..22f316031e01896153292ab0148406d25e79be0c 100644 (file)
@@ -285,6 +285,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
     sc/source/core/tool/unitconv \
     sc/source/core/tool/userlist \
     sc/source/core/tool/viewopti \
+    sc/source/core/tool/webservicelink \
     sc/source/core/tool/zforauto \
     sc/source/filter/xml/datastreamimport \
     sc/source/filter/xml/XMLCalculationSettingsContext \
index b17296e539f2fe726a1736e48fe05a84d96e672e..b68d92b7a4421743b19f3a83c0ea29120f08a7f6 100644 (file)
@@ -233,7 +233,8 @@ enum ScDocumentMode
 {
     SCDOCMODE_DOCUMENT,
     SCDOCMODE_CLIP,
-    SCDOCMODE_UNDO
+    SCDOCMODE_UNDO,
+    SCDOCMODE_FUNCTIONACCESS
 };
 
 struct ScDocStat
@@ -420,6 +421,7 @@ private:
     bool                bCalculatingFormulaTree;
     bool                bIsClip;
     bool                bIsUndo;
+    bool                bIsFunctionAccess;
     bool                bIsVisible;                     // set from view ctor
 
     bool                bIsEmbedded;                    // display/adjust Embedded area?
@@ -447,7 +449,7 @@ private:
     // for detective update, is set for each change of a formula
     bool                bDetectiveDirty;
 
-    bool                bHasMacroFunc;      // valid only after loading
+    bool                bLinkFormulaNeedingCheck; // valid only after loading, for ocDde and ocWebservice
 
     sal_uInt8               nAsianCompression;
     sal_uInt8               nAsianKerning;
@@ -1351,6 +1353,7 @@ public:
     bool            IsClipboard() const                         { return bIsClip; }
     bool            IsUndoEnabled() const                       { return mbUndoEnabled; }
     SC_DLLPUBLIC void EnableUndo( bool bVal );
+    bool                IsFunctionAccess() const        { return bIsFunctionAccess; }
 
     bool            IsAdjustHeightEnabled() const               { return mbAdjustHeightEnabled; }
     void            EnableAdjustHeight( bool bVal )             { mbAdjustHeightEnabled = bVal; }
@@ -1910,8 +1913,10 @@ public:
     bool            IsDetectiveDirty() const     { return bDetectiveDirty; }
     void            SetDetectiveDirty(bool bSet) { bDetectiveDirty = bSet; }
 
-    bool            GetHasMacroFunc() const      { return bHasMacroFunc; }
-    void            SetHasMacroFunc(bool bSet)   { bHasMacroFunc = bSet; }
+    bool            HasLinkFormulaNeedingCheck() const      { return bLinkFormulaNeedingCheck; }
+    void            SetLinkFormulaNeedingCheck(bool bSet)   { bLinkFormulaNeedingCheck = bSet; }
+    /** Check token array and set link check if ocDde/ocWebservice is contained. */
+    SC_DLLPUBLIC void CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode );
 
     static bool     CheckMacroWarn();
 
index d5d801a4aeb26037946d2998e64cb117981aa2ce..86dba66f2d3d3ed3a2feda87b253718d5a5016f4 100644 (file)
@@ -55,9 +55,9 @@ public:
     bool idleCheckLinks();
 
     bool hasDdeLinks() const;
-    bool hasDdeOrOleLinks() const;
+    bool hasDdeOrOleOrWebServiceLinks() const;
 
-    bool updateDdeOrOleLinks(vcl::Window* pWin);
+    bool updateDdeOrOleOrWebServiceLinks(vcl::Window* pWin);
 
     void updateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem );
 
@@ -65,7 +65,7 @@ public:
 
     void disconnectDdeLinks();
 private:
-    bool hasDdeOrOleLinks(bool bDde, bool bOle) const;
+    bool hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const;
 };
 
 }
index 7fd1ef53ac6916e873edf01b4daece8ce09eedf0..ba2767c27981a63a905114591af775e76889138c 100644 (file)
@@ -521,6 +521,12 @@ void ScConditionEntry::CompileXML()
     Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar1),
              GetExpression(aSrcPos, 1, 0, eTempGrammar2),
              aStrNmsp1, aStrNmsp2, eTempGrammar1, eTempGrammar2, true );
+
+    // Importing ocDde/ocWebservice?
+    if (pFormula1)
+        mpDoc->CheckLinkFormulaNeedingCheck(*pFormula1);
+    if (pFormula2)
+        mpDoc->CheckLinkFormulaNeedingCheck(*pFormula2);
 }
 
 void ScConditionEntry::SetSrcString( const OUString& rNew )
index 28e246813355cf5e6f30cdb6c298a558b342c051..995cf8879d32025373ede58e31281cd9850ff2e9 100644 (file)
@@ -180,12 +180,13 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
         eHardRecalcState(HARDRECALCSTATE_OFF),
         nVisibleTab( 0 ),
         eLinkMode(LM_UNKNOWN),
-        bAutoCalc( eMode == SCDOCMODE_DOCUMENT ),
+        bAutoCalc( eMode == SCDOCMODE_DOCUMENT || eMode == SCDOCMODE_FUNCTIONACCESS ),
         bAutoCalcShellDisabled( false ),
         bForcedFormulaPending( false ),
         bCalculatingFormulaTree( false ),
         bIsClip( eMode == SCDOCMODE_CLIP ),
         bIsUndo( eMode == SCDOCMODE_UNDO ),
+        bIsFunctionAccess( eMode == SCDOCMODE_FUNCTIONACCESS ),
         bIsVisible( false ),
         bIsEmbedded( false ),
         bInsertingFromOtherDoc( false ),
@@ -200,7 +201,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
         bInDtorClear( false ),
         bExpandRefs( false ),
         bDetectiveDirty( false ),
-        bHasMacroFunc( false ),
+        bLinkFormulaNeedingCheck( false ),
         nAsianCompression(SC_ASIANCOMPRESSION_INVALID),
         nAsianKerning(SC_ASIANKERNING_INVALID),
         bPastingDrawFromOtherDoc( false ),
@@ -222,7 +223,9 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
 
     eSrcSet = osl_getThreadTextEncoding();
 
-    if ( eMode == SCDOCMODE_DOCUMENT )
+    /* TODO: for SCDOCMODE_FUNCTIONACCESS it might not even be necessary to
+     * have all of these available. */
+    if ( eMode == SCDOCMODE_DOCUMENT || eMode == SCDOCMODE_FUNCTIONACCESS )
     {
         xPoolHelper = new ScPoolHelper( this );
 
index a84c2d09a01e473dcf8b325cb2aeb2a7c9c761ee..deb908f5f4969c7b9063a4a6be9f25f8084b08b0 100644 (file)
@@ -88,6 +88,7 @@
 #include "stringutil.hxx"
 #include <documentlinkmgr.hxx>
 #include <scopetools.hxx>
+#include <tokenarray.hxx>
 
 #include <memory>
 
@@ -1153,6 +1154,28 @@ void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode,
     }
 }
 
+void ScDocument::CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode )
+{
+    if (HasLinkFormulaNeedingCheck())
+        return;
+
+    // Prefer RPN over tokenized formula if available.
+    if (rCode.GetCodeLen())
+    {
+        if (rCode.HasOpCodeRPN(ocDde) || rCode.HasOpCodeRPN(ocWebservice))
+            SetLinkFormulaNeedingCheck(true);
+    }
+    else if (rCode.GetLen())
+    {
+        if (rCode.HasOpCode(ocDde) || rCode.HasOpCode(ocWebservice))
+            SetLinkFormulaNeedingCheck(true);
+    }
+    else
+    {
+        assert(!"called with empty ScTokenArray");
+    }
+}
+
 // TimerDelays etc.
 void ScDocument::KeyInput( const KeyEvent& )
 {
index a9cfdec8f7f602f624a5ef441bb12aa51672fa97..b7d8031c6c65df19a82efbd2ff55cccf05334be0 100644 (file)
@@ -1363,10 +1363,9 @@ void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rPr
             bChanged = true;
     }
 
-    //  Same as in Load: after loading, it must be known if ocMacro is in any formula
-    //  (for macro warning, CompileXML is called at the end of loading XML file)
-    if ( !pDocument->GetHasMacroFunc() && pCode->HasOpCodeRPN( ocMacro ) )
-        pDocument->SetHasMacroFunc( true );
+    //  After loading, it must be known if ocDde/ocWebservice is in any formula
+    //  (for external links warning, CompileXML is called at the end of loading XML file)
+    pDocument->CheckLinkFormulaNeedingCheck(*pCode);
 
     //volatile cells must be added here for import
     if( pCode->IsRecalcModeAlways() || pCode->IsRecalcModeForced() ||
diff --git a/sc/source/core/inc/webservicelink.hxx b/sc/source/core/inc/webservicelink.hxx
new file mode 100644 (file)
index 0000000..e61ebfd
--- /dev/null
@@ -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: */
index 38523e5e7e52c1de0727d9ab3b95439daf4563f8..6dc86605534bdb3863a8972d85abc85db0dd8d3c 100644 (file)
@@ -2520,8 +2520,14 @@ void ScInterpreter::ScDde()
                     pBindings->Invalidate( SID_LINKS );             // Link-Manager enablen
             }
 
+            //if the document was just loaded, but the ScDdeLink entry was missing, then
+            //don't update this link until the links are updated in response to the users
+            //decision
+            if (!pDok->HasLinkFormulaNeedingCheck())
+            {
                                     //TODO: evaluate asynchron ???
-            pLink->TryUpdate();     //  TryUpdate doesn't call Update multiple times
+                pLink->TryUpdate(); //  TryUpdate doesn't call Update multiple times
+            }
 
             if (pMyFormulaCell)
             {
index 2d48c6b74ad0de1b953d2c93182d3a7587e5c2d2..2e463d92c9bdcb997f2a82556ace7b6b22d69076 100644 (file)
@@ -13,7 +13,9 @@
 #include "scmatrix.hxx"
 #include <rtl/strbuf.hxx>
 #include <formula/errorcodes.hxx>
+#include <sfx2/bindings.hxx>
 #include <svtools/miscopt.hxx>
+#include <tools/urlobj.hxx>
 
 #include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
 #include <datastreamgettime.hxx>
 #include <dpobject.hxx>
 #include <document.hxx>
+#include <tokenarray.hxx>
+#include <webservicelink.hxx>
+
+#include <sc.hrc>
 
 #include <cstring>
 #include <memory>
@@ -228,6 +234,37 @@ 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].get();
+        if (ScWebServiceLink* pLink = dynamic_cast<ScWebServiceLink*>(pBase))
+        {
+            if (pLink->GetURL() == rURL)
+                return pLink;
+        }
+    }
+
+    return nullptr;
+}
+
+static bool lcl_FunctionAccessLoadWebServiceLink( OUString& rResult, ScDocument* pDoc, const OUString& rURI )
+{
+    // For FunctionAccess service always force a changed data update.
+    ScWebServiceLink aLink( pDoc, rURI);
+    if (aLink.DataChanged( OUString(), css::uno::Any()) != sfx2::SvBaseLink::UpdateResult::SUCCESS)
+        return false;
+
+    if (!aLink.HasResult())
+        return false;
+
+    rResult = aLink.GetResult();
+
+    return true;
+}
+
 void ScInterpreter::ScWebservice()
 {
     sal_uInt8 nParamCount = GetByte();
@@ -241,48 +278,88 @@ void ScInterpreter::ScWebservice()
             return;
         }
 
-        uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY );
-        if(!xFileAccess.is())
+        INetURLObject aObj(aURI, INetProtocol::File);
+        INetProtocol eProtocol = aObj.GetProtocol();
+        if (eProtocol != INetProtocol::Http && eProtocol != INetProtocol::Https)
         {
             PushError( formula::errNoValue );
             return;
         }
 
-        uno::Reference< io::XInputStream > xStream;
-        try {
-            xStream = xFileAccess->openFileRead( aURI );
-        }
-        catch (...)
-        {
-            // don't let any exceptions pass
-            PushError( formula::errNoValue );
-            return;
-        }
-        if ( !xStream.is() )
+        if (!mpLinkManager)
         {
-            PushError( formula::errNoValue );
+            if (!pDok->IsFunctionAccess() || pDok->HasLinkFormulaNeedingCheck())
+            {
+                PushError( formula::errNoValue);
+            }
+            else
+            {
+                OUString aResult;
+                if (lcl_FunctionAccessLoadWebServiceLink( aResult, pDok, aURI))
+                    PushString( aResult);
+                else
+                    PushError( formula::errNoValue);
+            }
+
             return;
         }
 
-        const sal_Int32 BUF_LEN = 8000;
-        uno::Sequence< sal_Int8 > buffer( BUF_LEN );
-        OStringBuffer aBuffer( 64000 );
+        // Need to reinterpret after loading (build links)
+        if (rArr.IsRecalcModeNormal())
+            rArr.SetExclusiveRecalcModeOnLoad();
+
+        //  while the link is not evaluated, idle must be disabled (to avoid circular references)
+        bool bOldEnabled = pDok->IsIdleEnabled();
+        pDok->EnableIdle(false);
+
+        // Get/ Create link object
+        ScWebServiceLink* pLink = lcl_GetWebServiceLink(mpLinkManager, aURI);
+
+        bool bWasError = (pMyFormulaCell && pMyFormulaCell->GetRawError() != formula::errNONE);
 
-        sal_Int32 nRead = 0;
-        while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN )
+        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 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 ( nRead > 0 )
+            if (pMyFormulaCell)
+            {
+                // StartListening after the Update to avoid circular references
+                pMyFormulaCell->StartListening(*pLink);
+            }
+        }
+        else
         {
-            aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
+            if (pMyFormulaCell)
+                pMyFormulaCell->StartListening(*pLink);
         }
 
-        xStream->closeInput();
+        //  If an new Error from Reschedule appears when the link is executed then reset the errorflag
+        if (pMyFormulaCell && pMyFormulaCell->GetRawError() != formula::errNONE && !bWasError)
+            pMyFormulaCell->SetErrCode(formula::errNONE);
+
+        //  check the value
+        if (pLink->HasResult())
+            PushString(pLink->GetResult());
+        else
+            PushError(formula::errNoValue);
 
-        OUString aContent = OStringToOUString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
-        PushString( aContent );
+        pDok->EnableIdle(bOldEnabled);
+        mpLinkManager->CloseCachedComps();
     }
 }
 
index 7626e16ae5f6a7c385597ffb75dca49a8c31b4d3..d147b101de61aa826b427cc0c8992440868aee0e 100644 (file)
@@ -64,9 +64,14 @@ ScRangeData::ScRangeData( ScDocument* pDok,
                 mnMaxCol    (-1)
 {
     if (!rSymbol.isEmpty())
-        CompileRangeData( rSymbol, pDoc->IsImportingXML());
+    {
         // Let the compiler set an error on unknown names for a subsequent
         // CompileUnresolvedXML().
+        const bool bImporting = pDoc->IsImportingXML();
+        CompileRangeData( rSymbol, bImporting);
+        if (bImporting)
+            pDoc->CheckLinkFormulaNeedingCheck( *pCode);
+    }
     else
     {
         // #i63513#/#i65690# don't leave pCode as NULL.
@@ -199,6 +204,7 @@ void ScRangeData::CompileUnresolvedXML( sc::CompileFormulaContext& rCxt )
         // Don't let the compiler set an error for unknown names on final
         // compile, errors are handled by the interpreter thereafter.
         CompileRangeData( aSymbol, false);
+        rCxt.getDoc()->CheckLinkFormulaNeedingCheck( *pCode);
     }
 }
 
diff --git a/sc/source/core/tool/webservicelink.cxx b/sc/source/core/tool/webservicelink.cxx
new file mode 100644 (file)
index 0000000..82310f2
--- /dev/null
@@ -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: */
index c3190550a68c3bcb9721a5c19dc250aa49f0adda..7fa06662194dd2eb3c61a6618a556ebe24f2a30d 100644 (file)
@@ -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);
index bea8ba395a8c89c771676342e81c60fe7cd5ae15..b5c9fef46862f1586927ee814592612f44aa38f5 100644 (file)
@@ -730,6 +730,7 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
                                         << nMerk0 << ocClose;
                                 aPool >> aStack;
                                 pExtName->CreateDdeData( GetDoc(), aApplic, aTopic );
+                                GetDoc().SetLinkFormulaNeedingCheck(true);
                             }
                         }
                         break;
index 6d27232ffd61bd5673354daa6a19f845536702a5..1c25921705c4acbb4e4668a22b36bf67312d1acb 100644 (file)
@@ -867,6 +867,7 @@ void ImportExcel::Shrfmla()
 
     ScFormulaCell* pCell = new ScFormulaCell(pD, aPos, *pErgebnis);
     pCell->GetCode()->WrapReference(aPos, EXC_MAXCOL8, EXC_MAXROW8);
+    rDoc.getDoc().CheckLinkFormulaNeedingCheck( *pCell->GetCode());
     rDoc.getDoc().EnsureTable(aPos.Tab());
     rDoc.setFormulaCell(aPos, pCell);
     pCell->SetNeedNumberFormat(false);
index 05a142d8b1f5ad3f1eeaf0b3e9d54e58c987e168..a863f9beda09a86d506e1e12aac2b88029f3175e 100644 (file)
@@ -663,7 +663,10 @@ void XclImpCondFormat::ReadCF( XclImpStream& rStrm )
         rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize1, false, FT_CondFormat );
         // formula converter owns pTokArr -> create a copy of the token array
         if( pTokArr )
+        {
             xTokArr1.reset( pTokArr->Clone() );
+            GetDocRef().CheckLinkFormulaNeedingCheck( *xTokArr1);
+        }
     }
 
     ::std::unique_ptr< ScTokenArray > pTokArr2;
@@ -674,7 +677,10 @@ void XclImpCondFormat::ReadCF( XclImpStream& rStrm )
         rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize2, false, FT_CondFormat );
         // formula converter owns pTokArr -> create a copy of the token array
         if( pTokArr )
+        {
             pTokArr2.reset( pTokArr->Clone() );
+            GetDocRef().CheckLinkFormulaNeedingCheck( *pTokArr2);
+        }
     }
 
     // *** create the Calc conditional formatting ***
index d09661503c6b0423af081ca4bd222a56f0208299..8decfc00e8e0c09d19257911f24fb3a1d5bc7d36 100644 (file)
@@ -265,7 +265,10 @@ void XclImpName::InsertName(const ScTokenArray* pArray)
         }
     }
     if (pData)
+    {
+        GetDoc().CheckLinkFormulaNeedingCheck( *pData->GetCode());
         mpScData = pData;               // cache for later use
+    }
 }
 
 XclImpNameManager::XclImpNameManager( const XclImpRoot& rRoot ) :
index 1c1eadd88518c4cf51c58acd1e63c8de2e95d0fe..8526d7ffea3ae99fe40b7a58928e072eb7e625ec 100644 (file)
@@ -875,11 +875,13 @@ void CondFormatRule::finalizeImport()
         {
             pTokenArray2.reset(new ScTokenArray());
             ScTokenConversion::ConvertToTokenArray( rDoc, *pTokenArray2.get(), maModel.maFormulas[ 1 ] );
+            rDoc.CheckLinkFormulaNeedingCheck( *pTokenArray2.get());
         }
 
         ScTokenArray aTokenArray;
         OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId );
         ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, maModel.maFormulas[ 0 ] );
+        rDoc.CheckLinkFormulaNeedingCheck( aTokenArray);
         ScCondFormatEntry* pNewEntry = new ScCondFormatEntry(eOperator,
                                             &aTokenArray, pTokenArray2.get(), &rDoc, aPos, aStyleName);
         mpFormat->AddEntry(pNewEntry);
index 9de5851e3978c7333eb88a936397a7b66e8eb36e..586511d1d25aabfd6ebd3b612b148ecec391930c 100644 (file)
@@ -39,6 +39,7 @@
 #include "tokenarray.hxx"
 #include "tokenuno.hxx"
 #include "compiler.hxx"
+#include "document.hxx"
 
 namespace oox {
 namespace xls {
@@ -339,6 +340,7 @@ std::unique_ptr<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);
 
index 41c99f80062e7b8e1140958e6f73f16fa8da9d72..b139ac9752404246e73a053dd35c99cbef226f73 100644 (file)
@@ -228,6 +228,10 @@ void applyCellFormulas(
             continue;
 
         aCompiler.CompileTokenArray(); // Generate RPN tokens.
+
+        // Check if ocDde/ocWebservice is in any formula for external links warning.
+        rDoc.getDoc().CheckLinkFormulaNeedingCheck(*pCode);
+
         ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, pCode);
         rDoc.setFormulaCell(aPos, pCell);
         rCache.store(aPos, pCell);
index 853692cf898e59ba15e713d5c297768b1c1b6bd5..0e7671bdeffb14d4445d6ca8cbf04a6eb404f5b5 100644 (file)
@@ -448,7 +448,7 @@ void ScDocShell::Execute( SfxRequest& rReq )
                     ReloadTabLinks();
                     aDocument.UpdateExternalRefLinks(GetActiveDialogParent());
 
-                    bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleLinks(GetActiveDialogParent());
+                    bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleOrWebServiceLinks(GetActiveDialogParent());
 
                     if (bAnyDde)
                     {
@@ -470,6 +470,8 @@ void ScDocShell::Execute( SfxRequest& rReq )
                     rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false);
                     rReq.Ignore();
                 }
+
+                rDoc.SetLinkFormulaNeedingCheck(false);
             }
             break;
 
index 520b8542afc037ad4905fbf11ac520cb9822bbe1..b8a9df65cb6bbb71ccdc28fedec1444ab75a47b0 100644 (file)
@@ -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;
index c5cb6d2a4791c51f52432756d7070c59841a7a2b..011202aa1edd73a3e86d7b373db4542a4002de39 100644 (file)
@@ -74,7 +74,7 @@ public:
 
 ScDocument* ScTempDocSource::CreateDocument()
 {
-    ScDocument* pDoc = new ScDocument;                  // SCDOCMODE_DOCUMENT
+    ScDocument* pDoc = new ScDocument( SCDOCMODE_FUNCTIONACCESS );
     pDoc->MakeTable( 0 );
     return pDoc;
 }
index a8f319708bb3da9bbb5ae71f159cfc5cb6320de1..f203b13bbc10055e599d815ecac4b1bc491fb85f 100644 (file)
@@ -1564,7 +1564,7 @@ void ScTabViewShell::Construct( TriState nForceDesignMode )
             if (!bLink)
             {
                 const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager();
-                if (rMgr.hasDdeOrOleLinks() || rDoc.HasAreaLinks())
+                if (rDoc.HasLinkFormulaNeedingCheck() || rDoc.HasAreaLinks() || rMgr.hasDdeOrOleOrWebServiceLinks())
                     bLink = true;
             }
             if (bLink)