[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-4.2' - include/sfx2 sc/inc sc/source sfx2/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed May 21 11:48:55 PDT 2014


 include/sfx2/sfxmodelfactory.hxx         |   14 
 sc/inc/compiler.hxx                      |    2 
 sc/inc/document.hxx                      |    3 
 sc/inc/externalrefmgr.hxx                |   35 ++
 sc/inc/sc.hrc                            |    3 
 sc/inc/scopetools.hxx                    |    9 
 sc/inc/unonames.hxx                      |    3 
 sc/inc/xmlwrap.hxx                       |   25 +
 sc/source/core/data/documen2.cxx         |    1 
 sc/source/core/data/documen8.cxx         |   62 ++--
 sc/source/core/data/documen9.cxx         |    5 
 sc/source/core/tool/compiler.cxx         |  106 ++----
 sc/source/core/tool/scopetools.cxx       |   14 
 sc/source/filter/xml/xmlimprt.cxx        |   40 ++
 sc/source/filter/xml/xmlimprt.hxx        |    7 
 sc/source/filter/xml/xmlwrap.cxx         |  471 +++++++++++++++----------------
 sc/source/ui/docshell/docsh.cxx          |   20 -
 sc/source/ui/docshell/externalrefmgr.cxx |  290 ++++++++++++++++---
 sc/source/ui/src/scstring.src            |    5 
 sfx2/source/doc/objxtor.cxx              |   11 
 20 files changed, 705 insertions(+), 421 deletions(-)

New commits:
commit a6e5c7934679329f84eca3c5eb8d021b277c905b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon May 19 23:42:05 2014 -0400

    cp#1000072: Improve on-load updates of external links.
    
    * Load all linked external sources up front, rather than on-demand after
      the cache purge.
    
    * Try to pre-populate updated caches rather than leaving them blank and
      wait until it gets filled during formula calculation.
    
    * Disable polling of stale doc shell instances while the update is
      on-going.  This improves the update performance especially when the update
      takes a long time.
    
    * Only close one doc shell instance at a time, even when there are multiple
      stale doc shell instances that need to be closed, to prevent too long of
      a pause.
    
    * Show progress bar during the update to give the user some visual feedback
      of the progress.
    
    * Skip loading of styles for the linked external document shells.  We don't
      need them.  For now, this is ODS only.
    
    * Minor performance improvement of ODS import.
    
    Conflicts:
    	include/sfx2/sfxmodelfactory.hxx
    	sc/inc/sc.hrc
    	sc/inc/xmlwrap.hxx
    	sc/source/core/data/documen8.cxx
    	sc/source/filter/xml/xmlimprt.cxx
    	sc/source/filter/xml/xmlwrap.cxx
    	sc/source/ui/docshell/docsh.cxx
    	sfx2/source/doc/objxtor.cxx
    
    Change-Id: I80aa71fa27e4960e9256253369aa898dd542c9b5

diff --git a/include/sfx2/sfxmodelfactory.hxx b/include/sfx2/sfxmodelfactory.hxx
index 70cfcf5..ed932e0 100644
--- a/include/sfx2/sfxmodelfactory.hxx
+++ b/include/sfx2/sfxmodelfactory.hxx
@@ -25,16 +25,14 @@
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
 
-//........................................................................
+#define SFXMODEL_STANDARD                   (sal_uInt64)(0x0000)
+#define SFXMODEL_EMBEDDED_OBJECT            (sal_uInt64)(0x0001)
+#define SFXMODEL_EXTERNAL_LINK              (sal_uInt64)(0x0002)
+#define SFXMODEL_DISABLE_EMBEDDED_SCRIPTS   (sal_uInt64)(0x0004)
+#define SFXMODEL_DISABLE_DOCUMENT_RECOVERY  (sal_uInt64)(0x0008)
+
 namespace sfx2
 {
-//........................................................................
-
-    #define SFXMODEL_STANDARD                   (sal_uInt64)(0x0000)
-    #define SFXMODEL_EMBEDDED_OBJECT            (sal_uInt64)(0x0001)
-    #define SFXMODEL_DISABLE_EMBEDDED_SCRIPTS   (sal_uInt64)(0x0002)
-    #define SFXMODEL_DISABLE_DOCUMENT_RECOVERY  (sal_uInt64)(0x0004)
-
     typedef ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > ( SAL_CALL * SfxModelFactoryFunc ) (
         const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory,
         const sal_uInt64 _nCreationFlags
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index b88ecd5..e17ad4f 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -323,7 +323,7 @@ private:
     sal_Unicode cSymbol[MAXSTRLEN];                 // current Symbol
     OUString    aFormula;                           // formula source code
     sal_Int32   nSrcPos;                            // tokenizer position (source code)
-    mutable ScRawTokenRef pRawToken;
+    mutable ScRawToken maRawToken;
 
     const CharClass*    pCharClass;         // which character classification is used for parseAnyToken
     sal_uInt16      mnPredetectedReference;     // reference when reading ODF, 0 (none), 1 (single) or 2 (double)
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 339bbb0..5e2d82a 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -396,7 +396,6 @@ private:
     bool                bInsertingFromOtherDoc;
     bool                bLoadingMedium;
     bool                bImportingXML;      // special handling of formula text
-    bool                bXMLFromWrapper;    // distinguish ScXMLImportWrapper from external component
     bool                bCalcingAfterLoad;              // in CalcAfterLoad TRUE
     // don't construct/destruct listeners temporarily
     bool                bNoListening;
@@ -1740,8 +1739,6 @@ public:
     void            SetLoadingMedium( bool bVal );
     void            SetImportingXML( bool bVal );
     bool            IsImportingXML() const { return bImportingXML; }
-    void            SetXMLFromWrapper( bool bVal );
-    bool            IsXMLFromWrapper() const { return bXMLFromWrapper; }
     void            SetCalcingAfterLoad( bool bVal ) { bCalcingAfterLoad = bVal; }
     bool            IsCalcingAfterLoad() const { return bCalcingAfterLoad; }
     void            SetNoListening( bool bVal ) { bNoListening = bVal; }
diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index d5b4d7f..1c20c58 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -56,6 +56,12 @@ class SharedStringPool;
 
 }
 
+namespace sc {
+
+class ColumnSpanSet;
+
+}
+
 class ScExternalRefLink : public ::sfx2::SvBaseLink
 {
 public:
@@ -146,6 +152,8 @@ public:
         Table();
         ~Table();
 
+        void clear();
+
         /**
          * Add cell value to the cache.
          *
@@ -269,6 +277,13 @@ public:
     void setAllCacheTableReferencedStati( bool bReferenced );
     bool areAllCacheTablesReferenced() const;
 
+    /**
+     * Collect all cached non-empty cell positions, inferred directly from the
+     * cached data, not the cached range metadata stored separately in the
+     * Table.
+     */
+    void getAllCachedDataSpans( sal_uInt16 nFileId, sc::ColumnSpanSet& rSet ) const;
+
 private:
     struct ReferencedStatus
     {
@@ -296,8 +311,17 @@ public:
     ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
     ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew, size_t* pnIndex);
 
+    /**
+     * Clear all caches including the cache tables.
+     */
     void clearCache(sal_uInt16 nFileId);
 
+    /**
+     * Clear all caches but keep the tables.  All cache tables will be empty
+     * after the call, but the tables will not be removed.
+     */
+    void clearCacheTables(sal_uInt16 nFileId);
+
 private:
     struct RangeHash
     {
@@ -600,7 +624,7 @@ public:
     const OUString* getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const;
     const OUString* getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const;
     void clearCache(sal_uInt16 nFileId);
-    void refreshNames(sal_uInt16 nFileId);
+    bool refreshSrcDocument(sal_uInt16 nFileId);
     void breakLink(sal_uInt16 nFileId);
     void switchSrcFile(sal_uInt16 nFileId, const OUString& rNewFile, const OUString& rNewFilter);
 
@@ -690,6 +714,8 @@ public:
 
     void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell);
 
+    void enableDocTimer( bool bEnable );
+
 private:
     ScExternalRefManager();
     ScExternalRefManager(const ScExternalRefManager&);
@@ -739,6 +765,11 @@ private:
     ScDocument* getSrcDocument(sal_uInt16 nFileId);
     SfxObjectShellRef loadSrcDocument(sal_uInt16 nFileId, OUString& rFilter);
 
+    /**
+     * Caller must ensure that the passed shell is not already stored.
+     */
+    ScDocument* cacheNewDocShell( sal_uInt16 nFileId, SrcShell& rSrcShell );
+
     void maybeLinkExternalFile(sal_uInt16 nFileId);
 
     /**
@@ -818,6 +849,8 @@ private:
      */
     bool mbUserInteractionEnabled:1;
 
+    bool mbDocTimerEnabled:1;
+
     AutoTimer maSrcDocTimer;
     DECL_LINK(TimeOutHdl, AutoTimer*);
 };
diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index ae2673d..02f0b81 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -962,7 +962,8 @@
 
 #define SCSTR_VALERR            (STR_START + 414)
 
-#define STR_END                 (SCSTR_VALERR)
+#define SCSTR_UPDATE_EXTDOCS    (STR_START + 415)
+#define STR_END                 (SCSTR_UPDATE_EXTDOCS)
 
 #define BMP_START               (STR_END)
 
diff --git a/sc/inc/scopetools.hxx b/sc/inc/scopetools.hxx
index 40f1dec..2a0bd5b 100644
--- a/sc/inc/scopetools.hxx
+++ b/sc/inc/scopetools.hxx
@@ -13,6 +13,7 @@
 #include "scdllapi.h"
 
 class ScDocument;
+class Window;
 
 namespace sc {
 
@@ -46,6 +47,14 @@ public:
     ~IdleSwitch();
 };
 
+class WaitPointerSwitch
+{
+    Window* mpFrameWin;
+public:
+    WaitPointerSwitch(Window* pWin);
+    ~WaitPointerSwitch();
+};
+
 }
 
 #endif
diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx
index ff4cf93..0471ae4 100644
--- a/sc/inc/unonames.hxx
+++ b/sc/inc/unonames.hxx
@@ -668,6 +668,9 @@
 
 #define SC_UNO_EMBED_FONTS     "EmbedFonts"
 
+#define SC_UNO_ODS_LOCK_SOLAR_MUTEX "ODSLockSolarMutex"
+#define SC_UNO_ODS_IMPORT_STYLES    "ODSImportStyles"
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/xmlwrap.hxx b/sc/inc/xmlwrap.hxx
index 107ceb4..82360f8 100644
--- a/sc/inc/xmlwrap.hxx
+++ b/sc/inc/xmlwrap.hxx
@@ -27,10 +27,6 @@
 
 #include <importfilterdata.hxx>
 
-class ScDocument;
-class SfxMedium;
-class ScMySharedData;
-
 #include <tools/errcode.hxx>
 
 namespace com { namespace sun { namespace star {
@@ -44,10 +40,16 @@ namespace com { namespace sun { namespace star {
         namespace sax { struct InputSource; class XParser; class XWriter; } }
 } } }
 
+class ScDocument;
+class SfxMedium;
+class ScMySharedData;
+class ScDocShell;
+
 class ScXMLImportWrapper
 {
     sc::ImportPostProcessData maPostProcessData;
 
+    ScDocShell& mrDocShell;
     ScDocument&     rDoc;
     SfxMedium*      pMedium;
     ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > xStorage;
@@ -71,9 +73,18 @@ class ScXMLImportWrapper
         ScMySharedData*& pSharedData);
 
 public:
-    ScXMLImportWrapper(ScDocument& rD, SfxMedium* pM, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >&);
-    sal_Bool Import(sal_Bool bStylesOnly, ErrCode& );
-    sal_Bool Export(sal_Bool bStylesOnly);
+
+    static const sal_uInt8 STYLES   = 0x01;
+    static const sal_uInt8 CONTENT  = 0x02;
+    static const sal_uInt8 METADATA = 0x04;
+    static const sal_uInt8 SETTINGS = 0x08;
+    static const sal_uInt8 ALL      = STYLES | CONTENT | METADATA | SETTINGS;
+
+    ScXMLImportWrapper(
+        ScDocShell& rDocSh, SfxMedium* pM, const css::uno::Reference<css::embed::XStorage>& xStor );
+
+    bool Import( sal_uInt8 nMode, ErrCode& rError );
+    bool Export(bool bStylesOnly);
 
     const sc::ImportPostProcessData& GetImportPostProcessData() const;
 };
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index eb3eab2..e61b7fa 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -190,7 +190,6 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
         bInsertingFromOtherDoc( false ),
         bLoadingMedium( false ),
         bImportingXML( false ),
-        bXMLFromWrapper( false ),
         bCalcingAfterLoad( false ),
         bNoListening( false ),
         mbIdleEnabled(true),
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index 47ad103..3272c9e 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -86,6 +86,7 @@
 #include "columniterator.hxx"
 #include "globalnames.hxx"
 #include "stringutil.hxx"
+#include <scopetools.hxx>
 
 #include <memory>
 #include <boost/scoped_ptr.hpp>
@@ -856,40 +857,61 @@ bool ScDocument::IsInLinkUpdate() const
 
 void ScDocument::UpdateExternalRefLinks(Window* pWin)
 {
-    if (!GetLinkManager())
+    sfx2::LinkManager* pMgr = GetLinkManager();
+    if (!pMgr)
+        return;
+
+    if (!pExternalRefMgr.get())
         return;
 
     const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
     sal_uInt16 nCount = rLinks.size();
 
     bool bAny = false;
+
+    // Collect all the external ref links first.
+    std::vector<ScExternalRefLink*> aRefLinks;
     for (sal_uInt16 i = 0; i < nCount; ++i)
     {
         ::sfx2::SvBaseLink* pBase = *rLinks[i];
         ScExternalRefLink* pRefLink = dynamic_cast<ScExternalRefLink*>(pBase);
         if (pRefLink)
+            aRefLinks.push_back(pRefLink);
+    }
+
+    sc::WaitPointerSwitch aWaitSwitch(pWin);
+
+    pExternalRefMgr->enableDocTimer(false);
+    ScProgress aProgress(GetDocumentShell(), ScResId(SCSTR_UPDATE_EXTDOCS).toString(), aRefLinks.size());
+    for (size_t i = 0, n = aRefLinks.size(); i < n; ++i)
+    {
+        aProgress.SetState(i+1);
+
+        ScExternalRefLink* pRefLink = aRefLinks[i];
+        if (pRefLink->Update())
         {
-            if (pRefLink->Update())
-                bAny = true;
-            else
-            {
-                // Update failed.  Notify the user.
-
-                OUString aFile;
-                pLinkManager->GetDisplayNames(pRefLink, NULL, &aFile, NULL, NULL);
-                // Decode encoded URL for display friendliness.
-                INetURLObject aUrl(aFile,INetURLObject::WAS_ENCODED);
-                aFile = aUrl.GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS);
-
-                OUStringBuffer aBuf;
-                aBuf.append(OUString(ScResId(SCSTR_EXTDOC_NOT_LOADED)));
-                aBuf.appendAscii("\n\n");
-                aBuf.append(aFile);
-                ErrorBox aBox(pWin, WB_OK, aBuf.makeStringAndClear());
-                aBox.Execute();
-            }
+            bAny = true;
+            continue;
         }
+
+        // Update failed.  Notify the user.
+
+        OUString aFile;
+        pMgr->GetDisplayNames(pRefLink, NULL, &aFile, NULL, NULL);
+        // Decode encoded URL for display friendliness.
+        INetURLObject aUrl(aFile,INetURLObject::WAS_ENCODED);
+        aFile = aUrl.GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS);
+
+        OUStringBuffer aBuf;
+        aBuf.append(OUString(ScResId(SCSTR_EXTDOC_NOT_LOADED)));
+        aBuf.appendAscii("\n\n");
+        aBuf.append(aFile);
+        ErrorBox aBox(pWin, WB_OK, aBuf.makeStringAndClear());
+        aBox.Execute();
     }
+
+    pExternalRefMgr->enableDocTimer(true);
+
     if (bAny)
     {
         TrackFormulas();
diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx
index 7eac811..13bc844 100644
--- a/sc/source/core/data/documen9.cxx
+++ b/sc/source/core/data/documen9.cxx
@@ -619,11 +619,6 @@ void ScDocument::SetImportingXML( bool bVal )
     SetLoadingMedium(bVal);
 }
 
-void ScDocument::SetXMLFromWrapper( bool bVal )
-{
-    bXMLFromWrapper = bVal;
-}
-
 rtl::Reference<SvxForbiddenCharactersTable> ScDocument::GetForbiddenCharacters()
 {
     return xForbiddenCharacters;
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index fa133d3..5e66f80 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -2342,7 +2342,6 @@ bool ScCompiler::IsOpCode( const OUString& rName, bool bInArray )
     bool bFound = (iLook != mxSymbols->getHashMap()->end());
     if (bFound)
     {
-        ScRawToken aToken;
         OpCode eOp = iLook->second;
         if (bInArray)
         {
@@ -2351,8 +2350,7 @@ bool ScCompiler::IsOpCode( const OUString& rName, bool bInArray )
             else if (rName.equals(mxSymbols->getSymbol(ocArrayRowSep)))
                 eOp = ocArrayRowSep;
         }
-        aToken.SetOpCode(eOp);
-        pRawToken = aToken.Clone();
+        maRawToken.SetOpCode(eOp);
     }
     else if (mxSymbols->isODFF())
     {
@@ -2380,9 +2378,7 @@ bool ScCompiler::IsOpCode( const OUString& rName, bool bInArray )
         {
             if (rName.equalsIgnoreAsciiCaseAscii( aOdffAliases[i].pName))
             {
-                ScRawToken aToken;
-                aToken.SetOpCode( aOdffAliases[i].eOp);
-                pRawToken = aToken.Clone();
+                maRawToken.SetOpCode( aOdffAliases[i].eOp);
                 bFound = true;
                 break;  // for
             }
@@ -2415,9 +2411,7 @@ bool ScCompiler::IsOpCode( const OUString& rName, bool bInArray )
             // Old (deprecated) addins first for legacy.
             if (ScGlobal::GetFuncCollection()->findByName(cSymbol))
             {
-                ScRawToken aToken;
-                aToken.SetExternal( cSymbol );
-                pRawToken = aToken.Clone();
+                maRawToken.SetExternal( cSymbol );
             }
             else
                 // bLocalFirst=false for (English) upper full original name
@@ -2427,14 +2421,12 @@ bool ScCompiler::IsOpCode( const OUString& rName, bool bInArray )
         }
         if (!aIntName.isEmpty())
         {
-            ScRawToken aToken;
-            aToken.SetExternal( aIntName.getStr() );     // international name
-            pRawToken = aToken.Clone();
+            maRawToken.SetExternal( aIntName.getStr() );     // international name
             bFound = true;
         }
     }
     OpCode eOp;
-    if (bFound && ((eOp = pRawToken->GetOpCode()) == ocSub || eOp == ocNegSub))
+    if (bFound && ((eOp = maRawToken.GetOpCode()) == ocSub || eOp == ocNegSub))
     {
         bool bShouldBeNegSub =
             (eLastOp == ocOpen || eLastOp == ocSep || eLastOp == ocNegSub ||
@@ -2442,10 +2434,10 @@ bool ScCompiler::IsOpCode( const OUString& rName, bool bInArray )
              eLastOp == ocArrayOpen ||
              eLastOp == ocArrayColSep || eLastOp == ocArrayRowSep);
         if (bShouldBeNegSub && eOp == ocSub)
-            pRawToken->NewOpCode( ocNegSub );
+            maRawToken.NewOpCode( ocNegSub );
             //! if ocNegSub had ForceArray we'd have to set it here
         else if (!bShouldBeNegSub && eOp == ocNegSub)
-            pRawToken->NewOpCode( ocSub );
+            maRawToken.NewOpCode( ocSub );
     }
     return bFound;
 }
@@ -2460,9 +2452,7 @@ bool ScCompiler::IsOpCode2( const OUString& rName )
 
     if (bFound)
     {
-        ScRawToken aToken;
-        aToken.SetOpCode( (OpCode) --i );
-        pRawToken = aToken.Clone();
+        maRawToken.SetOpCode( (OpCode) --i );
     }
     return bFound;
 }
