summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWinfried Donkers <winfrieddonkers@libreoffice.org>2014-08-08 17:39:04 +0200
committerEike Rathke <erack@redhat.com>2014-11-27 20:09:26 +0000
commit4feaf96f50fa89eccb4e7a638220099e9a8482f1 (patch)
treeca4e30cdeee2eb1707221fa6ace783a447fd2f80
parentb97600ff196f620145d0b56dbb589238bc6a9cbd (diff)
fdo#81596 export to OOXML that need argument changes
Change-Id: I3a99e416be9f3f04175939e4560f8f7c55497185 Reviewed-on: https://gerrit.libreoffice.org/10831 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com>
-rw-r--r--formula/source/core/api/FormulaCompiler.cxx14
-rw-r--r--formula/source/core/api/token.cxx190
-rw-r--r--include/formula/tokenarray.hxx13
3 files changed, 195 insertions, 22 deletions
diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 6c4f61765114..870d8f2d6e80 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -1737,12 +1737,22 @@ void FormulaCompiler::CreateStringFromTokenArray( OUStringBuffer& rBuffer )
FormulaTokenArray* pSaveArr = pArr;
bool bODFF = FormulaGrammar::isODFF( meGrammar);
+ MissingConventionPOF aConv( bODFF);
if (bODFF || FormulaGrammar::isPODF( meGrammar) )
{
// Scan token array for missing args and re-write if present.
- MissingConvention aConv( bODFF);
if (pArr->NeedsPofRewrite( aConv))
- pArr = pArr->RewriteMissingToPof( aConv);
+ pArr = pArr->RewriteMissing( false, aConv );
+ }
+ else
+ {
+ // fdo#81596
+ if ( FormulaGrammar::isOOXML( meGrammar ) )
+ {
+ // Scan token array for missing args and rewrite if present.
+ if ( pArr->NeedsOOXMLRewrite() )
+ pArr = pArr->RewriteMissing( true, aConv );
+ }
}
// At least one character per token, plus some are references, some are
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index 92486dca19d4..5e43ea0bd7ae 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -995,11 +995,9 @@ bool FormulaTokenArray::HasMatrixDoubleRefOps()
return false;
}
-
-
// --- POF (plain old formula) rewrite of a token array ---------------------
-inline bool MissingConvention::isRewriteNeeded( OpCode eOp ) const
+inline bool MissingConventionPOF::isRewriteNeeded( OpCode eOp ) const
{
switch (eOp)
{
@@ -1026,11 +1024,13 @@ class FormulaMissingContext
void Clear() { mpFunc = NULL; mnCurArg = 0; }
inline bool AddDefaultArg( FormulaTokenArray* pNewArr, int nArg, double f ) const;
bool AddMissingExternal( FormulaTokenArray* pNewArr ) const;
- bool AddMissing( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const;
- void AddMoreArgs( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const;
+ bool AddMissingPOF( FormulaTokenArray *pNewArr, const MissingConventionPOF & rConv ) const;
+ void AddMoreArgsPOF( FormulaTokenArray *pNewArr, const MissingConventionPOF & rConv ) const;
+ bool AddMissingOOXML( FormulaTokenArray *pNewArr ) const;
+ void AddMoreArgsOOXML( FormulaTokenArray *pNewArr ) const;
};
-void FormulaMissingContext::AddMoreArgs( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const
+void FormulaMissingContext::AddMoreArgsPOF( FormulaTokenArray *pNewArr, const MissingConventionPOF & rConv ) const
{
if ( !mpFunc )
return;
@@ -1082,6 +1082,76 @@ void FormulaMissingContext::AddMoreArgs( FormulaTokenArray *pNewArr, const Missi
}
}
+void FormulaMissingContext::AddMoreArgsOOXML( FormulaTokenArray *pNewArr ) const
+{
+ if ( !mpFunc )
+ return;
+
+ switch (mpFunc->GetOpCode())
+ {
+ case ocIf:
+ if( mnCurArg == 0 )
+ {
+ // Excel needs at least two parameters in IF function
+ pNewArr->AddOpCode( ocSep );
+ pNewArr->AddDouble( 1.0 ); // 2nd, true()
+ }
+ break;
+
+ case ocEuroConvert:
+ if ( mnCurArg == 2 )
+ {
+ pNewArr->AddOpCode( ocSep );
+ pNewArr->AddDouble( 0.0 ); // 4th, FullPrecision = false()
+ }
+ break;
+
+ case ocPoissonDist:
+ if (mnCurArg == 1)
+ {
+ pNewArr->AddOpCode( ocSep );
+ pNewArr->AddDouble( 1.0 ); // 3rd, Cumulative=true()
+ }
+ break;
+
+ case ocGammaDist:
+ case ocNormDist:
+ if (mnCurArg == 2)
+ {
+ pNewArr->AddOpCode( ocSep );
+ pNewArr->AddDouble( 1.0 ); // 4th, Cumulative=true()
+ }
+ break;
+
+ case ocLogNormDist:
+ if ( mnCurArg == 0 )
+ {
+ pNewArr->AddOpCode( ocSep );
+ pNewArr->AddDouble( 0.0 ); // 2nd, mean = 0.0
+ }
+ if ( mnCurArg <= 1 )
+ {
+ pNewArr->AddOpCode( ocSep );
+ pNewArr->AddDouble( 1.0 ); // 3rd, standard deviation = 1.0
+ }
+ break;
+
+ case ocRound:
+ case ocRoundUp:
+ case ocRoundDown:
+ if( mnCurArg == 0 )
+ {
+ // ROUND, ROUNDUP, ROUNDDOWN functions are fixed to 2 parameters in Excel
+ pNewArr->AddOpCode( ocSep );
+ pNewArr->AddDouble( 0.0 ); // 2nd, 0.0
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
inline bool FormulaMissingContext::AddDefaultArg( FormulaTokenArray* pNewArr, int nArg, double f ) const
{
if (mnCurArg == nArg)
@@ -1116,7 +1186,7 @@ bool FormulaMissingContext::AddMissingExternal( FormulaTokenArray *pNewArr ) con
return false;
}
-bool FormulaMissingContext::AddMissing( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const
+bool FormulaMissingContext::AddMissingPOF( FormulaTokenArray *pNewArr, const MissingConventionPOF & rConv ) const
{
if ( !mpFunc )
return false;
@@ -1178,7 +1248,27 @@ bool FormulaMissingContext::AddMissing( FormulaTokenArray *pNewArr, const Missin
return bRet;
}
-bool FormulaTokenArray::NeedsPofRewrite( const MissingConvention & rConv )
+bool FormulaMissingContext::AddMissingOOXML( FormulaTokenArray *pNewArr ) const
+{
+ if ( !mpFunc )
+ return false;
+
+ bool bRet = false;
+ const OpCode eOp = mpFunc->GetOpCode();
+
+ switch (eOp)
+ {
+ case ocExternal:
+ return AddMissingExternal( pNewArr );
+ break;
+
+ default:
+ break;
+ }
+ return bRet;
+}
+
+bool FormulaTokenArray::NeedsPofRewrite( const MissingConventionPOF & rConv )
{
for ( FormulaToken *pCur = First(); pCur; pCur = Next() )
{
@@ -1189,7 +1279,7 @@ bool FormulaTokenArray::NeedsPofRewrite( const MissingConvention & rConv )
}
-FormulaTokenArray * FormulaTokenArray::RewriteMissingToPof( const MissingConvention & rConv )
+FormulaTokenArray * FormulaTokenArray::RewriteMissing( bool bIsOOXML, const MissingConventionPOF & rConv )
{
const size_t nAlloc = 256;
FormulaMissingContext aCtx[ nAlloc ];
@@ -1232,12 +1322,18 @@ FormulaTokenArray * FormulaTokenArray::RewriteMissingToPof( const MissingConvent
++nFn; // all following operations on _that_ function
pCtx[ nFn ].mpFunc = PeekPrevNoSpaces();
pCtx[ nFn ].mnCurArg = 0;
- if (pCtx[ nFn ].mpFunc && pCtx[ nFn ].mpFunc->GetOpCode() == ocAddress && !rConv.isODFF())
- pOcas[ nOcas++ ] = nFn; // entering ADDRESS() if PODF
+ if ( !bIsOOXML )
+ {
+ if (pCtx[ nFn ].mpFunc && pCtx[ nFn ].mpFunc->GetOpCode() == ocAddress && !rConv.isODFF())
+ pOcas[ nOcas++ ] = nFn; // entering ADDRESS() if PODF
+ }
break;
case ocClose:
- pCtx[ nFn ].AddMoreArgs( pNewArr, rConv );
- DBG_ASSERT( nFn > 0, "FormulaTokenArray::RewriteMissingToPof: underflow");
+ if ( bIsOOXML )
+ pCtx[ nFn ].AddMoreArgsOOXML( pNewArr );
+ else
+ pCtx[ nFn ].AddMoreArgsPOF( pNewArr, rConv );
+ DBG_ASSERT( nFn > 0, "FormulaTokenArray::RewriteMissing: underflow");
if (nOcas > 0 && pOcas[ nOcas-1 ] == nFn)
--nOcas; // leaving ADDRESS()
if (nFn > 0)
@@ -1252,8 +1348,13 @@ FormulaTokenArray * FormulaTokenArray::RewriteMissingToPof( const MissingConvent
}
break;
case ocMissing:
- if (bAdd)
- bAdd = !pCtx[ nFn ].AddMissing( pNewArr, rConv );
+ if ( bAdd )
+ {
+ if ( bIsOOXML )
+ bAdd = !pCtx[ nFn ].AddMissingOOXML( pNewArr );
+ else
+ bAdd = !pCtx[ nFn ].AddMissingPOF( pNewArr, rConv );
+ }
break;
default:
break;
@@ -1270,6 +1371,65 @@ FormulaTokenArray * FormulaTokenArray::RewriteMissingToPof( const MissingConvent
return pNewArr;
}
+/*
+ * fdo 81596
+Test status ( . : in progress , v : tested , - not applicable )
+finished:
+- ocCosecant: // for OOXML not rewritten anymore
+- ocSecant: // for OOXML not rewritten anymore
+- ocCot: // for OOXML not rewritten anymore
+- ocCosecantHyp: // for OOXML not rewritten anymore
+- ocSecantHyp: // for OOXML not rewritten anymore
+- ocCotHyp: // for OOXML not rewritten anymore
+- ocArcCot: // for OOXML not rewritten anymore
+- ocArcCotHyp: // ACOTH(x), not needed for Excel2013 and later
+- ocChose: // CHOOSE() - no rewrite needed, it seems
+v ocEuroConvert:
+v ocIf:
+v ocRound:
+v ocRoundUp:
+v ocRoundDown:
+v ocGammaDist:
+v ocPoissonDist:
+v ocNormDist:
+v ocLogNormDist:
+
+To be implemented yet:
+ ocExternal: ?
+ ocMacro: ?
+ ocIndex: INDEX() ?
+ ocFDist: // later, fdo40835
+*/
+bool FormulaTokenArray::NeedsOOXMLRewrite()
+{
+ for ( FormulaToken *pCur = First(); pCur; pCur = Next() )
+ {
+ switch ( pCur->GetOpCode() )
+ {
+ case ocIf:
+
+ case ocExternal:
+ case ocEuroConvert:
+ case ocMacro:
+
+ case ocRound:
+ case ocRoundUp:
+ case ocRoundDown:
+
+ case ocIndex:
+
+ case ocGammaDist:
+ case ocPoissonDist:
+ case ocNormDist:
+ case ocLogNormDist:
+ return true;
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
bool FormulaTokenArray::MayReferenceFollow()
{
if ( pCode && nLen > 0 )
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index c6433aa43b07..e3589d997a96 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -53,11 +53,11 @@ typedef sal_uInt8 ScRecalcMode;
class FormulaMissingContext;
-class FORMULA_DLLPUBLIC MissingConvention
+class FORMULA_DLLPUBLIC MissingConventionPOF
{
bool mbODFF; /// TRUE: ODFF, FALSE: PODF
public:
- explicit MissingConvention( bool bODFF ) : mbODFF(bODFF) {}
+ explicit MissingConventionPOF( bool bODFF ) : mbODFF(bODFF) {}
// Implementation and usage only in token.cxx
inline bool isRewriteNeeded( OpCode eOp ) const;
inline bool isODFF() const { return mbODFF; }
@@ -239,11 +239,14 @@ public:
/** Determines if this formula needs any changes to convert it to something
previous versions of OOo could consume (Plain Old Formula). */
- bool NeedsPofRewrite(const MissingConvention & rConv);
+ bool NeedsPofRewrite(const MissingConventionPOF & rConv);
- /** Rewrites to Plain Old Formula, substituting missing parameters. The
+ /** Determines if this formula needs any changes to convert it to OOXML */
+ bool NeedsOOXMLRewrite();
+
+ /** Rewrites to Plain Old Formula or OOXML, substituting missing parameters. The
FormulaTokenArray* returned is new'ed. */
- FormulaTokenArray* RewriteMissingToPof(const MissingConvention & rConv);
+ FormulaTokenArray* RewriteMissing( bool bIsOOXML, const MissingConventionPOF & rConv );
/** Determines if this formula may be followed by a reference. */
bool MayReferenceFollow();