Resolves: tdf#96915 implement other-sheet-local named expressions
Change-Id: I0d62536caa6eb455473a755067abc585662cd9a5
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index 22d3c84..7009d94 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -221,15 +221,15 @@ void FormulaToken::SetIndex( sal_uInt16 )
SAL_WARN( "formula.core", "FormulaToken::SetIndex: virtual dummy called" );
}
bool FormulaToken::IsGlobal() const
sal_Int16 FormulaToken::GetSheet() const
{
SAL_WARN( "formula.core", "FormulaToken::IsGlobal: virtual dummy called" );
return true;
SAL_WARN( "formula.core", "FormulaToken::GetSheet: virtual dummy called" );
return -1;
}
void FormulaToken::SetGlobal( bool )
void FormulaToken::SetSheet( sal_Int16 )
{
SAL_WARN( "formula.core", "FormulaToken::SetGlobal: virtual dummy called" );
SAL_WARN( "formula.core", "FormulaToken::SetSheet: virtual dummy called" );
}
short* FormulaToken::GetJump() const
@@ -1724,12 +1724,12 @@ bool FormulaStringOpToken::operator==( const FormulaToken& r ) const
sal_uInt16 FormulaIndexToken::GetIndex() const { return nIndex; }
void FormulaIndexToken::SetIndex( sal_uInt16 n ) { nIndex = n; }
bool FormulaIndexToken::IsGlobal() const { return mbGlobal; }
void FormulaIndexToken::SetGlobal( bool b ) { mbGlobal = b; }
sal_Int16 FormulaIndexToken::GetSheet() const { return mnSheet; }
void FormulaIndexToken::SetSheet( sal_Int16 n ) { mnSheet = n; }
bool FormulaIndexToken::operator==( const FormulaToken& r ) const
{
return FormulaToken::operator==( r ) && nIndex == r.GetIndex() &&
mbGlobal == r.IsGlobal();
mnSheet == r.GetSheet();
}
const OUString& FormulaExternalToken::GetExternal() const { return aExternal; }
sal_uInt8 FormulaExternalToken::GetByte() const { return nByte; }
diff --git a/include/formula/token.hxx b/include/formula/token.hxx
index 618168e..e0cd6b7 100644
--- a/include/formula/token.hxx
+++ b/include/formula/token.hxx
@@ -154,8 +154,8 @@ public:
virtual void SetString( const svl::SharedString& rStr );
virtual sal_uInt16 GetIndex() const;
virtual void SetIndex( sal_uInt16 n );
virtual bool IsGlobal() const;
virtual void SetGlobal( bool b );
virtual sal_Int16 GetSheet() const;
virtual void SetSheet( sal_Int16 n );
virtual short* GetJump() const;
virtual const OUString& GetExternal() const;
virtual FormulaToken* GetFAPOrigToken() const;
@@ -310,18 +310,18 @@ class FORMULA_DLLPUBLIC FormulaIndexToken : public FormulaToken
{
private:
sal_uInt16 nIndex;
bool mbGlobal;
sal_Int16 mnSheet;
public:
FormulaIndexToken( OpCode e, sal_uInt16 n, bool bGlobal = true ) :
FormulaToken( svIndex, e ), nIndex( n ), mbGlobal( bGlobal ) {}
FormulaIndexToken( OpCode e, sal_uInt16 n, sal_Int16 nSheet = -1 ) :
FormulaToken( svIndex, e ), nIndex( n ), mnSheet( nSheet ) {}
FormulaIndexToken( const FormulaIndexToken& r ) :
FormulaToken( r ), nIndex( r.nIndex ), mbGlobal( r.mbGlobal ) {}
FormulaToken( r ), nIndex( r.nIndex ), mnSheet( r.mnSheet ) {}
virtual FormulaToken* Clone() const override { return new FormulaIndexToken(*this); }
virtual sal_uInt16 GetIndex() const override;
virtual void SetIndex( sal_uInt16 n ) override;
virtual bool IsGlobal() const override;
virtual void SetGlobal( bool b ) override;
virtual sal_Int16 GetSheet() const override;
virtual void SetSheet( sal_Int16 n ) override;
virtual bool operator==( const FormulaToken& rToken ) const override;
};
diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx
index a917de7..218f346 100644
--- a/sc/inc/address.hxx
+++ b/sc/inc/address.hxx
@@ -308,11 +308,19 @@ public:
nTabP = nTab;
}
/**
@param pSheetEndPos
If given and Parse() sucessfully parsed a sheet name it returns
the end position (exclusive) behind the sheet name AND a
following sheet name separator. This independent of whether the
resulting reference is fully valid or not.
*/
SC_DLLPUBLIC ScRefFlags Parse(
const OUString&, ScDocument* = nullptr,
const Details& rDetails = detailsOOOa1,
ExternalInfo* pExtInfo = nullptr,
const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr );
const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
sal_Int32* pSheetEndPos = nullptr );
SC_DLLPUBLIC void Format( OStringBuffer& r, ScRefFlags nFlags = ScRefFlags::ZERO,
const ScDocument* pDocument = nullptr,
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index 2af43e4..e1887aa 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -120,7 +120,7 @@ public:
sal_Unicode cName[MAXSTRLEN+1];
} extname;
struct {
bool bGlobal;
sal_Int16 nSheet;
sal_uInt16 nIndex;
} name;
struct {
@@ -157,7 +157,7 @@ public:
void SetErrorConstant( sal_uInt16 nErr );
// These methods are ok to use, reference count not cleared.
void SetName(bool bGlobal, sal_uInt16 nIndex);
void SetName(sal_Int16 nSheet, sal_uInt16 nIndex);
void SetExternalSingleRef( sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef );
void SetExternalDoubleRef( sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef );
void SetExternalName( sal_uInt16 nFileId, const OUString& rName );
@@ -272,6 +272,9 @@ private:
SvNumberFormatter* mpFormatter;
SCTAB mnCurrentSheetTab; // indicates current sheet number parsed so far
sal_Int32 mnCurrentSheetEndPos; // position after current sheet name if parsed
// For CONV_XL_OOX, may be set via API by MOOXML filter.
css::uno::Sequence<css::sheet::ExternalLinkInfo> maExternalLinks;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 7da2b4d..825e511 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -535,6 +535,15 @@ public:
void SetRangeName(SCTAB nTab, ScRangeName* pNew);
void SetRangeName( ScRangeName* pNewRangeName );
/** Find a named expression / range name in either global or a local scope.
@param nIndex
Index of named expression / range name.
@param nTab
If <0 search nIndex in global scope, if >=0 search nIndex in scope of nTab.
@return nullptr if indexed name not found.
*/
ScRangeData* FindRangeNameByIndexAndSheet( sal_uInt16 nIndex, SCTAB nTab ) const;
/**
* Call this immediately before updating all named ranges.
*/
diff --git a/sc/inc/token.hxx b/sc/inc/token.hxx
index 63c5ec7..b056d41 100644
--- a/sc/inc/token.hxx
+++ b/sc/inc/token.hxx
@@ -231,7 +231,7 @@ public:
virtual sal_uInt16 GetIndex() const override;
virtual void SetIndex( sal_uInt16 n ) override;
virtual bool IsGlobal() const override;
virtual sal_Int16 GetSheet() const override;
virtual bool operator==( const formula::FormulaToken& rToken ) const override;
virtual FormulaToken* Clone() const override { return new ScTableRefToken(*this); }
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index 26d6ca4..e495346 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -95,7 +95,7 @@ public:
/** ScSingleRefOpToken with ocMatRef. */
formula::FormulaToken* AddMatrixSingleReference( const ScSingleRefData& rRef );
formula::FormulaToken* AddDoubleReference( const ScComplexRefData& rRef );
formula::FormulaToken* AddRangeName( sal_uInt16 n, bool bGlobal );
formula::FormulaToken* AddRangeName( sal_uInt16 n, sal_Int16 nSheet );
formula::FormulaToken* AddDBRange( sal_uInt16 n );
formula::FormulaToken* AddExternalName( sal_uInt16 nFileId, const OUString& rName );
void AddExternalSingleReference( sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef );
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index b67b04f..84de73c 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -107,7 +107,7 @@ static bool lcl_HasRelRef( ScDocument* pDoc, ScTokenArray* pFormula, sal_uInt16
case svIndex:
{
if( t->GetOpCode() == ocName ) // DB areas always absolute
if( ScRangeData* pRangeData = pDoc->GetRangeName()->findByIndex( t->GetIndex() ) )
if( ScRangeData* pRangeData = pDoc->FindRangeNameByIndexAndSheet( t->GetIndex(), t->GetSheet()) )
if( (nRecursion < 42) && lcl_HasRelRef( pDoc, pRangeData->GetCode(), nRecursion + 1 ) )
return true;
}
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 9f10d88..bada3af 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -234,6 +234,12 @@ const ScRangeData* ScDocument::GetRangeAtBlock( const ScRange& rBlock, OUString*
return pData;
}
ScRangeData* ScDocument::FindRangeNameByIndexAndSheet( sal_uInt16 nIndex, SCTAB nTab ) const
{
const ScRangeName* pRN = (nTab < 0 ? GetRangeName() : GetRangeName(nTab));
return (pRN ? pRN->findByIndex( nIndex) : nullptr);
}
void ScDocument::SetDBCollection( ScDBCollection* pNewDBCollection, bool bRemoveAutoFilter )
{
if (pDBCollection && bRemoveAutoFilter)
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index c97e330..0db0ab4 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -422,16 +422,22 @@ bool lcl_isReference(const FormulaToken& rToken)
void adjustRangeName(formula::FormulaToken* pToken, ScDocument& rNewDoc, const ScDocument* pOldDoc, const ScAddress& aNewPos, const ScAddress& aOldPos)
{
bool bOldGlobal = pToken->IsGlobal();
SCTAB aOldTab = aOldPos.Tab();
bool bSameDoc = (rNewDoc.GetPool() == const_cast<ScDocument*>(pOldDoc)->GetPool());
SCTAB nOldSheet = pToken->GetSheet();
if (bSameDoc && (nOldSheet < 0 || nOldSheet != aOldPos.Tab()))
// Same doc and global name or sheet-local name on other sheet stays
// the same.
return;
OUString aRangeName;
int nOldIndex = pToken->GetIndex();
ScRangeData* pOldRangeData = nullptr;
//search the name of the RangeName
if (!bOldGlobal)
if (nOldSheet >= 0)
{
pOldRangeData = pOldDoc->GetRangeName(aOldTab)->findByIndex(nOldIndex);
const ScRangeName* pRangeName = pOldDoc->GetRangeName(nOldSheet);
pOldRangeData = pRangeName ? pRangeName->findByIndex(nOldIndex) : nullptr;
if (!pOldRangeData)
return; //might be an error in the formula array
aRangeName = pOldRangeData->GetUpperName();
@@ -444,12 +450,15 @@ void adjustRangeName(formula::FormulaToken* pToken, ScDocument& rNewDoc, const S
aRangeName = pOldRangeData->GetUpperName();
}
SAL_WARN_IF( !bSameDoc && nOldSheet >= 0 && nOldSheet != aOldPos.Tab(),
"sc.core", "adjustRangeName - sheet-local name was on other sheet in other document");
/* TODO: can we do something about that? e.g. loop over sheets? */
//find corresponding range name in new document
//first search for local range name then global range names
SCTAB aNewTab = aNewPos.Tab();
ScRangeName* pRangeName = rNewDoc.GetRangeName(aNewTab);
SCTAB nNewSheet = aNewPos.Tab();
ScRangeName* pRangeName = rNewDoc.GetRangeName(nNewSheet);
ScRangeData* pRangeData = nullptr;
bool bNewGlobal = false;
//search local range names
if (pRangeName)
{
@@ -458,7 +467,7 @@ void adjustRangeName(formula::FormulaToken* pToken, ScDocument& rNewDoc, const S
//search global range names
if (!pRangeData)
{
bNewGlobal = true;
nNewSheet = -1;
pRangeName = rNewDoc.GetRangeName();
if (pRangeName)
pRangeData = pRangeName->findByUpperName(aRangeName);
@@ -466,21 +475,24 @@ void adjustRangeName(formula::FormulaToken* pToken, ScDocument& rNewDoc, const S
//if no range name was found copy it
if (!pRangeData)
{
bNewGlobal = bOldGlobal;
if (nOldSheet < 0)
nNewSheet = -1;
else
nNewSheet = aNewPos.Tab();
pRangeData = new ScRangeData(*pOldRangeData, &rNewDoc);
pRangeData->SetIndex(0); // needed for insert to assign a new index
ScTokenArray* pRangeNameToken = pRangeData->GetCode();
if (rNewDoc.GetPool() != const_cast<ScDocument*>(pOldDoc)->GetPool())
if (!bSameDoc)
{
pRangeNameToken->ReadjustAbsolute3DReferences(pOldDoc, &rNewDoc, pRangeData->GetPos(), true);
pRangeNameToken->AdjustAbsoluteRefs(pOldDoc, aOldPos, aNewPos, false, true);
}
bool bInserted;
if (bNewGlobal)
if (nNewSheet < 0)
bInserted = rNewDoc.GetRangeName()->insert(pRangeData);
else
bInserted = rNewDoc.GetRangeName(aNewTab)->insert(pRangeData);
bInserted = rNewDoc.GetRangeName(nNewSheet)->insert(pRangeData);
if (!bInserted)
{
//if this happened we have a real problem
@@ -492,7 +504,7 @@ void adjustRangeName(formula::FormulaToken* pToken, ScDocument& rNewDoc, const S
}
sal_Int32 nIndex = pRangeData->GetIndex();
pToken->SetIndex(nIndex);
pToken->SetGlobal(bNewGlobal);
pToken->SetSheet(nNewSheet);
}
void adjustDBRange(formula::FormulaToken* pToken, ScDocument& rNewDoc, const ScDocument* pOldDoc)
@@ -3603,7 +3615,7 @@ void ScFormulaCell::UpdateTranspose( const ScRange& rSource, const ScAddress& rD
{
if( t->GetOpCode() == ocName )
{
ScRangeData* pName = pDocument->GetRangeName()->findByIndex( t->GetIndex() );
const ScRangeData* pName = pDocument->FindRangeNameByIndexAndSheet( t->GetIndex(), t->GetSheet());
if (pName)
{
if (pName->IsModified())
@@ -3657,7 +3669,7 @@ void ScFormulaCell::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY
{
if( t->GetOpCode() == ocName )
{
ScRangeData* pName = pDocument->GetRangeName()->findByIndex( t->GetIndex() );
const ScRangeData* pName = pDocument->FindRangeNameByIndexAndSheet( t->GetIndex(), t->GetSheet());
if (pName)
{
if (pName->IsModified())
@@ -3694,6 +3706,12 @@ static void lcl_FindRangeNamesInUse(std::set<sal_uInt16>& rIndexes, ScTokenArray
{
if (p->GetOpCode() == ocName)
{
/* TODO: this should collect also sheet-local names, currently it
* collects only global names. But looking even for indexes of
* local names.. this always was wrong. Probably use
* UpdatedRangeNames instead of the set, but doing so would also
* need more work in copying things over clipboard and such. */
sal_uInt16 nTokenIndex = p->GetIndex();
rIndexes.insert( nTokenIndex );
diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
index 2535990a..278ae4e 100644
--- a/sc/source/core/data/validat.cxx
+++ b/sc/source/core/data/validat.cxx
@@ -694,7 +694,7 @@ bool ScValidationData::GetSelectionFromFormula(
}
else if (eOpCode == ocName)
{
ScRangeData* pName = pDocument->GetRangeName()->findByIndex( t->GetIndex() );
const ScRangeData* pName = pDocument->FindRangeNameByIndexAndSheet( t->GetIndex(), t->GetSheet());
if (pName && pName->IsReference(aRange))
{
bRef = true;
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
index ef2e492..c016102 100644
--- a/sc/source/core/tool/address.cxx
+++ b/sc/source/core/tool/address.cxx
@@ -704,8 +704,12 @@ static ScRefFlags lcl_ScRange_Parse_XL_R1C1( ScRange& r,
ScDocument* pDoc,
const ScAddress::Details& rDetails,
bool bOnlyAcceptSingle,
ScAddress::ExternalInfo* pExtInfo )
ScAddress::ExternalInfo* pExtInfo,
sal_Int32* pSheetEndPos )
{
const sal_Unicode* const pStart = p;
if (pSheetEndPos)
*pSheetEndPos = 0;
const sal_Unicode* pTmp = nullptr;
OUString aExternDocName, aStartTabName, aEndTabName;
ScRefFlags nFlags = ScRefFlags::VALID | ScRefFlags::TAB_VALID;
@@ -715,6 +719,13 @@ static ScRefFlags lcl_ScRange_Parse_XL_R1C1( ScRange& r,
p = r.Parse_XL_Header( p, pDoc, aExternDocName, aStartTabName,
aEndTabName, nFlags, bOnlyAcceptSingle );
ScRefFlags nBailOutFlags = ScRefFlags::ZERO;
if (pSheetEndPos && pStart < p && (nFlags & ScRefFlags::TAB_VALID) && (nFlags & ScRefFlags::TAB_3D))
{
*pSheetEndPos = p - pStart;
nBailOutFlags = ScRefFlags::TAB_VALID | ScRefFlags::TAB_3D;
}
if (!aExternDocName.isEmpty())
lcl_ScRange_External_TabSpan( r, nFlags, pExtInfo, aExternDocName,
aStartTabName, aEndTabName, pDoc);
@@ -725,7 +736,7 @@ static ScRefFlags lcl_ScRange_Parse_XL_R1C1( ScRange& r,
if( *p == 'R' || *p == 'r' )
{
if( nullptr == (p = lcl_r1c1_get_row( p, rDetails, &r.aStart, &nFlags )) )
return ScRefFlags::ZERO;
return nBailOutFlags;
if( *p != 'C' && *p != 'c' ) // full row R#
{
@@ -800,7 +811,7 @@ static ScRefFlags lcl_ScRange_Parse_XL_R1C1( ScRange& r,
else if( *p == 'C' || *p == 'c' ) // full col C#
{
if( nullptr == (p = lcl_r1c1_get_col( p, rDetails, &r.aStart, &nFlags )))
return ScRefFlags::ZERO;
return nBailOutFlags;
if( p[0] != ':' || (p[1] != 'C' && p[1] != 'c') ||
nullptr == (pTmp = lcl_r1c1_get_col( p+1, rDetails, &r.aEnd, &nFlags2 )))
@@ -831,7 +842,7 @@ static ScRefFlags lcl_ScRange_Parse_XL_R1C1( ScRange& r,
return bOnlyAcceptSingle ? ScRefFlags::ZERO : nFlags;
}
return ScRefFlags::ZERO;
return nBailOutFlags;
}
static inline const sal_Unicode* lcl_a1_get_col( const sal_Unicode* p,
@@ -897,8 +908,12 @@ static ScRefFlags lcl_ScRange_Parse_XL_A1( ScRange& r,
ScDocument* pDoc,
bool bOnlyAcceptSingle,
ScAddress::ExternalInfo* pExtInfo,
const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks )
const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks,
sal_Int32* pSheetEndPos )
{
const sal_Unicode* const pStart = p;
if (pSheetEndPos)
*pSheetEndPos = 0;
const sal_Unicode* tmp1, *tmp2;
OUString aExternDocName, aStartTabName, aEndTabName; // for external link table
ScRefFlags nFlags = ScRefFlags::VALID | ScRefFlags::TAB_VALID, nFlags2 = ScRefFlags::TAB_VALID;
@@ -906,29 +921,36 @@ static ScRefFlags lcl_ScRange_Parse_XL_A1( ScRange& r,
p = r.Parse_XL_Header( p, pDoc, aExternDocName, aStartTabName,
aEndTabName, nFlags, bOnlyAcceptSingle, pExternalLinks );
ScRefFlags nBailOutFlags = ScRefFlags::ZERO;
if (pSheetEndPos && pStart < p && (nFlags & ScRefFlags::TAB_VALID) && (nFlags & ScRefFlags::TAB_3D))
{
*pSheetEndPos = p - pStart;
nBailOutFlags = ScRefFlags::TAB_VALID | ScRefFlags::TAB_3D;
}
if (!aExternDocName.isEmpty())
lcl_ScRange_External_TabSpan( r, nFlags, pExtInfo, aExternDocName,
aStartTabName, aEndTabName, pDoc);
if( nullptr == p )
return ScRefFlags::ZERO;
return nBailOutFlags;
tmp1 = lcl_a1_get_col( p, &r.aStart, &nFlags );
if( tmp1 == nullptr ) // Is it a row only reference 3:5
{
if( bOnlyAcceptSingle ) // by definition full row refs are ranges
return ScRefFlags::ZERO;
return nBailOutFlags;
tmp1 = lcl_a1_get_row( p, &r.aStart, &nFlags );
tmp1 = lcl_eatWhiteSpace( tmp1 );
if( !tmp1 || *tmp1++ != ':' ) // Even a singleton requires ':' (eg 2:2)
return ScRefFlags::ZERO;
return nBailOutFlags;
tmp1 = lcl_eatWhiteSpace( tmp1 );
tmp2 = lcl_a1_get_row( tmp1, &r.aEnd, &nFlags2 );
if( !tmp2 || *tmp2 != 0 ) // Must have fully parsed a singleton.
return ScRefFlags::ZERO;
return nBailOutFlags;
r.aStart.SetCol( 0 ); r.aEnd.SetCol( MAXCOL );
nFlags |=
@@ -942,16 +964,16 @@ static ScRefFlags lcl_ScRange_Parse_XL_A1( ScRange& r,
if( tmp2 == nullptr ) // check for col only reference F:H
{
if( bOnlyAcceptSingle ) // by definition full col refs are ranges
return ScRefFlags::ZERO;
return nBailOutFlags;
tmp1 = lcl_eatWhiteSpace( tmp1 );
if( *tmp1++ != ':' ) // Even a singleton requires ':' (eg F:F)
return ScRefFlags::ZERO;
return nBailOutFlags;
tmp1 = lcl_eatWhiteSpace( tmp1 );
tmp2 = lcl_a1_get_col( tmp1, &r.aEnd, &nFlags2 );
if( !tmp2 || *tmp2 != 0 ) // Must have fully parsed a singleton.
return ScRefFlags::ZERO;
return nBailOutFlags;
r.aStart.SetRow( 0 ); r.aEnd.SetRow( MAXROW );
nFlags |=
@@ -1047,8 +1069,13 @@ static ScRefFlags lcl_ScRange_Parse_XL_A1( ScRange& r,
*/
static ScRefFlags lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAddr,
ScRefFlags& rRawRes,
ScAddress::ExternalInfo* pExtInfo = nullptr, ScRange* pRange = nullptr )
ScAddress::ExternalInfo* pExtInfo,
ScRange* pRange,
sal_Int32* pSheetEndPos )
{
const sal_Unicode* const pStart = p;
if (pSheetEndPos)
*pSheetEndPos = 0;
ScRefFlags nRes = ScRefFlags::ZERO;
rRawRes = ScRefFlags::ZERO;
OUString aDocName; // the pure Document Name
@@ -1061,7 +1088,6 @@ static ScRefFlags lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDo
// document name is always quoted and has a trailing #.
if (*p == '\'')
{
const sal_Unicode* pStart = p;
OUString aTmp;
p = parseQuotedName(p, aTmp);
aDocName = aTmp;
@@ -1081,7 +1107,8 @@ static ScRefFlags lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDo
SCCOL nCol = 0;
SCROW nRow = 0;
SCTAB nTab = 0;
ScRefFlags nBits = ScRefFlags::TAB_VALID;
ScRefFlags nBailOutFlags = ScRefFlags::ZERO;
ScRefFlags nBits = ScRefFlags::TAB_VALID;
const sal_Unicode* q;
if ( ScGlobal::FindUnquoted( p, '.') )
{
@@ -1121,6 +1148,12 @@ static ScRefFlags lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDo
if( *p++ != '.' )
nBits = ScRefFlags::ZERO;
if (pSheetEndPos && (nBits & ScRefFlags::TAB_VALID))
{
*pSheetEndPos = p - pStart;
nBailOutFlags = ScRefFlags::TAB_VALID | ScRefFlags::TAB_3D;
}
if (!bExtDoc && (!pDoc || !pDoc->GetTable( aTab, nTab )))
{
// Specified table name is not found in this document. Assume this is an external document.
@@ -1305,14 +1338,15 @@ static ScRefFlags lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDo
nRes |= ScRefFlags::VALID;
}
else
nRes = ScRefFlags::ZERO;
nRes = nBailOutFlags;
return nRes;
}
static ScRefFlags lcl_ScAddress_Parse ( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAddr,
const ScAddress::Details& rDetails,
ScAddress::ExternalInfo* pExtInfo = nullptr,
const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks = nullptr )
const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
sal_Int32* pSheetEndPos = nullptr )
{
if( !*p )
return ScRefFlags::ZERO;
@@ -1324,15 +1358,16 @@ static ScRefFlags lcl_ScAddress_Parse ( const sal_Unicode* p, ScDocument* pDoc,
{
ScRange rRange = rAddr;
ScRefFlags nFlags = lcl_ScRange_Parse_XL_A1(
rRange, p, pDoc, true, pExtInfo,
(rDetails.eConv == formula::FormulaGrammar::CONV_XL_OOX ? pExternalLinks : nullptr) );
rRange, p, pDoc, true, pExtInfo,
(rDetails.eConv == formula::FormulaGrammar::CONV_XL_OOX ? pExternalLinks : nullptr),
pSheetEndPos);
rAddr = rRange.aStart;
return nFlags;
}
case formula::FormulaGrammar::CONV_XL_R1C1:
{
ScRange rRange = rAddr;
ScRefFlags nFlags = lcl_ScRange_Parse_XL_R1C1( rRange, p, pDoc, rDetails, true, pExtInfo );
ScRefFlags nFlags = lcl_ScRange_Parse_XL_R1C1( rRange, p, pDoc, rDetails, true, pExtInfo, pSheetEndPos);
rAddr = rRange.aStart;
return nFlags;
}
@@ -1340,7 +1375,7 @@ static ScRefFlags lcl_ScAddress_Parse ( const sal_Unicode* p, ScDocument* pDoc,
case formula::FormulaGrammar::CONV_OOO:
{
ScRefFlags nRawRes = ScRefFlags::ZERO;
return lcl_ScAddress_Parse_OOo( p, pDoc, rAddr, nRawRes, pExtInfo );
return lcl_ScAddress_Parse_OOo( p, pDoc, rAddr, nRawRes, pExtInfo, nullptr, pSheetEndPos);
}
}
}
@@ -1396,9 +1431,10 @@ bool ConvertDoubleRef( ScDocument* pDoc, const OUString& rRefString, SCTAB nDefT
ScRefFlags ScAddress::Parse( const OUString& r, ScDocument* pDoc,
const Details& rDetails,
ExternalInfo* pExtInfo,
const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks )
const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks,
sal_Int32* pSheetEndPos )
{
return lcl_ScAddress_Parse( r.getStr(), pDoc, *this, rDetails, pExtInfo, pExternalLinks );
return lcl_ScAddress_Parse( r.getStr(), pDoc, *this, rDetails, pExtInfo, pExternalLinks, pSheetEndPos );
}
bool ScRange::Intersects( const ScRange& rRange ) const
@@ -1476,13 +1512,14 @@ static ScRefFlags lcl_ScRange_Parse_OOo( ScRange& rRange,
aTmp[nPos] = 0;
const sal_Unicode* p = aTmp.getStr();
ScRefFlags nRawRes1 = ScRefFlags::ZERO;
if (((nRes1 = lcl_ScAddress_Parse_OOo( p, pDoc, rRange.aStart, nRawRes1, pExtInfo)) != ScRefFlags::ZERO) ||
nRes1 = lcl_ScAddress_Parse_OOo( p, pDoc, rRange.aStart, nRawRes1, pExtInfo, nullptr, nullptr);
if ((nRes1 != ScRefFlags::ZERO) ||
((nRawRes1 & (ScRefFlags::COL_VALID | ScRefFlags::ROW_VALID)) &&
(nRawRes1 & ScRefFlags::TAB_VALID)))
{
rRange.aEnd = rRange.aStart; // sheet must be initialized identical to first sheet
ScRefFlags nRawRes2 = ScRefFlags::ZERO;
nRes2 = lcl_ScAddress_Parse_OOo( p + nPos+ 1, pDoc, rRange.aEnd, nRawRes2, pExtInfo, &rRange);
nRes2 = lcl_ScAddress_Parse_OOo( p + nPos+ 1, pDoc, rRange.aEnd, nRawRes2, pExtInfo, &rRange, nullptr);
if (!((nRes1 & ScRefFlags::VALID) && (nRes2 & ScRefFlags::VALID)) &&
// If not fully valid addresses, check if both have a valid
// column or row, and both have valid (or omitted) sheet references.
@@ -1596,12 +1633,12 @@ ScRefFlags ScRange::Parse( const OUString& rString, ScDocument* pDoc,
case formula::FormulaGrammar::CONV_XL_OOX:
{
return lcl_ScRange_Parse_XL_A1( *this, rString.getStr(), pDoc, false, pExtInfo,
(rDetails.eConv == formula::FormulaGrammar::CONV_XL_OOX ? pExternalLinks : nullptr) );
(rDetails.eConv == formula::FormulaGrammar::CONV_XL_OOX ? pExternalLinks : nullptr), nullptr );
}
case formula::FormulaGrammar::CONV_XL_R1C1:
{
return lcl_ScRange_Parse_XL_R1C1( *this, rString.getStr(), pDoc, rDetails, false, pExtInfo );
return lcl_ScRange_Parse_XL_R1C1( *this, rString.getStr(), pDoc, rDetails, false, pExtInfo, nullptr );
}
default:
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 2f88dd9..c57f192 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -2892,14 +2892,34 @@ bool ScCompiler::IsDoubleReference( const OUString& rName )
bool ScCompiler::IsSingleReference( const OUString& rName )
{
mnCurrentSheetEndPos = 0;
mnCurrentSheetTab = -1;
ScAddress aAddr( aPos );
const ScAddress::Details aDetails( pConv->meConv, aPos );
ScAddress::ExternalInfo aExtInfo;
ScRefFlags nFlags = aAddr.Parse( rName, pDoc, aDetails, &aExtInfo, &maExternalLinks );
ScRefFlags nFlags = aAddr.Parse( rName, pDoc, aDetails, &aExtInfo, &maExternalLinks, &mnCurrentSheetEndPos);
// Something must be valid in order to recognize Sheet1.blah or blah.a1
// as a (wrong) reference.
if( nFlags & ( ScRefFlags::COL_VALID|ScRefFlags::ROW_VALID|ScRefFlags::TAB_VALID ) )
{
// Valid given tab and invalid col or row may indicate a sheet-local
// named expression, bail out early and don't create a reference token.
if (!(nFlags & ScRefFlags::VALID) && mnCurrentSheetEndPos > 0 &&
(nFlags & ScRefFlags::TAB_VALID) && (nFlags & ScRefFlags::TAB_3D))
{
if (aExtInfo.mbExternal)
{
// External names are handled separately.
mnCurrentSheetEndPos = 0;
mnCurrentSheetTab = -1;
}
else
{
mnCurrentSheetTab = aAddr.Tab();
}
return false;
}
ScSingleRefData aRef;
aRef.InitAddress( aAddr );
aRef.SetColRel( (nFlags & ScRefFlags::COL_ABS) == ScRefFlags::ZERO );
@@ -3093,8 +3113,8 @@ bool ScCompiler::IsNamedRange( const OUString& rUpperName )
// IsNamedRange is called only from NextNewToken, with an upper-case string
// try local names first
bool bGlobal = false;
ScRangeName* pRangeName = pDoc->GetRangeName(aPos.Tab());
sal_Int16 nSheet = aPos.Tab();
ScRangeName* pRangeName = pDoc->GetRangeName(nSheet);
const ScRangeData* pData = nullptr;
if (pRangeName)
pData = pRangeName->findByUpperName(rUpperName);
@@ -3104,16 +3124,32 @@ bool ScCompiler::IsNamedRange( const OUString& rUpperName )
if (pRangeName)
pData = pRangeName->findByUpperName(rUpperName);
if (pData)
bGlobal = true;
nSheet = -1;
}
if (pData)
{
maRawToken.SetName(bGlobal, pData->GetIndex());
maRawToken.SetName( nSheet, pData->GetIndex());
return true;
}
else
return false;
// Sheet-local name with sheet specified.
if (mnCurrentSheetEndPos > 0 && mnCurrentSheetTab >= 0)
{
OUString aName( rUpperName.copy( mnCurrentSheetEndPos));
pRangeName = pDoc->GetRangeName( mnCurrentSheetTab);
if (pRangeName)
{
pData = pRangeName->findByUpperName(aName);
if (pData)
{
maRawToken.SetName( mnCurrentSheetTab, pData->GetIndex());
return true;
}
}
}
return false;
}
bool ScCompiler::IsExternalNamedRange( const OUString& rSymbol, bool& rbInvalidExternalNameRange )
@@ -3161,7 +3197,7 @@ bool ScCompiler::IsDBRange( const OUString& rName )
if (!p)
return false;
maRawToken.SetName(true, p->GetIndex()); // DB range is always global.
maRawToken.SetName( -1, p->GetIndex()); // DB range is always global.
maRawToken.eOp = ocDBArea;
return true;
}
@@ -4387,19 +4423,7 @@ ScTokenArray* ScCompiler::CompileString( const OUString& rFormula, const OUStrin
ScRangeData* ScCompiler::GetRangeData( const FormulaToken& rToken ) const
{
ScRangeData* pRangeData = nullptr;
bool bGlobal = rToken.IsGlobal();
if (bGlobal)
// global named range.
pRangeData = pDoc->GetRangeName()->findByIndex( rToken.GetIndex());
else
{
// sheet local named range.
const ScRangeName* pRN = pDoc->GetRangeName( aPos.Tab());
if (pRN)
pRangeData = pRN->findByIndex( rToken.GetIndex());
}
return pRangeData;
return pDoc->FindRangeNameByIndexAndSheet( rToken.GetIndex(), rToken.GetSheet());
}
bool ScCompiler::HandleRange()
@@ -4759,7 +4783,20 @@ void ScCompiler::CreateStringFromIndex( OUStringBuffer& rBuffer, const FormulaTo
{
const ScRangeData* pData = GetRangeData( *_pTokenP);
if (pData)
{
SCTAB nTab = _pTokenP->GetSheet();
if (nTab >= 0 && nTab != aPos.Tab())
{
// Sheet-local on other sheet.
OUString aName;
if (pDoc->GetName( nTab, aName))
aBuffer.append( aName);
else
aBuffer.append( ScGlobal::GetRscString( STR_NO_NAME_REF));
aBuffer.append( pConv->getSpecialSymbol( ScCompiler::Convention::SHEET_SEPARATOR));
}
aBuffer.append(pData->GetName());
}
}
break;
case ocDBArea:
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 6a3f271..3d82694 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -293,12 +293,12 @@ void ScRawToken::SetErrorConstant( sal_uInt16 nErr )
nError = nErr;
}
void ScRawToken::SetName(bool bGlobal, sal_uInt16 nIndex)
void ScRawToken::SetName(sal_Int16 nSheet, sal_uInt16 nIndex)
{
eOp = ocName;
eType = svIndex;
name.bGlobal = bGlobal;
name.nSheet = nSheet;
name.nIndex = nIndex;
}
@@ -409,7 +409,7 @@ FormulaToken* ScRawToken::CreateToken() const
if (eOp == ocTableRef)
return new ScTableRefToken( table.nIndex, table.eItem);
else
return new FormulaIndexToken( eOp, name.nIndex, name.bGlobal);
return new FormulaIndexToken( eOp, name.nIndex, name.nSheet);
case svExternalSingleRef:
{
OUString aTabName(extref.cTabName);
@@ -933,13 +933,13 @@ void ScTableRefToken::SetIndex( sal_uInt16 n )
mnIndex = n;
}
bool ScTableRefToken::IsGlobal() const
sal_Int16 ScTableRefToken::GetSheet() const
{
// Code asking for this may have to be adapted as it might assume an
// svIndex token would always be ocName or ocDBArea.
SAL_WARN("sc.core","ScTableRefToken::IsGlobal - maybe adapt caller to know about TableRef?");
SAL_WARN("sc.core","ScTableRefToken::GetSheet - maybe adapt caller to know about TableRef?");
// Database range is always global.
return true;
return -1;
}
ScTableRefToken::Item ScTableRefToken::GetItem() const
@@ -1212,7 +1212,16 @@ bool ScTokenArray::AddFormulaToken(
sheet::NameToken aTokenData;
rToken.Data >>= aTokenData;
if ( eOpCode == ocName )
AddRangeName(aTokenData.Index, aTokenData.Global);
{
/* TODO: new token type with sheet number */
if (aTokenData.Global)
AddRangeName(aTokenData.Index, -1);
else
bError = true;
/* FIXME: resolve the non-global case to the
* current position's sheet as it implicitly was
* before, currently this is broken. */
}
else if (eOpCode == ocDBArea)
AddDBRange(aTokenData.Index);
else if (eOpCode == ocTableRef)
@@ -2059,9 +2068,9 @@ FormulaToken* ScTokenArray::AddMatrix( const ScMatrixRef& p )
return Add( new ScMatrixToken( p ) );
}
FormulaToken* ScTokenArray::AddRangeName( sal_uInt16 n, bool bGlobal )
FormulaToken* ScTokenArray::AddRangeName( sal_uInt16 n, sal_Int16 nSheet )
{
return Add( new FormulaIndexToken( ocName, n, bGlobal));
return Add( new FormulaIndexToken( ocName, n, nSheet));
}
FormulaToken* ScTokenArray::AddDBRange( sal_uInt16 n )
@@ -2826,7 +2835,7 @@ bool expandRangeByEdge( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, co
bool isNameModified( const sc::UpdatedRangeNames& rUpdatedNames, SCTAB nOldTab, const formula::FormulaToken& rToken )
{
SCTAB nTab = -1;
if (!rToken.IsGlobal())
if (rToken.GetSheet() >= 0)
nTab = nOldTab;
// Check if this named expression has been modified.
@@ -3003,8 +3012,17 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon
switch ((*pp)->GetOpCode())
{
case ocName:
if (isNameModified(rCxt.maUpdatedNames, rOldPos.Tab(), **pp))
aRes.mbNameModified = true;
{
SCTAB nOldTab = (*pp)->GetSheet();
if (isNameModified(rCxt.maUpdatedNames, nOldTab, **pp))
aRes.mbNameModified = true;
if (rCxt.mnTabDelta &&
rCxt.maRange.aStart.Tab() <= nOldTab && nOldTab <= rCxt.maRange.aEnd.Tab())
{
aRes.mbNameModified = true;
(*pp)->SetSheet( nOldTab + rCxt.mnTabDelta);
}
}
break;
case ocDBArea:
case ocTableRef:
@@ -3099,8 +3117,17 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnMove(
switch ((*pp)->GetOpCode())
{
case ocName:
if (isNameModified(rCxt.maUpdatedNames, rOldPos.Tab(), **pp))
aRes.mbNameModified = true;
{
SCTAB nOldTab = (*pp)->GetSheet();
if (isNameModified(rCxt.maUpdatedNames, nOldTab, **pp))
aRes.mbNameModified = true;
if (rCxt.mnTabDelta &&
rCxt.maRange.aStart.Tab() <= nOldTab && nOldTab <= rCxt.maRange.aEnd.Tab())
{
aRes.mbNameModified = true;
(*pp)->SetSheet( nOldTab + rCxt.mnTabDelta);
}
}
break;
case ocDBArea:
case ocTableRef:
@@ -3171,8 +3198,17 @@ sc::RefUpdateResult ScTokenArray::MoveReference( const ScAddress& rPos, const sc
switch ((*p)->GetOpCode())
{
case ocName:
if (isNameModified(rCxt.maUpdatedNames, aOldRange.aStart.Tab(), **p))
aRes.mbNameModified = true;
{
SCTAB nOldTab = (*p)->GetSheet();
if (isNameModified(rCxt.maUpdatedNames, nOldTab, **p))
aRes.mbNameModified = true;
if (rCxt.mnTabDelta &&
rCxt.maRange.aStart.Tab() <= nOldTab && nOldTab <= rCxt.maRange.aEnd.Tab())
{
aRes.mbNameModified = true;
(*p)->SetSheet( nOldTab + rCxt.mnTabDelta);
}
}
break;
case ocDBArea:
case ocTableRef:
@@ -3868,8 +3904,20 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnDeletedTab( sc::RefUpdateDele
switch ((*pp)->GetOpCode())
{
case ocName:
if (isNameModified(rCxt.maUpdatedNames, rOldPos.Tab(), **pp))
aRes.mbNameModified = true;
{
SCTAB nOldTab = (*pp)->GetSheet();
if (isNameModified(rCxt.maUpdatedNames, nOldTab, **pp))
aRes.mbNameModified = true;
if (rCxt.mnDeletePos <= nOldTab)
{
aRes.mbNameModified = true;
if (rCxt.mnDeletePos + rCxt.mnSheets < nOldTab)
(*pp)->SetSheet( nOldTab - rCxt.mnSheets);
else
// Would point to a deleted sheet. Invalidate.
(*pp)->SetSheet( SCTAB_MAX);
}
}
break;
case ocDBArea:
case ocTableRef:
@@ -3932,8 +3980,16 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnInsertedTab( sc::RefUpdateIns
switch ((*pp)->GetOpCode())
{
case ocName:
if (isNameModified(rCxt.maUpdatedNames, rOldPos.Tab(), **pp))
aRes.mbNameModified = true;
{
SCTAB nOldTab = (*pp)->GetSheet();
if (isNameModified(rCxt.maUpdatedNames, nOldTab, **pp))
aRes.mbNameModified = true;
if (rCxt.mnInsertPos <= nOldTab)
{
aRes.mbNameModified = true;
(*pp)->SetSheet( nOldTab + rCxt.mnSheets);
}
}
break;
case ocDBArea:
case ocTableRef:
@@ -4017,8 +4073,17 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnMovedTab( sc::RefUpdateMoveTa
switch ((*pp)->GetOpCode())
{
case ocName:
if (isNameModified(rCxt.maUpdatedNames, rOldPos.Tab(), **pp))
aRes.mbNameModified = true;
{
SCTAB nOldTab = (*pp)->GetSheet();
if (isNameModified(rCxt.maUpdatedNames, nOldTab, **pp))
aRes.mbNameModified = true;
SCTAB nNewTab = rCxt.getNewTab( nOldTab);
if (nNewTab != nOldTab)
{
aRes.mbNameModified = true;
(*pp)->SetSheet( nNewTab);
}
}
break;
case ocDBArea:
case ocTableRef:
@@ -4614,7 +4679,8 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons
{
case ocName:
{
if (rToken.IsGlobal())
SCTAB nTab = rToken.GetSheet();
if (nTab < 0)
{
// global named range
NameType::const_iterator it = rCxt.maGlobalRangeNames.find(nIndex);
@@ -4629,7 +4695,20 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons
else
{
// sheet-local named range
sc::TokenStringContext::TabIndexMapType::const_iterator itTab = rCxt.maSheetRangeNames.find(rPos.Tab());
if (nTab != rPos.Tab())
{
// On other sheet.
OUString aName;
if (static_cast<size_t>(nTab) < rCxt.maTabNames.size())
aName = rCxt.maTabNames[nTab];
if (!aName.isEmpty())
rBuf.append( aName);
else
rBuf.append( ScGlobal::GetRscString( STR_NO_NAME_REF));
rBuf.append( rCxt.mpRefConv->getSpecialSymbol( ScCompiler::Convention::SHEET_SEPARATOR));
}
sc::TokenStringContext::TabIndexMapType::const_iterator itTab = rCxt.maSheetRangeNames.find(nTab);
if (itTab == rCxt.maSheetRangeNames.end())
{
rBuf.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index 2be528a..33ec52f 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -544,7 +544,7 @@ ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, s
if(pName && !pName->GetScRangeData())
aStack << aPool.Store( ocMacro, pName->GetXclName() );
else
aStack << aPool.StoreName(nUINT16, true);
aStack << aPool.StoreName(nUINT16, -1);
}
break;
case 0x44:
@@ -733,7 +733,7 @@ ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, s
aPool >> aStack;
}
else
aStack << aPool.StoreName( nUINT16, true );
aStack << aPool.StoreName( nUINT16, -1 );
aIn.Ignore( 12 );
break;
}
diff --git a/sc/source/filter/excel/excform8.cxx b/sc/source/filter/excel/excform8.cxx
index c13876c..f0668cb 100644
--- a/sc/source/filter/excel/excform8.cxx
+++ b/sc/source/filter/excel/excform8.cxx
@@ -493,7 +493,7 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
// user-defined macro name.
aStack << aPool.Store(ocMacro, pName->GetXclName());
else
aStack << aPool.StoreName(nUINT16, pName->IsGlobal());
aStack << aPool.StoreName(nUINT16, pName->IsGlobal() ? -1 : pName->GetScTab());
}
break;
}
@@ -680,7 +680,7 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
if (pName)
{
if (pName->GetScRangeData())
aStack << aPool.StoreName( nNameIdx, pName->IsGlobal());
aStack << aPool.StoreName( nNameIdx, pName->IsGlobal() ? -1 : pName->GetScTab());
else
aStack << aPool.Store(ocMacro, pName->GetXclName());
}
diff --git a/sc/source/filter/excel/tokstack.cxx b/sc/source/filter/excel/tokstack.cxx
index 31e8995..9323f93 100644
--- a/sc/source/filter/excel/tokstack.cxx
+++ b/sc/source/filter/excel/tokstack.cxx
@@ -425,7 +425,7 @@ bool TokenPool::GetElement( const sal_uInt16 nId )
if (n < maRangeNames.size())
{
const RangeName& r = maRangeNames[n];
pScToken->AddRangeName(r.mnIndex, r.mbGlobal);
pScToken->AddRangeName(r.mnIndex, r.mnSheet);
}
}
break;
@@ -623,7 +623,7 @@ const TokenId TokenPool::Store( const double& rDouble )
const TokenId TokenPool::Store( const sal_uInt16 nIndex )
{
return StoreName(nIndex, true);
return StoreName(nIndex, -1);
}
const TokenId TokenPool::Store( const OUString& rString )
@@ -790,7 +790,7 @@ const TokenId TokenPool::StoreMatrix()
return static_cast<const TokenId>(nElementAkt);
}
const TokenId TokenPool::StoreName( sal_uInt16 nIndex, bool bGlobal )
const TokenId TokenPool::StoreName( sal_uInt16 nIndex, sal_Int16 nSheet )
{
if ( nElementAkt >= nElement )
if (!GrowElement())
@@ -802,7 +802,7 @@ const TokenId TokenPool::StoreName( sal_uInt16 nIndex, bool bGlobal )
maRangeNames.push_back(RangeName());
RangeName& r = maRangeNames.back();
r.mnIndex = nIndex;
r.mbGlobal = bGlobal;
r.mnSheet = nSheet;
++nElementAkt;
diff --git a/sc/source/filter/excel/xeformula.cxx b/sc/source/filter/excel/xeformula.cxx
index 29ac7a0..9742cb6a 100644
--- a/sc/source/filter/excel/xeformula.cxx
+++ b/sc/source/filter/excel/xeformula.cxx
@@ -2079,10 +2079,8 @@ void XclExpFmlaCompImpl::ProcessExternalRangeRef( const XclExpScToken& rTokData
void XclExpFmlaCompImpl::ProcessDefinedName( const XclExpScToken& rTokData )
{
SCTAB nTab = SCTAB_GLOBAL;
bool bGlobal = rTokData.mpScToken->IsGlobal();
if (!bGlobal)
nTab = GetCurrScTab();
sal_Int16 nSheet = rTokData.mpScToken->GetSheet();
SCTAB nTab = (nSheet < 0 ? SCTAB_GLOBAL : nSheet);
XclExpNameManager& rNameMgr = GetNameManager();
sal_uInt16 nNameIdx = rNameMgr.InsertName(nTab, rTokData.mpScToken->GetIndex());
diff --git a/sc/source/filter/inc/tokstack.hxx b/sc/source/filter/inc/tokstack.hxx
index 9ceb2a4..71ef978 100644
--- a/sc/source/filter/inc/tokstack.hxx
+++ b/sc/source/filter/inc/tokstack.hxx
@@ -126,7 +126,7 @@ private:
struct RangeName
{
sal_uInt16 mnIndex;
bool mbGlobal;
sal_Int16 mnSheet;
};
::std::vector<RangeName> maRangeNames;
@@ -205,7 +205,7 @@ public:
// 4 externals (e.g. AddIns, Macros...)
const TokenId StoreNlf( const ScSingleRefData& rTr );
const TokenId StoreMatrix();
const TokenId StoreName( sal_uInt16 nIndex, bool bGlobal );
const TokenId StoreName( sal_uInt16 nIndex, sal_Int16 nSheet );
const TokenId StoreExtName( sal_uInt16 nFileId, const OUString& rName );
const TokenId StoreExtRef( sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef );
const TokenId StoreExtRef( sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef );
diff --git a/sc/source/ui/unoobj/tokenuno.cxx b/sc/source/ui/unoobj/tokenuno.cxx
index 6e769d0..edea996 100644
--- a/sc/source/ui/unoobj/tokenuno.cxx
+++ b/sc/source/ui/unoobj/tokenuno.cxx
@@ -424,7 +424,8 @@ bool ScTokenConversion::ConvertToTokenSequence( const ScDocument& rDoc,
{
sheet::NameToken aNameToken;
aNameToken.Index = static_cast<sal_Int32>( rToken.GetIndex() );
aNameToken.Global = rToken.IsGlobal();
/* FIXME: we need a new token with sheet number */
aNameToken.Global = (rToken.GetSheet() < 0);
rAPI.Data <<= aNameToken;
}
break;