ooo-build r13457 - in trunk: . patches/test
- From: kyoshida svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r13457 - in trunk: . patches/test
- Date: Fri, 1 Aug 2008 07:28:23 +0000 (UTC)
Author: kyoshida
Date: Fri Aug 1 07:28:23 2008
New Revision: 13457
URL: http://svn.gnome.org/viewvc/ooo-build?rev=13457&view=rev
Log:
2008-08-01 Kohei Yoshida <kyoshida novell com>
* patches/test/calc-external-defined-names.diff: more progress; make
full use of cached external data to speed up file loading, fixed once
again the xls import/export filters to correctly read/write external
data, and more.
Modified:
trunk/ChangeLog
trunk/patches/test/calc-external-defined-names.diff
Modified: trunk/patches/test/calc-external-defined-names.diff
==============================================================================
--- trunk/patches/test/calc-external-defined-names.diff (original)
+++ trunk/patches/test/calc-external-defined-names.diff Fri Aug 1 07:28:23 2008
@@ -203,10 +203,10 @@
@return TRUE = Sheet created, rnTab contains valid sheet index. */
diff --git sc/inc/externalrefmgr.hxx sc/inc/externalrefmgr.hxx
new file mode 100644
-index 0000000..1245062
+index 0000000..08b0c53
--- /dev/null
+++ sc/inc/externalrefmgr.hxx
-@@ -0,0 +1,288 @@
+@@ -0,0 +1,343 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -246,6 +246,7 @@
+#include "sfx2/lnkbase.hxx"
+#include "tools/time.hxx"
+#include "vcl/timer.hxx"
++#include "scmatrix.hxx"
+
+#include <hash_map>
+#include <hash_set>
@@ -293,36 +294,126 @@
+ */
+class ScExternalRefCache
+{
++ struct RangeHash
++ {
++ size_t operator()(const ScRange& rRange) const
++ {
++ const ScAddress& s = rRange.aStart;
++ const ScAddress& e = rRange.aEnd;
++ return s.Tab() + s.Col() + s.Row() + e.Tab() + e.Col() + e.Row();
++ }
++ };
++
+public:
-+ typedef ::boost::shared_ptr<ScToken> TokenRef;
-+ typedef ::boost::shared_ptr<ScMatrix> MatrixRef;
++
++ typedef ::boost::shared_ptr<ScToken> TokenRef;
++ typedef ::boost::shared_ptr<ScTokenArray> TokenArrayRef;
++ typedef ::std::hash_map<SCCOL, TokenRef> RowDataType;
++ typedef ::std::hash_map<SCROW, RowDataType> RowsDataType;
++
++ class Table
++ {
++ public:
++ Table();
++ ~Table();
++
++ void setCell(SCROW nRow, SCCOL nCol, TokenRef pToken);
++ ScToken* getCell(SCROW nRow, SCCOL nCol) const;
++
++ private:
++ RowsDataType maRows;
++ };
++
++ typedef ::boost::shared_ptr<Table> TableTypeRef;
++ typedef ::std::hash_map<String, size_t, ScStringHashCode> TableNameIndexMap;
+
+ ScExternalRefCache();
+ ~ScExternalRefCache();
+
++ /**
++ * Get a cached cell data at specified cell location.
++ *
++ * @param nFileId file ID of an external document
++ * @param rTabName sheet name
++ * @param nRow
++ * @param nCol
++ *
++ * @return pointer to the token instance in the cache. <i>The caller does
++ * not need to delete this instance since its life cycle is
++ * managed by this class.</i>
++ */
+ ScToken* getCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol);
++
++ /**
++ * Get a cached cell range data.
++ *
++ * @return a new token array instance. Note that <i>the caller must
++ * manage the life cycle of the returned instance</i>.
++ */
+ ScTokenArray* getCellRangeData(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange);
+
++ ScTokenArray* getRangeNameTokens(sal_uInt16 nFileId, const String& rName);
++ void setRangeNameTokens(sal_uInt16 nFileId, const String& rName, TokenArrayRef pArray);
++
+ void setCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol, TokenRef pToken);
-+ void setCellRangeData(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange,
-+ const ::std::vector<MatrixRef>& rData);
++
++ struct SingleRangeData
++ {
++ String maTableName;
++ ScMatrixRef mpRangeData;
++ };
++ void setCellRangeData(sal_uInt16 nFileId, const ScRange& rRange, const ::std::vector<SingleRangeData>& rData,
++ TokenArrayRef pArray);
++
++ bool isDocInitialized(sal_uInt16 nFileId);
++ void initializeDoc(sal_uInt16 nFileId, const ::std::vector<String>& rTabNames);
++#if 0
++ const String* getExternalTableName(sal_uInt16 nFileId, SCTAB nTab);
++ SCTAB getExternalTableId(sal_uInt16 nFileId, const String& rTabName);
++#endif
++ const ::std::vector<String>* getAllTableNames(sal_uInt16 nFileId) const;
++
++ /**
++ * Get a cache table instance for specified file and table name. If the
++ * table instance is not already present, it'll instantiate a new one and
++ * append it to the end of the table array. <I>It's important to be
++ * aware of this fact especially for multi-table ranges for which
++ * table orders are critical.</I>
++ *
++ * Excel filter calls this method to populate the cache table from the
++ * XCT/CRN records.
++ *
++ * @param nFileId file ID
++ * @param rTabName table name
++ *
++ * @return pointer to the cache table instance
++ */
++ Table* getCacheTable(sal_uInt16 nFileId, const String& rTabName);
++
++ void clearCache(sal_uInt16 nFileId);
+
+private:
-+ typedef ::std::hash_map<SCCOL, TokenRef> RowDataType;
-+ typedef ::std::hash_map<SCROW, RowDataType> TableDataType;
-+ typedef ::boost::shared_ptr<TableDataType> TableDataTypeRef;
-+ typedef ::std::vector<TableDataTypeRef> TableListType;
++ typedef ::std::hash_map<String, TokenArrayRef, ScStringHashCode> RangeNameMap;
++ typedef ::std::hash_map<ScRange, TokenArrayRef, RangeHash> RangeArrayMap;
+
-+ typedef ::std::hash_map<String, size_t, ScStringHashCode> TableNameIndexMap;
-+
++ /** Represents data cached for a single external document. */
+ struct DocItem
+ {
-+ TableListType maTables;
-+ TableNameIndexMap maTableNameIndex;
++ ::std::vector<TableTypeRef> maTables;
++ ::std::vector<String> maTableNames;
++ TableNameIndexMap maTableNameIndex;
++ RangeNameMap maRangeNames;
++ RangeArrayMap maRangeArrays;
++
++ bool mbInitFromSource;
++
++ DocItem() : mbInitFromSource(false) {}
+ };
+ typedef ::std::hash_map<sal_uInt16, DocItem> DocDataType;
++ DocItem* getDocItem(sal_uInt16 nFileId) const;
+
-+ DocDataType maDocs;
++private:
++ mutable DocDataType maDocs;
+};
+
+// ============================================================================
@@ -339,16 +430,6 @@
+ }
+ };
+
-+ struct RangeHash
-+ {
-+ size_t operator()(const ScRange& rRange) const
-+ {
-+ const ScAddress& s = rRange.aStart;
-+ const ScAddress& e = rRange.aEnd;
-+ return s.Tab() + s.Col() + s.Row() + e.Tab() + e.Col() + e.Row();
-+ }
-+ };
-+
+ struct SrcDoc
+ {
+ SfxObjectShellRef maShell;
@@ -359,40 +440,34 @@
+ typedef ::boost::shared_ptr<ScTokenArray> TokenArrayRef;
+
+ typedef ::std::hash_map<sal_uInt16, SrcDoc> DocShellMap;
-+ typedef ::std::hash_map<ScAddress, TokenRef, AddressHash, ::std::equal_to<ScAddress> > SingleTokenMap;
-+ typedef ::std::hash_map<ScRange, TokenArrayRef, RangeHash, ::std::equal_to<ScRange> > DoubleTokenMap;
-+ typedef ::std::hash_map<String, TokenArrayRef, ScStringHashCode, ::std::equal_to<String> > RangeNameMap;
+ typedef ::std::hash_set<sal_uInt16, ScStringHashCode> LinkedDocSet;
+
+ typedef ::std::hash_set<ScAddress, AddressHash, ::std::equal_to<ScAddress> > RefCellSet;
+ typedef ::std::hash_map<sal_uInt16, RefCellSet> RefCellMap;
+
-+ /**
-+ * Cached content of a single external document
-+ */
-+ struct DocCache
-+ {
-+ SingleTokenMap maSingleTokens;
-+ DoubleTokenMap maDoubleTokens;
-+ RangeNameMap maRangeNames;
-+ ::std::vector<String> maTableNames;
-+ };
-+ typedef ::boost::shared_ptr<DocCache> DocCacheRef;
-+ typedef ::std::hash_map<sal_uInt16, DocCacheRef> DocCacheMap;
-+
+public:
+ explicit ScExternalRefManager(ScDocument* pDoc);
+ ~ScExternalRefManager();
+
++ ScExternalRefCache::Table* getCacheTable(sal_uInt16 nFileId, const String& rTabName);
++ void storeRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScTokenArray& rArray);
++
+ ScToken* getSingleRefToken(sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell, const ScAddress* pCurPos, SCTAB* pTab);
-+#if 1
-+ ScToken* getSingleRefToken(sal_uInt16 nFileId, const ScAddress& rCell, const ScAddress* pCurPos);
-+#endif
+
++ /**
++ * Get an array of tokens that consist of the specified external cell
++ * range.
++ *
++ * @param nFileId file ID for an external document
++ * @param rTabName referenced sheet name
++ * @param rRange referenced cell range
++ * @param pCurPos current cursor position to keep track of cells that
++ * reference an external data.
++ *
++ * @return pointer to a token array instance. <i>The caller must not
++ * delete the instance returned by this method.</i>
++ */
+ ScTokenArray* getDoubleRefTokens(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos);
-+#if 1
-+ ScTokenArray* getDoubleRefTokens(sal_uInt16 nFileId, const ScRange& rRange, const ScAddress* pCurPos);
-+#endif
+
+ /**
+ * Get an array of tokens corresponding with a specified name in a
@@ -416,18 +491,7 @@
+ void convertToAbsName(String& rFile) const;
+ sal_uInt16 getExternalFileId(const String& rFile);
+ const String* getExternalFileName(sal_uInt16 nFileId) const;
-+ const String* getExternalTableName(sal_uInt16 nFileId, SCTAB nTabId);
-+
-+ /**
-+ * Get the table index of an external table from its name.
-+ *
-+ * @param nFileId external file ID
-+ * @param rTabName table name
-+ *
-+ * @return table index, or -1 if the name is not found.
-+ */
-+ SCTAB getExternalTableId(sal_uInt16 nFileId, const String& rTabName);
-+
++ const ::std::vector<String>* getAllCachedTableNames(sal_uInt16 nFileId) const;
+ void refreshNames(sal_uInt16 nFileId);
+ void switchSrcFile(sal_uInt16 nFileId, const String& rNewFile);
+ void removeSrcDocument(sal_uInt16 nFileId, bool bBreakLink);
@@ -437,17 +501,10 @@
+ ScExternalRefManager();
+ ScExternalRefManager(const ScExternalRefManager&);
+
-+#if 1
-+ ScToken* getSingleRefToken(sal_uInt16 nFileId, const ScAddress& rCell);
-+#endif
-+
-+ ScTokenArray* getDoubleRefTokens(sal_uInt16 nFileId, const ScRange& rRange);
-+
+ void refreshAllReferencingCells(sal_uInt16 nFileId);
+
+ void insertReferencingCell(sal_uInt16 nFileId, const ScAddress& rCell);
+
-+ DocCache* getDocumentCache(sal_uInt16 nFileId);
+ ScDocument* getSrcDocument(sal_uInt16 nFileId);
+ SfxObjectShellRef loadSrcDocument(const String& rFile, String& rFilter);
+ void insertExternalFileLink(sal_uInt16 nFileId, const String& rFilterName);
@@ -463,6 +520,7 @@
+ void purgeStaleSrcDocument(sal_Int32 nTimeOut);
+
+private:
++ /** cache only of referenced ranges and names from source documents. */
+ ScExternalRefCache maRefCache;
+
+ ScDocument* mpDoc;
@@ -474,15 +532,12 @@
+ */
+ DocShellMap maDocShells;
+
-+ /** cache only of referenced ranges and names from source documents. */
-+ DocCacheMap maCachedDocContents;
-+
+ /** list of source documents that are managed by the link manager. */
+ LinkedDocSet maLinkedDocs;
+
+ /**
-+ * List of referencing cells that may contain external names. There is
-+ * one list per source document.
++ * List of referencing cells that may contain external names. There is
++ * one list per source document.
+ */
+ RefCellMap maRefCells;
+
@@ -508,7 +563,7 @@
ocIf = SC_OPCODE_IF,
ocChose = SC_OPCODE_CHOSE,
diff --git sc/inc/token.hxx sc/inc/token.hxx
-index ded3a94..92a9137 100644
+index ded3a94..7e49031 100644
--- sc/inc/token.hxx
+++ sc/inc/token.hxx
@@ -64,7 +64,7 @@ enum StackVarEnum
@@ -520,7 +575,7 @@
svError, // error token
svMissing = 0x70, // 0 or ""
svSep, // separator, ocSep, ocOpen, ocClose
-@@ -448,6 +448,65 @@ public:
+@@ -448,6 +448,69 @@ public:
};
@@ -560,6 +615,10 @@
+
+ virtual USHORT GetIndex() const;
+ virtual const String& GetString() const;
++ virtual const SingleRefData& GetSingleRef() const;
++ virtual SingleRefData& GetSingleRef();
++ virtual const SingleRefData& GetSingleRef2() const;
++ virtual SingleRefData& GetSingleRef2();
+ virtual const ComplRefData& GetDoubleRef() const;
+ virtual ComplRefData& GetDoubleRef();
+ virtual BOOL operator==( const ScToken& rToken ) const;
@@ -937,7 +996,7 @@
case ScAddress::CONV_XL_A1:
return lcl_ScRange_Parse_XL_A1( *this, r.GetBuffer(), pDoc, FALSE );
diff --git sc/source/core/tool/compiler.cxx sc/source/core/tool/compiler.cxx
-index f88d5d3..563adf9 100644
+index 084f533..820192e 100644
--- sc/source/core/tool/compiler.cxx
+++ sc/source/core/tool/compiler.cxx
@@ -74,9 +74,38 @@
@@ -979,7 +1038,7 @@
#if OSL_DEBUG_LEVEL > 1
// For some unknown reason the identical dbg_dump utilities in
-@@ -1165,6 +1194,174 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
+@@ -1175,6 +1204,174 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
return true;
}
@@ -1154,7 +1213,7 @@
struct Convention_A1 : public ScCompiler::Convention
{
Convention_A1( ScAddress::Convention eConv ) : ScCompiler::Convention( eConv ) { }
-@@ -1185,7 +1382,7 @@ struct Convention_A1 : public ScCompiler::Convention
+@@ -1195,7 +1392,7 @@ struct Convention_A1 : public ScCompiler::Convention
KParseTokens::ASC_UNDERSCORE | KParseTokens::ASC_DOLLAR;
static const sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT;
// '?' allowed in range names because of Xcl :-/
@@ -1163,7 +1222,7 @@
return pCharClass->parseAnyToken( rFormula,
nSrcPos, nStartFlags, aAddAllowed, nContFlags, aAddAllowed );
}
-@@ -1368,6 +1565,81 @@ struct ConventionOOO_A1 : public Convention_A1
+@@ -1378,6 +1575,81 @@ struct ConventionOOO_A1 : public Convention_A1
return sal_Unicode(0);
}
@@ -1245,7 +1304,7 @@
};
-@@ -1489,6 +1761,16 @@ struct ConventionXL
+@@ -1499,6 +1771,16 @@ struct ConventionXL
}
return sal_Unicode(0);
}
@@ -1262,7 +1321,7 @@
};
struct ConventionXL_A1 : public Convention_A1, public ConventionXL
-@@ -1587,6 +1869,16 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
+@@ -1597,6 +1879,16 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
{
return ConventionXL::getSpecialSymbol(eSymType);
}
@@ -1279,7 +1338,7 @@
};
static const ConventionXL_A1 ConvXL_A1;
-@@ -1714,6 +2006,16 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
+@@ -1724,6 +2016,16 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
{
return ConventionXL::getSpecialSymbol(eSymType);
}
@@ -1296,7 +1355,7 @@
};
static const ConventionXL_R1C1 ConvXL_R1C1;
-@@ -1888,6 +2190,7 @@ sal_Unicode* lcl_UnicodeStrNCpy( sal_Unicode* pDst, const sal_Unicode* pSrc, xub
+@@ -1898,6 +2200,7 @@ sal_Unicode* lcl_UnicodeStrNCpy( sal_Unicode* pDst, const sal_Unicode* pSrc, xub
xub_StrLen ScCompiler::NextSymbol(bool bInArray)
{
@@ -1304,7 +1363,7 @@
cSymbol[MAXSTRLEN-1] = 0; // Stopper
sal_Unicode* pSym = cSymbol;
const sal_Unicode* const pStart = aFormula.GetBuffer();
-@@ -1912,6 +2215,11 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+@@ -1922,6 +2225,11 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
bool bAutoIntersection = false;
int nRefInSheetName = 0;
mnPredetectedReference = 0;
@@ -1316,7 +1375,7 @@
// try to parse simple tokens before calling i18n parser
while ((c != 0) && (eState != ssStop) )
{
-@@ -2169,7 +2477,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+@@ -2179,7 +2487,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
static const int kQuote = kInc * 2;
static const int kPast = kInc * 3;
bool bAddToSymbol = true;
@@ -1325,7 +1384,7 @@
{
// eat it, no sheet name
bAddToSymbol = false;
-@@ -2184,7 +2492,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+@@ -2194,7 +2502,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
}
else if (nRefInSheetName < kPast)
{
@@ -1334,7 +1393,7 @@
nRefInSheetName += kDollar;
else if ('\'' == c)
{
-@@ -2235,6 +2543,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+@@ -2245,6 +2553,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
cLast = c;
c = *pSrc;
}
@@ -1342,7 +1401,7 @@
if ( bi18n )
{
nSrcPos = sal::static_int_cast<xub_StrLen>( nSrcPos + nSpaces );
-@@ -2287,6 +2596,9 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+@@ -2297,6 +2606,9 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
aCorrectedSymbol = cSymbol;
if (bAutoIntersection && nSpaces > 1)
--nSpaces; // replace '!!' with only one space
@@ -1352,7 +1411,7 @@
return nSpaces;
}
-@@ -2506,7 +2818,8 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
+@@ -2516,7 +2828,8 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
{
ScRange aRange( aPos, aPos );
const ScAddress::Details aDetails( pConv->meConv, aPos );
@@ -1362,7 +1421,7 @@
if( nFlags & SCA_VALID )
{
ScRawToken aToken;
-@@ -2525,23 +2838,41 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
+@@ -2535,23 +2848,41 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
aRef.Ref2.SetTabDeleted( TRUE ); // #REF!
aRef.Ref2.SetFlag3D( ( nFlags & SCA_TAB2_3D ) != 0 );
aRef.CalcRelFromAbs( aPos );
@@ -1406,7 +1465,7 @@
ScRawToken aToken;
SingleRefData aRef;
aRef.InitAddress( aAddr );
-@@ -2561,16 +2892,28 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
+@@ -2571,16 +2902,28 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
nFlags |= SCA_VALID;
}
aRef.CalcRelFromAbs( aPos );
@@ -1436,7 +1495,7 @@
// Has to be called before IsValue
sal_Unicode ch1 = rName.GetChar(0);
sal_Unicode cDecSep = ( mxSymbols->isEnglish() ? '.' :
-@@ -2669,6 +3012,30 @@ BOOL ScCompiler::IsNamedRange( const String& rUpperName )
+@@ -2679,6 +3022,30 @@ BOOL ScCompiler::IsNamedRange( const String& rUpperName )
return FALSE;
}
@@ -1467,7 +1526,7 @@
BOOL ScCompiler::IsDBRange( const String& rName )
{
USHORT n;
-@@ -3267,6 +3634,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
+@@ -3277,6 +3644,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
&& !(bAllowBooleans && IsBoolean( aUpper ))
&& !IsValue( aUpper )
&& !IsNamedRange( aUpper )
@@ -1475,7 +1534,7 @@
&& !IsDBRange( aUpper )
&& !IsColRowName( aUpper )
&& !(bMayBeFuncName && IsMacro( aUpper ))
-@@ -3593,6 +3961,69 @@ BOOL ScCompiler::GetToken()
+@@ -3603,6 +3971,70 @@ BOOL ScCompiler::GetToken()
}
if( pToken->GetOpCode() == ocSubTotal )
glSubTotal = TRUE;
@@ -1534,6 +1593,7 @@
+ ScTokenArray* pNew = pRefMgr->getDoubleRefTokens(pToken->GetIndex(), pToken->GetString(), aRange, &aPos);
+ if (pNew)
+ {
++ // This is already a new instance - no need to clone it.
+ PushTokenArray(pNew->Clone(), true);
+ return GetToken();
+ }
@@ -1545,7 +1605,7 @@
else if( pToken->GetOpCode() == ocName )
{
ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex( pToken->GetIndex() );
-@@ -5543,6 +5974,7 @@ ScToken* ScCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToke
+@@ -5553,6 +5985,7 @@ ScToken* ScCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToke
BOOL bSpaces = FALSE;
ScToken* t = pTokenP;
OpCode eOp = t->GetOpCode();
@@ -1553,7 +1613,7 @@
if( eOp >= ocAnd && eOp <= ocOr )
{
// AND, OR infix?
-@@ -5590,111 +6022,141 @@ ScToken* ScCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToke
+@@ -5600,111 +6033,141 @@ ScToken* ScCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToke
DBG_ERRORFILE("unknown OpCode");
rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
}
@@ -1782,7 +1842,7 @@
rBuffer.append(sal_Unicode(' '));
if ( bAllowArrAdvance )
diff --git sc/source/core/tool/token.cxx sc/source/core/tool/token.cxx
-index a20cbd5..25090a8 100644
+index a20cbd5..438f46a 100644
--- sc/source/core/tool/token.cxx
+++ sc/source/core/tool/token.cxx
@@ -54,6 +54,33 @@
@@ -2034,7 +2094,7 @@
}
if (!xRes)
return NULL; // shouldn't happen..
-@@ -1035,6 +1149,170 @@ BOOL ScIndexToken::operator==( const ScToken& r ) const
+@@ -1035,6 +1149,190 @@ BOOL ScIndexToken::operator==( const ScToken& r ) const
return ScToken::operator==( r ) && nIndex == r.GetIndex();
}
@@ -2126,6 +2186,26 @@
+ return maTabName;
+}
+
++const SingleRefData& ScExternalDoubleRefToken::GetSingleRef() const
++{
++ return maDoubleRef.Ref1;
++}
++
++SingleRefData& ScExternalDoubleRefToken::GetSingleRef()
++{
++ return maDoubleRef.Ref1;
++}
++
++const SingleRefData& ScExternalDoubleRefToken::GetSingleRef2() const
++{
++ return maDoubleRef.Ref2;
++}
++
++SingleRefData& ScExternalDoubleRefToken::GetSingleRef2()
++{
++ return maDoubleRef.Ref2;
++}
++
+const ComplRefData& ScExternalDoubleRefToken::GetDoubleRef() const
+{
+ return maDoubleRef;
@@ -2205,7 +2285,7 @@
short* ScJumpToken::GetJump() const { return pJump; }
BOOL ScJumpToken::operator==( const ScToken& r ) const
-@@ -1893,6 +2171,21 @@ ScToken* ScTokenArray::AddMatrix( ScMatrix* p )
+@@ -1893,6 +2191,21 @@ ScToken* ScTokenArray::AddMatrix( ScMatrix* p )
return Add( new ScMatrixToken( p ) );
}
@@ -2227,16 +2307,45 @@
ScToken* ScTokenArray::AddColRowName( const SingleRefData& rRef )
{
return Add( new ScSingleRefOpToken( ocColRowName, rRef ) );
+diff --git sc/source/filter/excel/excform.cxx sc/source/filter/excel/excform.cxx
+index 3070f34..fd87dbf 100644
+--- sc/source/filter/excel/excform.cxx
++++ sc/source/filter/excel/excform.cxx
+@@ -46,6 +46,7 @@
+ #include "xilink.hxx"
+ #include "xiname.hxx"
+
++using ::std::vector;
+
+ const UINT16 ExcelToSc::nRowMask = 0x3FFF;
+ const UINT16 ExcelToSc::nLastInd = 399;
+@@ -1329,6 +1330,13 @@ ConvErr ExcelToSc::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sal
+ return eRet;
+ }
+
++ConvErr ExcelToSc::ConvertExternName( const ScTokenArray*& /*rpArray*/, XclImpStream& /*rStrm*/, sal_Size /*nFormulaLen*/,
++ const String& /*rUrl*/, const vector<String>& /*rTabNames*/ )
++{
++ // not implemented ...
++ return ConvErrNi;
++}
++
+ BOOL ExcelToSc::GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sal_Size nLen )
+ {
+ DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF5 );
diff --git sc/source/filter/excel/excform8.cxx sc/source/filter/excel/excform8.cxx
-index ebf8543..e4968c2 100644
+index ebf8543..be5ec15 100644
--- sc/source/filter/excel/excform8.cxx
+++ sc/source/filter/excel/excform8.cxx
-@@ -41,6 +41,32 @@
+@@ -41,6 +41,35 @@
#include "xilink.hxx"
#include "xiname.hxx"
+#include "externalrefmgr.hxx"
+
++#include <vector>
++
++using ::std::vector;
+
+namespace {
+
@@ -2264,7 +2373,7 @@
ExcelToSc8::ExcelToSc8( const XclImpRoot& rRoot ) :
ExcelToSc( rRoot ),
-@@ -53,15 +79,23 @@ ExcelToSc8::~ExcelToSc8()
+@@ -53,15 +82,23 @@ ExcelToSc8::~ExcelToSc8()
{
}
@@ -2276,17 +2385,17 @@
+ const String* pFileUrl = rLinkMan.GetSupbookUrl(nIxti);
+ if (!pFileUrl || pFileUrl->Len() == 0)
+ return false;
-
-- UINT16 nIxti;
-- rStrm >> nIxti;
++
+ String aFileUrl = ScGlobal::GetAbsDocName(*pFileUrl, GetDocShell());
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ rFileId = pRefMgr->getExternalFileId(aFileUrl);
-- return rLinkMan.GetScTabRange( rFirstTab, rLastTab, nIxti );
+- UINT16 nIxti;
+- rStrm >> nIxti;
+ return true;
+}
-+
+
+- return rLinkMan.GetScTabRange( rFirstTab, rLastTab, nIxti );
+bool ExcelToSc8::Read3DTabReference( SCTAB& rFirstTab, SCTAB& rLastTab, UINT16 nIxti )
+{
+ rFirstTab = rLastTab = 0;
@@ -2294,7 +2403,7 @@
}
-@@ -608,8 +642,14 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
+@@ -608,8 +645,15 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
{
case xlExtName:
{
@@ -2308,10 +2417,11 @@
+ }
+
+ aStack << aPool.StoreExtName(nFileId, pExtName->GetName());
++ pExtName->CreateExtNameData(GetDoc(), nFileId);
}
break;
-@@ -657,47 +697,81 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
+@@ -657,47 +701,81 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
case 0x7C:
case 0x3C: // Deleted 3-D Cell Reference [ 277]
{
@@ -2427,7 +2537,7 @@
}
break;
case 0x5B:
-@@ -707,55 +781,75 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
+@@ -707,55 +785,75 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
case 0x7D:
case 0x3D: // Deleted 3-D Area Reference [ 277]
{
@@ -2544,6 +2654,190 @@
}
break;
default: bError = TRUE;
+@@ -1143,7 +1241,135 @@ ConvErr ExcelToSc8::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sa
+ return eRet;
+ }
+
++ConvErr ExcelToSc8::ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
++ const String& rUrl, const vector<String>& rTabNames )
++{
++ StackPrinter __stack_print__("ExcelToSc8::ConvertExternName");
++ String aFileUrl = ScGlobal::GetAbsDocName(rUrl, GetDocShell());
++
++ sal_uInt8 nOp, nByte;
++ bool bError = false;
++
++ SingleRefData aSRD;
++ ComplRefData aCRD;
++
++ if (eStatus != ConvOK)
++ {
++ rStrm.Ignore(nFormulaLen);
++ return eStatus;
++ }
++
++ if (nFormulaLen == 0)
++ {
++ aPool.Store(CREATE_STRING("-/-"));
++ aPool >> aStack;
++ rpArray = aPool[aStack.Get()];
++ return ConvOK;
++ }
+
++ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
++ sal_uInt16 nFileId = pRefMgr->getExternalFileId(aFileUrl);
++ sal_uInt16 nTabCount = rTabNames.size();
++
++ sal_Size nEndPos = rStrm.GetRecPos() + nFormulaLen;
++
++ while( (rStrm.GetRecPos() < nEndPos) && !bError )
++ {
++ rStrm >> nOp;
++
++ // #98524# always reset flags
++ aSRD.InitFlags();
++ aCRD.InitFlags();
++
++ switch( nOp )
++ {
++ case 0x1C: // Error Value
++ {
++ rStrm >> nByte;
++ DefTokenId eOc;
++ switch( nByte )
++ {
++ case EXC_ERR_NULL:
++ case EXC_ERR_DIV0:
++ case EXC_ERR_VALUE:
++ case EXC_ERR_REF:
++ case EXC_ERR_NAME:
++ case EXC_ERR_NUM: eOc = ocStop; break;
++ case EXC_ERR_NA: eOc = ocNotAvail; break;
++ default: eOc = ocNoName;
++ }
++ aPool << eOc;
++ if( eOc != ocStop )
++ aPool << ocOpen << ocClose;
++ aPool >> aStack;
++ }
++ break;
++ case 0x3A:
++ {
++ // cell reference in external range name
++ fprintf(stdout, "ExcelToSc8::ConvertExternName: cell reference (0x3A)\n");
++ sal_uInt16 nExtTab1, nExtTab2, nRow, nGrbitCol;
++ rStrm >> nExtTab1 >> nExtTab2 >> nRow >> nGrbitCol;
++ fprintf(stdout, "ExcelToSc8::ConvertExternName: tab1 = %d; tab2 = %d\n", nExtTab1, nExtTab2);
++ if (nExtTab1 >= nTabCount || nExtTab2 >= nTabCount)
++ {
++ bError = true;
++ break;
++ }
++
++ aSRD.nTab = nExtTab1;
++ aSRD.SetFlag3D(true);
++ aSRD.SetTabRel(false);
++ ExcRelToScRel8(nRow, nGrbitCol, aSRD, true);
++ aCRD.Ref1 = aCRD.Ref2 = aSRD;
++ String aTabName = rTabNames[nExtTab1];
++
++ if (nExtTab1 == nExtTab2)
++ {
++ // single cell reference
++ aStack << aPool.StoreExtRef(nFileId, aTabName, aSRD);
++ }
++ else
++ {
++ // area reference
++ aCRD.Ref2.nTab = nExtTab2;
++ aStack << aPool.StoreExtRef(nFileId, aTabName, aCRD);
++ }
++ fprintf(stdout, "ExcelToSc8::ConvertExternName: external ref inserted\n");
++ }
++ break;
++ default:
++ fprintf(stdout, "ExcelToSc8::ConvertExternName: un-handled opcode (%2.2X)\n", nOp);
++ bError = true;
++ }
++ bError |= !rStrm.IsValid();
++ }
++
++ ConvErr eRet;
++
++ if( bError )
++ {
++ aPool << ocBad;
++ aPool >> aStack;
++ rpArray = aPool[ aStack.Get() ];
++ eRet = ConvErrNi;
++ }
++ else if( rStrm.GetRecPos() != nEndPos )
++ {
++ aPool << ocBad;
++ aPool >> aStack;
++ rpArray = aPool[ aStack.Get() ];
++ eRet = ConvErrCount;
++ }
++ else
++ {
++ rpArray = aPool[ aStack.Get() ];
++ eRet = ConvOK;
++ }
++
++ rStrm.Seek(nEndPos);
++ return eRet;
++}
+
+ void ExcelToSc8::ExcRelToScRel8( UINT16 nRow, UINT16 nC, SingleRefData &rSRD, const BOOL bName )
+ {
+diff --git sc/source/filter/excel/impop.cxx sc/source/filter/excel/impop.cxx
+index 258a7c7..4687365 100644
+--- sc/source/filter/excel/impop.cxx
++++ sc/source/filter/excel/impop.cxx
+@@ -98,6 +98,30 @@
+ using namespace ::com::sun::star;
+
+
++namespace {
++
++#include <string>
++
++class StackPrinter
++{
++public:
++ explicit StackPrinter(const char* msg) :
++ msMsg(msg)
++ {
++ fprintf(stdout, "%s: --begin\n", msMsg.c_str());
++ }
++
++ ~StackPrinter()
++ {
++ fprintf(stdout, "%s: --end\n", msMsg.c_str());
++ }
++
++private:
++ ::std::string msMsg;
++};
++
++}
++
+ const double ImportExcel::fExcToTwips =
+ ( double ) TWIPS_PER_CHAR / 256.0;
+
+diff --git sc/source/filter/excel/read.cxx sc/source/filter/excel/read.cxx
+index 2cc592c..7f1c44b 100644
+--- sc/source/filter/excel/read.cxx
++++ sc/source/filter/excel/read.cxx
+@@ -967,7 +967,7 @@ FltError ImportExcel8::Read( void )
+ case EXC_ID_SUPBOOK: rLinkMgr.ReadSupbook( maStrm ); break;
+ case EXC_ID_XCT: rLinkMgr.ReadXct( maStrm ); break;
+ case EXC_ID_CRN: rLinkMgr.ReadCrn( maStrm ); break;
+- case EXC_ID_EXTERNNAME: rLinkMgr.ReadExternname( maStrm ); break;
++ case EXC_ID_EXTERNNAME: rLinkMgr.ReadExternname( maStrm, pFormConv ); break;
+
+ case EXC_ID_MSODRAWINGGROUP:rObjMgr.ReadMsoDrawingGroup( maStrm ); break;
+
diff --git sc/source/filter/excel/tokstack.cxx sc/source/filter/excel/tokstack.cxx
index 20ada63..9c4ddba 100644
--- sc/source/filter/excel/tokstack.cxx
@@ -2688,7 +2982,7 @@
diff --git sc/source/filter/excel/xeformula.cxx sc/source/filter/excel/xeformula.cxx
-index 3db8da7..65a5775 100644
+index 3db8da7..0debb70 100644
--- sc/source/filter/excel/xeformula.cxx
+++ sc/source/filter/excel/xeformula.cxx
@@ -42,6 +42,12 @@
@@ -2758,7 +3052,7 @@
switch( eTokType )
{
case svUnknown: mbOk = false; break;
-@@ -1248,6 +1287,107 @@ void XclExpFmlaCompImpl::ProcessExternal( const XclExpTokenData& rTokData, sal_u
+@@ -1248,6 +1287,136 @@ void XclExpFmlaCompImpl::ProcessExternal( const XclExpTokenData& rTokData, sal_u
ProcessFunction( rTokData, nExpClass );
}
@@ -2772,7 +3066,6 @@
+ {
+ case svSingleRef:
+ {
-+ fprintf(stdout, "XclExpFmlaCompImpl::ProcessExternalName: svSingleRef not supported yet\n");
+ if (!mpScBasePos)
+ {
+ AppendErrorToken(EXC_ERR_REF, rTokData.mnSpaces);
@@ -2780,22 +3073,22 @@
+ }
+ SingleRefData aRef(rTokData.mpScToken->GetSingleRef());
+ aRef.CalcAbsIfRel(*mpScBasePos);
-+ ScToken* p = pRefMgr->getSingleRefToken(nFileId, ScAddress(aRef.nCol, aRef.nRow, aRef.nTab), NULL);
++ const String& rTabName = rTokData.mpScToken->GetString();
++ ScToken* p = pRefMgr->getSingleRefToken(nFileId, rTabName, ScAddress(aRef.nCol, aRef.nRow, aRef.nTab), NULL, NULL);
+ if (!p)
+ {
+ AppendErrorToken(EXC_ERR_REF, rTokData.mnSpaces);
+ break;
+ }
+
-+ mpLinkMgr->StoreCell(nFileId, rTokData.mpScToken->GetString(), aRef);
++ mpLinkMgr->StoreCell(nFileId, rTabName, aRef);
+
+ XclAddress aXclPos(ScAddress::UNINITIALIZED);
+ ConvertRefData(aRef, aXclPos, false, false, false);
+
+ const String* pFile = pRefMgr->getExternalFileName(nFileId);
+ sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
-+ mpLinkMgr->FindExtSheet(nFileId, nExtSheet, nFirstSBTab, nLastSBTab,
-+ aRef.nTab, aRef.nTab, GetNewRefLogEntry());
++ mpLinkMgr->FindExtSheet(nFileId, rTabName, 1, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry());
+ sal_uInt8 nBaseId = lclIsRefDel2D(aRef) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
+ AppendOpTokenId(GetTokenId(nBaseId, EXC_TOKCLASS_REF), nExpClass, rTokData.mnSpaces);
+ Append(nExtSheet);
@@ -2810,13 +3103,43 @@
+ break;
+ case svDoubleRef:
+ {
-+ fprintf(stdout, "XclExpFmlaCompImpl::ProcessExternalName: svDoubleRef not supported yet\n");
++ fprintf(stdout, "XclExpFmlaCompImpl::ProcessExternalName: *** svDoubleRef support in progress ***\n");
+ if (!mpScBasePos)
+ {
+ AppendErrorToken(XclTools::GetXclErrorCode(errNoRef), rTokData.mnSpaces);
+ break;
+ }
-+ AppendBoolToken(true, rTokData.mnSpaces);
++ ComplRefData aRef(rTokData.mpScToken->GetDoubleRef());
++ aRef.CalcAbsIfRel(*mpScBasePos);
++ const String& rTabName = rTokData.mpScToken->GetString();
++ const SingleRefData& r1 = aRef.Ref1;
++ const SingleRefData& r2 = aRef.Ref2;
++ ScRange aRange(r1.nCol, r1.nRow, r1.nTab, r2.nCol, r2.nRow, r2.nTab);
++ ScTokenArray* pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, aRange, NULL);
++ if (!pArray)
++ {
++ AppendErrorToken(EXC_ERR_REF, rTokData.mnSpaces);
++ break;
++ }
++
++ mpLinkMgr->StoreCellRange(nFileId, rTabName, aRef);
++ XclRange aXclRange(ScAddress::UNINITIALIZED);
++ ConvertRefData(aRef, aXclRange, false);
++ const String* pFile = pRefMgr->getExternalFileName(nFileId);
++ sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
++ sal_uInt16 nTabSpan = r2.nTab - r1.nTab + 1;
++ mpLinkMgr->FindExtSheet(nFileId, rTabName, nTabSpan, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry());
++
++ sal_uInt8 nBaseId = lclIsRefDel2D(aRef) ? EXC_TOKID_AREAERR3D : EXC_TOKID_AREA3D;
++ AppendOpTokenId(GetTokenId( nBaseId, EXC_TOKCLASS_REF ), nExpClass, rTokData.mnSpaces);
++ Append(nExtSheet);
++ if (meBiff <= EXC_BIFF5)
++ {
++ Append(0, 8);
++ Append(static_cast<sal_uInt16>(nFirstSBTab));
++ Append(static_cast<sal_uInt16>(nLastSBTab));
++ }
++ AppendRange(aXclRange);
+ }
+ break;
+ case svExternalName:
@@ -2866,7 +3189,7 @@
void XclExpFmlaCompImpl::ProcessFunction( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
{
OpCode eOpCode = rTokData.GetOpCode();
-@@ -1623,32 +1763,6 @@ void XclExpFmlaCompImpl::AppendTrailingParam( XclExpFuncData& rFuncData )
+@@ -1623,32 +1792,6 @@ void XclExpFmlaCompImpl::AppendTrailingParam( XclExpFuncData& rFuncData )
}
}
@@ -2900,10 +3223,10 @@
SCTAB XclExpFmlaCompImpl::GetScTab( const SingleRefData& rRefData ) const
diff --git sc/source/filter/excel/xelink.cxx sc/source/filter/excel/xelink.cxx
-index b1bacad..ebd2999 100644
+index b1bacad..4f1ed68 100644
--- sc/source/filter/excel/xelink.cxx
+++ sc/source/filter/excel/xelink.cxx
-@@ -38,6 +38,15 @@
+@@ -38,6 +38,40 @@
#include "document.hxx"
#include "cell.hxx"
#include "scextopt.hxx"
@@ -2916,10 +3239,35 @@
+using ::std::auto_ptr;
+using ::std::find_if;
+using ::std::vector;
++
++
++namespace {
++
++#include <string>
++
++class StackPrinter
++{
++public:
++ explicit StackPrinter(const char* msg) :
++ msMsg(msg)
++ {
++ fprintf(stdout, "%s: --begin\n", msMsg.c_str());
++ }
++
++ ~StackPrinter()
++ {
++ fprintf(stdout, "%s: --end\n", msMsg.c_str());
++ }
++
++private:
++ ::std::string msMsg;
++};
++
++}
// ============================================================================
// *** Helper classes ***
-@@ -102,6 +111,22 @@ private:
+@@ -102,6 +136,22 @@ private:
XclExpCachedMatRef mxMatrix; /// Cached results of the DDE link.
};
@@ -2942,7 +3290,7 @@
// List of external names =====================================================
/** List of all external names of a sheet. */
-@@ -117,6 +142,8 @@ public:
+@@ -117,6 +167,8 @@ public:
@return The 1-based (Excel-like) list index of the DDE link. */
sal_uInt16 InsertDde( const String& rApplic, const String& rTopic, const String& rItem );
@@ -2951,7 +3299,7 @@
/** Writes the EXTERNNAME record list. */
virtual void Save( XclExpStream& rStrm );
-@@ -220,6 +247,9 @@ public:
+@@ -220,6 +272,9 @@ public:
/** Stores all cells in the given range in the CRN list. */
void StoreCellRange( const XclExpRoot& rRoot, const ScRange& rRange );
@@ -2961,19 +3309,20 @@
/** Writes the XCT and all CRN records. */
virtual void Save( XclExpStream& rStrm );
-@@ -319,6 +349,11 @@ public:
+@@ -319,6 +374,12 @@ public:
/** Stores all cells in the given range in the CRN list of the specified SUPBOOK sheet. */
void StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab );
+ void StoreCell( sal_uInt16 nSBTab, const ScAddress& rCell, const ScToken& rToken );
+ void StoreCellRange( sal_uInt16 nSBTab, const ScRange& rRange, const ScToken& rToken );
+
-+ sal_uInt16 GetTabIndex( const String& rTabName );
++ sal_uInt16 GetTabIndex( const String& rTabName ) const;
++ sal_uInt16 GetTabCount() const;
+
/** Inserts a new sheet name into the SUPBOOK and returns the SUPBOOK internal sheet index. */
sal_uInt16 InsertTabName( const String& rTabName );
/** Finds or inserts an EXTERNNAME record for add-ins.
-@@ -328,6 +363,8 @@ public:
+@@ -328,6 +389,8 @@ public:
@return The 1-based EXTERNNAME record index; or 0, if the record list is full. */
sal_uInt16 InsertDde( const String& rItem );
@@ -2982,7 +3331,7 @@
/** Writes the SUPBOOK and all EXTERNNAME, XCT and CRN records. */
virtual void Save( XclExpStream& rStrm );
-@@ -394,6 +431,9 @@ public:
+@@ -394,6 +457,9 @@ public:
/** Stores all cells in the given range in a CRN record list. */
void StoreCellRange( const ScRange& rRange );
@@ -2992,7 +3341,7 @@
/** Finds or inserts an EXTERNNAME record for an add-in function name.
@param rnSupbook Returns the index of the SUPBOOK record which contains the add-in function name.
@param rnExtName Returns the 1-based EXTERNNAME record index. */
-@@ -407,9 +447,25 @@ public:
+@@ -407,9 +473,25 @@ public:
sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
const String& rApplic, const String& rTopic, const String& rItem );
@@ -3000,7 +3349,7 @@
+ sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rUrl,
+ const String& rName, const ScTokenArray* pArray );
+
-+ XclExpXti GetXti( sal_uInt16 nFileId, sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
++ XclExpXti GetXti( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ XclExpRefLogEntry* pRefLogEntry = NULL );
+
/** Writes all SUPBOOK records with their sub records. */
@@ -3018,8 +3367,12 @@
private:
typedef XclExpRecordList< XclExpSupbook > XclExpSupbookList;
typedef XclExpSupbookList::RecordRefType XclExpSupbookRef;
-@@ -435,15 +491,6 @@ private:
- void AddExtSupbook( SCTAB nScTab );
+@@ -431,19 +513,8 @@ private:
+ /** Appends a new SUPBOOK to the list.
+ @return The list index of the SUPBOOK record. */
+ sal_uInt16 Append( XclExpSupbookRef xSupbook );
+- /** Creates and appends an external SUPBOOK record from the Calc sheet nScTab. */
+- void AddExtSupbook( SCTAB nScTab );
private:
- struct XclExpSBIndex
@@ -3034,13 +3387,12 @@
XclExpSupbookList maSupbookList; /// List of all SUPBOOK records.
XclExpSBIndexVec maSBIndexVec; /// SUPBOOK and sheet name index for each Excel sheet.
sal_uInt16 mnOwnDocSB; /// Index to SUPBOOK for own document.
-@@ -464,9 +511,17 @@ public:
+@@ -464,9 +535,16 @@ public:
/** Derived classes search for a special EXTERNSHEET index for the own document. */
virtual sal_uInt16 FindExtSheet( sal_Unicode cCode ) = 0;
-+ virtual void FindExtSheet( sal_uInt16 nFileId, sal_uInt16& rnExtSheet,
-+ sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
-+ sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
++ virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
++ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry ) = 0;
+
/** Derived classes store all cells in the given range in a CRN record list. */
@@ -3052,7 +3404,7 @@
/** Derived classes find or insert an EXTERNNAME record for an add-in function name. */
virtual bool InsertAddIn(
sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
-@@ -476,6 +531,10 @@ public:
+@@ -476,6 +554,10 @@ public:
sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
const String& rApplic, const String& rTopic, const String& rItem ) = 0;
@@ -3063,13 +3415,12 @@
/** Derived classes write the entire link table to the passed stream. */
virtual void Save( XclExpStream& rStrm ) = 0;
-@@ -497,15 +556,28 @@ public:
+@@ -497,15 +579,27 @@ public:
XclExpRefLogEntry* pRefLogEntry );
virtual sal_uInt16 FindExtSheet( sal_Unicode cCode );
-+ virtual void FindExtSheet( sal_uInt16 nFileId, sal_uInt16& rnExtSheet,
-+ sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
-+ sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
++ virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
++ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry );
+
virtual void StoreCellRange( const SingleRefData& rRef1, const SingleRefData& rRef2 );
@@ -3092,13 +3443,12 @@
virtual void Save( XclExpStream& rStrm );
private:
-@@ -550,15 +622,28 @@ public:
+@@ -550,15 +644,27 @@ public:
XclExpRefLogEntry* pRefLogEntry );
virtual sal_uInt16 FindExtSheet( sal_Unicode cCode );
-+ virtual void FindExtSheet( sal_uInt16 nFileId, sal_uInt16& rnExtSheet,
-+ sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
-+ sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
++ virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
++ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry );
+
virtual void StoreCellRange( const SingleRefData& rRef1, const SingleRefData& rRef2 );
@@ -3121,7 +3471,7 @@
virtual void Save( XclExpStream& rStrm );
private:
-@@ -885,6 +970,94 @@ void XclExpExtNameDde::WriteAddData( XclExpStream& rStrm )
+@@ -885,6 +991,94 @@ void XclExpExtNameDde::WriteAddData( XclExpStream& rStrm )
mxMatrix->Save( rStrm );
}
@@ -3216,7 +3566,7 @@
// List of external names =====================================================
XclExpExtNameBuffer::XclExpExtNameBuffer( const XclExpRoot& rRoot ) :
-@@ -920,6 +1093,12 @@ sal_uInt16 XclExpExtNameBuffer::InsertDde(
+@@ -920,6 +1114,12 @@ sal_uInt16 XclExpExtNameBuffer::InsertDde(
return nIndex;
}
@@ -3229,7 +3579,7 @@
void XclExpExtNameBuffer::Save( XclExpStream& rStrm )
{
maNameList.Save( rStrm );
-@@ -1066,6 +1245,78 @@ void XclExpXct::StoreCellRange( const XclExpRoot& rRoot, const ScRange& rRange )
+@@ -1066,6 +1266,83 @@ void XclExpXct::StoreCellRange( const XclExpRoot& rRoot, const ScRange& rRange )
maUsedCells.SetMultiMarkArea( rRange );
}
@@ -3263,6 +3613,7 @@
+
+void XclExpXct::StoreCellRange( const XclExpRoot& /*rRoot*/, const ScRange& rRange, const ScToken& rToken )
+{
++ StackPrinter __stack_print__("XclExpXct::StoreCellRange");
+ if (rToken.GetType() != svMatrix)
+ return;
+
@@ -3294,12 +3645,16 @@
+ XclExpCrnRef xCrn(new XclExpCrnString(
+ s.Col() + nCol, s.Row() + nRow, pMtx->GetString(nCol, nRow)));
+ maCrnList.AppendRecord(xCrn);
++ fprintf(stdout, "XclExpXct::StoreCellRange: storing at (col=%d; row=%d) (%s)\n",
++ s.Col()+nCol, s.Row()+nRow, rtl::OUStringToOString(pMtx->GetString(nCol, nRow), RTL_TEXTENCODING_UTF8).getStr());
+ }
+ else if (pMtx->IsValueOrEmpty(nCol, nRow))
+ {
+ XclExpCrnRef xCrn(new XclExpCrnDouble(
+ s.Col() + nCol, s.Row() + nRow, pMtx->GetDouble(nCol, nRow)));
+ maCrnList.AppendRecord(xCrn);
++ fprintf(stdout, "XclExpXct::StoreCellRange: storing at (col=%d; row=%d) (%g)\n",
++ s.Col()+nCol, s.Row()+nRow, pMtx->GetDouble(nCol, nRow));
+ }
+ }
+ }
@@ -3308,7 +3663,29 @@
void XclExpXct::Save( XclExpStream& rStrm )
{
XclExpRecord::Save( rStrm );
-@@ -1206,6 +1457,41 @@ void XclExpSupbook::StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab )
+@@ -1168,6 +1445,21 @@ XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl ) :
+ mnXclTabCount( 0 )
+ {
+ SetRecSize( 2 + maUrlEncoded.GetSize() );
++
++ // We need to create all tables up front to ensure the correct table order.
++ ScExternalRefManager* pRefMgr = rRoot.GetDoc().GetExternalRefManager();
++ sal_uInt16 nFileId = pRefMgr->getExternalFileId(rUrl);
++ const vector<String>* pTabNames = pRefMgr->getAllCachedTableNames(nFileId);
++ if (!pTabNames)
++ return;
++
++ vector<String>::const_iterator itr = pTabNames->begin(), itrEnd = pTabNames->end();
++ for (; itr != itrEnd; ++itr)
++ {
++ fprintf(stdout, "XclExpSupbook::InsertTabName: name = '%s'\n",
++ rtl::OUStringToOString(*itr, RTL_TEXTENCODING_UTF8).getStr());
++ InsertTabName(*itr);
++ }
+ }
+
+ XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rApplic, const String& rTopic ) :
+@@ -1206,6 +1498,46 @@ void XclExpSupbook::StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab )
xXct->StoreCellRange( GetRoot(), rRange );
}
@@ -3334,7 +3711,7 @@
+ xXct->StoreCellRange(GetRoot(), rRange, rToken);
+}
+
-+sal_uInt16 XclExpSupbook::GetTabIndex( const String& rTabName )
++sal_uInt16 XclExpSupbook::GetTabIndex( const String& rTabName ) const
+{
+ XclExpString aXclName(rTabName);
+ size_t nSize = maXctList.GetSize();
@@ -3344,13 +3721,18 @@
+ if (aXclName == aRec->GetTabName())
+ return ulimit_cast<sal_uInt16>(i);
+ }
-+ return InsertTabName(rTabName);
++ return EXC_NOTAB;
++}
++
++sal_uInt16 XclExpSupbook::GetTabCount() const
++{
++ return ulimit_cast<sal_uInt16>(maXctList.GetSize());
+}
+
sal_uInt16 XclExpSupbook::InsertTabName( const String& rTabName )
{
DBG_ASSERT( meType == EXC_SBTYPE_EXTERN, "XclExpSupbook::InsertTabName - don't insert sheet names here" );
-@@ -1226,6 +1512,11 @@ sal_uInt16 XclExpSupbook::InsertDde( const String& rItem )
+@@ -1226,6 +1558,11 @@ sal_uInt16 XclExpSupbook::InsertDde( const String& rItem )
return GetExtNameBuffer().InsertDde( maUrl, maDdeTopic, rItem );
}
@@ -3362,7 +3744,19 @@
void XclExpSupbook::Save( XclExpStream& rStrm )
{
// SUPBOOK record
-@@ -1352,6 +1643,135 @@ void XclExpSupbookBuffer::StoreCellRange( const ScRange& rRange )
+@@ -1289,11 +1626,6 @@ XclExpSupbookBuffer::XclExpSupbookBuffer( const XclExpRoot& rRoot ) :
+ mnOwnDocSB = Append( xSupbook );
+ for( sal_uInt16 nXclTab = 0; nXclTab < nXclCnt; ++nXclTab )
+ maSBIndexVec[ nXclTab ].Set( mnOwnDocSB, nXclTab );
+-
+- // add SUPBOOKs with external references
+- for( SCTAB nScTab = 0, nScCnt = rTabInfo.GetScTabCount(); nScTab < nScCnt; ++nScTab )
+- if( rTabInfo.IsExternalTab( nScTab ) )
+- AddExtSupbook( nScTab );
+ }
+ }
+
+@@ -1352,6 +1684,135 @@ void XclExpSupbookBuffer::StoreCellRange( const ScRange& rRange )
}
}
@@ -3405,11 +3799,11 @@
+ if (!pToken)
+ return;
+
-+// const String* pTabName = pRefMgr->getExternalTableName(nFileId, rCell.Tab());
-+// if (!pTabName)
-+// return;
-+
+ sal_uInt16 nSheetId = xSupbook->GetTabIndex(rTabName);
++ if (nSheetId == EXC_NOTAB)
++ // specified table name not found in this SUPBOOK.
++ return;
++
+ FindSBIndexEntry f(nSupbookId, nSheetId);
+ fprintf(stdout, "XclExpSupbookBuffer::StoreCell: supbook id = %d; sheet id = %d\n", nSupbookId, nSheetId);
+ XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
@@ -3427,6 +3821,8 @@
+
+void XclExpSupbookBuffer::StoreCellRange( sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange )
+{
++ StackPrinter __stack_print__("XclExpSupbookBuffer::StoreCellRange");
++
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ const String* pUrl = pRefMgr->getExternalFileName(nFileId);
+ if (!pUrl)
@@ -3446,12 +3842,13 @@
+ // If this is a multi-table range, get token for each table.
+ vector<ScToken*> aMatrixList;
+ aMatrixList.reserve(nTabCount);
++
++ // This is a new'ed instance, so we must manage its life cycle here.
+ ScTokenArray* pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, rRange, NULL);
+ if (!pArray)
+ return;
+
-+ auto_ptr<ScTokenArray> pNew(pArray->Clone());
-+ for (ScToken* p = pNew->First(); p; p = pNew->Next())
++ for (ScToken* p = pArray->First(); p; p = pArray->Next())
+ {
+ if (p->GetType() == svMatrix)
+ aMatrixList.push_back(p);
@@ -3475,10 +3872,6 @@
+ aRange.aEnd.SetTab(0);
+ for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
+ {
-+ const String* pTabName = pRefMgr->getExternalTableName(nFileId, nTab);
-+ if (!pTabName)
-+ continue;
-+
+ sal_uInt16 nSheetId = nFirstSheetId + static_cast<sal_uInt16>(nTab);
+ FindSBIndexEntry f(nSupbookId, nSheetId);
+ XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
@@ -3491,6 +3884,7 @@
+ r.mnSBTab = nSheetId;
+ }
+
++ fprintf(stdout, "XclExpSupbookBuffer::StoreCellRange: supbook sheet id = %d\n", nSheetId);
+ xSupbook->StoreCellRange(nSheetId, aRange, *aMatrixList[nTab-nTab1]);
+ }
+}
@@ -3498,7 +3892,7 @@
bool XclExpSupbookBuffer::InsertAddIn(
sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rName )
{
-@@ -1383,6 +1803,72 @@ bool XclExpSupbookBuffer::InsertDde(
+@@ -1383,6 +1844,83 @@ bool XclExpSupbookBuffer::InsertDde(
return rnExtName > 0;
}
@@ -3516,9 +3910,13 @@
+ return rnExtName > 0;
+}
+
-+XclExpXti XclExpSupbookBuffer::GetXti( sal_uInt16 nFileId, sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
++XclExpXti XclExpSupbookBuffer::GetXti( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
+ XclExpRefLogEntry* pRefLogEntry )
+{
++ StackPrinter __stack_print__("XclExpSupbookBuffer::GetXti");
++ fprintf(stdout, "XclExpSupbookBuffer::GetXti: tab name = '%s'; tab span = %d\n",
++ rtl::OUStringToOString(rTabName, RTL_TEXTENCODING_UTF8).getStr(), nXclTabSpan);
++
+ XclExpXti aXti(0, EXC_NOTAB, EXC_NOTAB);
+ ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
+ const String* pUrl = pRefMgr->getExternalFileName(nFileId);
@@ -3534,13 +3932,20 @@
+ }
+ aXti.mnSupbook = nSupbookId;
+
-+ for (sal_uInt16 nTab = nFirstXclTab; nTab <= nLastXclTab; ++nTab)
++ sal_uInt16 nFirstSheetId = xSupbook->GetTabIndex(rTabName);
++ if (nFirstSheetId == EXC_NOTAB)
++ {
++ fprintf(stdout, "XclExpSupbookBuffer::GetXti: first sheet not found in SUPBOOK (%s)\n",
++ rtl::OUStringToOString(rTabName, RTL_TEXTENCODING_UTF8).getStr());
++ return aXti;
++ }
++ sal_uInt16 nSheetCount = xSupbook->GetTabCount();
++ for (sal_uInt16 i = 0; i < nXclTabSpan; ++i)
+ {
-+ const String* pTabName = pRefMgr->getExternalTableName(nFileId, nTab);
-+ if (!pTabName)
-+ continue;
++ sal_uInt16 nSheetId = nFirstSheetId + i;
++ if (nSheetId >= nSheetCount)
++ return aXti;
+
-+ sal_uInt16 nSheetId = xSupbook->GetTabIndex(*pTabName);
+ FindSBIndexEntry f(nSupbookId, nSheetId);
+ XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
+ XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
@@ -3551,16 +3956,16 @@
+ r.mnSupbook = nSupbookId;
+ r.mnSBTab = nSheetId;
+ }
-+ if (nTab == nFirstXclTab)
++ if (i == 0)
+ aXti.mnFirstSBTab = nSheetId;
-+ if (nTab == nLastXclTab)
++ if (i == nXclTabSpan - 1)
+ aXti.mnLastSBTab = nSheetId;
+ }
+
+ if (pRefLogEntry)
+ {
-+ pRefLogEntry->mnFirstXclTab = nFirstXclTab;
-+ pRefLogEntry->mnLastXclTab = nLastXclTab;
++ pRefLogEntry->mnFirstXclTab = 0;
++ pRefLogEntry->mnLastXclTab = 0;
+ if (xSupbook.is())
+ xSupbook->FillRefLogEntry(*pRefLogEntry, aXti.mnFirstSBTab, aXti.mnLastSBTab);
+ }
@@ -3571,13 +3976,42 @@
void XclExpSupbookBuffer::Save( XclExpStream& rStrm )
{
maSupbookList.Save( rStrm );
-@@ -1485,11 +1971,28 @@ sal_uInt16 XclExpLinkManagerImpl5::FindExtSheet( sal_Unicode cCode )
+@@ -1424,27 +1962,6 @@ sal_uInt16 XclExpSupbookBuffer::Append( XclExpSupbookRef xSupbook )
+ return ulimit_cast< sal_uInt16 >( maSupbookList.GetSize() - 1 );
+ }
+
+-void XclExpSupbookBuffer::AddExtSupbook( SCTAB nScTab )
+-{
+- sal_uInt16 nXclTab = GetTabInfo().GetXclTab( nScTab );
+- DBG_ASSERT( nXclTab < maSBIndexVec.size(), "XclExpSupbookBuffer::AddExtSupbook - out of range" );
+-
+- // find ext doc name or append new one, save position in maSBIndexBuffer
+- const String& rUrl = GetDoc().GetLinkDoc( nScTab );
+- DBG_ASSERT( rUrl.Len(), "XclExpSupbookBuffer::AddExtSupbook - missing external linked sheet" );
+- sal_uInt16 nSupbook;
+- XclExpSupbookRef xSupbook;
+- if( !GetSupbookUrl( xSupbook, nSupbook, rUrl ) )
+- {
+- xSupbook.reset( new XclExpSupbook( GetRoot(), rUrl ) );
+- nSupbook = Append( xSupbook );
+- }
+-
+- // append new sheet name, save SUPBOOK and sheet position in maSBIndexVec
+- maSBIndexVec[ nXclTab ].mnSupbook = nSupbook;
+- maSBIndexVec[ nXclTab ].mnSBTab = xSupbook->InsertTabName( GetDoc().GetLinkTab( nScTab ) );
+-}
+-
+ // Export link manager ========================================================
+
+ XclExpLinkManagerImpl::XclExpLinkManagerImpl( const XclExpRoot& rRoot ) :
+@@ -1485,11 +2002,29 @@ sal_uInt16 XclExpLinkManagerImpl5::FindExtSheet( sal_Unicode cCode )
return nExtSheet;
}
+void XclExpLinkManagerImpl5::FindExtSheet(
-+ sal_uInt16 /*nFileId*/, sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnFirstSBTab*/, sal_uInt16& /*rnLastSBTab*/,
-+ sal_uInt16 /*nFirstXclTab*/, sal_uInt16 /*nLastXclTab*/, XclExpRefLogEntry* /*pRefLogEntry*/ )
++ sal_uInt16 /*nFileId*/, const String& /*rTabName*/, sal_uInt16 /*nXclTabSpan*/,
++ sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnFirstSBTab*/, sal_uInt16& /*rnLastSBTab*/,
++ XclExpRefLogEntry* /*pRefLogEntry*/ )
+{
+ // not implemented
+}
@@ -3600,7 +4034,7 @@
bool XclExpLinkManagerImpl5::InsertAddIn(
sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
{
-@@ -1510,6 +2013,14 @@ bool XclExpLinkManagerImpl5::InsertDde(
+@@ -1510,6 +2045,14 @@ bool XclExpLinkManagerImpl5::InsertDde(
return false;
}
@@ -3615,15 +4049,16 @@
void XclExpLinkManagerImpl5::Save( XclExpStream& rStrm )
{
if( sal_uInt16 nExtSheetCount = GetExtSheetCount() )
-@@ -1630,6 +2141,16 @@ sal_uInt16 XclExpLinkManagerImpl8::FindExtSheet( sal_Unicode cCode )
+@@ -1630,6 +2173,17 @@ sal_uInt16 XclExpLinkManagerImpl8::FindExtSheet( sal_Unicode cCode )
return InsertXti( maSBBuffer.GetXti( EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
}
+void XclExpLinkManagerImpl8::FindExtSheet(
-+ sal_uInt16 nFileId, sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
-+ sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab, XclExpRefLogEntry* pRefLogEntry )
++ sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
++ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
++ XclExpRefLogEntry* pRefLogEntry )
+{
-+ XclExpXti aXti = maSBBuffer.GetXti(nFileId, nFirstXclTab, nLastXclTab, pRefLogEntry);
++ XclExpXti aXti = maSBBuffer.GetXti(nFileId, rTabName, nXclTabSpan, pRefLogEntry);
+ rnExtSheet = InsertXti(aXti);
+ rnFirstSBTab = aXti.mnFirstSBTab;
+ rnLastSBTab = aXti.mnLastSBTab;
@@ -3632,7 +4067,7 @@
void XclExpLinkManagerImpl8::StoreCellRange( const SingleRefData& rRef1, const SingleRefData& rRef2 )
{
if( !rRef1.IsDeleted() && !rRef2.IsDeleted() && (rRef1.nTab >= 0) && (rRef2.nTab >= 0) )
-@@ -1652,6 +2173,19 @@ void XclExpLinkManagerImpl8::StoreCellRange( const SingleRefData& rRef1, const S
+@@ -1652,6 +2206,19 @@ void XclExpLinkManagerImpl8::StoreCellRange( const SingleRefData& rRef1, const S
}
}
@@ -3652,7 +4087,7 @@
bool XclExpLinkManagerImpl8::InsertAddIn(
sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
{
-@@ -1677,6 +2211,18 @@ bool XclExpLinkManagerImpl8::InsertDde(
+@@ -1677,6 +2244,18 @@ bool XclExpLinkManagerImpl8::InsertDde(
return false;
}
@@ -3671,22 +4106,21 @@
void XclExpLinkManagerImpl8::Save( XclExpStream& rStrm )
{
if( !maXtiVec.empty() )
-@@ -1745,6 +2291,14 @@ sal_uInt16 XclExpLinkManager::FindExtSheet( sal_Unicode cCode )
+@@ -1745,6 +2324,13 @@ sal_uInt16 XclExpLinkManager::FindExtSheet( sal_Unicode cCode )
return mxImpl->FindExtSheet( cCode );
}
-+void XclExpLinkManager::FindExtSheet( sal_uInt16 nFileId, sal_uInt16& rnExtSheet,
-+ sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
-+ sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
++void XclExpLinkManager::FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
++ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry )
+{
-+ mxImpl->FindExtSheet( nFileId, rnExtSheet, rnFirstSBTab, rnLastSBTab, nFirstXclTab, nLastXclTab, pRefLogEntry );
++ mxImpl->FindExtSheet( nFileId, rTabName, nXclTabSpan, rnExtSheet, rnFirstSBTab, rnLastSBTab, pRefLogEntry );
+}
+
void XclExpLinkManager::StoreCell( const SingleRefData& rRef )
{
mxImpl->StoreCellRange( rRef, rRef );
-@@ -1755,6 +2309,16 @@ void XclExpLinkManager::StoreCellRange( const ComplRefData& rRef )
+@@ -1755,6 +2341,16 @@ void XclExpLinkManager::StoreCellRange( const ComplRefData& rRef )
mxImpl->StoreCellRange( rRef.Ref1, rRef.Ref2 );
}
@@ -3703,7 +4137,7 @@
bool XclExpLinkManager::InsertAddIn(
sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
{
-@@ -1768,6 +2332,13 @@ bool XclExpLinkManager::InsertDde(
+@@ -1768,6 +2364,13 @@ bool XclExpLinkManager::InsertDde(
return mxImpl->InsertDde( rnExtSheet, rnExtName, rApplic, rTopic, rItem );
}
@@ -3718,13 +4152,20 @@
{
mxImpl->Save( rStrm );
diff --git sc/source/filter/excel/xilink.cxx sc/source/filter/excel/xilink.cxx
-index 01932a5..38b846b 100644
+index 01932a5..ae4623c 100644
--- sc/source/filter/excel/xilink.cxx
+++ sc/source/filter/excel/xilink.cxx
-@@ -39,6 +39,31 @@
+@@ -38,6 +38,37 @@
+ #include "xistream.hxx"
#include "xihelper.hxx"
#include "xiname.hxx"
-
++#include "excform.hxx"
++#include "tokenarray.hxx"
++#include "externalrefmgr.hxx"
++
++#include <vector>
++
++using ::std::vector;
+
+namespace {
+
@@ -3749,14 +4190,15 @@
+};
+
+}
-+
+
// ============================================================================
// *** Helper classes ***
- // ============================================================================
-@@ -52,8 +77,10 @@ public:
+@@ -52,8 +83,12 @@ public:
/** Reads a cached value and stores it with its cell address. */
explicit XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
++ const XclAddress& GetAddress() const;
++
+#if 0
/** Copies the cached value to sheet nTab in the document. */
void SetCell( const XclImpRoot& rRoot, SCTAB nScTab ) const;
@@ -3764,7 +4206,14 @@
private:
XclAddress maXclPos; /// Excel position of the cached cell.
-@@ -76,11 +103,13 @@ public:
+@@ -71,16 +106,21 @@ public:
+ ~XclImpSupbookTab();
+
+ inline const String& GetTabName() const { return maTabName; }
++#if 0
+ inline SCTAB GetScTab() const { return mnScTab; }
+-
++#endif
/** Reads a CRN record (external referenced cell) at the specified address. */
void ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos );
@@ -3775,10 +4224,20 @@
const XclImpRoot& rRoot, const String& rAbsUrl,
const String& rFilterName, const String& rFilterOpt );
+#endif
++
++ void LoadCachedValues(ScExternalRefCache::Table* pCacheTable);
private:
typedef ScfDelList< XclImpCrn > XclImpCrnList;
-@@ -112,11 +141,13 @@ public:
+@@ -105,18 +145,20 @@ public:
+ /** Reads a CRN record (external referenced cell). */
+ void ReadCrn( XclImpStream& rStrm );
+ /** Reads an EXTERNNAME record. */
+- void ReadExternname( XclImpStream& rStrm );
++ void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
+
+ /** Returns the SUPBOOK record type. */
+ inline XclSupbookType GetType() const { return meType; }
/** Returns the URL of the external document. */
inline const String& GetXclUrl() const { return maXclUrl; }
@@ -3793,22 +4252,35 @@
/** Returns the external name specified by an index from the Excel document (one-based). */
const XclImpExtName* GetExternName( sal_uInt16 nXclIndex ) const;
-@@ -128,10 +159,14 @@ public:
+@@ -128,10 +170,18 @@ public:
/** Returns the specified macro name (1-based) or an empty string on error. */
const String& GetMacroName( sal_uInt16 nXclNameIdx ) const;
+ const String& GetTabName( sal_uInt16 nXtiTab ) const;
+
++ sal_uInt16 GetTabCount() const;
++
+#if 0
/** Creates all sheets of this external document.
@param nFirstTab The external Excel index of the first sheet to be created.
@param nLastTab The external Excel index of the last sheet to be created. */
void CreateTables( sal_uInt16 nSBTabFirst, sal_uInt16 nSBTabLast );
+#endif
++
++ void LoadCachedValues();
private:
typedef ScfDelList< XclImpSupbookTab > XclImpSupbookTabList;
-@@ -191,6 +226,13 @@ public:
+@@ -180,7 +230,7 @@ public:
+ /** Reads a CRN record and appends it to the current SUPBOOK. */
+ void ReadCrn( XclImpStream& rStrm );
+ /** Reads an EXTERNNAME record and appends it to the current SUPBOOK. */
+- void ReadExternname( XclImpStream& rStrm );
++ void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
+
+ /** Returns true, if the specified XTI entry contains an internal reference. */
+ bool IsSelfRef( sal_uInt16 nXtiIndex ) const;
+@@ -191,6 +241,13 @@ public:
sal_uInt16 nXtiIndex ) const;
/** Returns the specified external name or 0 on error. */
const XclImpExtName* GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const;
@@ -3822,7 +4294,7 @@
/** Tries to decode the URL of the specified XTI entry to OLE or DDE link components.
@descr For DDE links: Decodes to application name and topic.
For OLE object links: Decodes to class name and document URL.
-@@ -198,19 +240,23 @@ public:
+@@ -198,19 +255,23 @@ public:
bool GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const;
/** Returns the specified macro name or an empty string on error. */
const String& GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const;
@@ -3848,15 +4320,88 @@
/** Finds the largest range of sheet indexes in a SUPBOOK after a start sheet index.
@param rnSBTabFirst (out-param) The first sheet index of the range in SUPBOOK is returned here.
-@@ -341,6 +387,7 @@ XclImpCrn::XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos ) :
+@@ -291,13 +352,16 @@ sal_uInt16 XclImpTabInfo::GetCurrentIndex( sal_uInt16 nCreatedId, sal_uInt16 nMa
+
+ // External names =============================================================
+
+-XclImpExtName::XclImpExtName( XclImpStream& rStrm, bool bAddIn )
++XclImpExtName::XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm, bool bAddIn, ExcelToSc* pFormulaConv )
+ {
++ StackPrinter __stack_print__("XclImpExtName::XclImpExtName");
+ sal_uInt16 nFlags;
+ sal_uInt8 nLen;
+
+ rStrm >> nFlags >> mnStorageId >> nLen ;
+ maName = rStrm.ReadUniString( nLen );
++ fprintf(stdout, "XclImpExtName::XclImpExtName: flags = 0x%2.2X; storage id = %d; name = '%s'\n",
++ nFlags, mnStorageId, rtl::OUStringToOString(maName, RTL_TEXTENCODING_UTF8).getStr());
+
+ if( ::get_flag( nFlags, EXC_EXTN_BUILTIN ) || !::get_flag( nFlags, EXC_EXTN_OLE_OR_DDE ) )
+ {
+@@ -319,6 +383,35 @@ XclImpExtName::XclImpExtName( XclImpStream& rStrm, bool bAddIn )
+
+ if( (meType == xlExtDDE) && (rStrm.GetRecLeft() > 1) )
+ mxDdeMatrix.reset( new XclImpCachedMatrix( rStrm ) );
++
++ if (meType == xlExtName)
++ {
++ if (mnStorageId == 0)
++ {
++ fprintf(stdout, "XclImpExtName::XclImpExtName: global external name\n");
++ if (pFormulaConv)
++ {
++ const ScTokenArray* pArray = NULL;
++ sal_uInt16 nFmlaLen;
++ rStrm >> nFmlaLen;
++ vector<String> aTabNames;
++ sal_uInt16 nCount = rSupbook.GetTabCount();
++ fprintf(stdout, "XclImpExtName::XclImpExtName: tab count = %d\n", nCount);
++ aTabNames.reserve(nCount);
++ for (sal_uInt16 i = 0; i < nCount; ++i)
++ aTabNames.push_back(rSupbook.GetTabName(i));
++
++ pFormulaConv->ConvertExternName(pArray, rStrm, nFmlaLen, rSupbook.GetXclUrl(), aTabNames);
++ if (pArray)
++ {
++ fprintf(stdout, "XclImpExtName::XclImpExtName: formula token processed\n");
++ mxArray.reset(pArray->Clone());
++ }
++ }
++ }
++ else
++ fprintf(stdout, "XclImpExtName::XclImpExtName: external name for sheet %ld\n", mnStorageId);
++ }
+ }
+
+ XclImpExtName::~XclImpExtName()
+@@ -333,6 +426,13 @@ void XclImpExtName::CreateDdeData( ScDocument& rDoc, const String& rApplic, cons
+ rDoc.CreateDdeLink( rApplic, rTopic, maName, SC_DDE_DEFAULT, xResults );
+ }
+
++void XclImpExtName::CreateExtNameData( ScDocument& rDoc, sal_uInt16 nFileId ) const
++{
++ StackPrinter __stack_print__("XclImpExtName::CreateExtNameData");
++ ScExternalRefManager* pRefMgr = rDoc.GetExternalRefManager();
++ pRefMgr->storeRangeNameTokens(nFileId, maName, *mxArray);
++}
++
+ // Cached external cells ======================================================
+
+ XclImpCrn::XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos ) :
+@@ -341,6 +441,12 @@ XclImpCrn::XclImpCrn( XclImpStream& rStrm, const XclAddress& rXclPos ) :
{
}
++const XclAddress& XclImpCrn::GetAddress() const
++{
++ return maXclPos;
++}
++
+#if 0
void XclImpCrn::SetCell( const XclImpRoot& rRoot, SCTAB nScTab ) const
{
ScAddress aScPos( ScAddress::UNINITIALIZED );
-@@ -365,6 +412,7 @@ void XclImpCrn::SetCell( const XclImpRoot& rRoot, SCTAB nScTab ) const
+@@ -365,6 +471,7 @@ void XclImpCrn::SetCell( const XclImpRoot& rRoot, SCTAB nScTab ) const
}
}
}
@@ -3864,7 +4409,7 @@
// Sheet in an external document ==============================================
-@@ -383,6 +431,7 @@ void XclImpSupbookTab::ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos )
+@@ -383,6 +490,7 @@ void XclImpSupbookTab::ReadCrn( XclImpStream& rStrm, const XclAddress& rXclPos )
maCrnList.Append( new XclImpCrn( rStrm, rXclPos ) );
}
@@ -3872,17 +4417,71 @@
void XclImpSupbookTab::CreateAndFillTable( const XclImpRoot& rRoot,
const String& rAbsUrl, const String& rFilterName, const String& rFilterOpt )
{
-@@ -391,6 +440,7 @@ void XclImpSupbookTab::CreateAndFillTable( const XclImpRoot& rRoot,
+@@ -391,6 +499,53 @@ void XclImpSupbookTab::CreateAndFillTable( const XclImpRoot& rRoot,
for( const XclImpCrn* pCrn = maCrnList.First(); pCrn; pCrn = maCrnList.Next() )
pCrn->SetCell( rRoot, mnScTab );
}
+#endif
++
++void XclImpSupbookTab::LoadCachedValues(ScExternalRefCache::Table* pCacheTable)
++{
++ StackPrinter __stack_print__("XclImpSupbookTab::LoadCachedValues");
++ if (maCrnList.Empty())
++ {
++ fprintf(stdout, "XclImpSupbookTab::LoadCachedValues: no CRN record to speak of\n");
++ return;
++ }
++
++ for (XclImpCrn* p = maCrnList.First(); p; p = maCrnList.Next())
++ {
++ const XclAddress& rAddr = p->GetAddress();
++ fprintf(stdout, "XclImpSupbookTab::LoadCachedValues: col = %d; row = %d\n", rAddr.mnCol, rAddr.mnRow);
++ switch (p->GetType())
++ {
++ case EXC_CACHEDVAL_BOOL:
++ fprintf(stdout, "XclImpSupbookTab::LoadCachedValues: bool\n");
++ break;
++ case EXC_CACHEDVAL_DOUBLE:
++ {
++ double f = p->GetValue();
++ ScExternalRefCache::TokenRef pToken(new ScDoubleToken(f));
++ pCacheTable->setCell(rAddr.mnRow, rAddr.mnCol, pToken);
++ fprintf(stdout, "XclImpSupbookTab::LoadCachedValues: double (%g)\n", f);
++ }
++ break;
++ case EXC_CACHEDVAL_EMPTY:
++ fprintf(stdout, "XclImpSupbookTab::LoadCachedValues: empty\n");
++ break;
++ case EXC_CACHEDVAL_ERROR:
++ fprintf(stdout, "XclImpSupbookTab::LoadCachedValues: error\n");
++ break;
++ case EXC_CACHEDVAL_STRING:
++ {
++ const String& rStr = p->GetString();
++ ScExternalRefCache::TokenRef pToken(new ScStringToken(rStr));
++ pCacheTable->setCell(rAddr.mnRow, rAddr.mnCol, pToken);
++ fprintf(stdout, "XclImpSupbookTab::LoadCachedValues: string (%s)\n", rtl::OUStringToOString(rStr, RTL_TEXTENCODING_UTF8).getStr());
++ }
++ break;
++ default:
++ fprintf(stdout, "XclImpSupbookTab::LoadCachedValues: other type\n");
++ }
++ }
++}
// External document (SUPBOOK) ================================================
-@@ -457,13 +507,14 @@ void XclImpSupbook::ReadExternname( XclImpStream& rStrm )
+@@ -453,17 +608,20 @@ void XclImpSupbook::ReadCrn( XclImpStream& rStrm )
+ }
+ }
+
+-void XclImpSupbook::ReadExternname( XclImpStream& rStrm )
++void XclImpSupbook::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
{
- maExtNameList.Append( new XclImpExtName( rStrm, meType == EXC_SBTYPE_ADDIN ) );
+- maExtNameList.Append( new XclImpExtName( rStrm, meType == EXC_SBTYPE_ADDIN ) );
++ StackPrinter __stack_print__("XclImpSupbook::ReadExternname");
++ fprintf(stdout, "XclImpSupbook::ReadExternname: tab count = %ld %ld\n", GetTabCount(), maSupbTabList.Count());
++ maExtNameList.Append( new XclImpExtName( *this, rStrm, meType == EXC_SBTYPE_ADDIN, pFormulaConv ) );
}
-
+#if 0
@@ -3898,7 +4497,7 @@
}
SCTAB XclImpSupbook::GetScTabNum( const String& rTabName ) const
-@@ -473,6 +524,15 @@ SCTAB XclImpSupbook::GetScTabNum( const String& rTabName ) const
+@@ -473,6 +631,15 @@ SCTAB XclImpSupbook::GetScTabNum( const String& rTabName ) const
return pSBTab->GetScTab();
return SCTAB_INVALID;
}
@@ -3914,7 +4513,7 @@
const XclImpExtName* XclImpSupbook::GetExternName( sal_uInt16 nXclIndex ) const
{
-@@ -492,6 +552,22 @@ const String& XclImpSupbook::GetMacroName( sal_uInt16 nXclNameIdx ) const
+@@ -492,6 +659,27 @@ const String& XclImpSupbook::GetMacroName( sal_uInt16 nXclNameIdx ) const
return (pName && pName->IsVBName()) ? pName->GetScName() : EMPTY_STRING;
}
@@ -3933,19 +4532,60 @@
+ return EMPTY_STRING;
+}
+
++sal_uInt16 XclImpSupbook::GetTabCount() const
++{
++ return ulimit_cast<sal_uInt16>(maSupbTabList.Count());
++}
++
+#if 0
void XclImpSupbook::CreateTables( sal_uInt16 nSBTabFirst, sal_uInt16 nSBTabLast )
{
if( (meType == EXC_SBTYPE_EXTERN) && (GetExtDocOptions().GetDocSettings().mnLinkCnt == 0) && GetDocShell() )
-@@ -508,6 +584,7 @@ void XclImpSupbook::CreateTables( sal_uInt16 nSBTabFirst, sal_uInt16 nSBTabLast
+@@ -508,6 +696,43 @@ void XclImpSupbook::CreateTables( sal_uInt16 nSBTabFirst, sal_uInt16 nSBTabLast
pSBTab->CreateAndFillTable( GetRoot(), aAbsUrl, maFilterName, maFilterOpt );
}
}
+#endif
++
++void XclImpSupbook::LoadCachedValues()
++{
++ StackPrinter __stack_print__("XclImpSupbook::LoadCachedValues");
++ if (meType == EXC_SBTYPE_SELF)
++ fprintf(stdout, "XclImpSupbook::LoadCachedValues: internal book\n");
++
++ if (meType != EXC_SBTYPE_EXTERN || GetExtDocOptions().GetDocSettings().mnLinkCnt > 0)
++ {
++ fprintf(stdout, "XclImpSupbook::LoadCachedValues: don't load cached values\n");
++ return;
++ }
++
++ String aAbsUrl( ScGlobal::GetAbsDocName(maXclUrl, GetDocShell()) );
++ fprintf(stdout, "XclImpSupbook::LoadCachedValues: doc url = '%s'\n",
++ rtl::OUStringToOString(aAbsUrl, RTL_TEXTENCODING_UTF8).getStr());
++
++ ScExternalRefManager* pRefMgr = GetRoot().GetDoc().GetExternalRefManager();
++ sal_uInt16 nFileId = pRefMgr->getExternalFileId(aAbsUrl);
++
++ sal_uInt16 nCount = maSupbTabList.Count();
++ for (sal_uInt16 i = 0; i < nCount; ++i)
++ {
++ XclImpSupbookTab* pTab = maSupbTabList.GetObject(i);
++ if (!pTab)
++ {
++ fprintf(stdout, "XclImpSupbook::LoadCachedValues: supbook table instance is NULL!\n");
++ return;
++ }
++
++ const String& rTabName = pTab->GetTabName();
++ fprintf(stdout, "XclImpSupbook::LoadCachedValues: tab name = '%s'\n", rtl::OUStringToOString(rTabName, RTL_TEXTENCODING_UTF8).getStr());
++ ScExternalRefCache::Table* pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName);
++ pTab->LoadCachedValues(pCacheTable);
++ }
++}
// Import link manager ========================================================
-@@ -531,7 +608,7 @@ void XclImpLinkManagerImpl::ReadExternsheet( XclImpStream& rStrm )
+@@ -531,7 +756,7 @@ void XclImpLinkManagerImpl::ReadExternsheet( XclImpStream& rStrm )
--nXtiCount;
}
@@ -3954,7 +4594,20 @@
}
void XclImpLinkManagerImpl::ReadSupbook( XclImpStream& rStrm )
-@@ -570,8 +647,8 @@ bool XclImpLinkManagerImpl::GetScTabRange(
+@@ -551,10 +776,10 @@ void XclImpLinkManagerImpl::ReadCrn( XclImpStream& rStrm )
+ pSupbook->ReadCrn( rStrm );
+ }
+
+-void XclImpLinkManagerImpl::ReadExternname( XclImpStream& rStrm )
++void XclImpLinkManagerImpl::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
+ {
+ if( XclImpSupbook* pSupbook = maSupbookList.Last() )
+- pSupbook->ReadExternname( rStrm );
++ pSupbook->ReadExternname( rStrm, pFormulaConv );
+ }
+
+ bool XclImpLinkManagerImpl::IsSelfRef( sal_uInt16 nXtiIndex ) const
+@@ -570,8 +795,8 @@ bool XclImpLinkManagerImpl::GetScTabRange(
{
if( const XclImpSupbook* pSupbook = maSupbookList.GetObject( pXti->mnSupbook ) )
{
@@ -3965,7 +4618,7 @@
return true;
}
}
-@@ -584,6 +661,20 @@ const XclImpExtName* XclImpLinkManagerImpl::GetExternName( sal_uInt16 nXtiIndex,
+@@ -584,6 +809,20 @@ const XclImpExtName* XclImpLinkManagerImpl::GetExternName( sal_uInt16 nXtiIndex,
return pSupbook ? pSupbook->GetExternName( nExtName ) : 0;
}
@@ -3986,7 +4639,7 @@
bool XclImpLinkManagerImpl::GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const
{
const XclImpSupbook* pSupbook = GetSupbook( nXtiIndex );
-@@ -595,12 +686,18 @@ const String& XclImpLinkManagerImpl::GetMacroName( sal_uInt16 nExtSheet, sal_uIn
+@@ -595,12 +834,18 @@ const String& XclImpLinkManagerImpl::GetMacroName( sal_uInt16 nExtSheet, sal_uIn
const XclImpSupbook* pSupbook = GetSupbook( nExtSheet );
return pSupbook ? pSupbook->GetMacroName( nExtName ) : EMPTY_STRING;
}
@@ -4006,7 +4659,7 @@
const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( sal_uInt32 nXtiIndex ) const
{
-@@ -616,6 +713,7 @@ const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( const String& rUrl ) con
+@@ -616,6 +861,7 @@ const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( const String& rUrl ) con
return 0;
}
@@ -4014,7 +4667,7 @@
void XclImpLinkManagerImpl::CreateTables()
{
DBG_ASSERT( !mbCreated, "XclImpLinkManager::CreateTables - multiple call" );
-@@ -637,6 +735,15 @@ void XclImpLinkManagerImpl::CreateTables()
+@@ -637,6 +883,21 @@ void XclImpLinkManagerImpl::CreateTables()
}
mbCreated = true;
}
@@ -4022,15 +4675,33 @@
+
+void XclImpLinkManagerImpl::LoadCachedValues()
+{
++ StackPrinter __stack_print__("XclImpLinkManagerImpl::LoadCachedValues");
+ // Read all CRN records which can be accessed via XclImpSupbook, and store
+ // the cached values to the external reference manager.
+
-+ // TODO: Implement this.
++ sal_uInt32 nCount = maSupbookList.Count();
++ for (sal_uInt16 nSupbook = 0; nSupbook < nCount; ++nSupbook)
++ {
++ XclImpSupbook* pSupbook = maSupbookList.GetObject(nSupbook);
++ pSupbook->LoadCachedValues();
++ }
+}
bool XclImpLinkManagerImpl::FindNextTabRange(
sal_uInt16& rnSBTabFirst, sal_uInt16& rnSBTabLast,
-@@ -707,6 +814,16 @@ const XclImpExtName* XclImpLinkManager::GetExternName( sal_uInt16 nXtiIndex, sal
+@@ -686,9 +947,9 @@ void XclImpLinkManager::ReadCrn( XclImpStream& rStrm )
+ mxImpl->ReadCrn( rStrm );
+ }
+
+-void XclImpLinkManager::ReadExternname( XclImpStream& rStrm )
++void XclImpLinkManager::ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv )
+ {
+- mxImpl->ReadExternname( rStrm );
++ mxImpl->ReadExternname( rStrm, pFormulaConv );
+ }
+
+ bool XclImpLinkManager::IsSelfRef( sal_uInt16 nXtiIndex ) const
+@@ -707,6 +968,16 @@ const XclImpExtName* XclImpLinkManager::GetExternName( sal_uInt16 nXtiIndex, sal
return mxImpl->GetExternName( nXtiIndex, nExtName );
}
@@ -4047,7 +4718,7 @@
bool XclImpLinkManager::GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const
{
return mxImpl->GetLinkData( rApplic, rTopic, nXtiIndex );
-@@ -716,11 +833,16 @@ const String& XclImpLinkManager::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16
+@@ -716,11 +987,16 @@ const String& XclImpLinkManager::GetMacroName( sal_uInt16 nExtSheet, sal_uInt16
{
return mxImpl->GetMacroName( nExtSheet, nExtName );
}
@@ -4079,10 +4750,29 @@
public:
inline XclImpChTrFmlConverter(
diff --git sc/source/filter/inc/excform.hxx sc/source/filter/inc/excform.hxx
-index 915dd98..6913b25 100644
+index 915dd98..1b36638 100644
--- sc/source/filter/inc/excform.hxx
+++ sc/source/filter/inc/excform.hxx
-@@ -113,8 +113,9 @@ private:
+@@ -35,6 +35,7 @@
+ #include "xiroot.hxx"
+ #include "formel.hxx"
+
++#include <vector>
+
+ class ScRangeList;
+
+@@ -64,6 +65,10 @@ public:
+ bool bAllowArrays, const FORMULA_TYPE eFT = FT_CellFormula );
+
+ virtual ConvErr Convert( _ScRangeListTabs&, XclImpStream& rStrm, sal_Size nFormulaLen, SCsTAB nTab, const FORMULA_TYPE eFT = FT_CellFormula );
++
++ virtual ConvErr ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
++ const String& rUrl, const ::std::vector<String>& rTabNames );
++
+ virtual BOOL GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sal_Size nLen );
+
+ void GetDummy( const ScTokenArray*& );
+@@ -113,8 +118,9 @@ private:
void ExcRelToScRel8( UINT16 nRow, UINT16 nCol, SingleRefData&,
const BOOL bName );
@@ -4094,6 +4784,16 @@
public:
ExcelToSc8( const XclImpRoot& rRoot );
+@@ -124,6 +130,9 @@ public:
+
+ virtual ConvErr Convert( _ScRangeListTabs&, XclImpStream& rStrm, sal_Size nFormulaLen, SCsTAB nTab, const FORMULA_TYPE eFT = FT_CellFormula );
+
++ virtual ConvErr ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
++ const String& rUrl, const ::std::vector<String>& rTabNames );
++
+ static inline BOOL IsComplRowRange( const UINT16 nRow1, const UINT16 nRow2 );
+
+ virtual BOOL GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sal_Size nLen );
diff --git sc/source/filter/inc/fdumper.hxx sc/source/filter/inc/fdumper.hxx
index aea8de6..8f57403 100644
--- sc/source/filter/inc/fdumper.hxx
@@ -4202,16 +4902,15 @@
#endif
diff --git sc/source/filter/inc/xelink.hxx sc/source/filter/inc/xelink.hxx
-index 795219c..53e864f 100644
+index 795219c..ee53c3a 100644
--- sc/source/filter/inc/xelink.hxx
+++ sc/source/filter/inc/xelink.hxx
-@@ -173,11 +173,20 @@ public:
+@@ -173,11 +173,19 @@ public:
/** Searches for a special EXTERNSHEET index for the own document. */
sal_uInt16 FindExtSheet( sal_Unicode cCode );
-+ void FindExtSheet( sal_uInt16 nFileId, sal_uInt16& rnExtSheet,
-+ sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
-+ sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
++ void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
++ sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
+ XclExpRefLogEntry* pRefLogEntry = NULL );
+
/** Stores the cell with the given address in a CRN record list. */
@@ -4226,7 +4925,7 @@
/** Finds or inserts an EXTERNNAME record for an add-in function name.
@param rnExtSheet (out-param) Returns the index of the EXTSHEET structure for the add-in function name.
@param rnExtName (out-param) Returns the 1-based EXTERNNAME record index.
-@@ -193,6 +202,10 @@ public:
+@@ -193,6 +201,10 @@ public:
sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
const String& rApplic, const String& rTopic, const String& rItem );
@@ -4238,10 +4937,56 @@
virtual void Save( XclExpStream& rStrm );
diff --git sc/source/filter/inc/xilink.hxx sc/source/filter/inc/xilink.hxx
-index 0d547fe..c9d7567 100644
+index 0d547fe..ffb9f4c 100644
--- sc/source/filter/inc/xilink.hxx
+++ sc/source/filter/inc/xilink.hxx
-@@ -179,6 +179,11 @@ public:
+@@ -107,6 +107,8 @@ enum XclImpExtNameType
+ // ----------------------------------------------------------------------------
+
+ class XclImpCachedMatrix;
++class ScTokenArray;
++class XclImpSupbook;
+
+ /** Stores contents of an external name.
+ @descr Supported: External defined names, AddIn names, DDE links and OLE objects. */
+@@ -114,21 +116,26 @@ class XclImpExtName
+ {
+ public:
+ /** Reads the external name from the stream. */
+- explicit XclImpExtName( XclImpStream& rStrm, bool bAddIn = false );
++ explicit XclImpExtName( const XclImpSupbook& rSupbook, XclImpStream& rStrm, bool bAddIn = false,
++ ExcelToSc* pFormulaConv = NULL );
+ ~XclImpExtName();
+
+ /** Create and apply the cached list of this DDE Link to the document. */
+ void CreateDdeData( ScDocument& rDoc,
+ const String& rApplc, const String& rExtDoc ) const;
+
++ void CreateExtNameData( ScDocument& rDoc, sal_uInt16 nFileId ) const;
++
+ inline XclImpExtNameType GetType() const { return meType; }
+ inline const String& GetName() const { return maName; }
+ inline sal_uInt32 GetStorageId() const { return mnStorageId; }
+
+ private:
+ typedef ::std::auto_ptr< XclImpCachedMatrix > XclImpCachedMatrixPtr;
++ typedef ::std::auto_ptr< ScTokenArray > TokenArrayPtr;
+
+ XclImpCachedMatrixPtr mxDdeMatrix; /// Cached results of the DDE link.
++ TokenArrayPtr mxArray; /// Formula tokens for external name.
+ String maName; /// The name of the external name.
+ sal_uInt32 mnStorageId; /// Storage ID for OLE object storages.
+ XclImpExtNameType meType; /// Type of the external name.
+@@ -168,7 +175,7 @@ public:
+ /** Reads a CRN record and appends it to the current SUPBOOK. */
+ void ReadCrn( XclImpStream& rStrm );
+ /** Reads an EXTERNNAME record and appends it to the current SUPBOOK. */
+- void ReadExternname( XclImpStream& rStrm );
++ void ReadExternname( XclImpStream& rStrm, ExcelToSc* pFormulaConv = NULL );
+
+ /** Returns true, if the specified XTI entry contains an internal reference. */
+ bool IsSelfRef( sal_uInt16 nXtiIndex ) const;
+@@ -179,6 +186,11 @@ public:
sal_uInt16 nXtiIndex ) const;
/** Returns the specified external name or 0 on error. */
const XclImpExtName* GetExternName( sal_uInt16 nXtiIndex, sal_uInt16 nExtName ) const;
@@ -4253,7 +4998,7 @@
/** Tries to decode the URL of the specified XTI entry to OLE or DDE link components.
@descr For DDE links: Decodes to application name and topic.
For OLE object links: Decodes to class name and document URL.
-@@ -186,10 +191,12 @@ public:
+@@ -186,10 +198,12 @@ public:
bool GetLinkData( String& rApplic, String& rTopic, sal_uInt16 nXtiIndex ) const;
/** Returns the specified macro name or an empty string on error. */
const String& GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const;
@@ -4291,12 +5036,24 @@
return rChangeTrack.Read3DTabRefInfo( rFirstTab, rLastTab );
}
+diff --git sc/source/ui/docshell/docsh.cxx sc/source/ui/docshell/docsh.cxx
+index c702954..219b227 100644
+--- sc/source/ui/docshell/docsh.cxx
++++ sc/source/ui/docshell/docsh.cxx
+@@ -2093,6 +2093,7 @@ bool lcl_NeedHashRegen(const ScDocument& rDoc, ScPasswordHash eHash)
+
+ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
+ {
++ fprintf(stdout, "ScDocShell::ConvertTo: ****************************************\n");
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertTo" );
+
+ ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
diff --git sc/source/ui/docshell/externalrefmgr.cxx sc/source/ui/docshell/externalrefmgr.cxx
new file mode 100644
-index 0000000..b1d4117
+index 0000000..7e3ddcc
--- /dev/null
+++ sc/source/ui/docshell/externalrefmgr.cxx
-@@ -0,0 +1,1115 @@
+@@ -0,0 +1,1332 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -4399,6 +5156,67 @@
+
+// ============================================================================
+
++ScExternalRefCache::Table::Table()
++{
++}
++
++ScExternalRefCache::Table::~Table()
++{
++}
++
++void ScExternalRefCache::Table::setCell(SCROW nRow, SCCOL nCol, TokenRef pToken)
++{
++ StackPrinter __stack_print__("ScExternalRefCache:Table::setCell");
++ fprintf(stdout, "ScExternalRefCache:Table::setCell: row = %d; col = %d\n", nRow, nCol);
++ using ::std::pair;
++ RowsDataType::iterator itrRow = maRows.find(nRow);
++ if (itrRow == maRows.end())
++ {
++ // This row does not exist yet.
++ pair<RowsDataType::iterator, bool> res = maRows.insert(
++ RowsDataType::value_type(nRow, RowDataType()));
++
++ if (!res.second)
++ return;
++
++ itrRow = res.first;
++ }
++
++ // Insert this token into the specified column location. I don't need to
++ // check for existing data. Just overwrite it.
++ RowDataType& rRow = itrRow->second;
++ rRow.insert(RowDataType::value_type(nCol, pToken));
++ fprintf(stdout, "ScExternalRefCache:Table::setCell: token inserted (row = %d; col = %d)\n", nRow, nCol);
++}
++
++ScToken* ScExternalRefCache::Table::getCell(SCROW nRow, SCCOL nCol) const
++{
++ StackPrinter __stack_print__("ScExternalRefCache:Table::getCell");
++ fprintf(stdout, "ScExternalRefCache:Table::getCell: row = %d; col = %d\n", nRow, nCol);
++
++ RowsDataType::const_iterator itrTable = maRows.find(nRow);
++ if (itrTable == maRows.end())
++ {
++ fprintf(stdout, "ScExternalRefCache:Table::getCell: row not found\n");
++ // this table doesn't have the specified row.
++ return NULL;
++ }
++
++ const RowDataType& rRowData = itrTable->second;
++ RowDataType::const_iterator itrRow = rRowData.find(nCol);
++ if (itrRow == rRowData.end())
++ {
++ fprintf(stdout, "ScExternalRefCache:Table::getCell: column not found\n");
++ // this row doesn't have the specified column.
++ return NULL;
++ }
++
++ fprintf(stdout, "ScExternalRefCache:Table::getCell: cached cell found\n");
++ return itrRow->second.get();
++}
++
++// ----------------------------------------------------------------------------
++
+ScExternalRefCache::ScExternalRefCache()
+{
+}
@@ -4410,30 +5228,31 @@
+{
+ StackPrinter __stack_print__("ScExternalRefCache::getCellData");
+
-+ DocDataType::iterator itrDoc = maDocs.find(nFileId);
++ DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
+ if (itrDoc == maDocs.end())
++ {
++ fprintf(stdout, "ScExternalRefCache::getCellData: specified document not cached\n");
+ // specified document is not cached.
+ return NULL;
++ }
+
-+ DocItem& rDoc = itrDoc->second;
-+ TableNameIndexMap::iterator itrTabId = rDoc.maTableNameIndex.find(rTabName);
++ const DocItem& rDoc = itrDoc->second;
++ TableNameIndexMap::const_iterator itrTabId = rDoc.maTableNameIndex.find(rTabName);
+ if (itrTabId == rDoc.maTableNameIndex.end())
++ {
++ fprintf(stdout, "ScExternalRefCache::getCellData: table not in cache\n");
+ // the specified table is not in cache.
+ return NULL;
++ }
+
-+ TableDataTypeRef pTableData = rDoc.maTables[itrTabId->second];
-+ TableDataType::iterator itrTable = pTableData->find(nRow);
-+ if (itrTable == pTableData->end())
-+ // this table doesn't have the specified row.
-+ return NULL;
-+
-+ RowDataType& rRowData = itrTable->second;
-+ RowDataType::iterator itrRow = rRowData.find(nCol);
-+ if (itrRow == rRowData.end())
-+ // this row doesn't have the specified column.
++ const TableTypeRef& pTableData = rDoc.maTables[itrTabId->second];
++ if (!pTableData.get())
++ {
++ fprintf(stdout, "ScExternalRefCache::getCellData: table instance is NULL\n");
++ // the table data is not instantiated yet.
+ return NULL;
-+
-+ return itrRow->second.get();
++ }
++ return pTableData->getCell(nRow, nCol);
+}
+
+ScTokenArray* ScExternalRefCache::getCellRangeData(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange)
@@ -4446,6 +5265,13 @@
+ return NULL;
+
+ DocItem& rDoc = itrDoc->second;
++ RangeArrayMap::const_iterator itrRange = rDoc.maRangeArrays.find(rRange);
++ if (itrRange != rDoc.maRangeArrays.end())
++ {
++ fprintf(stdout, "ScExternalRefCache::getCellRangeData: range array cached. let's use this.\n");
++ return itrRange->second.get();
++ }
++
+ TableNameIndexMap::iterator itrTabId = rDoc.maTableNameIndex.find(rTabName);
+ if (itrTabId == rDoc.maTableNameIndex.end())
+ // the specified table is not in cache.
@@ -4465,33 +5291,25 @@
+ // not all tables are cached.
+ return NULL;
+
-+ auto_ptr<ScTokenArray> pArray(new ScTokenArray);
++ TokenArrayRef pArray(new ScTokenArray);
+ bool bFirstTab = true;
+ for (size_t nTab = nTabFirstId; nTab <= nTabLastId; ++nTab)
+ {
-+ TableDataTypeRef pTab = rDoc.maTables[nTab];
++ TableTypeRef pTab = rDoc.maTables[nTab];
++ if (!pTab.get())
++ return NULL;
+
+ ScMatrixRef xMat = new ScMatrix(
+ static_cast<SCSIZE>(nCol2-nCol1+1), static_cast<SCSIZE>(nRow2-nRow1+1));
+
-+
+ for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+ {
-+ TableDataType::iterator itrTable = pTab->find(nRow);
-+ if (itrTable == pTab->end())
-+ // this table doesn't have the specified row.
-+ return NULL;
-+
-+ RowDataType& rRowData = itrTable->second;
-+
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ {
-+ RowDataType::iterator itrRow = rRowData.find(nCol);
-+ if (itrRow == rRowData.end())
-+ // this row doesn't have the specified column.
++ ScToken* pToken = pTab->getCell(nRow, nCol);
++ if (!pToken)
+ return NULL;
+
-+ ScToken* pToken = itrRow->second.get();
+ SCSIZE nC = nCol - nCol1, nR = nRow - nRow1;
+ switch (pToken->GetType())
+ {
@@ -4506,6 +5324,7 @@
+ }
+ }
+ }
++
+ if (!bFirstTab)
+ pArray->AddOpCode(ocSep);
+
@@ -4515,69 +5334,292 @@
+
+ bFirstTab = false;
+ }
-+ return pArray.release();
++ rDoc.maRangeArrays.insert(RangeArrayMap::value_type(rRange, pArray));
++ return pArray.get();
++}
++
++ScTokenArray* ScExternalRefCache::getRangeNameTokens(sal_uInt16 nFileId, const String& rName)
++{
++ StackPrinter __stack_print__("ScExternalRefCache::getRangeNameTokens");
++
++ DocItem* pDoc = getDocItem(nFileId);
++ if (!pDoc)
++ return NULL;
++
++ RangeNameMap& rMap = pDoc->maRangeNames;
++ RangeNameMap::const_iterator itr = rMap.find(rName);
++ if (itr == rMap.end())
++ return NULL;
++
++ return itr->second.get();
++}
++
++void ScExternalRefCache::setRangeNameTokens(sal_uInt16 nFileId, const String& rName, TokenArrayRef pArray)
++{
++ StackPrinter __stack_print__("ScExternalRefCache::setRangeNameTokens");
++
++ DocItem* pDoc = getDocItem(nFileId);
++ if (!pDoc)
++ return;
++
++ RangeNameMap& rMap = pDoc->maRangeNames;
++ rMap.insert(RangeNameMap::value_type(rName, pArray));
++ fprintf(stdout, "ScExternalRefCache::setRangeNameTokens: name inserted into cache\n");
+}
+
+void ScExternalRefCache::setCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol, TokenRef pToken)
+{
+ StackPrinter __stack_print__("ScExternalRefCache::setCellData");
++ if (!isDocInitialized(nFileId))
++ return;
+
+ using ::std::pair;
-+ DocDataType::iterator itrDoc = maDocs.find(nFileId);
-+ if (itrDoc == maDocs.end())
-+ {
-+ // specified document is not cached.
-+ pair<DocDataType::iterator, bool> res = maDocs.insert(
-+ DocDataType::value_type(nFileId, DocItem()));
-+
-+ if (!res.second)
-+ // insertion failed.
-+ return;
-+
-+ itrDoc = res.first;
-+ }
++ DocItem* pDocItem = getDocItem(nFileId);
++ if (!pDocItem)
++ return;
+
-+ DocItem& rDoc = itrDoc->second;
++ DocItem& rDoc = *pDocItem;
+
+ // See if the table by this name already exists.
+ TableNameIndexMap::iterator itrTabName = rDoc.maTableNameIndex.find(rTabName);
+ if (itrTabName == rDoc.maTableNameIndex.end())
++ // Table not found. Maybe the table name or the file id is wrong ???
++ return;
++
++ TableTypeRef& pTableData = rDoc.maTables[itrTabName->second];
++ if (!pTableData.get())
++ pTableData.reset(new Table);
++
++ pTableData->setCell(nRow, nCol, pToken);
++}
++
++void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRange, const vector<SingleRangeData>& rData,
++ TokenArrayRef pArray)
++{
++ using ::std::pair;
++ StackPrinter __stack_print__("ScExternalRefCache::setCellRangeData");
++ if (rData.empty() || !isDocInitialized(nFileId))
++ // nothing to cache
++ return;
++
+ {
-+ // Insert a new table by this name.
-+ rDoc.maTables.push_back(TableDataTypeRef(new TableDataType));
-+ pair<TableNameIndexMap::iterator, bool> res = rDoc.maTableNameIndex.insert(
-+ TableNameIndexMap::value_type(rTabName, rDoc.maTables.size()-1));
++ vector<SingleRangeData>::const_iterator itr = rData.begin(), itrEnd = rData.end();
++ for (; itr != itrEnd; ++itr)
++ {
++ fprintf(stdout, "ScExternalRefCache::setCellRangeData: tab name to cache = '%s'\n",
++ rtl::OUStringToOString(itr->maTableName, RTL_TEXTENCODING_UTF8).getStr());
++ }
++ }
+
-+ if (!res.second)
-+ return;
++ String aStr;
++ rRange.Format(aStr, SCR_ABS_3D, NULL);
++ fprintf(stdout, "ScExternalRefCache::setCellRangeData: range = '%s'\n",
++ rtl::OUStringToOString(aStr, RTL_TEXTENCODING_UTF8).getStr());
++
++ // First, get the document item for the given file ID.
++ DocItem* pDocItem = getDocItem(nFileId);
++ if (!pDocItem)
++ return;
++
++ DocItem& rDoc = *pDocItem;
++
++ // Now, find the table position of the first table to cache.
++ const String& rFirstTabName = rData.front().maTableName;
++ TableNameIndexMap::iterator itrTabName = rDoc.maTableNameIndex.find(rFirstTabName);
++ if (itrTabName == rDoc.maTableNameIndex.end())
++ {
++ // table index not found.
++ fprintf(stdout, "ScExternalRefCache::setCellRangeData: table index not found\n");
++ return;
++ }
++
++ fprintf(stdout, "ScExternalRefCache::setCellRangeData: table index for cached table '%s' = %d\n",
++ rtl::OUStringToOString(rFirstTabName, RTL_TEXTENCODING_UTF8).getStr(), itrTabName->second);
++
++ size_t nTab1 = itrTabName->second;
++ SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row();
++ SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col();
++ vector<SingleRangeData>::const_iterator itrDataBeg = rData.begin(), itrDataEnd = rData.end();
++ for (vector<SingleRangeData>::const_iterator itrData = itrDataBeg; itrData != itrDataEnd; ++itrData)
++ {
++ size_t i = nTab1 + ::std::distance(itrDataBeg, itrData);
++ TableTypeRef& pTabData = rDoc.maTables[i];
++ if (!pTabData.get())
++ pTabData.reset(new Table);
++
++ for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
++ {
++ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
++ {
++ SCSIZE nC = nCol - nCol1, nR = nRow - nRow1;
++ TokenRef pToken;
++ const ScMatrixRef& pMat = itrData->mpRangeData;
++ if (pMat->IsValue(nC, nR))
++ pToken.reset(new ScDoubleToken(pMat->GetDouble(nC, nR)));
++ else if (pMat->IsString(nC, nR))
++ pToken.reset(new ScStringToken(pMat->GetString(nC, nR)));
++ else
++ pToken.reset(new ScEmptyCellToken(false, false));
+
-+ itrTabName = res.first;
++ pTabData->setCell(nRow, nCol, pToken);
++ }
++ }
+ }
+
-+ TableDataTypeRef pTableData = rDoc.maTables[itrTabName->second];
-+ TableDataType::iterator itrRow = pTableData->find(nRow);
-+ if (itrRow == pTableData->end())
++ rDoc.maRangeArrays.insert(RangeArrayMap::value_type(rRange, pArray));
++}
++
++bool ScExternalRefCache::isDocInitialized(sal_uInt16 nFileId)
++{
++ DocItem* pDoc = getDocItem(nFileId);
++ if (!pDoc)
++ return false;
++
++ return pDoc->mbInitFromSource;
++}
++
++static bool lcl_getTableDataIndex(const ScExternalRefCache::TableNameIndexMap& rMap, const String& rName, size_t& rIndex)
++{
++ ScExternalRefCache::TableNameIndexMap::const_iterator itr = rMap.find(rName);
++ if (itr == rMap.end())
++ return false;
++
++ rIndex = itr->second;
++ return true;
++}
++
++void ScExternalRefCache::initializeDoc(sal_uInt16 nFileId, const vector<String>& rTabNames)
++{
++ StackPrinter __stack_print__("ScExternalRefCache::initializeDoc");
++
++ DocItem* pDoc = getDocItem(nFileId);
++ if (!pDoc)
++ return;
++
++ size_t n = rTabNames.size();
++ for (size_t i = 0; i < n; ++i)
++ fprintf(stdout, "ScExternalRefCache::initializeDoc: %d: '%s'\n", i, rtl::OUStringToOString(rTabNames[i], RTL_TEXTENCODING_UTF8).getStr());
++
++ // table name list - the list must include all table names in the source
++ // document and only to be populated when loading the source document, not
++ // when loading cached data from, say, Excel XCT/CRN records.
++ pDoc->maTableNames.assign(rTabNames.begin(), rTabNames.end());
++
++ // data tables - preserve any existing data that may have been set during
++ // Excel import.
++ vector<TableTypeRef> aNewTables(n);
++ for (size_t i = 0; i < n; ++i)
+ {
-+ // This row does not exist yet.
-+ pair<TableDataType::iterator, bool> res = pTableData->insert(
-+ TableDataType::value_type(nRow, RowDataType()));
++ size_t nIndex;
++ if (lcl_getTableDataIndex(pDoc->maTableNameIndex, rTabNames[i], nIndex))
++ {
++ fprintf(stdout, "ScExternalRefCache::initializeDoc: transferring '%s'\n", rtl::OUStringToOString(rTabNames[i], RTL_TEXTENCODING_UTF8).getStr());
++ aNewTables[i] = pDoc->maTables[nIndex];
++ }
++ }
++ pDoc->maTables.swap(aNewTables);
+
-+ if (!res.second)
-+ return;
++ // name index map
++ TableNameIndexMap aNewNameIndex;
++ for (size_t i = 0; i < n; ++i)
++ aNewNameIndex.insert(TableNameIndexMap::value_type(rTabNames[i], i));
++ pDoc->maTableNameIndex.swap(aNewNameIndex);
+
-+ itrRow = res.first;
++ pDoc->mbInitFromSource = true;
++}
++#if 0
++const String* ScExternalRefCache::getExternalTableName(sal_uInt16 nFileId, SCTAB nTab)
++{
++ DocItem* pDocItem = getDocItem(nFileId);
++ if (!pDocItem || nTab < 0)
++ return NULL;
++
++ const vector<String>& rNames = pDocItem->maTableNames;
++ if (static_cast<size_t>(nTab) >= rNames.size())
++ return NULL;
++
++ return &rNames[nTab];
++}
++
++SCTAB ScExternalRefCache::getExternalTableId(sal_uInt16 nFileId, const String& rTabName)
++{
++ if (!isDocInitialized(nFileId))
++ return -1;
++
++ DocItem* pDocItem = getDocItem(nFileId);
++ if (!pDocItem)
++ return -1;
++
++ TableNameIndexMap::const_iterator itr = pDocItem->maTableNameIndex.find(rTabName);
++ if (itr == pDocItem->maTableNameIndex.end())
++ return -1;
++
++ return static_cast<SCTAB>(itr->second);
++}
++#endif
++const vector<String>* ScExternalRefCache::getAllTableNames(sal_uInt16 nFileId) const
++{
++ DocItem* pDoc = getDocItem(nFileId);
++ if (!pDoc)
++ return NULL;
++
++ return &pDoc->maTableNames;
++}
++
++ScExternalRefCache::Table* ScExternalRefCache::getCacheTable(sal_uInt16 nFileId, const String& rTabName)
++{
++ StackPrinter __stack_print__("ScExternalRefCache::getCacheTable");
++
++ fprintf(stdout, "ScExternalRefCache::getCacheTable: tab name requested = '%s'\n",
++ rtl::OUStringToOString(rTabName, RTL_TEXTENCODING_UTF8).getStr());
++
++ DocItem* pDoc = getDocItem(nFileId);
++ if (!pDoc)
++ return NULL;
++
++ DocItem& rDoc = *pDoc;
++
++ size_t nIndex;
++ if (lcl_getTableDataIndex(rDoc.maTableNameIndex, rTabName, nIndex))
++ {
++ fprintf(stdout, "ScExternalRefCache::getCacheTable: exists\n");
++ return rDoc.maTables[nIndex].get();
+ }
+
-+ // Insert this token into the specified column location. I don't need to
-+ // check for existing data. Just overwrite it.
-+ RowDataType& rRow = itrRow->second;
-+ rRow.insert(RowDataType::value_type(nCol, pToken));
-+ fprintf(stdout, "ScExternalRefCache::setCellData: token inserted\n");
++ fprintf(stdout, "ScExternalRefCache::getCacheTable: creating a new cache table\n");
++
++ // Specified table doesn't exist yet. Create one.
++ TableTypeRef pTab(new Table);
++ rDoc.maTables.push_back(pTab);
++ rDoc.maTableNames.push_back(rTabName);
++ rDoc.maTableNameIndex.insert(
++ TableNameIndexMap::value_type(rTabName, rDoc.maTables.size()-1));
++ return pTab.get();
+}
+
-+void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange,
-+ const vector<MatrixRef>& rData)
++void ScExternalRefCache::clearCache(sal_uInt16 nFileId)
+{
++ maDocs.erase(nFileId);
++}
++
++ScExternalRefCache::DocItem* ScExternalRefCache::getDocItem(sal_uInt16 nFileId) const
++{
++ using ::std::pair;
++ DocDataType::iterator itrDoc = maDocs.find(nFileId);
++ if (itrDoc == maDocs.end())
++ {
++ // specified document is not cached.
++ pair<DocDataType::iterator, bool> res = maDocs.insert(
++ DocDataType::value_type(nFileId, DocItem()));
++
++ if (!res.second)
++ // insertion failed.
++ return NULL;
++
++ itrDoc = res.first;
++ }
++
++ return &itrDoc->second;
+}
+
+// ============================================================================
@@ -4645,8 +5687,6 @@
+
+static ScToken* lcl_convertToToken(ScBaseCell* pCell)
+{
-+ StackPrinter __stack_print__("::lcl_convertToToken");
-+
+ if (!pCell)
+ return NULL;
+
@@ -4695,7 +5735,8 @@
+ return NULL;
+}
+
-+static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, const ScRange& rRange)
++static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, const ScRange& rRange,
++ vector<ScExternalRefCache::SingleRangeData>& rCacheData)
+{
+ const ScAddress& s = rRange.aStart;
+ const ScAddress& e = rRange.aEnd;
@@ -4706,7 +5747,9 @@
+
+ auto_ptr<ScTokenArray> pArray(new ScTokenArray);
+ bool bFirstTab = true;
-+ for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
++ vector<ScExternalRefCache::SingleRangeData>::iterator
++ itrCache = rCacheData.begin(), itrCacheEnd = rCacheData.end();
++ for (SCTAB nTab = nTab1; nTab <= nTab2 && itrCache != itrCacheEnd; ++nTab, ++itrCache)
+ {
+ ScMatrixRef xMat = new ScMatrix(
+ static_cast<SCSIZE>(nCol2-nCol1+1),
@@ -4769,6 +5812,8 @@
+ ScMatrixToken aToken(pMat2);
+ pArray->AddToken(aToken);
+
++ itrCache->mpRangeData = xMat;
++
+ bFirstTab = false;
+ }
+ return pArray.release();
@@ -4786,6 +5831,24 @@
+ clear();
+}
+
++ScExternalRefCache::Table* ScExternalRefManager::getCacheTable(sal_uInt16 nFileId, const String& rTabName)
++{
++ return maRefCache.getCacheTable(nFileId, rTabName);
++}
++
++void ScExternalRefManager::storeRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScTokenArray& rArray)
++{
++ StackPrinter __stack_print__("ScExternalRefManager::storeRangeNameTokens");
++ ScExternalRefCache::TokenArrayRef pArray(rArray.Clone());
++ maRefCache.setRangeNameTokens(nFileId, rName, pArray);
++
++ for (ScToken* pToken = pArray->First(); pToken; pToken = pArray->Next())
++ {
++ fprintf(stdout, "ScExternalRefManager::storeRangeNameTokens: type = %d; opcode = %d\n",
++ pToken->GetType(), pToken->GetOpCode());
++ }
++}
++
+ScToken* ScExternalRefManager::getSingleRefToken(sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell,
+ const ScAddress* pCurPos, SCTAB* pTab)
+{
@@ -4843,129 +5906,81 @@
+ return pTok.get();
+}
+
-+#if 1
-+ScToken* ScExternalRefManager::getSingleRefToken(sal_uInt16 nFileId, const ScAddress& rCell, const ScAddress* pCurPos)
++ScTokenArray* ScExternalRefManager::getDoubleRefTokens(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos)
+{
+ if (pCurPos)
+ insertReferencingCell(nFileId, *pCurPos);
-+ return getSingleRefToken(nFileId, rCell);
-+}
+
-+ScToken* ScExternalRefManager::getSingleRefToken(sal_uInt16 nFileId, const ScAddress& rCell)
-+{
++ // Check if the given table name and the cell position is cached.
++ ScTokenArray* p = maRefCache.getCellRangeData(nFileId, rTabName, rRange);
++ if (p)
+ {
-+ String aStr;
-+ rCell.Format(aStr, SCA_ABS_3D);
-+ const String *pFile = getExternalFileName(nFileId);
-+ fprintf(stdout, "ScExternalRefManager::getSingleRefToken: --begin (file = '%s'; address = '%s')\n",
-+ rtl::OUStringToOString(*pFile, RTL_TEXTENCODING_UTF8).getStr(),
-+ rtl::OUStringToOString(aStr, RTL_TEXTENCODING_UTF8).getStr());
++ fprintf(stdout, "ScExternalRefManager::getDoubleRefTokens: range reference cached.\n");
++ return p;
+ }
+
-+ SingleTokenMap& rMap = getDocumentCache(nFileId)->maSingleTokens;
-+ SingleTokenMap::iterator itr = rMap.find(rCell);
-+ if (itr != rMap.end())
-+ {
-+ fprintf(stdout, "ScExternalRefManager::getSingleRefToken: reference cached\n");
-+ // this single reference is cached.
-+ return itr->second.get();
-+ }
++ fprintf(stdout, "ScExternalRefManager::getDoubleRefTokens: range reference not cached.\n");
+
-+ // reference not cached. read from the source document.
+ ScDocument* pSrcDoc = getSrcDocument(nFileId);
+ if (!pSrcDoc)
-+ return NULL;
-+
-+ ScBaseCell* pCell = NULL;
-+ pSrcDoc->GetCell(rCell.Col(), rCell.Row(), rCell.Tab(), pCell);
-+ TokenRef pTok(lcl_convertToToken(pCell));
-+
-+ if (!pTok.get())
+ {
-+ // Cell in the source document is probably empty.
-+ pTok.reset(new ScEmptyCellToken(false, false));
++ fprintf(stdout, "ScExternalRefManager::getDoubleRefTokens: source document is null\n");
++ return NULL;
+ }
+
-+ rMap.insert(SingleTokenMap::value_type(rCell, pTok));
-+ fprintf(stdout, "ScExternalRefManager::getSingleRefToken: --end\n");
-+ return pTok.get();
-+}
-+#endif
-+
-+ScTokenArray* ScExternalRefManager::getDoubleRefTokens(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos)
-+{
-+ if (pCurPos)
-+ insertReferencingCell(nFileId, *pCurPos);
-+
-+ // Check if the given table name and the cell position is cached.
-+ auto_ptr<ScTokenArray> pArray;
-+ pArray.reset(maRefCache.getCellRangeData(nFileId, rTabName, rRange));
-+ if (pArray.get())
++ SCTAB nTab1;
++ if (!pSrcDoc->GetTable(rTabName, nTab1))
+ {
-+ fprintf(stdout, "ScExternalRefManager::getDoubleRefTokens: range reference cached.\n");
-+ return pArray.release();
++ // specified table name doesn't exist in the source document.
++ fprintf(stdout, "ScExternalRefManager::getSingleRefToken: tab name doesn't exist in the source document.\n");
++ return NULL;
+ }
+
++ fprintf(stdout, "ScExternalRefManager::getDoubleRefTokens: tab id = %d\n", nTab1);
+
-+ SCTAB nTab = getExternalTableId(nFileId, rTabName);
-+ if (nTab < 0)
-+ return NULL;
-+
+ ScRange aRange(rRange);
+ SCTAB nTabSpan = aRange.aEnd.Tab() - aRange.aStart.Tab();
-+ aRange.aStart.SetTab(nTab);
-+ aRange.aEnd.SetTab(nTab + nTabSpan);
-+ return getDoubleRefTokens(nFileId, aRange);
-+}
+
-+#if 1
-+ScTokenArray* ScExternalRefManager::getDoubleRefTokens(sal_uInt16 nFileId, const ScRange& rRange)
-+{
-+ {
-+ String aStr;
-+ rRange.Format(aStr, SCR_ABS_3D, mpDoc);
-+ const String *pFile = getExternalFileName(nFileId);
-+ fprintf(stdout, "ScExternalRefManager::getDoubleRefToken: --begin (file = '%s'; range = '%s)\n",
-+ rtl::OUStringToOString(*pFile, RTL_TEXTENCODING_UTF8).getStr(),
-+ rtl::OUStringToOString(aStr, RTL_TEXTENCODING_UTF8).getStr());
-+ }
++ vector<ScExternalRefCache::SingleRangeData> aCacheData;
++ aCacheData.reserve(nTabSpan+1);
++ aCacheData.push_back(ScExternalRefCache::SingleRangeData());
++ aCacheData.back().maTableName = rTabName;
+
-+ DoubleTokenMap& rMap = getDocumentCache(nFileId)->maDoubleTokens;
-+ DoubleTokenMap::iterator itr = rMap.find(rRange);
-+ if (itr != rMap.end())
++ for (SCTAB i = 1; i < nTabSpan + 1; ++i)
+ {
-+ fprintf(stdout, "ScExternalRefManager::getDoubleRefToken: range reference cached\n");
-+ // this range reference is cached.
-+ return itr->second.get();
++ String aTabName;
++ if (!pSrcDoc->GetName(nTab1 + 1, aTabName))
++ {
++ fprintf(stdout, "ScExternalRefManager::getDoubleRefTokens: src doc does not have a table named '%s'\n",
++ rtl::OUStringToOString(aTabName, RTL_TEXTENCODING_UTF8).getStr());
++ break;
++ }
++
++ aCacheData.push_back(ScExternalRefCache::SingleRangeData());
++ aCacheData.back().maTableName = aTabName;
+ }
+
-+ // reference not cached. read from the source document.
-+ ScDocument* pSrcDoc = getSrcDocument(nFileId);
-+ if (!pSrcDoc)
-+ return NULL;
++ aRange.aStart.SetTab(nTab1);
++ aRange.aEnd.SetTab(nTab1 + nTabSpan);
+
-+ TokenArrayRef pArray(lcl_convertToTokenArray(pSrcDoc, rRange));
-+ if (!pArray.get())
-+ {
-+ // highly unlikely since lcl_convertToTokenArray never returns NULL.
-+ fprintf(stdout, "ScExternalRefManager::getDoubleRefToken: --end (NULL)\n");
-+ return NULL;
-+ }
++ ScExternalRefCache::TokenArrayRef pArray;
++ pArray.reset(lcl_convertToTokenArray(pSrcDoc, aRange, aCacheData));
++
++ // Cache these values.
++ maRefCache.setCellRangeData(nFileId, rRange, aCacheData, pArray);
+
-+ rMap.insert(DoubleTokenMap::value_type(rRange, pArray));
-+ fprintf(stdout, "ScExternalRefManager::getDoubleRefToken: --end\n");
+ return pArray.get();
+}
-+#endif
+
+ScTokenArray* ScExternalRefManager::getRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos)
+{
++ StackPrinter __stack_print__("ScExternalRefManager::getRangeNameTokens");
+ if (pCurPos)
+ {
+ String aCellStr;
+ pCurPos->Format(aCellStr, SCA_ABS_3D);
+ const String* pFile = getExternalFileName(nFileId);
-+ fprintf(stdout, "ScExternalRefManager::getRangeNameTokens: --begin (file = '%s' [%d]; name = '%s'; pos = '%s')\n",
++ fprintf(stdout, "ScExternalRefManager::getRangeNameTokens: file = '%s' [%d]; name = '%s'; pos = '%s'\n",
+ rtl::OUStringToOString(*pFile, RTL_TEXTENCODING_UTF8).getStr(),
+ nFileId,
+ rtl::OUStringToOString(rName, RTL_TEXTENCODING_UTF8).getStr(),
@@ -4975,14 +5990,11 @@
+ if (pCurPos)
+ insertReferencingCell(nFileId, *pCurPos);
+
-+ // First, check if this name has already been cached.
-+ RangeNameMap& rMap = getDocumentCache(nFileId)->maRangeNames;
-+ RangeNameMap::iterator itr = rMap.find(rName);
-+ if (itr != rMap.end())
++ ScTokenArray* pArray = maRefCache.getRangeNameTokens(nFileId, rName);
++ if (pArray)
+ {
+ fprintf(stdout, "ScExternalRefManager::getRangeNameTokens: name is cached\n");
-+ // this name is cached.
-+ return itr->second.get();
++ return pArray;
+ }
+
+ ScDocument* pSrcDoc = getSrcDocument(nFileId);
@@ -5015,16 +6027,20 @@
+ {
+ case svSingleRef:
+ {
-+ fprintf(stdout, "ScDocument::FindExternalRangeName: single ref\n");
-+ ScExternalSingleRefToken aNewToken(nFileId, String(), pToken->GetSingleRef());
++ const SingleRefData& rRef = pToken->GetSingleRef();
++ String aTabName;
++ pSrcDoc->GetName(rRef.nTab, aTabName);
++ ScExternalSingleRefToken aNewToken(nFileId, aTabName, pToken->GetSingleRef());
+ pNew->AddToken(aNewToken);
+ bTokenAdded = true;
+ }
+ break;
+ case svDoubleRef:
+ {
-+ fprintf(stdout, "ScDocument::FindExternalRangeName: double ref\n");
-+ ScExternalDoubleRefToken aNewToken(nFileId, String(), pToken->GetDoubleRef());
++ const SingleRefData& rRef = pToken->GetSingleRef();
++ String aTabName;
++ pSrcDoc->GetName(rRef.nTab, aTabName);
++ ScExternalDoubleRefToken aNewToken(nFileId, aTabName, pToken->GetDoubleRef());
+ pNew->AddToken(aNewToken);
+ bTokenAdded = true;
+ }
@@ -5035,8 +6051,7 @@
+ pNew->AddToken(*pToken);
+ }
+
-+ rMap.insert(RangeNameMap::value_type(rName, pNew));
-+ fprintf(stdout, "ScExternalRefManager::getRangeNameTokens: --end\n");
++ maRefCache.setRangeNameTokens(nFileId, rName, pNew);
+ return pNew.get();
+}
+
@@ -5091,18 +6106,6 @@
+ maRefCells.insert(RefCellMap::value_type(nFileId, aSet));
+}
+
-+ScExternalRefManager::DocCache* ScExternalRefManager::getDocumentCache(
-+ sal_uInt16 nFileId)
-+{
-+ DocCacheMap::iterator itr = maCachedDocContents.find(nFileId);
-+ if (itr != maCachedDocContents.end())
-+ return itr->second.get();
-+
-+ DocCacheRef pCache(new DocCache);
-+ maCachedDocContents.insert(DocCacheMap::value_type(nFileId, pCache));
-+ return pCache.get();
-+}
-+
+ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId)
+{
+ DocShellMap::iterator itrEnd = maDocShells.end();
@@ -5122,9 +6125,11 @@
+ return NULL;
+ }
+
-+ fprintf(stdout, "ScExternalRefManager::getSourceDocument: file not found: '%s'\n",
++ fprintf(stdout, "ScExternalRefManager::getSourceDocument: file not loaded yet: '%s'\n",
+ rtl::OUStringToOString(*pFile, RTL_TEXTENCODING_UTF8).getStr());
+
++ // TODO: Check whether the file really exists. If not, return NULL.
++
+ String aFilter;
+ SrcDoc aSrcDoc;
+ aSrcDoc.maShell = loadSrcDocument(*pFile, aFilter);
@@ -5144,19 +6149,20 @@
+ SfxObjectShell* p = aSrcDoc.maShell;
+ ScDocument* pSrcDoc = static_cast<ScDocShell*>(p)->GetDocument();
+
-+ // Store all its table names. Excel exporter needs this info.
-+ vector<String> aTableNames;
-+ SCTAB nCount = pSrcDoc->GetTableCount();
-+ aTableNames.reserve(nCount);
-+ for (SCTAB i = 0; i < nCount; ++i)
++ SCTAB nTabCount = pSrcDoc->GetTableCount();
++ if (!maRefCache.isDocInitialized(nFileId) && nTabCount)
+ {
-+ String aTabName;
-+ pSrcDoc->GetName(i, aTabName);
-+ aTableNames.push_back(aTabName);
++ // Populate the cache with all table names in the source document.
++ vector<String> aTabNames;
++ aTabNames.reserve(nTabCount);
++ for (SCTAB i = 0; i < nTabCount; ++i)
++ {
++ String aName;
++ pSrcDoc->GetName(i, aName);
++ aTabNames.push_back(aName);
++ }
++ maRefCache.initializeDoc(nFileId, aTabNames);
+ }
-+ DocCache* pCache = getDocumentCache(nFileId);
-+ pCache->maTableNames.swap(aTableNames);
-+
+ return pSrcDoc;
+}
+
@@ -5284,41 +6290,9 @@
+ return &maFileNames[nFileId];
+}
+
-+const String* ScExternalRefManager::getExternalTableName(sal_uInt16 nFileId, SCTAB nTabId)
-+{
-+ if (nFileId >= maFileNames.size())
-+ return NULL;
-+
-+ DocCache* pCache = getDocumentCache(nFileId);
-+ if (nTabId >= pCache->maTableNames.size())
-+ return NULL;
-+
-+ return &pCache->maTableNames[nTabId];
-+}
-+
-+SCTAB ScExternalRefManager::getExternalTableId(sal_uInt16 nFileId, const String& rTabName)
++const vector<String>* ScExternalRefManager::getAllCachedTableNames(sal_uInt16 nFileId) const
+{
-+ vector<String>& rNames = getDocumentCache(nFileId)->maTableNames;
-+ vector<String>::iterator itrBeg = rNames.begin(), itrEnd = rNames.end();
-+ vector<String>::iterator itr = find(itrBeg, itrEnd, rTabName);
-+ if (itr != itrEnd)
-+ // found in cache
-+ return static_cast<SCTAB>(distance(itrBeg, itr));
-+
-+ // Loading the source document resets the table name vector.
-+ ScDocument* pSrcDoc = getSrcDocument(nFileId);
-+ if (!pSrcDoc)
-+ // source document could not be loaded.
-+ return -1;
-+
-+ itrBeg = rNames.begin();
-+ itrEnd = rNames.end();
-+ itr = find(itrBeg, itrEnd, rTabName);
-+ if (itr != itrEnd)
-+ // found in the source document
-+ return static_cast<SCTAB>(distance(itrBeg, itr));
-+
-+ return -1;
++ return maRefCache.getAllTableNames(nFileId);
+}
+
+template<typename MapContainer>
@@ -5360,7 +6334,7 @@
+ rtl::OUStringToOString(*pFile, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
-+ lcl_removeByFileId(nFileId, maCachedDocContents);
++ maRefCache.clearCache(nFileId);
+ lcl_removeByFileId(nFileId, maDocShells);
+
+ if (bBreakLink)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]