| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #ifndef SC_TOKEN_HXX |
| #define SC_TOKEN_HXX |
| |
| #include <memory> |
| #include <vector> |
| #include <boost/shared_ptr.hpp> |
| |
| #include "formula/opcode.hxx" |
| #include "refdata.hxx" |
| #include "scmatrix.hxx" |
| #include "formula/intruref.hxx" |
| #include <tools/mempool.hxx> |
| #include "scdllapi.h" |
| #include "formula/IFunctionDescription.hxx" |
| #include "formula/token.hxx" |
| |
| |
| class ScJumpMatrix; |
| class ScToken; |
| |
| typedef ::std::vector< ScComplexRefData > ScRefList; |
| typedef formula::SimpleIntrusiveReference< class ScToken > ScTokenRef; |
| |
| /** |
| * Another ref-counted token type using shared_ptr. <b>Be extra careful |
| * not to mix use of this smart pointer type with ScTokenRef</b>, since |
| * mixing them might cause a premature object deletion because the same |
| * object may be ref-counted by two different smart pointer wrappers. |
| * |
| * You have been warned. |
| */ |
| typedef ::boost::shared_ptr< ScToken > ScSharedTokenRef; |
| |
| class SC_DLLPUBLIC ScToken : public formula::FormulaToken |
| { |
| private: |
| // not implemented, prevent usage |
| ScToken(); |
| ScToken& operator=( const ScToken& ); |
| |
| protected: |
| |
| ScToken( formula::StackVar eTypeP,OpCode e = ocPush ) : formula::FormulaToken(eTypeP,e) {} |
| ScToken( const ScToken& r ): formula::FormulaToken(r) {} |
| |
| public: |
| |
| virtual ~ScToken(); |
| |
| /** |
| Dummy methods to avoid switches and casts where possible, |
| the real token classes have to overload the appropriate method[s]. |
| The only methods valid anytime if not overloaded are: |
| |
| - GetByte() since this represents the count of parameters to a function |
| which of course is 0 on non-functions. formula::FormulaByteToken and ScExternal do |
| overload it. |
| |
| - HasForceArray() since also this is only used for operators and |
| functions and is 0 for other tokens. |
| |
| Any other non-overloaded method pops up an assertion. |
| */ |
| |
| virtual const ScSingleRefData& GetSingleRef() const; |
| virtual ScSingleRefData& GetSingleRef(); |
| virtual const ScComplexRefData& GetDoubleRef() const; |
| virtual ScComplexRefData& GetDoubleRef(); |
| virtual const ScSingleRefData& GetSingleRef2() const; |
| virtual ScSingleRefData& GetSingleRef2(); |
| virtual void CalcAbsIfRel( const ScAddress& ); |
| virtual void CalcRelFromAbs( const ScAddress& ); |
| virtual const ScMatrix* GetMatrix() const; |
| virtual ScMatrix* GetMatrix(); |
| virtual ScJumpMatrix* GetJumpMatrix() const; |
| virtual const ScRefList* GetRefList() const; |
| virtual ScRefList* GetRefList(); |
| |
| virtual sal_Bool TextEqual( const formula::FormulaToken& rToken ) const; |
| virtual sal_Bool Is3DRef() const; // reference with 3D flag set |
| |
| /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge |
| ranges as needed for ocRange. |
| @param rPos |
| The formula's position, used to calculate absolute positions from |
| relative references. |
| @param bReuseDoubleRef |
| If sal_True, a DoubleRef token is reused if passed as rTok1 or rTok2, |
| else a new DoubleRef token is created and returned. |
| @return |
| A reused or new'ed ScDoubleRefToken, or a NULL TokenRef if rTok1 or |
| rTok2 are not of sv(Single|Double)Ref |
| */ |
| static formula::FormulaTokenRef ExtendRangeReference( formula::FormulaToken & rTok1, formula::FormulaToken & rTok2, const ScAddress & rPos, bool bReuseDoubleRef ); |
| }; |
| |
| class ScSingleRefToken : public ScToken |
| { |
| private: |
| ScSingleRefData aSingleRef; |
| public: |
| ScSingleRefToken( const ScSingleRefData& r, OpCode e = ocPush ) : |
| ScToken( formula::svSingleRef, e ), aSingleRef( r ) {} |
| ScSingleRefToken( const ScSingleRefToken& r ) : |
| ScToken( r ), aSingleRef( r.aSingleRef ) {} |
| virtual const ScSingleRefData& GetSingleRef() const; |
| virtual ScSingleRefData& GetSingleRef(); |
| virtual void CalcAbsIfRel( const ScAddress& ); |
| virtual void CalcRelFromAbs( const ScAddress& ); |
| virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; |
| virtual FormulaToken* Clone() const { return new ScSingleRefToken(*this); } |
| |
| DECL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken ); |
| }; |
| |
| class ScDoubleRefToken : public ScToken |
| { |
| private: |
| ScComplexRefData aDoubleRef; |
| public: |
| ScDoubleRefToken( const ScComplexRefData& r, OpCode e = ocPush ) : |
| ScToken( formula::svDoubleRef, e ), aDoubleRef( r ) {} |
| ScDoubleRefToken( const ScSingleRefData& r, OpCode e = ocPush ) : |
| ScToken( formula::svDoubleRef, e ) |
| { |
| aDoubleRef.Ref1 = r; |
| aDoubleRef.Ref2 = r; |
| } |
| ScDoubleRefToken( const ScDoubleRefToken& r ) : |
| ScToken( r ), aDoubleRef( r.aDoubleRef ) {} |
| virtual const ScSingleRefData& GetSingleRef() const; |
| virtual ScSingleRefData& GetSingleRef(); |
| virtual const ScComplexRefData& GetDoubleRef() const; |
| virtual ScComplexRefData& GetDoubleRef(); |
| virtual const ScSingleRefData& GetSingleRef2() const; |
| virtual ScSingleRefData& GetSingleRef2(); |
| virtual void CalcAbsIfRel( const ScAddress& ); |
| virtual void CalcRelFromAbs( const ScAddress& ); |
| virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; |
| virtual FormulaToken* Clone() const { return new ScDoubleRefToken(*this); } |
| |
| DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken ); |
| }; |
| |
| class ScMatrixToken : public ScToken |
| { |
| private: |
| ScMatrixRef pMatrix; |
| public: |
| ScMatrixToken( ScMatrix* p ) : |
| ScToken( formula::svMatrix ), pMatrix( p ) {} |
| ScMatrixToken( const ScMatrixToken& r ) : |
| ScToken( r ), pMatrix( r.pMatrix ) {} |
| virtual const ScMatrix* GetMatrix() const; |
| virtual ScMatrix* GetMatrix(); |
| virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; |
| virtual FormulaToken* Clone() const { return new ScMatrixToken(*this); } |
| }; |
| |
| |
| class ScExternalSingleRefToken : public ScToken |
| { |
| private: |
| sal_uInt16 mnFileId; |
| String maTabName; |
| ScSingleRefData maSingleRef; |
| |
| ScExternalSingleRefToken(); // disabled |
| public: |
| ScExternalSingleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& r ); |
| ScExternalSingleRefToken( const ScExternalSingleRefToken& r ); |
| virtual ~ScExternalSingleRefToken(); |
| |
| virtual sal_uInt16 GetIndex() const; |
| virtual const String& GetString() const; |
| virtual const ScSingleRefData& GetSingleRef() const; |
| virtual ScSingleRefData& GetSingleRef(); |
| virtual void CalcAbsIfRel( const ScAddress& ); |
| virtual void CalcRelFromAbs( const ScAddress& ); |
| virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; |
| virtual FormulaToken* Clone() const { return new ScExternalSingleRefToken(*this); } |
| }; |
| |
| |
| class ScExternalDoubleRefToken : public ScToken |
| { |
| private: |
| sal_uInt16 mnFileId; |
| String maTabName; // name of the first sheet |
| ScComplexRefData maDoubleRef; |
| |
| ScExternalDoubleRefToken(); // disabled |
| public: |
| ScExternalDoubleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& r ); |
| ScExternalDoubleRefToken( const ScExternalDoubleRefToken& r ); |
| explicit ScExternalDoubleRefToken( const ScExternalSingleRefToken& r ); |
| virtual ~ScExternalDoubleRefToken(); |
| |
| virtual sal_uInt16 GetIndex() const; |
| virtual const String& GetString() const; |
| virtual const ScSingleRefData& GetSingleRef() const; |
| virtual ScSingleRefData& GetSingleRef(); |
| virtual const ScSingleRefData& GetSingleRef2() const; |
| virtual ScSingleRefData& GetSingleRef2(); |
| virtual const ScComplexRefData& GetDoubleRef() const; |
| virtual ScComplexRefData& GetDoubleRef(); |
| virtual void CalcAbsIfRel( const ScAddress& ); |
| virtual void CalcRelFromAbs( const ScAddress& ); |
| virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; |
| virtual FormulaToken* Clone() const { return new ScExternalDoubleRefToken(*this); } |
| }; |
| |
| |
| class ScExternalNameToken : public ScToken |
| { |
| private: |
| sal_uInt16 mnFileId; |
| String maName; |
| private: |
| ScExternalNameToken(); // disabled |
| public: |
| ScExternalNameToken( sal_uInt16 nFileId, const String& rName ); |
| ScExternalNameToken( const ScExternalNameToken& r ); |
| virtual ~ScExternalNameToken(); |
| virtual sal_uInt16 GetIndex() const; |
| virtual const String& GetString() const; |
| virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; |
| virtual FormulaToken* Clone() const { return new ScExternalNameToken(*this); } |
| }; |
| |
| |
| // Only created from within the interpreter, no conversion from ScRawToken, |
| // never added to ScTokenArray! |
| class ScJumpMatrixToken : public ScToken |
| { |
| private: |
| ScJumpMatrix* pJumpMatrix; |
| public: |
| ScJumpMatrixToken( ScJumpMatrix* p ) : |
| ScToken( formula::svJumpMatrix ), pJumpMatrix( p ) {} |
| ScJumpMatrixToken( const ScJumpMatrixToken& r ) : |
| ScToken( r ), pJumpMatrix( r.pJumpMatrix ) {} |
| virtual ~ScJumpMatrixToken(); |
| virtual ScJumpMatrix* GetJumpMatrix() const; |
| virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; |
| virtual FormulaToken* Clone() const { return new ScJumpMatrixToken(*this); } |
| }; |
| |
| |
| // Only created from within the interpreter, no conversion from ScRawToken, |
| // never added to ScTokenArray! |
| class ScRefListToken : public ScToken |
| { |
| private: |
| ScRefList aRefList; |
| public: |
| ScRefListToken() : |
| ScToken( formula::svRefList ) {} |
| ScRefListToken( const ScRefListToken & r ) : |
| ScToken( r ), aRefList( r.aRefList ) {} |
| virtual void CalcAbsIfRel( const ScAddress& ); |
| virtual void CalcRelFromAbs( const ScAddress& ); |
| virtual const ScRefList* GetRefList() const; |
| virtual ScRefList* GetRefList(); |
| virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; |
| virtual FormulaToken* Clone() const { return new ScRefListToken(*this); } |
| }; |
| |
| |
| class SC_DLLPUBLIC ScEmptyCellToken : public ScToken |
| { |
| bool bInherited :1; |
| bool bDisplayedAsString :1; |
| public: |
| explicit ScEmptyCellToken( bool bInheritedP, bool bDisplayAsString ) : |
| ScToken( formula::svEmptyCell ), |
| bInherited( bInheritedP ), |
| bDisplayedAsString( bDisplayAsString ) {} |
| ScEmptyCellToken( const ScEmptyCellToken& r ) : |
| ScToken( r ), |
| bInherited( r.bInherited ), |
| bDisplayedAsString( r.bDisplayedAsString ) {} |
| bool IsInherited() const { return bInherited; } |
| bool IsDisplayedAsString() const { return bDisplayedAsString; } |
| virtual double GetDouble() const; |
| virtual const String & GetString() const; |
| virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; |
| virtual FormulaToken* Clone() const { return new ScEmptyCellToken(*this); } |
| }; |
| |
| |
| /** Transports the result from the interpreter to the formula cell. */ |
| class SC_DLLPUBLIC ScMatrixCellResultToken : public ScToken |
| { |
| // No non-const access implemented, silence down unxsols4 complaining about |
| // the public GetMatrix() hiding the one from ScToken. |
| virtual ScMatrix* GetMatrix(); |
| |
| protected: |
| ScConstMatrixRef xMatrix; |
| formula::FormulaConstTokenRef xUpperLeft; |
| public: |
| ScMatrixCellResultToken( ScMatrix* pMat, formula::FormulaToken* pUL ) : |
| ScToken( formula::svMatrixCell ), |
| xMatrix( pMat), xUpperLeft( pUL) {} |
| ScMatrixCellResultToken( const ScMatrixCellResultToken& r ) : |
| ScToken( r ), xMatrix( r.xMatrix ), |
| xUpperLeft( r.xUpperLeft ) {} |
| virtual double GetDouble() const; |
| virtual const String & GetString() const; |
| virtual const ScMatrix* GetMatrix() const; |
| virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; |
| virtual FormulaToken* Clone() const { return new ScMatrixCellResultToken(*this); } |
| formula::StackVar GetUpperLeftType() const |
| { |
| return xUpperLeft ? |
| xUpperLeft->GetType() : |
| static_cast<formula::StackVar>(formula::svUnknown); |
| } |
| inline formula::FormulaConstTokenRef GetUpperLeftToken() const { return xUpperLeft; } |
| void Assign( const ScMatrixCellResultToken & r ) |
| { |
| xMatrix = r.xMatrix; |
| xUpperLeft = r.xUpperLeft; |
| } |
| }; |
| |
| |
| /** Stores the matrix result at the formula cell, additionally the range the |
| matrix formula occupies. */ |
| class SC_DLLPUBLIC ScMatrixFormulaCellToken : public ScMatrixCellResultToken |
| { |
| private: |
| SCROW nRows; |
| SCCOL nCols; |
| public: |
| ScMatrixFormulaCellToken( SCCOL nC, SCROW nR ) : |
| ScMatrixCellResultToken( NULL, NULL ), |
| nRows( nR ), nCols( nC ) {} |
| ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken& r ) : |
| ScMatrixCellResultToken( r ), |
| nRows( r.nRows ), nCols( r.nCols ) |
| { |
| // xUpperLeft is modifiable through |
| // SetUpperLeftDouble(), so clone it. |
| if (xUpperLeft) |
| xUpperLeft = xUpperLeft->Clone(); |
| } |
| virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; |
| virtual FormulaToken* Clone() const { return new ScMatrixFormulaCellToken(*this); } |
| void SetMatColsRows( SCCOL nC, SCROW nR ) |
| { |
| nRows = nR; |
| nCols = nC; |
| } |
| void GetMatColsRows( SCCOL & nC, SCROW & nR ) const |
| { |
| nR = nRows; |
| nC = nCols; |
| } |
| SCCOL GetMatCols() const { return nCols; } |
| SCROW GetMatRows() const { return nRows; } |
| |
| /** Assign matrix result, keep matrix formula |
| dimension. */ |
| void Assign( const ScMatrixCellResultToken & r ) |
| { |
| ScMatrixCellResultToken::Assign( r); |
| } |
| |
| /** Assign any result, keep matrix formula |
| dimension. If token is of type |
| ScMatrixCellResultToken uses the |
| appropriate Assign() call, other tokens |
| are assigned to xUpperLeft and xMatrix will |
| be assigned NULL. */ |
| void Assign( const formula::FormulaToken & r ); |
| |
| /** Modify xUpperLeft if formula::svDouble, or create |
| new formula::FormulaDoubleToken if not set yet. Does |
| nothing if xUpperLeft is of different type! */ |
| void SetUpperLeftDouble( double f); |
| |
| /** Reset matrix and upper left, keep matrix |
| formula dimension. */ |
| void ResetResult() |
| { |
| xMatrix = NULL; |
| xUpperLeft = NULL; |
| } |
| }; |
| |
| |
| class SC_DLLPUBLIC ScHybridCellToken : public ScToken |
| { |
| private: |
| double fDouble; |
| String aString; |
| String aFormula; |
| public: |
| ScHybridCellToken( double f, |
| const String & rStr, |
| const String & rFormula ) : |
| ScToken( formula::svHybridCell ), |
| fDouble( f ), aString( rStr ), |
| aFormula( rFormula ) {} |
| ScHybridCellToken( const ScHybridCellToken& r ) : |
| ScToken( r ), fDouble( r.fDouble), |
| aString( r.aString), aFormula( r.aFormula) {} |
| const String & GetFormula() const { return aFormula; } |
| virtual double GetDouble() const; |
| virtual const String & GetString() const; |
| virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; |
| virtual FormulaToken* Clone() const { return new ScHybridCellToken(*this); } |
| }; |
| |
| |
| // Simplify argument passing to RefUpdate methods with ScSingleRefToken or |
| // ScDoubleRefToken |
| class SingleDoubleRefModifier |
| { |
| ScComplexRefData aDub; |
| ScSingleRefData* pS; |
| ScComplexRefData* pD; |
| |
| // not implemented, prevent usage |
| SingleDoubleRefModifier( const SingleDoubleRefModifier& ); |
| SingleDoubleRefModifier& operator=( const SingleDoubleRefModifier& ); |
| |
| public: |
| SingleDoubleRefModifier( ScToken& rT ) |
| { |
| if ( rT.GetType() == formula::svSingleRef ) |
| { |
| pS = &rT.GetSingleRef(); |
| aDub.Ref1 = aDub.Ref2 = *pS; |
| pD = &aDub; |
| } |
| else |
| { |
| pS = 0; |
| pD = &rT.GetDoubleRef(); |
| } |
| } |
| SingleDoubleRefModifier( ScSingleRefData& rS ) |
| { |
| pS = &rS; |
| aDub.Ref1 = aDub.Ref2 = *pS; |
| pD = &aDub; |
| } |
| ~SingleDoubleRefModifier() |
| { |
| if ( pS ) |
| *pS = (*pD).Ref1; |
| } |
| inline ScComplexRefData& Ref() { return *pD; } |
| }; |
| |
| class SingleDoubleRefProvider |
| { |
| public: |
| |
| const ScSingleRefData& Ref1; |
| const ScSingleRefData& Ref2; |
| |
| SingleDoubleRefProvider( const ScToken& r ) |
| : Ref1( r.GetSingleRef() ), |
| Ref2( r.GetType() == formula::svDoubleRef ? |
| r.GetDoubleRef().Ref2 : Ref1 ) |
| {} |
| SingleDoubleRefProvider( const ScSingleRefData& r ) |
| : Ref1( r ), Ref2( r ) |
| {} |
| SingleDoubleRefProvider( const ScComplexRefData& r ) |
| : Ref1( r.Ref1 ), Ref2( r.Ref2 ) |
| {} |
| ~SingleDoubleRefProvider() |
| {} |
| }; |
| |
| #endif |