summaryrefslogtreecommitdiff
path: root/sc/source/ui/docshell/externalrefmgr.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/docshell/externalrefmgr.cxx')
-rw-r--r--sc/source/ui/docshell/externalrefmgr.cxx207
1 files changed, 206 insertions, 1 deletions
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());