summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvo Hinkelmann <ihi@openoffice.org>2009-04-02 15:00:15 +0000
committerIvo Hinkelmann <ihi@openoffice.org>2009-04-02 15:00:15 +0000
commit760a525883ee333624157487b0b8cb7c7e820a10 (patch)
treebceef256789aa71e085462a2549d555d4fb93b3b
parentc5346586d66eeede35498b10c86641b7b2f919b5 (diff)
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
-rw-r--r--sc/inc/cell.hxx1
-rw-r--r--sc/inc/column.hxx1
-rw-r--r--sc/inc/conditio.hxx8
-rw-r--r--sc/inc/document.hxx4
-rw-r--r--sc/inc/externalrefmgr.hxx75
-rw-r--r--sc/inc/table.hxx1
-rw-r--r--sc/inc/validat.hxx4
-rw-r--r--sc/source/core/data/cell.cxx7
-rw-r--r--sc/source/core/data/column.cxx16
-rw-r--r--sc/source/core/data/conditio.cxx30
-rw-r--r--sc/source/core/data/documen3.cxx23
-rw-r--r--sc/source/core/data/documen4.cxx38
-rw-r--r--sc/source/core/data/table2.cxx12
-rw-r--r--sc/source/core/data/validat.cxx9
-rw-r--r--sc/source/core/tool/compiler.cxx31
-rw-r--r--sc/source/filter/excel/excform8.cxx15
-rw-r--r--sc/source/filter/excel/xilink.cxx4
-rw-r--r--sc/source/filter/ftools/ftools.cxx1
-rw-r--r--sc/source/filter/html/htmlimp.cxx2
-rw-r--r--sc/source/filter/xml/XMLStylesExportHelper.cxx4
-rw-r--r--sc/source/filter/xml/xmlexprt.cxx7
-rw-r--r--sc/source/filter/xml/xmlexternaltabi.cxx5
-rw-r--r--sc/source/ui/docshell/docsh.cxx60
-rw-r--r--sc/source/ui/docshell/externalrefmgr.cxx207
-rw-r--r--sc/source/ui/inc/docsh.hxx15
-rw-r--r--sc/source/ui/unoobj/fmtuno.cxx11
26 files changed, 537 insertions, 54 deletions
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 186a40d15..656d58905 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -381,6 +381,7 @@ public:
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; }
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index f36b0c276..eff91ed76 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -279,6 +279,7 @@ public:
void CalcAfterLoad();
void CompileAll();
void CompileXML( ScProgress& rProgress );
+ bool MarkUsedExternalReferences();
void ResetChanged( SCROW nStartRow, SCROW nEndRow );
diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx
index 82d80a0e8..52d791999 100644
--- a/sc/inc/conditio.hxx
+++ b/sc/inc/conditio.hxx
@@ -149,6 +149,8 @@ public:
void SourceChanged( const ScAddress& rChanged );
+ bool MarkUsedExternalReferences() const;
+
protected:
virtual void DataChanged( const ScRange* pModified ) const;
ScDocument* GetDocument() const { return pDoc; }
@@ -240,6 +242,8 @@ public:
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; }
@@ -278,6 +282,10 @@ public:
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
};
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index f0d682547..882032006 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -606,7 +606,11 @@ public:
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;
diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index d20840f9d..dfb814596 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -138,12 +138,18 @@ public:
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;
@@ -202,6 +208,45 @@ public:
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);
@@ -434,6 +479,33 @@ public:
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(
@@ -618,6 +690,9 @@ private:
/** original source file index. */
::std::vector<SrcFileData> maSrcFiles;
+ /** Status whether in reference marking state. See isInReferenceMarking(). */
+ bool bInReferenceMarking;
+
AutoTimer maSrcDocTimer;
DECL_LINK(TimeOutHdl, AutoTimer*);
};
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 71f443d40..ba4b02238 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -376,6 +376,7 @@ public:
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,
diff --git a/sc/inc/validat.hxx b/sc/inc/validat.hxx
index 7babc68a9..44b739007 100644
--- a/sc/inc/validat.hxx
+++ b/sc/inc/validat.hxx
@@ -205,6 +205,10 @@ public:
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
};
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index c85a1e339..07f6018aa 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -53,6 +53,7 @@
#include "editutil.hxx"
#include "recursionhelper.hxx"
#include "postit.hxx"
+#include "externalrefmgr.hxx"
#include <svx/editobj.hxx>
#include <svtools/intitem.hxx>
#include <svx/flditem.hxx>
@@ -1120,6 +1121,12 @@ void ScFormulaCell::CalcAfterLoad()
}
+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.
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index cdf3ef9bf..a05a1f701 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2096,6 +2096,22 @@ void ScColumn::CalcAfterLoad()
}
+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)
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index ada7440eb..e1097daae 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -1111,6 +1111,18 @@ void ScConditionEntry::DataChanged( const ScRange* /* pModified */ ) const
// 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,
@@ -1458,6 +1470,14 @@ void ScConditionalFormat::SourceChanged( const ScAddress& rAddr )
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) :
@@ -1555,5 +1575,11 @@ void ScConditionalFormatList::SourceChanged( const ScAddress& rAddr )
(*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;
+}
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 9566d7500..f40768aa4 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -484,6 +484,29 @@ ScExternalRefManager* ScDocument::GetExternalRefManager()
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;
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index a1dfee536..7b6b5be95 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -38,6 +38,7 @@
#include <svtools/intitem.hxx>
#include <svtools/zforlist.hxx>
#include <vcl/sound.hxx>
+#include <formula/token.hxx>
#include "document.hxx"
#include "table.hxx"
@@ -56,6 +57,9 @@
#include "progress.hxx"
#include "paramisc.hxx"
#include "compiler.hxx"
+#include "externalrefmgr.hxx"
+
+using namespace formula;
// -----------------------------------------------------------------------
@@ -290,6 +294,40 @@ void ScDocument::InsertTableOp(const ScTabOpParam& rParam, // Mehrfachopera
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
{
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index acea6051b..257fb5af4 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1072,13 +1072,23 @@ void ScTable::CompileXML( ScProgress& rProgress )
}
}
-
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();
diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
index eb0ba7f47..d08d84a49 100644
--- a/sc/source/core/data/validat.cxx
+++ b/sc/source/core/data/validat.cxx
@@ -939,6 +939,15 @@ void ScValidationDataList::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
(*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
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 08eceeb83..8af7c1d42 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -1125,24 +1125,25 @@ struct ConventionOOO_A1 : public Convention_A1
rBuffer.append(sal_Unicode(':'));
- // 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);
- break;
- }
-
String aLastTabName;
- if (!lcl_getLastTabName(aLastTabName, rTabName, aTabNames, aRef))
+ bool bDisplayTabName = (aRef.Ref1.nTab != aRef.Ref2.nTab);
+ if (bDisplayTabName)
{
- rBuffer.append(aLastTabName);
- DBG_ERROR( "ConventionOOO_A1::makeExternalRefStrImpl: sheet name not found");
- 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.
+ }
}
- 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);
diff --git a/sc/source/filter/excel/excform8.cxx b/sc/source/filter/excel/excform8.cxx
index 205f803be..015f06d43 100644
--- a/sc/source/filter/excel/excform8.cxx
+++ b/sc/source/filter/excel/excform8.cxx
@@ -68,7 +68,7 @@ ExcelToSc8::~ExcelToSc8()
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());
@@ -638,9 +638,9 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
{
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;
@@ -679,7 +679,7 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
}
}
break;
-
+
case xlExtEuroConvert:
{
aStack << aPool.Store( ocEuroConvert, String() );
@@ -1222,6 +1222,9 @@ ConvErr ExcelToSc8::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sa
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;
@@ -1314,7 +1317,7 @@ ConvErr ExcelToSc8::ConvertExternName( const ScTokenArray*& rpArray, XclImpStrea
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;
diff --git a/sc/source/filter/excel/xilink.cxx b/sc/source/filter/excel/xilink.cxx
index 83907fca0..16a3edf46 100644
--- a/sc/source/filter/excel/xilink.cxx
+++ b/sc/source/filter/excel/xilink.cxx
@@ -322,7 +322,7 @@ XclImpExtName::XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm
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)
{
@@ -548,7 +548,7 @@ sal_uInt16 XclImpSupbook::GetTabCount() const
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()) );
diff --git a/sc/source/filter/ftools/ftools.cxx b/sc/source/filter/ftools/ftools.cxx
index c92547b31..98faeb9f0 100644
--- a/sc/source/filter/ftools/ftools.cxx
+++ b/sc/source/filter/ftools/ftools.cxx
@@ -396,7 +396,6 @@ bool ScfTools::GetHTMLNameFromName( const String& rSource, String& rName )
ScFormatFilterPluginImpl::ScFormatFilterPluginImpl()
{
- fprintf (stderr, "loaded\n");
}
ScFormatFilterPlugin * SAL_CALL ScFilterCreate(void)
diff --git a/sc/source/filter/html/htmlimp.cxx b/sc/source/filter/html/htmlimp.cxx
index 443dfed67..79154d40a 100644
--- a/sc/source/filter/html/htmlimp.cxx
+++ b/sc/source/filter/html/htmlimp.cxx
@@ -217,7 +217,7 @@ void ScHTMLImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor )
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 )
diff --git a/sc/source/filter/xml/XMLStylesExportHelper.cxx b/sc/source/filter/xml/XMLStylesExportHelper.cxx
index fda3d2052..6d7ea020d 100644
--- a/sc/source/filter/xml/XMLStylesExportHelper.cxx
+++ b/sc/source/filter/xml/XMLStylesExportHelper.cxx
@@ -194,6 +194,10 @@ sal_Bool ScMyValidationsContainer::AddValidation(const uno::Any& aTempAny,
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)
{
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 4346d2178..728a90df9 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -3325,7 +3325,7 @@ void ScXMLExport::WriteExternalRefCaches()
itr != itrEnd; ++itr)
{
ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, *itr, false);
- if (!pTable.get())
+ if (!pTable.get() || !pTable->isReferenced())
continue;
OUStringBuffer aBuf;
@@ -3368,10 +3368,9 @@ void ScXMLExport::WriteExternalRefCaches()
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;
}
diff --git a/sc/source/filter/xml/xmlexternaltabi.cxx b/sc/source/filter/xml/xmlexternaltabi.cxx
index 540d3f3e1..a79b379df 100644
--- a/sc/source/filter/xml/xmlexternaltabi.cxx
+++ b/sc/source/filter/xml/xmlexternaltabi.cxx
@@ -166,10 +166,13 @@ void ScXMLExternalRefRowContext::EndElement()
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)
{
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index a3986ada5..2785abfab 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -1265,22 +1265,51 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
}
+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();
@@ -1296,16 +1325,7 @@ BOOL __EXPORT ScDocShell::SaveAs( SfxMedium& rMedium )
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 );
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 8f56581c4..8634ea47d 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -143,6 +143,7 @@ private:
// ============================================================================
ScExternalRefCache::Table::Table()
+ : mbReferenced( true) // Prevent accidental data loss due to lack of knowledge.
{
}
@@ -150,6 +151,16 @@ ScExternalRefCache::Table::~Table()
{
}
+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;
@@ -702,6 +713,168 @@ size_t ScExternalRefCache::getCacheTableCount(sal_uInt16 nFileId) const
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);
@@ -987,7 +1160,8 @@ static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, const ScRange&
}
ScExternalRefManager::ScExternalRefManager(ScDocument* pDoc) :
- mpDoc(pDoc)
+ mpDoc(pDoc),
+ bInReferenceMarking(false)
{
maSrcDocTimer.SetTimeoutHdl( LINK(this, ScExternalRefManager, TimeOutHdl) );
maSrcDocTimer.SetTimeout(SRCDOC_SCAN_INTERVAL);
@@ -1278,6 +1452,37 @@ sal_uInt16 ScExternalRefManager::getExternalFileCount() const
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());
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
index e70071b49..348beb0d7 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -135,6 +135,21 @@ class SC_DLLPUBLIC ScDocShell: public SfxObjectShell, public SfxListener
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();
diff --git a/sc/source/ui/unoobj/fmtuno.cxx b/sc/source/ui/unoobj/fmtuno.cxx
index ffc293705..857295511 100644
--- a/sc/source/ui/unoobj/fmtuno.cxx
+++ b/sc/source/ui/unoobj/fmtuno.cxx
@@ -147,6 +147,10 @@ ScTableConditionalFormat::ScTableConditionalFormat(ScDocument* pDoc, ULONG nKey,
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++)
{
@@ -624,6 +628,13 @@ ScTableValidationObj::ScTableValidationObj(ScDocument* pDoc, ULONG nKey,
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;
}
}