[Libreoffice-commits] core.git: sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed Jan 8 13:29:45 PST 2014


 sc/inc/document.hxx                       |    4 
 sc/inc/documentlinkmgr.hxx                |   21 +
 sc/source/core/data/documen2.cxx          |   37 --
 sc/source/core/data/documen8.cxx          |  387 ++++++++++++++++--------------
 sc/source/core/data/documen9.cxx          |    7 
 sc/source/ui/docshell/documentlinkmgr.cxx |   36 ++
 sc/source/ui/inc/areasave.hxx             |    5 
 sc/source/ui/undo/areasave.cxx            |   16 -
 8 files changed, 293 insertions(+), 220 deletions(-)

New commits:
commit 8fde2885236d5490be8f54e96dfe4a63d9bb9dec
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Jan 8 16:29:35 2014 -0500

    Move the LinkManager instance from ScDocument to ScDocumentLinkManager.
    
    Change-Id: I096322fa200abed5bacc786c1abc57a3ec51276f

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 0b7fe1d..b3d2a92 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -280,7 +280,6 @@ private:
     ScChartCollection*  pChartCollection;
     std::auto_ptr< ScTemporaryChartLock > apTemporaryChartLock;
     ScPatternAttr*      pSelectionAttr;                 // Attributes of a block
-    mutable sfx2::LinkManager*      pLinkManager;
     ScFormulaCell*      pFormulaTree;                   // formula tree (start)
     ScFormulaCell*      pEOFormulaTree;                 // formula tree (end), last cell
     ScFormulaCell*      pFormulaTrack;                  // BroadcastTrack (start)
@@ -469,7 +468,8 @@ public:
     SC_DLLPUBLIC void  InitDrawLayer( SfxObjectShell* pDocShell = NULL );
     rtl::Reference<XColorList>          GetColorList();
 
-    SC_DLLPUBLIC sfx2::LinkManager*     GetLinkManager() const;
+    SC_DLLPUBLIC sfx2::LinkManager* GetLinkManager();
+    SC_DLLPUBLIC const sfx2::LinkManager* GetLinkManager() const;
 
     sc::DocumentLinkManager& GetDocLinkManager();
     const sc::DocumentLinkManager& GetDocLinkManager() const;
diff --git a/sc/inc/documentlinkmgr.hxx b/sc/inc/documentlinkmgr.hxx
index ead5698..2206dfb 100644
--- a/sc/inc/documentlinkmgr.hxx
+++ b/sc/inc/documentlinkmgr.hxx
@@ -12,6 +12,15 @@
 
 #include <boost/noncopyable.hpp>
 
+class ScDocument;
+class SfxObjectShell;
+
+namespace sfx2 {
+
+class LinkManager;
+
+}
+
 namespace sc {
 
 class DataStream;
@@ -22,11 +31,21 @@ class DocumentLinkManager : boost::noncopyable
     DocumentLinkManagerImpl* mpImpl;
 
 public:
-    DocumentLinkManager();
+    DocumentLinkManager( ScDocument& rDoc, SfxObjectShell* pShell );
 
     void setDataStream( DataStream* p );
     DataStream* getDataStream();
     const DataStream* getDataStream() const;
+
+    /**
+     * @param bCreate if true, create a new link manager instance in case one
+     *                does not exist.
+     *
+     * @return link manager instance.
+     */
+    sfx2::LinkManager* getLinkManager( bool bCreate = true );
+
+    const sfx2::LinkManager* getExistingLinkManager() const;
 };
 
 }
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 8803d25..eeb04b1 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -139,7 +139,6 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
         pFormatExchangeList( NULL ),
         pRangeName(NULL),
         pDPCollection( NULL ),
-        pLinkManager( NULL ),
         pFormulaTree( NULL ),
         pEOFormulaTree( NULL ),
         pFormulaTrack( NULL ),
@@ -228,9 +227,6 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
 
     if ( eMode == SCDOCMODE_DOCUMENT )
     {
-        if ( pDocShell )
-            pLinkManager = new sfx2::LinkManager( pDocShell );
-
         xPoolHelper = new ScPoolHelper( this );
 
         pBASM = new ScBroadcastAreaSlotMachine( this );
@@ -257,27 +253,26 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
     aTrackTimer.SetTimeout( 100 );
 }
 
