Kaydet (Commit) 1b243b14 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

cp#1000072: Load external documents when refreshing caches.

Rather than just clearing the existing caches and loading the external
documents on demand as the formula cells gets re-calculated.  This has two
advantages: 1) when the loading itself fails, we can keep the existing cache
rather than turning all affected cells to error cells, and 2) this prevents
on-demand loading after the external linkes get refreshed, which can make
scrolling very slow & painful.

Change-Id: Ie8243f6f94c5e477964413ab83f6b4b746fe3220
üst dea4a3b9
...@@ -599,7 +599,7 @@ public: ...@@ -599,7 +599,7 @@ public:
const OUString* getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const; const OUString* getRealTableName(sal_uInt16 nFileId, const OUString& rTabName) const;
const OUString* getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const; const OUString* getRealRangeName(sal_uInt16 nFileId, const OUString& rRangeName) const;
void clearCache(sal_uInt16 nFileId); void clearCache(sal_uInt16 nFileId);
void refreshNames(sal_uInt16 nFileId); bool refreshSrcDocument(sal_uInt16 nFileId);
void breakLink(sal_uInt16 nFileId); void breakLink(sal_uInt16 nFileId);
void switchSrcFile(sal_uInt16 nFileId, const OUString& rNewFile, const OUString& rNewFilter); void switchSrcFile(sal_uInt16 nFileId, const OUString& rNewFile, const OUString& rNewFilter);
...@@ -738,6 +738,11 @@ private: ...@@ -738,6 +738,11 @@ private:
ScDocument* getSrcDocument(sal_uInt16 nFileId); ScDocument* getSrcDocument(sal_uInt16 nFileId);
SfxObjectShellRef loadSrcDocument(sal_uInt16 nFileId, OUString& rFilter); SfxObjectShellRef loadSrcDocument(sal_uInt16 nFileId, OUString& rFilter);
/**
* Caller must ensure that the passed shell is not already stored.
*/
ScDocument* cacheNewDocShell( sal_uInt16 nFileId, SrcShell& rSrcShell );
void maybeLinkExternalFile(sal_uInt16 nFileId); void maybeLinkExternalFile(sal_uInt16 nFileId);
/** /**
......
...@@ -136,17 +136,18 @@ struct UpdateFormulaCell : public unary_function<ScFormulaCell*, void> ...@@ -136,17 +136,18 @@ struct UpdateFormulaCell : public unary_function<ScFormulaCell*, void>
// Check to make sure the cell really contains ocExternalRef. // Check to make sure the cell really contains ocExternalRef.
// External names, external cell and range references all have a // External names, external cell and range references all have a
// ocExternalRef token. // ocExternalRef token.
const ScTokenArray* pCode = pCell->GetCode(); ScTokenArray* pCode = pCell->GetCode();
if (!pCode->HasExternalRef()) if (!pCode->HasExternalRef())
return; return;
ScTokenArray* pArray = pCell->GetCode(); if (pCode->GetCodeError())
if (pArray) {
// Clear the error code, or a cell with error won't get re-compiled. // Clear the error code, or a cell with error won't get re-compiled.
pArray->SetCodeError(0); pCode->SetCodeError(0);
pCell->SetCompile(true);
pCell->CompileTokenArray();
}
pCell->SetCompile(true);
pCell->CompileTokenArray();
pCell->SetDirty(); pCell->SetDirty();
} }
}; };
...@@ -1258,7 +1259,8 @@ void ScExternalRefLink::Closed() ...@@ -1258,7 +1259,8 @@ void ScExternalRefLink::Closed()
if (pCurFile->equals(aFile)) if (pCurFile->equals(aFile))
{ {
// Refresh the current source document. // Refresh the current source document.
pMgr->refreshNames(mnFileId); if (!pMgr->refreshSrcDocument(mnFileId))
return ERROR_GENERAL;
} }
else else
{ {
...@@ -2234,17 +2236,7 @@ ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId) ...@@ -2234,17 +2236,7 @@ ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId)
return NULL; return NULL;
} }
if (maDocShells.empty()) return cacheNewDocShell(nFileId, aSrcDoc);
{
// If this is the first source document insertion, start up the timer.
maSrcDocTimer.Start();
}
maDocShells.insert(DocShellMap::value_type(nFileId, aSrcDoc));
SfxObjectShell* p = aSrcDoc.maShell;
ScDocument* pSrcDoc = static_cast<ScDocShell*>(p)->GetDocument();
initDocInCache(maRefCache, pSrcDoc, nFileId);
return pSrcDoc;
} }
SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUString& rFilter) SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUString& rFilter)
...@@ -2321,7 +2313,12 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUSt ...@@ -2321,7 +2313,12 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUSt
} }
pExtOptNew->GetDocSettings().mnLinkCnt = nLinkCount + 1; pExtOptNew->GetDocSettings().mnLinkCnt = nLinkCount + 1;
pNewShell->DoLoad(pMedium.release()); if (!pNewShell->DoLoad(pMedium.release()))
{
aRef->DoClose();
aRef.Clear();
return aRef;
}
// with UseInteractionHandler, options may be set by dialog during DoLoad // with UseInteractionHandler, options may be set by dialog during DoLoad
OUString aNew = ScDocumentLoader::GetOptions(*pNewShell->GetMedium()); OUString aNew = ScDocumentLoader::GetOptions(*pNewShell->GetMedium());
...@@ -2332,6 +2329,19 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUSt ...@@ -2332,6 +2329,19 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUSt
return aRef; return aRef;
} }
ScDocument* ScExternalRefManager::cacheNewDocShell( sal_uInt16 nFileId, SrcShell& rSrcShell )
{
if (maDocShells.empty())
// If this is the first source document insertion, start up the timer.
maSrcDocTimer.Start();
maDocShells.insert(DocShellMap::value_type(nFileId, rSrcShell));
SfxObjectShell& rShell = *rSrcShell.maShell;
ScDocument* pSrcDoc = static_cast<ScDocShell&>(rShell).GetDocument();
initDocInCache(maRefCache, pSrcDoc, nFileId);
return pSrcDoc;
}
bool ScExternalRefManager::isFileLoadable(const OUString& rFile) const bool ScExternalRefManager::isFileLoadable(const OUString& rFile) const
{ {
if (rFile.isEmpty()) if (rFile.isEmpty())
...@@ -2548,18 +2558,43 @@ void ScExternalRefManager::clearCache(sal_uInt16 nFileId) ...@@ -2548,18 +2558,43 @@ void ScExternalRefManager::clearCache(sal_uInt16 nFileId)
maRefCache.clearCache(nFileId); maRefCache.clearCache(nFileId);
} }
void ScExternalRefManager::refreshNames(sal_uInt16 nFileId) bool ScExternalRefManager::refreshSrcDocument(sal_uInt16 nFileId)
{ {
clearCache(nFileId); OUString aFilter;
lcl_removeByFileId(nFileId, maDocShells); SfxObjectShellRef xDocShell;
try
{
xDocShell = loadSrcDocument(nFileId, aFilter);
}
catch ( const css::uno::Exception& ) {}
if (maDocShells.empty()) if (!xDocShell.Is())
maSrcDocTimer.Stop(); // Failed to load the document. Bail out.
return false;
// Clear the existing cache, and store the loaded doc shell until it expires.
clearCache(nFileId);
DocShellMap::iterator it = maDocShells.find(nFileId);
if (it != maDocShells.end())
{
it->second.maShell->DoClose();
it->second.maShell = xDocShell;
it->second.maLastAccess = Time(Time::SYSTEM);
}
else
{
SrcShell aSrcDoc;
aSrcDoc.maShell = xDocShell;
aSrcDoc.maLastAccess = Time(Time::SYSTEM);
cacheNewDocShell(nFileId, aSrcDoc);
}
// Update all cells containing names from this source document. // Update all cells containing names from this source document.
refreshAllRefCells(nFileId); refreshAllRefCells(nFileId);
notifyAllLinkListeners(nFileId, LINK_MODIFIED); notifyAllLinkListeners(nFileId, LINK_MODIFIED);
return true;
} }
void ScExternalRefManager::breakLink(sal_uInt16 nFileId) void ScExternalRefManager::breakLink(sal_uInt16 nFileId)
...@@ -2615,7 +2650,7 @@ void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const OUString& rNe ...@@ -2615,7 +2650,7 @@ void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const OUString& rNe
maSrcFiles[nFileId].maFilterName = rNewFilter; maSrcFiles[nFileId].maFilterName = rNewFilter;
maSrcFiles[nFileId].maFilterOptions = OUString(); maSrcFiles[nFileId].maFilterOptions = OUString();
} }
refreshNames(nFileId); refreshSrcDocument(nFileId);
} }
void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const OUString& rRelUrl) void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const OUString& rRelUrl)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment