diff options
author | Eike Rathke <erack@redhat.com> | 2015-06-23 13:02:01 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2015-06-23 13:19:25 +0200 |
commit | 80aafaf79306ea82cd24f10f200908addccaf34f (patch) | |
tree | a33ce059c74aac70560022f3dfc232e3889ef4de /sc | |
parent | 42713c52c6e145362e0d1409d2db1bb1f048b1c3 (diff) |
in OOXML save references of named expressions with col,row=0,0 base position
Saving relative references of named expressions to OOXML never worked,
upon reload they pointed to a different position offset by the value of
the original base position. This at least saves positive relative
references correctly, while generating #REF! for negative offsets which
is slightly better than having them point to a wrong location and
silently calculate different values..
Also, this is a prerequisite for TableRef ThisRow references in named
expressions to be saved correctly in A1 notation, which results in a
relative row 0 value.
Change-Id: I3734f910794ceab4b9224b214ad11c64d1d18e67
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/compiler.hxx | 2 | ||||
-rw-r--r-- | sc/inc/tokenarray.hxx | 4 | ||||
-rw-r--r-- | sc/source/core/tool/compiler.cxx | 58 | ||||
-rw-r--r-- | sc/source/core/tool/rangenam.cxx | 9 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 19 |
5 files changed, 63 insertions, 29 deletions
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index 8c6b3732e48d..2dfa2f7247b1 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -218,7 +218,7 @@ public: formula::FormulaGrammar::Grammar eGram, const ScAddress& rPos, const OUString& rErrRef, const std::vector<OUString>& rTabNames, - const ScComplexRefData& rRef, bool bSingleRef ) const = 0; + const ScComplexRefData& rRef, bool bSingleRef, bool bFromRangeName ) const = 0; virtual ::com::sun::star::i18n::ParseResult parseAnyToken( const OUString& rFormula, diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx index b36936a332e7..0d3fa0245f50 100644 --- a/sc/inc/tokenarray.hxx +++ b/sc/inc/tokenarray.hxx @@ -52,7 +52,6 @@ class SC_DLLPUBLIC ScTokenArray : public formula::FormulaTokenArray size_t mnHashValue; ScFormulaVectorState meVectorState; - bool mbFromRangeName; public: ScTokenArray(); @@ -70,9 +69,6 @@ public: ScFormulaVectorState GetVectorState() const { return meVectorState;} - void SetFromRangeName( bool b ) { mbFromRangeName = b; } - bool IsFromRangeName() const { return mbFromRangeName; } - /** * If the array contains at least one relative row reference or named * expression, it's variant. Otherwise invariant. diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index 30bd1e2bee14..125abb417753 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -800,12 +800,13 @@ struct ConventionOOO_A1 : public Convention_A1 MakeRowStr(rBuffer, rAbsRef.Row()); } - void makeRefStr( OUStringBuffer& rBuffer, + virtual void makeRefStr( OUStringBuffer& rBuffer, formula::FormulaGrammar::Grammar /*eGram*/, const ScAddress& rPos, const OUString& rErrRef, const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, - bool bSingleRef ) const SAL_OVERRIDE + bool bSingleRef, + bool /*bFromRangeName*/ ) const SAL_OVERRIDE { ScComplexRefData aRef( rRef ); // In case absolute/relative positions weren't separately available: @@ -952,12 +953,14 @@ struct ConventionOOO_A1 : public Convention_A1 struct ConventionOOO_A1_ODF : public ConventionOOO_A1 { ConventionOOO_A1_ODF() : ConventionOOO_A1 (FormulaGrammar::CONV_ODF) { } - void makeRefStr( OUStringBuffer& rBuffer, + + virtual void makeRefStr( OUStringBuffer& rBuffer, formula::FormulaGrammar::Grammar eGram, const ScAddress& rPos, const OUString& rErrRef, const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, - bool bSingleRef ) const SAL_OVERRIDE + bool bSingleRef, + bool /*bFromRangeName*/ ) const SAL_OVERRIDE { rBuffer.append('['); ScComplexRefData aRef( rRef ); @@ -1197,12 +1200,13 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL MakeRowStr(rBuf, rAbs.Row()); } - void makeRefStr( OUStringBuffer& rBuf, + virtual void makeRefStr( OUStringBuffer& rBuf, formula::FormulaGrammar::Grammar /*eGram*/, const ScAddress& rPos, const OUString& /*rErrRef*/, const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, - bool bSingleRef ) const SAL_OVERRIDE + bool bSingleRef, + bool /*bFromRangeName*/ ) const SAL_OVERRIDE { ScComplexRefData aRef( rRef ); @@ -1338,6 +1342,32 @@ struct ConventionXL_OOX : public ConventionXL_A1 { ConventionXL_OOX() : ConventionXL_A1( FormulaGrammar::CONV_XL_OOX ) { } + virtual void makeRefStr( OUStringBuffer& rBuf, + formula::FormulaGrammar::Grammar eGram, + const ScAddress& rPos, + const OUString& rErrRef, const std::vector<OUString>& rTabNames, + const ScComplexRefData& rRef, + bool bSingleRef, + bool bFromRangeName ) const SAL_OVERRIDE + { + // In OOXML relative references in named expressions are relative to + // column 0 and row 0. Relative sheet references don't exist. + ScAddress aPos( rPos ); + if (bFromRangeName) + { + // XXX NOTE: by decrementing the reference position we may end up + // with resolved references with negative values. There's no proper + // way to solve that or wrap them around without sheet dimensions + // that are stored along. That, or blindly assume fixed dimensions + // here and in import. + /* TODO: maybe do that blind fixed dimensions wrap? */ + aPos.SetCol(0); + aPos.SetRow(0); + } + + ConventionXL_A1::makeRefStr( rBuf, eGram, aPos, rErrRef, rTabNames, rRef, bSingleRef, bFromRangeName); + } + virtual OUString makeExternalNameStr( sal_uInt16 nFileId, const OUString& /*rFile*/, const OUString& rName ) const SAL_OVERRIDE { @@ -1442,12 +1472,14 @@ r1c1_add_row( OUStringBuffer &rBuf, const ScSingleRefData& rRef, const ScAddress struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL { ConventionXL_R1C1() : ScCompiler::Convention( FormulaGrammar::CONV_XL_R1C1 ) { } - void makeRefStr( OUStringBuffer& rBuf, + + virtual void makeRefStr( OUStringBuffer& rBuf, formula::FormulaGrammar::Grammar /*eGram*/, const ScAddress& rPos, const OUString& /*rErrRef*/, const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, - bool bSingleRef ) const SAL_OVERRIDE + bool bSingleRef, + bool /*bFromRangeName*/ ) const SAL_OVERRIDE { ScRange aAbsRef = rRef.toAbs(rPos); ScComplexRefData aRef( rRef ); @@ -4575,7 +4607,7 @@ void ScCompiler::CreateStringFromSingleRef( OUStringBuffer& rBuffer, const Formu { rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF)); pConv->makeRefStr(rBuffer, meGrammar, aPos, aErrRef, - GetSetupTabNames(), aRef, true); + GetSetupTabNames(), aRef, true, (pArr && pArr->IsFromRangeName())); } } else if (pArr && (p = pArr->PeekPrevNoSpaces()) && p->GetOpCode() == ocTableRefOpen) @@ -4587,14 +4619,14 @@ void ScCompiler::CreateStringFromSingleRef( OUStringBuffer& rBuffer, const Formu } else pConv->makeRefStr(rBuffer, meGrammar, aPos, aErrRef, - GetSetupTabNames(), aRef, true); + GetSetupTabNames(), aRef, true, (pArr && pArr->IsFromRangeName())); } void ScCompiler::CreateStringFromDoubleRef( OUStringBuffer& rBuffer, const FormulaToken* _pTokenP ) const { OUString aErrRef = GetCurrentOpCodeMap()->getSymbol(ocErrRef); pConv->makeRefStr(rBuffer, meGrammar, aPos, aErrRef, GetSetupTabNames(), - *_pTokenP->GetDoubleRef(), false); + *_pTokenP->GetDoubleRef(), false, (pArr && pArr->IsFromRangeName())); } void ScCompiler::CreateStringFromIndex( OUStringBuffer& rBuffer, const FormulaToken* _pTokenP ) const @@ -5214,7 +5246,7 @@ bool ScCompiler::HandleTableRef() { aRefData.SetRowRel( true); if (!bCol1RelName) - bCol1RelName = static_cast<ScTokenArray*>(pArr)->IsFromRangeName(); + bCol1RelName = pArr->IsFromRangeName(); } aRefData.SetRelName( bCol1RelName); aRefData.SetFlag3D( true); @@ -5242,7 +5274,7 @@ bool ScCompiler::HandleTableRef() aRefData.Ref1.SetRowRel( true); aRefData.Ref2.SetRowRel( true); if (!bRelName) - bRelName = static_cast<ScTokenArray*>(pArr)->IsFromRangeName(); + bRelName = pArr->IsFromRangeName(); } aRefData.Ref1.SetRelName( bRelName); aRefData.Ref2.SetRelName( bRelName); diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx index 616ec8fd6884..4235ef772f22 100644 --- a/sc/source/core/tool/rangenam.cxx +++ b/sc/source/core/tool/rangenam.cxx @@ -73,6 +73,7 @@ ScRangeData::ScRangeData( ScDocument* pDok, // to ensure same behavior if unnecessary copying is left out. pCode = new ScTokenArray(); + pCode->SetFromRangeName(true); } } @@ -93,6 +94,7 @@ ScRangeData::ScRangeData( ScDocument* pDok, mnMaxRow (-1), mnMaxCol (-1) { + pCode->SetFromRangeName(true); InitCode(); } @@ -115,6 +117,7 @@ ScRangeData::ScRangeData( ScDocument* pDok, aRefData.InitAddress( rTarget ); aRefData.SetFlag3D( true ); pCode->AddSingleReference( aRefData ); + pCode->SetFromRangeName(true); ScCompiler aComp( pDoc, aPos, *pCode ); aComp.SetGrammar(pDoc->GetGrammar()); aComp.CompileTokenArray(); @@ -134,7 +137,9 @@ ScRangeData::ScRangeData(const ScRangeData& rScRangeData, ScDocument* pDocument) bModified (rScRangeData.bModified), mnMaxRow (rScRangeData.mnMaxRow), mnMaxCol (rScRangeData.mnMaxCol) -{} +{ + pCode->SetFromRangeName(true); +} ScRangeData::~ScRangeData() { @@ -158,6 +163,7 @@ void ScRangeData::CompileRangeData( const OUString& rSymbol, bool bSetError ) ScTokenArray* pNewCode = aComp.CompileString( rSymbol ); boost::scoped_ptr<ScTokenArray> pOldCode( pCode); // old pCode will be deleted pCode = pNewCode; + pCode->SetFromRangeName(true); if( !pCode->GetCodeError() ) { pCode->Reset(); @@ -618,6 +624,7 @@ void ScRangeData::SetCode( ScTokenArray& rArr ) { boost::scoped_ptr<ScTokenArray> pOldCode( pCode); // old pCode will be deleted pCode = new ScTokenArray( rArr ); + pCode->SetFromRangeName(true); InitCode(); } diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 914787dbb430..c2a9f5bb171f 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -1743,16 +1743,14 @@ bool ScTokenArray::IsValidReference( ScRange& rRange, const ScAddress& rPos ) co ScTokenArray::ScTokenArray() : FormulaTokenArray(), mnHashValue(0), - meVectorState(FormulaVectorEnabled), - mbFromRangeName(false) + meVectorState(FormulaVectorEnabled) { } ScTokenArray::ScTokenArray( const ScTokenArray& rArr ) : FormulaTokenArray(rArr), mnHashValue(rArr.mnHashValue), - meVectorState(rArr.meVectorState), - mbFromRangeName(rArr.mbFromRangeName) + meVectorState(rArr.meVectorState) { } @@ -1764,7 +1762,6 @@ ScTokenArray& ScTokenArray::operator=( const ScTokenArray& rArr ) { Clear(); Assign( rArr ); - mbFromRangeName = rArr.mbFromRangeName; return *this; } @@ -1772,7 +1769,6 @@ void ScTokenArray::ClearScTokenArray() { Clear(); meVectorState = FormulaVectorEnabled; - mbFromRangeName = false; } ScTokenArray* ScTokenArray::Clone() const @@ -4207,7 +4203,8 @@ void appendString( OUStringBuffer& rBuf, const OUString& rStr ) rBuf.append('"'); } -void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, const FormulaToken& rToken, const ScAddress& rPos ) +void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, const FormulaToken& rToken,\ + const ScAddress& rPos, bool bFromRangeName ) { if (rToken.IsExternalRef()) { @@ -4275,7 +4272,8 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons ScComplexRefData aRef; aRef.Ref1 = rRef; aRef.Ref2 = rRef; - rCxt.mpRefConv->makeRefStr(rBuf, rCxt.meGram, rPos, rCxt.maErrRef, rCxt.maTabNames, aRef, true); + rCxt.mpRefConv->makeRefStr(rBuf, rCxt.meGram, rPos, rCxt.maErrRef, rCxt.maTabNames, aRef, true, + bFromRangeName); } else rBuf.append(rCxt.maErrRef); @@ -4286,7 +4284,8 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons if (rCxt.mpRefConv) { const ScComplexRefData& rRef = *rToken.GetDoubleRef(); - rCxt.mpRefConv->makeRefStr(rBuf, rCxt.meGram, rPos, rCxt.maErrRef, rCxt.maTabNames, rRef, false); + rCxt.mpRefConv->makeRefStr(rBuf, rCxt.meGram, rPos, rCxt.maErrRef, rCxt.maTabNames, rRef, false, + bFromRangeName); } else rBuf.append(rCxt.maErrRef); @@ -4490,7 +4489,7 @@ OUString ScTokenArray::CreateString( sc::TokenStringContext& rCxt, const ScAddre aBuf.append(rCxt.mxOpCodeMap->getSymbol(eOp)); if (bCheckType) - appendTokenByType(rCxt, aBuf, *pToken, rPos); + appendTokenByType(rCxt, aBuf, *pToken, rPos, IsFromRangeName()); } return aBuf.makeStringAndClear(); |