@@ -2497,9 +2487,7 @@ bool ScCompiler::IsValue( const OUString& rSym )
     if( nType == NUMBERFORMAT_TEXT )
         // HACK: number too big!
         SetError( errIllegalArgument );
-    ScRawToken aToken;
-    aToken.SetDouble( fVal );
-    pRawToken = aToken.Clone();
+    maRawToken.SetDouble( fVal );
     return true;
 }
 
@@ -2518,11 +2506,9 @@ bool ScCompiler::IsString()
     if ( bQuote )
     {
         cSymbol[nLen] = '\0';
-        ScRawToken aToken;
         const sal_Unicode* pStr = cSymbol+1;
         svl::SharedString aSS = pDoc->GetSharedStringPool().intern(OUString(pStr));
-        aToken.SetString(aSS.getData(), aSS.getDataIgnoreCase());
-        pRawToken = aToken.Clone();
+        maRawToken.SetString(aSS.getData(), aSS.getDataIgnoreCase());
         return true;
     }
     return false;
@@ -2593,7 +2579,6 @@ bool ScCompiler::IsDoubleReference( const OUString& rName )
     sal_uInt16 nFlags = aRange.Parse( rName, pDoc, aDetails, &aExtInfo, &maExternalLinks );
     if( nFlags & SCA_VALID )
     {
-        ScRawToken aToken;
         ScComplexRefData aRef;
         aRef.InitRange( aRange );
         aRef.Ref1.SetColRel( (nFlags & SCA_COL_ABSOLUTE) == 0 );
@@ -2613,15 +2598,14 @@ bool ScCompiler::IsDoubleReference( const OUString& rName )
         {
             ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
             const OUString* pRealTab = pRefMgr->getRealTableName(aExtInfo.mnFileId, aExtInfo.maTabName);
-            aToken.SetExternalDoubleRef(
+            maRawToken.SetExternalDoubleRef(
                 aExtInfo.mnFileId, pRealTab ? *pRealTab : aExtInfo.maTabName, aRef);
             maExternalFiles.push_back(aExtInfo.mnFileId);
         }
         else
         {
-            aToken.SetDoubleReference(aRef);
+            maRawToken.SetDoubleReference(aRef);
         }
-        pRawToken = aToken.Clone();
     }
 
     return ( nFlags & SCA_VALID ) != 0;
@@ -2637,7 +2621,6 @@ bool ScCompiler::IsSingleReference( const OUString& rName )
     // as a (wrong) reference.
     if( nFlags & ( SCA_VALID_COL|SCA_VALID_ROW|SCA_VALID_TAB ) )
     {
-        ScRawToken aToken;
         ScSingleRefData aRef;
         aRef.InitAddress( aAddr );
         aRef.SetColRel( (nFlags & SCA_COL_ABSOLUTE) == 0 );
@@ -2661,13 +2644,12 @@ bool ScCompiler::IsSingleReference( const OUString& rName )
         {
             ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
             const OUString* pRealTab = pRefMgr->getRealTableName(aExtInfo.mnFileId, aExtInfo.maTabName);
-            aToken.SetExternalSingleRef(
+            maRawToken.SetExternalSingleRef(
                 aExtInfo.mnFileId, pRealTab ? *pRealTab : aExtInfo.maTabName, aRef);
             maExternalFiles.push_back(aExtInfo.mnFileId);
         }
         else
-            aToken.SetSingleReference(aRef);
-        pRawToken = aToken.Clone();
+            maRawToken.SetSingleReference(aRef);
     }
 
     return ( nFlags & SCA_VALID ) != 0;
@@ -2818,10 +2800,8 @@ bool ScCompiler::IsMacro( const OUString& rName )
         rSolarMutex.release();
         return false;
     }
-    ScRawToken aToken;
-    aToken.SetExternal( aName.getStr() );
-    aToken.eOp = ocMacro;
-    pRawToken = aToken.Clone();
+    maRawToken.SetExternal( aName.getStr() );
+    maRawToken.eOp = ocMacro;
     rSolarMutex.release();
     return true;
 #endif
@@ -2848,9 +2828,7 @@ bool ScCompiler::IsNamedRange( const OUString& rUpperName )
 
     if (pData)
     {
-        ScRawToken aToken;
-        aToken.SetName(bGlobal, pData->GetIndex());
-        pRawToken = aToken.Clone();
+        maRawToken.SetName(bGlobal, pData->GetIndex());
         return true;
     }
     else
@@ -2872,7 +2850,6 @@ bool ScCompiler::IsExternalNamedRange( const OUString& rSymbol )
     if (!pConv->parseExternalName( rSymbol, aFile, aName, pDoc, &maExternalLinks))
         return false;
 
-    ScRawToken aToken;
     if (aFile.getLength() > MAXSTRLEN || aName.getLength() > MAXSTRLEN)
         return false;
 
@@ -2886,8 +2863,7 @@ bool ScCompiler::IsExternalNamedRange( const OUString& rSymbol )
         return false;
 
     const OUString* pRealName = pRefMgr->getRealRangeName(nFileId, aName);
-    aToken.SetExternalName(nFileId, pRealName ? *pRealName : OUString(aTmp));
-    pRawToken = aToken.Clone();
+    maRawToken.SetExternalName(nFileId, pRealName ? *pRealName : OUString(aTmp));
     maExternalFiles.push_back(nFileId);
     return true;
 }
