summaryrefslogtreecommitdiffstats
path: root/lotuswordpro/source/filter/lwptblformula.cxx
diff options
context:
space:
mode:
authorFong Lin <pflin@novell.com>2010-10-08 17:04:46 +0100
committerMichael Meeks <michael.meeks@novell.com>2010-10-08 17:04:46 +0100
commitcc316b39d9110c536e1758a4f814738ca209bb02 (patch)
tree0ff290d366ff8fea16ebc7e7781cc14b563f9b37 /lotuswordpro/source/filter/lwptblformula.cxx
parentPort of Lotus Word Pro filter, by Fong Lin and Noel Power (diff)
downloadcore-cc316b39d9110c536e1758a4f814738ca209bb02.tar.gz
core-cc316b39d9110c536e1758a4f814738ca209bb02.zip
Port of Lotus Word Pro filter, by Fong Lin and Noel Power
Diffstat (limited to 'lotuswordpro/source/filter/lwptblformula.cxx')
-rw-r--r--lotuswordpro/source/filter/lwptblformula.cxx803
1 files changed, 803 insertions, 0 deletions
diff --git a/lotuswordpro/source/filter/lwptblformula.cxx b/lotuswordpro/source/filter/lwptblformula.cxx
new file mode 100644
index 000000000000..3caef2a0d79d
--- /dev/null
+++ b/lotuswordpro/source/filter/lwptblformula.cxx
@@ -0,0 +1,803 @@
+/*************************************************************************
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: IBM Corporation
+ *
+ * Copyright: 2008 by IBM Corporation
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+/**
+ * @file
+ * For LWP filter architecture prototype - table cell numerics format
+ */
+/*************************************************************************
+ * Change History
+ Mar 2005 Created
+ ************************************************************************/
+
+#include "lwpoverride.hxx"
+#include "lwptblcell.hxx"
+#include "lwppara.hxx"
+#include "lwptblformula.hxx"
+
+#include "lwptablelayout.hxx"
+
+//////////////////////////////////////////////////////////////////
+ LwpFormulaInfo::LwpFormulaInfo(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
+:LwpCellList(objHdr, pStrm),m_nFormulaRow(0),m_bSupported(sal_True)
+{}
+
+LwpFormulaInfo::~LwpFormulaInfo()
+{
+ try{
+ while(m_aStack.size()>0)
+ {
+ LwpFormulaArg* pArg=m_aStack.back();
+ m_aStack.pop_back();
+ delete pArg; pArg=NULL;
+ }
+ }catch (...)
+ {
+ assert(false);
+ }
+}
+
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return sal_Bool.
+*/
+sal_Bool LwpFormulaInfo::ReadConst()
+{
+ double Constant;
+ m_pObjStrm->QuickRead(&Constant, sizeof(Constant));
+
+ m_aStack.push_back( new LwpFormulaConst(Constant) );
+
+ return sal_True;
+}
+/**
+* Need more effort for unicode.
+* @date 03/26/2005
+* @param
+* @param
+* @return sal_Bool.
+*/
+sal_Bool LwpFormulaInfo::ReadText()
+{
+ USHORT nDiskSize,nStrLen;
+ nDiskSize = m_pObjStrm->QuickReadInt16();
+ nStrLen = m_pObjStrm->QuickReadInt16();
+
+ auto_ptr<char> pBuf(new char[nStrLen+1]);
+ m_pObjStrm->QuickRead( pBuf.get(), nStrLen );
+ *(pBuf.get()+nStrLen)='\0';
+ String aText;
+ aText += String::CreateFromAscii("\"");
+ aText.Append(String(pBuf.get(),nStrLen,gsl_getSystemTextEncoding()));
+ aText += String::CreateFromAscii("\"");
+
+ m_aStack.push_back(new LwpFormulaText(aText));
+ return sal_True;
+}
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return sal_Bool.
+*/
+sal_Bool LwpFormulaInfo::ReadCellID()
+{
+ LwpRowSpecifier RowSpecifier;
+ LwpColumnSpecifier ColumnSpecifier;
+ sal_Bool readSucceeded = true;
+
+ RowSpecifier.QuickRead(m_pObjStrm);
+ ColumnSpecifier.QuickRead(m_pObjStrm);
+
+ m_aStack.push_back( new LwpFormulaCellAddr(ColumnSpecifier.ColumnID(cColumn),
+ RowSpecifier.RowID(m_nFormulaRow)) );
+ return readSucceeded;
+}
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return sal_Bool.
+*/
+sal_Bool LwpFormulaInfo::ReadCellRange()
+{
+ sal_Bool readSucceeded = sal_True;
+ if (!ReadCellID( )) // start
+ readSucceeded = false;
+ LwpFormulaCellAddr* pStartCellAddr = (LwpFormulaCellAddr*)m_aStack.back();
+ m_aStack.pop_back();
+
+ if (!ReadCellID()) // end
+ readSucceeded = false;
+ LwpFormulaCellAddr* pEndCellAddr = (LwpFormulaCellAddr*)m_aStack.back();
+ m_aStack.pop_back();
+
+ m_aStack.push_back( new LwpFormulaCellRangeAddr(pStartCellAddr->GetCol(),
+ pStartCellAddr->GetRow(),
+ pEndCellAddr->GetCol(),
+ pEndCellAddr->GetRow()) );
+ delete pStartCellAddr;
+ delete pEndCellAddr;
+
+ return readSucceeded;
+}
+
+/**
+* Read expression from wordpro file
+* @date 03/26/2005
+* @param
+* @param
+* @return sal_Bool.
+*/
+sal_Bool LwpFormulaInfo::ReadExpression()
+{
+ sal_uInt16 TokenType, DiskLength;
+ sal_Bool readSucceeded = sal_True;
+
+ /* Read the compiled expression length */
+// Len = m_pObjStrm->QuickReaduInt16();
+ m_pObjStrm->SeekRel(2);
+
+ while ((TokenType = m_pObjStrm->QuickReaduInt16()) != TK_END)
+ {
+ // Get the disk length of this token
+ DiskLength = m_pObjStrm->QuickReaduInt16();
+
+ switch (TokenType)
+ {
+ case TK_CONSTANT:
+ {
+ ReadConst();
+ break;
+ }
+
+ case TK_CELLID:
+ if (!ReadCellID())
+ readSucceeded = FALSE;
+ break;
+
+ case TK_CELLRANGE:
+ readSucceeded = ReadCellRange();
+ break;
+
+ case TK_SUM:
+ case TK_IF:
+ case TK_COUNT:
+ case TK_MINIMUM:
+ case TK_MAXIMUM:
+ case TK_AVERAGE:
+ {
+ LwpFormulaFunc* pFunc = new LwpFormulaFunc(TokenType);
+ if (!ReadArguments(*pFunc))
+ readSucceeded = FALSE;
+ m_aStack.push_back(pFunc);
+ }
+ break;
+
+ case TK_ADD://7
+ case TK_SUBTRACT:
+ case TK_MULTIPLY:
+ case TK_DIVIDE:
+ case TK_LESS:
+ case TK_LESS_OR_EQUAL:
+ case TK_GREATER:
+ case TK_GREATER_OR_EQUAL:
+ case TK_EQUAL:
+ case TK_NOT_EQUAL:
+ case TK_AND:
+ case TK_OR:
+ case TK_NOT:
+ m_pObjStrm->SeekRel(DiskLength); // extensible for future
+
+ {//binary operator
+ LwpFormulaOp* pOp = new LwpFormulaOp(TokenType);
+ pOp->AddArg(m_aStack.back()); m_aStack.pop_back();
+ pOp->AddArg(m_aStack.back()); m_aStack.pop_back();
+ m_aStack.push_back(pOp);
+ }
+ break;
+ case TK_UNARY_MINUS:
+ {
+ LwpFormulaUnaryOp* pOp = new LwpFormulaUnaryOp(TokenType);
+ pOp->AddArg(m_aStack.back()); m_aStack.pop_back();
+ m_aStack.push_back(pOp);
+ }
+ break;
+ default:
+ // We don't know what to do with this token, so eat it.
+ m_pObjStrm->SeekRel(DiskLength);
+ readSucceeded = FALSE;
+ break;
+ }
+ MarkUnsupported(TokenType);
+ }
+ return readSucceeded;
+}
+
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return
+*/
+void LwpFormulaInfo::MarkUnsupported(sal_uInt16 TokenType)
+{
+ switch(TokenType)
+ {
+ case TK_IF:
+ case TK_COUNT:
+ case TK_NOT:
+ {
+ m_bSupported = sal_False;//Not supported formulas
+ }
+ break;
+ default:
+ break;
+ }
+}
+/**
+* Read arguments of functions from wordpro file
+* @date 03/26/2005
+* @param LwpFormulaFunc& aFunc, functions object
+* @return sal_Bool.
+*/
+sal_Bool LwpFormulaInfo::ReadArguments(LwpFormulaFunc& aFunc)
+{
+ sal_uInt16 NumberOfArguments = m_pObjStrm->QuickReaduInt16();
+ sal_uInt16 ArgumentDiskLength, Count;
+ sal_uInt8 ArgumentType;
+ sal_Bool bArgument = sal_False;
+ sal_Bool readSucceeded = sal_True;
+
+ for (Count = 0; Count < NumberOfArguments; Count++)
+ {
+ ArgumentType = (sal_uInt8) m_pObjStrm->QuickReaduInt16(); // written as lushort
+ ArgumentDiskLength = m_pObjStrm->QuickReaduInt16();
+ bArgument = sal_True;
+
+ switch(ArgumentType)
+ {
+ case TK_CELLID:
+ ReadCellID();
+ break;
+
+ case TK_CELLRANGE:
+ ReadCellRange();
+ break;
+
+ case TK_CONSTANT:
+ ReadConst();
+ break;
+
+ case TK_TEXT:
+ ReadText();
+ break;
+
+ case TK_EXPRESSION:
+ ReadExpression();
+ break;
+
+ default:
+ bArgument = sal_False;
+ m_pObjStrm->SeekRel(ArgumentDiskLength);
+ readSucceeded = sal_False;
+ break;
+ }
+
+ if (bArgument)
+ {
+ aFunc.AddArg( m_aStack.back() );
+ m_aStack.pop_back();
+ }
+ }
+ return readSucceeded;
+}
+
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return
+*/
+void LwpFormulaInfo::Read()
+{
+ LwpCellList::Read();
+ {
+ LwpRowList* pRowList =(LwpRowList*)cParent.obj();
+ if (pRowList)
+ {
+ m_nFormulaRow = pRowList->GetRowID();
+ }
+ else
+ {
+ assert(false);
+ }
+ }
+// sal_uInt8 cFlags = (sal_uInt8) m_pObjStrm->QuickReaduInt16(); // written as a sal_uInt16
+ m_pObjStrm->SeekRel(2);//flags, size in file: sal_uInt16
+
+ LwpNotifyListPersistent cNotifyList;
+ cNotifyList.Read(m_pObjStrm);
+
+ ReadExpression();
+
+ m_pObjStrm->SkipExtra();
+}
+
+/**
+* Make the formula string.
+* @date 03/26/2005
+* @param
+* @param
+* @return sal_Bool.
+*/
+String LwpFormulaInfo::Convert(LwpTableLayout* pCellsMap)
+{
+ String aFormula;
+ if (m_bSupported)
+ {
+ if(1==m_aStack.size())
+ {
+ LwpFormulaArg* pFormula = m_aStack.back();
+ aFormula = pFormula->ToString(pCellsMap);
+ }
+ else
+ {
+ assert(false);
+ }
+ }
+ return aFormula;
+}
+
+/**
+* Fill the XFCell content
+* @date 03/26/2005
+* @param
+* @param
+* @return sal_Bool.
+*/
+void LwpFormulaInfo::Convert(XFCell * pCell,LwpTableLayout* pCellsMap)
+{
+ String aFormula;
+ aFormula = Convert(pCellsMap);
+ if (aFormula.Len())
+ {
+ pCell->SetFormula(aFormula);
+ }
+ LwpCellList::Convert(pCell);
+}
+
+//////////////////////////////////////////////////////////////////
+
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return sal_Bool.
+*/
+LwpFormulaConst::LwpFormulaConst(double dVal)
+{
+ m_dVal = dVal;
+}
+
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return sal_Bool.
+*/
+String LwpFormulaConst::ToString(LwpTableLayout* pCellsMap)
+{
+ return String::CreateFromDouble(m_dVal);
+}
+
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return
+*/
+LwpFormulaText::LwpFormulaText( String aText)
+{
+ m_aText = aText;
+}
+
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return
+*/
+LwpFormulaCellAddr::LwpFormulaCellAddr(sal_Int16 aCol, sal_Int16 aRow)
+{
+ m_aCol = aCol;
+ m_aRow = aRow;
+}
+
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return String
+*/
+String LwpFormulaCellAddr::ToString(LwpTableLayout* pCellsMap)
+{
+// String aCellAddr;
+// aCellAddr.AppendAscii("<");//&lt;
+// aCellAddr+=m_aCol;
+// aCellAddr+=m_aRow;
+// aCellAddr.AppendAscii(">");//&gt;
+
+ String aCellAddr;
+ aCellAddr.AppendAscii("<");//&lt;
+
+ aCellAddr += LwpFormulaTools::GetCellAddr(m_aRow,m_aCol,pCellsMap);
+
+ aCellAddr.AppendAscii(">");//&gt;
+ return aCellAddr;
+}
+
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return
+*/
+LwpFormulaCellRangeAddr::LwpFormulaCellRangeAddr(sal_Int16 aStartCol,
+ sal_Int16 aStartRow,
+ sal_Int16 aEndCol,
+ sal_Int16 aEndRow)
+{
+ m_aStartCol = aStartCol;
+ m_aStartRow = aStartRow;
+ m_aEndCol = aEndCol;
+ m_aEndRow = aEndRow;
+}
+
+/**
+* Convert the cell range into a string
+* @date 03/26/2005
+* @param
+* @param
+* @return String.
+*/
+String LwpFormulaCellRangeAddr::ToString(LwpTableLayout* pCellsMap)
+{
+// String aCellAddr;
+// aCellAddr.AppendAscii("<");//&lt;
+// aCellAddr+=m_aStartCol;
+// aCellAddr+=m_aStartRow;
+// aCellAddr.AppendAscii(":");
+// aCellAddr+=m_aEndCol;
+// aCellAddr+=m_aEndRow;
+// aCellAddr.AppendAscii(">");//&gt;
+
+ String aCellAddr;
+ aCellAddr.AppendAscii("<");//&lt;
+
+ aCellAddr += LwpFormulaTools::GetCellAddr(m_aStartRow,m_aStartCol,pCellsMap);
+ aCellAddr.AppendAscii(":");
+ aCellAddr += LwpFormulaTools::GetCellAddr(m_aEndRow,m_aEndCol,pCellsMap);
+
+ aCellAddr.AppendAscii(">");//&gt;
+
+ return aCellAddr;
+}
+
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return
+*/
+LwpFormulaFunc::LwpFormulaFunc(sal_uInt16 nTokenType)
+{
+ m_nTokenType = nTokenType;
+}
+
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return
+*/
+LwpFormulaFunc::~LwpFormulaFunc()
+{
+ try
+ {
+ while(m_aArgs.size()>0)
+ {
+ LwpFormulaArg* pArg = m_aArgs.back();
+ m_aArgs.pop_back();
+ delete pArg;pArg=NULL;
+ }
+ }catch (...) {
+ assert(false);
+ }
+
+}
+/**
+*
+* @date 03/26/2005
+* @param
+* @param
+* @return
+*/
+void LwpFormulaFunc::AddArg(LwpFormulaArg* pArg)
+{
+ m_aArgs.push_back(pArg);
+}
+/**
+* Convert the functions to a string, which is a argument of other formula
+* @date 03/26/2005
+* @param
+* @param
+* @return String.
+*/
+String LwpFormulaFunc::ToArgString(LwpTableLayout* pCellsMap)
+{
+ String aFormula;
+ aFormula.AppendAscii("(");
+ aFormula+=ToString(pCellsMap);
+ aFormula.AppendAscii(")");
+ return aFormula;
+}
+/**
+* Convert the function to a formula string.
+* @date 03/26/2005
+* @param
+* @param
+* @return sal_Bool.
+*/
+String LwpFormulaFunc::ToString(LwpTableLayout* pCellsMap)
+{
+ String aFormula;
+
+ String aFuncName = LwpFormulaTools::GetName(m_nTokenType);
+ aFormula += aFuncName;
+ aFormula.AppendAscii(" ");//Append a blank space
+
+ //Append args
+ vector<LwpFormulaArg*>::iterator aItr;
+ for (aItr=m_aArgs.begin();aItr!=m_aArgs.end();aItr++)
+ {
+ aFormula.Append( (*aItr)->ToArgString(pCellsMap) );
+ aFormula.AppendAscii("|");//separator
+ }
+
+ //erase the last "|"
+ if (m_aArgs.size()>0)
+ {
+ aFormula.Erase(aFormula.Len()-1,1);
+ }
+ else
+ {
+ assert(false);
+ }
+
+ return aFormula;
+}
+
+/**
+* Convert the formula in operators to a string : e.g. 1+2+3
+* @date 03/26/2005
+* @param
+* @param
+* @return sal_Bool.
+*/
+String LwpFormulaOp::ToString(LwpTableLayout* pCellsMap)
+{
+ String aFormula;
+ if (2==m_aArgs.size())
+ {
+ vector<LwpFormulaArg*>::iterator aItr = m_aArgs.end();
+ aItr--;
+ aFormula.Append( (*aItr)->ToArgString(pCellsMap) );
+
+ aFormula.AppendAscii(" ");
+
+ String aFuncName = LwpFormulaTools::GetName(m_nTokenType);
+ aFormula.Append(aFuncName);
+
+ aFormula.AppendAscii(" ");
+
+ aItr--;
+ aFormula.Append( (*aItr)->ToArgString(pCellsMap) );
+ }
+ else
+ {
+ assert(false);
+ }
+ return aFormula;
+}
+
+/**
+* convert the formula in unary operators into string : e.g. -2
+* @date 03/26/2005
+* @param
+* @param
+* @return sal_Bool.
+*/
+String LwpFormulaUnaryOp::ToString(LwpTableLayout* pCellsMap)
+{
+ String aFormula;
+ if (1==m_aArgs.size())
+ {
+ String aFuncName = LwpFormulaTools::GetName(m_nTokenType);
+ aFormula.Append(aFuncName);
+
+ vector<LwpFormulaArg*>::iterator aItr = m_aArgs.begin();
+ aFormula.Append( (*aItr)->ToArgString(pCellsMap) );
+ }
+ else
+ {
+ assert(false);
+ }
+ return aFormula;
+}
+/**
+* Get token name
+* @date 03/26/2005
+* @param
+* @param
+* @return String.
+*/
+String LwpFormulaTools::GetName(sal_uInt16 nTokenType)
+{
+ String aName;
+ switch(nTokenType)
+ {
+ case TK_SUM:
+ aName = String::CreateFromAscii("SUM");
+ break;
+ case TK_IF:
+ aName = String::CreateFromAscii("IF");//Not supported by SODC
+ break;
+ case TK_COUNT:
+ aName = String::CreateFromAscii("COUNT");//Not supported by SODC
+ break;
+ case TK_MINIMUM:
+ aName = String::CreateFromAscii("MIN");
+ break;
+ case TK_MAXIMUM:
+ aName = String::CreateFromAscii("MAX");
+ break;
+ case TK_AVERAGE:
+ aName = String::CreateFromAscii("MEAN");
+ break;
+ case TK_ADD:
+ aName = String::CreateFromAscii("+");
+ break;
+ case TK_SUBTRACT:
+ aName = String::CreateFromAscii("-");
+ break;
+ case TK_MULTIPLY:
+ aName = String::CreateFromAscii("*");
+ break;
+ case TK_DIVIDE:
+ aName = String::CreateFromAscii("/");
+ break;
+ case TK_UNARY_MINUS:
+ aName = String::CreateFromAscii("-");
+ break;
+ case TK_LESS:
+ aName = String::CreateFromAscii("L");
+ break;
+ case TK_LESS_OR_EQUAL:
+ aName = String::CreateFromAscii("LEQ");
+ break;
+ case TK_GREATER:
+ aName = String::CreateFromAscii("G");
+ break;
+ case TK_GREATER_OR_EQUAL:
+ aName = String::CreateFromAscii("GEQ");
+ break;
+ case TK_EQUAL:
+ aName = String::CreateFromAscii("EQ");
+ break;
+ case TK_NOT_EQUAL:
+ aName = String::CreateFromAscii("NEQ");
+ break;
+ case TK_NOT:
+ aName = String::CreateFromAscii("NOT");
+ break;
+ case TK_AND:
+ aName = String::CreateFromAscii("AND");
+ break;
+ case TK_OR:
+ aName = String::CreateFromAscii("OR");
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ return aName;
+}
+
+/**
+* Get cell address in String
+* @date 03/26/2005
+* @param
+* @param
+* @return String.
+*/
+String LwpFormulaTools::GetCellAddr(sal_Int16 nRow, sal_Int16 nCol, LwpTableLayout* pCellsMap)
+{
+ String aCellAddr;
+ XFCell* pCell = pCellsMap->GetCellsMap(nRow,(sal_uInt8)nCol);
+ if (pCell)
+ {
+ aCellAddr = pCell->GetCellName();
+ }
+ else
+ {
+ assert( -1==nRow || -1==(sal_Int8)nCol);
+ }
+ return aCellAddr;
+}