Commits

Anonymous committed bc8954f

CWS-TOOLING: integrate CWS calc31stopper4_DEV300
2009-03-25 11:52:59 +0100 nn r270010 : GetHTMLRangeNameList: call ScHTMLImport static method, not same method again (bug-id not available yet)
2009-03-20 14:24:51 +0100 er r269808 : #i100416# makeExternalRefStrImpl: don't care about a second sheet name if not needed
2009-03-20 13:14:30 +0100 er r269803 : carry along row position also for non-existing (empty) rows
2009-03-20 11:26:33 +0100 er r269790 : SUNWS12: declarator required in declaration; removed SC_DLLPRIVATE from inner class declaration
2009-03-19 19:40:09 +0100 er r269767 : #i100300# save only referenced tables of external data cache
2009-03-19 14:45:05 +0100 dr r269746 : #i100346# more places where checking docshell is needed
2009-03-19 14:13:20 +0100 fs r269744 : #i100349# do not delete the pool before all instances knowing it have been deleted
2009-03-19 11:35:45 +0100 dr r269735 : #i100346# always check docshell, is missing when pasting from clipboard
2009-03-19 09:39:49 +0100 dr r269728 : #i100332# remove debug statement, patch from kohei

Comments (0)

Files changed (27)

 	void			CompileTokenArray( BOOL bNoListening = FALSE );
 	void			CompileXML( ScProgress& rProgress );		// compile temporary string tokens
 	void			CalcAfterLoad();
+    bool            MarkUsedExternalReferences();
 	void			Interpret();
     inline BOOL     IsIterCell() const { return bIsIterCell; }
     inline USHORT   GetSeenInIteration() const { return nSeenInIteration; }

sc/inc/column.hxx

 	void		CalcAfterLoad();
 	void		CompileAll();
 	void		CompileXML( ScProgress& rProgress );
+    bool        MarkUsedExternalReferences();
 
 	void		ResetChanged( SCROW nStartRow, SCROW nEndRow );
 

sc/inc/conditio.hxx

 
 	void			SourceChanged( const ScAddress& rChanged );
 
+    bool            MarkUsedExternalReferences() const;
+
 protected:
 	virtual void	DataChanged( const ScRange* pModified ) const;
 	ScDocument*		GetDocument() const		{ return pDoc; }
 	void			SetUsed(BOOL bSet)		{ bIsUsed = bSet; }
 	BOOL			IsUsed() const			{ return bIsUsed; }
 
+    bool            MarkUsedExternalReferences() const;
+
 	//	sortiert (per PTRARR) nach Index
 	//	operator== nur fuer die Sortierung
 	BOOL operator ==( const ScConditionalFormat& r ) const	{ return nKey == r.nKey; }
 
 	void	SourceChanged( const ScAddress& rAddr );
 
+    /** Temporarily during save, returns RefManager's decision whether ALL 
+     *  references are marked now. */
+    bool    MarkUsedExternalReferences() const;
+
 	BOOL	operator==( const ScConditionalFormatList& r ) const;		// fuer Ref-Undo
 };
 

sc/inc/document.hxx

 									const String& aFileName,
 									const String& aTabName );
 
+    bool            HasExternalRefManager() { return pExternalRefMgr.get(); }
     SC_DLLPUBLIC ScExternalRefManager* GetExternalRefManager();
+    bool            IsInExternalReferenceMarking() const;
+    void            MarkUsedExternalReferences();
+    bool            MarkUsedExternalReferences( ScTokenArray & rArr );
 
 	BOOL			HasDdeLinks() const;
 	BOOL			HasAreaLinks() const;

sc/inc/externalrefmgr.hxx

         SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex = 0);
         TokenRef getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex = NULL) const;
         bool hasRow( SCROW nRow ) const;
+        /// A temporary state used only during store to file.
+        bool isReferenced() const;
+        void setReferenced( bool bReferenced );
+        /// Obtain a sorted vector of rows.
         void getAllRows(::std::vector<SCROW>& rRows) const;
+        /// Obtain a sorted vector of columns.
         void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols) const;
         void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
 
     private:
         RowsDataType maRows;
+        bool         mbReferenced;
     };
 
     typedef ::boost::shared_ptr<Table>      TableTypeRef;
     bool hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const;
     size_t getCacheTableCount(sal_uInt16 nFileId) const;
 