@@ -2896,13 +2872,11 @@ bool ScCompiler::IsDBRange( const OUString& rName )
 {
     if (rName.equalsAscii("[]"))
     {
-        if (pRawToken && pRawToken->GetOpCode() == ocDBArea)
+        if (maRawToken.GetOpCode() == ocDBArea)
         {
             // In OOXML, a database range is named Table1[], Table2[] etc.
             // Skip the [] part if the previous token is a valid db range.
-            ScRawToken aToken;
-            aToken.eOp = ocSkip;
-            pRawToken = aToken.Clone();
+            maRawToken.eOp = ocSkip;
             return true;
         }
     }
@@ -2911,10 +2885,8 @@ bool ScCompiler::IsDBRange( const OUString& rName )
     if (!p)
         return false;
 
-    ScRawToken aToken;
-    aToken.SetName(true, p->GetIndex()); // DB range is always global.
-    aToken.eOp = ocDBArea;
-    pRawToken = aToken.Clone();
+    maRawToken.SetName(true, p->GetIndex()); // DB range is always global.
+    maRawToken.eOp = ocDBArea;
     return true;
 }
 
@@ -3160,10 +3132,8 @@ bool ScCompiler::IsColRowName( const OUString& rName )
     }
     if ( bFound )
     {
-        ScRawToken aToken;
-        aToken.SetSingleReference( aRef );
-        aToken.eOp = ocColRowName;
-        pRawToken = aToken.Clone();
+        maRawToken.SetSingleReference( aRef );
+        maRawToken.eOp = ocColRowName;
         return true;
     }
     else
@@ -3177,9 +3147,7 @@ bool ScCompiler::IsBoolean( const OUString& rName )
         ((*iLook).second == ocTrue ||
          (*iLook).second == ocFalse) )
     {
-        ScRawToken aToken;
-        aToken.SetOpCode( (*iLook).second );
-        pRawToken = aToken.Clone();
+        maRawToken.SetOpCode( (*iLook).second );
         return true;
     }
     else
@@ -3191,9 +3159,7 @@ bool ScCompiler::IsErrorConstant( const OUString& rName ) const
     sal_uInt16 nError = GetErrorConstant( rName);
     if (nError)
     {
-        ScRawToken aToken;
-        aToken.SetErrorConstant( nError);
-        pRawToken = aToken.Clone();
+        maRawToken.SetErrorConstant( nError);
         return true;
     }
     else
@@ -3432,11 +3398,9 @@ bool ScCompiler::NextNewToken( bool bInArray )
              * original string containing partial valid address
              * information if not ODFF (in that case it was already handled).
              * */
-            ScRawToken aToken;
             svl::SharedString aSS = pDoc->GetSharedStringPool().intern(aStr);
-            aToken.SetString(aSS.getData(), aSS.getDataIgnoreCase());
-            aToken.NewOpCode( ocBad );
-            pRawToken = aToken.Clone();
+            maRawToken.SetString(aSS.getData(), aSS.getDataIgnoreCase());
+            maRawToken.NewOpCode( ocBad );
         }
         return true;
     }
@@ -3530,7 +3494,7 @@ bool ScCompiler::NextNewToken( bool bInArray )
             // If a syntactically correct reference was recognized but invalid
             // e.g. because of non-existing sheet name => entire reference
             // ocBad to preserve input instead of #REF!.A1
-            if (!pRawToken->IsValidReference())
+            if (!maRawToken.IsValidReference())
             {
                 aUpper = aOrg;          // ensure for ocBad
                 break;                  // do; create ocBad token or set error.
@@ -3583,11 +3547,9 @@ bool ScCompiler::NextNewToken( bool bInArray )
     // would prematurely end compilation. Simple unknown names are handled by
     // the interpreter.
     aUpper = ScGlobal::pCharClass->lowercase( aUpper );
-    ScRawToken aToken;
     svl::SharedString aSS = pDoc->GetSharedStringPool().intern(aUpper);
-    aToken.SetString(aSS.getData(), aSS.getDataIgnoreCase());
-    aToken.NewOpCode( ocBad );
-    pRawToken = aToken.Clone();
+    maRawToken.SetString(aSS.getData(), aSS.getDataIgnoreCase());
+    maRawToken.NewOpCode( ocBad );
     if ( bAutoCorrect )
         AutoCorrectParsedSymbol();
     return true;
@@ -3679,7 +3641,7 @@ ScTokenArray* ScCompiler::CompileString( const OUString& rFormula )
     eLastOp = ocOpen;
     while( NextNewToken( bInArray ) )
     {
-        const OpCode eOp = pRawToken->GetOpCode();
+        const OpCode eOp = maRawToken.GetOpCode();
         if (eOp == ocSkip)
             continue;
 
@@ -3809,7 +3771,7 @@ ScTokenArray* ScCompiler::CompileString( const OUString& rFormula )
                 ++pFunctionStack[ nFunction ].nSep;
             }
         }
-        FormulaToken* pNewToken = static_cast<ScTokenArray*>(pArr)->Add( pRawToken->CreateToken());
+        FormulaToken* pNewToken = static_cast<ScTokenArray*>(pArr)->Add( maRawToken.CreateToken());
         if (!pNewToken)
         {
             SetError(errCodeOverflow); break;
@@ -3817,7 +3779,7 @@ ScTokenArray* ScCompiler::CompileString( const OUString& rFormula )
         else if (eLastOp == ocRange && pNewToken->GetOpCode() == ocPush &&
                 pNewToken->GetType() == svSingleRef)
             static_cast<ScTokenArray*>(pArr)->MergeRangeReference( aPos);
-        eLastOp = pRawToken->GetOpCode();
+        eLastOp = maRawToken.GetOpCode();
         if ( bAutoCorrect )
             aCorrectedFormula += aCorrectedSymbol;
     }
diff --git a/sc/source/core/tool/scopetools.cxx b/sc/source/core/tool/scopetools.cxx
index 6f423d0..d8e9a30 100644
--- a/sc/source/core/tool/scopetools.cxx
+++ b/sc/source/core/tool/scopetools.cxx
@@ -9,6 +9,7 @@
 
 #include "scopetools.hxx"
 #include "document.hxx"
