[Libreoffice-commits] core.git: formula/source include/formula sc/inc sc/source
Eike Rathke
erack at redhat.com
Tue Jun 23 04:20:07 PDT 2015
formula/source/core/api/token.cxx | 6 +++
include/formula/tokenarray.hxx | 4 ++
sc/inc/compiler.hxx | 2 -
sc/inc/tokenarray.hxx | 4 --
sc/source/core/tool/compiler.cxx | 58 +++++++++++++++++++++++++++++---------
sc/source/core/tool/rangenam.cxx | 9 +++++
sc/source/core/tool/token.cxx | 19 +++++-------
7 files changed, 72 insertions(+), 30 deletions(-)
New commits:
commit 80aafaf79306ea82cd24f10f200908addccaf34f
Author: Eike Rathke <erack at redhat.com>
Date: Tue Jun 23 13:02:01 2015 +0200
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
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index e098a49..ac95b8d 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -706,7 +706,8 @@ FormulaTokenArray::FormulaTokenArray() :
nIndex(0),
nError(0),
nMode(ScRecalcMode::NORMAL),
- bHyperLink(false)
+ bHyperLink(false),
+ mbFromRangeName(false)
{
}
@@ -728,6 +729,7 @@ void FormulaTokenArray::Assign( const FormulaTokenArray& r )
nError = r.nError;
nMode = r.nMode;
bHyperLink = r.bHyperLink;
+ mbFromRangeName = r.mbFromRangeName;
pCode = NULL;
pRPN = NULL;
FormulaToken** pp;
@@ -780,6 +782,7 @@ FormulaTokenArray* FormulaTokenArray::Clone() const
p->nMode = nMode;
p->nError = nError;
p->bHyperLink = bHyperLink;
+ p->mbFromRangeName = mbFromRangeName;
FormulaToken** pp;
if( nLen )
{
@@ -837,6 +840,7 @@ void FormulaTokenArray::Clear()
pCode = NULL; pRPN = NULL;
nError = nLen = nIndex = nRPN = 0;
bHyperLink = false;
+ mbFromRangeName = false;
ClearRecalcMode();
}
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index 1050047..58bb092 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -115,6 +115,7 @@ protected:
sal_uInt16 nError; // Error code
ScRecalcMode nMode; // Flags to indicate when to recalc this code
bool bHyperLink; // If HYPERLINK() occurs in the formula.
+ bool mbFromRangeName; // If this array originates from a named expression
protected:
void Assign( const FormulaTokenArray& );
@@ -164,6 +165,9 @@ public:
virtual ~FormulaTokenArray();
FormulaTokenArray* Clone() const; /// True copy!
+ void SetFromRangeName( bool b ) { mbFromRangeName = b; }
+ bool IsFromRangeName() const { return mbFromRangeName; }
+
void Clear();
void DelRPN();
FormulaToken* First() { nIndex = 0; return Next(); }
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index 8c6b373..2dfa2f7 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 b36936a..0d3fa02 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 30bd1e2..125abb4 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 616ec8f..4235ef7 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 914787d..c2a9f5b 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();
More information about the Libreoffice-commits
mailing list