summaryrefslogtreecommitdiff
path: root/sc/source/ui/docshell
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-05-19 23:42:05 -0400
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-05-21 13:25:19 -0400
commit1b243b14e9715b7b7da6359b5b752ee6d8278731 (patch)
treec6cf493fc59c6e3da70711405457459e758f0cb3 /sc/source/ui/docshell
parentdea4a3b9d7182700abeb4dc756a24a9e8dea8474 (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.cxx85
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)