+    /**
+     * Set all tables of a document as referenced, used only during 
+     * store-to-file.
+     * @returns <TRUE/> if ALL tables of ALL documents are marked.
+     */
+    bool setCacheDocReferenced( sal_uInt16 nFileId );
+
+    /**
+     * Set a table as referenced, used only during store-to-file.
+     * @returns <TRUE/> if ALL tables of ALL documents are marked.
+     */
+    bool setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName );
+    void setAllCacheTableReferencedStati( bool bReferenced );
+    bool areAllCacheTablesReferenced() const;
+private:
+    struct ReferencedStatus
+    {
+        struct DocReferenced
+        {
+            ::std::vector<bool> maTables;
+            bool                mbAllTablesReferenced;
+            // Initially, documents have no tables but all referenced.
+            DocReferenced() : mbAllTablesReferenced(true) {}
+        };
+        typedef ::std::vector<DocReferenced> DocReferencedVec;
+
+        DocReferencedVec maDocs;
+        bool             mbAllReferenced;
+
+                    ReferencedStatus();
+        explicit    ReferencedStatus( size_t nDocs );
+        void        reset( size_t nDocs );
+        void        checkAllDocs();
+
+    } maReferenced;
+    void addCacheTableToReferenced( sal_uInt16 nFileId, size_t nIndex );
+    void addCacheDocToReferenced( sal_uInt16 nFileId );
+public:
+
     ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
     ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew, size_t* pnIndex);
 
     size_t getCacheTableCount(sal_uInt16 nFileId) const;
     sal_uInt16 getExternalFileCount() const;
 
+    /**
+     * Mark all tables as referenced that are used by any LinkListener, used 
+     * only during store-to-file.
+     * @returns <TRUE/> if ALL tables of ALL external documents are marked.
+     */
+    bool markUsedByLinkListeners();
+
+    /**
+     * Set all tables of a document as referenced, used only during 
+     * store-to-file.
+     * @returns <TRUE/> if ALL tables of ALL external documents are marked.
+     */
+    bool setCacheDocReferenced( sal_uInt16 nFileId );
+
+    /**
+     * Set a table as referenced, used only during store-to-file.
+     * @returns <TRUE/> if ALL tables of ALL external documents are marked.
+     */
+    bool setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName );
+    void setAllCacheTableReferencedStati( bool bReferenced );
+
+    /**
+     * @returns <TRUE/> if setAllCacheTableReferencedStati(false) was called, 
+     * <FALSE/> if setAllCacheTableReferencedStati(true) was called.
+     */
+    bool isInReferenceMarking() const   { return bInReferenceMarking; }
+
     void storeRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScTokenArray& rArray);
 
     ScExternalRefCache::TokenRef getSingleRefToken(
     /** original source file index. */
     ::std::vector<SrcFileData> maSrcFiles;
 
+    /** Status whether in reference marking state. See isInReferenceMarking(). */
+    bool bInReferenceMarking;
+
     AutoTimer maSrcDocTimer;
     DECL_LINK(TimeOutHdl, AutoTimer*);
 };
 	void		CalcAfterLoad();
 	void		CompileAll();
 	void		CompileXML( ScProgress& rProgress );
+    bool        MarkUsedExternalReferences();
 
 	void		UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
 									SCCOL nCol2, SCROW nRow2, SCTAB nTab2,

sc/inc/validat.hxx

 								const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
     void    UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );
 
+    /** Temporarily during save, returns RefManager's decision whether ALL 
+     *  references are marked now. */
+    bool    MarkUsedExternalReferences() const;
+
 	BOOL	operator==( const ScValidationDataList& r ) const;		// fuer Ref-Undo
 };
 

sc/source/core/data/cell.cxx

 #include "editutil.hxx"
 #include "recursionhelper.hxx"
 #include "postit.hxx"
+#include "externalrefmgr.hxx"
 #include <svx/editobj.hxx>
 #include <svtools/intitem.hxx>
 #include <svx/flditem.hxx>
 }
 
 
+bool ScFormulaCell::MarkUsedExternalReferences()
+{
+    return pCode && pDocument->MarkUsedExternalReferences( *pCode);
+}
+
+
 // FIXME: set to 0
 #define erDEBUGDOT 0
 // If set to 1, write output that's suitable for graphviz tools like dot.

sc/source/core/data/column.cxx

 }
 
 
+bool ScColumn::MarkUsedExternalReferences()
+{
+    bool bAllMarked = false;
+	if (pItems)
+    {
+		for (SCSIZE i = 0; i < nCount && !bAllMarked; ++i)
+		{
+			ScBaseCell* pCell = pItems[i].pCell;
+			if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+				bAllMarked = ((ScFormulaCell*)pCell)->MarkUsedExternalReferences();
+		}
+    }
+    return bAllMarked;
+}
+
+
 void ScColumn::ResetChanged( SCROW nStartRow, SCROW nEndRow )
 {
 	if (pItems)

sc/source/core/data/conditio.cxx

 	// nix
 }
 
+bool ScConditionEntry::MarkUsedExternalReferences() const
+{
+    bool bAllMarked = false;
+    for (USHORT nPass = 0; !bAllMarked && nPass < 2; nPass++)
+    {
+        ScTokenArray* pFormula = nPass ? pFormula2 : pFormula1;
+        if (pFormula)
+            bAllMarked = pDoc->MarkUsedExternalReferences( *pFormula);
+    }
+    return bAllMarked;
+}
+
 //------------------------------------------------------------------------
 
 ScCondFormatEntry::ScCondFormatEntry( ScConditionMode eOper,
 		ppEntries[i]->SourceChanged( rAddr );
 }
 
