summaryrefslogtreecommitdiff
path: root/sc/source
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-08-05 22:26:11 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-08-12 19:46:24 -0400
commit86a2dc96c7ce312f251b5a063c2aa8332c8817a0 (patch)
tree6d2660f08e8639b64d2e4d8171bdd5ac67776aa0 /sc/source
parentf4b757d7e7a3f5bc23fea3e540671b0f40133f24 (diff)
Prepare for importing shared formulas as formula groups from xls.
Still the first step. Change-Id: I1897c9c2cd3a5b5245febbfba76e1b088054f578
Diffstat (limited to 'sc/source')
-rw-r--r--sc/source/core/data/formulacell.cxx95
-rw-r--r--sc/source/filter/excel/excform.cxx132
-rw-r--r--sc/source/filter/excel/read.cxx2
-rw-r--r--sc/source/filter/inc/excform.hxx2
4 files changed, 138 insertions, 93 deletions
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 0ad7cb68b8cb..cdedb660bc9f 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -384,6 +384,7 @@ void adjustDBRange(ScToken* pToken, ScDocument& rNewDoc, const ScDocument* pOldD
ScFormulaCellGroup::ScFormulaCellGroup() :
mnRefCount(0),
+ mpCode(NULL),
mnStart(0),
mnLength(0),
mbInvariant(false),
@@ -393,6 +394,7 @@ ScFormulaCellGroup::ScFormulaCellGroup() :
ScFormulaCellGroup::~ScFormulaCellGroup()
{
+ delete mpCode;
}
// ============================================================================
@@ -477,6 +479,53 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
pCode->GenHash();
}
+ScFormulaCell::ScFormulaCell(
+ ScDocument* pDoc, const ScAddress& rPos, const ScFormulaCellGroupRef& xGroup,
+ const FormulaGrammar::Grammar eGrammar, sal_uInt8 cInd ) :
+ mxGroup(xGroup),
+ eTempGrammar( eGrammar),
+ pCode(xGroup->mpCode ? xGroup->mpCode : new ScTokenArray),
+ pDocument( pDoc ),
+ pPrevious(0),
+ pNext(0),
+ pPreviousTrack(0),
+ pNextTrack(0),
+ nSeenInIteration(0),
+ cMatrixFlag ( cInd ),
+ nFormatType ( NUMBERFORMAT_NUMBER ),
+ bDirty(false),
+ bChanged( false ),
+ bRunning( false ),
+ bCompile( false ),
+ bSubTotal( false ),
+ bIsIterCell( false ),
+ bInChangeTrack( false ),
+ bTableOpDirty( false ),
+ bNeedListening( false ),
+ mbNeedsNumberFormat( false ),
+ aPos( rPos )
+{
+ // UPN-Array generation
+ if( pCode->GetLen() && !pCode->GetCodeError() && !pCode->GetCodeLen() )
+ {
+ ScCompiler aComp( pDocument, aPos, *pCode);
+ aComp.SetGrammar(eTempGrammar);
+ bSubTotal = aComp.CompileTokenArray();
+ nFormatType = aComp.GetNumFormatType();
+ }
+ else
+ {
+ pCode->Reset();
+ if ( pCode->GetNextOpCodeRPN( ocSubTotal ) )
+ bSubTotal = true;
+ }
+
+ if (bSubTotal)
+ pDocument->AddSubTotalCell(this);
+
+ pCode->GenHash();
+}
+
ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags ) :
SvtListener(),
aResult( rCell.aResult ),
@@ -605,7 +654,9 @@ ScFormulaCell::~ScFormulaCell()
if (pDocument->HasExternalRefManager())
pDocument->GetExternalRefManager()->removeRefCell(this);
- delete pCode;
+ if (!mxGroup || !mxGroup->mpCode)
+ // Formula token is not shared.
+ delete pCode;
}
ScFormulaCell* ScFormulaCell::Clone() const
@@ -1579,8 +1630,8 @@ void ScFormulaCell::SetDirty( bool bDirtyFlag )
void ScFormulaCell::SetDirtyVar()
{
bDirty = true;
- if (xGroup)
- xGroup->meCalcState = sc::GroupCalcEnabled;
+ if (mxGroup)
+ mxGroup->meCalcState = sc::GroupCalcEnabled;
// mark the sheet of this cell to be calculated
//#FIXME do we need to revert this remnant of old fake vba events? pDocument->AddCalculateTable( aPos.Tab() );
@@ -2239,8 +2290,8 @@ bool ScFormulaCell::UpdateReferenceOnShift(
// This formula cell itself is being shifted during cell range
// insertion or deletion. Update its position.
aPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
- if (xGroup && xGroup->mnStart == aOldPos.Row())
- xGroup->mnStart += rCxt.mnRowDelta;
+ if (mxGroup && mxGroup->mnStart == aOldPos.Row())
+ mxGroup->mnStart += rCxt.mnRowDelta;
bCellStateChanged = aPos != aOldPos;
}
@@ -3074,12 +3125,12 @@ void ScFormulaCell::SetNextTrack( ScFormulaCell* pF ) { pNextTr
ScFormulaCellGroupRef ScFormulaCell::GetCellGroup()
{
- return xGroup;
+ return mxGroup;
}
void ScFormulaCell::SetCellGroup( const ScFormulaCellGroupRef &xRef )
{
- xGroup = xRef;
+ mxGroup = xRef;
}
ScFormulaCell::CompareState ScFormulaCell::CompareByTokenArray( ScFormulaCell& rOther ) const
@@ -3309,10 +3360,10 @@ bool ScFormulaCell::InterpretFormulaGroup()
// import / insert / delete etc. and is integral to the data structures
pDocument->RebuildFormulaGroups();
- if (!xGroup || !pCode)
+ if (!mxGroup || !pCode)
return false;
- if (xGroup->meCalcState == sc::GroupCalcDisabled)
+ if (mxGroup->meCalcState == sc::GroupCalcDisabled)
return false;
switch (pCode->GetVectorState())
@@ -3328,28 +3379,28 @@ bool ScFormulaCell::InterpretFormulaGroup()
return false;
}
- if (xGroup->mbInvariant)
+ if (mxGroup->mbInvariant)
return InterpretInvariantFormulaGroup();
sc::FormulaGroupContext aCxt;
ScTokenArray aCode;
ScAddress aTopPos = aPos;
- aTopPos.SetRow(xGroup->mnStart);
+ aTopPos.SetRow(mxGroup->mnStart);
GroupTokenConverter aConverter(aCxt, aCode, *pDocument, *this, aTopPos);
if (!aConverter.convert(*pCode))
{
- xGroup->meCalcState = sc::GroupCalcDisabled;
+ mxGroup->meCalcState = sc::GroupCalcDisabled;
return false;
}
- xGroup->meCalcState = sc::GroupCalcRunning;
- if (!sc::FormulaGroupInterpreter::getStatic()->interpret(*pDocument, aTopPos, xGroup, aCode))
+ mxGroup->meCalcState = sc::GroupCalcRunning;
+ if (!sc::FormulaGroupInterpreter::getStatic()->interpret(*pDocument, aTopPos, mxGroup, aCode))
{
- xGroup->meCalcState = sc::GroupCalcDisabled;
+ mxGroup->meCalcState = sc::GroupCalcDisabled;
return false;
}
- xGroup->meCalcState = sc::GroupCalcEnabled;
+ mxGroup->meCalcState = sc::GroupCalcEnabled;
return true;
}
@@ -3409,10 +3460,10 @@ bool ScFormulaCell::InterpretInvariantFormulaGroup()
aResult.SetToken(aInterpreter.GetResultToken().get());
}
- for ( sal_Int32 i = 0; i < xGroup->mnLength; i++ )
+ for ( sal_Int32 i = 0; i < mxGroup->mnLength; i++ )
{
ScAddress aTmpPos = aPos;
- aTmpPos.SetRow(xGroup->mnStart + i);
+ aTmpPos.SetRow(mxGroup->mnStart + i);
ScFormulaCell* pCell = pDocument->GetFormulaCell(aTmpPos);
assert( pCell != NULL );
@@ -3642,21 +3693,21 @@ void ScFormulaCell::EndListeningTo( sc::EndListeningContext& rCxt )
bool ScFormulaCell::IsShared() const
{
- return xGroup.get() != NULL;
+ return mxGroup.get() != NULL;
}
bool ScFormulaCell::IsSharedInvariant() const
{
- return xGroup ? xGroup->mbInvariant : false;
+ return mxGroup ? mxGroup->mbInvariant : false;
}
SCROW ScFormulaCell::GetSharedTopRow() const
{
- return xGroup ? xGroup->mnStart : -1;
+ return mxGroup ? mxGroup->mnStart : -1;
}
SCROW ScFormulaCell::GetSharedLength() const
{
- return xGroup ? xGroup->mnLength : 0;
+ return mxGroup ? mxGroup->mnLength : 0;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index b2a161991f52..4f60d7ec56bb 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -101,56 +101,63 @@ void ImportExcel::Formula4()
void ImportExcel::Formula(
const XclAddress& rXclPos, sal_uInt16 nXF, sal_uInt16 nFormLen, double fCurVal, bool bShrFmla)
{
- ConvErr eErr = ConvOK;
ScAddress aScPos( ScAddress::UNINITIALIZED );
- if( GetAddressConverter().ConvertAddress( aScPos, rXclPos, GetCurrScTab(), true ) )
- {
- // Formula will be read next, length in nFormLen
- const ScTokenArray* pResult = NULL;
- bool bConvert = false;
+ if (!GetAddressConverter().ConvertAddress(aScPos, rXclPos, GetCurrScTab(), true))
+ // Conversion failed.
+ return;
- pFormConv->Reset( aScPos );
+ // Formula will be read next, length in nFormLen
+ const ScTokenArray* pResult = NULL;
- if( bShrFmla )
- bConvert = !pFormConv->GetShrFmla( pResult, maStrm, nFormLen );
- else
- bConvert = true;
+ pFormConv->Reset( aScPos );
- if( bConvert )
- eErr = pFormConv->Convert( pResult, maStrm, nFormLen, true, FT_CellFormula);
+ if (bShrFmla)
+ {
+ // This is a shared formula. Get the token array from the shared formula pool.
+ pResult = pFormConv->GetShrFmla(maStrm, nFormLen);
+ if (!pResult)
+ return;
+
+ ScFormulaCell* pCell = new ScFormulaCell( pD, aScPos, pResult );
+ pD->EnsureTable(aScPos.Tab());
+ pCell = pD->SetFormulaCell(aScPos, pCell);
+ pCell->SetNeedNumberFormat(false);
+ if (!rtl::math::isNan(fCurVal))
+ pCell->SetResultDouble(fCurVal);
+
+ GetXFRangeBuffer().SetXF(aScPos, nXF);
+ return;
+ }
- ScFormulaCell* pCell = NULL;
+ ConvErr eErr = pFormConv->Convert( pResult, maStrm, nFormLen, true, FT_CellFormula);
- if (pResult)
- {
- pCell = new ScFormulaCell( pD, aScPos, pResult );
- pD->EnsureTable(aScPos.Tab());
- pCell = pD->SetFormulaCell(aScPos, pCell);
- }
- else
- {
- CellType eCellType = pD->GetCellType(aScPos);
- if( eCellType == CELLTYPE_FORMULA )
- {
- pCell = pD->GetFormulaCell(aScPos);
- if( pCell )
- pCell->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
- }
- }
+ ScFormulaCell* pCell = NULL;
+ if (pResult)
+ {
+ pCell = new ScFormulaCell( pD, aScPos, pResult );
+ pD->EnsureTable(aScPos.Tab());
+ pCell = pD->SetFormulaCell(aScPos, pCell);
+ }
+ else
+ {
+ pCell = pD->GetFormulaCell(aScPos);
if (pCell)
- {
- pCell->SetNeedNumberFormat(false);
- if( eErr != ConvOK )
- ExcelToSc::SetError( *pCell, eErr );
+ pCell->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+ }
- if (!rtl::math::isNan(fCurVal))
- pCell->SetResultDouble(fCurVal);
- }
+ if (pCell)
+ {
+ pCell->SetNeedNumberFormat(false);
+ if( eErr != ConvOK )
+ ExcelToSc::SetError( *pCell, eErr );
- GetXFRangeBuffer().SetXF( aScPos, nXF );
+ if (!rtl::math::isNan(fCurVal))
+ pCell->SetResultDouble(fCurVal);
}
+
+ GetXFRangeBuffer().SetXF(aScPos, nXF);
}
@@ -1669,45 +1676,32 @@ const ScTokenArray* ExcelToSc::GetBoolErr( XclBoolError eType )
// if a shared formula was found, stream seeks to first byte after <nFormulaLen>,
// else stream pointer stays unchanged
-sal_Bool ExcelToSc::GetShrFmla( const ScTokenArray*& rpErgebnis, XclImpStream& aIn, sal_Size nFormulaLen )
+const ScTokenArray* ExcelToSc::GetShrFmla( XclImpStream& aIn, sal_Size nFormulaLen )
{
- sal_uInt8 nOp;
- sal_Bool bRet = sal_True;
+ if (!nFormulaLen)
+ return NULL;
- if( nFormulaLen == 0 )
- bRet = false;
- else
- {
- aIn.PushPosition();
-
- aIn >> nOp;
+ aIn.PushPosition();
- if( nOp == 0x01 ) // Shared Formula [ 277]
- {
- sal_uInt16 nCol, nRow;
-
- aIn >> nRow >> nCol;
-
- aStack << aPool.StoreName( GetOldRoot().pShrfmlaBuff->Find(
- ScAddress(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), GetCurrScTab())), true);
-
- bRet = sal_True;
- }
- else
- bRet = false;
+ sal_uInt8 nOp;
+ aIn >> nOp;
+ if (nOp != 0x01) // Shared Formula [ 277]
+ {
aIn.PopPosition();
+ return NULL;
}
- if( bRet )
- {
- aIn.Ignore( nFormulaLen );
- rpErgebnis = aPool[ aStack.Get() ];
- }
- else
- rpErgebnis = NULL;
+ sal_uInt16 nCol, nRow;
+ aIn >> nRow >> nCol;
+
+ aStack << aPool.StoreName( GetOldRoot().pShrfmlaBuff->Find(
+ ScAddress(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), GetCurrScTab())), true);
+
+ aIn.PopPosition();
- return bRet;
+ aIn.Ignore(nFormulaLen);
+ return aPool[aStack.Get()];
}
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
index d1ec8aed8f2b..9c4c5e77b334 100644
--- a/sc/source/filter/excel/read.cxx
+++ b/sc/source/filter/excel/read.cxx
@@ -1140,7 +1140,7 @@ FltError ImportExcel8::Read( void )
case EXC_ID2_ARRAY:
case EXC_ID3_ARRAY: Array34(); break; // ARRAY [ 34 ]
case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345 ]
- case 0x04BC: Shrfmla(); break; // SHRFMLA [ 5 ]
+ case EXC_ID_SHRFMLA: Shrfmla(); break; // SHRFMLA [ 5 ]
case 0x0867: SheetProtection(); break; // SHEETPROTECTION
}
}
diff --git a/sc/source/filter/inc/excform.hxx b/sc/source/filter/inc/excform.hxx
index 1b7786fa6aaf..fb866fe812e8 100644
--- a/sc/source/filter/inc/excform.hxx
+++ b/sc/source/filter/inc/excform.hxx
@@ -63,7 +63,7 @@ public:
void GetDummy( const ScTokenArray*& );
const ScTokenArray* GetBoolErr( XclBoolError );
- sal_Bool GetShrFmla( const ScTokenArray*&, XclImpStream& rStrm, sal_Size nFormulaLen );
+ const ScTokenArray* GetShrFmla( XclImpStream& rStrm, sal_Size nFormulaLen );
static void SetError( ScFormulaCell& rCell, const ConvErr eErr );