+#include <vcl/window.hxx>
 
 namespace sc {
 
@@ -45,6 +46,19 @@ IdleSwitch::~IdleSwitch()
     mrDoc.EnableIdle(mbOldValue);
 }
 
+WaitPointerSwitch::WaitPointerSwitch(Window* pWin) :
+    mpFrameWin(pWin)
+{
+    if (mpFrameWin)
+        mpFrameWin->EnterWait();
+}
+
+WaitPointerSwitch::~WaitPointerSwitch()
+{
+    if (mpFrameWin)
+        mpFrameWin->LeaveWait();
+}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 5c5a761..904d62c 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -68,6 +68,7 @@
 #include "editattributemap.hxx"
 #include "documentimport.hxx"
 #include "pivotsource.hxx"
+#include <unonames.hxx>
 
 #include <comphelper/extract.hxx>
 
@@ -2116,7 +2117,8 @@ ScXMLImport::ScXMLImport(
     bRemoveLastChar(false),
     bNullDateSetted(false),
     bSelfImportingXMLSet(false),
-    bFromWrapper(false),
+    mbLockSolarMutex(true),
+    mbImportStyles(true),
     mbHasNewCondFormatData(false)
 {
     pStylesImportHelper = new ScMyStylesImportHelper(*this);
@@ -2254,7 +2256,25 @@ ScXMLImport::~ScXMLImport() throw()
     delete pDetectiveOpArray;
 }
 
-// ---------------------------------------------------------------------
+void ScXMLImport::initialize( const css::uno::Sequence<css::uno::Any>& aArguments )
+        throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
+{
+    SvXMLImport::initialize(aArguments);
+
+    uno::Reference<beans::XPropertySet> xInfoSet = getImportInfo();
+    if (!xInfoSet.is())
+        return;
+
+    uno::Reference<beans::XPropertySetInfo> xInfoSetInfo = xInfoSet->getPropertySetInfo();
+    if (!xInfoSetInfo.is())
+        return;
+
+    if (xInfoSetInfo->hasPropertyByName(SC_UNO_ODS_LOCK_SOLAR_MUTEX))
+        xInfoSet->getPropertyValue(SC_UNO_ODS_LOCK_SOLAR_MUTEX) >>= mbLockSolarMutex;
+
+    if (xInfoSetInfo->hasPropertyByName(SC_UNO_ODS_IMPORT_STYLES))
+        xInfoSet->getPropertyValue(SC_UNO_ODS_IMPORT_STYLES) >>= mbImportStyles;
+}
 
 SvXMLImportContext *ScXMLImport::CreateFontDeclsContext(const sal_uInt16 nPrefix, const OUString& rLocalName,
                                                         const uno::Reference<xml::sax::XAttributeList>& xAttrList)
@@ -2763,6 +2783,9 @@ void ScXMLImport::SetType(uno::Reference <beans::XPropertySet>& rProperties,
                           const sal_Int16 nCellType,
                           const OUString& rCurrency)
 {
+    if (!mbImportStyles)
+        return;
+
     if ((nCellType != util::NumberFormat::TEXT) && (nCellType != util::NumberFormat::UNDEFINED))
     {
         if (rNumberFormat == -1)
@@ -2830,6 +2853,9 @@ void ScXMLImport::SetType(uno::Reference <beans::XPropertySet>& rProperties,
 
 void ScXMLImport::AddStyleRange(const table::CellRangeAddress& rCellRange)
 {
+    if (!mbImportStyles)
+        return;
+
     if (!xSheetCellRanges.is() && GetModel().is())
     {
         uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
@@ -2843,6 +2869,9 @@ void ScXMLImport::AddStyleRange(const table::CellRangeAddress& rCellRange)
 
 void ScXMLImport::SetStyleToRanges()
 {
+    if (!mbImportStyles)
+        return;
+
     if (!sPrevStyleName.isEmpty())
     {
         uno::Reference <beans::XPropertySet> xProperties (xSheetCellRanges, uno::UNO_QUERY);
@@ -2899,6 +2928,9 @@ void ScXMLImport::SetStyleToRanges()
 void ScXMLImport::SetStyleToRange(const ScRange& rRange, const OUString* pStyleName,
                                   const sal_Int16 nCellType, const OUString* pCurrency)
 {
+    if (!mbImportStyles)
+        return;
+
     if (sPrevStyleName.isEmpty())
     {
         nPrevCellType = nCellType;
@@ -2980,8 +3012,6 @@ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::R
     mpComp.reset(new ScCompiler(pDoc, ScAddress()));
     mpComp->SetGrammar(formula::FormulaGrammar::GRAM_ODFF);
 
-    bFromWrapper = pDoc->IsXMLFromWrapper();    // UnlockSolarMutex below still works normally
-
     uno::Reference<document::XActionLockable> xActionLockable(xDoc, uno::UNO_QUERY);
     if (xActionLockable.is())
         xActionLockable->addActionLock();
@@ -3320,7 +3350,7 @@ void ScXMLImport::LockSolarMutex()
 {
     // #i62677# When called from DocShell/Wrapper, the SolarMutex is already locked,
     // so there's no need to allocate (and later delete) the SolarMutexGuard.
-    if (bFromWrapper)
+    if (!mbLockSolarMutex)
     {
         DBG_TESTSOLARMUTEX();
         return;
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index 584b3de..1d2e8ed 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -964,7 +964,8 @@ class ScXMLImport: public SvXMLImport, boost::noncopyable
     bool                    bRemoveLastChar;
     bool                    bNullDateSetted;
     bool                    bSelfImportingXMLSet;
-    bool                    bFromWrapper;           // called from ScDocShell / ScXMLImportWrapper?
+    bool mbLockSolarMutex;
+    bool mbImportStyles;
     bool mbHasNewCondFormatData;
 
 
@@ -986,6 +987,10 @@ public:
 
     ~ScXMLImport() throw();
 
+    // XInitialization
+    virtual void SAL_CALL initialize( const css::uno::Sequence<css::uno::Any>& aArguments )
+        throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
+
     // namespace office
     // NB: in contrast to other CreateFooContexts, this particular one handles
     //     the root element (i.e. office:document-meta)
diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx
index 5fdf581..2e3210f 100644
--- a/sc/source/filter/xml/xmlwrap.cxx
+++ b/sc/source/filter/xml/xmlwrap.cxx
@@ -70,16 +70,17 @@
 #include "docuno.hxx"
 #include "sheetdata.hxx"
 #include "XMLCodeNameProvider.hxx"
+#include <docsh.hxx>
+#include <unonames.hxx>
 
 #define MAP_LEN(x) x, sizeof(x) - 1
 
 using namespace com::sun::star;
 
 
-// -----------------------------------------------------------------------
-
-ScXMLImportWrapper::ScXMLImportWrapper(ScDocument& rD, SfxMedium* pM, const uno::Reference < embed::XStorage >& xStor ) :
-    rDoc(rD),
+ScXMLImportWrapper::ScXMLImportWrapper( ScDocShell& rDocSh, SfxMedium* pM, const uno::Reference < embed::XStorage >& xStor ) :
+    mrDocShell(rDocSh),
+    rDoc(*rDocSh.GetDocument()),
     pMedium(pM),
     xStorage(xStor)
 {
@@ -310,7 +311,7 @@ sal_uInt32 ScXMLImportWrapper::ImportFromComponent(const uno::Reference<uno::XCo
     return nReturn;
 }
 
-sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError)
+bool ScXMLImportWrapper::Import( sal_uInt8 nMode, ErrCode& rError )
 {
     uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
 
@@ -325,132 +326,129 @@ sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError)
     uno::Reference<xml::sax::XParser> xXMLParser = xml::sax::Parser::create(xContext);
 
     // get filter
-    SfxObjectShell* pObjSh = rDoc.GetDocumentShell();
-    if ( pObjSh )
+    OUString sEmpty;
+    uno::Reference<frame::XModel> xModel = mrDocShell.GetModel();
+
+    /** property map for export info set */
+    comphelper::PropertyMapEntry const aImportInfoMap[] =
     {
-        OUString sEmpty;
-        uno::Reference<frame::XModel> xModel(pObjSh->GetModel());
+        { OUString("ProgressRange"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+        { OUString("ProgressMax"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+        { OUString("ProgressCurrent"), 0, ::cppu::UnoType<sal_Int32>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+        { OUString("NumberStyles"), 0, cppu::UnoType<container::XNameAccess>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+        { OUString("PrivateData"), 0, cppu::UnoType<uno::XInterface>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+        { OUString("BaseURI"), 0, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+        { OUString("StreamRelPath"), 0, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+        { OUString("StreamName"), 0, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+        { OUString("BuildId"), 0, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+        { OUString("VBACompatibilityMode"), 0, ::getBooleanCppuType(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+        { OUString("ScriptConfiguration"), 0, cppu::UnoType<container::XNameAccess>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
+        { OUString("OrganizerMode"), 0, ::getBooleanCppuType(),
+            ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+        { OUString("SourceStorage"), 0, cppu::UnoType<embed::XStorage>::get(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
+        { OUString(SC_UNO_ODS_LOCK_SOLAR_MUTEX), 0, getBooleanCppuType(), css::beans::PropertyAttribute::MAYBEVOID, 0 },
+        { OUString(SC_UNO_ODS_IMPORT_STYLES), 0, getBooleanCppuType(), css::beans::PropertyAttribute::MAYBEVOID, 0 },
+        { OUString(), 0, css::uno::Type(), 0, 0 }
+    };
+    uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aImportInfoMap ) ) );
 
-        /** property map for export info set */
-        comphelper::PropertyMapEntry aImportInfoMap[] =
-        {
-            { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
-            { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
-            { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
-            { MAP_LEN( "NumberStyles" ), 0, &::getCppuType((uno::Reference<container::XNameAccess> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
-            { MAP_LEN( "PrivateData" ), 0, &::getCppuType( (uno::Reference<uno::XInterface> *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
-            { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
-            { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
-            { MAP_LEN( "StreamName" ), 0, &::getCppuType( (OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
-            { MAP_LEN( "BuildId" ), 0, &::getCppuType( (OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
-            { MAP_LEN( "VBACompatibilityMode" ), 0, &::getBooleanCppuType(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
-            { MAP_LEN( "ScriptConfiguration" ), 0, &::getCppuType((uno::Reference<container::XNameAccess> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
-            { MAP_LEN( "OrganizerMode" ), 0, &::getBooleanCppuType(),
-                ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
-            { MAP_LEN( "SourceStorage" ), 0, &embed::XStorage::static_type(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
-
-            { NULL, 0, 0, NULL, 0, 0 }
-        };
-        uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aImportInfoMap ) ) );
-
-        // ---- get BuildId from parent container if available
-
-        uno::Reference< container::XChild > xChild( xModel, uno::UNO_QUERY );
-        if( xChild.is() )
+    // No need to lock solar mutex when calling from the wrapper.
+    xInfoSet->setPropertyValue(SC_UNO_ODS_LOCK_SOLAR_MUTEX, uno::makeAny(false));
+
+    // ---- get BuildId from parent container if available
+
+    uno::Reference< container::XChild > xChild( xModel, uno::UNO_QUERY );
+    if( xChild.is() )
+    {
+        uno::Reference< beans::XPropertySet > xParentSet( xChild->getParent(), uno::UNO_QUERY );
+        if( xParentSet.is() )
         {
-            uno::Reference< beans::XPropertySet > xParentSet( xChild->getParent(), uno::UNO_QUERY );
-            if( xParentSet.is() )
+            uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xParentSet->getPropertySetInfo() );
+            OUString sPropName("BuildId" );
+            if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(sPropName) )
             {
-                uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xParentSet->getPropertySetInfo() );
-                OUString sPropName("BuildId" );
-                if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(sPropName) )
-                {
-                    xInfoSet->setPropertyValue( sPropName, xParentSet->getPropertyValue(sPropName) );
-                }
+                xInfoSet->setPropertyValue( sPropName, xParentSet->getPropertyValue(sPropName) );
             }
         }
+    }
 
-        // -------------------------------------
-
-        uno::Reference<task::XStatusIndicator> xStatusIndicator(GetStatusIndicator());
-        if (xStatusIndicator.is())
-        {
-            sal_Int32 nProgressRange(1000000);
-            xStatusIndicator->start(ScGlobal::GetRscString(STR_LOAD_DOC), nProgressRange);
-            xInfoSet->setPropertyValue("ProgressRange", uno::makeAny(nProgressRange));
-        }
+    uno::Reference<task::XStatusIndicator> xStatusIndicator = GetStatusIndicator();
+    if (xStatusIndicator.is())
+    {
+        sal_Int32 nProgressRange(1000000);
+        xStatusIndicator->start(ScGlobal::GetRscString(STR_LOAD_DOC), nProgressRange);
+        xInfoSet->setPropertyValue("ProgressRange", uno::makeAny(nProgressRange));
+    }
 
-        // Set base URI
-        OSL_ENSURE( pMedium, "There is no medium to get MediaDescriptor from!\n" );
-        OUString aBaseURL = pMedium ? pMedium->GetBaseURL() : OUString();
-        OUString sPropName("BaseURI");
-        xInfoSet->setPropertyValue( sPropName, uno::makeAny( aBaseURL ) );
+    // Set base URI
+    OSL_ENSURE( pMedium, "There is no medium to get MediaDescriptor from!\n" );
+    OUString aBaseURL = pMedium ? pMedium->GetBaseURL() : OUString();
+    OUString sPropName("BaseURI");
+    xInfoSet->setPropertyValue( sPropName, uno::makeAny( aBaseURL ) );
 
-        // TODO/LATER: do not do it for embedded links
-        OUString aName;
-        if( SFX_CREATE_MODE_EMBEDDED == pObjSh->GetCreateMode() )
+    // TODO/LATER: do not do it for embedded links
+    OUString aName;
+    if (SFX_CREATE_MODE_EMBEDDED == mrDocShell.GetCreateMode())
+    {
+        if ( pMedium && pMedium->GetItemSet() )
         {
-            if ( pMedium && pMedium->GetItemSet() )
-            {
-                const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
-                    pMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
-                if ( pDocHierarchItem )
-                    aName = pDocHierarchItem->GetValue();
-            }
-            else
-                aName = "dummyObjectName";
-
-            if( !aName.isEmpty() )
-            {
-                sPropName = "StreamRelPath";
-                xInfoSet->setPropertyValue( sPropName, uno::makeAny( aName ) );
-            }
+            const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
+                pMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
+            if ( pDocHierarchItem )
+                aName = pDocHierarchItem->GetValue();
         }
+        else
+            aName = "dummyObjectName";
 
-        if (bStylesOnly)
+        if( !aName.isEmpty() )
         {
-            OUString const sOrganizerMode(
-                "OrganizerMode");
-            xInfoSet->setPropertyValue(sOrganizerMode, uno::makeAny(sal_True));
+            sPropName = "StreamRelPath";
+            xInfoSet->setPropertyValue( sPropName, uno::makeAny( aName ) );
         }
+    }
 
-        xInfoSet->setPropertyValue( "SourceStorage", uno::Any( xStorage ) );
+    if (mrDocShell.GetCreateMode() == SFX_CREATE_MODE_ORGANIZER)
+        xInfoSet->setPropertyValue("OrganizerMode", uno::makeAny(true));
 
-        sal_Bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 );
+    xInfoSet->setPropertyValue( "SourceStorage", uno::Any( xStorage ) );
 
-        if (!bStylesOnly && bOasis)
+    bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 );
+
+    if ((nMode & METADATA) == METADATA && bOasis)
+    {
+        // RDF metadata: ODF >= 1.2
+        try
         {
-            // RDF metadata: ODF >= 1.2
-            try
-            {
-                const uno::Reference< rdf::XDocumentMetadataAccess > xDMA(
-                    xModel, uno::UNO_QUERY_THROW );
-                const uno::Reference< rdf::XURI > xBaseURI(
-                    ::sfx2::createBaseURI( xContext, xStorage, aBaseURL, aName ) );
-                const uno::Reference< task::XInteractionHandler > xHandler(
-                    pObjSh->GetMedium()->GetInteractionHandler() );
-                xDMA->loadMetadataFromStorage( xStorage, xBaseURI, xHandler );
-            }
-            catch ( const lang::WrappedTargetException & e)
+            const uno::Reference< rdf::XDocumentMetadataAccess > xDMA(
+                xModel, uno::UNO_QUERY_THROW );
+            const uno::Reference< rdf::XURI > xBaseURI(
+                ::sfx2::createBaseURI( xContext, xStorage, aBaseURL, aName ) );
+            uno::Reference<task::XInteractionHandler> xHandler =
+                mrDocShell.GetMedium()->GetInteractionHandler();
+            xDMA->loadMetadataFromStorage( xStorage, xBaseURI, xHandler );
+        }
+        catch ( const lang::WrappedTargetException & e)
+        {
+            ucb::InteractiveAugmentedIOException iaioe;
+            if ( e.TargetException >>= iaioe )
             {
-                ucb::InteractiveAugmentedIOException iaioe;
-                if ( e.TargetException >>= iaioe )
-                {
-                    nError = SCERR_IMPORT_UNKNOWN;
-                }
-                else
-                {
-                    nError = SCWARN_IMPORT_FEATURES_LOST;
-                }
+                rError = SCERR_IMPORT_UNKNOWN;
             }
-            catch ( const uno::Exception &)
+            else
             {
-                nError = SCWARN_IMPORT_FEATURES_LOST;
+                rError = SCWARN_IMPORT_FEATURES_LOST;
             }
         }
+        catch ( const uno::Exception &)
+        {
+            rError = SCWARN_IMPORT_FEATURES_LOST;
+        }
+    }
 
-        // #i103539#: always read meta.xml for generator
-        sal_uInt32 nMetaRetval(0);
+    // #i103539#: always read meta.xml for generator
+    sal_uInt32 nMetaRetval(0);
+    if ((nMode & METADATA) == METADATA)
+    {
         uno::Sequence<uno::Any> aMetaArgs(1);
         uno::Any* pMetaArgs = aMetaArgs.getArray();
         pMetaArgs[0] <<= xInfoSet;
@@ -464,167 +462,158 @@ sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError)
                                 "meta.xml", "Meta.xml", aMetaArgs, false);
 
         SAL_INFO( "sc.filter", "meta import end" );
+    }
 
-        SvXMLGraphicHelper* pGraphicHelper = NULL;
-        uno::Reference< document::XGraphicObjectResolver > xGrfContainer;
-
-        uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver;
-        SvXMLEmbeddedObjectHelper *pObjectHelper = NULL;
-
-        if( xStorage.is() )
-        {
-            pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_READ );
-            xGrfContainer = pGraphicHelper;
+    SvXMLGraphicHelper* pGraphicHelper = NULL;
+    uno::Reference< document::XGraphicObjectResolver > xGrfContainer;
 
-            if( pObjSh )
-            {
-                pObjectHelper = SvXMLEmbeddedObjectHelper::Create(xStorage, *pObjSh, EMBEDDEDOBJECTHELPER_MODE_READ, false );
-                xObjectResolver = pObjectHelper;
-            }
-        }
-        uno::Sequence<uno::Any> aStylesArgs(4);
-        uno::Any* pStylesArgs = aStylesArgs.getArray();
-        pStylesArgs[0] <<= xInfoSet;
-        pStylesArgs[1] <<= xGrfContainer;
-        pStylesArgs[2] <<= xStatusIndicator;
-        pStylesArgs[3] <<= xObjectResolver;
-
-        sal_uInt32 nSettingsRetval(0);
-        if (!bStylesOnly)
-        {
-            //  Settings must be loaded first because of the printer setting,
-            //  which is needed in the page styles (paper tray).
+    uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver;
+    SvXMLEmbeddedObjectHelper *pObjectHelper = NULL;
 
-            uno::Sequence<uno::Any> aSettingsArgs(1);
-            uno::Any* pSettingsArgs = aSettingsArgs.getArray();
-            pSettingsArgs[0] <<= xInfoSet;
+    if( xStorage.is() )
+    {
+        pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_READ );
+        xGrfContainer = pGraphicHelper;
 
-            SAL_INFO( "sc.filter", "settings import start" );
+        pObjectHelper = SvXMLEmbeddedObjectHelper::Create(xStorage, mrDocShell, EMBEDDEDOBJECTHELPER_MODE_READ, false);
+        xObjectResolver = pObjectHelper;
+    }
+    uno::Sequence<uno::Any> aStylesArgs(4);
+    uno::Any* pStylesArgs = aStylesArgs.getArray();
+    pStylesArgs[0] <<= xInfoSet;
+    pStylesArgs[1] <<= xGrfContainer;
+    pStylesArgs[2] <<= xStatusIndicator;
+    pStylesArgs[3] <<= xObjectResolver;
+
+    sal_uInt32 nSettingsRetval(0);
+    if ((nMode & SETTINGS) == SETTINGS)
+    {
+        //  Settings must be loaded first because of the printer setting,
+        //  which is needed in the page styles (paper tray).
 
-            nSettingsRetval = ImportFromComponent(
-                                xContext, xModel, xXMLParser, aParserInput,
-                                bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisSettingsImporter")
-                                       : OUString("com.sun.star.comp.Calc.XMLSettingsImporter"),
-                                "settings.xml", sEmpty, aSettingsArgs, false);
+        uno::Sequence<uno::Any> aSettingsArgs(1);
+        uno::Any* pSettingsArgs = aSettingsArgs.getArray();
+        pSettingsArgs[0] <<= xInfoSet;
 
-            SAL_INFO( "sc.filter", "settings import end" );
-        }
+        SAL_INFO( "sc.filter", "settings import start" );
 
-        sal_uInt32 nStylesRetval(0);
-        {
-            SAL_INFO( "sc.filter", "styles import start" );
+        nSettingsRetval = ImportFromComponent(
+                            xContext, xModel, xXMLParser, aParserInput,
+                            bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisSettingsImporter")
+                                   : OUString("com.sun.star.comp.Calc.XMLSettingsImporter"),
+                            "settings.xml", sEmpty, aSettingsArgs, false);
 
-            nStylesRetval = ImportFromComponent(xContext, xModel, xXMLParser, aParserInput,
-                bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisStylesImporter")
-                       : OUString("com.sun.star.comp.Calc.XMLStylesImporter"),
-                OUString("styles.xml"),
-                sEmpty, aStylesArgs, sal_True);
+        SAL_INFO( "sc.filter", "settings import end" );
+    }
 
-            SAL_INFO( "sc.filter", "styles import end" );
-        }
+    sal_uInt32 nStylesRetval(0);
+    if ((nMode & STYLES) == STYLES)
+    {
+        SAL_INFO( "sc.filter", "styles import start" );
 
-        sal_uInt32 nDocRetval(0);
-        if (!bStylesOnly)
-        {
-            uno::Sequence<uno::Any> aDocArgs(4);
-            uno::Any* pDocArgs = aDocArgs.getArray();
-            pDocArgs[0] <<= xInfoSet;
-            pDocArgs[1] <<= xGrfContainer;
-            pDocArgs[2] <<= xStatusIndicator;
-            pDocArgs[3] <<= xObjectResolver;
+        nStylesRetval = ImportFromComponent(xContext, xModel, xXMLParser, aParserInput,
+            bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisStylesImporter")
+                   : OUString("com.sun.star.comp.Calc.XMLStylesImporter"),
+            OUString("styles.xml"),
+            sEmpty, aStylesArgs, true);
 
-            SAL_INFO( "sc.filter", "content import start" );
+        SAL_INFO( "sc.filter", "styles import end" );
+    }
 
-            nDocRetval = ImportFromComponent(xContext, xModel, xXMLParser, aParserInput,
-                bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisContentImporter")
-                       : OUString("com.sun.star.comp.Calc.XMLContentImporter"),
-                OUString("content.xml"),
-                OUString("Content.xml"), aDocArgs,
-                sal_True);
+    sal_uInt32 nDocRetval(0);
+    if ((nMode & CONTENT) == CONTENT)
+    {
+        if (mrDocShell.GetCreateMode() == SFX_CREATE_MODE_INTERNAL)
+            // We only need to import content for external link cache document.
+            xInfoSet->setPropertyValue(SC_UNO_ODS_IMPORT_STYLES, uno::makeAny(false));
+
+        uno::Sequence<uno::Any> aDocArgs(4);
+        uno::Any* pDocArgs = aDocArgs.getArray();
+        pDocArgs[0] <<= xInfoSet;
+        pDocArgs[1] <<= xGrfContainer;
+        pDocArgs[2] <<= xStatusIndicator;
+        pDocArgs[3] <<= xObjectResolver;
+
+        SAL_INFO( "sc.filter", "content import start" );
+
+        nDocRetval = ImportFromComponent(xContext, xModel, xXMLParser, aParserInput,
+            bOasis ? OUString("com.sun.star.comp.Calc.XMLOasisContentImporter")
+                   : OUString("com.sun.star.comp.Calc.XMLContentImporter"),
+            OUString("content.xml"),
+            OUString("Content.xml"), aDocArgs,
+            true);
+
+        SAL_INFO( "sc.filter", "content import end" );
+    }
+    if( pGraphicHelper )
+        SvXMLGraphicHelper::Destroy( pGraphicHelper );
 
-            SAL_INFO( "sc.filter", "content import end" );
-        }
-        if( pGraphicHelper )
-            SvXMLGraphicHelper::Destroy( pGraphicHelper );
+    if( pObjectHelper )
+        SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
 
-        if( pObjectHelper )
-            SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper );
+    if (xStatusIndicator.is())
+        xStatusIndicator->end();
 
-        if (xStatusIndicator.is())
-            xStatusIndicator->end();
+    bool bRet = false;
+    if (nDocRetval)
+    {
+        rError = nDocRetval;
+        if (nDocRetval == SCWARN_IMPORT_RANGE_OVERFLOW ||
+            nDocRetval == SCWARN_IMPORT_ROW_OVERFLOW ||
+            nDocRetval == SCWARN_IMPORT_COLUMN_OVERFLOW ||
+            nDocRetval == SCWARN_IMPORT_SHEET_OVERFLOW)
+            bRet = true;
+    }
+    else if (nStylesRetval)
+        rError = nStylesRetval;
+    else if (nMetaRetval)
+        rError = nMetaRetval;
+    else if (nSettingsRetval)
+        rError = nSettingsRetval;
+    else
+        bRet = true;
 
-        sal_Bool bRet(false);
-        if (bStylesOnly)
-        {
-            if (nStylesRetval)
-                nError = nStylesRetval;
-            else
-                bRet = sal_True;
-        }
-        else
+    // set BuildId on XModel for later OLE object loading
+    if( xInfoSet.is() )
+    {
+        uno::Reference< beans::XPropertySet > xModelSet( xModel, uno::UNO_QUERY );
+        if( xModelSet.is() )
         {
-            if (nDocRetval)
+            uno::Reference< beans::XPropertySetInfo > xModelSetInfo( xModelSet->getPropertySetInfo() );
+            OUString sBuildPropName("BuildId" );
+            if( xModelSetInfo.is() && xModelSetInfo->hasPropertyByName(sBuildPropName) )
             {
-                nError = nDocRetval;
-                if (nDocRetval == SCWARN_IMPORT_RANGE_OVERFLOW ||
-                    nDocRetval == SCWARN_IMPORT_ROW_OVERFLOW ||
-                    nDocRetval == SCWARN_IMPORT_COLUMN_OVERFLOW ||
-                    nDocRetval == SCWARN_IMPORT_SHEET_OVERFLOW)
-                    bRet = sal_True;
+                xModelSet->setPropertyValue( sBuildPropName, xInfoSet->getPropertyValue(sBuildPropName) );
             }
-            else if (nStylesRetval)
-                nError = nStylesRetval;
-            else if (nMetaRetval)
-                nError = nMetaRetval;
-            else if (nSettingsRetval)
-                nError = nSettingsRetval;
-            else
-                bRet = sal_True;
         }
 
-        // set BuildId on XModel for later OLE object loading
-        if( xInfoSet.is() )
+        // Set Code Names
+        uno::Any aAny = xInfoSet->getPropertyValue("ScriptConfiguration");
+        uno::Reference <container::XNameAccess> xCodeNameAccess;
+        if( aAny >>= xCodeNameAccess )
+            XMLCodeNameProvider::set( xCodeNameAccess, &rDoc );
+
+        // VBA compatibility
+        bool bVBACompat = false;
+        if ( (xInfoSet->getPropertyValue("VBACompatibilityMode") >>= bVBACompat) && bVBACompat )
         {
-            uno::Reference< beans::XPropertySet > xModelSet( xModel, uno::UNO_QUERY );
-            if( xModelSet.is() )
+            /*  Set library container to VBA compatibility mode, this
+                forces loading the Basic project, which in turn creates the
+                VBA Globals object and does all related initialization. */
+            if ( xModelSet.is() ) try
             {
-                uno::Reference< beans::XPropertySetInfo > xModelSetInfo( xModelSet->getPropertySetInfo() );
-                OUString sBuildPropName("BuildId" );
-                if( xModelSetInfo.is() && xModelSetInfo->hasPropertyByName(sBuildPropName) )
-                {
-                    xModelSet->setPropertyValue( sBuildPropName, xInfoSet->getPropertyValue(sBuildPropName) );
-                }
+                uno::Reference< script::vba::XVBACompatibility > xVBACompat( xModelSet->getPropertyValue(
+                    OUString( "BasicLibraries" ) ), uno::UNO_QUERY_THROW );
+                xVBACompat->setVBACompatibilityMode( sal_True );
             }
-
-            // Set Code Names
-            uno::Any aAny = xInfoSet->getPropertyValue("ScriptConfiguration");
-            uno::Reference <container::XNameAccess> xCodeNameAccess;
-            if( aAny >>= xCodeNameAccess )
-                XMLCodeNameProvider::set( xCodeNameAccess, &rDoc );
-
-            // VBA compatibility
-            bool bVBACompat = false;
-            if ( (xInfoSet->getPropertyValue("VBACompatibilityMode") >>= bVBACompat) && bVBACompat )
+            catch( const uno::Exception& )
             {
-                /*  Set library container to VBA compatibility mode, this
-                    forces loading the Basic project, which in turn creates the
-                    VBA Globals object and does all related initialization. */
-                if ( xModelSet.is() ) try
-                {
-                    uno::Reference< script::vba::XVBACompatibility > xVBACompat( xModelSet->getPropertyValue(
-                        OUString( "BasicLibraries" ) ), uno::UNO_QUERY_THROW );
-                    xVBACompat->setVBACompatibilityMode( sal_True );
-                }
-                catch( const uno::Exception& )
-                {
-                }
             }
         }
-
-        // Don't test bStylesRetval and bMetaRetval, because it could be an older file which not contain such streams
-        return bRet;//!bStylesOnly ? bDocRetval : bStylesRetval;
     }
-    return false;
+
+    // Don't test bStylesRetval and bMetaRetval, because it could be an older file which not contain such streams
+    return bRet;//!bStylesOnly ? bDocRetval : bStylesRetval;
 }
 
 static bool lcl_HasValidStream(ScDocument& rDoc)
@@ -760,7 +749,7 @@ sal_Bool ScXMLImportWrapper::ExportToComponent(const uno::Reference<uno::XCompon
     return bRet;
 }
 
-sal_Bool ScXMLImportWrapper::Export(sal_Bool bStylesOnly)
+bool ScXMLImportWrapper::Export(bool bStylesOnly)
 {
     rDoc.CreateAllNoteCaptions();
 
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index bfc94db..93d5665 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -445,20 +445,15 @@ sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::un
 
     BeforeXMLLoading();
 
-    // #i62677# BeforeXMLLoading is also called from ScXMLImport::startDocument when invoked
-    // from an external component. The XMLFromWrapper flag is only set here, when called
-    // through ScDocShell.
-    aDocument.SetXMLFromWrapper( sal_True );
+    ScXMLImportWrapper aImport(*this, pLoadMedium, xStor);
 
-    ScXMLImportWrapper aImport( aDocument, pLoadMedium, xStor );
-
-    sal_Bool bRet(false);
+    bool bRet = false;
     ErrCode nError = ERRCODE_NONE;
     aDocument.EnableAdjustHeight(false);
-    if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
-        bRet = aImport.Import(false, nError);
+    if (GetCreateMode() == SFX_CREATE_MODE_ORGANIZER)
+        bRet = aImport.Import(ScXMLImportWrapper::STYLES, nError);
     else
-        bRet = aImport.Import(sal_True, nError);
+        bRet = aImport.Import(ScXMLImportWrapper::ALL, nError);
 
     if ( nError )
         pLoadMedium->SetError( nError, OUString( OSL_LOG_PREFIX ) );
@@ -514,7 +509,6 @@ sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::un
         aDocument.Broadcast(ScHint(SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS));
     }
 
-    aDocument.SetXMLFromWrapper( false );
     AfterXMLLoading(bRet);
 
     aDocument.EnableAdjustHeight(true);
@@ -525,8 +519,8 @@ sal_Bool ScDocShell::SaveXML( SfxMedium* pSaveMedium, const ::com::sun::star::un
 {
     aDocument.EnableIdle(false);
 
-    ScXMLImportWrapper aImport( aDocument, pSaveMedium, xStor );
-    sal_Bool bRet(false);
+    ScXMLImportWrapper aImport(*this, pSaveMedium, xStor);
+    bool bRet(false);
     if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
         bRet = aImport.Export(false);
     else
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 3c051ac..7e9f6bd 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -53,6 +53,8 @@
 #include "vcl/msgbox.hxx"
 #include "stringutil.hxx"
 #include "scmatrix.hxx"
+#include <columnspanset.hxx>
+#include <column.hxx>
 
 #include <memory>
 #include <algorithm>
@@ -71,8 +73,8 @@ using ::std::list;
 using ::std::unary_function;
 using namespace formula;
 
-#define SRCDOC_LIFE_SPAN     6000       // 1 minute (in 100th of a sec)
-#define SRCDOC_SCAN_INTERVAL 1000*5     // every 5 seconds (in msec)
+#define SRCDOC_LIFE_SPAN     30000      // 5 minutes (in 100th of a sec)
+#define SRCDOC_SCAN_INTERVAL 1000*30    // every 30 seconds (in msec)
 
 namespace {
 
@@ -136,17 +138,18 @@ struct UpdateFormulaCell : public unary_function<ScFormulaCell*, void>
         // Check to make sure the cell really contains ocExternalRef.
         // External names, external cell and range references all have a
         // ocExternalRef token.
-        const ScTokenArray* pCode = pCell->GetCode();
+        ScTokenArray* pCode = pCell->GetCode();
         if (!pCode->HasExternalRef())
             return;
 
-        ScTokenArray* pArray = pCell->GetCode();
-        if (pArray)
+        if (pCode->GetCodeError())
+        {
             // Clear the error code, or a cell with error won't get re-compiled.
-            pArray->SetCodeError(0);
+            pCode->SetCodeError(0);
+            pCell->SetCompile(true);
+            pCell->CompileTokenArray();
+        }
 
-        pCell->SetCompile(true);
-        pCell->CompileTokenArray();
         pCell->SetDirty();
     }
 };
@@ -255,6 +258,13 @@ ScExternalRefCache::Table::~Table()
 {
 }
 
+void ScExternalRefCache::Table::clear()
+{
+    maRows.clear();
+    maCachedRanges.RemoveAll();
+    meReferenced = REFERENCED_MARKED;
+}
+
 void ScExternalRefCache::Table::setReferencedFlag( ScExternalRefCache::Table::ReferencedFlag eFlag )
 {
     meReferenced = eFlag;
@@ -446,9 +456,6 @@ void ScExternalRefCache::Table::setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCC
         maCachedRanges.Append(aRange);
     else
         maCachedRanges.Join(aRange);
-
-    OUString aStr;
-    maCachedRanges.Format(aStr, SCA_VALID);
 }
 
 void ScExternalRefCache::Table::setWholeTableCached()
@@ -1113,6 +1120,35 @@ bool ScExternalRefCache::areAllCacheTablesReferenced() const
     return maReferenced.mbAllReferenced;
 }
 
+void ScExternalRefCache::getAllCachedDataSpans( sal_uInt16 nFileId, sc::ColumnSpanSet& rSet ) const
+{
+    const DocItem* pDocItem = getDocItem(nFileId);
+    if (!pDocItem)
+        // This document is not cached.
+        return;
+
+    const std::vector<TableTypeRef>& rTables = pDocItem->maTables;
+    for (size_t nTab = 0, nTabCount = rTables.size(); nTab < nTabCount; ++nTab)
+    {
+        const Table& rTable = *rTables[nTab];
+        std::vector<SCROW> aRows;
+        rTable.getAllRows(aRows);
+        std::vector<SCROW>::const_iterator itRow = aRows.begin(), itRowEnd = aRows.end();
+        for (; itRow != itRowEnd; ++itRow)
+        {
+            SCROW nRow = *itRow;
+            std::vector<SCCOL> aCols;
+            rTable.getAllCols(nRow, aCols);
+            std::vector<SCCOL>::const_iterator itCol = aCols.begin(), itColEnd = aCols.end();
+            for (; itCol != itColEnd; ++itCol)
+            {
+                SCCOL nCol = *itCol;
+                rSet.set(nTab, nCol, nRow, true);
+            }
+        }
+    }
+}
+
 ScExternalRefCache::ReferencedStatus::ReferencedStatus() :
     mbAllReferenced(false)
 {
@@ -1206,6 +1242,28 @@ void ScExternalRefCache::clearCache(sal_uInt16 nFileId)
     maDocs.erase(nFileId);
 }
 
+void ScExternalRefCache::clearCacheTables(sal_uInt16 nFileId)
+{
+    osl::MutexGuard aGuard(&maMtxDocs);
+    DocItem* pDocItem = getDocItem(nFileId);
+    if (!pDocItem)
+        // This document is not cached at all.
+        return;
+
+    // Clear all cache table content, but keep the tables.
+    std::vector<TableTypeRef>& rTabs = pDocItem->maTables;
+    for (size_t i = 0, n = rTabs.size(); i < n; ++i)
+    {
+        Table& rTab = *rTabs[i];
+        rTab.clear();
+    }
+
+    // Clear the external range name caches.
+    pDocItem->maRangeNames.clear();
+    pDocItem->maRangeArrays.clear();
+    pDocItem->maRealRangeNameMap.clear();
+}
+
 ScExternalRefCache::DocItem* ScExternalRefCache::getDocItem(sal_uInt16 nFileId) const
 {
     osl::MutexGuard aGuard(&maMtxDocs);
@@ -1268,7 +1326,8 @@ void ScExternalRefLink::Closed()
     if (pCurFile->equals(aFile))
     {
         // Refresh the current source document.
-        pMgr->refreshNames(mnFileId);
+        if (!pMgr->refreshSrcDocument(mnFileId))
+            return ERROR_GENERAL;
     }
     else
     {
@@ -1547,7 +1606,8 @@ static ScTokenArray* lcl_fillEmptyMatrix(const ScRange& rRange)
 ScExternalRefManager::ScExternalRefManager(ScDocument* pDoc) :
     mpDoc(pDoc),
     mbInReferenceMarking(false),
-    mbUserInteractionEnabled(true)
+    mbUserInteractionEnabled(true),
+    mbDocTimerEnabled(true)
 {
     maSrcDocTimer.SetTimeoutHdl( LINK(this, ScExternalRefManager, TimeOutHdl) );
     maSrcDocTimer.SetTimeout(SRCDOC_SCAN_INTERVAL);
@@ -2025,6 +2085,27 @@ void ScExternalRefManager::insertRefCell(sal_uInt16 nFileId, const ScAddress& rC
         itr->second.insert(pCell);
 }
 
+void ScExternalRefManager::enableDocTimer( bool bEnable )
+{
+    if (mbDocTimerEnabled == bEnable)
+        return;
+
+    mbDocTimerEnabled = bEnable;
+    if (mbDocTimerEnabled)
+    {
+        if (!maDocShells.empty())
+        {
+            DocShellMap::iterator it = maDocShells.begin(), itEnd = maDocShells.end();
+            for (; it != itEnd; ++it)
+                it->second.maLastAccess = Time(Time::SYSTEM);
+
+            maSrcDocTimer.Start();
+        }
+    }
+    else
+        maSrcDocTimer.Stop();
+}
+
 void ScExternalRefManager::fillCellFormat(sal_uLong nFmtIndex, ScExternalRefCache::CellFormat* pFmt) const
 {
     if (!pFmt)
@@ -2246,17 +2327,7 @@ ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId)
         return NULL;
     }
 
-    if (maDocShells.empty())
-    {
-        // If this is the first source document insertion, start up the timer.
-        maSrcDocTimer.Start();
-    }
-
-    maDocShells.insert(DocShellMap::value_type(nFileId, aSrcDoc));
-    SfxObjectShell* p = aSrcDoc.maShell;
-    ScDocument* pSrcDoc = static_cast<ScDocShell*>(p)->GetDocument();
-    initDocInCache(maRefCache, pSrcDoc, nFileId);
-    return pSrcDoc;
+    return cacheNewDocShell(nFileId, aSrcDoc);
 }
 
 SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUString& rFilter)
@@ -2313,7 +2384,7 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUSt
     // To load encrypted documents with password, user interaction needs to be enabled.
     pMedium->UseInteractionHandler(mbUserInteractionEnabled);
 
-    ScDocShell* pNewShell = new ScDocShell(SFX_CREATE_MODE_INTERNAL);
+    ScDocShell* pNewShell = new ScDocShell(SFXMODEL_EXTERNAL_LINK);
     SfxObjectShellRef aRef = pNewShell;
 
     // increment the recursive link count of the source document.
@@ -2333,7 +2404,12 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUSt
     }
     pExtOptNew->GetDocSettings().mnLinkCnt = nLinkCount + 1;
 
-    pNewShell->DoLoad(pMedium.release());
+    if (!pNewShell->DoLoad(pMedium.release()))
+    {
+        aRef->DoClose();
+        aRef.Clear();
+        return aRef;
+    }
 
     // with UseInteractionHandler, options may be set by dialog during DoLoad
     OUString aNew = ScDocumentLoader::GetOptions(*pNewShell->GetMedium());
@@ -2344,6 +2420,19 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUSt
     return aRef;
 }
 
+ScDocument* ScExternalRefManager::cacheNewDocShell( sal_uInt16 nFileId, SrcShell& rSrcShell )
+{
+    if (mbDocTimerEnabled && maDocShells.empty())
+        // If this is the first source document insertion, start up the timer.
+        maSrcDocTimer.Start();
+
+    maDocShells.insert(DocShellMap::value_type(nFileId, rSrcShell));
+    SfxObjectShell& rShell = *rSrcShell.maShell;
+    ScDocument* pSrcDoc = static_cast<ScDocShell&>(rShell).GetDocument();
+    initDocInCache(maRefCache, pSrcDoc, nFileId);
+    return pSrcDoc;
+}
+
 bool ScExternalRefManager::isFileLoadable(const OUString& rFile) const
 {
     if (rFile.isEmpty())
@@ -2555,18 +2644,142 @@ void ScExternalRefManager::clearCache(sal_uInt16 nFileId)
     maRefCache.clearCache(nFileId);
 }
 
-void ScExternalRefManager::refreshNames(sal_uInt16 nFileId)
+namespace {
+
+class RefCacheFiller : public sc::ColumnSpanSet::ColumnAction
 {
-    clearCache(nFileId);
-    lcl_removeByFileId(nFileId, maDocShells);
+    svl::SharedStringPool& mrStrPool;
 
-    if (maDocShells.empty())
-        maSrcDocTimer.Stop();
+    ScExternalRefCache& mrRefCache;
+    ScExternalRefCache::TableTypeRef mpRefTab;
+    sal_uInt16 mnFileId;
+    ScColumn* mpCurCol;
+    sc::ColumnBlockConstPosition maBlockPos;
+
+public:
+    RefCacheFiller( svl::SharedStringPool& rStrPool, ScExternalRefCache& rRefCache, sal_uInt16 nFileId ) :
+        mrStrPool(rStrPool), mrRefCache(rRefCache), mnFileId(nFileId), mpCurCol(NULL) {}
+
+    virtual void startColumn( ScColumn* pCol )
+    {
+        mpCurCol = pCol;
+        if (!mpCurCol)
+            return;
+
+        mpCurCol->InitBlockPosition(maBlockPos);
+        mpRefTab = mrRefCache.getCacheTable(mnFileId, mpCurCol->GetTab());
+    }
+
+    virtual void execute( SCROW nRow1, SCROW nRow2, bool bVal )
+    {
+        if (!mpCurCol || !bVal)
+            return;
+
+        if (!mpRefTab)
+            return;
+
+        for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+        {
+            ScExternalRefCache::TokenRef pTok;
+            ScRefCellValue aCell = mpCurCol->GetCellValue(maBlockPos, nRow);
+            switch (aCell.meType)
+            {
+                case CELLTYPE_STRING:
+                case CELLTYPE_EDIT:
+                {
+                    OUString aStr = aCell.getString(&mpCurCol->GetDoc());
+                    svl::SharedString aSS = mrStrPool.intern(aStr);
+                    pTok.reset(new formula::FormulaStringToken(aSS));
+                }
+                break;
+                case CELLTYPE_VALUE:
+                    pTok.reset(new formula::FormulaDoubleToken(aCell.mfValue));
+                break;
+                case CELLTYPE_FORMULA:
+                {
+                    sc::FormulaResultValue aRes = aCell.mpFormula->GetResult();
+                    switch (aRes.meType)
+                    {
+                        case sc::FormulaResultValue::Value:
+                            pTok.reset(new formula::FormulaDoubleToken(aRes.mfValue));
+                        break;
+                        case sc::FormulaResultValue::String:
+                        {
+                            // Re-intern the string to the host document pool.
+                            svl::SharedString aInterned = mrStrPool.intern(aRes.maString.getString());
+                            pTok.reset(new formula::FormulaStringToken(aInterned));
+                        }
+                        break;
+                        case sc::FormulaResultValue::Error:
+                        case sc::FormulaResultValue::Invalid:
+                        default:
+                            pTok.reset(new FormulaErrorToken(errNoValue));
+                    }
+                }
+                break;
+                default:
+                    pTok.reset(new FormulaErrorToken(errNoValue));
+            }
+
+            if (pTok)
+            {
+                // Cache this cell.
+                mpRefTab->setCell(mpCurCol->GetCol(), nRow, pTok, mpCurCol->GetNumberFormat(nRow));
+                mpRefTab->setCachedCell(mpCurCol->GetCol(), nRow);
+            }
+        }
+    };
+};
+
+}
+
+bool ScExternalRefManager::refreshSrcDocument(sal_uInt16 nFileId)
+{
+    sc::ColumnSpanSet aCachedArea(false);
+    maRefCache.getAllCachedDataSpans(nFileId, aCachedArea);
+
+    OUString aFilter;
+    SfxObjectShellRef xDocShell;
+    try
+    {
+        xDocShell = loadSrcDocument(nFileId, aFilter);
+    }
+    catch ( const css::uno::Exception& ) {}
+
+    if (!xDocShell.Is())
+        // Failed to load the document.  Bail out.
+        return false;
+
+    ScDocShell& rDocSh = static_cast<ScDocShell&>(*xDocShell);
+    ScDocument* pSrcDoc = rDocSh.GetDocument();
+
+    // Clear the existing cache, and refill it.  Make sure we keep the
+    // existing cache table instances here.
+    maRefCache.clearCacheTables(nFileId);
+    RefCacheFiller aAction(mpDoc->GetSharedStringPool(), maRefCache, nFileId);
+    aCachedArea.executeColumnAction(*pSrcDoc, aAction);
+
+    DocShellMap::iterator it = maDocShells.find(nFileId);
+    if (it != maDocShells.end())
+    {
+        it->second.maShell->DoClose();
+        it->second.maShell = xDocShell;
+        it->second.maLastAccess = Time(Time::SYSTEM);
+    }
+    else
+    {
+        SrcShell aSrcDoc;
+        aSrcDoc.maShell = xDocShell;
+        aSrcDoc.maLastAccess = Time(Time::SYSTEM);
+        cacheNewDocShell(nFileId, aSrcDoc);
+    }
 
     // Update all cells containing names from this source document.
     refreshAllRefCells(nFileId);
 
     notifyAllLinkListeners(nFileId, LINK_MODIFIED);
+
+    return true;
 }
 
 void ScExternalRefManager::breakLink(sal_uInt16 nFileId)
@@ -2622,7 +2835,7 @@ void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const OUString& rNe
         maSrcFiles[nFileId].maFilterName = rNewFilter;
         maSrcFiles[nFileId].maFilterOptions = OUString();
     }
-    refreshNames(nFileId);
+    refreshSrcDocument(nFileId);
 }
 
 void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const OUString& rRelUrl)
@@ -2746,19 +2959,20 @@ void ScExternalRefManager::notifyAllLinkListeners(sal_uInt16 nFileId, LinkUpdate
 
 void ScExternalRefManager::purgeStaleSrcDocument(sal_Int32 nTimeOut)
 {
-    DocShellMap aNewDocShells;
+    // To avoid potentially freezing Calc, we close one stale document at a time.
     DocShellMap::iterator itr = maDocShells.begin(), itrEnd = maDocShells.end();
     for (; itr != itrEnd; ++itr)
     {
         // in 100th of a second.
         sal_Int32 nSinceLastAccess = (Time( Time::SYSTEM ) - itr->second.maLastAccess).GetTime();
-        if (nSinceLastAccess < nTimeOut)
-            aNewDocShells.insert(*itr);
-        else
-            // Timed out.  Let's close this.
+        if (nSinceLastAccess >= nTimeOut)
+        {
+            // Timed out.  Let's close this, and exit the loop.
             itr->second.maShell->DoClose();
+            maDocShells.erase(itr);
+            break;
+        }
     }
-    maDocShells.swap(aNewDocShells);
 
     if (maDocShells.empty())
         maSrcDocTimer.Stop();
diff --git a/sc/source/ui/src/scstring.src b/sc/source/ui/src/scstring.src
index 6a6061c..ade96a6 100644
--- a/sc/source/ui/src/scstring.src
+++ b/sc/source/ui/src/scstring.src
@@ -814,6 +814,11 @@ String SCSTR_EXTDOC_NOT_LOADED
     Text [ en-US ] = "The following external file could not be loaded. Data linked from this file did not get updated." ;
 };
 
+String SCSTR_UPDATE_EXTDOCS
+{
+    Text [ en-US ] = "Updating external links.";
+};
+
 String SCSTR_FORMULA_SYNTAX_CALC_A1
 {
     Text [ en-US ] = "Calc A1";
diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx
index befa7ae..54b67be 100644
--- a/sfx2/source/doc/objxtor.cxx
+++ b/sfx2/source/doc/objxtor.cxx
@@ -291,11 +291,14 @@ SfxObjectShell::SfxObjectShell( const sal_uInt64 i_nCreationFlags )
     :   pImp( new SfxObjectShell_Impl( *this ) )
     ,   pMedium(0)
     ,   pStyleSheetPool(0)
-    ,   eCreateMode( ( i_nCreationFlags & SFXMODEL_EMBEDDED_OBJECT ) ? SFX_CREATE_MODE_EMBEDDED : SFX_CREATE_MODE_STANDARD )
-    ,   bHasName( sal_False )
-    ,   bIsInGenerateThumbnail ( sal_False )
+    ,   eCreateMode(SFX_CREATE_MODE_STANDARD)
+    ,   bHasName( false )
+    ,   bIsInGenerateThumbnail ( false )
 {
-    DBG_CTOR(SfxObjectShell, 0);
+    if (i_nCreationFlags & SFXMODEL_EMBEDDED_OBJECT)
+        eCreateMode = SFX_CREATE_MODE_EMBEDDED;
+    else if (i_nCreationFlags & SFXMODEL_EXTERNAL_LINK)
+        eCreateMode = SFX_CREATE_MODE_INTERNAL;
 
     const bool bScriptSupport = ( i_nCreationFlags & SFXMODEL_DISABLE_EMBEDDED_SCRIPTS ) == 0;
     if ( !bScriptSupport )


More information about the Libreoffice-commits mailing list