+bool ScConditionalFormat::MarkUsedExternalReferences() const
+{
+    bool bAllMarked = false;
+	for (USHORT i=0; !bAllMarked && i<nEntryCount; i++)
+		bAllMarked = ppEntries[i]->MarkUsedExternalReferences();
+    return bAllMarked;
+}
+
 //------------------------------------------------------------------------
 
 ScConditionalFormatList::ScConditionalFormatList(const ScConditionalFormatList& rList) :
 		(*this)[i]->SourceChanged( rAddr );
 }
 
-
-
+bool ScConditionalFormatList::MarkUsedExternalReferences() const
+{
+    bool bAllMarked = false;
+	USHORT nCount = Count();
+	for (USHORT i=0; !bAllMarked && i<nCount; i++)
+		bAllMarked = (*this)[i]->MarkUsedExternalReferences();
+    return bAllMarked;
+}

sc/source/core/data/documen3.cxx

     return pExternalRefMgr.get();
 }
 
+bool ScDocument::IsInExternalReferenceMarking() const
+{
+    return pExternalRefMgr.get() && pExternalRefMgr->isInReferenceMarking();
+}
+
+void ScDocument::MarkUsedExternalReferences()
+{
+    if (!pExternalRefMgr.get())
+        return;
+    if (!pExternalRefMgr->hasExternalData())
+        return;
+    // Charts.
+    bool bAllMarked = pExternalRefMgr->markUsedByLinkListeners();
+    // Formula cells.
+    for (SCTAB nTab = 0; !bAllMarked && nTab < nMaxTableNumber; ++nTab)
+    {
+        if (pTab[nTab])
+            bAllMarked = pTab[nTab]->MarkUsedExternalReferences();
+    }
+    /* NOTE: Conditional formats and validation objects are marked when 
+     * collecting them during export. */
+}
+
 ScOutlineTable* ScDocument::GetOutlineTable( SCTAB nTab, BOOL bCreate )
 {
 	ScOutlineTable* pVal = NULL;

sc/source/core/data/documen4.cxx

 #include <svtools/intitem.hxx>
 #include <svtools/zforlist.hxx>
 #include <vcl/sound.hxx>
+#include <formula/token.hxx>
 
 #include "document.hxx"
 #include "table.hxx"
 #include "progress.hxx"
 #include "paramisc.hxx"
 #include "compiler.hxx"
+#include "externalrefmgr.hxx"
+
+using namespace formula;
 
 // -----------------------------------------------------------------------
 
                     pTab[i]->PutCell( j, k, aRefCell.CloneWithoutNote( *this, ScAddress( j, k, i ), SC_CLONECELL_STARTLISTENING ) );
 }
 
+bool ScDocument::MarkUsedExternalReferences( ScTokenArray & rArr )
+{
+    bool bAllMarked = false;
+    if (rArr.GetLen())
+    {
+        ScExternalRefManager* pRefMgr = NULL;
+        rArr.Reset();
+        ScToken* t;
+        while (!bAllMarked && (t = static_cast<ScToken*>(rArr.GetNextReferenceOrName())) != NULL)
+        {
+            if (t->GetOpCode() == ocExternalRef)
+            {
+                if (!pRefMgr)
+                    pRefMgr = GetExternalRefManager();
+                switch (t->GetType())
+                {
+                    case svExternalSingleRef:
+                    case svExternalDoubleRef:
+                        bAllMarked = pRefMgr->setCacheTableReferenced( 
+                                t->GetIndex(), t->GetString());
+                        break;
+                    case svExternalName:
+                        /* TODO: external names aren't supported yet, but would 
+                         * have to be marked as well, if so. Mechanism would be 
+                         * different. */
+                        DBG_ERRORFILE("ScDocument::MarkUsedExternalReferences: implement the svExternalName case!");
+                        break;
+                }
+            }
+        }
+    }
+    return bAllMarked;
+}
+
 BOOL ScDocument::GetNextSpellingCell(SCCOL& nCol, SCROW& nRow, SCTAB nTab,
 						BOOL bInSel, const ScMarkData& rMark) const
 {

sc/source/core/data/table2.cxx

 	}
 }
 
-
 void ScTable::CalcAfterLoad()
 {
 	for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CalcAfterLoad();
 }
 
 
+bool ScTable::MarkUsedExternalReferences()
+{
+    bool bAllMarked = false;
+    for (SCCOL i=0; i <= MAXCOL && !bAllMarked; ++i)
+    {
+        bAllMarked = aCol[i].MarkUsedExternalReferences();
+    }
+    return bAllMarked;
+}
+
+
 void ScTable::ResetChanged( const ScRange& rRange )
 {
 	SCCOL nStartCol = rRange.aStart.Col();

sc/source/core/data/validat.cxx

 		(*this)[i]->UpdateMoveTab( nOldPos, nNewPos );
 }
 
