diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-05-19 23:42:05 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-05-21 13:25:19 -0400 |
commit | 1b243b14e9715b7b7da6359b5b752ee6d8278731 (patch) | |
tree | c6cf493fc59c6e3da70711405457459e758f0cb3 /sc/source/ui/docshell | |
parent | dea4a3b9d7182700abeb4dc756a24a9e8dea8474 (diff) |
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
Diffstat (limited to 'sc/source/ui/docshell')
-rw-r--r-- | sc/source/ui/docshell/externalrefmgr.cxx | 85 |
1 files changed, 60 insertions, 25 deletions
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index 25dfe63ae1f7..549549a64c42 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -136,17 +136,18 @@ struct UpdateFormulaCell : public unary_function<ScFormulaCell*, void> // Check to make sure the cell really contains ocExternalRef. // External names, external cell and range references all have a // ocExternalRef token. - const ScTokenArray* pCode = pCell->GetCode(); + ScTokenArray* pCode = pCell->GetCode(); if (!pCode->HasExternalRef()) return; - ScTokenArray* pArray = pCell->GetCode(); - if (pArray) + if (pCode->GetCodeError()) + { // 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(); } }; @@ -1258,7 +1259,8 @@ void ScExternalRefLink::Closed() if (pCurFile->equals(aFile)) { // Refresh the current source document. - pMgr->refreshNames(mnFileId); + if (!pMgr->refreshSrcDocument(mnFileId)) + return ERROR_GENERAL; } else { @@ -2234,17 +2236,7 @@ ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId) return NULL; } - if (maDocShells.empty()) - { - // 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; + return cacheNewDocShell(nFileId, aSrcDoc); } SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUString& rFilter) @@ -2321,7 +2313,12 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUSt } 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 OUString aNew = ScDocumentLoader::GetOptions(*pNewShell->GetMedium()); @@ -2332,6 +2329,19 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUSt 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 { if (rFile.isEmpty()) @@ -2548,18 +2558,43 @@ void ScExternalRefManager::clearCache(sal_uInt16 nFileId) maRefCache.clearCache(nFileId); } -void ScExternalRefManager::refreshNames(sal_uInt16 nFileId) +bool ScExternalRefManager::refreshSrcDocument(sal_uInt16 nFileId) { - clearCache(nFileId); - lcl_removeByFileId(nFileId, maDocShells); + OUString aFilter; + SfxObjectShellRef xDocShell; + try + { + xDocShell = loadSrcDocument(nFileId, aFilter); + } + catch ( const css::uno::Exception& ) {} - if (maDocShells.empty()) - maSrcDocTimer.Stop(); + if (!xDocShell.Is()) + // 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. refreshAllRefCells(nFileId); notifyAllLinkListeners(nFileId, LINK_MODIFIED); + + return true; } void ScExternalRefManager::breakLink(sal_uInt16 nFileId) @@ -2615,7 +2650,7 @@ void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const OUString& rNe maSrcFiles[nFileId].maFilterName = rNewFilter; maSrcFiles[nFileId].maFilterOptions = OUString(); } - refreshNames(nFileId); + refreshSrcDocument(nFileId); } void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const OUString& rRelUrl) |