-sfx2::LinkManager*  ScDocument::GetLinkManager()  const
+sfx2::LinkManager* ScDocument::GetLinkManager()
 {
-    if ( bAutoCalc && !pLinkManager && pShell)
-    {
-        pLinkManager = new sfx2::LinkManager( pShell );
-    }
-    return pLinkManager;
+    return GetDocLinkManager().getLinkManager(bAutoCalc);
+}
+
+const sfx2::LinkManager* ScDocument::GetLinkManager() const
+{
+    return GetDocLinkManager().getExistingLinkManager();
 }
 
 sc::DocumentLinkManager& ScDocument::GetDocLinkManager()
 {
     if (!mpDocLinkMgr)
-        mpDocLinkMgr.reset(new sc::DocumentLinkManager);
+        mpDocLinkMgr.reset(new sc::DocumentLinkManager(*this, pShell));
     return *mpDocLinkMgr;
 }
 
 const sc::DocumentLinkManager& ScDocument::GetDocLinkManager() const
 {
-    if (!mpDocLinkMgr)
-        mpDocLinkMgr.reset(new sc::DocumentLinkManager);
-    return *mpDocLinkMgr;
+    return const_cast<ScDocument*>(this)->GetDocLinkManager();
 }
 
 void ScDocument::SetStorageGrammar( formula::FormulaGrammar::Grammar eGram )
@@ -386,19 +381,6 @@ ScDocument::~ScDocument()
         delete pRefreshTimerControl, pRefreshTimerControl = NULL;
     }
 
-    // Links aufrauemen
-
-    if ( GetLinkManager() )
-    {
-        // BaseLinks freigeben
-        ::sfx2::SvLinkSources aTemp(pLinkManager->GetServers());
-        for( ::sfx2::SvLinkSources::const_iterator it = aTemp.begin(); it != aTemp.end(); ++it )
-            (*it)->Closed();
-
-        if ( pLinkManager->GetLinks().size() )
-            pLinkManager->Remove( 0, pLinkManager->GetLinks().size() );
-    }
-
     mxFormulaParserPool.reset();
     // Destroy the external ref mgr instance here because it has a timer
     // which needs to be stopped before the app closes.
@@ -438,7 +420,6 @@ ScDocument::~ScDocument()
     delete pPrinter;
     ImplDeleteOptions();
     delete pConsolidateDlgData;
-    delete pLinkManager;
     delete pClipData;
     delete pDetOpList;                  // loescht auch die Eintraege
     delete pChangeTrack;
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index 47ad103..1b9b20dd 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 <documentlinkmgr.hxx>
 
 #include <memory>
 #include <boost/scoped_ptr.hpp>