+bool ScValidationDataList::MarkUsedExternalReferences() const
+{
+    bool bAllMarked = false;
+	USHORT nCount = Count();
+	for (USHORT i=0; !bAllMarked && i<nCount; i++)
+		bAllMarked = (*this)[i]->MarkUsedExternalReferences();
+    return bAllMarked;
+}
+
 BOOL ScValidationDataList::operator==( const ScValidationDataList& r ) const
 {
 	// fuer Ref-Undo - interne Variablen werden nicht verglichen

sc/source/core/tool/compiler.cxx

 
             rBuffer.append(sal_Unicode(':'));
 
-            // Get the name of the last table.
-            vector<String> aTabNames;
-            pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
-            if (aTabNames.empty())
+            String aLastTabName;
+            bool bDisplayTabName = (aRef.Ref1.nTab != aRef.Ref2.nTab);
+            if (bDisplayTabName)
             {
-                DBG_ERROR1( "ConventionOOO_A1::makeExternalRefStrImpl: no sheet names for document ID %s", nFileId);
-                break;
+                // Get the name of the last table.
+                vector<String> aTabNames;
+                pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
+                if (aTabNames.empty())
+                {
+                    DBG_ERROR1( "ConventionOOO_A1::makeExternalRefStrImpl: no sheet names for document ID %s", nFileId);
+                }
+
+                if (!lcl_getLastTabName(aLastTabName, rTabName, aTabNames, aRef))
+                {
+                    DBG_ERROR( "ConventionOOO_A1::makeExternalRefStrImpl: sheet name not found");
+                    // aLastTabName contains #REF!, proceed.
+                }
             }
-
-            String aLastTabName;
-            if (!lcl_getLastTabName(aLastTabName, rTabName, aTabNames, aRef))
-            {
-                rBuffer.append(aLastTabName);
-                DBG_ERROR( "ConventionOOO_A1::makeExternalRefStrImpl: sheet name not found");
-                break;
-            }
-            bool bDisplayTabName = (aRef.Ref1.nTab != aRef.Ref2.nTab);
-            if (bODF && !bDisplayTabName)
+            else if (bODF)
                 rBuffer.append( sal_Unicode('.'));      // need at least the sheet separator in ODF
             makeExternalSingleRefStr( rBuffer, nFileId, aLastTabName,
                     aRef.Ref2, pRefMgr, bDisplayTabName);

sc/source/filter/excel/excform8.cxx

 bool ExcelToSc8::GetExternalFileIdFromXti( UINT16 nIxti, sal_uInt16& rFileId ) const
 {
     const String* pFileUrl = rLinkMan.GetSupbookUrl(nIxti);
-    if (!pFileUrl || pFileUrl->Len() == 0)
+    if (!pFileUrl || pFileUrl->Len() == 0 || !GetDocShell())
         return false;
 
     String aFileUrl = ScGlobal::GetAbsDocName(*pFileUrl, GetDocShell());
                     {
                         case xlExtName:
                         {
-                            /* FIXME: enable this code for #i4385# once 
-                             * external name reference can be stored in ODF, 
-                             * which remains to be done for #i3740#. Until then 
+                            /* FIXME: enable this code for #i4385# once
+                             * external name reference can be stored in ODF,
+                             * which remains to be done for #i3740#. Until then
                              * create a #NAME? token. */
 #if 0
                             sal_uInt16 nFileId;
                             }
                         }
                         break;
-                        
+
                         case xlExtEuroConvert:
                             {
                                 aStack << aPool.Store( ocEuroConvert, String() );
 ConvErr ExcelToSc8::ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
                                        const String& rUrl, const vector<String>& rTabNames )
 {
+    if( !GetDocShell() )
+        return ConvErrNi;
+
     String aFileUrl = ScGlobal::GetAbsDocName(rUrl, GetDocShell());
 
     sal_uInt8               nOp, nByte;
             break;
             case 0x3B:
             {
-                // area reference 
+                // area reference
 				sal_uInt16 nExtTab1, nExtTab2, nRow1, nRow2, nGrbitCol1, nGrbitCol2;
 				rStrm >> nExtTab1 >> nExtTab2 >> nRow1 >> nRow2 >> nGrbitCol1 >> nGrbitCol2;
                 ScSingleRefData& rR1 = aCRD.Ref1;

sc/source/filter/excel/xilink.cxx

 
     if (meType == xlExtName)
     {
-        // TODO: For now, only global external names are supported.  In future 
+        // TODO: For now, only global external names are supported.  In future
         // we should extend this to supporting per-sheet external names.
         if (mnStorageId == 0)
         {
 
 void XclImpSupbook::LoadCachedValues()
 {
-    if (meType != EXC_SBTYPE_EXTERN || GetExtDocOptions().GetDocSettings().mnLinkCnt > 0)
+    if (meType != EXC_SBTYPE_EXTERN || GetExtDocOptions().GetDocSettings().mnLinkCnt > 0 || !GetDocShell())
         return;
 
     String aAbsUrl( ScGlobal::GetAbsDocName(maXclUrl, GetDocShell()) );

sc/source/filter/ftools/ftools.cxx

 
 ScFormatFilterPluginImpl::ScFormatFilterPluginImpl()
 {
-  fprintf (stderr, "loaded\n");
 }
 
 ScFormatFilterPlugin * SAL_CALL ScFilterCreate(void)

sc/source/filter/html/htmlimp.cxx

 
 String ScFormatFilterPluginImpl::GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName )
 {
-    return GetHTMLRangeNameList( pDoc, rOrigName );
+    return ScHTMLImport::GetHTMLRangeNameList( pDoc, rOrigName );
 }
 
 String ScHTMLImport::GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName )

sc/source/filter/xml/XMLStylesExportHelper.cxx

 
 rtl::OUString ScMyValidationsContainer::GetCondition(ScXMLExport& rExport, const ScMyValidation& aValidation)
 {
+    /* ATTENTION! Should the condition to not write sheet::ValidationType_ANY 
+     * ever be changed, adapt the conditional call of 
+     * MarkUsedExternalReferences() in 
+     * ScTableValidationObj::ScTableValidationObj() accordingly! */
 	rtl::OUString sCondition;
 	if (aValidation.aValidationType != sheet::ValidationType_ANY)
 	{

sc/source/filter/xml/xmlexprt.cxx

               itr != itrEnd; ++itr)
         {
             ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, *itr, false);
-            if (!pTable.get())
+            if (!pTable.get() || !pTable->isReferenced())
                 continue;
 
             OUStringBuffer aBuf;
                 SCROW nRow = *itrRow;
                 vector<SCCOL> aCols;
                 pTable->getAllCols(nRow, aCols);
-                for (vector<SCCOL>::const_iterator itrCol = aCols.begin(), itrColEnd = aCols.end();
-                      itrCol != itrColEnd; ++itrCol)
+                if (!aCols.empty())
                 {
-                    SCCOL nCol = *itrCol;
+                    SCCOL nCol = aCols.back();
                     if (nMaxColsUsed <= nCol)
                         nMaxColsUsed = nCol + 1;
                 }

sc/source/filter/xml/xmlexternaltabi.cxx

     for (sal_Int32 i = 1; i < mnRepeatRowCount; ++i)
     {
         // Performance: duplicates of a non-existent row will still not exist. 
-        // Don't find that out that for every cell.
+        // Don't find that out for every cell.
         // External references often are a sparse matrix.
         if (i == 1 && !pTab->hasRow( mrExternalRefInfo.mnRow))
+        {
+            mrExternalRefInfo.mnRow += mnRepeatRowCount;
             return;
+        }
 
         for (sal_Int32 j = 0; j < mrExternalRefInfo.mnCol; ++j)
         {

sc/source/ui/docshell/docsh.cxx

 }
 
 
+ScDocShell::PrepareSaveGuard::PrepareSaveGuard( ScDocShell& rDocShell )
+    : mrDocShell( rDocShell)
+{
+    // DoEnterHandler not here (because of AutoSave), is in ExecuteSave.
+
+    ScChartListenerCollection* pCharts = mrDocShell.aDocument.GetChartListenerCollection();
+    if (pCharts)
+        pCharts->UpdateDirtyCharts();                           // Charts to be updated.
+    mrDocShell.aDocument.StopTemporaryChartLock();
+    if (mrDocShell.pAutoStyleList)
+        mrDocShell.pAutoStyleList->ExecuteAllNow();             // Execute template timeouts now.
+    if (mrDocShell.aDocument.HasExternalRefManager())
+    {
+        ScExternalRefManager* pRefMgr = mrDocShell.aDocument.GetExternalRefManager();
+        if (pRefMgr && pRefMgr->hasExternalData())
+        {
+            pRefMgr->setAllCacheTableReferencedStati( false);
+            mrDocShell.aDocument.MarkUsedExternalReferences();  // Mark tables of external references to be written.
+        }
+    }
+    if (mrDocShell.GetCreateMode()== SFX_CREATE_MODE_STANDARD)
+        mrDocShell.SfxObjectShell::SetVisArea( Rectangle() );   // "Normally" worked on => no VisArea.
+}
+
+ScDocShell::PrepareSaveGuard::~PrepareSaveGuard()
+{
+    if (mrDocShell.aDocument.HasExternalRefManager())
+    {
+        ScExternalRefManager* pRefMgr = mrDocShell.aDocument.GetExternalRefManager();
+        if (pRefMgr && pRefMgr->hasExternalData())
+        {
+            // Prevent accidental data loss due to lack of knowledge.
+            pRefMgr->setAllCacheTableReferencedStati( true);
+        }
+    }
+}
+
+
 BOOL __EXPORT ScDocShell::Save()
 {
 	RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Save" );
 
 	ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
 
-	//	DoEnterHandler hier nicht (wegen AutoSave), ist im ExecuteSave
-
-	ScChartListenerCollection* pCharts = aDocument.GetChartListenerCollection();
-	if (pCharts)
-		pCharts->UpdateDirtyCharts();					// Charts, die noch upgedated werden muessen
-    aDocument.StopTemporaryChartLock();
-	if (pAutoStyleList)
-		pAutoStyleList->ExecuteAllNow();				// Vorlagen-Timeouts jetzt ausfuehren
-	if (GetCreateMode()== SFX_CREATE_MODE_STANDARD)
-        SfxObjectShell::SetVisArea( Rectangle() );     // normal bearbeitet -> keine VisArea
+    PrepareSaveGuard aPrepareGuard( *this);
 
 	//	wait cursor is handled with progress bar
     BOOL bRet = SfxObjectShell::Save();
 
 	ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
 
-	//	DoEnterHandler hier nicht (wegen AutoSave), ist im ExecuteSave
-
-	ScChartListenerCollection* pCharts = aDocument.GetChartListenerCollection();
-	if (pCharts)
-		pCharts->UpdateDirtyCharts();					// Charts, die noch upgedated werden muessen
-    aDocument.StopTemporaryChartLock();
-	if (pAutoStyleList)
-		pAutoStyleList->ExecuteAllNow();				// Vorlagen-Timeouts jetzt ausfuehren
-	if (GetCreateMode()== SFX_CREATE_MODE_STANDARD)
-        SfxObjectShell::SetVisArea( Rectangle() );     // normal bearbeitet -> keine VisArea
+    PrepareSaveGuard aPrepareGuard( *this);
 
 	//	wait cursor is handled with progress bar
     BOOL bRet = SfxObjectShell::SaveAs( rMedium );

sc/source/ui/docshell/externalrefmgr.cxx

 // ============================================================================
 
 ScExternalRefCache::Table::Table()
+    : mbReferenced( true)   // Prevent accidental data loss due to lack of knowledge.
 {
 }
 
 {
 }
 
+void ScExternalRefCache::Table::setReferenced( bool bReferenced )
+{
+    mbReferenced = bReferenced;
+}
+
+bool ScExternalRefCache::Table::isReferenced() const
+{
+    return mbReferenced;
+}
+
 void ScExternalRefCache::Table::setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex)
 {
     using ::std::pair;
     return pDoc ? pDoc->maTables.size() : 0;
 }
 
+bool ScExternalRefCache::setCacheDocReferenced( sal_uInt16 nFileId )
+{
+    DocItem* pDocItem = getDocItem(nFileId);
+    if (!pDocItem)
+        return areAllCacheTablesReferenced();
+
+    for (::std::vector<TableTypeRef>::iterator itrTab = pDocItem->maTables.begin();
+            itrTab != pDocItem->maTables.end(); ++itrTab)
+    {
+        if ((*itrTab).get())
+            (*itrTab)->setReferenced( true);
+    }
+    addCacheDocToReferenced( nFileId);
+    return areAllCacheTablesReferenced();
+}
+
+bool ScExternalRefCache::setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName )
+{
+    size_t nIndex = 0;
+    TableTypeRef pTab = getCacheTable( nFileId, rTabName, false, &nIndex);
+    if (pTab.get())
+    {
+        if (!pTab->isReferenced())
+        {
+            pTab->setReferenced( true);
+            addCacheTableToReferenced( nFileId, nIndex);
+        }
+    }
+    return areAllCacheTablesReferenced();
+}
+
+void ScExternalRefCache::setAllCacheTableReferencedStati( bool bReferenced )
+{
+    if (bReferenced)
+    {
+        maReferenced.reset(0);
+        for (DocDataType::iterator itrDoc = maDocs.begin(); itrDoc != maDocs.end(); ++itrDoc)
+        {
+            ScExternalRefCache::DocItem& rDocItem = (*itrDoc).second;
+            for (::std::vector<TableTypeRef>::iterator itrTab = rDocItem.maTables.begin();
+                    itrTab != rDocItem.maTables.end(); ++itrTab)
+            {
+                if ((*itrTab).get())
+                    (*itrTab)->setReferenced( true);
+            }
+        }
+    }
+    else
+    {
+        size_t nDocs = 0;
+        for (DocDataType::const_iterator itrDoc = maDocs.begin(); itrDoc != maDocs.end(); ++itrDoc)
+        {
+            if (nDocs <= (*itrDoc).first)
+                nDocs  = (*itrDoc).first + 1;
+        }
+        maReferenced.reset( nDocs);
+
+        for (DocDataType::iterator itrDoc = maDocs.begin(); itrDoc != maDocs.end(); ++itrDoc)
+        {
+            ScExternalRefCache::DocItem& rDocItem = (*itrDoc).second;
+            sal_uInt16 nFileId = (*itrDoc).first;
+            size_t nTables = rDocItem.maTables.size();
+            ReferencedStatus::DocReferenced & rDocReferenced = maReferenced.maDocs[nFileId];
+            // All referenced => non-existing tables evaluate as completed.
+            rDocReferenced.maTables.resize( nTables, true);
+            for (size_t i=0; i < nTables; ++i)
+            {
+                TableTypeRef & xTab = rDocItem.maTables[i];
+                if (xTab.get())
+                {
+                    xTab->setReferenced( false);
+                    rDocReferenced.maTables[i] = false;
+                    rDocReferenced.mbAllTablesReferenced = false;
+                }
+            }
+        }
+    }
+}
+
+void ScExternalRefCache::addCacheTableToReferenced( sal_uInt16 nFileId, size_t nIndex )
+{
+    if (nFileId >= maReferenced.maDocs.size())
+        return;
+
+    ::std::vector<bool> & rTables = maReferenced.maDocs[nFileId].maTables;
+    size_t nTables = rTables.size();
+    if (nIndex >= nTables)
+        return;
+
+    if (!rTables[nIndex])
+    {
+        rTables[nIndex] = true;
+        size_t i = 0;
+        while (i < nTables && rTables[i])
+            ++i;
+        if (i == nTables)
+        {
+            maReferenced.maDocs[nFileId].mbAllTablesReferenced = true;
+            maReferenced.checkAllDocs();
+        }
+    }
+}
+
+void ScExternalRefCache::addCacheDocToReferenced( sal_uInt16 nFileId )
+{
+    if (nFileId >= maReferenced.maDocs.size())
+        return;
+
+    if (!maReferenced.maDocs[nFileId].mbAllTablesReferenced)
+    {
+        ::std::vector<bool> & rTables = maReferenced.maDocs[nFileId].maTables;
+        size_t nSize = rTables.size();
+        for (size_t i=0; i < nSize; ++i)
+            rTables[i] = true;
+        maReferenced.maDocs[nFileId].mbAllTablesReferenced = true;
+        maReferenced.checkAllDocs();
+    }
+}
+
+bool ScExternalRefCache::areAllCacheTablesReferenced() const
+{
+    return maReferenced.mbAllReferenced;
+}
+
+ScExternalRefCache::ReferencedStatus::ReferencedStatus() :
+    mbAllReferenced(false)
+{
+    reset(0);
+}
+
+ScExternalRefCache::ReferencedStatus::ReferencedStatus( size_t nDocs ) :
+    mbAllReferenced(false)
+{
+    reset( nDocs);
+}
+
+void ScExternalRefCache::ReferencedStatus::reset( size_t nDocs )
+{
+    if (nDocs)
+    {
+        mbAllReferenced = false;
+        DocReferencedVec aRefs( nDocs);
+        maDocs.swap( aRefs);
+    }
+    else
+    {
+        mbAllReferenced = true;
+        DocReferencedVec aRefs;
+        maDocs.swap( aRefs);
+    }
+}
+
+void ScExternalRefCache::ReferencedStatus::checkAllDocs()
+{
+    for (DocReferencedVec::const_iterator itr = maDocs.begin(); itr != maDocs.end(); ++itr)
+    {
+        if (!(*itr).mbAllTablesReferenced)
+            return;
+    }
+    mbAllReferenced = true;
+}
+
 ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const
 {
     DocItem* pDoc = getDocItem(nFileId);
 }
 
 ScExternalRefManager::ScExternalRefManager(ScDocument* pDoc) :
-    mpDoc(pDoc)
+    mpDoc(pDoc),
+    bInReferenceMarking(false)
 {
     maSrcDocTimer.SetTimeoutHdl( LINK(this, ScExternalRefManager, TimeOutHdl) );
     maSrcDocTimer.SetTimeout(SRCDOC_SCAN_INTERVAL);
     return static_cast< sal_uInt16 >( maSrcFiles.size() );
 }
 
+bool ScExternalRefManager::markUsedByLinkListeners()
+{
+    bool bAllMarked = false;
+    for (LinkListenerMap::const_iterator itr = maLinkListeners.begin();
+            itr != maLinkListeners.end() && !bAllMarked; ++itr)
+    {
+        if (!(*itr).second.empty())
+            bAllMarked = maRefCache.setCacheDocReferenced( (*itr).first);
+        /* TODO: LinkListeners should remember the table they're listening to. 
+         * As is, listening to one table will mark all tables of the document 
+         * being referenced. */
+    }
+    return bAllMarked;
+}
+
+bool ScExternalRefManager::setCacheDocReferenced( sal_uInt16 nFileId )
+{
+    return maRefCache.setCacheDocReferenced( nFileId);
+}
+
+bool ScExternalRefManager::setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName )
+{
+    return maRefCache.setCacheTableReferenced( nFileId, rTabName);
+}
+
+void ScExternalRefManager::setAllCacheTableReferencedStati( bool bReferenced )
+{
+    bInReferenceMarking = !bReferenced;
+    maRefCache.setAllCacheTableReferencedStati( bReferenced );
+}
+
 void ScExternalRefManager::storeRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScTokenArray& rArray)
 {
     ScExternalRefCache::TokenArrayRef pArray(rArray.Clone());

sc/source/ui/inc/docsh.hxx

 	SC_DLLPRIVATE void			InitOptions();
 	SC_DLLPRIVATE void			ResetDrawObjectShell();
 
+    // SUNWS needs a forward declared friend, otherwise types and members
+    // of the outer class are not accessible.
+    class PrepareSaveGuard;
+    friend class ScDocShell::PrepareSaveGuard;
+    /** Do things that need to be done before saving to our own format and 
+        necessary clean ups in dtor. */
+    class PrepareSaveGuard
+    {
+        public:
+            explicit    PrepareSaveGuard( ScDocShell & rDocShell );
+                        ~PrepareSaveGuard();
+        private:
+                        ScDocShell & mrDocShell;
+    };
+
     SC_DLLPRIVATE BOOL            LoadXML( SfxMedium* pMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& );
     SC_DLLPRIVATE BOOL            SaveXML( SfxMedium* pMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& );
 	SC_DLLPRIVATE SCTAB			GetSaveTab();

sc/source/ui/unoobj/fmtuno.cxx

 			const ScConditionalFormat* pFormat = pList->GetFormat( nKey );
 			if (pFormat)
 			{
+                // During save to XML.
+                if (pDoc->IsInExternalReferenceMarking())
+                    pFormat->MarkUsedExternalReferences();
+
 				USHORT nEntryCount = pFormat->Count();
 				for (USHORT i=0; i<nEntryCount; i++)
 				{
 			bShowError = pData->GetErrMsg( aErrorTitle, aErrorMessage, eStyle );
             nErrorStyle = sal::static_int_cast<USHORT>( eStyle );
 
+            // During save to XML, sheet::ValidationType_ANY formulas are not 
+            // saved, even if in the list, see  
+            // ScMyValidationsContainer::GetCondition(), so shall not mark 
+            // anything in use.
+            if (nValMode != SC_VALID_ANY && pDoc->IsInExternalReferenceMarking())
+                pData->MarkUsedExternalReferences();
+
 			bFound = TRUE;
 		}
 	}

svx/source/form/fmtextcontrolshell.cxx

 
         SfxItemPool* pPool = EditEngine::CreatePool();
         pPool->FreezeIdRanges();
-        SfxItemSet aPureItems( *pPool );
+        ::std::auto_ptr< SfxItemSet > pPureItems( new SfxItemSet( *pPool ) );
 
         // put the current states of the items into the set
-        SfxAllItemSet aCurrentItems( aPureItems );
-        transferFeatureStatesToItemSet( m_aControlFeatures, aCurrentItems );
+        ::std::auto_ptr< SfxAllItemSet > pCurrentItems( new SfxAllItemSet( *pPureItems ) );
+        transferFeatureStatesToItemSet( m_aControlFeatures, *pCurrentItems );
 
         // additional items, which we are not responsible for at the SfxShell level,
         // but which need to be forwarded to the dialog, anyway
         ControlFeatures aAdditionalFestures;
         fillFeatureDispatchers( m_xActiveControl, pDialogSlots, aAdditionalFestures );
-        transferFeatureStatesToItemSet( aAdditionalFestures, aCurrentItems, true );
+        transferFeatureStatesToItemSet( aAdditionalFestures, *pCurrentItems, true );
 
         ::std::auto_ptr< SfxTabDialog > pDialog ( _eSet == eCharAttribs
-                                                ? static_cast< SfxTabDialog* >( new TextControlCharAttribDialog( NULL, aCurrentItems, *pFontList ) )
-                                                : static_cast< SfxTabDialog* >( new TextControlParaAttribDialog( NULL, aCurrentItems ) ) );
+                                                ? static_cast< SfxTabDialog* >( new TextControlCharAttribDialog( NULL, *pCurrentItems, *pFontList ) )
+                                                : static_cast< SfxTabDialog* >( new TextControlParaAttribDialog( NULL, *pCurrentItems ) ) );
         if ( RET_OK == pDialog->Execute() )
         {
             const SfxItemSet& rModifiedItems = *pDialog->GetOutputItemSet();
                         Sequence< PropertyValue > aArgs;
                         // temporarily put the modified item into a "clean" set,
                         // and let TransformItems calc the respective UNO parameters
-                        aPureItems.Put( *pModifiedItem );
-                        TransformItems( nSlotForItemSet, aPureItems, aArgs );
-                        aPureItems.ClearItem( nWhich );
+                        pPureItems->Put( *pModifiedItem );
+                        TransformItems( nSlotForItemSet, *pPureItems, aArgs );
+                        pPureItems->ClearItem( nWhich );
 
                         if  (   ( nSlotForItemSet == SID_ATTR_PARA_HANGPUNCTUATION )
                             ||  ( nSlotForItemSet == SID_ATTR_PARA_FORBIDDEN_RULES )
             _rReq.Done( rModifiedItems );
         }
 
+        pDialog.reset();
+        pCurrentItems.reset();
+        pPureItems.reset();
         SfxItemPool::Free(pPool);
     }
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.