summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorNiklas Nebel <nn@openoffice.org>2011-02-21 16:27:34 +0100
committerMichael Meeks <michael.meeks@suse.com>2012-12-04 07:17:10 +0000
commit68dad00d0d548f94ae943fa585eb614cb6714d66 (patch)
tree9eb649a855dcf4c2cdeeb83334dd11354e34ff1f /sc
parent02d54922c060a42190bbb5757433fc7189008a33 (diff)
calc66: #i116940# update link URLs after CompileXML, count only
allocated sheet caches in link API Conflicts: sc/inc/externalrefmgr.hxx sc/source/ui/docshell/externalrefmgr.cxx sc/source/ui/unoobj/linkuno.cxx
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/externalrefmgr.hxx9
-rw-r--r--sc/source/core/tool/interpr1.cxx2
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx9
-rw-r--r--sc/source/ui/docshell/externalrefmgr.cxx46
-rw-r--r--sc/source/ui/unoobj/linkuno.cxx36
5 files changed, 58 insertions, 44 deletions
diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index 4b9c42c96fe5..c31f512e56d2 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -255,8 +255,6 @@ public:
void getAllTableNames(sal_uInt16 nFileId, ::std::vector<rtl::OUString>& rTabNames) const;
SCsTAB getTabSpan( sal_uInt16 nFileId, const ::rtl::OUString& rStartTabName, const ::rtl::OUString& rEndTabName ) const;
void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
- bool hasCacheTable(sal_uInt16 nFileId, const ::rtl::OUString& rTabName) const;
- size_t getCacheTableCount(sal_uInt16 nFileId) const;
/**
* Set all tables of a document as referenced, used only during
@@ -501,8 +499,6 @@ public:
*/
void getAllCachedNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
- bool hasCacheTable(sal_uInt16 nFileId, const ::rtl::OUString& rTabName) const;
- size_t getCacheTableCount(sal_uInt16 nFileId) const;
sal_uInt16 getExternalFileCount() const;
/**
@@ -634,6 +630,11 @@ public:
void resetSrcFileData(const ::rtl::OUString& rBaseFileUrl);
/**
+ * Replace the original URL wirh the real URL that was generated from the relative URL.
+ */
+ void updateAbsAfterLoad();
+
+ /**
* Stop tracking a specific formula cell.
*
* @param pCell pointer to cell that formerly contained external
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 32b5747cda28..805562562394 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -2460,7 +2460,7 @@ void ScInterpreter::ScCellExternal()
// For SHEET, No idea what number we should set, but let's always set
// 1 if the external sheet exists, no matter what sheet. Excel does
// the same.
- if (pRefMgr->hasCacheTable(nFileId, aTabName))
+ if (pRefMgr->getCacheTable(nFileId, aTabName, false, NULL).get())
PushInt(1);
else
SetError(errNoName);
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 688000e64138..a15a57baf989 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -71,6 +71,7 @@
#include "rangeutl.hxx"
#include "postit.hxx"
#include "formulaparserpool.hxx"
+#include "externalrefmgr.hxx"
#include <comphelper/extract.hxx>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
@@ -3121,8 +3122,16 @@ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeE
}
GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars
if (pDoc)
+ {
pDoc->CompileXML();
+ // After CompileXML, links must be completely changed to the new URLs.
+ // Otherwise, hasExternalFile for API wouldn't work (#i116940#),
+ // and typing a new formula would create a second link with the same "real" file name.
+ if (pDoc->HasExternalRefManager())
+ pDoc->GetExternalRefManager()->updateAbsAfterLoad();
+ }
+
if (pDoc && GetModel().is())
{
// set "valid stream" flags after loading (before UpdateRowHeights, so changed formula results
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index c0134fd0fca9..144c39676669 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -937,26 +937,6 @@ void ScExternalRefCache::getAllNumberFormats(vector<sal_uInt32>& rNumFmts) const
rNumFmts.swap(aNumFmts);
}
-bool ScExternalRefCache::hasCacheTable(sal_uInt16 nFileId, const OUString& rTabName) const
-{
- DocItem* pDoc = getDocItem(nFileId);
- if (!pDoc)
- return false;
-
- String aUpperName = ScGlobal::pCharClass->uppercase(rTabName);
- vector<TableName>::const_iterator itrBeg = pDoc->maTableNames.begin(), itrEnd = pDoc->maTableNames.end();
- vector<TableName>::const_iterator itr = ::std::find_if(
- itrBeg, itrEnd, TabNameSearchPredicate(aUpperName));
-
- return itr != itrEnd;
-}
-
-size_t ScExternalRefCache::getCacheTableCount(sal_uInt16 nFileId) const
-{
- DocItem* pDoc = getDocItem(nFileId);
- return pDoc ? pDoc->maTables.size() : 0;
-}
-
bool ScExternalRefCache::setCacheDocReferenced( sal_uInt16 nFileId )
{
DocItem* pDocItem = getDocItem(nFileId);
@@ -1547,16 +1527,6 @@ void ScExternalRefManager::getAllCachedNumberFormats(vector<sal_uInt32>& rNumFmt
maRefCache.getAllNumberFormats(rNumFmts);
}
-bool ScExternalRefManager::hasCacheTable(sal_uInt16 nFileId, const OUString& rTabName) const
-{
- return maRefCache.hasCacheTable(nFileId, rTabName);
-}
-
-size_t ScExternalRefManager::getCacheTableCount(sal_uInt16 nFileId) const
-{
- return maRefCache.getCacheTableCount(nFileId);
-}
-
sal_uInt16 ScExternalRefManager::getExternalFileCount() const
{
return static_cast< sal_uInt16 >( maSrcFiles.size() );
@@ -2560,6 +2530,22 @@ void ScExternalRefManager::resetSrcFileData(const OUString& rBaseFileUrl)
}
}
+void ScExternalRefManager::updateAbsAfterLoad()
+{
+ String aOwn( getOwnDocumentName() );
+ for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
+ itr != itrEnd; ++itr)
+ {
+ // update maFileName to the real file name,
+ // to be called when the original name is no longer needed (after CompileXML)
+
+ itr->maybeCreateRealFileName( aOwn );
+ String aReal = itr->maRealFileName;
+ if (aReal.Len())
+ itr->maFileName = aReal;
+ }
+}
+
void ScExternalRefManager::removeRefCell(ScFormulaCell* pCell)
{
for_each(maRefCells.begin(), maRefCells.end(), RemoveFormulaCell(pCell));
diff --git a/sc/source/ui/unoobj/linkuno.cxx b/sc/source/ui/unoobj/linkuno.cxx
index a618287fc5a3..dd8e2714dcf2 100644
--- a/sc/source/ui/unoobj/linkuno.cxx
+++ b/sc/source/ui/unoobj/linkuno.cxx
@@ -1628,10 +1628,17 @@ Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames()
SolarMutexGuard aGuard;
vector<OUString> aTabNames;
mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames);
- size_t n = aTabNames.size();
+
+ // #i116940# be consistent with getByName: include only table names which have a cache already
+ vector<OUString> aValidNames;
+ for (vector<OUString>::iterator aIter = aTabNames.begin(); aIter != aTabNames.end(); ++aIter)
+ if (mpRefMgr->getCacheTable(mnFileId, *aIter, false))
+ aValidNames.push_back(*aIter);
+
+ size_t n = aValidNames.size();
Sequence<OUString> aSeq(n);
for (size_t i = 0; i < n; ++i)
- aSeq[i] = aTabNames[i];
+ aSeq[i] = aValidNames[i];
return aSeq;
}
@@ -1639,25 +1646,34 @@ sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName)
throw (RuntimeException)
{
SolarMutexGuard aGuard;
- return static_cast<sal_Bool>(mpRefMgr->hasCacheTable(mnFileId, aName));
+
+ // #i116940# be consistent with getByName: allow only table names which have a cache already
+ ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false);
+ return (pTable.get() != NULL);
}
sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount()
throw (RuntimeException)
{
SolarMutexGuard aGuard;
- return static_cast<sal_Int32>(mpRefMgr->getCacheTableCount(mnFileId));
+
+ // #i116940# be consistent with getByName: count only table names which have a cache already
+ return getElementNames().getLength();
}
-Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nIndex)
+Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex)
throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
{
SolarMutexGuard aGuard;
- size_t nTabCount = mpRefMgr->getCacheTableCount(mnFileId);
- if (nIndex < 0 || nIndex >= static_cast<sal_Int32>(nTabCount))
+
+ // #i116940# Can't use nApiIndex as index for the ref manager, because the API counts only
+ // the entries which have a cache already. Quick solution: Use getElementNames.
+ Sequence< OUString > aNames( getElementNames() );
+ if (nApiIndex < 0 || nApiIndex >= aNames.getLength())
throw lang::IndexOutOfBoundsException();
- ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, static_cast<size_t>(nIndex));
+ size_t nIndex = 0;
+ ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aNames[nApiIndex], false, &nIndex);
if (!pTable)
throw lang::IndexOutOfBoundsException();
@@ -1689,7 +1705,9 @@ sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements()
throw (RuntimeException)
{
SolarMutexGuard aGuard;
- return static_cast<sal_Bool>(mpRefMgr->getCacheTableCount(mnFileId) > 0);
+
+ // #i116940# be consistent with getByName: count only table names which have a cache already
+ return ( getElementNames().getLength() > 0 );
}
sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex()