ooo-build r13873 - in trunk: . patches/dev300
- From: kyoshida svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r13873 - in trunk: . patches/dev300
- Date: Wed, 10 Sep 2008 22:50:38 +0000 (UTC)
Author: kyoshida
Date: Wed Sep 10 22:50:37 2008
New Revision: 13873
URL: http://svn.gnome.org/viewvc/ooo-build?rev=13873&view=rev
Log:
2008-09-10 Kohei Yoshida <kyoshida novell com>
* patches/dev300/apply: added IZ number to the sc unused methods patch.
* patches/dev300/calc-external-defined-names-offapi.diff:
* patches/dev300/calc-external-defined-names-sc.diff: more update from
mooxlsc cws. Added correct implementation of keeping track of all
formula cells that contain external references. This is used when
updating linked documents.
Modified:
trunk/ChangeLog
trunk/patches/dev300/apply
trunk/patches/dev300/calc-external-defined-names-offapi.diff
trunk/patches/dev300/calc-external-defined-names-sc.diff
Modified: trunk/patches/dev300/apply
==============================================================================
--- trunk/patches/dev300/apply (original)
+++ trunk/patches/dev300/apply Wed Sep 10 22:50:37 2008
@@ -2627,4 +2627,4 @@
# This section should always be at the bottom so that no other patches would
# depend on it.
-unused-methods-removal-sc.diff, kohei
+unused-methods-removal-sc.diff, i#85185, kohei
Modified: trunk/patches/dev300/calc-external-defined-names-offapi.diff
==============================================================================
--- trunk/patches/dev300/calc-external-defined-names-offapi.diff (original)
+++ trunk/patches/dev300/calc-external-defined-names-offapi.diff Wed Sep 10 22:50:37 2008
@@ -298,7 +298,7 @@
+
diff --git offapi/com/sun/star/sheet/ExternalReference.idl offapi/com/sun/star/sheet/ExternalReference.idl
new file mode 100644
-index 0000000..21f0e3a
+index 0000000..7686310
--- /dev/null
+++ offapi/com/sun/star/sheet/ExternalReference.idl
@@ -0,0 +1,99 @@
@@ -343,7 +343,7 @@
+ external reference can be either a single cell reference, a cell range
+ reference, or a named range.
+
-+ @see FormulaMapGroupSpecialOffset::EXTERNAL_REFERENCE
++ @see FormulaMapGroupSpecialOffset::PUSH
+
+ @since OOo 3.1
+ */
@@ -701,7 +701,7 @@
@see com::sun::star::sheet::FormulaMapGroupSpecialOffset::NAME
diff --git offapi/com/sun/star/sheet/XExternalDocLink.idl offapi/com/sun/star/sheet/XExternalDocLink.idl
new file mode 100644
-index 0000000..e444682
+index 0000000..27a706c
--- /dev/null
+++ offapi/com/sun/star/sheet/XExternalDocLink.idl
@@ -0,0 +1,94 @@
@@ -789,7 +789,7 @@
+
+ @see com::sun::star::sheet::ExternalDocLinks
+ @see com::sun::star::sheet::FormulaToken
-+ @see com::sun::star::sheet::FormulaMapGroupSpecialOffset::EXTERNAL_REFERENCE
++ @see com::sun::star::sheet::ExternalReference
+ */
+ [attribute, readonly] long TokenIndex;
+};
@@ -873,10 +873,10 @@
+#endif
diff --git offapi/com/sun/star/sheet/XExternalSheetCache.idl offapi/com/sun/star/sheet/XExternalSheetCache.idl
new file mode 100644
-index 0000000..c246680
+index 0000000..1d91f70
--- /dev/null
+++ offapi/com/sun/star/sheet/XExternalSheetCache.idl
-@@ -0,0 +1,103 @@
+@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -971,7 +971,6 @@
+
+ @see FormulaToken
+ @see ExternalReference
-+ @see FormulaMapGroupSpecialOffset::EXTERNAL_REFERENCE
+ */
+ [attribute, readonly] long TokenIndex;
+
Modified: trunk/patches/dev300/calc-external-defined-names-sc.diff
==============================================================================
--- trunk/patches/dev300/calc-external-defined-names-sc.diff (original)
+++ trunk/patches/dev300/calc-external-defined-names-sc.diff Wed Sep 10 22:50:37 2008
@@ -112,7 +112,7 @@
/*** error constants #... ***/
#define SC_OPCODE_START_ERRORS 30
diff --git sc/inc/compiler.hxx sc/inc/compiler.hxx
-index 7bb6767..bdffc05 100644
+index 7974267..d901f78 100644
--- sc/inc/compiler.hxx
+++ sc/inc/compiler.hxx
@@ -45,6 +45,8 @@
@@ -220,7 +220,7 @@
BOOL IsDBRange( const String& );
BOOL IsColRowName( const String& );
BOOL IsBoolean( const String& );
-@@ -540,6 +578,29 @@ public:
+@@ -543,6 +581,29 @@ public:
void SetGrammar( const ScGrammar::Grammar eGrammar );
inline ScGrammar::Grammar GetGrammar() const { return meGrammar; }
@@ -251,7 +251,7 @@
BOOL IsCorrected() { return bCorrected; }
diff --git sc/inc/document.hxx sc/inc/document.hxx
-index a01f09b..5d4ca1f 100644
+index 2a27407..414f0c5 100644
--- sc/inc/document.hxx
+++ sc/inc/document.hxx
@@ -93,6 +93,7 @@ class ScDocProtection;
@@ -289,10 +289,10 @@
diff --git sc/inc/externalrefmgr.hxx sc/inc/externalrefmgr.hxx
new file mode 100644
-index 0000000..90b8cd4
+index 0000000..d40afbc
--- /dev/null
+++ sc/inc/externalrefmgr.hxx
-@@ -0,0 +1,429 @@
+@@ -0,0 +1,486 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -338,6 +338,7 @@
+#include <hash_set>
+#include <boost/shared_ptr.hpp>
+#include <vector>
++#include <list>
+
+class ScDocument;
+class ScToken;
@@ -514,16 +515,50 @@
+
+class ScExternalRefManager
+{
-+private:
-+ struct AddressHash
++public:
++ /**
++ * Collection of cell addresses that contain external references. This
++ * data is used for link updates.
++ */
++ class RefCells
+ {
-+ size_t operator()(const ScAddress& rAddr) const
-+ {
-+ // dumb hashing - how do we properly hash a cell address?
-+ return rAddr.Tab() + rAddr.Col() + rAddr.Row();
-+ }
++ public:
++ RefCells();
++ ~RefCells();
++
++ void insertCell(const ScAddress& rAddr);
++ void removeCell(const ScAddress& rAddr);
++ void moveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy);
++ void insertTable(SCTAB nPos);
++ void removeTable(SCTAB nPos);
++ void refreshAllCells(ScExternalRefManager& rRefMgr);
++ private:
++
++ typedef ::std::hash_set<SCROW> RowSet;
++ typedef ::std::hash_map<SCCOL, RowSet> ColSet;
++ struct TabItem
++ {
++ SCTAB mnIndex;
++ ColSet maCols;
++ explicit TabItem(SCTAB nIndex);
++ explicit TabItem(const TabItem& r);
++ };
++ typedef ::boost::shared_ptr<TabItem> TabItemRef;
++
++ /**
++ * Return the position that points either to the specified table
++ * position or to the position where a new table would be inserted in
++ * case the specified table is not present.
++ *
++ * @param nTab index of the desired table
++ */
++ ::std::list<TabItemRef>::iterator getTabPos(SCTAB nTab);
++
++ // This list must be sorted by the table index at all times.
++ ::std::list<TabItemRef> maTables;
+ };
+
++private:
+ /** Shell instance for a source document. */
+ struct SrcShell
+ {
@@ -531,14 +566,10 @@
+ Time maLastAccess;
+ };
+
-+ typedef ::boost::shared_ptr<ScToken> TokenRef;
-+ typedef ::boost::shared_ptr<ScTokenArray> TokenArrayRef;
++ typedef ::std::hash_map<sal_uInt16, SrcShell> DocShellMap;
++ typedef ::std::hash_set<sal_uInt16> LinkedDocSet;
+
-+ typedef ::std::hash_map<sal_uInt16, SrcShell> DocShellMap;
-+ typedef ::std::hash_set<sal_uInt16> LinkedDocSet;
-+
-+ typedef ::std::hash_set<ScAddress, AddressHash, ::std::equal_to<ScAddress> > RefCellSet;
-+ typedef ::std::hash_map<sal_uInt16, RefCellSet> RefCellMap;
++ typedef ::std::hash_map<sal_uInt16, RefCells> RefCellMap;
+
+public:
+ /** Source document meta-data container. */
@@ -666,7 +697,33 @@
+ */
+ void resetSrcFileData();
+
-+ void updateRefCell(const ScAddress& rOldPos, const ScAddress& rNewPos);
++ /**
++ * Update a single referencing cell position.
++ *
++ * @param rOldPos old position
++ * @param rNewPos new position
++ */
++ void updateRefCell(const ScAddress& rOldPos, const ScAddress& rNewPos, bool bCopy);
++
++ /**
++ * Update referencing cells affected by sheet movement.
++ *
++ * @param nOldTab old sheet position
++ * @param nNewTab new sheet position
++ * @param bCopy whether this is a sheet move (false) or sheet copy (true)
++ */
++ void updateRefMoveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy);
++
++ /**
++ * Update referencing cells affected by sheet insertion.
++ *
++ * @param nPos sheet insertion position. All sheets to the right
++ * including the one at the insertion poistion shift to the
++ * right by one.
++ */
++ void updateRefInsertTable(SCTAB nPos);
++
++ void updateRefDeleteTable(SCTAB nPos);
+
+private:
+ ScExternalRefManager();
@@ -1087,7 +1144,7 @@
ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex( t->GetIndex() );
if( pRangeData )
diff --git sc/source/core/data/cell2.cxx sc/source/core/data/cell2.cxx
-index fc6df5f..2d71b6e 100644
+index fc6df5f..b49a9fd 100644
--- sc/source/core/data/cell2.cxx
+++ sc/source/core/data/cell2.cxx
@@ -7,7 +7,7 @@
@@ -1118,7 +1175,7 @@
+ StackVar sv = t->GetType();
+ if (sv == svExternalSingleRef || sv == svExternalDoubleRef || sv == svExternalName)
+ {
-+ pDocument->GetExternalRefManager()->updateRefCell(aOldPos, aPos);
++ pDocument->GetExternalRefManager()->updateRefCell(aOldPos, aPos, eUpdateRefMode == URM_COPY);
+ break;
+ }
+ }
@@ -1126,7 +1183,7 @@
void ScFormulaCell::UpdateInsertTab(SCTAB nTable)
diff --git sc/source/core/data/documen2.cxx sc/source/core/data/documen2.cxx
-index b75279e..d739a17 100644
+index b75279e..825baf5 100644
--- sc/source/core/data/documen2.cxx
+++ sc/source/core/data/documen2.cxx
@@ -94,6 +94,7 @@
@@ -1157,6 +1214,28 @@
ScAddInAsync::RemoveDocument( this );
ScAddInListener::RemoveDocument( this );
delete pChartListenerCollection; // vor pBASM wg. evtl. Listener!
+@@ -1429,6 +1436,10 @@ BOOL ScDocument::MoveTab( SCTAB nOldPos, SCTAB nNewPos )
+ if (pDrawLayer)
+ DrawMovePage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
+
++ // Update cells containing external references.
++ if (pExternalRefMgr.get())
++ pExternalRefMgr->updateRefMoveTable(nOldPos, nNewPos, false);
++
+ bValid = TRUE;
+ }
+ }
+@@ -1548,6 +1559,10 @@ BOOL ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
+ DrawCopyPage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
+
+ pTab[nNewPos]->SetPageStyle( pTab[nOldPos]->GetPageStyle() );
++
++ // Update cells containing external references.
++ if (pExternalRefMgr.get())
++ pExternalRefMgr->updateRefMoveTable(nOldPos, nNewPos, true);
+ }
+ else
+ SetAutoCalc( bOldAutoCalc );
diff --git sc/source/core/data/documen3.cxx sc/source/core/data/documen3.cxx
index 541e2e4..20dae1e 100644
--- sc/source/core/data/documen3.cxx
@@ -1242,7 +1321,7 @@
{
if (pLinkManager)
diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
-index 886156d..0fb382f 100644
+index 886156d..6183449 100644
--- sc/source/core/data/document.cxx
+++ sc/source/core/data/document.cxx
@@ -7,7 +7,7 @@
@@ -1254,6 +1333,38 @@
*
* This file is part of OpenOffice.org.
*
+@@ -91,6 +91,7 @@
+ #include "bcaslot.hxx"
+ #include "postit.hxx"
+ #include "tabprotection.hxx"
++#include "externalrefmgr.hxx"
+
+ struct ScDefaultAttr
+ {
+@@ -368,6 +369,10 @@ BOOL ScDocument::InsertTab( SCTAB nPos, const String& rName,
+ if ( pChartListenerCollection )
+ pChartListenerCollection->UpdateScheduledSeriesRanges();
+
++ // Update cells containing external references.
++ if (pExternalRefMgr.get())
++ pExternalRefMgr->updateRefInsertTable(nPos);
++
+ SetDirty();
+ bValid = TRUE;
+ }
+@@ -457,6 +462,12 @@ BOOL ScDocument::DeleteTab( SCTAB nTab, ScDocument* pRefUndoDoc )
+ }
+ // #81844# sheet names of references are not valid until sheet is deleted
+ pChartListenerCollection->UpdateScheduledSeriesRanges();
++
++
++ // Update cells containing external references.
++ if (pExternalRefMgr.get())
++ pExternalRefMgr->updateRefDeleteTable(nTab);
++
+ SetAutoCalc( bOldAutoCalc );
+ bValid = TRUE;
+ }
diff --git sc/source/core/inc/interpre.hxx sc/source/core/inc/interpre.hxx
index b9dd766..3a85852 100644
--- sc/source/core/inc/interpre.hxx
@@ -2099,7 +2210,7 @@
aString.Append( '$' );
diff --git sc/source/core/tool/compiler.cxx sc/source/core/tool/compiler.cxx
-index 918332d..41df88b 100644
+index d39afdf..be4ee1c 100644
--- sc/source/core/tool/compiler.cxx
+++ sc/source/core/tool/compiler.cxx
@@ -74,9 +74,11 @@
@@ -2123,7 +2234,7 @@
enum ScanState
{
-@@ -680,20 +682,15 @@ void ScCompiler::SetGrammar( const ScGrammar::Grammar eGrammar )
+@@ -707,20 +709,15 @@ void ScCompiler::SetGrammar( const ScGrammar::Grammar eGrammar )
xMap = ScCompiler::GetOpCodeMap( ::com::sun::star::sheet::FormulaLanguage::NATIVE);
eMyGrammar = xMap->getGrammar();
}
@@ -2150,8 +2261,8 @@
+ SetGrammarAndRefConvention( eMyGrammar, eOldGrammar);
}
- // static
-@@ -737,7 +734,25 @@ void ScCompiler::SetFormulaLanguage( const ScCompiler::OpCodeMapPtr & xMap )
+ void ScCompiler::SetFormulaLanguage( const ScCompiler::OpCodeMapPtr & xMap )
+@@ -736,7 +733,25 @@ void ScCompiler::SetFormulaLanguage( const ScCompiler::OpCodeMapPtr & xMap )
}
else
pCharClass = ScGlobal::pCharClass;
@@ -2177,7 +2288,7 @@
}
-@@ -866,20 +881,19 @@ ScCompiler::OpCodeMap::createSequenceOfAvailableMappings( const sal_Int32 nGroup
+@@ -865,20 +880,19 @@ ScCompiler::OpCodeMap::createSequenceOfAvailableMappings( const sal_Int32 nGroup
sal_Int32 nOff;
OpCode eOp;
} aMap[] = {
@@ -2211,7 +2322,7 @@
};
const size_t nCount = sizeof(aMap)/sizeof(aMap[0]);
// Preallocate vector elements.
-@@ -1078,7 +1092,7 @@ ScCompiler::Convention::Convention( ScAddress::Convention eConv )
+@@ -1077,7 +1091,7 @@ ScCompiler::Convention::Convention( ScAddress::Convention eConv )
/* */ t[32] = SC_COMPILER_C_CHAR_DONTCARE | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
/* ! */ t[33] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
if (ScAddress::CONV_ODF == meConv)
@@ -2220,7 +2331,7 @@
/* " */ t[34] = SC_COMPILER_C_CHAR_STRING | SC_COMPILER_C_STRING_SEP;
/* # */ t[35] = SC_COMPILER_C_WORD_SEP;
/* $ */ t[36] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT;
-@@ -1093,8 +1107,10 @@ ScCompiler::Convention::Convention( ScAddress::Convention eConv )
+@@ -1092,8 +1106,10 @@ ScCompiler::Convention::Convention( ScAddress::Convention eConv )
/* - */ t[45] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_SIGN;
/* . */ t[46] = SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_VALUE | SC_COMPILER_C_IDENT;
/* / */ t[47] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
@@ -2232,7 +2343,7 @@
/* : */ t[58] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD;
/* ; */ t[59] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
/* < */ t[60] = SC_COMPILER_C_CHAR_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-@@ -1102,8 +1118,10 @@ for (i = 48; i < 58; i++)
+@@ -1101,8 +1117,10 @@ for (i = 48; i < 58; i++)
/* > */ t[62] = SC_COMPILER_C_CHAR_BOOL | SC_COMPILER_C_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
/* ? */ t[63] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD;
/* @ */ // FREE
@@ -2244,7 +2355,7 @@
if (ScAddress::CONV_ODF == meConv)
{
/* [ */ t[91] = SC_COMPILER_C_ODF_LBRACKET;
-@@ -1119,14 +1137,17 @@ for (i = 65; i < 91; i++)
+@@ -1118,14 +1136,17 @@ for (i = 65; i < 91; i++)
/* ^ */ t[94] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
/* _ */ t[95] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT;
/* ` */ // FREE
@@ -2264,7 +2375,7 @@
{
/* */ t[32] |= SC_COMPILER_C_WORD;
/* ! */ t[33] |= SC_COMPILER_C_IDENT | SC_COMPILER_C_WORD;
-@@ -1165,9 +1186,14 @@ for (i = 97; i < 123; i++)
+@@ -1164,9 +1185,14 @@ for (i = 97; i < 123; i++)
if( ScAddress::CONV_XL_R1C1 == meConv )
{
@@ -2282,7 +2393,7 @@
}
}
}
-@@ -1191,7 +1217,7 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
+@@ -1190,7 +1216,7 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
{
rRes.TokenType = KParseType::SINGLE_QUOTE_NAME;
rRes.EndPos = nPos+1;
@@ -2291,7 +2402,7 @@
}
++nPos;
}
-@@ -1199,9 +1225,203 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
+@@ -1198,9 +1224,203 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
}
}
@@ -2431,9 +2542,9 @@
+
+ rFile = aTmpFile;
+ rName = aTmpName;
- return true;
- }
-
++ return true;
++}
++
+static String lcl_makeExternalNameStr( const String& rFile, const String& rName,
+ const sal_Unicode cSep, bool bODF )
+{
@@ -2479,9 +2590,9 @@
+ else
+ rTabName2 = rTabName1;
+
-+ return true;
-+}
-+
+ return true;
+ }
+
+static void lcl_appendTabName(::rtl::OUStringBuffer& rBuffer, const String& rTabName)
+{
+ bool bQuote = (rTabName.Search(sal_Unicode(' '), 0) != STRING_NOTFOUND);
@@ -2495,7 +2606,7 @@
struct Convention_A1 : public ScCompiler::Convention
{
Convention_A1( ScAddress::Convention eConv ) : ScCompiler::Convention( eConv ) { }
-@@ -1215,14 +1435,14 @@ struct Convention_A1 : public ScCompiler::Convention
+@@ -1214,14 +1434,14 @@ struct Convention_A1 : public ScCompiler::Convention
const CharClass* pCharClass) const
{
ParseResult aRet;
@@ -2512,7 +2623,7 @@
return pCharClass->parseAnyToken( rFormula,
nSrcPos, nStartFlags, aAddAllowed, nContFlags, aAddAllowed );
}
-@@ -1405,6 +1625,114 @@ struct ConventionOOO_A1 : public Convention_A1
+@@ -1404,6 +1624,121 @@ struct ConventionOOO_A1 : public Convention_A1
return sal_Unicode(0);
}
@@ -2603,16 +2714,23 @@
+ vector<String> aTabNames;
+ pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
+ if (aTabNames.empty())
++ {
++ DBG_ERROR1( "ConventionOOO_A1::makeExternalRefStrImpl: no sheet names for document ID %s", nFileId);
+ break;
++ }
+
+ String aLastTabName;
+ if (!lcl_getLastTabName(aLastTabName, rTabName, aTabNames, aRef))
+ {
+ rBuffer.append(aLastTabName);
++ DBG_ERROR( "ConventionOOO_A1::makeExternalRefStrImpl: sheet name not found");
+ break;
+ }
++ bool bDisplayTabName = (aRef.Ref1.nTab != aRef.Ref2.nTab);
++ if (bODF && !bDisplayTabName)
++ rBuffer.append( sal_Unicode('.')); // need at least the sheet separator in ODF
+ makeExternalSingleRefStr( rBuffer, nFileId, aLastTabName,
-+ aRef.Ref2, pRefMgr, (aRef.Ref1.nTab != aRef.Ref2.nTab));
++ aRef.Ref2, pRefMgr, bDisplayTabName);
+ } while (0);
+ if (bODF)
+ rBuffer.append( sal_Unicode(']'));
@@ -2627,7 +2745,7 @@
};
-@@ -1423,6 +1751,25 @@ struct ConventionOOO_A1_ODF : public ConventionOOO_A1
+@@ -1422,6 +1757,25 @@ struct ConventionOOO_A1_ODF : public ConventionOOO_A1
{
MakeRefStrImpl( rBuffer, rComp, rRef, bSingleRef, true);
}
@@ -2653,7 +2771,7 @@
};
static const ConventionOOO_A1_ODF ConvOOO_A1_ODF;
-@@ -1526,11 +1873,129 @@ struct ConventionXL
+@@ -1525,11 +1879,129 @@ struct ConventionXL
}
return sal_Unicode(0);
}
@@ -2783,7 +2901,7 @@
void MakeRefStr( rtl::OUStringBuffer& rBuf,
const ScCompiler& rComp,
const ComplRefData& rRef,
-@@ -1584,22 +2049,11 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
+@@ -1583,22 +2055,11 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
}
}
@@ -2808,7 +2926,7 @@
}
}
-@@ -1607,8 +2061,10 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
+@@ -1606,8 +2067,10 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
xub_StrLen nSrcPos,
const CharClass* pCharClass) const
{
@@ -2820,7 +2938,7 @@
return aRet;
static const sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
-@@ -1624,11 +2080,83 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
+@@ -1623,11 +2086,83 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
{
return ConventionXL::getSpecialSymbol(eSymType);
}
@@ -2904,7 +3022,7 @@
//-----------------------------------------------------------------------------
static void
-@@ -1733,8 +2261,10 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
+@@ -1732,8 +2267,10 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
xub_StrLen nSrcPos,
const CharClass* pCharClass) const
{
@@ -2916,7 +3034,7 @@
return aRet;
static const sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
-@@ -1751,6 +2281,96 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
+@@ -1750,6 +2287,96 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
{
return ConventionXL::getSpecialSymbol(eSymType);
}
@@ -3013,7 +3131,7 @@
};
static const ConventionXL_R1C1 ConvXL_R1C1;
-@@ -1817,13 +2437,15 @@ void ScCompiler::CheckTabQuotes( String& rString,
+@@ -1816,13 +2443,15 @@ void ScCompiler::CheckTabQuotes( String& rString,
KParseType::IDENTNAME, rString, 0, nStartFlags, EMPTY_STRING, nContFlags, EMPTY_STRING);
bool bNeedsQuote = !((aRes.TokenType & KParseType::IDENTNAME) && aRes.EndPos == rString.Len());
@@ -3030,7 +3148,7 @@
if( bNeedsQuote )
{
static const String one_quote = static_cast<sal_Unicode>( '\'' );
-@@ -1859,6 +2481,7 @@ void ScCompiler::SetRefConvention( ScAddress::Convention eConv )
+@@ -1858,6 +2487,7 @@ void ScCompiler::SetRefConvention( ScAddress::Convention eConv )
case ScAddress::CONV_ODF : SetRefConvention( pConvOOO_A1_ODF ); break;
case ScAddress::CONV_XL_A1 : SetRefConvention( pConvXL_A1 ); break;
case ScAddress::CONV_XL_R1C1 : SetRefConvention( pConvXL_R1C1 ); break;
@@ -3038,25 +3156,152 @@
}
}
-@@ -2208,7 +2831,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
- static const int kQuote = kInc * 2;
- static const int kPast = kInc * 3;
+@@ -2184,71 +2814,88 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+ }
+ // fall through and follow logic
+ case ssSkipReference:
+- // ODF reference: [$'Sheet'.A1:.B2] with dots being mandatory
+- // also if no sheet name.
+- //
+- // nRefInSheetName: 0 := not in sheet name yet.
+- // +1 := encountered leading '$'
+- // +2 := encountered opening ''', which
+- // may be after $ or not.
+- // 4(+ ) := somewhere in sheet name.
+- // 8(+ ) := encountered ''' in sheet name,
+- // will be decremented (-4) again if
+- // double or incremented (+4) again
+- // if not.
+- // 12(+ ) := past closing ''' or no sheet name
+- // and past leading '.'
++ // ODF reference: ['External'#$'Sheet'.A1:.B2] with dots being
++ // mandatory also if no sheet name. 'External'# is optional,
++ // sheet name is optional, quotes around sheet name are
++ // optional if no quote contained.
+ {
+- // kOpen can be used in bit tests in this arrangement
+- static const int kDollar = 1;
+- static const int kOpen = 2;
+- static const int kInc = 4;
+- static const int kSheet = kInc * 1;
+- static const int kQuote = kInc * 2;
+- static const int kPast = kInc * 3;
++
++ // nRefInSheetName: 0 := not in sheet name yet. 'External'
++ // is parsed as if it was a sheet name and nRefInSheetName
++ // is reset when # is encountered immediately after closing
++ // quote.
++
++ // Encountered leading $.
++ static const int kDollar = (1 << 1);
++ // Encountered ' opening quote, which may be after $ or
++ // not.
++ static const int kOpen = (1 << 2);
++ // Somewhere in sheet name.
++ static const int kSheet = (1 << 3);
++ // Encountered ' in sheet name, will be cleared if double
++ // or transformed to kClose if not, in which case kOpen is
++ // cleared.
++ static const int kQuote = (1 << 4);
++ // Past ' closing quote.
++ static const int kClose = (1 << 5);
++ // Past . sheet name separator.
++ static const int kPast = (1 << 6);
++
bool bAddToSymbol = true;
- if ('.' == c && nRefInSheetName == 0)
+ if (cSheetSep == c && nRefInSheetName == 0)
{
- // eat it, no sheet name
+- // eat it, no sheet name
++ // eat it, no sheet name [.A1]
bAddToSymbol = false;
-@@ -2223,7 +2846,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+- nRefInSheetName = kPast;
++ nRefInSheetName |= kPast;
}
- else if (nRefInSheetName < kPast)
+- else if (':' == c && nRefInSheetName < kSheet)
++ else if (!(nRefInSheetName & kPast))
{
+- DBG_ERRORFILE("ScCompiler::NextSymbol: reference:"
+- "range operator ':' without prior sheet name separator '.' violates ODF spec");
+- nRefInSheetName = 0;
+- ++mnPredetectedReference;
+- }
+- else if (nRefInSheetName < kPast)
+- {
- if ('$' == c && nRefInSheetName < kDollar)
-+ if (cSheetPrefix == c && nRefInSheetName < kDollar)
- nRefInSheetName += kDollar;
+- nRefInSheetName += kDollar;
++ if (nMask & SC_COMPILER_C_ODF_RBRACKET &&
++ !(nRefInSheetName & kOpen))
++ {
++ DBG_ERRORFILE("ScCompiler::NextSymbol: reference: "
++ "closing bracket ']' without prior sheet name separator '.' violates ODF spec");
++ // eaten, not added to pSym
++ bAddToSymbol = false;
++ eState = ssStop;
++ }
++ else if (cSheetPrefix == c && nRefInSheetName == 0)
++ nRefInSheetName |= kDollar;
else if ('\'' == c)
{
-@@ -2545,7 +3168,8 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
+- if (nRefInSheetName < kSheet)
+- nRefInSheetName += kOpen + kSheet;
++ if (!(nRefInSheetName & kSheet))
++ nRefInSheetName |= (kOpen | kSheet);
+ else if (!(nRefInSheetName & kOpen))
+ {
+- DBG_ERRORFILE("ScCompiler::NextSymbol: reference:"
++ DBG_ERRORFILE("ScCompiler::NextSymbol: reference: "
+ "a ''' without the sheet name being enclosed in '...' violates ODF spec");
+ }
+- else if (nRefInSheetName >= kQuote)
++ else if (nRefInSheetName & kQuote)
+ // escaped embedded quote
+- nRefInSheetName -= kInc;
++ nRefInSheetName &= ~kQuote;
+ else
+ // a quote in (or after) sheet name
+- nRefInSheetName += kInc;
++ nRefInSheetName |= kQuote;
+ }
+- else if ('.' == c && !(nRefInSheetName & kOpen))
++ else if (cSheetSep == c && !(nRefInSheetName & kOpen))
+ // unquoted sheet name separator
+- nRefInSheetName += kPast;
+- else if (nRefInSheetName < kSheet)
++ nRefInSheetName |= kPast;
++ else if (':' == c && !(nRefInSheetName & kOpen))
++ {
++ DBG_ERRORFILE("ScCompiler::NextSymbol: reference: "
++ "range operator ':' without prior sheet name separator '.' violates ODF spec");
++ nRefInSheetName = 0;
++ ++mnPredetectedReference;
++ }
++ else if (!(nRefInSheetName & kSheet))
+ // start unquoted sheet name
+- nRefInSheetName += kSheet;
+- else if (nRefInSheetName >= kQuote)
+- // quote not followed by quote => past
+- nRefInSheetName += kInc;
++ nRefInSheetName |= kSheet;
++ else if (nRefInSheetName & kQuote)
++ {
++ // quote not followed by quote => close
++ nRefInSheetName |= kClose;
++ nRefInSheetName &= ~kOpen;
++ }
+ }
+ else if (':' == c)
+ {
+@@ -2263,7 +2910,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+ eState = ssStop;
+ }
+ if (bAddToSymbol && eState != ssSkipReference)
+- *pSym++ = c; // everything is part of sheet reference
++ *pSym++ = c; // everything is part of reference
+ }
+ break;
+ case ssStop:
+@@ -2544,7 +3191,8 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
{
ScRange aRange( aPos, aPos );
const ScAddress::Details aDetails( pConv->meConv, aPos );
@@ -3066,7 +3311,7 @@
if( nFlags & SCA_VALID )
{
ScRawToken aToken;
-@@ -2564,7 +3188,17 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
+@@ -2563,7 +3211,17 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
aRef.Ref2.SetTabDeleted( TRUE ); // #REF!
aRef.Ref2.SetFlag3D( ( nFlags & SCA_TAB2_3D ) != 0 );
aRef.CalcRelFromAbs( aPos );
@@ -3085,7 +3330,7 @@
pRawToken = aToken.Clone();
}
-@@ -2576,7 +3210,8 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
+@@ -2575,7 +3233,8 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
{
ScAddress aAddr( aPos );
const ScAddress::Details aDetails( pConv->meConv, aPos );
@@ -3095,7 +3340,7 @@
// Something must be valid in order to recognize Sheet1.blah or blah.a1
// as a (wrong) reference.
if( nFlags & ( SCA_VALID_COL|SCA_VALID_ROW|SCA_VALID_TAB ) )
-@@ -2600,7 +3235,16 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
+@@ -2599,7 +3258,16 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
nFlags |= SCA_VALID;
}
aRef.CalcRelFromAbs( aPos );
@@ -3113,7 +3358,7 @@
pRawToken = aToken.Clone();
}
-@@ -2708,6 +3352,32 @@ BOOL ScCompiler::IsNamedRange( const String& rUpperName )
+@@ -2707,6 +3375,32 @@ BOOL ScCompiler::IsNamedRange( const String& rUpperName )
return FALSE;
}
@@ -3146,7 +3391,7 @@
BOOL ScCompiler::IsDBRange( const String& rName )
{
USHORT n;
-@@ -3243,7 +3913,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
+@@ -3242,7 +3936,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
if (mnPredetectedReference)
{
String aStr( cSymbol);
@@ -3155,7 +3400,7 @@
{
/* TODO: it would be nice to generate a #REF! error here, which
* would need an ocBad token with additional error value.
-@@ -3306,6 +3976,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
+@@ -3305,6 +3999,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
&& !(bAllowBooleans && IsBoolean( aUpper ))
&& !IsValue( aUpper )
&& !IsNamedRange( aUpper )
@@ -3163,7 +3408,7 @@
&& !IsDBRange( aUpper )
&& !IsColRowName( aUpper )
&& !(bMayBeFuncName && IsMacro( aUpper ))
-@@ -3628,9 +4299,9 @@ BOOL ScCompiler::GetToken()
+@@ -3627,9 +4322,9 @@ BOOL ScCompiler::GetToken()
else
{
if ( nWasColRowName >= 2 && pToken->GetOpCode() == ocColRowName )
@@ -3175,33 +3420,58 @@
}
}
}
-@@ -3641,6 +4312,25 @@ BOOL ScCompiler::GetToken()
+@@ -3640,6 +4335,50 @@ BOOL ScCompiler::GetToken()
}
if( pToken->GetOpCode() == ocSubTotal )
glSubTotal = TRUE;
-+ else if ( pToken->GetOpCode() == ocExternalRef && pToken->GetType() == svExternalName )
++ else if ( pToken->GetOpCode() == ocExternalRef )
+ {
+ // Handle external range names.
++ switch (pToken->GetType())
++ {
++ case svExternalSingleRef:
++ case svExternalDoubleRef:
++ pArr->nRefs++;
++ break;
++ case svExternalName:
++ {
++ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
++ const String* pFile = pRefMgr->getExternalFileName(pToken->GetIndex());
++ if (!pFile)
++ {
++ SetError(errNoName);
++ return true;
++ }
+
-+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
-+ const String* pFile = pRefMgr->getExternalFileName(pToken->GetIndex());
-+ if (!pFile)
-+ SetError(errNoName);
-+
-+ const String& rName = pToken->GetString();
-+ ScExternalRefCache::TokenArrayRef xNew = pRefMgr->getRangeNameTokens(pToken->GetIndex(), rName, &aPos);
-+ if (!xNew)
-+ SetError(errNoName);
-+
-+ ScTokenArray* pNew = xNew->Clone();
-+ PushTokenArray( pNew, true);
-+ pNew->Reset();
-+ return GetToken();
++ const String& rName = pToken->GetString();
++ ScExternalRefCache::TokenArrayRef xNew = pRefMgr->getRangeNameTokens(
++ pToken->GetIndex(), rName, &aPos);
++
++ if (!xNew)
++ {
++ SetError(errNoName);
++ return true;
++ }
++
++ ScTokenArray* pNew = xNew->Clone();
++ PushTokenArray( pNew, true);
++ if (pNew->GetNextReference() != NULL)
++ {
++ SetRelNameReference();
++ MoveRelWrap();
++ }
++ pNew->Reset();
++ return GetToken();
++ }
++ break;
++ default:
++ DBG_ERROR1( "ScCompiler::GetToken: unhandled ocExternalRef type %d", pToken->GetType());
++ }
+ }
else if( pToken->GetOpCode() == ocName )
{
ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex( pToken->GetIndex() );
-@@ -3796,7 +4486,7 @@ BOOL ScCompiler::GetToken()
+@@ -3795,7 +4534,7 @@ BOOL ScCompiler::GetToken()
{ // next defined RowNameRange to the right limits column
const ScRange& rRange = pR->GetRange(1);
if ( rRange.aStart.Row() <= nRow && nRow <= rRange.aEnd.Row() )
@@ -3210,18 +3480,7 @@
SCCOL nTmp = rRange.aStart.Col();
if ( nStartCol < nTmp && nTmp <= nMaxCol )
nMaxCol = nTmp - 1;
-@@ -3937,6 +4627,10 @@ BOOL ScCompiler::GetToken()
- // SetError(errNoRef);
- pArr->nRefs++;
- }
-+ else if ( pToken->GetType() == svExternalSingleRef || pToken->GetType() == svExternalDoubleRef )
-+ {
-+ pArr->nRefs++;
-+ }
- return TRUE;
- }
-
-@@ -4420,6 +5114,11 @@ void ScCompiler::Factor()
+@@ -4419,6 +5158,11 @@ void ScCompiler::Factor()
bCorrected = TRUE;
}
}
@@ -3233,7 +3492,25 @@
else
{
SetError( errUnknownToken );
-@@ -4830,7 +5529,7 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
+@@ -4700,7 +5444,7 @@ void ScCompiler::MoveRelWrap()
+ for( ScToken* t = pArr->GetNextReference(); t;
+ t = pArr->GetNextReference() )
+ {
+- if ( t->GetType() == svSingleRef )
++ if ( t->GetType() == svSingleRef || t->GetType() == svExternalSingleRef )
+ ScRefUpdate::MoveRelWrap( pDoc, aPos, SingleDoubleRefModifier( t->GetSingleRef() ).Ref() );
+ else
+ ScRefUpdate::MoveRelWrap( pDoc, aPos, t->GetDoubleRef() );
+@@ -4717,7 +5461,7 @@ void ScCompiler::MoveRelWrap( ScTokenArray& rArr, ScDocument* pDoc,
+ for( ScToken* t = rArr.GetNextReference(); t;
+ t = rArr.GetNextReference() )
+ {
+- if ( t->GetType() == svSingleRef )
++ if ( t->GetType() == svSingleRef || t->GetType() == svExternalSingleRef )
+ ScRefUpdate::MoveRelWrap( pDoc, rPos, SingleDoubleRefModifier( t->GetSingleRef() ).Ref() );
+ else
+ ScRefUpdate::MoveRelWrap( pDoc, rPos, t->GetDoubleRef() );
+@@ -4829,7 +5573,7 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
else if( t->GetType() != svIndex ) // it may be a DB area!!!
{
t->CalcAbsIfRel( rOldPos );
@@ -3242,7 +3519,7 @@
{
if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos,
r, nDx, nDy, nDz,
-@@ -5638,111 +6337,144 @@ ScToken* ScCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToke
+@@ -5637,111 +6381,144 @@ ScToken* ScCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToke
DBG_ERRORFILE("unknown OpCode");
rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
}
@@ -3271,15 +3548,15 @@
{
- rRef.CalcAbsIfRel( aPos );
- if ( pDoc->HasStringData( rRef.nCol, rRef.nRow, rRef.nTab ) )
-+ case svExternalName:
- {
+- {
- String aStr;
- pDoc->GetString( rRef.nCol, rRef.nRow, rRef.nTab, aStr );
- EnQuote( aStr );
- rBuffer.append(aStr);
- }
- else
-- {
++ case svExternalName:
+ {
- rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
- pConv->MakeRefStr (rBuffer, *this, aRef, TRUE );
+ const String *pStr = pRefMgr->getExternalFileName(t->GetIndex());
@@ -8748,10 +9025,10 @@
diff --git sc/source/ui/docshell/externalrefmgr.cxx sc/source/ui/docshell/externalrefmgr.cxx
new file mode 100644
-index 0000000..bcfa272
+index 0000000..ae864bb
--- /dev/null
+++ sc/source/ui/docshell/externalrefmgr.cxx
-@@ -0,0 +1,1507 @@
+@@ -0,0 +1,1742 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -8828,6 +9105,8 @@
+using ::std::find;
+using ::std::find_if;
+using ::std::distance;
++using ::std::pair;
++using ::std::list;
+
+#define SRCDOC_LIFE_SPAN 6000 // 1 minute (in 100th of a sec)
+#define SRCDOC_SCAN_INTERVAL 1000*5 // every 5 seconds (in msec)
@@ -8852,6 +9131,23 @@
+ String maSearchName;
+};
+
++class FindSrcFileByName : public ::std::unary_function<ScExternalRefManager::SrcFileData, bool>
++{
++public:
++ FindSrcFileByName(const String& rMatchName) :
++ mrMatchName(rMatchName)
++ {
++ }
++
++ bool operator()(const ScExternalRefManager::SrcFileData& rSrcData) const
++ {
++ return rSrcData.maFileName.Equals(mrMatchName);
++ }
++
++private:
++ const String& mrMatchName;
++};
++
+}
+
+// ============================================================================
@@ -9611,6 +9907,223 @@
+ return maRefCache.getCacheTable(nFileId, rTabName, bCreateNew, pnIndex);
+}
+
++// ============================================================================
++
++ScExternalRefManager::RefCells::TabItem::TabItem(SCTAB nIndex) :
++ mnIndex(nIndex)
++{
++}
++
++ScExternalRefManager::RefCells::TabItem::TabItem(const TabItem& r) :
++ mnIndex(r.mnIndex),
++ maCols(r.maCols)
++{
++}
++
++ScExternalRefManager::RefCells::RefCells()
++{
++}
++
++ScExternalRefManager::RefCells::~RefCells()
++{
++}
++
++list<ScExternalRefManager::RefCells::TabItemRef>::iterator ScExternalRefManager::RefCells::getTabPos(SCTAB nTab)
++{
++ list<TabItemRef>::iterator itr = maTables.begin(), itrEnd = maTables.end();
++ for (; itr != itrEnd; ++itr)
++ if ((*itr)->mnIndex >= nTab)
++ return itr;
++ // Not found. return the end position.
++ return itrEnd;
++}
++
++void ScExternalRefManager::RefCells::insertCell(const ScAddress& rAddr)
++{
++ SCTAB nTab = rAddr.Tab();
++ SCCOL nCol = rAddr.Col();
++ SCROW nRow = rAddr.Row();
++
++ // Search by table index.
++ list<TabItemRef>::iterator itrTab = getTabPos(nTab);
++ TabItemRef xTabRef;
++ if (itrTab == maTables.end())
++ {
++ // All previous tables come before the specificed table.
++ xTabRef.reset(new TabItem(nTab));
++ maTables.push_back(xTabRef);
++ }
++ else if ((*itrTab)->mnIndex > nTab)
++ {
++ // Insert at the current iterator position.
++ xTabRef.reset(new TabItem(nTab));
++ maTables.insert(itrTab, xTabRef);
++ }
++ else if ((*itrTab)->mnIndex == nTab)
++ {
++ // The table found.
++ xTabRef = *itrTab;
++ }
++ ColSet& rCols = xTabRef->maCols;
++
++ // Then by column index.
++ ColSet::iterator itrCol = rCols.find(nCol);
++ if (itrCol == rCols.end())
++ {
++ RowSet aRows;
++ pair<ColSet::iterator, bool> r = rCols.insert(ColSet::value_type(nCol, aRows));
++ if (!r.second)
++ // column insertion failed.
++ return;
++ itrCol = r.first;
++ }
++ RowSet& rRows = itrCol->second;
++
++ // Finally, insert the row index.
++ rRows.insert(nRow);
++}
++
++void ScExternalRefManager::RefCells::removeCell(const ScAddress& rAddr)
++{
++ SCTAB nTab = rAddr.Tab();
++ SCCOL nCol = rAddr.Col();
++ SCROW nRow = rAddr.Row();
++
++ // Search by table index.
++ list<TabItemRef>::iterator itrTab = getTabPos(nTab);
++ if (itrTab == maTables.end() || (*itrTab)->mnIndex != nTab)
++ // No such table.
++ return;
++
++ ColSet& rCols = (*itrTab)->maCols;
++
++ // Then by column index.
++ ColSet::iterator itrCol = rCols.find(nCol);
++ if (itrCol == rCols.end())
++ // No such column
++ return;
++
++ RowSet& rRows = itrCol->second;
++ rRows.erase(nRow);
++}
++
++void ScExternalRefManager::RefCells::moveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy)
++{
++ if (nOldTab == nNewTab)
++ // Nothing to do here.
++ return;
++
++ list<TabItemRef>::iterator itrOld = getTabPos(nOldTab);
++ if (itrOld == maTables.end() || (*itrOld)->mnIndex != nOldTab)
++ // No table to move or copy.
++ return;
++
++ list<TabItemRef>::iterator itrNew = getTabPos(nNewTab);
++ if (bCopy)
++ {
++ // Simply make a duplicate of the original table, insert it at the
++ // new tab position, and increment the table index for all tables
++ // that come after that inserted table.
++
++ TabItemRef xNewTab(new TabItem(*(*itrOld)));
++ xNewTab->mnIndex = nNewTab;
++ maTables.insert(itrNew, xNewTab);
++ list<TabItemRef>::iterator itr = itrNew, itrEnd = maTables.end();
++ for (++itr; itr != itrEnd; ++itr)
++ (*itr)->mnIndex += 1;
++ }
++ else
++ {
++ if (nOldTab < nNewTab)
++ {
++ // Iterate from the old tab position to the new tab position (not
++ // inclusive of the old tab itself), and decrement their tab
++ // index by one.
++ list<TabItemRef>::iterator itr = itrOld;
++ for (++itr; itr != itrNew; ++itr)
++ (*itr)->mnIndex -= 1;
++
++ // Insert a duplicate of the original table. This does not
++ // invalidate the iterators.
++ (*itrOld)->mnIndex = nNewTab - 1;
++ if (itrNew == maTables.end())
++ maTables.push_back(*itrOld);
++ else
++ maTables.insert(itrNew, *itrOld);
++
++ // Remove the original table.
++ maTables.erase(itrOld);
++ }
++ else
++ {
++ // nNewTab < nOldTab
++
++ // Iterate from the new tab position to the old tab position, and
++ // increment the tab index by one.
++ list<TabItemRef>::iterator itr = itrNew;
++ for (++itr; itr != itrOld; ++itr)
++ (*itr)->mnIndex += 1;
++
++ (*itrOld)->mnIndex = nNewTab;
++ maTables.insert(itrNew, *itrOld);
++
++ maTables.erase(itrOld);
++ }
++ }
++}
++
++void ScExternalRefManager::RefCells::insertTable(SCTAB nPos)
++{
++ TabItemRef xNewTab(new TabItem(nPos));
++ list<TabItemRef>::iterator itr = getTabPos(nPos);
++ if (itr == maTables.end())
++ maTables.push_back(xNewTab);
++ else
++ maTables.insert(itr, xNewTab);
++}
++
++void ScExternalRefManager::RefCells::removeTable(SCTAB nPos)
++{
++ list<TabItemRef>::iterator itr = getTabPos(nPos);
++ if (itr == maTables.end())
++ // nothing to remove.
++ return;
++
++ maTables.erase(itr);
++}
++
++void ScExternalRefManager::RefCells::refreshAllCells(ScExternalRefManager& rRefMgr)
++{
++ // Get ALL the cell positions for re-compilation.
++ for (list<TabItemRef>::iterator itrTab = maTables.begin(), itrTabEnd = maTables.end();
++ itrTab != itrTabEnd; ++itrTab)
++ {
++ SCTAB nTab = (*itrTab)->mnIndex;
++ ColSet& rCols = (*itrTab)->maCols;
++ for (ColSet::iterator itrCol = rCols.begin(), itrColEnd = rCols.end();
++ itrCol != itrColEnd; ++itrCol)
++ {
++ SCCOL nCol = itrCol->first;
++ RowSet& rRows = itrCol->second;
++ RowSet aNewRows;
++ for (RowSet::iterator itrRow = rRows.begin(), itrRowEnd = rRows.end();
++ itrRow != itrRowEnd; ++itrRow)
++ {
++ SCROW nRow = *itrRow;
++ ScAddress aCell(nCol, nRow, nTab);
++ if (rRefMgr.compileTokensByCell(aCell))
++ // This cell still contains an external refernce.
++ aNewRows.insert(nRow);
++ }
++ // Update the rows so that cells with no external references are
++ // no longer tracked.
++ rRows.swap(aNewRows);
++ }
++ }
++}
++
++// ----------------------------------------------------------------------------
++
+void ScExternalRefManager::getAllCachedTableNames(sal_uInt16 nFileId, vector<String>& rTabNames) const
+{
+ maRefCache.getAllTableNames(nFileId, rTabNames);
@@ -9675,7 +10188,7 @@
+ *pTab = nTab;
+
+ pSrcDoc->GetCell(rCell.Col(), rCell.Row(), nTab, pCell);
-+ TokenRef pTok(lcl_convertToToken(pCell));
++ ScExternalRefCache::TokenRef pTok(lcl_convertToToken(pCell));
+
+ if (!pTok.get())
+ {
@@ -9772,7 +10285,7 @@
+ // register the source document with the link manager if it's a new
+ // source.
+
-+ TokenArrayRef pNew(new ScTokenArray);
++ ScExternalRefCache::TokenArrayRef pNew(new ScTokenArray);
+
+ ScTokenArray* pCode = pRangeData->GetCode();
+ for (ScToken* pToken = pCode->First(); pToken; pToken = pCode->Next())
@@ -9815,20 +10328,12 @@
+
+void ScExternalRefManager::refreshAllRefCells(sal_uInt16 nFileId)
+{
-+ RefCellMap::iterator itr = maRefCells.find(nFileId);
-+ if (itr == maRefCells.end())
++ RefCellMap::iterator itrFile = maRefCells.find(nFileId);
++ if (itrFile == maRefCells.end())
+ return;
+
-+ RefCellSet aNewSet;
-+ RefCellSet& rSet = itr->second;
-+ RefCellSet::const_iterator itrSet = rSet.begin(), itrSetEnd = rSet.end();
-+ for (; itrSet != itrSetEnd; ++itrSet)
-+ {
-+ if (compileTokensByCell(*itrSet))
-+ // Cell still contains an external name/ref token.
-+ aNewSet.insert(*itrSet);
-+ }
-+ rSet.swap(aNewSet);
++ RefCells& rRefCells = itrFile->second;
++ rRefCells.refreshAllCells(*this);
+
+ ScViewData* pViewData = ScDocShell::GetViewData();
+ if (!pViewData)
@@ -9846,16 +10351,20 @@
+
+void ScExternalRefManager::insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell)
+{
++ using ::std::pair;
+ RefCellMap::iterator itr = maRefCells.find(nFileId);
-+ if (itr != maRefCells.end())
++ if (itr == maRefCells.end())
+ {
-+ itr->second.insert(rCell);
-+ return;
-+ }
++ RefCells aRefCells;
++ pair<RefCellMap::iterator, bool> r = maRefCells.insert(
++ RefCellMap::value_type(nFileId, aRefCells));
++ if (!r.second)
++ // insertion failed.
++ return;
+
-+ RefCellSet aSet;
-+ aSet.insert(rCell);
-+ maRefCells.insert(RefCellMap::value_type(nFileId, aSet));
++ itr = r.first;
++ }
++ itr->second.insertCell(rCell);
+}
+
+ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId)
@@ -10074,26 +10583,6 @@
+ rFile = ScGlobal::GetAbsDocName(rFile, pDocShell);
+}
+
-+namespace {
-+
-+class FindSrcFileByName : public ::std::unary_function<ScExternalRefManager::SrcFileData, bool>
-+{
-+public:
-+ FindSrcFileByName(const String& rMatchName) :
-+ mrMatchName(rMatchName)
-+ {
-+ }
-+
-+ bool operator()(const ScExternalRefManager::SrcFileData& rSrcData) const
-+ {
-+ return rSrcData.maFileName.Equals(mrMatchName);
-+ }
-+
-+private:
-+ const String& mrMatchName;
-+};
-+
-+}
+sal_uInt16 ScExternalRefManager::getExternalFileId(const String& rFile)
+{
+ vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
@@ -10229,9 +10718,32 @@
+ }
+}
+
-+void ScExternalRefManager::updateRefCell(const ScAddress& /*rOldPos*/, const ScAddress& /*rNewPos*/)
++void ScExternalRefManager::updateRefCell(const ScAddress& rOldPos, const ScAddress& rNewPos, bool bCopy)
++{
++ for (RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); itr != itrEnd; ++itr)
++ {
++ if (!bCopy)
++ itr->second.removeCell(rOldPos);
++ itr->second.insertCell(rNewPos);
++ }
++}
++
++void ScExternalRefManager::updateRefMoveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy)
++{
++ for (RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); itr != itrEnd; ++itr)
++ itr->second.moveTable(nOldTab, nNewTab, bCopy);
++}
++
++void ScExternalRefManager::updateRefInsertTable(SCTAB nPos)
+{
-+ // Implement this.
++ for (RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); itr != itrEnd; ++itr)
++ itr->second.insertTable(nPos);
++}
++
++void ScExternalRefManager::updateRefDeleteTable(SCTAB nPos)
++{
++ for (RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); itr != itrEnd; ++itr)
++ itr->second.removeTable(nPos);
+}
+
+void ScExternalRefManager::purgeStaleSrcDocument(sal_Int32 nTimeOut)
@@ -10799,7 +11311,7 @@
diff --git sc/source/ui/unoobj/tokenuno.cxx sc/source/ui/unoobj/tokenuno.cxx
-index f16b1c5..f515341 100644
+index f16b1c5..1435cde 100644
--- sc/source/ui/unoobj/tokenuno.cxx
+++ sc/source/ui/unoobj/tokenuno.cxx
@@ -31,15 +31,16 @@
@@ -11023,7 +11535,7 @@
switch ( rToken.GetType() )
{
case svByte:
-@@ -473,9 +579,50 @@ bool ScTokenConversion::ConvertToTokenSequence( uno::Sequence<sheet::FormulaToke
+@@ -473,9 +579,52 @@ bool ScTokenConversion::ConvertToTokenSequence( uno::Sequence<sheet::FormulaToke
if (!ScRangeToSequence::FillMixedArray( rAPI.Data, rToken.GetMatrix(), true))
rAPI.Data.clear();
break;
@@ -11067,7 +11579,9 @@
+ break;
default:
+ DBG_ERROR1( "ScTokenConversion::ConvertToTokenSequence: unhandled token type SvStackVar %d", rToken.GetType());
-+ case svSep:
++ case svSep: // occurs with ocSep, ocOpen, ocClose, ocArray*
++ case svJump: // occurs with ocIf, ocChose
++ case svMissing: // occurs with ocMissing
rAPI.Data.clear(); // no data
}
+ rAPI.OpCode = static_cast<sal_Int32>(eOpCode); //! assuming equal values for the moment
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]