@@ -750,9 +751,10 @@ bool ScDocument::IdleCheckLinks()           // true = demnaechst wieder versuche
 {
     bool bAnyLeft = false;
 
-    if (GetLinkManager())
+    sfx2::LinkManager* pMgr = GetLinkManager();
+    if (pMgr)
     {
-        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+        const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
         sal_uInt16 nCount = rLinks.size();
         for (sal_uInt16 i=0; i<nCount; i++)
         {
@@ -814,29 +816,32 @@ void ScDocument::SaveDdeLinks(SvStream& rStream) const
 
 void ScDocument::LoadDdeLinks(SvStream& rStream)
 {
+    sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
+    if (!pMgr)
+        return;
+
     ScMultipleReadHeader aHdr( rStream );
 
-    GetLinkManager();
     sal_uInt16 nCount;
     rStream >> nCount;
     for (sal_uInt16 i=0; i<nCount; i++)
     {
         ScDdeLink* pLink = new ScDdeLink( this, rStream, aHdr );
-        pLinkManager->InsertDDELink( pLink,
-                            pLink->GetAppl(), pLink->GetTopic(), pLink->GetItem() );
+        pMgr->InsertDDELink(pLink, pLink->GetAppl(), pLink->GetTopic(), pLink->GetItem());
     }
 }
 
 bool ScDocument::HasDdeLinks() const
 {
-    if (GetLinkManager())           // Clipboard z.B. hat keinen LinkManager
-    {
-        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
-        sal_uInt16 nCount = rLinks.size();
-        for (sal_uInt16 i=0; i<nCount; i++)
-            if ((*rLinks[i])->ISA(ScDdeLink))
-                return true;
-    }
+    const sfx2::LinkManager* pMgr = GetDocLinkManager().getExistingLinkManager();
+    if (!pMgr)
+        return false;
+
+    const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
+    sal_uInt16 nCount = rLinks.size();
+    for (sal_uInt16 i=0; i<nCount; i++)
+        if ((*rLinks[i])->ISA(ScDdeLink))
+            return true;
 
     return false;
 }
@@ -856,10 +861,11 @@ bool ScDocument::IsInLinkUpdate() const
 
 void ScDocument::UpdateExternalRefLinks(Window* pWin)
 {
-    if (!GetLinkManager())
+    sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
+    if (!pMgr)
         return;
 
-    const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+    const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
     sal_uInt16 nCount = rLinks.size();
 
     bool bAny = false;
@@ -876,7 +882,7 @@ void ScDocument::UpdateExternalRefLinks(Window* pWin)
                 // Update failed.  Notify the user.
 
                 OUString aFile;
-                pLinkManager->GetDisplayNames(pRefLink, NULL, &aFile, NULL, NULL);
+                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);
@@ -911,56 +917,57 @@ void ScDocument::UpdateExternalRefLinks(Window* pWin)
 
 void ScDocument::UpdateDdeLinks(Window* pWin)
 {
-    if (GetLinkManager())
-    {
-        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
-        sal_uInt16 nCount = rLinks.size();
-        sal_uInt16 i;
+    sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
+    if (!pMgr)
+        return;
 
-        //  falls das Updaten laenger dauert, erstmal alle Werte
-        //  zuruecksetzen, damit nichts altes (falsches) stehen bleibt
-        bool bAny = false;
-        for (i=0; i<nCount; i++)
+    const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
+    sal_uInt16 nCount = rLinks.size();
+    sal_uInt16 i;
+
+    //  falls das Updaten laenger dauert, erstmal alle Werte
+    //  zuruecksetzen, damit nichts altes (falsches) stehen bleibt
+    bool bAny = false;
+    for (i=0; i<nCount; i++)
+    {
+        ::sfx2::SvBaseLink* pBase = *rLinks[i];
+        ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
+        if (pDdeLink)
         {
-            ::sfx2::SvBaseLink* pBase = *rLinks[i];
-            ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
-            if (pDdeLink)
+            if (pDdeLink->Update())
+                bAny = true;
+            else
             {
-                if (pDdeLink->Update())
-                    bAny = true;
-                else
-                {
-                    // Update failed.  Notify the user.
-                    OUString aFile = pDdeLink->GetTopic();
-                    OUString aElem = pDdeLink->GetItem();
-                    OUString aType = pDdeLink->GetAppl();
-
-                    OUStringBuffer aBuf;
-                    aBuf.append(OUString(ScResId(SCSTR_DDEDOC_NOT_LOADED)));
-                    aBuf.appendAscii("\n\n");
-                    aBuf.appendAscii("Source : ");
-                    aBuf.append(aFile);
-                    aBuf.appendAscii("\nElement : ");
-                    aBuf.append(aElem);
-                    aBuf.appendAscii("\nType : ");
-                    aBuf.append(aType);
-                    ErrorBox aBox(pWin, WB_OK, aBuf.makeStringAndClear());
-                    aBox.Execute();
-                }
-            }
-        }
-        if (bAny)
-        {
-            //  Formeln berechnen und painten wie im TrackTimeHdl
-            TrackFormulas();
-            pShell->Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
+                // Update failed.  Notify the user.
+                OUString aFile = pDdeLink->GetTopic();
+                OUString aElem = pDdeLink->GetItem();
+                OUString aType = pDdeLink->GetAppl();
 
-            //  wenn FID_DATACHANGED irgendwann mal asynchron werden sollte
-            //  (z.B. mit Invalidate am Window), muss hier ein Update erzwungen werden.
+                OUStringBuffer aBuf;
+                aBuf.append(OUString(ScResId(SCSTR_DDEDOC_NOT_LOADED)));
+                aBuf.appendAscii("\n\n");
+                aBuf.appendAscii("Source : ");
+                aBuf.append(aFile);
+                aBuf.appendAscii("\nElement : ");
+                aBuf.append(aElem);
+                aBuf.appendAscii("\nType : ");
+                aBuf.append(aType);
+                ErrorBox aBox(pWin, WB_OK, aBuf.makeStringAndClear());
+                aBox.Execute();
+            }
         }
+    }
+    if (bAny)
+    {
+        //  Formeln berechnen und painten wie im TrackTimeHdl
+        TrackFormulas();
+        pShell->Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
 
-        pLinkManager->CloseCachedComps();
+        //  wenn FID_DATACHANGED irgendwann mal asynchron werden sollte
+        //  (z.B. mit Invalidate am Window), muss hier ein Update erzwungen werden.
     }
+
+    pMgr->CloseCachedComps();
 }
 
 bool ScDocument::UpdateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem )
@@ -969,43 +976,47 @@ bool ScDocument::UpdateDdeLink( const OUString& rAppl, const OUString& rTopic, c
     //  ResetValue() fuer einzelnen Link nicht noetig
     //! wenn's mal alles asynchron wird, aber auch hier
 
+    sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
+    if (!pMgr)
+        return false;
+
     bool bFound = false;
-    if (GetLinkManager())
+
+    const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
+    sal_uInt16 nCount = rLinks.size();
+    for (sal_uInt16 i=0; i<nCount; i++)
     {
-        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
-        sal_uInt16 nCount = rLinks.size();
-        for (sal_uInt16 i=0; i<nCount; i++)
+        ::sfx2::SvBaseLink* pBase = *rLinks[i];
+        if (pBase->ISA(ScDdeLink))
         {
-            ::sfx2::SvBaseLink* pBase = *rLinks[i];
-            if (pBase->ISA(ScDdeLink))
+            ScDdeLink* pDdeLink = (ScDdeLink*)pBase;
+            if ( OUString(pDdeLink->GetAppl()) == rAppl &&
+                 OUString(pDdeLink->GetTopic()) == rTopic &&
+                 OUString(pDdeLink->GetItem()) == rItem )
             {
-                ScDdeLink* pDdeLink = (ScDdeLink*)pBase;
-                if ( OUString(pDdeLink->GetAppl()) == rAppl &&
-                     OUString(pDdeLink->GetTopic()) == rTopic &&
-                     OUString(pDdeLink->GetItem()) == rItem )
-                {
-                    pDdeLink->TryUpdate();
-                    bFound = true;          // koennen theoretisch mehrere sein (Mode), darum weitersuchen
-                }
+                pDdeLink->TryUpdate();
+                bFound = true;          // koennen theoretisch mehrere sein (Mode), darum weitersuchen
             }
         }
-        pLinkManager->CloseCachedComps();
     }
+    pMgr->CloseCachedComps();
+
     return bFound;
 }
 
 void ScDocument::DisconnectDdeLinks()
 {
-    if (GetLinkManager())
+    sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
+    if (!pMgr)
+        return;
+
+    const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
+    sal_uInt16 nCount = rLinks.size();
+    for (sal_uInt16 i=0; i<nCount; i++)
     {
-        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
-        sal_uInt16 nCount = rLinks.size();
-        for (sal_uInt16 i=0; i<nCount; i++)
-        {
-            ::sfx2::SvBaseLink* pBase = *rLinks[i];
-            if (pBase->ISA(ScDdeLink))
-                pBase->Disconnect();            // bleibt im LinkManager eingetragen
-        }
+        ::sfx2::SvBaseLink* pBase = *rLinks[i];
+        if (pBase->ISA(ScDdeLink))
+            pBase->Disconnect();            // bleibt im LinkManager eingetragen
     }
 }
 
@@ -1018,31 +1029,42 @@ void ScDocument::CopyDdeLinks( ScDocument* pDestDoc ) const
             pClipData->Seek(0);
             pDestDoc->LoadDdeLinks(*pClipData);
         }
+
+        return;
     }
-    else if (GetLinkManager())              // Links direkt kopieren
+
+    const sfx2::LinkManager* pMgr = GetDocLinkManager().getExistingLinkManager();
+    if (!pMgr)
+        return;
+
+    sfx2::LinkManager* pDestMgr = pDestDoc->GetDocLinkManager().getLinkManager(pDestDoc->bAutoCalc);
+    if (!pDestMgr)
+        return;
+
+    const sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
+    for (size_t i = 0, n = rLinks.size(); i < n; ++i)
     {
-        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
-        size_t nCount = rLinks.size();
-        for (size_t i=0; i<nCount; i++)
+        const sfx2::SvBaseLink* pBase = *rLinks[i];
+        if (pBase->ISA(ScDdeLink))
         {
-            ::sfx2::SvBaseLink* pBase = *rLinks[i];
-            if (pBase->ISA(ScDdeLink))
-            {
-                ScDdeLink* pNew = new ScDdeLink( pDestDoc, *(ScDdeLink*)pBase );
-
-                pDestDoc->pLinkManager->InsertDDELink( pNew,
-                                pNew->GetAppl(), pNew->GetTopic(), pNew->GetItem() );
-            }
+            const ScDdeLink* p = static_cast<const ScDdeLink*>(pBase);
+            ScDdeLink* pNew = new ScDdeLink(pDestDoc, *p);
+            pDestMgr->InsertDDELink(
+                pNew, pNew->GetAppl(), pNew->GetTopic(), pNew->GetItem());
         }
     }
 }
 
 size_t ScDocument::GetDdeLinkCount() const
 {
+    const sfx2::LinkManager* pMgr = GetDocLinkManager().getExistingLinkManager();
+    if (!pMgr)
+        return 0;
+
     size_t nDdeCount = 0;
     if (GetLinkManager())
     {
-        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
+        const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
         size_t nCount = rLinks.size();
         for (size_t i=0; i<nCount; i++)
             if ((*rLinks[i])->ISA(ScDdeLink))
@@ -1155,14 +1177,19 @@ bool ScDocument::CreateDdeLink( const OUString& rAppl, const OUString& rTopic, c
         on existing and new links. */
     //! store DDE links additionally at document (for efficiency)?
     OSL_ENSURE( nMode != SC_DDE_IGNOREMODE, "ScDocument::CreateDdeLink - SC_DDE_IGNOREMODE not allowed here" );
-    if( GetLinkManager() && (nMode != SC_DDE_IGNOREMODE) )
+
+    sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
+    if (!pMgr)
+        return false;
+
+    if (nMode != SC_DDE_IGNOREMODE)
     {
-        ScDdeLink* pDdeLink = lclGetDdeLink( pLinkManager, rAppl, rTopic, rItem, nMode );
+        ScDdeLink* pDdeLink = lclGetDdeLink(pMgr, rAppl, rTopic, rItem, nMode);
         if( !pDdeLink )
         {
             // create a new DDE link, but without TryUpdate
             pDdeLink = new ScDdeLink( this, rAppl, rTopic, rItem, nMode );
-            pLinkManager->InsertDDELink( pDdeLink, rAppl, rTopic, rItem );
+            pMgr->InsertDDELink(pDdeLink, rAppl, rTopic, rItem);
         }
 
         // insert link results
@@ -1188,117 +1215,121 @@ bool ScDocument::SetDdeLinkResultMatrix( size_t nDdePos, ScMatrixRef pResults )
 
 bool ScDocument::HasAreaLinks() const
 {
-    if (GetLinkManager())           // Clipboard z.B. hat keinen LinkManager
-    {
-        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
-        sal_uInt16 nCount = rLinks.size();
-        for (sal_uInt16 i=0; i<nCount; i++)
-            if ((*rLinks[i])->ISA(ScAreaLink))
-                return true;
-    }
+    const sfx2::LinkManager* pMgr = GetDocLinkManager().getExistingLinkManager();
+    if (!pMgr)
+        return false;
+
+    const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
+    sal_uInt16 nCount = rLinks.size();
+    for (sal_uInt16 i=0; i<nCount; i++)
+        if ((*rLinks[i])->ISA(ScAreaLink))
+            return true;
 
     return false;
 }
 
 void ScDocument::UpdateAreaLinks()
 {
-    if (GetLinkManager())
+    sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false);
+    if (!pMgr)
+        return;
+
+    const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
+    for (sal_uInt16 i=0; i<rLinks.size(); i++)
     {
-        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
-        for (sal_uInt16 i=0; i<rLinks.size(); i++)
-        {
-            ::sfx2::SvBaseLink* pBase = *rLinks[i];
-            if (pBase->ISA(ScAreaLink))
-                pBase->Update();
-        }
+        ::sfx2::SvBaseLink* pBase = *rLinks[i];
+        if (pBase->ISA(ScAreaLink))
+            pBase->Update();
     }
 }
 
 void ScDocument::DeleteAreaLinksOnTab( SCTAB nTab )
 {
-    if (GetLinkManager())
+    sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false);
+    if (!pMgr)
+        return;
+
+    const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
+    sal_uInt16 nPos = 0;
+    while ( nPos < rLinks.size() )
     {
-        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
-        sal_uInt16 nPos = 0;
-        while ( nPos < rLinks.size() )
-        {
-            const ::sfx2::SvBaseLink* pBase = *rLinks[nPos];
-            if ( pBase->ISA(ScAreaLink) &&
-                 static_cast<const ScAreaLink*>(pBase)->GetDestArea().aStart.Tab() == nTab )
-                pLinkManager->Remove( nPos );
-            else
-                ++nPos;
-        }
+        const ::sfx2::SvBaseLink* pBase = *rLinks[nPos];
+        if ( pBase->ISA(ScAreaLink) &&
+             static_cast<const ScAreaLink*>(pBase)->GetDestArea().aStart.Tab() == nTab )
+            pMgr->Remove(nPos);
+        else
+            ++nPos;
     }
 }
 
 void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode,
                              const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
 {
-    if (GetLinkManager())
-    {
-        bool bAnyUpdate = false;
+    sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(false);
+    if (!pMgr)
+        return;
 
-        const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
-        sal_uInt16 nCount = rLinks.size();
-        for (sal_uInt16 i=0; i<nCount; i++)
+    bool bAnyUpdate = false;
+
+    const ::sfx2::SvBaseLinks& rLinks = pMgr->GetLinks();
+    sal_uInt16 nCount = rLinks.size();
+    for (sal_uInt16 i=0; i<nCount; i++)
+    {
+        ::sfx2::SvBaseLink* pBase = *rLinks[i];
+        if (pBase->ISA(ScAreaLink))
         {
-            ::sfx2::SvBaseLink* pBase = *rLinks[i];
-            if (pBase->ISA(ScAreaLink))
+            ScAreaLink* pLink = (ScAreaLink*) pBase;
+            ScRange aOutRange = pLink->GetDestArea();
+
+            SCCOL nCol1 = aOutRange.aStart.Col();
+            SCROW nRow1 = aOutRange.aStart.Row();
+            SCTAB nTab1 = aOutRange.aStart.Tab();
+            SCCOL nCol2 = aOutRange.aEnd.Col();
+            SCROW nRow2 = aOutRange.aEnd.Row();
+            SCTAB nTab2 = aOutRange.aEnd.Tab();
+
+            ScRefUpdateRes eRes =
+                ScRefUpdate::Update( this, eUpdateRefMode,
+                    rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
+                    rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
+                    nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+            if ( eRes != UR_NOTHING )
             {
-                ScAreaLink* pLink = (ScAreaLink*) pBase;
-                ScRange aOutRange = pLink->GetDestArea();
-
-                SCCOL nCol1 = aOutRange.aStart.Col();
-                SCROW nRow1 = aOutRange.aStart.Row();
-                SCTAB nTab1 = aOutRange.aStart.Tab();
-                SCCOL nCol2 = aOutRange.aEnd.Col();
-                SCROW nRow2 = aOutRange.aEnd.Row();
-                SCTAB nTab2 = aOutRange.aEnd.Tab();
-
-                ScRefUpdateRes eRes =
-                    ScRefUpdate::Update( this, eUpdateRefMode,
-                        rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
-                        rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
-                        nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
-                if ( eRes != UR_NOTHING )
-                {
-                    pLink->SetDestArea( ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ) );
-                    bAnyUpdate = true;
-                }
+                pLink->SetDestArea( ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ) );
+                bAnyUpdate = true;
             }
         }
+    }
 
-        if ( bAnyUpdate )
-        {
-            // #i52120# Look for duplicates (after updating all positions).
-            // If several links start at the same cell, the one with the lower index is removed
-            // (file format specifies only one link definition for a cell).
+    if ( bAnyUpdate )
+    {
+        // #i52120# Look for duplicates (after updating all positions).
+        // If several links start at the same cell, the one with the lower index is removed
+        // (file format specifies only one link definition for a cell).
 
-            sal_uInt16 nFirstIndex = 0;
-            while ( nFirstIndex < nCount )
+        sal_uInt16 nFirstIndex = 0;
+        while ( nFirstIndex < nCount )
+        {
+            bool bFound = false;
+            ::sfx2::SvBaseLink* pFirst = *rLinks[nFirstIndex];
+            if ( pFirst->ISA(ScAreaLink) )
             {
-                bool bFound = false;
-                ::sfx2::SvBaseLink* pFirst = *rLinks[nFirstIndex];
-                if ( pFirst->ISA(ScAreaLink) )
+                ScAddress aFirstPos = static_cast<ScAreaLink*>(pFirst)->GetDestArea().aStart;
+                for ( sal_uInt16 nSecondIndex = nFirstIndex + 1; nSecondIndex < nCount && !bFound; ++nSecondIndex )
                 {
-                    ScAddress aFirstPos = static_cast<ScAreaLink*>(pFirst)->GetDestArea().aStart;
-                    for ( sal_uInt16 nSecondIndex = nFirstIndex + 1; nSecondIndex < nCount && !bFound; ++nSecondIndex )
+                    ::sfx2::SvBaseLink* pSecond = *rLinks[nSecondIndex];
+                    if ( pSecond->ISA(ScAreaLink) &&
+                         static_cast<ScAreaLink*>(pSecond)->GetDestArea().aStart == aFirstPos )
                     {
-                        ::sfx2::SvBaseLink* pSecond = *rLinks[nSecondIndex];
-                        if ( pSecond->ISA(ScAreaLink) &&
-                             static_cast<ScAreaLink*>(pSecond)->GetDestArea().aStart == aFirstPos )
-                        {
-                            // remove the first link, exit the inner loop, don't increment nFirstIndex
-                            pLinkManager->Remove( pFirst );
-                            nCount = rLinks.size();
-                            bFound = true;
-                        }
+                        // remove the first link, exit the inner loop, don't increment nFirstIndex
+                        pMgr->Remove(pFirst);
+                        nCount = rLinks.size();
+                        bFound = true;
                     }
                 }
-                if (!bFound)
-                    ++nFirstIndex;
             }
+            if (!bFound)
+                ++nFirstIndex;
         }
     }
 }
diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx
index 7eac811..52a4547 100644
--- a/sc/source/core/data/documen9.cxx
+++ b/sc/source/core/data/documen9.cxx
@@ -54,6 +54,7 @@
 #include "postit.hxx"
 #include "charthelper.hxx"
 #include "interpre.hxx"
+#include <documentlinkmgr.hxx>
 
 using namespace ::com::sun::star;
 #include <stdio.h>
@@ -130,8 +131,10 @@ void ScDocument::InitDrawLayer( SfxObjectShell* pDocShell )
         if ( pShell && !pShell->IsLoading() )       // don't call GetTitle while loading
             aName = pShell->GetTitle();
         pDrawLayer = new ScDrawLayer( this, aName );
-        if (GetLinkManager())
-            pDrawLayer->SetLinkManager( pLinkManager );
+
+        sfx2::LinkManager* pMgr = GetDocLinkManager().getLinkManager(bAutoCalc);
+        if (pMgr)
+            pDrawLayer->SetLinkManager(pMgr);
 
         //  Drawing pages are accessed by table number, so they must also be present
         //  for preceding table numbers, even if the tables aren't allocated
diff --git a/sc/source/ui/docshell/documentlinkmgr.cxx b/sc/source/ui/docshell/documentlinkmgr.cxx
index 2b9998f..399e15e 100644
--- a/sc/source/ui/docshell/documentlinkmgr.cxx
+++ b/sc/source/ui/docshell/documentlinkmgr.cxx
@@ -9,6 +9,7 @@
 
 #include <documentlinkmgr.hxx>
 #include <datastream.hxx>
+#include <sfx2/linkmgr.hxx>
 
 #include <boost/noncopyable.hpp>
 #include <boost/scoped_ptr.hpp>
@@ -17,12 +18,31 @@ namespace sc {
 
 struct DocumentLinkManagerImpl : boost::noncopyable
 {
+    ScDocument& mrDoc;
+    SfxObjectShell* mpShell;
     boost::scoped_ptr<DataStream> mpDataStream;
+    boost::scoped_ptr<sfx2::LinkManager> mpLinkManager;
 
-    DocumentLinkManagerImpl() : mpDataStream(NULL) {}
+    DocumentLinkManagerImpl( ScDocument& rDoc, SfxObjectShell* pShell ) :
+        mrDoc(rDoc), mpShell(pShell), mpDataStream(NULL), mpLinkManager(NULL) {}
+
+    ~DocumentLinkManagerImpl()
+    {
+        // Shared base links
+        if (mpLinkManager)
+        {
+            sfx2::SvLinkSources aTemp = mpLinkManager->GetServers();
+            for (sfx2::SvLinkSources::const_iterator it = aTemp.begin(); it != aTemp.end(); ++it)
+                (*it)->Closed();
+
+            if (!mpLinkManager->GetLinks().empty())
+                mpLinkManager->Remove(0, mpLinkManager->GetLinks().size());
+        }
+    }
 };
 
-DocumentLinkManager::DocumentLinkManager() : mpImpl(new DocumentLinkManagerImpl) {}
+DocumentLinkManager::DocumentLinkManager( ScDocument& rDoc, SfxObjectShell* pShell ) :
+    mpImpl(new DocumentLinkManagerImpl(rDoc, pShell)) {}
 
 void DocumentLinkManager::setDataStream( DataStream* p )
 {
@@ -39,6 +59,18 @@ const DataStream* DocumentLinkManager::getDataStream() const
     return mpImpl->mpDataStream.get();
 }
 
+sfx2::LinkManager* DocumentLinkManager::getLinkManager( bool bCreate )
+{
+    if (!mpImpl->mpLinkManager && bCreate && mpImpl->mpShell)
+        mpImpl->mpLinkManager.reset(new sfx2::LinkManager(mpImpl->mpShell));
+    return mpImpl->mpLinkManager.get();
+}
+
+const sfx2::LinkManager* DocumentLinkManager::getExistingLinkManager() const
+{
+    return mpImpl->mpLinkManager.get();
+}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/areasave.hxx b/sc/source/ui/inc/areasave.hxx
index 8d7ff13..067cba8 100644
--- a/sc/source/ui/inc/areasave.hxx
+++ b/sc/source/ui/inc/areasave.hxx
@@ -47,7 +47,7 @@ public:
     bool        IsEqualSource( const ScAreaLink& rCompare ) const;
 
     void        WriteToLink( ScAreaLink& rLink ) const;
-    void        InsertNewLink( ScDocument* pDoc ) const;
+    void InsertNewLink( ScDocument* pDoc );
 };
 
 
@@ -62,11 +62,12 @@ public:
 
 
     bool        IsEqual( const ScDocument* pDoc ) const;
-    void        Restore( ScDocument* pDoc ) const;
+    void Restore( ScDocument* pDoc );
 
     // returns NULL if empty
     static ScAreaLinkSaveCollection* CreateFromDoc( const ScDocument* pDoc );
 
+    ScAreaLinkSaver* operator[](size_t nIndex);
     const ScAreaLinkSaver* operator[](size_t nIndex) const;
     size_t size() const;
     void push_back(ScAreaLinkSaver* p);
diff --git a/sc/source/ui/undo/areasave.cxx b/sc/source/ui/undo/areasave.cxx
index f44b098..3c9a8d1 100644
--- a/sc/source/ui/undo/areasave.cxx
+++ b/sc/source/ui/undo/areasave.cxx
@@ -22,6 +22,7 @@
 #include "areasave.hxx"
 #include "arealink.hxx"
 #include "document.hxx"
+#include <documentlinkmgr.hxx>
 
 // -----------------------------------------------------------------------
 
@@ -67,7 +68,7 @@ void ScAreaLinkSaver::WriteToLink( ScAreaLink& rLink ) const
     rLink.SetDestArea( aDestArea );
 }
 
-void ScAreaLinkSaver::InsertNewLink( ScDocument* pDoc ) const
+void ScAreaLinkSaver::InsertNewLink( ScDocument* pDoc )
 {
     // (see ScUndoRemoveAreaLink::Undo)
 
@@ -99,7 +100,7 @@ bool ScAreaLinkSaveCollection::IsEqual( const ScDocument* pDoc ) const
     // IsEqual can be checked in sequence.
     // Neither ref-update nor removing links will change the order.
 
-    sfx2::LinkManager* pLinkManager = const_cast<ScDocument*>(pDoc)->GetLinkManager();
+    const sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
     if (pLinkManager)
     {
         size_t nPos = 0;
@@ -138,21 +139,21 @@ static ScAreaLink* lcl_FindLink( const ::sfx2::SvBaseLinks& rLinks, const ScArea
     return NULL;    // not found
 }
 
-void ScAreaLinkSaveCollection::Restore( ScDocument* pDoc ) const
+void ScAreaLinkSaveCollection::Restore( ScDocument* pDoc )
 {
     // The save collection may contain additional entries that are not in the document.
     // They must be inserted again.
     // Entries from the save collection must be searched via source data, as the order
     // of links changes if deleted entries are re-added to the link manager (always at the end).
 
-    sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+    sfx2::LinkManager* pLinkManager = pDoc->GetDocLinkManager().getLinkManager(false);
     if (pLinkManager)
     {
         const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
         size_t nSaveCount = size();
         for (size_t nPos=0; nPos<nSaveCount; ++nPos)
         {
-            const ScAreaLinkSaver* pSaver = (*this)[nPos];
+            ScAreaLinkSaver* pSaver = (*this)[nPos];
             ScAreaLink* pLink = lcl_FindLink( rLinks, *pSaver );
             if ( pLink )
                 pSaver->WriteToLink( *pLink );          // restore output position
@@ -188,6 +189,11 @@ ScAreaLinkSaveCollection* ScAreaLinkSaveCollection::CreateFromDoc( const ScDocum
     return pColl;
 }
 
+ScAreaLinkSaver* ScAreaLinkSaveCollection::operator [](size_t nIndex)
+{
+    return &maData[nIndex];
+}
+
 const ScAreaLinkSaver* ScAreaLinkSaveCollection::operator [](size_t nIndex) const
 {
     return &maData[nIndex];


More information about the Libreoffice-commits mailing list