diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2009-01-08 10:47:13 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2009-01-08 10:47:13 +0000 |
commit | 2cb4c646a81c92d7582c0db6eedeb09128ace1c5 (patch) | |
tree | 4a0a18f27da908aa4507a8fd6cde5d99eb97635d /formula/source | |
parent | 0c14679312da5bc50a3be71d39a5032b24887155 (diff) |
CWS-TOOLING: integrate CWS frmdlg
2008-12-18 09:13:09 +0100 oj r265667 : merge from odff05
2008-12-18 07:58:16 +0100 oj r265658 : #i94555# patch from <regina>, ODFF:
Add GAMMA, CHISQDIST, CHISQINV.
Make the 'cumulative' parameter of GAMMADIST optional.
Adapt the domain of CHIDIST to allow negative x.
Remove the constraint "degrees of freedom < 1.0E5" from CHIDIST and CHIINV.
Plus a mechanism to write the now optional parameter of GAMMADIST to PODF and
ODFF if omitted, for backwards compatibility.
2008-12-15 14:06:11 +0100 oj r265490 : CWS-TOOLING: rebase CWS frmdlg to trunk@264807 (milestone: DEV300:m37)
2008-12-15 13:55:28 +0100 oj r265488 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 13:55:07 +0100 oj r265487 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 13:54:48 +0100 oj r265486 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 13:54:36 +0100 oj r265485 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 13:54:24 +0100 oj r265484 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 13:48:11 +0100 oj r265483 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 13:31:12 +0100 oj r265479 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 13:13:58 +0100 oj r265477 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 13:10:09 +0100 oj r265476 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 13:05:11 +0100 oj r265475 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 10:47:17 +0100 oj r265467 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 10:46:19 +0100 oj r265466 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 10:45:47 +0100 oj r265465 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C'
CWS: frmdlg
New MWS: DEV300
New milestone: m37
2008-12-15 07:35:07 +0100 oj r265458 : add dependency to formula
2008-12-15 07:34:24 +0100 oj r265457 : add dependency to formula
2008-12-12 13:22:00 +0100 msc r265413 : #i97089#
2008-12-12 13:20:25 +0100 msc r265412 : #i97089#
2008-12-12 12:35:12 +0100 msc r265406 : #i97089#
2008-12-12 12:34:16 +0100 msc r265405 : #i97089#
2008-12-12 12:33:05 +0100 msc r265404 : #i97089#
2008-12-12 12:31:11 +0100 msc r265403 : #i97089#
2008-12-08 11:59:10 +0100 oj r264981 : insert RTL_LOG
2008-12-08 11:50:17 +0100 oj r264980 : some small changes
2008-12-05 12:57:57 +0100 oj r264902 : eof changed
2008-12-05 12:56:46 +0100 oj r264901 : eof changed
2008-12-05 12:28:47 +0100 oj r264899 : wrong var used
2008-12-05 10:08:57 +0100 oj r264890 : token order reversed
2008-12-04 13:49:22 +0100 oc r264843 : #i96688: Adapt autotests because of outsourced functionwizard
2008-12-04 13:45:27 +0100 oc r264842 : #i96688: Adapt autotests because of outsourced functionwizard
2008-12-04 13:42:54 +0100 oc r264841 : #i96688: Adapt autotests because of outsourced functionwizard
2008-12-04 13:37:41 +0100 oc r264840 : #i96688: Adapt autotests because of outsourced functionwizard
2008-12-04 13:34:11 +0100 oc r264839 : #i96688: Adapt autotests because of outsourced functionwizard
2008-12-04 12:35:31 +0100 oj r264835 : new help ids for struct and function tabpage
2008-12-04 12:00:35 +0100 oj r264828 : set explicit help id
2008-12-03 14:53:27 +0100 oj r264786 : #i96845# change ref button
2008-12-03 14:51:49 +0100 oj r264785 : #i96845# change ref button
2008-12-03 08:51:57 +0100 oj r264746 : convert dos to unix lineends
2008-12-03 08:50:45 +0100 oj r264745 : convert dos to unix lineends
2008-12-03 08:50:05 +0100 oj r264744 : convert dos to unix lineends
2008-12-02 12:28:33 +0100 oj r264686 : clear help text when new helpid is set
2008-12-02 12:28:02 +0100 oj r264685 : set help id for listbox category
2008-12-02 07:15:56 +0100 oj r264655 : remove define to auto generate help ids
2008-12-01 14:36:43 +0100 oj r264604 : use temp var
2008-12-01 14:18:31 +0100 oj r264601 : moved ScJumpToken to formula
2008-12-01 14:18:11 +0100 oj r264600 : moved ScJumpToken to formula
2008-12-01 14:14:35 +0100 oj r264599 : moved ScJumpToken from sc
2008-12-01 10:48:51 +0100 oj r264589 : change quickhelptext from Shrink to Select
2008-12-01 10:28:41 +0100 oj r264588 : fix opcode data, has to be Any.Void
2008-11-28 11:16:48 +0100 oj r264532 : add help ids
2008-11-28 10:16:56 +0100 oj r264529 : set help id
2008-11-28 10:16:43 +0100 oj r264528 : set help id
2008-11-26 13:55:04 +0100 oj r264381 : #94535# use of optional instead of deleting a string myself and some small changes
2008-11-26 09:53:20 +0100 oj r264346 : compile error with debug/without debug
2008-11-25 07:41:28 +0100 oj r264271 : put static into the method which make use of them
2008-11-24 08:16:07 +0100 oj r264196 : removed not needed classes for op code
2008-11-24 08:13:44 +0100 oj r264195 : removed not needed classes for op code
2008-11-21 14:05:53 +0100 oj r264135 : make GetOpCode inline
2008-11-21 12:35:27 +0100 oj r264124 : hold symbols
2008-11-20 09:27:27 +0100 oj r264028 : merged code from DEV300_m35 which got lost
2008-11-19 20:42:12 +0100 oj r264022 : more changes for formula dialog remove
2008-11-19 20:37:41 +0100 oj r264021 : removed unused var
2008-11-19 20:35:35 +0100 oj r264020 : some more changes at token
2008-11-19 10:59:47 +0100 oj r263967 : deleted
2008-11-19 10:58:24 +0100 oj r263966 : add forui and for res files
2008-11-18 15:27:36 +0100 oj r263777 : unused para removed
2008-11-18 15:23:23 +0100 oj r263775 : add insert button to add field dlg
2008-11-18 13:39:53 +0100 oj r263764 : enable the formula dialog as well for conditional print as for conditional formatting
2008-11-18 12:03:25 +0100 oj r263760 : rename isRef in IsRef
2008-11-17 11:46:16 +0100 oj r263711 : patches for function handling
2008-11-17 11:36:22 +0100 oj r263710 : add new for forui and res file
2008-11-17 09:21:12 +0100 oj r263704 : patches for some resource for libformula
2008-11-15 12:45:30 +0100 oj r263701 : changes for formula editor extraction
2008-11-07 08:23:27 +0100 oj r263416 : merge from DEV300:m35
2008-11-07 08:22:35 +0100 oj r263415 : merge from DEV300:m35
2008-11-07 08:22:16 +0100 oj r263414 : merge from DEV300:m35
2008-11-07 08:21:41 +0100 oj r263413 : merge from DEV300:m35
2008-11-07 08:21:31 +0100 oj r263412 : merge from DEV300:m35
2008-11-07 08:20:38 +0100 oj r263411 : merge from DEV300:m35
2008-11-07 08:20:00 +0100 oj r263410 : merge from DEV300:m35
2008-11-07 08:18:50 +0100 oj r263409 : merge from DEV300:m35
2008-11-07 08:18:19 +0100 oj r263408 : merge from DEV300:m35
2008-11-07 08:10:27 +0100 oj r263407 : merge from DEV300:m35
2008-10-21 07:43:46 +0200 oj r262560 : some compile errors resolved
2008-10-17 16:40:01 +0200 oj r262291 : dep for 1st target
2008-10-07 10:08:39 +0200 oj r262077 : copy
2008-10-07 09:45:31 +0200 oj r262076 : #i94535#
2008-10-07 09:44:26 +0200 oj r262075 : #i94535# new base class
2008-10-07 09:43:21 +0200 oj r262074 : moved to formula
2008-10-07 09:41:51 +0200 oj r262073 : new images
2008-10-07 09:03:01 +0200 oj r262072 : new ids for formula
2008-10-02 08:46:27 +0200 oj r262024 : #i94535# move the formula compiler to formula
2008-10-02 08:08:54 +0200 oj r262023 : #i94535#
2008-10-02 08:06:28 +0200 oj r262022 : #i94535#
2008-10-02 08:05:52 +0200 oj r262021 : #i94535#
2008-10-01 17:15:29 +0200 oj r262014 : #i94535#
2008-10-01 17:12:40 +0200 oj r262013 : new module formula
2008-10-01 17:04:55 +0200 oj r262012 : #i94535#
2008-10-01 16:49:03 +0200 oj r262010 : #i94535#
2008-10-01 16:46:59 +0200 oj r262009 : #i94535#
Diffstat (limited to 'formula/source')
29 files changed, 12436 insertions, 0 deletions
diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx new file mode 100644 index 000000000000..49b60c663d0e --- /dev/null +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -0,0 +1,1837 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tokenuno.hxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "precompiled_formula.hxx" +#include "formula/FormulaCompiler.hxx" +#include "formula/errorcodes.hxx" +#include "formula/token.hxx" +#include "formula/tokenarray.hxx" +#include "core_resource.hxx" +#include "core_resource.hrc" + +#include <svtools/zforlist.hxx> +#include <tools/rc.hxx> +#include <tools/rcid.h> +#include <com/sun/star/sheet/FormulaOpCodeMapEntry.hpp> +#include <com/sun/star/sheet/FormulaMapGroup.hpp> +#include <com/sun/star/sheet/FormulaMapGroupSpecialOffset.hpp> +#include <stdio.h> + +// ============================================================================= +namespace formula +{ +// ============================================================================= + using namespace ::com::sun::star; + + static const sal_Char* pInternal[ 5 ] = { "GAME", "SPEW", "TTT", "STARCALCTEAM", "ANTWORT" }; + +// ============================================================================= +namespace +{ +// ============================================================================= +class FormulaCompilerRecursionGuard +{ +private: + short& rRecursion; +public: + FormulaCompilerRecursionGuard( short& rRec ) + : rRecursion( rRec ) { ++rRecursion; } + ~FormulaCompilerRecursionGuard() { --rRecursion; } +}; + +short lcl_GetRetFormat( OpCode eOpCode ) +{ + switch (eOpCode) + { + case ocEqual: + case ocNotEqual: + case ocLess: + case ocGreater: + case ocLessEqual: + case ocGreaterEqual: + case ocAnd: + case ocOr: + case ocNot: + case ocTrue: + case ocFalse: + case ocIsEmpty: + case ocIsString: + case ocIsNonString: + case ocIsLogical: + case ocIsRef: + case ocIsValue: + case ocIsFormula: + case ocIsNA: + case ocIsErr: + case ocIsError: + case ocIsEven: + case ocIsOdd: + case ocExact: + return NUMBERFORMAT_LOGICAL; + case ocGetActDate: + case ocGetDate: + case ocEasterSunday : + return NUMBERFORMAT_DATE; + case ocGetActTime: + return NUMBERFORMAT_DATETIME; + case ocGetTime: + return NUMBERFORMAT_TIME; + case ocNPV: + case ocBW: + case ocDIA: + case ocGDA: + case ocGDA2: + case ocVBD: + case ocLIA: + case ocRMZ: + case ocZW: + case ocZinsZ: + case ocKapz: + case ocKumZinsZ: + case ocKumKapZ: + return NUMBERFORMAT_CURRENCY; + case ocZins: + case ocIRR: + case ocMIRR: + case ocZGZ: + case ocEffektiv: + case ocNominal: + case ocPercentSign: + return NUMBERFORMAT_PERCENT; +// case ocSum: +// case ocSumSQ: +// case ocProduct: +// case ocAverage: +// return -1; + default: + return NUMBERFORMAT_NUMBER; + } + return NUMBERFORMAT_NUMBER; +} + +inline void lclPushOpCodeMapEntry( ::std::vector< sheet::FormulaOpCodeMapEntry >& rVec, const String* pTable, USHORT nOpCode ) +{ + sheet::FormulaOpCodeMapEntry aEntry; + aEntry.Token.OpCode = nOpCode; + aEntry.Name = pTable[nOpCode]; + rVec.push_back( aEntry); +} + +void lclPushOpCodeMapEntries( ::std::vector< sheet::FormulaOpCodeMapEntry >& rVec, const String* pTable, USHORT nOpCodeBeg, USHORT nOpCodeEnd ) +{ + for (USHORT nOpCode = nOpCodeBeg; nOpCode < nOpCodeEnd; ++nOpCode) + lclPushOpCodeMapEntry( rVec, pTable, nOpCode ); +} + +void lclPushOpCodeMapEntries( ::std::vector< sheet::FormulaOpCodeMapEntry >& rVec, const String* pTable, const USHORT* pnOpCodes, size_t nCount ) +{ + for (const USHORT* pnEnd = pnOpCodes + nCount; pnOpCodes < pnEnd; ++pnOpCodes) + lclPushOpCodeMapEntry( rVec, pTable, *pnOpCodes ); +} + +class OpCodeList : public Resource // temp object for resource +{ +public: + + OpCodeList( USHORT, FormulaCompiler::NonConstOpCodeMapPtr ); + +private: + bool getOpCodeString( String& rStr, USHORT nOp ); + void putDefaultOpCode( FormulaCompiler::NonConstOpCodeMapPtr xMap, USHORT nOp ); + +private: + enum SeparatorType + { + SEMICOLON_BASE, + COMMA_BASE + }; + SeparatorType meSepType; +}; + +OpCodeList::OpCodeList( USHORT nRID, FormulaCompiler::NonConstOpCodeMapPtr xMap ) : + Resource( ResId(nRID,*ResourceManager::getResManager()) ) + ,meSepType(SEMICOLON_BASE) +{ + for (USHORT i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; ++i) + { + String aOpStr; + if ( getOpCodeString(aOpStr, i) ) + xMap->putOpCode(aOpStr, OpCode(i)); + else + putDefaultOpCode(xMap, i); + } + + FreeResource(); +} + +bool OpCodeList::getOpCodeString( String& rStr, USHORT nOp ) +{ + switch (nOp) + { + case SC_OPCODE_SEP: + { + if (meSepType == COMMA_BASE) + { + rStr = String::CreateFromAscii(","); + return true; + } + else if (meSepType == SEMICOLON_BASE) + { + rStr = String::CreateFromAscii(";"); + return true; + } + } + break; + case SC_OPCODE_ARRAY_COL_SEP: + { + if (meSepType == COMMA_BASE) + { + rStr = String::CreateFromAscii(","); + return true; + } + else if (meSepType == SEMICOLON_BASE) + { + rStr = String::CreateFromAscii(";"); + return true; + } + } + break; + case SC_OPCODE_ARRAY_ROW_SEP: + { + if (meSepType == COMMA_BASE) + { + rStr = String::CreateFromAscii(";"); + return true; + } + else if (meSepType == SEMICOLON_BASE) + { + rStr = String::CreateFromAscii("|"); + return true; + } + } + break; + } + + return false; +} + +void OpCodeList::putDefaultOpCode( FormulaCompiler::NonConstOpCodeMapPtr xMap, USHORT nOp ) +{ + ResId aRes(nOp,*ResourceManager::getResManager()); + aRes.SetRT(RSC_STRING); + if (IsAvailableRes(aRes)) + xMap->putOpCode(aRes, OpCode(nOp)); +} +// ----------------------------------------------------------------------------- +// static +const sal_Unicode* lcl_UnicodeStrChr( const sal_Unicode* pStr,sal_Unicode c ) +{ + if ( !pStr ) + return NULL; + while ( *pStr ) + { + if ( *pStr == c ) + return pStr; + pStr++; + } + return NULL; +} +// ============================================================================= +} // empty +// ============================================================================= + +void FormulaCompiler::OpCodeMap::putExternal( const String & rSymbol, const String & rAddIn ) +{ + bool bOk = mpExternalHashMap->insert( ExternalHashMap::value_type( rSymbol, rAddIn)).second; + if (bOk) + bOk = mpReverseExternalHashMap->insert( ExternalHashMap::value_type( rAddIn, rSymbol)).second; + DBG_ASSERT( bOk, "OpCodeMap::putExternal: symbol not inserted"); +} + +void FormulaCompiler::OpCodeMap::putExternalSoftly( const String & rSymbol, const String & rAddIn ) +{ + bool bOk = mpReverseExternalHashMap->insert( ExternalHashMap::value_type( rAddIn, rSymbol)).second; + if (bOk) + mpExternalHashMap->insert( ExternalHashMap::value_type( rSymbol, rAddIn)).second; +} +uno::Sequence< sheet::FormulaToken > FormulaCompiler::OpCodeMap::createSequenceOfFormulaTokens(const FormulaCompiler& _rCompiler,const uno::Sequence< ::rtl::OUString >& rNames ) const +{ + const sal_Int32 nLen = rNames.getLength(); + uno::Sequence< sheet::FormulaToken > aTokens( nLen); + sheet::FormulaToken* pToken = aTokens.getArray(); + ::rtl::OUString const * pName = rNames.getConstArray(); + ::rtl::OUString const * const pStop = pName + nLen; + for ( ; pName < pStop; ++pName, ++pToken) + { + OpCodeHashMap::const_iterator iLook( mpHashMap->find( *pName)); + if (iLook != mpHashMap->end()) + pToken->OpCode = (*iLook).second; + else + { + ::rtl::OUString aIntName; + if (hasExternals()) + { + ExternalHashMap::const_iterator iExt( mpExternalHashMap->find( *pName)); + if (iExt != mpExternalHashMap->end()) + aIntName = (*iExt).second; + // Check for existence not needed here, only name-mapping is of + // interest. + } + if (!aIntName.getLength()) + aIntName = _rCompiler.FindAddInFunction(*pName, !isEnglish()); // bLocalFirst=FALSE for english + if (!aIntName.getLength()) + pToken->OpCode = getOpCodeUnknown(); + else + { + pToken->OpCode = ocExternal; + pToken->Data <<= aIntName; + } + } + } + return aTokens; +} +uno::Sequence< sheet::FormulaOpCodeMapEntry > FormulaCompiler::OpCodeMap::createSequenceOfAvailableMappings(const FormulaCompiler& _rCompiler,const sal_Int32 nGroups ) const +{ + using namespace sheet; + + // Unfortunately uno::Sequence can't grow without cumbersome reallocs. As + // we don't know in advance how many elements it will have we use a + // temporary vector to add elements and then copy to Sequence :-( + ::std::vector< FormulaOpCodeMapEntry > aVec; + + if (nGroups == FormulaMapGroup::SPECIAL) + { + // Use specific order, keep in sync with + // offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl + static const struct + { + sal_Int32 nOff; + OpCode eOp; + } aMap[] = { + { FormulaMapGroupSpecialOffset::PUSH , ocPush } , + { FormulaMapGroupSpecialOffset::CALL , ocCall } , + { FormulaMapGroupSpecialOffset::STOP , ocStop } , + { FormulaMapGroupSpecialOffset::EXTERNAL , ocExternal } , + { FormulaMapGroupSpecialOffset::NAME , ocName } , + { FormulaMapGroupSpecialOffset::NO_NAME , ocNoName } , + { FormulaMapGroupSpecialOffset::MISSING , ocMissing } , + { FormulaMapGroupSpecialOffset::BAD , ocBad } , + { FormulaMapGroupSpecialOffset::SPACES , ocSpaces } , + { FormulaMapGroupSpecialOffset::MAT_REF , ocMatRef } , + { FormulaMapGroupSpecialOffset::DB_AREA , ocDBArea } , + { FormulaMapGroupSpecialOffset::MACRO , ocMacro } , + { FormulaMapGroupSpecialOffset::COL_ROW_NAME , ocColRowName } , + { FormulaMapGroupSpecialOffset::COL_ROW_NAME_AUTO , ocColRowNameAuto } + }; + const size_t nCount = sizeof(aMap)/sizeof(aMap[0]); + // Preallocate vector elements. + if (aVec.size() < nCount) + { + FormulaOpCodeMapEntry aEntry; + aEntry.Token.OpCode = getOpCodeUnknown(); + aVec.resize( nCount, aEntry); + } // if (aVec.size() < nCount) + + FormulaOpCodeMapEntry aEntry; + for (size_t i=0; i < nCount; ++i) + { + size_t nIndex = static_cast< size_t >( aMap[i].nOff ); + if (aVec.size() <= nIndex) + { + // The offsets really should be aligned with the size, so if + // the vector was preallocated above this code to resize it is + // just a measure in case the table isn't in sync with the API, + // usually it isn't executed. + aEntry.Token.OpCode = getOpCodeUnknown(); + aVec.resize( nIndex + 1, aEntry ); + } + aEntry.Token.OpCode = aMap[i].eOp; + aVec[nIndex] = aEntry; + } + } + else + { + /* FIXME: Once we support error constants in formulas we'll need a map + * group for that, e.g. FormulaMapGroup::ERROR_CONSTANTS, and fill + * SC_OPCODE_START_ERRORS to SC_OPCODE_STOP_ERRORS. */ + + // Anything else but SPECIAL. + if ((nGroups & FormulaMapGroup::SEPARATORS) != 0) + { + static const USHORT aOpCodes[] = { + SC_OPCODE_OPEN, + SC_OPCODE_CLOSE, + SC_OPCODE_SEP, + }; + lclPushOpCodeMapEntries( aVec, mpTable, aOpCodes, sizeof(aOpCodes)/sizeof(aOpCodes[0]) ); + } + if ((nGroups & FormulaMapGroup::ARRAY_SEPARATORS) != 0) + { + static const USHORT aOpCodes[] = { + SC_OPCODE_ARRAY_OPEN, + SC_OPCODE_ARRAY_CLOSE, + SC_OPCODE_ARRAY_ROW_SEP, + SC_OPCODE_ARRAY_COL_SEP + }; + lclPushOpCodeMapEntries( aVec, mpTable, aOpCodes, sizeof(aOpCodes)/sizeof(aOpCodes[0]) ); + } + if ((nGroups & FormulaMapGroup::UNARY_OPERATORS) != 0) + { + // Due to the nature of the percent operator following its operand + // it isn't sorted into unary operators for compiler interna. + lclPushOpCodeMapEntry( aVec, mpTable, ocPercentSign ); + // "+" can be used as unary operator too, push only if binary group is not set + if ((nGroups & FormulaMapGroup::BINARY_OPERATORS) == 0) + lclPushOpCodeMapEntry( aVec, mpTable, ocAdd ); + // regular unary operators + for (USHORT nOp = SC_OPCODE_START_UN_OP; nOp < SC_OPCODE_STOP_UN_OP && nOp < mnSymbols; ++nOp) + { + switch (nOp) + { + // NOT and NEG in fact are functions but for legacy reasons + // are sorted into unary operators for compiler interna. + case SC_OPCODE_NOT : + case SC_OPCODE_NEG : + break; // nothing, + default: + lclPushOpCodeMapEntry( aVec, mpTable, nOp ); + } + } + } + if ((nGroups & FormulaMapGroup::BINARY_OPERATORS) != 0) + { + for (USHORT nOp = SC_OPCODE_START_BIN_OP; nOp < SC_OPCODE_STOP_BIN_OP && nOp < mnSymbols; ++nOp) + { + switch (nOp) + { + // AND and OR in fact are functions but for legacy reasons + // are sorted into binary operators for compiler interna. + case SC_OPCODE_AND : + case SC_OPCODE_OR : + break; // nothing, + default: + lclPushOpCodeMapEntry( aVec, mpTable, nOp ); + } + } + } + if ((nGroups & FormulaMapGroup::FUNCTIONS) != 0) + { + // Function names are not consecutive, skip the gaps between + // functions with no parameter, functions with 1 parameter + lclPushOpCodeMapEntries( aVec, mpTable, SC_OPCODE_START_NO_PAR, ::std::min< USHORT >( SC_OPCODE_STOP_NO_PAR, mnSymbols ) ); + lclPushOpCodeMapEntries( aVec, mpTable, SC_OPCODE_START_1_PAR, ::std::min< USHORT >( SC_OPCODE_STOP_1_PAR, mnSymbols ) ); + // Additional functions not within range of functions. + static const USHORT aOpCodes[] = { + SC_OPCODE_IF, + SC_OPCODE_CHOSE, + SC_OPCODE_AND, + SC_OPCODE_OR, + SC_OPCODE_NOT, + SC_OPCODE_NEG + }; + lclPushOpCodeMapEntries( aVec, mpTable, aOpCodes, sizeof(aOpCodes)/sizeof(aOpCodes[0]) ); + // functions with 2 or more parameters. + for (USHORT nOp = SC_OPCODE_START_2_PAR; nOp < SC_OPCODE_STOP_2_PAR && nOp < mnSymbols; ++nOp) + { + switch (nOp) + { + // NO_NAME is in SPECIAL. + case SC_OPCODE_NO_NAME : + break; // nothing, + default: + lclPushOpCodeMapEntry( aVec, mpTable, nOp ); + } + } + // If AddIn functions are present in this mapping, use them, and only those. + if (hasExternals()) + { + for (ExternalHashMap::const_iterator it( mpExternalHashMap->begin());it != mpExternalHashMap->end(); ++it) + { + FormulaOpCodeMapEntry aEntry; + aEntry.Name = (*it).first; + aEntry.Token.Data <<= ::rtl::OUString( (*it).second); + aEntry.Token.OpCode = ocExternal; + aVec.push_back( aEntry); + } + } + else + { + //DBG_ASSERT( isCore(), "FormulaCompiler::OpCodeMap::createSequenceOfAvailableMappings: AddIn mapping from collection only implemented for core languages"); + _rCompiler.fillAddInToken(aVec,isEnglish()); + } + } + } + const FormulaOpCodeMapEntry* pRet = aVec.empty() ? 0 : &aVec[0]; + return uno::Sequence< FormulaOpCodeMapEntry >(pRet, aVec.size()); +} +//----------------------------------------------------------------------------- + +void FormulaCompiler::OpCodeMap::putOpCode( const String & rStr, const OpCode eOp ) +{ + DBG_ASSERT( 0 < eOp && USHORT(eOp) < mnSymbols, "OpCodeMap::putOpCode: OpCode out of range"); + if (0 < eOp && USHORT(eOp) < mnSymbols) + { + DBG_ASSERT( (mpTable[eOp].Len() == 0) || (mpTable[eOp] == rStr), + ByteString( "OpCodeMap::putOpCode: reusing OpCode "). + Append( ByteString::CreateFromInt32( sal_Int32( eOp))).Append( " ("). + Append( ByteString( rStr, RTL_TEXTENCODING_ASCII_US)).Append( ')').GetBuffer()); + mpTable[eOp] = rStr; + mpHashMap->insert( OpCodeHashMap::value_type( rStr, eOp)); + } +} +// ----------------------------------------------------------------------------- +// class FormulaCompiler +// ----------------------------------------------------------------------------- +DBG_NAME(FormulaCompiler) +FormulaCompiler::FormulaCompiler(FormulaTokenArray& _rArr) + : + pArr( &_rArr ), + pStack( NULL ), + nRecursion(0), + nNumFmt( NUMBERFORMAT_UNDEFINED ), + meGrammar( formula::FormulaGrammar::GRAM_UNSPECIFIED ), + bAutoCorrect( FALSE ), + bCorrected( FALSE ), + bCompileForFAP( FALSE ), + bIgnoreErrors( FALSE ) + +{ + DBG_CTOR(FormulaCompiler,NULL); +} +FormulaCompiler::FormulaCompiler() + : + pArr( NULL ), + pStack( NULL ), + nRecursion(0), + nNumFmt( NUMBERFORMAT_UNDEFINED ), + meGrammar( formula::FormulaGrammar::GRAM_UNSPECIFIED ), + bAutoCorrect( FALSE ), + bCorrected( FALSE ), + bCompileForFAP( FALSE ), + bIgnoreErrors( FALSE ) + +{ + DBG_CTOR(FormulaCompiler,NULL); +} +FormulaCompiler::~FormulaCompiler() +{ + DBG_DTOR(FormulaCompiler,NULL); +} + +FormulaCompiler::OpCodeMapPtr FormulaCompiler::GetOpCodeMap( const sal_Int32 nLanguage ) const +{ + FormulaCompiler::OpCodeMapPtr xMap; + using namespace sheet; + switch (nLanguage) + { + case FormulaLanguage::ODFF : + if (!mxSymbolsODFF) + InitSymbolsODFF(); + xMap = mxSymbolsODFF; + break; + case FormulaLanguage::ODF_11 : + if (!mxSymbolsPODF) + InitSymbolsPODF(); + xMap = mxSymbolsPODF; + break; + case FormulaLanguage::ENGLISH : + if (!mxSymbolsEnglish) + InitSymbolsEnglish(); + xMap = mxSymbolsEnglish; + break; + case FormulaLanguage::NATIVE : + if (!mxSymbolsNative) + InitSymbolsNative(); + xMap = mxSymbolsNative; + break; + default: + ; // nothing, NULL map returned + } + return xMap; +} +// ----------------------------------------------------------------------------- + +String FormulaCompiler::FindAddInFunction( const String& /*rUpperName*/, BOOL /*bLocalFirst*/ ) const +{ + return String(); +} +// ----------------------------------------------------------------------------- +FormulaCompiler::OpCodeMapPtr FormulaCompiler::CreateOpCodeMap( + const uno::Sequence< + const sheet::FormulaOpCodeMapEntry > & rMapping, + bool bEnglish ) +{ + using sheet::FormulaOpCodeMapEntry; + // Filter / API maps are never Core + NonConstOpCodeMapPtr xMap( new OpCodeMap( SC_OPCODE_LAST_OPCODE_ID + 1,false, FormulaGrammar::mergeToGrammar( FormulaGrammar::setEnglishBit(FormulaGrammar::GRAM_EXTERNAL, bEnglish),FormulaGrammar::CONV_UNSPECIFIED))); + FormulaOpCodeMapEntry const * pArr2 = rMapping.getConstArray(); + FormulaOpCodeMapEntry const * const pStop = pArr2 + rMapping.getLength(); + for ( ; pArr2 < pStop; ++pArr2) + { + OpCode eOp = OpCode(pArr2->Token.OpCode); + if (eOp != ocExternal) + xMap->putOpCode( pArr2->Name, eOp); + else + { + ::rtl::OUString aExternalName; + if (pArr2->Token.Data >>= aExternalName) + xMap->putExternal( pArr2->Name, aExternalName); + else + { + DBG_ERRORFILE( "FormulaCompiler::CreateOpCodeMap: no Token.Data external name"); + } + } + } + return xMap; +} + +// ----------------------------------------------------------------------------- +void lcl_fillNativeSymbols(FormulaCompiler::NonConstOpCodeMapPtr& _xMap,bool _destroy = false) +{ + static FormulaCompiler::NonConstOpCodeMapPtr s_SymbolMap; + if ( _destroy ) + { + s_SymbolMap.reset(); + } // if ( _destroy ) + else if ( !s_SymbolMap.get() ) + { + // Core + s_SymbolMap.reset( new FormulaCompiler::OpCodeMap( SC_OPCODE_LAST_OPCODE_ID + 1, true, FormulaGrammar::GRAM_NATIVE_UI)); + OModuleClient aModuleClient; + OpCodeList aOpCodeListNative( RID_STRLIST_FUNCTION_NAMES, s_SymbolMap ); + // No AddInMap for native core mapping. + } // if ( !s_SymbolMap.get() ) + _xMap = s_SymbolMap; +} +// ----------------------------------------------------------------------------- +const String& FormulaCompiler::GetNativeSymbol( OpCode eOp ) +{ + NonConstOpCodeMapPtr xSymbolsNative; + lcl_fillNativeSymbols(xSymbolsNative); + return xSymbolsNative->getSymbol( eOp ); +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::InitSymbolsNative() const +{ + if (mxSymbolsNative.get()) + return; + //! Experimental! + // Use English function names and separators instead of native in UI. + static const sal_Char aEnvVarName[] = "OOO_CALC_USE_ENGLISH_FORMULAS"; + const char* pEnv = getenv( aEnvVarName); + if (pEnv && (*pEnv == 'Y' || *pEnv == 'y' || *pEnv == '1') ) + { + fprintf( stderr, "%s=%s => UI uses English function names and separators in formulas.\n", + aEnvVarName, pEnv); + InitSymbolsEnglish(); + mxSymbolsNative = mxSymbolsEnglish; + return; + } + static NonConstOpCodeMapPtr s_sSymbol; + if ( !s_sSymbol.get() ) + lcl_fillNativeSymbols(s_sSymbol); + mxSymbolsNative = s_sSymbol; +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::InitSymbolsEnglish() const +{ + static NonConstOpCodeMapPtr s_sSymbol; + if ( !s_sSymbol.get() ) + loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH,FormulaGrammar::GRAM_ENGLISH,s_sSymbol); + mxSymbolsEnglish = s_sSymbol; +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::InitSymbolsPODF() const +{ + static NonConstOpCodeMapPtr s_sSymbol; + if ( !s_sSymbol.get() ) + loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH,FormulaGrammar::GRAM_PODF,s_sSymbol); + mxSymbolsPODF = s_sSymbol; +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::InitSymbolsODFF() const +{ + static NonConstOpCodeMapPtr s_sSymbol; + if ( !s_sSymbol.get() ) + loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF,FormulaGrammar::GRAM_ODFF,s_sSymbol); + mxSymbolsODFF = s_sSymbol; +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::loadSymbols(USHORT _nSymbols,FormulaGrammar::Grammar _eGrammar,NonConstOpCodeMapPtr& _xMap) const +{ + if ( !_xMap.get() ) + { + // not Core + _xMap.reset( new OpCodeMap( SC_OPCODE_LAST_OPCODE_ID + 1, _eGrammar != FormulaGrammar::GRAM_ODFF, _eGrammar )); + OModuleClient aModuleClient; + OpCodeList aOpCodeList( _nSymbols, _xMap ); + + fillFromAddInMap( _xMap, _eGrammar); + // Fill from collection for AddIns not already present. + if ( FormulaGrammar::GRAM_ENGLISH != _eGrammar ) + fillFromAddInCollectionUpperName( _xMap); + else + fillFromAddInCollectionEnglishName( mxSymbolsEnglish); + } +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::fillFromAddInCollectionUpperName( NonConstOpCodeMapPtr /*xMap */) const +{ +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::fillFromAddInCollectionEnglishName( NonConstOpCodeMapPtr /*xMap */) const +{ +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::fillFromAddInMap( NonConstOpCodeMapPtr /*xMap*/, FormulaGrammar::Grammar /*_eGrammar */) const +{ +} +// ----------------------------------------------------------------------------- +OpCode FormulaCompiler::GetEnglishOpCode( const String& rName ) const +{ + FormulaCompiler::OpCodeMapPtr xMap = GetOpCodeMap(sheet::FormulaLanguage::ENGLISH); + + formula::OpCodeHashMap::const_iterator iLook( xMap->getHashMap()->find( rName ) ); + bool bFound = (iLook != xMap->getHashMap()->end()); + return bFound ? (*iLook).second : OpCode(ocNone); +} + +// Remove quotes, escaped quotes are unescaped. +BOOL FormulaCompiler::DeQuote( String& rStr ) +{ + xub_StrLen nLen = rStr.Len(); + if ( nLen > 1 && rStr.GetChar(0) == '\'' && rStr.GetChar( nLen-1 ) == '\'' ) + { + rStr.Erase( nLen-1, 1 ); + rStr.Erase( 0, 1 ); + xub_StrLen nPos = 0; + while ( (nPos = rStr.SearchAscii( "\\\'", nPos)) != STRING_NOTFOUND ) + { + rStr.Erase( nPos, 1 ); + ++nPos; + } + return TRUE; + } + return FALSE; +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::fillAddInToken(::std::vector< sheet::FormulaOpCodeMapEntry >& /*_rVec*/,bool /*_bIsEnglish*/) const +{ +} +// ----------------------------------------------------------------------------- +BOOL FormulaCompiler::IsMatrixFunction(OpCode _eOpCode) +{ + switch ( _eOpCode ) + { + case ocDde : + case ocGrowth : + case ocTrend : + case ocRKP : + case ocRGP : + case ocFrequency : + case ocMatTrans : + case ocMatMult : + case ocMatInv : + case ocMatrixUnit : + return TRUE; + default: + { + // added to avoid warnings + } + } + return FALSE; +} + +// ----------------------------------------------------------------------------- +FormulaCompiler::OpCodeMap::~OpCodeMap() +{ + delete mpReverseExternalHashMap; + delete mpExternalHashMap; + delete [] mpTable; + delete mpHashMap; +} +// ----------------------------------------------------------------------------- +sal_Int32 FormulaCompiler::OpCodeMap::getOpCodeUnknown() +{ + static const sal_Int32 kOpCodeUnknown = -1; + return kOpCodeUnknown; +} +// ----------------------------------------------------------------------------- +BOOL FormulaCompiler::GetToken() +{ + static const short nRecursionMax = 42; + FormulaCompilerRecursionGuard aRecursionGuard( nRecursion ); + if ( nRecursion > nRecursionMax ) + { + SetError( errStackOverflow ); + pToken = new FormulaByteToken( ocStop ); + return FALSE; + } + if ( bAutoCorrect && !pStack ) + { // #61426# don't merge stacked subroutine code into entered formula + aCorrectedFormula += aCorrectedSymbol; + aCorrectedSymbol.Erase(); + } + BOOL bStop = FALSE; + if( pArr->GetCodeError() && !bIgnoreErrors ) + bStop = TRUE; + else + { + short nWasColRowName; + if ( pArr->nIndex + && pArr->pCode[ pArr->nIndex-1 ]->GetOpCode() == ocColRowName ) + nWasColRowName = 1; + else + nWasColRowName = 0; + pToken = pArr->Next(); + while( pToken && pToken->GetOpCode() == ocSpaces ) + { + if ( nWasColRowName ) + nWasColRowName++; + if ( bAutoCorrect && !pStack ) + CreateStringFromToken( aCorrectedFormula, pToken, FALSE ); + pToken = pArr->Next(); + } + if ( bAutoCorrect && !pStack && pToken ) + CreateStringFromToken( aCorrectedSymbol, pToken, FALSE ); + if( !pToken ) + { + if( pStack ) + { + PopTokenArray(); + return GetToken(); + } + else + bStop = TRUE; + } + else + { + if ( nWasColRowName >= 2 && pToken->GetOpCode() == ocColRowName ) + { // aus einem ocSpaces ein ocIntersect im RPN machen + pToken = new FormulaByteToken( ocIntersect ); + pArr->nIndex--; // ganz schweinisch.. + } + } + } + if( bStop ) + { + pToken = new FormulaByteToken( ocStop ); + return FALSE; + } + if( pToken->GetOpCode() == ocSubTotal ) + glSubTotal = TRUE; + else if( pToken->GetOpCode() == ocName ) + { + return HandleRange(); + } + else if( pToken->GetOpCode() == ocColRowName ) + { + return HandleSingleRef(); + } + else if( pToken->GetOpCode() == ocDBArea ) + { + return HandleDbData(); + } + else if( pToken->GetType() == svSingleRef ) + { + pArr->nRefs++; + } + else if( pToken->GetType() == svDoubleRef ) + { + pArr->nRefs++; + } + return TRUE; +} +//--------------------------------------------------------------------------- +// RPN creation by recursion +//--------------------------------------------------------------------------- + +void FormulaCompiler::Factor() +{ + if ( pArr->GetCodeError() && !bIgnoreErrors ) + return; + + CurrentFactor pFacToken( this ); + + OpCode eOp = pToken->GetOpCode(); + if( eOp == ocPush || eOp == ocColRowNameAuto || eOp == ocMatRef || + eOp == ocDBArea + || (bCompileForFAP && ((eOp == ocName) || (eOp == ocDBArea) + || (eOp == ocColRowName) || (eOp == ocBad))) + ) + { + PutCode( pToken ); + eOp = NextToken(); + if( eOp == ocOpen ) + { + // PUSH( is an error that may be caused by an unknown function. + SetError( + ( pToken->GetType() == svString + || pToken->GetType() == svSingleRef ) + ? errNoName : errOperatorExpected ); + if ( bAutoCorrect && !pStack ) + { // assume multiplication + aCorrectedFormula += mxSymbols->getSymbol(ocMul); + bCorrected = TRUE; + NextToken(); + eOp = Expression(); + if( eOp != ocClose ) + SetError(errPairExpected); + else + eOp = NextToken(); + } + } + } + else if( eOp == ocOpen ) + { + NextToken(); + eOp = Expression(); + while ((eOp == ocSep) && (!pArr->GetCodeError() || bIgnoreErrors)) + { // range list (A1;A2) converted to (A1~A2) + pFacToken = pToken; + NextToken(); + eOp = Expression(); + // Do not ignore error here, regardless of bIgnoreErrors, otherwise + // errors like =(1;) would also result in display of =(1~) + if (!pArr->GetCodeError()) + { + pFacToken->NewOpCode( ocUnion,FormulaToken::PrivateAccess()); + PutCode( pFacToken); + } + } + if (eOp != ocClose) + SetError(errPairExpected); + else + eOp = NextToken(); + } + else + { + if( nNumFmt == NUMBERFORMAT_UNDEFINED ) + nNumFmt = lcl_GetRetFormat( eOp ); + // Functions that have to be always recalculated + switch( eOp ) + { + // no parameters: + case ocRandom: + case ocGetActDate: + case ocGetActTime: + // one parameter: + case ocFormula: + case ocInfo: + // more than one parameters: + // ocIndirect/ocIndirectXL otherwise would have to do + // StopListening and StartListening on a reference for every + // interpreted value. + case ocIndirect: + case ocIndirectXL: + // ocOffset results in indirect references. + case ocOffset: + pArr->SetRecalcModeAlways(); + break; + // Functions recalculated on every document load. + // Don't use SetRecalcModeOnLoad() which would override + // ModeAlways. + case ocConvert : + pArr->AddRecalcMode( RECALCMODE_ONLOAD ); + break; + // If the referred cell is moved the value changes. + case ocColumn : + case ocRow : + // ocCell needs recalc on move for some possible type values. + case ocCell : + pArr->SetRecalcModeOnRefMove(); + break; + case ocHyperLink : + pArr->SetHyperLink(TRUE); + break; + default: + ; // nothing + } + if (SC_OPCODE_START_NO_PAR <= eOp && eOp < SC_OPCODE_STOP_NO_PAR) + { + pFacToken = pToken; + eOp = NextToken(); + if (eOp != ocOpen) + { + SetError(errPairExpected); + PutCode( pFacToken ); + } + else + { + eOp = NextToken(); + if (eOp != ocClose) + SetError(errPairExpected); + PutCode(pFacToken); + eOp = NextToken(); + } + } + // special cases NOT() and NEG() + else if( eOp == ocNot || eOp == ocNeg + || (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR) ) + { + pFacToken = pToken; + eOp = NextToken(); + if( nNumFmt == NUMBERFORMAT_UNDEFINED && eOp == ocNot ) + nNumFmt = NUMBERFORMAT_LOGICAL; + if (eOp == ocOpen) + { + NextToken(); + eOp = Expression(); + } + else + SetError(errPairExpected); + if (eOp != ocClose) + SetError(errPairExpected); + else if ( !pArr->GetCodeError() ) + pFacToken->SetByte( 1 ); + PutCode( pFacToken ); + eOp = NextToken(); + } + else if ((SC_OPCODE_START_2_PAR <= eOp && eOp < SC_OPCODE_STOP_2_PAR) + || eOp == ocExternal + || eOp == ocMacro + || eOp == ocAnd + || eOp == ocOr + || eOp == ocBad + || ( eOp >= ocInternalBegin && eOp <= ocInternalEnd ) + || (bCompileForFAP && ((eOp == ocIf) || (eOp == ocChose))) + ) + { + pFacToken = pToken; + OpCode eMyLastOp = eOp; + eOp = NextToken(); + bool bNoParam = false; + bool bBadName = false; + if (eOp == ocOpen) + { + eOp = NextToken(); + if (eOp == ocClose) + bNoParam = true; + else + eOp = Expression(); + } + else if (eMyLastOp == ocBad) + { + // Just a bad name, not an unknown function, no parameters, no + // closing expected. + bBadName = true; + bNoParam = true; + } + else + SetError(errPairExpected); + BYTE nSepCount = 0; + if( !bNoParam ) + { + nSepCount++; + while ( (eOp == ocSep) && (!pArr->GetCodeError() || bIgnoreErrors) ) + { + nSepCount++; + NextToken(); + eOp = Expression(); + } + } + if (bBadName) + ; // nothing, keep current token for return + else if (eOp != ocClose) + SetError(errPairExpected); + else + eOp = NextToken(); + // Jumps are just normal functions for the FunctionAutoPilot tree view + if ( bCompileForFAP && pFacToken->GetType() == svJump ) + pFacToken = new FormulaFAPToken( pFacToken->GetOpCode(), nSepCount, pFacToken ); + else + pFacToken->SetByte( nSepCount ); + PutCode( pFacToken ); + } + else if (eOp == ocIf || eOp == ocChose) + { + // the PC counters are -1 + pFacToken = pToken; + if ( eOp == ocIf ) + pFacToken->GetJump()[ 0 ] = 3; // if, else, behind + else + pFacToken->GetJump()[ 0 ] = MAXJUMPCOUNT+1; + eOp = NextToken(); + if (eOp == ocOpen) + { + NextToken(); + eOp = Expression(); + } + else + SetError(errPairExpected); + short nJumpCount = 0; + PutCode( pFacToken ); + // #36253# during AutoCorrect (since pArr->GetCodeError() is + // ignored) an unlimited ocIf would crash because + // ScRawToken::Clone() allocates the JumpBuffer according to + // nJump[0]*2+2, which is 3*2+2 on ocIf. + const short nJumpMax = + (pFacToken->GetOpCode() == ocIf ? 3 : MAXJUMPCOUNT); + while ( (nJumpCount < (MAXJUMPCOUNT - 1)) && (eOp == ocSep) + && (!pArr->GetCodeError() || bIgnoreErrors) ) + { + if ( ++nJumpCount <= nJumpMax ) + pFacToken->GetJump()[nJumpCount] = pc-1; + NextToken(); + eOp = Expression(); + // ocSep or ocClose terminate the subexpression + PutCode( pToken ); + } + if (eOp != ocClose) + SetError(errPairExpected); + else + { + eOp = NextToken(); + // always limit to nJumpMax, no arbitrary overwrites + if ( ++nJumpCount <= nJumpMax ) + pFacToken->GetJump()[ nJumpCount ] = pc-1; + if ((pFacToken->GetOpCode() == ocIf && (nJumpCount > 3)) || + (nJumpCount >= MAXJUMPCOUNT)) + SetError(errIllegalParameter); + else + pFacToken->GetJump()[ 0 ] = nJumpCount; + } + } + else if ( eOp == ocMissing ) + { + PutCode( pToken ); + eOp = NextToken(); + } + else if ( eOp == ocClose ) + { + SetError( errParameterExpected ); + } + else if ( eOp == ocSep ) + { // Subsequent ocSep + SetError( errParameterExpected ); + if ( bAutoCorrect && !pStack ) + { + aCorrectedSymbol.Erase(); + bCorrected = TRUE; + } + } + else + { + SetError( errUnknownToken ); + if ( bAutoCorrect && !pStack ) + { + if ( eOp == ocStop ) + { // trailing operator w/o operand + xub_StrLen nLen = aCorrectedFormula.Len(); + if ( nLen ) + aCorrectedFormula.Erase( nLen - 1 ); + aCorrectedSymbol.Erase(); + bCorrected = TRUE; + } + } + } + } +} + +//--------------------------------------------------------------------------- + +void FormulaCompiler::RangeLine() +{ + Factor(); + while (pToken->GetOpCode() == ocRange) + { + FormulaToken** pCode1 = pCode - 1; + FormulaTokenRef p = pToken; + NextToken(); + Factor(); + FormulaToken** pCode2 = pCode - 1; + if (!MergeRangeReference( pCode1, pCode2)) + PutCode(p); + } +} + +//--------------------------------------------------------------------------- + +void FormulaCompiler::UnionLine() +{ + RangeLine(); + while (pToken->GetOpCode() == ocUnion) + { + FormulaTokenRef p = pToken; + NextToken(); + RangeLine(); + PutCode(p); + } +} + +//--------------------------------------------------------------------------- + +void FormulaCompiler::IntersectionLine() +{ + UnionLine(); + while (pToken->GetOpCode() == ocIntersect) + { + FormulaTokenRef p = pToken; + NextToken(); + UnionLine(); + PutCode(p); + } +} + +//--------------------------------------------------------------------------- + +void FormulaCompiler::UnaryLine() +{ + if( pToken->GetOpCode() == ocAdd ) + GetToken(); + else if (SC_OPCODE_START_UN_OP <= pToken->GetOpCode() && + pToken->GetOpCode() < SC_OPCODE_STOP_UN_OP) + { + FormulaTokenRef p = pToken; + NextToken(); + UnaryLine(); + PutCode( p ); + } + else + IntersectionLine(); +} + +//--------------------------------------------------------------------------- + +void FormulaCompiler::PostOpLine() +{ + UnaryLine(); + while ( pToken->GetOpCode() == ocPercentSign ) + { // this operator _follows_ its operand + PutCode( pToken ); + NextToken(); + } +} + +//--------------------------------------------------------------------------- + +void FormulaCompiler::PowLine() +{ + PostOpLine(); + while (pToken->GetOpCode() == ocPow) + { + FormulaTokenRef p = pToken; + NextToken(); + PostOpLine(); + PutCode(p); + } +} + +//--------------------------------------------------------------------------- + +void FormulaCompiler::MulDivLine() +{ + PowLine(); + while (pToken->GetOpCode() == ocMul || pToken->GetOpCode() == ocDiv) + { + FormulaTokenRef p = pToken; + NextToken(); + PowLine(); + PutCode(p); + } +} + +//--------------------------------------------------------------------------- + +void FormulaCompiler::AddSubLine() +{ + MulDivLine(); + while (pToken->GetOpCode() == ocAdd || pToken->GetOpCode() == ocSub) + { + FormulaTokenRef p = pToken; + NextToken(); + MulDivLine(); + PutCode(p); + } +} + +//--------------------------------------------------------------------------- + +void FormulaCompiler::ConcatLine() +{ + AddSubLine(); + while (pToken->GetOpCode() == ocAmpersand) + { + FormulaTokenRef p = pToken; + NextToken(); + AddSubLine(); + PutCode(p); + } +} + +//--------------------------------------------------------------------------- + +void FormulaCompiler::CompareLine() +{ + ConcatLine(); + while (pToken->GetOpCode() >= ocEqual && pToken->GetOpCode() <= ocGreaterEqual) + { + FormulaTokenRef p = pToken; + NextToken(); + ConcatLine(); + PutCode(p); + } +} + +//--------------------------------------------------------------------------- + +void FormulaCompiler::NotLine() +{ + CompareLine(); + while (pToken->GetOpCode() == ocNot) + { + FormulaTokenRef p = pToken; + NextToken(); + CompareLine(); + PutCode(p); + } +} + +//--------------------------------------------------------------------------- + +OpCode FormulaCompiler::Expression() +{ + static const short nRecursionMax = 42; + FormulaCompilerRecursionGuard aRecursionGuard( nRecursion ); + if ( nRecursion > nRecursionMax ) + { + SetError( errStackOverflow ); + return ocStop; //! generate token instead? + } + NotLine(); + while (pToken->GetOpCode() == ocAnd || pToken->GetOpCode() == ocOr) + { + FormulaTokenRef p = pToken; + pToken->SetByte( 2 ); // 2 parameters! + NextToken(); + NotLine(); + PutCode(p); + } + return pToken->GetOpCode(); +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::SetError(USHORT /*nError*/) +{ +} +// ----------------------------------------------------------------------------- +FormulaTokenRef FormulaCompiler::ExtendRangeReference( FormulaToken & /*rTok1*/, FormulaToken & /*rTok2*/, bool /*bReuseDoubleRef*/ ) +{ + return FormulaTokenRef(); +} +// ----------------------------------------------------------------------------- +bool FormulaCompiler::MergeRangeReference(FormulaToken * * const pCode1, FormulaToken * const * const pCode2 ) +{ + FormulaToken *p1, *p2; + if (pc < 2 || !pCode1 || !pCode2 || + (pCode2 - pCode1 != 1) || (pCode - pCode2 != 1) || + ((p1 = *pCode1) == 0) || ((p2 = *pCode2) == 0) ) + return false; + + FormulaTokenRef p = ExtendRangeReference( *p1, *p2, true); + if (!p) + return false; + + p->IncRef(); + p1->DecRef(); + p2->DecRef(); + *pCode1 = p; + --pCode, --pc; + pArr->nRefs--; + + return true; +} +// ----------------------------------------------------------------------------- +BOOL FormulaCompiler::CompileTokenArray() +{ + glSubTotal = FALSE; + bCorrected = FALSE; + if( !pArr->GetCodeError() || bIgnoreErrors ) + { + if ( bAutoCorrect ) + { + aCorrectedFormula.Erase(); + aCorrectedSymbol.Erase(); + } + pArr->nRefs = 0; // count from start + pArr->DelRPN(); + pStack = NULL; + FormulaToken* pData[ MAXCODE ]; + pCode = pData; + BOOL bWasForced = pArr->IsRecalcModeForced(); + if ( bWasForced ) + { + if ( bAutoCorrect ) + aCorrectedFormula = '='; + } + pArr->ClearRecalcMode(); + pArr->Reset(); + eLastOp = ocOpen; + pc = 0; + NextToken(); + OpCode eOp = Expression(); + // Some trailing garbage that doesn't form an expression? + if (eOp != ocStop) + SetError( errOperatorExpected); + + USHORT nErrorBeforePop = pArr->GetCodeError(); + + while( pStack ) + PopTokenArray(); + if( pc ) + { + pArr->pRPN = new FormulaToken*[ pc ]; + pArr->nRPN = pc; + memcpy( pArr->pRPN, pData, pc * sizeof( FormulaToken* ) ); + } + + // once an error, always an error + if( !pArr->GetCodeError() && nErrorBeforePop ) + pArr->SetCodeError( nErrorBeforePop); + + if( pArr->GetCodeError() && !bIgnoreErrors ) + { + pArr->DelRPN(); + pArr->SetHyperLink(FALSE); + } + + if ( bWasForced ) + pArr->SetRecalcModeForced(); + } + if( nNumFmt == NUMBERFORMAT_UNDEFINED ) + nNumFmt = NUMBERFORMAT_NUMBER; + return glSubTotal; +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::PopTokenArray() +{ + if( pStack ) + { + FormulaArrayStack* p = pStack; + pStack = p->pNext; + p->pArr->nRefs = sal::static_int_cast<short>( p->pArr->nRefs + pArr->nRefs ); + // obtain special RecalcMode from SharedFormula + if ( pArr->IsRecalcModeAlways() ) + p->pArr->SetRecalcModeAlways(); + else if ( !pArr->IsRecalcModeNormal() && p->pArr->IsRecalcModeNormal() ) + p->pArr->SetMaskedRecalcMode( pArr->GetRecalcMode() ); + p->pArr->SetCombinedBitsRecalcMode( pArr->GetRecalcMode() ); + if( p->bTemp ) + delete pArr; + pArr = p->pArr; + delete p; + } +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::CreateStringFromTokenArray( String& rFormula ) +{ + rtl::OUStringBuffer aBuffer( pArr->GetLen() * 5 ); + CreateStringFromTokenArray( aBuffer ); + rFormula = aBuffer; +} + +void FormulaCompiler::CreateStringFromTokenArray( rtl::OUStringBuffer& rBuffer ) +{ + rBuffer.setLength(0); + if( !pArr->GetLen() ) + return; + + FormulaTokenArray* pSaveArr = pArr; + if (formula::FormulaGrammar::isPODF( meGrammar)) + { + // Scan token array for missing args and re-write if present. + if (pArr->NeedsPofRewrite()) + pArr = pArr->RewriteMissingToPof(); + } + + // At least one character per token, plus some are references, some are + // function names, some are numbers, ... + rBuffer.ensureCapacity( pArr->GetLen() * 5 ); + + if ( pArr->IsRecalcModeForced() ) + rBuffer.append(sal_Unicode('=')); + FormulaToken* t = pArr->First(); + while( t ) + t = CreateStringFromToken( rBuffer, t, TRUE ); + + if (pSaveArr != pArr) + { + delete pArr; + pArr = pSaveArr; + } +} +// ----------------------------------------------------------------------------- +FormulaToken* FormulaCompiler::CreateStringFromToken( String& rFormula, FormulaToken* pTokenP,BOOL bAllowArrAdvance ) +{ + rtl::OUStringBuffer aBuffer; + FormulaToken* p = CreateStringFromToken( aBuffer, pTokenP, bAllowArrAdvance ); + rFormula += aBuffer; + return p; +} + +FormulaToken* FormulaCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, FormulaToken* pTokenP,BOOL bAllowArrAdvance ) +{ + BOOL bNext = TRUE; + BOOL bSpaces = FALSE; + FormulaToken* t = pTokenP; + OpCode eOp = t->GetOpCode(); + if( eOp >= ocAnd && eOp <= ocOr ) + { + // AND, OR infix? + if ( bAllowArrAdvance ) + t = pArr->Next(); + else + t = pArr->PeekNext(); + bNext = FALSE; + bSpaces = ( !t || t->GetOpCode() != ocOpen ); + } + if( bSpaces ) + rBuffer.append(sal_Unicode(' ')); + + if( eOp == ocSpaces ) + { + bool bIntersectionOp = mxSymbols->isODFF(); + if (bIntersectionOp) + { + const FormulaToken* p = pArr->PeekPrevNoSpaces(); + bIntersectionOp = (p && p->GetOpCode() == ocColRowName); + if (bIntersectionOp) + { + p = pArr->PeekNextNoSpaces(); + bIntersectionOp = (p && p->GetOpCode() == ocColRowName); + } + } + if (bIntersectionOp) + rBuffer.appendAscii( "!!"); + else + { + // most times it's just one blank + BYTE n = t->GetByte(); + for ( BYTE j=0; j<n; ++j ) + { + rBuffer.append(sal_Unicode(' ')); + } + } + } + else if( eOp >= ocInternalBegin && eOp <= ocInternalEnd ) + rBuffer.appendAscii( pInternal[ eOp - ocInternalBegin ] ); + else if( (USHORT) eOp < mxSymbols->getSymbolCount()) // Keyword: + rBuffer.append(mxSymbols->getSymbol(eOp)); + else + { + DBG_ERRORFILE("unknown OpCode"); + rBuffer.append(GetNativeSymbol( ocErrName )); + } + if( bNext ) + switch( t->GetType() ) + { + case svDouble: + AppendDouble( rBuffer, t->GetDouble() ); + break; + + case svString: + if( eOp == ocBad ) + rBuffer.append(t->GetString()); + else + AppendString( rBuffer, t->GetString() ); + break; + case svSingleRef: + CreateStringFromSingleRef(rBuffer,t); + break; + case svDoubleRef: + CreateStringFromDoubleRef(rBuffer,t); + break; + case svMatrix: + CreateStringFromMatrix( rBuffer, t ); + break; + + case svIndex: + CreateStringFromIndex( rBuffer, t ); + break; + case svExternal: + { + // mapped or translated name of AddIns + String aAddIn( t->GetExternal() ); + bool bMapped = mxSymbols->isPODF(); // ODF 1.1 directly uses programmatical name + if (!bMapped && mxSymbols->hasExternals()) + { + ExternalHashMap::const_iterator iLook = mxSymbols->getReverseExternalHashMap()->find( aAddIn); + if (iLook != mxSymbols->getReverseExternalHashMap()->end()) + { + aAddIn = (*iLook).second; + bMapped = true; + } + } + if (!bMapped && !mxSymbols->isEnglish()) + LocalizeString( aAddIn ); + rBuffer.append(aAddIn); + } + break; + case svByte: + case svJump: + case svFAP: + case svMissing: + case svSep: + break; // Opcodes + default: + DBG_ERROR("FormulaCompiler:: GetStringFromToken errUnknownVariable"); + } // of switch + if( bSpaces ) + rBuffer.append(sal_Unicode(' ')); + if ( bAllowArrAdvance ) + { + if( bNext ) + t = pArr->Next(); + return t; + } + return pTokenP; +} +// ----------------------------------------------------------------------------- + +void FormulaCompiler::AppendDouble( rtl::OUStringBuffer& rBuffer, double fVal ) +{ + if ( mxSymbols->isEnglish() ) + { + ::rtl::math::doubleToUStringBuffer( rBuffer, fVal, + rtl_math_StringFormat_Automatic, + rtl_math_DecimalPlaces_Max, '.', TRUE ); + } + else + { + SvtSysLocale aSysLocale; + ::rtl::math::doubleToUStringBuffer( rBuffer, fVal, + rtl_math_StringFormat_Automatic, + rtl_math_DecimalPlaces_Max, + aSysLocale.GetLocaleDataPtr()->getNumDecimalSep().GetChar(0), + TRUE ); + } +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::AppendBoolean( rtl::OUStringBuffer& rBuffer, bool bVal ) +{ + rBuffer.append( mxSymbols->getSymbol(static_cast<OpCode>(bVal ? ocTrue : ocFalse)) ); +} +// ----------------------------------------------------------------------------- +BOOL FormulaCompiler::IsImportingXML() const +{ + return FALSE; +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::AppendString( rtl::OUStringBuffer& rBuffer, const String & rStr ) +{ + if (IsImportingXML()) + rBuffer.append( rStr ); + else + { + rBuffer.append(sal_Unicode('"')); + if ( lcl_UnicodeStrChr( rStr.GetBuffer(), '"' ) == NULL ) + rBuffer.append( rStr ); + else + { + String aStr( rStr ); + xub_StrLen nPos = 0; + while ( (nPos = aStr.Search( '"', nPos)) != STRING_NOTFOUND ) + { + aStr.Insert( '"', nPos ); + nPos += 2; + } + rBuffer.append(aStr); + } + rBuffer.append(sal_Unicode('"')); + } +} +// ----------------------------------------------------------------------------- +OpCode FormulaCompiler::NextToken() +{ + if( !GetToken() ) + return ocStop; + OpCode eOp = pToken->GetOpCode(); + // There must be an operator before a push + if ( (eOp == ocPush || eOp == ocColRowNameAuto) && + !( (eLastOp == ocOpen) || (eLastOp == ocSep) || + (SC_OPCODE_START_BIN_OP <= eLastOp && eLastOp < SC_OPCODE_STOP_UN_OP)) ) + SetError(errOperatorExpected); + // Operator and Plus => operator + if (eOp == ocAdd && (eLastOp == ocOpen || eLastOp == ocSep || + (SC_OPCODE_START_BIN_OP <= eLastOp && eLastOp < SC_OPCODE_STOP_UN_OP))) + eOp = NextToken(); + else + { + // Before an operator there must not be another operator, with the + // exception of AND and OR. + if ( eOp != ocAnd && eOp != ocOr && + (SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP ) + && (eLastOp == ocOpen || eLastOp == ocSep || + (SC_OPCODE_START_BIN_OP <= eLastOp && eLastOp < SC_OPCODE_STOP_UN_OP))) + { + SetError(errVariableExpected); + if ( bAutoCorrect && !pStack ) + { + if ( eOp == eLastOp || eLastOp == ocOpen ) + { // throw away duplicated operator + aCorrectedSymbol.Erase(); + bCorrected = TRUE; + } + else + { + xub_StrLen nPos = aCorrectedFormula.Len(); + if ( nPos ) + { + nPos--; + sal_Unicode c = aCorrectedFormula.GetChar( nPos ); + switch ( eOp ) + { // swap operators + case ocGreater: + if ( c == mxSymbols->getSymbol(ocEqual).GetChar(0) ) + { // >= instead of => + aCorrectedFormula.SetChar( nPos, + mxSymbols->getSymbol(ocGreater).GetChar(0) ); + aCorrectedSymbol = c; + bCorrected = TRUE; + } + break; + case ocLess: + if ( c == mxSymbols->getSymbol(ocEqual).GetChar(0) ) + { // <= instead of =< + aCorrectedFormula.SetChar( nPos, + mxSymbols->getSymbol(ocLess).GetChar(0) ); + aCorrectedSymbol = c; + bCorrected = TRUE; + } + else if ( c == mxSymbols->getSymbol(ocGreater).GetChar(0) ) + { // <> instead of >< + aCorrectedFormula.SetChar( nPos, + mxSymbols->getSymbol(ocLess).GetChar(0) ); + aCorrectedSymbol = c; + bCorrected = TRUE; + } + break; + case ocMul: + if ( c == mxSymbols->getSymbol(ocSub).GetChar(0) ) + { // *- instead of -* + aCorrectedFormula.SetChar( nPos, + mxSymbols->getSymbol(ocMul).GetChar(0) ); + aCorrectedSymbol = c; + bCorrected = TRUE; + } + break; + case ocDiv: + if ( c == mxSymbols->getSymbol(ocSub).GetChar(0) ) + { // /- instead of -/ + aCorrectedFormula.SetChar( nPos, + mxSymbols->getSymbol(ocDiv).GetChar(0) ); + aCorrectedSymbol = c; + bCorrected = TRUE; + } + break; + default: + ; // nothing + } + } + } + } + } + eLastOp = eOp; + } + return eOp; +} +void FormulaCompiler::PutCode( FormulaTokenRef& p ) +{ + if( pc >= MAXCODE-1 ) + { + if ( pc == MAXCODE-1 ) + { + p = new FormulaByteToken( ocStop ); + p->IncRef(); + *pCode++ = p; + ++pc; + } + SetError(errCodeOverflow); + return; + } + if( pArr->GetCodeError() && !bCompileForFAP ) + return; + ForceArrayOperator( p, pCurrentFactorToken); + p->IncRef(); + *pCode++ = p; + pc++; +} + +// ----------------------------------------------------------------------------- +BOOL FormulaCompiler::HandleRange() +{ + return TRUE; +} +// ----------------------------------------------------------------------------- +BOOL FormulaCompiler::HandleSingleRef() +{ + return TRUE; +} +// ----------------------------------------------------------------------------- +BOOL FormulaCompiler::HandleDbData() +{ + return TRUE; +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::CreateStringFromSingleRef(rtl::OUStringBuffer& /*rBuffer*/,FormulaToken* /*pTokenP*/) +{ +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::CreateStringFromDoubleRef(rtl::OUStringBuffer& /*rBuffer*/,FormulaToken* /*pTokenP*/) +{ +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::CreateStringFromIndex(rtl::OUStringBuffer& /*rBuffer*/,FormulaToken* /*pTokenP*/) +{ +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::CreateStringFromMatrix(rtl::OUStringBuffer& /*rBuffer*/,FormulaToken* /*pTokenP*/) +{ +} +// ----------------------------------------------------------------------------- +void FormulaCompiler::LocalizeString( String& /*rName*/ ) +{ +} +void FormulaCompiler::PushTokenArray( FormulaTokenArray* pa, BOOL bTemp ) +{ + if ( bAutoCorrect && !pStack ) + { // #61426# don't merge stacked subroutine code into entered formula + aCorrectedFormula += aCorrectedSymbol; + aCorrectedSymbol.Erase(); + } + FormulaArrayStack* p = new FormulaArrayStack; + p->pNext = pStack; + p->pArr = pArr; + p->bTemp = bTemp; + pStack = p; + pArr = pa; +} + +// ============================================================================= +} // formula +// ============================================================================= diff --git a/formula/source/core/api/FormulaOpCodeMapperObj.cxx b/formula/source/core/api/FormulaOpCodeMapperObj.cxx new file mode 100644 index 000000000000..29f0a2d2789a --- /dev/null +++ b/formula/source/core/api/FormulaOpCodeMapperObj.cxx @@ -0,0 +1,129 @@ +/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: tokenuno.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "precompiled_formula.hxx"
+#include "formula/FormulaOpCodeMapperObj.hxx"
+#include "formula/opcode.hxx"
+#include <comphelper/sequence.hxx>
+
+// =============================================================================
+namespace formula
+{
+// =============================================================================
+
+ using namespace ::com::sun::star;
+
+ // -----------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
+sal_Bool SAL_CALL FormulaOpCodeMapperObj::supportsService( const ::rtl::OUString& _rServiceName ) throw(uno::RuntimeException)
+{
+ return ::comphelper::findValue( getSupportedServiceNames_Static(), _rServiceName, sal_True ).getLength() != 0;
+}
+//------------------------------------------------------------------------
+FormulaOpCodeMapperObj::FormulaOpCodeMapperObj(::std::auto_ptr<FormulaCompiler> _pCompiler)
+: m_pCompiler(_pCompiler)
+{
+}
+
+FormulaOpCodeMapperObj::~FormulaOpCodeMapperObj()
+{
+}
+
+
+::sal_Int32 SAL_CALL FormulaOpCodeMapperObj::getOpCodeExternal()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return ocExternal;
+}
+
+
+::sal_Int32 SAL_CALL FormulaOpCodeMapperObj::getOpCodeUnknown()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return FormulaCompiler::OpCodeMap::getOpCodeUnknown();
+}
+
+
+::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken >
+SAL_CALL FormulaOpCodeMapperObj::getMappings(
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rNames,
+ sal_Int32 nLanguage )
+ throw ( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ FormulaCompiler::OpCodeMapPtr xMap = m_pCompiler->GetOpCodeMap( nLanguage);
+ if (!xMap)
+ throw lang::IllegalArgumentException();
+ return xMap->createSequenceOfFormulaTokens( *m_pCompiler,rNames);
+}
+
+
+::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaOpCodeMapEntry >
+SAL_CALL FormulaOpCodeMapperObj::getAvailableMappings(
+ sal_Int32 nLanguage, sal_Int32 nGroups )
+ throw ( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ FormulaCompiler::OpCodeMapPtr xMap = m_pCompiler->GetOpCodeMap( nLanguage);
+ if (!xMap)
+ throw lang::IllegalArgumentException();
+ return xMap->createSequenceOfAvailableMappings( *m_pCompiler,nGroups);
+}
+//--------------------------------------------------------------------------
+::rtl::OUString SAL_CALL FormulaOpCodeMapperObj::getImplementationName( ) throw(uno::RuntimeException)
+{
+ return getImplementationName_Static();
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString SAL_CALL FormulaOpCodeMapperObj::getImplementationName_Static()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "simple.formula.FormulaOpCodeMapperObj" ) );
+}
+// --------------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL FormulaOpCodeMapperObj::getSupportedServiceNames( ) throw(uno::RuntimeException)
+{
+ return getSupportedServiceNames_Static();
+}
+uno::Sequence< rtl::OUString > SAL_CALL FormulaOpCodeMapperObj::getSupportedServiceNames_Static()
+{
+ uno::Sequence< rtl::OUString > aSeq( 1 );
+ aSeq[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.FormulaOpCodeMapper" ));
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL FormulaOpCodeMapperObj::create(
+ uno::Reference< uno::XComponentContext > const & /*_xContext*/)
+{
+ return static_cast<sheet::XFormulaOpCodeMapper*>(new FormulaOpCodeMapperObj(::std::auto_ptr<FormulaCompiler>(new FormulaCompiler())));
+}
+// -----------------------------------------------------------------------------
+
+// =============================================================================
+} // formula
+// =============================================================================
diff --git a/formula/source/core/api/makefile.mk b/formula/source/core/api/makefile.mk new file mode 100644 index 000000000000..d4c132ac41b0 --- /dev/null +++ b/formula/source/core/api/makefile.mk @@ -0,0 +1,51 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJINC=$(PRJ)$/source +PRJNAME=formula +TARGET=core_api +ENABLE_EXCEPTIONS=TRUE +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES= $(SLO)$/FormulaOpCodeMapperObj.obj \ + $(SLO)$/FormulaCompiler.obj \ + $(SLO)$/token.obj \ + $(SLO)$/services.obj + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk diff --git a/formula/source/core/api/services.cxx b/formula/source/core/api/services.cxx new file mode 100644 index 000000000000..cbead3c9766e --- /dev/null +++ b/formula/source/core/api/services.cxx @@ -0,0 +1,78 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: services.cxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "precompiled_formula.hxx" +#include "sal/types.h" +#include <cppuhelper/factory.hxx> +#include <osl/diagnose.h> +#include <cppuhelper/implementationentry.hxx> +#include "formula/FormulaOpCodeMapperObj.hxx" + +/********************************************************************************************/ + +using namespace ::formula; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; + +//*************************************************************************************** +// +// registry functions +namespace +{ + +cppu::ImplementationEntry entries[] = { + { &FormulaOpCodeMapperObj::create, &FormulaOpCodeMapperObj::getImplementationName_Static, &FormulaOpCodeMapperObj::getSupportedServiceNames_Static, + &cppu::createSingleComponentFactory, 0, 0 }, + { 0, 0, 0, 0, 0, 0 } +}; +} + +extern "C" +{ +SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( + char const * implName, void * serviceManager, void * registryKey) +{ + return cppu::component_getFactoryHelper( + implName, serviceManager, registryKey, entries); +} + +SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( + char const ** envTypeName, uno_Environment **) +{ + *envTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( + void * serviceManager, void * registryKey) +{ + return cppu::component_writeInfoHelper( + serviceManager, registryKey, entries); +} +} // extern "C" diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx new file mode 100644 index 000000000000..8a9615752daf --- /dev/null +++ b/formula/source/core/api/token.cxx @@ -0,0 +1,1366 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: token.cxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_formula.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#if STLPORT_VERSION<321 +#include <stddef.h> +#else +#include <cstddef> +#endif +#include <cstdio> + +#include <string.h> +#include <tools/debug.hxx> + +#include "formula/token.hxx" +#include "formula/tokenarray.hxx" +#include "formula/FormulaCompiler.hxx" +#include <formula/compiler.hrc> +//#include "rechead.hxx" +//#include "parclass.hxx" +//#include "jumpmatrix.hxx" +#define MAXJUMPCOUNT 32 /* maximum number of jumps (ocChose) */ + +namespace formula +{ + using namespace com::sun::star; +// ImpTokenIterator wird je Interpreter angelegt, mehrfache auch durch +// SubCode via FormulaTokenIterator Push/Pop moeglich +IMPL_FIXEDMEMPOOL_NEWDEL( ImpTokenIterator, 32, 16 ) + +// Align MemPools on 4k boundaries - 64 bytes (4k is a MUST for OS/2) + +// Need a lot of FormulaDoubleToken +const USHORT nMemPoolDoubleToken = (0x3000 - 64) / sizeof(FormulaDoubleToken); +IMPL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaDoubleToken, nMemPoolDoubleToken, nMemPoolDoubleToken ) +// Need a lot of FormulaByteToken +const USHORT nMemPoolByteToken = (0x3000 - 64) / sizeof(FormulaByteToken); +IMPL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaByteToken, nMemPoolByteToken, nMemPoolByteToken ) +// Need several FormulaStringToken +const USHORT nMemPoolStringToken = (0x1000 - 64) / sizeof(FormulaStringToken); +IMPL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaStringToken, nMemPoolStringToken, nMemPoolStringToken ) + + +// --- helpers -------------------------------------------------------------- + +inline BOOL lcl_IsReference( OpCode eOp, StackVar eType ) +{ + return + (eOp == ocPush && (eType == svSingleRef || eType == svDoubleRef)) + || (eOp == ocColRowNameAuto && eType == svDoubleRef) + || (eOp == ocColRowName && eType == svSingleRef) + || (eOp == ocMatRef && eType == svSingleRef) + ; +} + +// --- class FormulaToken -------------------------------------------------------- +FormulaToken::~FormulaToken() +{ +} + +BOOL FormulaToken::Is3DRef() const +{ + return FALSE; +} + +BOOL FormulaToken::IsFunction() const +{ +// OpCode eOp = GetOpCode(); + return (eOp != ocPush && eOp != ocBad && eOp != ocColRowName && + eOp != ocColRowNameAuto && eOp != ocName && eOp != ocDBArea && + (GetByte() != 0 // x parameters + || (SC_OPCODE_START_NO_PAR <= eOp && eOp < SC_OPCODE_STOP_NO_PAR) // no parameter + || (ocIf == eOp || ocChose == eOp ) // @ jump commands + || (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR) // one parameter + || (SC_OPCODE_START_2_PAR <= eOp && eOp < SC_OPCODE_STOP_2_PAR) // x parameters (cByte==0 in + // FuncAutoPilot) + || eOp == ocMacro || eOp == ocExternal // macros, AddIns + || eOp == ocAnd || eOp == ocOr // former binary, now x parameters + || eOp == ocNot || eOp == ocNeg // unary but function + || (eOp >= ocInternalBegin && eOp <= ocInternalEnd) // internal + )); +} + + +BYTE FormulaToken::GetParamCount() const +{ + // OpCode eOp = GetOpCode(); + if ( eOp < SC_OPCODE_STOP_DIV && eOp != ocExternal && eOp != ocMacro && + eOp != ocIf && eOp != ocChose && eOp != ocPercentSign ) + return 0; // parameters and specials + // ocIf and ocChose not for FAP, have cByte then +//2do: BOOL parameter whether FAP or not? + else if ( GetByte() ) + return GetByte(); // all functions, also ocExternal and ocMacro + else if (SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP) + return 2; // binary + else if ((SC_OPCODE_START_UN_OP <= eOp && eOp < SC_OPCODE_STOP_UN_OP) + || eOp == ocPercentSign) + return 1; // unary + else if (SC_OPCODE_START_NO_PAR <= eOp && eOp < SC_OPCODE_STOP_NO_PAR) + return 0; // no parameter + else if (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR) + return 1; // one parameter + else if ( eOp == ocIf || eOp == ocChose ) + return 1; // only the condition counts as parameter + else + return 0; // all the rest, no Parameter, or + // if so then it should be in cByte +} + + +BOOL FormulaToken::IsMatrixFunction() const +{ + return formula::FormulaCompiler::IsMatrixFunction(GetOpCode()); +} + +BOOL FormulaToken::operator==( const FormulaToken& rToken ) const +{ + // don't compare reference count! + return eType == rToken.eType && GetOpCode() == rToken.GetOpCode(); +} + + +// --- virtual dummy methods ------------------------------------------------- + +BYTE FormulaToken::GetByte() const +{ + // ok to be called for any derived class + return 0; +} + +void FormulaToken::SetByte( BYTE ) +{ + DBG_ERRORFILE( "FormulaToken::SetByte: virtual dummy called" ); +} + +bool FormulaToken::HasForceArray() const +{ + // ok to be called for any derived class + return false; +} + +void FormulaToken::SetForceArray( bool ) +{ + DBG_ERRORFILE( "FormulaToken::SetForceArray: virtual dummy called" ); +} + +double FormulaToken::GetDouble() const +{ + DBG_ERRORFILE( "FormulaToken::GetDouble: virtual dummy called" ); + return 0.0; +} + +double & FormulaToken::GetDoubleAsReference() +{ + DBG_ERRORFILE( "FormulaToken::GetDouble: virtual dummy called" ); + static double fVal = 0.0; + return fVal; +} + +const String& FormulaToken::GetString() const +{ + DBG_ERRORFILE( "FormulaToken::GetString: virtual dummy called" ); + static String aDummyString; + return aDummyString; +} + +USHORT FormulaToken::GetIndex() const +{ + DBG_ERRORFILE( "FormulaToken::GetIndex: virtual dummy called" ); + return 0; +} + +void FormulaToken::SetIndex( USHORT ) +{ + DBG_ERRORFILE( "FormulaToken::SetIndex: virtual dummy called" ); +} + +short* FormulaToken::GetJump() const +{ + DBG_ERRORFILE( "FormulaToken::GetJump: virtual dummy called" ); + return NULL; +} + + +const String& FormulaToken::GetExternal() const +{ + DBG_ERRORFILE( "FormulaToken::GetExternal: virtual dummy called" ); + static String aDummyString; + return aDummyString; +} + +FormulaToken* FormulaToken::GetFAPOrigToken() const +{ + DBG_ERRORFILE( "FormulaToken::GetFAPOrigToken: virtual dummy called" ); + return NULL; +} + +USHORT FormulaToken::GetError() const +{ + DBG_ERRORFILE( "FormulaToken::GetError: virtual dummy called" ); + return 0; +} + +void FormulaToken::SetError( USHORT ) +{ + DBG_ERRORFILE( "FormulaToken::SetError: virtual dummy called" ); +} +BOOL FormulaToken::TextEqual( const FormulaToken& rToken ) const +{ + return *this == rToken; +} +// ========================================================================== +// real implementations of virtual functions +// -------------------------------------------------------------------------- + + +BYTE FormulaByteToken::GetByte() const { return nByte; } +void FormulaByteToken::SetByte( BYTE n ) { nByte = n; } +bool FormulaByteToken::HasForceArray() const { return bHasForceArray; } +void FormulaByteToken::SetForceArray( bool b ) { bHasForceArray = b; } +BOOL FormulaByteToken::operator==( const FormulaToken& r ) const +{ + return FormulaToken::operator==( r ) && nByte == r.GetByte() && + bHasForceArray == r.HasForceArray(); +} + + +FormulaToken* FormulaFAPToken::GetFAPOrigToken() const { return pOrigToken; } +BOOL FormulaFAPToken::operator==( const FormulaToken& r ) const +{ + return FormulaByteToken::operator==( r ) && pOrigToken == r.GetFAPOrigToken(); +} +short* FormulaJumpToken::GetJump() const { return pJump; } +BOOL FormulaJumpToken::operator==( const FormulaToken& r ) const +{ + return FormulaToken::operator==( r ) && pJump[0] == r.GetJump()[0] && + memcmp( pJump+1, r.GetJump()+1, pJump[0] * sizeof(short) ) == 0; +} +FormulaJumpToken::~FormulaJumpToken() +{ + delete [] pJump; +} + + +bool FormulaTokenArray::AddFormulaToken(const sheet::FormulaToken& _aToken) +{ + bool bError = false; + const OpCode eOpCode = static_cast<OpCode>(_aToken.OpCode); //! assuming equal values for the moment + + const uno::TypeClass eClass = _aToken.Data.getValueTypeClass(); + switch ( eClass ) + { + case uno::TypeClass_VOID: + // empty data -> use AddOpCode (does some special cases) + AddOpCode( eOpCode ); + break; + case uno::TypeClass_DOUBLE: + // double is only used for "push" + if ( eOpCode == ocPush ) + AddDouble( _aToken.Data.get<double>() ); + else + bError = true; + break; + case uno::TypeClass_LONG: + { + // long is svIndex, used for name / database area, or "byte" for spaces + sal_Int32 nValue = _aToken.Data.get<sal_Int32>(); + if ( eOpCode == ocName || eOpCode == ocDBArea ) + AddToken( formula::FormulaIndexToken( eOpCode, static_cast<USHORT>(nValue) ) ); + else if ( eOpCode == ocSpaces ) + AddToken( formula::FormulaByteToken( ocSpaces, static_cast<BYTE>(nValue) ) ); + else + bError = true; + } + break; + case uno::TypeClass_STRING: + { + String aStrVal( _aToken.Data.get<rtl::OUString>() ); + if ( eOpCode == ocPush ) + AddString( aStrVal ); + else if ( eOpCode == ocBad ) + AddBad( aStrVal ); + else if ( eOpCode == ocExternal || eOpCode == ocMacro ) + AddToken( formula::FormulaExternalToken( eOpCode, aStrVal ) ); + else + bError = true; // unexpected string: don't know what to do with it + } + break; + default: + bError = true; + } // switch ( eClass ) + return bError; +} +bool FormulaTokenArray::Fill(const uno::Sequence< sheet::FormulaToken >& _aSequence) +{ + bool bError = false; + const sal_Int32 nCount = _aSequence.getLength(); + for (sal_Int32 nPos=0; nPos<nCount; nPos++) + { + bError |= AddFormulaToken( _aSequence[nPos] ); + } + return bError; +} +////////////////////////////////////////////////////////////////////////// +FormulaToken* FormulaTokenArray::GetNextReference() +{ + while( nIndex < nLen ) + { + FormulaToken* t = pCode[ nIndex++ ]; + switch( t->GetType() ) + { + case svSingleRef: + case svDoubleRef: + case svExternalSingleRef: + case svExternalDoubleRef: + return t; + default: + { + // added to avoid warnings + } + } + } + return NULL; +} + +FormulaToken* FormulaTokenArray::GetNextColRowName() +{ + while( nIndex < nLen ) + { + FormulaToken* t = pCode[ nIndex++ ]; + if ( t->GetOpCode() == ocColRowName ) + return t; + } + return NULL; +} + +FormulaToken* FormulaTokenArray::GetNextReferenceRPN() +{ + while( nIndex < nRPN ) + { + FormulaToken* t = pRPN[ nIndex++ ]; + switch( t->GetType() ) + { + case svSingleRef: + case svDoubleRef: + case svExternalSingleRef: + case svExternalDoubleRef: + return t; + default: + { + // added to avoid warnings + } + } + } + return NULL; +} + +FormulaToken* FormulaTokenArray::GetNextReferenceOrName() +{ + if( pCode ) + { + while ( nIndex < nLen ) + { + FormulaToken* t = pCode[ nIndex++ ]; + switch( t->GetType() ) + { + case svSingleRef: + case svDoubleRef: + case svIndex: + case svExternalSingleRef: + case svExternalDoubleRef: + case svExternalName: + return t; + default: + { + // added to avoid warnings + } + } + } + } + return NULL; +} + +FormulaToken* FormulaTokenArray::GetNextName() +{ + if( pCode ) + { + while ( nIndex < nLen ) + { + FormulaToken* t = pCode[ nIndex++ ]; + if( t->GetType() == svIndex ) + return t; + } + } // if( pCode ) + return NULL; +} + +FormulaToken* FormulaTokenArray::GetNextDBArea() +{ + if( pCode ) + { + while ( nIndex < nLen ) + { + FormulaToken* t = pCode[ nIndex++ ]; + if( t->GetOpCode() == ocDBArea ) + return t; + } // while ( nIndex < nLen )+ + } + return NULL; +} + +FormulaToken* FormulaTokenArray::GetNextOpCodeRPN( OpCode eOp ) +{ + while( nIndex < nRPN ) + { + FormulaToken* t = pRPN[ nIndex++ ]; + if ( t->GetOpCode() == eOp ) + return t; + } + return NULL; +} + +FormulaToken* FormulaTokenArray::Next() +{ + if( pCode && nIndex < nLen ) + return pCode[ nIndex++ ]; + else + return NULL; +} + +FormulaToken* FormulaTokenArray::NextNoSpaces() +{ + if( pCode ) + { + while( (nIndex < nLen) && (pCode[ nIndex ]->GetOpCode() == ocSpaces) ) + ++nIndex; + if( nIndex < nLen ) + return pCode[ nIndex++ ]; + } + return NULL; +} + +FormulaToken* FormulaTokenArray::NextRPN() +{ + if( pRPN && nIndex < nRPN ) + return pRPN[ nIndex++ ]; + else + return NULL; +} + +FormulaToken* FormulaTokenArray::PrevRPN() +{ + if( pRPN && nIndex ) + return pRPN[ --nIndex ]; + else + return NULL; +} + +void FormulaTokenArray::DelRPN() +{ + if( nRPN ) + { + FormulaToken** p = pRPN; + for( USHORT i = 0; i < nRPN; i++ ) + { + (*p++)->DecRef(); + } + delete [] pRPN; + } + pRPN = NULL; + nRPN = nIndex = 0; +} + +FormulaToken* FormulaTokenArray::PeekPrev( USHORT & nIdx ) +{ + if (0 < nIdx && nIdx <= nLen) + return pCode[--nIdx]; + return NULL; +} + +FormulaToken* FormulaTokenArray::PeekNext() +{ + if( pCode && nIndex < nLen ) + return pCode[ nIndex ]; + else + return NULL; +} + +FormulaToken* FormulaTokenArray::PeekNextNoSpaces() +{ + if( pCode && nIndex < nLen ) + { + USHORT j = nIndex; + while ( pCode[j]->GetOpCode() == ocSpaces && j < nLen ) + j++; + if ( j < nLen ) + return pCode[ j ]; + else + return NULL; + } + else + return NULL; +} + +FormulaToken* FormulaTokenArray::PeekPrevNoSpaces() +{ + if( pCode && nIndex > 1 ) + { + USHORT j = nIndex - 2; + while ( pCode[j]->GetOpCode() == ocSpaces && j > 0 ) + j--; + if ( j > 0 || pCode[j]->GetOpCode() != ocSpaces ) + return pCode[ j ]; + else + return NULL; + } + else + return NULL; +} + +BOOL FormulaTokenArray::HasOpCode( OpCode eOp ) const +{ + for ( USHORT j=0; j < nLen; j++ ) + { + if ( pCode[j]->GetOpCode() == eOp ) + return TRUE; + } + return FALSE; +} + +BOOL FormulaTokenArray::HasOpCodeRPN( OpCode eOp ) const +{ + for ( USHORT j=0; j < nRPN; j++ ) + { + if ( pRPN[j]->GetOpCode() == eOp ) + return TRUE; + } + return FALSE; +} + +BOOL FormulaTokenArray::HasNameOrColRowName() const +{ + for ( USHORT j=0; j < nLen; j++ ) + { + if( pCode[j]->GetType() == svIndex || pCode[j]->GetOpCode() == ocColRowName ) + return TRUE; + } + return FALSE; +} + +//////////////////////////////////////////////////////////////////////////// + +FormulaTokenArray::FormulaTokenArray() +{ + pCode = NULL; pRPN = NULL; + nError = nLen = nIndex = nRPN = nRefs = 0; + bHyperLink = FALSE; + ClearRecalcMode(); +} + +FormulaTokenArray::FormulaTokenArray( const FormulaTokenArray& rArr ) +{ + Assign( rArr ); +} + +FormulaTokenArray::~FormulaTokenArray() +{ + Clear(); +} + +void FormulaTokenArray::Assign( const FormulaTokenArray& r ) +{ + nLen = r.nLen; + nRPN = r.nRPN; + nIndex = r.nIndex; + nError = r.nError; + nRefs = r.nRefs; + nMode = r.nMode; + bHyperLink = r.bHyperLink; + pCode = NULL; + pRPN = NULL; + FormulaToken** pp; + if( nLen ) + { + pp = pCode = new FormulaToken*[ nLen ]; + memcpy( pp, r.pCode, nLen * sizeof( FormulaToken* ) ); + for( USHORT i = 0; i < nLen; i++ ) + (*pp++)->IncRef(); + } + if( nRPN ) + { + pp = pRPN = new FormulaToken*[ nRPN ]; + memcpy( pp, r.pRPN, nRPN * sizeof( FormulaToken* ) ); + for( USHORT i = 0; i < nRPN; i++ ) + (*pp++)->IncRef(); + } +} + +FormulaTokenArray& FormulaTokenArray::operator=( const FormulaTokenArray& rArr ) +{ + Clear(); + Assign( rArr ); + return *this; +} + +FormulaTokenArray* FormulaTokenArray::Clone() const +{ + FormulaTokenArray* p = new FormulaTokenArray; + p->nLen = nLen; + p->nRPN = nRPN; + p->nRefs = nRefs; + p->nMode = nMode; + p->nError = nError; + p->bHyperLink = bHyperLink; + FormulaToken** pp; + if( nLen ) + { + pp = p->pCode = new FormulaToken*[ nLen ]; + memcpy( pp, pCode, nLen * sizeof( FormulaToken* ) ); + for( USHORT i = 0; i < nLen; i++, pp++ ) + { + *pp = (*pp)->Clone(); + (*pp)->IncRef(); + } + } + if( nRPN ) + { + pp = p->pRPN = new FormulaToken*[ nRPN ]; + memcpy( pp, pRPN, nRPN * sizeof( FormulaToken* ) ); + for( USHORT i = 0; i < nRPN; i++, pp++ ) + { + FormulaToken* t = *pp; + if( t->GetRef() > 1 ) + { + FormulaToken** p2 = pCode; + USHORT nIdx = 0xFFFF; + for( USHORT j = 0; j < nLen; j++, p2++ ) + { + if( *p2 == t ) + { + nIdx = j; break; + } + } + if( nIdx == 0xFFFF ) + *pp = t->Clone(); + else + *pp = p->pCode[ nIdx ]; + } + else + *pp = t->Clone(); + (*pp)->IncRef(); + } + } + return p; +} + +void FormulaTokenArray::Clear() +{ + if( nRPN ) DelRPN(); + if( pCode ) + { + FormulaToken** p = pCode; + for( USHORT i = 0; i < nLen; i++ ) + { + (*p++)->DecRef(); + } + delete [] pCode; + } + pCode = NULL; pRPN = NULL; + nError = nLen = nIndex = nRPN = nRefs = 0; + bHyperLink = FALSE; + ClearRecalcMode(); +} + +FormulaToken* FormulaTokenArray::AddToken( const FormulaToken& r ) +{ + return Add( r.Clone() ); +} + +FormulaToken* FormulaTokenArray::MergeArray( ) +{ + return NULL; +} + +FormulaToken* FormulaTokenArray::Add( FormulaToken* t ) +{ + if( !pCode ) + pCode = new FormulaToken*[ MAXCODE ]; + if( nLen < MAXCODE-1 ) + { + // fprintf (stderr, "Add : %d\n", t->GetOpCode()); + pCode[ nLen++ ] = t; + if( t->GetOpCode() == ocPush + && ( t->GetType() == svSingleRef || t->GetType() == svDoubleRef ) ) + nRefs++; + t->IncRef(); + if( t->GetOpCode() == ocArrayClose ) + return MergeArray(); + return t; + } + else + { + t->Delete(); + if ( nLen == MAXCODE-1 ) + { + t = new FormulaByteToken( ocStop ); + pCode[ nLen++ ] = t; + t->IncRef(); + } + return NULL; + } +} + +FormulaToken* FormulaTokenArray::AddString( const sal_Unicode* pStr ) +{ + return AddString( String( pStr ) ); +} + +FormulaToken* FormulaTokenArray::AddString( const String& rStr ) +{ + return Add( new FormulaStringToken( rStr ) ); +} + +FormulaToken* FormulaTokenArray::AddDouble( double fVal ) +{ + return Add( new FormulaDoubleToken( fVal ) ); +} + +FormulaToken* FormulaTokenArray::AddName( USHORT n ) +{ + return Add( new FormulaIndexToken( ocName, n ) ); +} + +FormulaToken* FormulaTokenArray::AddExternal( const sal_Unicode* pStr ) +{ + return AddExternal( String( pStr ) ); +} + +FormulaToken* FormulaTokenArray::AddExternal( const String& rStr, + OpCode eOp /* = ocExternal */ ) +{ + return Add( new FormulaExternalToken( eOp, rStr ) ); +} + +FormulaToken* FormulaTokenArray::AddBad( const sal_Unicode* pStr ) +{ + return AddBad( String( pStr ) ); +} + +FormulaToken* FormulaTokenArray::AddBad( const String& rStr ) +{ + return Add( new FormulaStringOpToken( ocBad, rStr ) ); +} + + + +void FormulaTokenArray::AddRecalcMode( ScRecalcMode nBits ) +{ + //! Reihenfolge ist wichtig + if ( nBits & RECALCMODE_ALWAYS ) + SetRecalcModeAlways(); + else if ( !IsRecalcModeAlways() ) + { + if ( nBits & RECALCMODE_ONLOAD ) + SetRecalcModeOnLoad(); + else if ( nBits & RECALCMODE_ONLOAD_ONCE && !IsRecalcModeOnLoad() ) + SetRecalcModeOnLoadOnce(); + } + SetCombinedBitsRecalcMode( nBits ); +} + + +BOOL FormulaTokenArray::HasMatrixDoubleRefOps() +{ + if ( pRPN && nRPN ) + { + // RPN-Interpreter Simulation + // als Ergebnis jeder Funktion wird einfach ein Double angenommen + FormulaToken** pStack = new FormulaToken* [nRPN]; + FormulaToken* pResult = new FormulaDoubleToken( 0.0 ); + short sp = 0; + for ( USHORT j = 0; j < nRPN; j++ ) + { + FormulaToken* t = pRPN[j]; + OpCode eOp = t->GetOpCode(); + BYTE nParams = t->GetParamCount(); + switch ( eOp ) + { + case ocAdd : + case ocSub : + case ocMul : + case ocDiv : + case ocPow : + case ocPower : + case ocAmpersand : + case ocEqual : + case ocNotEqual : + case ocLess : + case ocGreater : + case ocLessEqual : + case ocGreaterEqual : + { + for ( BYTE k = nParams; k; k-- ) + { + if ( sp >= k && pStack[sp-k]->GetType() == svDoubleRef ) + { + pResult->Delete(); + delete [] pStack; + return TRUE; + } + } + } + break; + default: + { + // added to avoid warnings + } + } + if ( eOp == ocPush || lcl_IsReference( eOp, t->GetType() ) ) + pStack[sp++] = t; + else if ( eOp == ocIf || eOp == ocChose ) + { // Jumps ignorieren, vorheriges Result (Condition) poppen + if ( sp ) + --sp; + } + else + { // pop parameters, push result + sp = sal::static_int_cast<short>( sp - nParams ); + if ( sp < 0 ) + { + DBG_ERROR( "FormulaTokenArray::HasMatrixDoubleRefOps: sp < 0" ); + sp = 0; + } + pStack[sp++] = pResult; + } + } + pResult->Delete(); + delete [] pStack; + } + + return FALSE; +} + + + +// --- POF (plain old formula) rewrite of a token array --------------------- + +/* TODO: When both POF OOoXML and ODFF are to be supported differently, the + * FormulaMissingContext and FormulaTokenArray::*Pof* methods should go to a convention + * on its own. + */ + +#if 0 +// static function can't be compiled if not used (warning) +//#if OSL_DEBUG_LEVEL > 0 +static void DumpTokArr( FormulaTokenArray *pCode ) +{ + fprintf (stderr, "TokenArr: "); + for ( FormulaToken *pCur = pCode->First(); pCur; pCur = pCode->Next() ) + fprintf( stderr, "t%d,o%d ", + pCur->GetType(), pCur->GetOpCode() ); + fprintf (stderr, "\n"); +} +#endif + +inline bool MissingConvention::isRewriteNeeded( OpCode eOp ) const
+{
+ switch (eOp)
+ {
+ case ocGammaDist:
+ case ocPoissonDist:
+ return true;
+ case ocMissing:
+ case ocLog:
+ case ocAddress:
+ return !isODFF(); // rewrite only for PODF
+ default:
+ return false;
+ }
+} + +class FormulaMissingContext +{ + public: + const FormulaToken* mpFunc; + int mnCurArg; + + void Clear() { mpFunc = NULL; mnCurArg = 0; } + inline bool AddDefaultArg( FormulaTokenArray* pNewArr, int nArg, double f ) const; + static inline bool IsRewriteNeeded( OpCode eOp ); + bool AddMissingExternal( FormulaTokenArray* pNewArr ) const; + bool AddMissing( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const; + void AddMoreArgs( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const; +}; +void FormulaMissingContext::AddMoreArgs( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const +{ + if ( !mpFunc )
+ return;
+
+ switch (mpFunc->GetOpCode())
+ {
+ case ocGammaDist:
+ if (mnCurArg == 2)
+ {
+ pNewArr->AddOpCode( ocSep );
+ pNewArr->AddDouble( 1.0 ); // 4th, Cumulative=TRUE()
+ }
+ break;
+ case ocPoissonDist:
+ if (mnCurArg == 1)
+ {
+ pNewArr->AddOpCode( ocSep );
+ pNewArr->AddDouble( 1.0 ); // 3rd, Cumulative=TRUE()
+ }
+ break;
+ case ocLog:
+ if ( !rConv.isODFF() && mnCurArg == 0 )
+ {
+ pNewArr->AddOpCode( ocSep );
+ pNewArr->AddDouble( 10.0 ); // 2nd, basis 10
+ }
+ break;
+ default:
+ break;
+ } +} + +inline bool FormulaMissingContext::AddDefaultArg( FormulaTokenArray* pNewArr, int nArg, double f ) const +{ + if (mnCurArg == nArg) + { + pNewArr->AddDouble( f ); + return true; + } + return false; +} + +inline bool FormulaMissingContext::IsRewriteNeeded( OpCode eOp ) +{ + switch (eOp) + { + case ocMissing: + case ocLog: + case ocAddress: + return true; + default: + return false; + } +} + +bool FormulaMissingContext::AddMissingExternal( FormulaTokenArray *pNewArr ) const +{ + const String &rName = mpFunc->GetExternal(); + + // initial (fast) check: + sal_Unicode nLastChar = rName.GetChar( rName.Len() - 1); + if ( nLastChar != 't' && nLastChar != 'm' ) + return false; + + if (rName.EqualsIgnoreCaseAscii( + "com.sun.star.sheet.addin.Analysis.getAccrint" )) + { + return AddDefaultArg( pNewArr, 4, 1000.0 ); + } + if (rName.EqualsIgnoreCaseAscii( + "com.sun.star.sheet.addin.Analysis.getAccrintm" )) + { + return AddDefaultArg( pNewArr, 3, 1000.0 ); + } + return false; +} + +bool FormulaMissingContext::AddMissing( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const +{ + if ( !mpFunc )
+ return false;
+
+ bool bRet = false;
+ if (rConv.isODFF())
+ {
+ }
+ else
+ {
+ switch ( mpFunc->GetOpCode() )
+ {
+ case ocFixed:
+ return AddDefaultArg( pNewArr, 1, 2.0 );
+ //break;
+ case ocBetaDist:
+ case ocBetaInv:
+ case ocRMZ: // PMT
+ return AddDefaultArg( pNewArr, 3, 0.0 );
+ //break;
+ case ocZinsZ: // IPMT
+ case ocKapz: // PPMT
+ return AddDefaultArg( pNewArr, 4, 0.0 );
+ //break;
+ case ocBW: // PV
+ case ocZW: // FV
+ bRet |= AddDefaultArg( pNewArr, 2, 0.0 ); // pmt
+ bRet |= AddDefaultArg( pNewArr, 3, 0.0 ); // [fp]v
+ break;
+ case ocZins: // RATE
+ bRet |= AddDefaultArg( pNewArr, 1, 0.0 ); // pmt
+ bRet |= AddDefaultArg( pNewArr, 3, 0.0 ); // fv
+ bRet |= AddDefaultArg( pNewArr, 4, 0.0 ); // type
+ break;
+ case ocExternal:
+ return AddMissingExternal( pNewArr );
+ //break;
+
+ // --- more complex cases ---
+
+ case ocOffset:
+ // FIXME: rather tough.
+ // if arg 3 (height) ommitted, export arg1 (rows)
+ break;
+ default:
+ break;
+ }
+ }
+
+ return bRet; +} + +bool FormulaTokenArray::NeedsPofRewrite( const MissingConvention & rConv ) +{ + for ( FormulaToken *pCur = First(); pCur; pCur = Next() ) + { + if ( rConv.isRewriteNeeded( pCur->GetOpCode())) + return true; + } + return false; +} + + +FormulaTokenArray * FormulaTokenArray::RewriteMissingToPof( const MissingConvention & rConv ) +{ + const size_t nAlloc = 256; + FormulaMissingContext aCtx[ nAlloc ]; + int aOpCodeAddressStack[ nAlloc ]; // use of ADDRESS() function + const int nOmitAddressArg = 3; // ADDRESS() 4th parameter A1/R1C1 + USHORT nTokens = GetLen() + 1; + FormulaMissingContext* pCtx = (nAlloc < nTokens ? new FormulaMissingContext[nTokens] : &aCtx[0]); + int* pOcas = (nAlloc < nTokens ? new int[nTokens] : &aOpCodeAddressStack[0]); + // Never go below 0, never use 0, mpFunc always NULL. + pCtx[0].Clear(); + int nFn = 0; + int nOcas = 0; + + FormulaTokenArray *pNewArr = new FormulaTokenArray; + // At least RECALCMODE_ALWAYS needs to be set. + pNewArr->AddRecalcMode( GetRecalcMode()); + + for ( FormulaToken *pCur = First(); pCur; pCur = Next() ) + { + bool bAdd = true; + // Don't write the expression of the new inserted ADDRESS() parameter. + // Do NOT omit the new second parameter of INDIRECT() though. If that + // was done for both, INDIRECT() actually could calculate different and + // valid (but wrong) results with the then changed return value of + // ADDRESS(). Better let it generate an error instead. + for (int i = nOcas; i-- > 0 && bAdd; ) + { + if (pCtx[ pOcas[ i ] ].mnCurArg == nOmitAddressArg) + { + // Omit erverything except a trailing separator, the leading + // separator is omitted below. The other way around would leave + // an extraneous separator if no parameter followed. + if (!(pOcas[ i ] == nFn && pCur->GetOpCode() == ocSep)) + bAdd = false; + } + //fprintf( stderr, "ocAddress %d arg %d%s\n", (int)i, (int)pCtx[ pOcas[ i ] ].mnCurArg, (bAdd ? "" : " omitted")); + } + switch ( pCur->GetOpCode() ) + { + case ocOpen: + ++nFn; // all following operations on _that_ function + pCtx[ nFn ].mpFunc = PeekPrevNoSpaces(); + pCtx[ nFn ].mnCurArg = 0; + if (pCtx[ nFn ].mpFunc && pCtx[ nFn ].mpFunc->GetOpCode() == ocAddress) + pOcas[ nOcas++ ] = nFn; // entering ADDRESS() + break; + case ocClose: + pCtx[ nFn ].AddMoreArgs( pNewArr, rConv ); + DBG_ASSERT( nFn > 0, "FormulaTokenArray::RewriteMissingToPof: underflow"); + if (nOcas > 0 && pOcas[ nOcas-1 ] == nFn) + --nOcas; // leaving ADDRESS() + if (nFn > 0) + --nFn; + break; + case ocSep: + pCtx[ nFn ].mnCurArg++; + // Omit leading separator of ADDRESS() parameter. + if (nOcas && pOcas[ nOcas-1 ] == nFn && pCtx[ nFn ].mnCurArg == nOmitAddressArg) + { + bAdd = false; + //fprintf( stderr, "ocAddress %d sep %d omitted\n", (int)nOcas-1, nOmitAddressArg); + } + break; + case ocMissing: + if (bAdd) + bAdd = !pCtx[ nFn ].AddMissing( pNewArr, rConv ); + break; + default: + break; + } + if (bAdd) + pNewArr->AddToken( *pCur ); + } + + if (pOcas != &aOpCodeAddressStack[0]) + delete [] pOcas; + if (pCtx != &aCtx[0]) + delete [] pCtx; + + return pNewArr; +} + +bool FormulaTokenArray::MayReferenceFollow() +{ + if ( pCode && nLen > 0 ) + { + // ignore trailing spaces + USHORT i = nLen - 1; + while ( i > 0 && pCode[i]->GetOpCode() == SC_OPCODE_SPACES ) + { + --i; + } + if ( i > 0 || pCode[i]->GetOpCode() != SC_OPCODE_SPACES ) + { + OpCode eOp = pCode[i]->GetOpCode(); + if ( (SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP ) || + (SC_OPCODE_START_UN_OP <= eOp && eOp < SC_OPCODE_STOP_UN_OP ) || + eOp == SC_OPCODE_OPEN || eOp == SC_OPCODE_SEP ) + { + return true; + } + } + } + return false; +} +FormulaToken* FormulaTokenArray::AddOpCode( OpCode eOp ) +{ + FormulaToken* pRet = NULL; + switch ( eOp ) + { + case ocOpen: + case ocClose: + case ocSep: + case ocArrayOpen: + case ocArrayClose: + case ocArrayRowSep: + case ocArrayColSep: + pRet = new FormulaToken( svSep,eOp ); + break; + case ocIf: + case ocChose: + { + short nJump[MAXJUMPCOUNT + 1]; + nJump[ 0 ] = ocIf == eOp ? 3 : MAXJUMPCOUNT+1; + pRet = new FormulaJumpToken( eOp, (short*)nJump ); + } + break; + default: + pRet = new FormulaByteToken( eOp, 0, FALSE ); + break; + } + return AddToken( *pRet ); +} + + +/*----------------------------------------------------------------------*/ + +FormulaTokenIterator::FormulaTokenIterator( const FormulaTokenArray& rArr ) +{ + pCur = NULL; + Push( &rArr ); +} + +FormulaTokenIterator::~FormulaTokenIterator() +{ + while( pCur ) + Pop(); +} + +void FormulaTokenIterator::Push( const FormulaTokenArray* pArr ) +{ + ImpTokenIterator* p = new ImpTokenIterator; + p->pArr = pArr; + p->nPC = -1; + p->nStop = SHRT_MAX; + p->pNext = pCur; + pCur = p; +} + +void FormulaTokenIterator::Pop() +{ + ImpTokenIterator* p = pCur; + if( p ) + { + pCur = p->pNext; + delete p; + } +} + +void FormulaTokenIterator::Reset() +{ + while( pCur->pNext ) + Pop(); + pCur->nPC = -1; +} + +const FormulaToken* FormulaTokenIterator::First() +{ + Reset(); + return Next(); +} + +const FormulaToken* FormulaTokenIterator::Next() +{ + const FormulaToken* t = NULL; + ++pCur->nPC; + if( pCur->nPC < pCur->pArr->nRPN && pCur->nPC < pCur->nStop ) + { + t = pCur->pArr->pRPN[ pCur->nPC ]; + // such an OpCode ends an IF() or CHOOSE() path + if( t->GetOpCode() == ocSep || t->GetOpCode() == ocClose ) + t = NULL; + } + if( !t && pCur->pNext ) + { + Pop(); + t = Next(); + } + return t; +} + +//! The nPC counts after a Push() are -1 + +void FormulaTokenIterator::Jump( short nStart, short nNext, short nStop ) +{ + pCur->nPC = nNext; + if( nStart != nNext ) + { + Push( pCur->pArr ); + pCur->nPC = nStart; + pCur->nStop = nStop; + } +} + +bool FormulaTokenIterator::IsEndOfPath() const +{ + USHORT nTest = pCur->nPC + 1; + if( nTest < pCur->pArr->nRPN && nTest < pCur->nStop ) + { + const FormulaToken* t = pCur->pArr->pRPN[ nTest ]; + // such an OpCode ends an IF() or CHOOSE() path + return t->GetOpCode() == ocSep || t->GetOpCode() == ocClose; + } + return true; +} +// ----------------------------------------------------------------------------- +// ========================================================================== +// real implementations of virtual functions +// -------------------------------------------------------------------------- + +double FormulaDoubleToken::GetDouble() const { return fDouble; } +double & FormulaDoubleToken::GetDoubleAsReference() { return fDouble; } +BOOL FormulaDoubleToken::operator==( const FormulaToken& r ) const +{ + return FormulaToken::operator==( r ) && fDouble == r.GetDouble(); +} + + +const String& FormulaStringToken::GetString() const { return aString; } +BOOL FormulaStringToken::operator==( const FormulaToken& r ) const +{ + return FormulaToken::operator==( r ) && aString == r.GetString(); +} + + +const String& FormulaStringOpToken::GetString() const { return aString; } +BOOL FormulaStringOpToken::operator==( const FormulaToken& r ) const +{ + return FormulaByteToken::operator==( r ) && aString == r.GetString(); +} + +USHORT FormulaIndexToken::GetIndex() const { return nIndex; } +void FormulaIndexToken::SetIndex( USHORT n ) { nIndex = n; } +BOOL FormulaIndexToken::operator==( const FormulaToken& r ) const +{ + return FormulaToken::operator==( r ) && nIndex == r.GetIndex(); +} +const String& FormulaExternalToken::GetExternal() const { return aExternal; } +BYTE FormulaExternalToken::GetByte() const { return nByte; } +void FormulaExternalToken::SetByte( BYTE n ) { nByte = n; } +BOOL FormulaExternalToken::operator==( const FormulaToken& r ) const +{ + return FormulaToken::operator==( r ) && nByte == r.GetByte() && + aExternal == r.GetExternal(); +} + + +USHORT FormulaErrorToken::GetError() const { return nError; } +void FormulaErrorToken::SetError( USHORT nErr ) { nError = nErr; } +BOOL FormulaErrorToken::operator==( const FormulaToken& r ) const +{ + return FormulaToken::operator==( r ) && + nError == static_cast< const FormulaErrorToken & >(r).GetError(); +} +double FormulaMissingToken::GetDouble() const { return 0.0; } +const String& FormulaMissingToken::GetString() const +{ + static String aDummyString; + return aDummyString; +} +BOOL FormulaMissingToken::operator==( const FormulaToken& r ) const +{ + return FormulaToken::operator==( r ); +} + + +BOOL FormulaUnknownToken::operator==( const FormulaToken& r ) const +{ + return FormulaToken::operator==( r ); +} + +// ----------------------------------------------------------------------------- +} // formula +// ----------------------------------------------------------------------------- + diff --git a/formula/source/core/inc/core_resource.hrc b/formula/source/core/inc/core_resource.hrc new file mode 100644 index 000000000000..4a64fddaba4b --- /dev/null +++ b/formula/source/core/inc/core_resource.hrc @@ -0,0 +1,48 @@ +/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: core_resource.hrc,v $
+ * $Revision: 1.16.68.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMULA_CORE_RESOURCE_HRC_
+#define _FORMULA_CORE_RESOURCE_HRC_
+
+#include <svtools/solar.hrc>
+
+//------------------------------------------------------------------------------
+#define RID_CORE_STRINGS_START RID_FORMULA_START
+#define RID_CORE_OTHER_START RID_FORMULA_START
+
+//------------------------------------------------------------------------------
+//- String-IDs
+#define RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF (RID_CORE_OTHER_START + 0)
+#define RID_STRLIST_FUNCTION_NAMES_ENGLISH (RID_CORE_OTHER_START + 1)
+#define RID_STRLIST_FUNCTION_NAMES (RID_CORE_OTHER_START + 2)
+
+
+#endif // _FORMULA_CORE_RESOURCE_HRC_
+
diff --git a/formula/source/core/inc/core_resource.hxx b/formula/source/core/inc/core_resource.hxx new file mode 100644 index 000000000000..f079fbf95100 --- /dev/null +++ b/formula/source/core/inc/core_resource.hxx @@ -0,0 +1,114 @@ +/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: core_resource.hxx,v $
+ * $Revision: 1.5.68.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FORMULA_CORE_RESOURCE_HXX_
+#define _FORMULA_CORE_RESOURCE_HXX_
+
+#ifndef _RTL_USTRING_HXX_
+#include <rtl/ustring.hxx>
+#endif
+#include <osl/mutex.hxx>
+
+class ResMgr;
+//.........................................................................
+namespace formula
+{
+
+#define FORMULA_RES( id ) ResourceManager::loadString( id )
+#define FORMULA_RES_PARAM( id, ascii, replace ) ResourceManager::loadString( id, ascii, replace )
+
+#define FORMULACORE_RESSTRING( id ) FORMULA_RES( id )
+ // (compatibility)
+
+ //==================================================================
+ //= ResourceManager
+ //= handling ressources within the FORMULA-Core library
+ //==================================================================
+ class ResourceManager
+ {
+ friend class OModuleClient;
+ static ::osl::Mutex s_aMutex; /// access safety
+ static sal_Int32 s_nClients; /// number of registered clients
+ static ResMgr* m_pImpl;
+
+ private:
+ // no instantiation allowed
+ ResourceManager() { }
+ ~ResourceManager() { }
+
+ protected:
+ static void ensureImplExists();
+ /// register a client for the module
+ static void registerClient();
+ /// revoke a client for the module
+ static void revokeClient();
+
+ public:
+ /** loads the string with the specified resource id
+ */
+ static ::rtl::OUString loadString(sal_uInt16 _nResId);
+
+ /** loads a string from the resource file, substituting a placeholder with a given string
+
+ @param _nResId
+ the resource ID of the string to loAD
+ @param _pPlaceholderAscii
+ the ASCII representation of the placeholder string
+ @param _rReplace
+ the string which should substutite the placeholder
+ */
+ static ::rtl::OUString loadString(
+ sal_uInt16 _nResId,
+ const sal_Char* _pPlaceholderAscii,
+ const ::rtl::OUString& _rReplace
+ );
+
+ static ResMgr* getResManager();
+ };
+
+ //=========================================================================
+ //= OModuleClient
+ //=========================================================================
+ /** base class for objects which uses any global module-specific ressources
+ */
+ class OModuleClient
+ {
+ public:
+ OModuleClient() { ResourceManager::registerClient(); }
+ ~OModuleClient() { ResourceManager::revokeClient(); }
+ };
+
+
+//.........................................................................
+} // formula
+//.........................................................................
+
+#endif // _FORMULA_CORE_RESOURCE_HXX_
+
diff --git a/formula/source/core/resource/core_resource.cxx b/formula/source/core/resource/core_resource.cxx new file mode 100644 index 000000000000..8d2933375b17 --- /dev/null +++ b/formula/source/core/resource/core_resource.cxx @@ -0,0 +1,111 @@ +/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: core_resource.cxx,v $
+ * $Revision: 1.11.68.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_formula.hxx"
+
+#include "core_resource.hxx"
+
+#include <tools/resmgr.hxx>
+
+// ---- needed as long as we have no contexts for components ---
+#include <vcl/svapp.hxx>
+#include <svtools/solar.hrc>
+
+//.........................................................................
+namespace formula
+{
+
+ //==================================================================
+ //= ResourceManager
+ //==================================================================
+ ::osl::Mutex ResourceManager::s_aMutex;
+ sal_Int32 ResourceManager::s_nClients = 0;
+ ResMgr* ResourceManager::m_pImpl = NULL;
+
+ //------------------------------------------------------------------
+ void ResourceManager::ensureImplExists()
+ {
+ if (m_pImpl)
+ return;
+
+ ::com::sun::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();
+
+ ByteString sFileName("for");
+
+ m_pImpl = ResMgr::CreateResMgr(sFileName.GetBuffer(), aLocale);
+ }
+
+ //------------------------------------------------------------------
+ ::rtl::OUString ResourceManager::loadString(sal_uInt16 _nResId)
+ {
+ ::rtl::OUString sReturn;
+
+ ensureImplExists();
+ if (m_pImpl)
+ sReturn = String(ResId(_nResId,*m_pImpl));
+
+ return sReturn;
+ }
+
+ //------------------------------------------------------------------
+ ::rtl::OUString ResourceManager::loadString( sal_uInt16 _nResId, const sal_Char* _pPlaceholderAscii, const ::rtl::OUString& _rReplace )
+ {
+ String sString( loadString( _nResId ) );
+ sString.SearchAndReplaceAscii( _pPlaceholderAscii, _rReplace );
+ return sString;
+ }
+ //-------------------------------------------------------------------------
+ void ResourceManager::registerClient()
+ {
+ ::osl::MutexGuard aGuard(s_aMutex);
+ ++s_nClients;
+ }
+
+ //-------------------------------------------------------------------------
+ void ResourceManager::revokeClient()
+ {
+ ::osl::MutexGuard aGuard(s_aMutex);
+ if (!--s_nClients && m_pImpl)
+ {
+ delete m_pImpl;
+ m_pImpl = NULL;
+ }
+ }
+ ResMgr* ResourceManager::getResManager()
+ {
+ ensureImplExists();
+ return m_pImpl;
+ }
+
+//.........................................................................
+} // formula
+//.........................................................................
+
diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src new file mode 100644 index 000000000000..e5fb345e20f3 --- /dev/null +++ b/formula/source/core/resource/core_resource.src @@ -0,0 +1,1881 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: compiler.src,v $ + * $Revision: 1.59 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "core_resource.hrc" +#include "formula/compiler.hrc" + +// DO NOT CHANGE! +// These English names are used internally to store/load ODFF as of ODF v1.2 +Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF +{ + String SC_OPCODE_IF { Text = "IF" ; }; + String SC_OPCODE_CHOSE { Text = "CHOOSE" ; }; + String SC_OPCODE_OPEN { Text = "(" ; }; + String SC_OPCODE_CLOSE { Text = ")" ; }; + String SC_OPCODE_ARRAY_OPEN { Text = "{" ; }; + String SC_OPCODE_ARRAY_CLOSE { Text = "}" ; }; + String SC_OPCODE_ARRAY_ROW_SEP { Text = "|" ; }; + String SC_OPCODE_ARRAY_COL_SEP { Text = ";" ; }; + String SC_OPCODE_SEP { Text = ";" ; }; + String SC_OPCODE_PERCENT_SIGN { Text = "%" ; }; + String SC_OPCODE_ADD { Text = "+" ; }; + String SC_OPCODE_SUB { Text = "-" ; }; + String SC_OPCODE_MUL { Text = "*" ; }; + String SC_OPCODE_DIV { Text = "/" ; }; + String SC_OPCODE_AMPERSAND { Text = "&" ; }; + String SC_OPCODE_POW { Text = "^" ; }; + String SC_OPCODE_EQUAL { Text = "=" ; }; + String SC_OPCODE_NOT_EQUAL { Text = "<>" ; }; + String SC_OPCODE_LESS { Text = "<" ; }; + String SC_OPCODE_GREATER { Text = ">" ; }; + String SC_OPCODE_LESS_EQUAL { Text = "<=" ; }; + String SC_OPCODE_GREATER_EQUAL { Text = ">=" ; }; + String SC_OPCODE_AND { Text = "AND" ; }; + String SC_OPCODE_OR { Text = "OR" ; }; + String SC_OPCODE_INTERSECT { Text = "!" ; }; + String SC_OPCODE_UNION { Text = "~" ; }; + String SC_OPCODE_RANGE { Text = ":" ; }; + String SC_OPCODE_NOT { Text = "NOT" ; }; + String SC_OPCODE_NEG { Text = "NEG" ; }; + String SC_OPCODE_NEG_SUB { Text = "-" ; }; + String SC_OPCODE_PI { Text = "PI" ; }; + String SC_OPCODE_RANDOM { Text = "RAND" ; }; + String SC_OPCODE_TRUE { Text = "TRUE" ; }; + String SC_OPCODE_FALSE { Text = "FALSE" ; }; + String SC_OPCODE_GET_ACT_DATE { Text = "TODAY" ; }; + String SC_OPCODE_GET_ACT_TIME { Text = "NOW" ; }; + String SC_OPCODE_NO_VALUE { Text = "NA" ; }; + String SC_OPCODE_CURRENT { Text = "ORG.OPENOFFICE.CURRENT" ; }; + String SC_OPCODE_DEG { Text = "DEGREES" ; }; + String SC_OPCODE_RAD { Text = "RADIANS" ; }; + String SC_OPCODE_SIN { Text = "SIN" ; }; + String SC_OPCODE_COS { Text = "COS" ; }; + String SC_OPCODE_TAN { Text = "TAN" ; }; + String SC_OPCODE_COT { Text = "COT" ; }; + String SC_OPCODE_ARC_SIN { Text = "ASIN" ; }; + String SC_OPCODE_ARC_COS { Text = "ACOS" ; }; + String SC_OPCODE_ARC_TAN { Text = "ATAN" ; }; + String SC_OPCODE_ARC_COT { Text = "ACOT" ; }; + String SC_OPCODE_SIN_HYP { Text = "SINH" ; }; + String SC_OPCODE_COS_HYP { Text = "COSH" ; }; + String SC_OPCODE_TAN_HYP { Text = "TANH" ; }; + String SC_OPCODE_COT_HYP { Text = "COTH" ; }; + String SC_OPCODE_ARC_SIN_HYP { Text = "ASINH" ; }; + String SC_OPCODE_ARC_COS_HYP { Text = "ACOSH" ; }; + String SC_OPCODE_ARC_TAN_HYP { Text = "ATANH" ; }; + String SC_OPCODE_ARC_COT_HYP { Text = "ACOTH" ; }; + String SC_OPCODE_EXP { Text = "EXP" ; }; + String SC_OPCODE_LN { Text = "LN" ; }; + String SC_OPCODE_SQRT { Text = "SQRT" ; }; + String SC_OPCODE_FACT { Text = "FACT" ; }; + String SC_OPCODE_GET_YEAR { Text = "YEAR" ; }; + String SC_OPCODE_GET_MONTH { Text = "MONTH" ; }; + String SC_OPCODE_GET_DAY { Text = "DAY" ; }; + String SC_OPCODE_GET_HOUR { Text = "HOUR" ; }; + String SC_OPCODE_GET_MIN { Text = "MINUTE" ; }; + String SC_OPCODE_GET_SEC { Text = "SECOND" ; }; + String SC_OPCODE_PLUS_MINUS { Text = "SIGN" ; }; + String SC_OPCODE_ABS { Text = "ABS" ; }; + String SC_OPCODE_INT { Text = "INT" ; }; + String SC_OPCODE_PHI { Text = "PHI" ; }; + String SC_OPCODE_GAUSS { Text = "GAUSS" ; }; + String SC_OPCODE_IS_EMPTY { Text = "ISBLANK" ; }; + String SC_OPCODE_IS_STRING { Text = "ISTEXT" ; }; + String SC_OPCODE_IS_NON_STRING { Text = "ISNONTEXT" ; }; + String SC_OPCODE_IS_LOGICAL { Text = "ISLOGICAL" ; }; + String SC_OPCODE_TYPE { Text = "TYPE" ; }; + String SC_OPCODE_CELL { Text = "CELL" ; }; + String SC_OPCODE_IS_REF { Text = "ISREF" ; }; + String SC_OPCODE_IS_VALUE { Text = "ISNUMBER" ; }; + String SC_OPCODE_IS_FORMULA { Text = "ISFORMULA" ; }; + String SC_OPCODE_IS_NV { Text = "ISNA" ; }; + String SC_OPCODE_IS_ERR { Text = "ISERR" ; }; + String SC_OPCODE_IS_ERROR { Text = "ISERROR" ; }; + String SC_OPCODE_IS_EVEN { Text = "ISEVEN" ; }; + String SC_OPCODE_IS_ODD { Text = "ISODD" ; }; + String SC_OPCODE_N { Text = "N" ; }; + String SC_OPCODE_GET_DATE_VALUE { Text = "DATEVALUE" ; }; + String SC_OPCODE_GET_TIME_VALUE { Text = "TIMEVALUE" ; }; + String SC_OPCODE_CODE { Text = "CODE" ; }; + String SC_OPCODE_TRIM { Text = "TRIM" ; }; + String SC_OPCODE_UPPER { Text = "UPPER" ; }; + String SC_OPCODE_PROPPER { Text = "PROPER" ; }; + String SC_OPCODE_LOWER { Text = "LOWER" ; }; + String SC_OPCODE_LEN { Text = "LEN" ; }; + String SC_OPCODE_T { Text = "T" ; }; + String SC_OPCODE_VALUE { Text = "VALUE" ; }; + String SC_OPCODE_CLEAN { Text = "CLEAN" ; }; + String SC_OPCODE_CHAR { Text = "CHAR" ; }; + String SC_OPCODE_JIS { Text = "JIS" ; }; + String SC_OPCODE_ASC { Text = "ASC" ; }; + String SC_OPCODE_UNICODE { Text = "UNICODE" ; }; + String SC_OPCODE_UNICHAR { Text = "UNICHAR" ; }; + String SC_OPCODE_LOG10 { Text = "LOG10" ; }; + String SC_OPCODE_EVEN { Text = "EVEN" ; }; + String SC_OPCODE_ODD { Text = "ODD" ; }; + String SC_OPCODE_STD_NORM_DIST { Text = "LEGACY.NORMSDIST" ; }; + String SC_OPCODE_FISHER { Text = "FISHER" ; }; + String SC_OPCODE_FISHER_INV { Text = "FISHERINV" ; }; + String SC_OPCODE_S_NORM_INV { Text = "LEGACY.NORMSINV" ; }; + String SC_OPCODE_GAMMA_LN { Text = "GAMMALN" ; }; + String SC_OPCODE_ERROR_TYPE { Text = "ORG.OPENOFFICE.ERRORTYPE" ; }; + String SC_OPCODE_ERR_CELL { Text = "ZellError" ; }; // TODO: ancient legacy only, remove? + String SC_OPCODE_FORMULA { Text = "FORMULA"; }; + String SC_OPCODE_ARC_TAN_2 { Text = "ATAN2" ; }; + String SC_OPCODE_CEIL { Text = "CEILING" ; }; + String SC_OPCODE_FLOOR { Text = "FLOOR" ; }; + String SC_OPCODE_ROUND { Text = "ROUND" ; }; + String SC_OPCODE_ROUND_UP { Text = "ROUNDUP" ; }; + String SC_OPCODE_ROUND_DOWN { Text = "ROUNDDOWN" ; }; + String SC_OPCODE_TRUNC { Text = "TRUNC" ; }; + String SC_OPCODE_LOG { Text = "LOG" ; }; + String SC_OPCODE_POWER { Text = "POWER" ; }; + String SC_OPCODE_GGT { Text = "GCD" ; }; + String SC_OPCODE_KGV { Text = "LCM" ; }; + String SC_OPCODE_MOD { Text = "MOD" ; }; + String SC_OPCODE_SUM_PRODUCT { Text = "SUMPRODUCT" ; }; + String SC_OPCODE_SUM_SQ { Text = "SUMSQ" ; }; + String SC_OPCODE_SUM_X2MY2 { Text = "SUMX2MY2" ; }; + String SC_OPCODE_SUM_X2DY2 { Text = "SUMX2PY2" ; }; + String SC_OPCODE_SUM_XMY2 { Text = "SUMXMY2" ; }; + String SC_OPCODE_GET_DATE { Text = "DATE" ; }; + String SC_OPCODE_GET_TIME { Text = "TIME" ; }; + String SC_OPCODE_GET_DIFF_DATE { Text = "DAYS" ; }; + String SC_OPCODE_GET_DIFF_DATE_360 { Text = "DAYS360" ; }; + String SC_OPCODE_MIN { Text = "MIN" ; }; + String SC_OPCODE_MIN_A { Text = "MINA" ; }; + String SC_OPCODE_MAX { Text = "MAX" ; }; + String SC_OPCODE_MAX_A { Text = "MAXA" ; }; + String SC_OPCODE_SUM { Text = "SUM" ; }; + String SC_OPCODE_PRODUCT { Text = "PRODUCT" ; }; + String SC_OPCODE_AVERAGE { Text = "AVERAGE" ; }; + String SC_OPCODE_AVERAGE_A { Text = "AVERAGEA" ; }; + String SC_OPCODE_COUNT { Text = "COUNT" ; }; + String SC_OPCODE_COUNT_2 { Text = "COUNTA" ; }; + String SC_OPCODE_NBW { Text = "NPV" ; }; + String SC_OPCODE_IKV { Text = "IRR" ; }; + String SC_OPCODE_MIRR { Text = "MIRR" ; }; + String SC_OPCODE_ISPMT { Text = "ISPMT" ; }; + String SC_OPCODE_VAR { Text = "VAR" ; }; + String SC_OPCODE_VAR_A { Text = "VARA" ; }; + String SC_OPCODE_VAR_P { Text = "VARP" ; }; + String SC_OPCODE_VAR_P_A { Text = "VARPA" ; }; + String SC_OPCODE_ST_DEV { Text = "STDEV" ; }; + String SC_OPCODE_ST_DEV_A { Text = "STDEVA" ; }; + String SC_OPCODE_ST_DEV_P { Text = "STDEVP" ; }; + String SC_OPCODE_ST_DEV_P_A { Text = "STDEVPA" ; }; + String SC_OPCODE_B { Text = "B" ; }; + String SC_OPCODE_NORM_DIST { Text = "NORMDIST" ; }; + String SC_OPCODE_EXP_DIST { Text = "EXPONDIST" ; }; + String SC_OPCODE_BINOM_DIST { Text = "BINOMDIST" ; }; + String SC_OPCODE_POISSON_DIST { Text = "POISSON" ; }; + String SC_OPCODE_KOMBIN { Text = "COMBIN" ; }; + String SC_OPCODE_KOMBIN_2 { Text = "COMBINA" ; }; + String SC_OPCODE_VARIATIONEN { Text = "PERMUT" ; }; + String SC_OPCODE_VARIATIONEN_2 { Text = "PERMUTATIONA" ; }; + String SC_OPCODE_BW { Text = "PV" ; }; + String SC_OPCODE_DIA { Text = "SYD" ; }; + String SC_OPCODE_GDA { Text = "DDB" ; }; + String SC_OPCODE_GDA_2 { Text = "DB" ; }; + String SC_OPCODE_VBD { Text = "VDB" ; }; + String SC_OPCODE_LAUFZ { Text = "PDURATION" ; }; + String SC_OPCODE_LIA { Text = "SLN" ; }; + String SC_OPCODE_RMZ { Text = "PMT" ; }; + String SC_OPCODE_COLUMNS { Text = "COLUMNS" ; }; + String SC_OPCODE_ROWS { Text = "ROWS" ; }; + String SC_OPCODE_TABLES { Text = "SHEETS" ; }; + String SC_OPCODE_COLUMN { Text = "COLUMN" ; }; + String SC_OPCODE_ROW { Text = "ROW" ; }; + String SC_OPCODE_TABLE { Text = "SHEET" ; }; + String SC_OPCODE_ZGZ { Text = "ZGZ" ; }; + String SC_OPCODE_ZW { Text = "FV" ; }; + String SC_OPCODE_ZZR { Text = "NPER" ; }; + String SC_OPCODE_ZINS { Text = "RATE" ; }; + String SC_OPCODE_ZINS_Z { Text = "IPMT" ; }; + String SC_OPCODE_KAPZ { Text = "PPMT" ; }; + String SC_OPCODE_KUM_ZINS_Z { Text = "CUMIPMT" ; }; + String SC_OPCODE_KUM_KAP_Z { Text = "CUMPRINC" ; }; + String SC_OPCODE_EFFEKTIV { Text = "EFFECT" ; }; + String SC_OPCODE_NOMINAL { Text = "NOMINAL" ; }; + String SC_OPCODE_SUB_TOTAL { Text = "SUBTOTAL" ; }; + String SC_OPCODE_DB_SUM { Text = "DSUM" ; }; + String SC_OPCODE_DB_COUNT { Text = "DCOUNT" ; }; + String SC_OPCODE_DB_COUNT_2 { Text = "DCOUNTA" ; }; + String SC_OPCODE_DB_AVERAGE { Text = "DAVERAGE" ; }; + String SC_OPCODE_DB_GET { Text = "DGET" ; }; + String SC_OPCODE_DB_MAX { Text = "DMAX" ; }; + String SC_OPCODE_DB_MIN { Text = "DMIN" ; }; + String SC_OPCODE_DB_PRODUCT { Text = "DPRODUCT" ; }; + String SC_OPCODE_DB_STD_DEV { Text = "DSTDEV" ; }; + String SC_OPCODE_DB_STD_DEV_P { Text = "DSTDEVP" ; }; + String SC_OPCODE_DB_VAR { Text = "DVAR" ; }; + String SC_OPCODE_DB_VAR_P { Text = "DVARP" ; }; + String SC_OPCODE_INDIRECT { Text = "INDIRECT" ; }; + String SC_OPCODE_ADDRESS { Text = "ADDRESS" ; }; + String SC_OPCODE_MATCH { Text = "MATCH" ; }; + String SC_OPCODE_COUNT_EMPTY_CELLS { Text = "COUNTBLANK" ; }; + String SC_OPCODE_COUNT_IF { Text = "COUNTIF" ; }; + String SC_OPCODE_SUM_IF { Text = "SUMIF" ; }; + String SC_OPCODE_LOOKUP { Text = "LOOKUP" ; }; + String SC_OPCODE_V_LOOKUP { Text = "VLOOKUP" ; }; + String SC_OPCODE_H_LOOKUP { Text = "HLOOKUP" ; }; + String SC_OPCODE_MULTI_AREA { Text = "ORG.OPENOFFICE.MULTIRANGE" ; }; // legacy for range list (union) + String SC_OPCODE_OFFSET { Text = "OFFSET" ; }; + String SC_OPCODE_INDEX { Text = "INDEX" ; }; + String SC_OPCODE_AREAS { Text = "AREAS" ; }; + String SC_OPCODE_CURRENCY { Text = "DOLLAR" ; }; + String SC_OPCODE_REPLACE { Text = "REPLACE" ; }; + String SC_OPCODE_FIXED { Text = "FIXED" ; }; + String SC_OPCODE_FIND { Text = "FIND" ; }; + String SC_OPCODE_EXACT { Text = "EXACT" ; }; + String SC_OPCODE_LEFT { Text = "LEFT" ; }; + String SC_OPCODE_RIGHT { Text = "RIGHT" ; }; + String SC_OPCODE_SEARCH { Text = "SEARCH" ; }; + String SC_OPCODE_MID { Text = "MID" ; }; + String SC_OPCODE_TEXT { Text = "TEXT" ; }; + String SC_OPCODE_SUBSTITUTE { Text = "SUBSTITUTE" ; }; + String SC_OPCODE_REPT { Text = "REPT" ; }; + String SC_OPCODE_CONCAT { Text = "CONCATENATE" ; }; + String SC_OPCODE_MAT_VALUE { Text = "MVALUE" ; }; + String SC_OPCODE_MAT_DET { Text = "MDETERM" ; }; + String SC_OPCODE_MAT_INV { Text = "MINVERSE" ; }; + String SC_OPCODE_MAT_MULT { Text = "MMULT" ; }; + String SC_OPCODE_MAT_TRANS { Text = "TRANSPOSE" ; }; + String SC_OPCODE_MATRIX_UNIT { Text = "MUNIT" ; }; + String SC_OPCODE_BACK_SOLVER { Text = "GOALSEEK" ; }; + String SC_OPCODE_HYP_GEOM_DIST { Text = "HYPGEOMDIST" ; }; + String SC_OPCODE_LOG_NORM_DIST { Text = "LOGNORMDIST" ; }; + String SC_OPCODE_T_DIST { Text = "TDIST" ; }; + String SC_OPCODE_F_DIST { Text = "LEGACY.FDIST" ; }; + String SC_OPCODE_CHI_DIST { Text = "LEGACY.CHIDIST" ; }; + String SC_OPCODE_WEIBULL { Text = "WEIBULL" ; }; + String SC_OPCODE_NEG_BINOM_VERT { Text = "NEGBINOMDIST" ; }; + String SC_OPCODE_KRIT_BINOM { Text = "CRITBINOM" ; }; + String SC_OPCODE_KURT { Text = "KURT" ; }; + String SC_OPCODE_HAR_MEAN { Text = "HARMEAN" ; }; + String SC_OPCODE_GEO_MEAN { Text = "GEOMEAN" ; }; + String SC_OPCODE_STANDARD { Text = "STANDARDIZE" ; }; + String SC_OPCODE_AVE_DEV { Text = "AVEDEV" ; }; + String SC_OPCODE_SCHIEFE { Text = "SKEW" ; }; + String SC_OPCODE_DEV_SQ { Text = "DEVSQ" ; }; + String SC_OPCODE_MEDIAN { Text = "MEDIAN" ; }; + String SC_OPCODE_MODAL_VALUE { Text = "MODE" ; }; + String SC_OPCODE_Z_TEST { Text = "ZTEST" ; }; + String SC_OPCODE_T_TEST { Text = "TTEST" ; }; + String SC_OPCODE_RANK { Text = "RANK" ; }; + String SC_OPCODE_PERCENTILE { Text = "PERCENTILE" ; }; + String SC_OPCODE_PERCENT_RANK { Text = "PERCENTRANK" ; }; + String SC_OPCODE_LARGE { Text = "LARGE" ; }; + String SC_OPCODE_SMALL { Text = "SMALL" ; }; + String SC_OPCODE_FREQUENCY { Text = "FREQUENCY" ; }; + String SC_OPCODE_QUARTILE { Text = "QUARTILE" ; }; + String SC_OPCODE_NORM_INV { Text = "NORMINV" ; }; + String SC_OPCODE_CONFIDENCE { Text = "CONFIDENCE" ; }; + String SC_OPCODE_F_TEST { Text = "FTEST" ; }; + String SC_OPCODE_TRIM_MEAN { Text = "TRIMMEAN" ; }; + String SC_OPCODE_PROB { Text = "PROB" ; }; + String SC_OPCODE_CORREL { Text = "CORREL" ; }; + String SC_OPCODE_COVAR { Text = "COVAR" ; }; + String SC_OPCODE_PEARSON { Text = "PEARSON" ; }; + String SC_OPCODE_RSQ { Text = "RSQ" ; }; + String SC_OPCODE_STEYX { Text = "STEYX" ; }; + String SC_OPCODE_SLOPE { Text = "SLOPE" ; }; + String SC_OPCODE_INTERCEPT { Text = "INTERCEPT" ; }; + String SC_OPCODE_TREND { Text = "TREND" ; }; + String SC_OPCODE_GROWTH { Text = "GROWTH" ; }; + String SC_OPCODE_RGP { Text = "LINEST" ; }; + String SC_OPCODE_RKP { Text = "LOGEST" ; }; + String SC_OPCODE_FORECAST { Text = "FORECAST" ; }; + String SC_OPCODE_CHI_INV { Text = "LEGACY.CHIINV" ; }; + String SC_OPCODE_GAMMA_DIST { Text = "GAMMADIST" ; }; + String SC_OPCODE_GAMMA_INV { Text = "GAMMAINV" ; }; + String SC_OPCODE_T_INV { Text = "TINV" ; }; + String SC_OPCODE_F_INV { Text = "LEGACY.FINV" ; }; + String SC_OPCODE_CHI_TEST { Text = "LEGACY.CHITEST" ; }; + String SC_OPCODE_LOG_INV { Text = "LOGINV" ; }; + String SC_OPCODE_TABLE_OP { Text = "MULTIPLE.OPERATIONS" ; }; + String SC_OPCODE_BETA_DIST { Text = "BETADIST" ; }; + String SC_OPCODE_BETA_INV { Text = "BETAINV" ; }; + String SC_OPCODE_WEEK { Text = "ISOWEEKNUM" ; }; + String SC_OPCODE_EASTERSUNDAY { Text = "EASTERSUNDAY" ; }; + String SC_OPCODE_GET_DAY_OF_WEEK { Text = "WEEKDAY" ; }; + String SC_OPCODE_NO_NAME { Text = "#NAME!" ; }; + String SC_OPCODE_STYLE { Text = "ORG.OPENOFFICE.STYLE" ; }; + String SC_OPCODE_DDE { Text = "DDE" ; }; + String SC_OPCODE_BASE { Text = "BASE" ; }; + String SC_OPCODE_DECIMAL { Text = "DECIMAL" ; }; + String SC_OPCODE_CONVERT { Text = "ORG.OPENOFFICE.CONVERT" ; }; + String SC_OPCODE_ROMAN { Text = "ROMAN" ; }; + String SC_OPCODE_ARABIC { Text = "ARABIC" ; }; + String SC_OPCODE_HYPERLINK { Text = "HYPERLINK" ; }; + String SC_OPCODE_INFO { Text = "INFO" ; }; + String SC_OPCODE_BAHTTEXT { Text = "COM.MICROSOFT.BAHTTEXT" ; }; + String SC_OPCODE_GET_PIVOT_DATA { Text = "GETPIVOTDATA" ; }; + String SC_OPCODE_EUROCONVERT { Text = "EUROCONVERT" ; }; + String SC_OPCODE_NUMBERVALUE { Text = "NUMBERVALUE" ; }; + String SC_OPCODE_GAMMA { Text = "GAMMA" ; }; + String SC_OPCODE_CHISQ_DIST { Text = "CHISQDIST" ; }; + String SC_OPCODE_CHISQ_INV { Text = "CHISQINV" ;}; + + /* BEGIN defined ERROR.TYPE() values. */ + String SC_OPCODE_ERROR_NULL { Text = "#NULL!" ; }; + String SC_OPCODE_ERROR_DIVZERO { Text = "#DIV/0!" ; }; + String SC_OPCODE_ERROR_VALUE { Text = "#VALUE!" ; }; + String SC_OPCODE_ERROR_REF { Text = "#REF!" ; }; + String SC_OPCODE_ERROR_NAME { Text = "#NAME?" ; }; + String SC_OPCODE_ERROR_NUM { Text = "#NUM!" ; }; + String SC_OPCODE_ERROR_NA { Text = "#N/A" ; }; + /* END defined ERROR.TYPE() values. */ +}; +// DO NOT CHANGE! +// These English names are used internally to store/load ODF v1.0/v1.1 and for +// API XFunctionAccess. +Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH +{ + String SC_OPCODE_IF { Text = "IF" ; }; + String SC_OPCODE_CHOSE { Text = "CHOOSE" ; }; + String SC_OPCODE_OPEN { Text = "(" ; }; + String SC_OPCODE_CLOSE { Text = ")" ; }; + String SC_OPCODE_ARRAY_OPEN { Text = "{" ; }; + String SC_OPCODE_ARRAY_CLOSE { Text = "}" ; }; + String SC_OPCODE_ARRAY_ROW_SEP { Text = "|" ; }; + String SC_OPCODE_ARRAY_COL_SEP { Text = ";" ; }; + String SC_OPCODE_SEP { Text = ";" ; }; + String SC_OPCODE_PERCENT_SIGN { Text = "%" ; }; + String SC_OPCODE_ADD { Text = "+" ; }; + String SC_OPCODE_SUB { Text = "-" ; }; + String SC_OPCODE_MUL { Text = "*" ; }; + String SC_OPCODE_DIV { Text = "/" ; }; + String SC_OPCODE_AMPERSAND { Text = "&" ; }; + String SC_OPCODE_POW { Text = "^" ; }; + String SC_OPCODE_EQUAL { Text = "=" ; }; + String SC_OPCODE_NOT_EQUAL { Text = "<>" ; }; + String SC_OPCODE_LESS { Text = "<" ; }; + String SC_OPCODE_GREATER { Text = ">" ; }; + String SC_OPCODE_LESS_EQUAL { Text = "<=" ; }; + String SC_OPCODE_GREATER_EQUAL { Text = ">=" ; }; + String SC_OPCODE_AND { Text = "AND" ; }; + String SC_OPCODE_OR { Text = "OR" ; }; + String SC_OPCODE_INTERSECT { Text = "!" ; }; + String SC_OPCODE_UNION { Text = "~" ; }; + String SC_OPCODE_RANGE { Text = ":" ; }; + String SC_OPCODE_NOT { Text = "NOT" ; }; + String SC_OPCODE_NEG { Text = "NEG" ; }; + String SC_OPCODE_NEG_SUB { Text = "-" ; }; + String SC_OPCODE_PI { Text = "PI" ; }; + String SC_OPCODE_RANDOM { Text = "RAND" ; }; + String SC_OPCODE_TRUE { Text = "TRUE" ; }; + String SC_OPCODE_FALSE { Text = "FALSE" ; }; + String SC_OPCODE_GET_ACT_DATE { Text = "TODAY" ; }; + String SC_OPCODE_GET_ACT_TIME { Text = "NOW" ; }; + String SC_OPCODE_NO_VALUE { Text = "NA" ; }; + String SC_OPCODE_CURRENT { Text = "CURRENT" ; }; + String SC_OPCODE_DEG { Text = "DEGREES" ; }; + String SC_OPCODE_RAD { Text = "RADIANS" ; }; + String SC_OPCODE_SIN { Text = "SIN" ; }; + String SC_OPCODE_COS { Text = "COS" ; }; + String SC_OPCODE_TAN { Text = "TAN" ; }; + String SC_OPCODE_COT { Text = "COT" ; }; + String SC_OPCODE_ARC_SIN { Text = "ASIN" ; }; + String SC_OPCODE_ARC_COS { Text = "ACOS" ; }; + String SC_OPCODE_ARC_TAN { Text = "ATAN" ; }; + String SC_OPCODE_ARC_COT { Text = "ACOT" ; }; + String SC_OPCODE_SIN_HYP { Text = "SINH" ; }; + String SC_OPCODE_COS_HYP { Text = "COSH" ; }; + String SC_OPCODE_TAN_HYP { Text = "TANH" ; }; + String SC_OPCODE_COT_HYP { Text = "COTH" ; }; + String SC_OPCODE_ARC_SIN_HYP { Text = "ASINH" ; }; + String SC_OPCODE_ARC_COS_HYP { Text = "ACOSH" ; }; + String SC_OPCODE_ARC_TAN_HYP { Text = "ATANH" ; }; + String SC_OPCODE_ARC_COT_HYP { Text = "ACOTH" ; }; + String SC_OPCODE_EXP { Text = "EXP" ; }; + String SC_OPCODE_LN { Text = "LN" ; }; + String SC_OPCODE_SQRT { Text = "SQRT" ; }; + String SC_OPCODE_FACT { Text = "FACT" ; }; + String SC_OPCODE_GET_YEAR { Text = "YEAR" ; }; + String SC_OPCODE_GET_MONTH { Text = "MONTH" ; }; + String SC_OPCODE_GET_DAY { Text = "DAY" ; }; + String SC_OPCODE_GET_HOUR { Text = "HOUR" ; }; + String SC_OPCODE_GET_MIN { Text = "MINUTE" ; }; + String SC_OPCODE_GET_SEC { Text = "SECOND" ; }; + String SC_OPCODE_PLUS_MINUS { Text = "SIGN" ; }; + String SC_OPCODE_ABS { Text = "ABS" ; }; + String SC_OPCODE_INT { Text = "INT" ; }; + String SC_OPCODE_PHI { Text = "PHI" ; }; + String SC_OPCODE_GAUSS { Text = "GAUSS" ; }; + String SC_OPCODE_IS_EMPTY { Text = "ISBLANK" ; }; + String SC_OPCODE_IS_STRING { Text = "ISTEXT" ; }; + String SC_OPCODE_IS_NON_STRING { Text = "ISNONTEXT" ; }; + String SC_OPCODE_IS_LOGICAL { Text = "ISLOGICAL" ; }; + String SC_OPCODE_TYPE { Text = "TYPE" ; }; + String SC_OPCODE_CELL { Text = "CELL" ; }; + String SC_OPCODE_IS_REF { Text = "ISREF" ; }; + String SC_OPCODE_IS_VALUE { Text = "ISNUMBER" ; }; + String SC_OPCODE_IS_FORMULA { Text = "ISFORMULA" ; }; + String SC_OPCODE_IS_NV { Text = "ISNA" ; }; + String SC_OPCODE_IS_ERR { Text = "ISERR" ; }; + String SC_OPCODE_IS_ERROR { Text = "ISERROR" ; }; + String SC_OPCODE_IS_EVEN { Text = "ISEVEN" ; }; + String SC_OPCODE_IS_ODD { Text = "ISODD" ; }; + String SC_OPCODE_N { Text = "N" ; }; + String SC_OPCODE_GET_DATE_VALUE { Text = "DATEVALUE" ; }; + String SC_OPCODE_GET_TIME_VALUE { Text = "TIMEVALUE" ; }; + String SC_OPCODE_CODE { Text = "CODE" ; }; + String SC_OPCODE_TRIM { Text = "TRIM" ; }; + String SC_OPCODE_UPPER { Text = "UPPER" ; }; + String SC_OPCODE_PROPPER { Text = "PROPER" ; }; + String SC_OPCODE_LOWER { Text = "LOWER" ; }; + String SC_OPCODE_LEN { Text = "LEN" ; }; + String SC_OPCODE_T { Text = "T" ; }; + String SC_OPCODE_VALUE { Text = "VALUE" ; }; + String SC_OPCODE_CLEAN { Text = "CLEAN" ; }; + String SC_OPCODE_CHAR { Text = "CHAR" ; }; + String SC_OPCODE_JIS { Text = "JIS" ; }; + String SC_OPCODE_ASC { Text = "ASC" ; }; + String SC_OPCODE_UNICODE { Text = "UNICODE" ; }; + String SC_OPCODE_UNICHAR { Text = "UNICHAR" ; }; + String SC_OPCODE_LOG10 { Text = "LOG10" ; }; + String SC_OPCODE_EVEN { Text = "EVEN" ; }; + String SC_OPCODE_ODD { Text = "ODD" ; }; + String SC_OPCODE_STD_NORM_DIST { Text = "NORMSDIST" ; }; + String SC_OPCODE_FISHER { Text = "FISHER" ; }; + String SC_OPCODE_FISHER_INV { Text = "FISHERINV" ; }; + String SC_OPCODE_S_NORM_INV { Text = "NORMSINV" ; }; + String SC_OPCODE_GAMMA_LN { Text = "GAMMALN" ; }; + String SC_OPCODE_ERROR_TYPE { Text = "ERRORTYPE" ; }; + String SC_OPCODE_ERR_CELL { Text = "ZellError" ; }; // TODO: ancient legacy only, remove? + String SC_OPCODE_FORMULA { Text = "FORMULA"; }; + String SC_OPCODE_ARC_TAN_2 { Text = "ATAN2" ; }; + String SC_OPCODE_CEIL { Text = "CEILING" ; }; + String SC_OPCODE_FLOOR { Text = "FLOOR" ; }; + String SC_OPCODE_ROUND { Text = "ROUND" ; }; + String SC_OPCODE_ROUND_UP { Text = "ROUNDUP" ; }; + String SC_OPCODE_ROUND_DOWN { Text = "ROUNDDOWN" ; }; + String SC_OPCODE_TRUNC { Text = "TRUNC" ; }; + String SC_OPCODE_LOG { Text = "LOG" ; }; + String SC_OPCODE_POWER { Text = "POWER" ; }; + String SC_OPCODE_GGT { Text = "GCD" ; }; + String SC_OPCODE_KGV { Text = "LCM" ; }; + String SC_OPCODE_MOD { Text = "MOD" ; }; + String SC_OPCODE_SUM_PRODUCT { Text = "SUMPRODUCT" ; }; + String SC_OPCODE_SUM_SQ { Text = "SUMSQ" ; }; + String SC_OPCODE_SUM_X2MY2 { Text = "SUMX2MY2" ; }; + String SC_OPCODE_SUM_X2DY2 { Text = "SUMX2PY2" ; }; + String SC_OPCODE_SUM_XMY2 { Text = "SUMXMY2" ; }; + String SC_OPCODE_GET_DATE { Text = "DATE" ; }; + String SC_OPCODE_GET_TIME { Text = "TIME" ; }; + String SC_OPCODE_GET_DIFF_DATE { Text = "DAYS" ; }; + String SC_OPCODE_GET_DIFF_DATE_360 { Text = "DAYS360" ; }; + String SC_OPCODE_MIN { Text = "MIN" ; }; + String SC_OPCODE_MIN_A { Text = "MINA" ; }; + String SC_OPCODE_MAX { Text = "MAX" ; }; + String SC_OPCODE_MAX_A { Text = "MAXA" ; }; + String SC_OPCODE_SUM { Text = "SUM" ; }; + String SC_OPCODE_PRODUCT { Text = "PRODUCT" ; }; + String SC_OPCODE_AVERAGE { Text = "AVERAGE" ; }; + String SC_OPCODE_AVERAGE_A { Text = "AVERAGEA" ; }; + String SC_OPCODE_COUNT { Text = "COUNT" ; }; + String SC_OPCODE_COUNT_2 { Text = "COUNTA" ; }; + String SC_OPCODE_NBW { Text = "NPV" ; }; + String SC_OPCODE_IKV { Text = "IRR" ; }; + String SC_OPCODE_MIRR { Text = "MIRR" ; }; + String SC_OPCODE_ISPMT { Text = "ISPMT" ; }; + String SC_OPCODE_VAR { Text = "VAR" ; }; + String SC_OPCODE_VAR_A { Text = "VARA" ; }; + String SC_OPCODE_VAR_P { Text = "VARP" ; }; + String SC_OPCODE_VAR_P_A { Text = "VARPA" ; }; + String SC_OPCODE_ST_DEV { Text = "STDEV" ; }; + String SC_OPCODE_ST_DEV_A { Text = "STDEVA" ; }; + String SC_OPCODE_ST_DEV_P { Text = "STDEVP" ; }; + String SC_OPCODE_ST_DEV_P_A { Text = "STDEVPA" ; }; + String SC_OPCODE_B { Text = "B" ; }; + String SC_OPCODE_NORM_DIST { Text = "NORMDIST" ; }; + String SC_OPCODE_EXP_DIST { Text = "EXPONDIST" ; }; + String SC_OPCODE_BINOM_DIST { Text = "BINOMDIST" ; }; + String SC_OPCODE_POISSON_DIST { Text = "POISSON" ; }; + String SC_OPCODE_KOMBIN { Text = "COMBIN" ; }; + String SC_OPCODE_KOMBIN_2 { Text = "COMBINA" ; }; + String SC_OPCODE_VARIATIONEN { Text = "PERMUT" ; }; + String SC_OPCODE_VARIATIONEN_2 { Text = "PERMUTATIONA" ; }; + String SC_OPCODE_BW { Text = "PV" ; }; + String SC_OPCODE_DIA { Text = "SYD" ; }; + String SC_OPCODE_GDA { Text = "DDB" ; }; + String SC_OPCODE_GDA_2 { Text = "DB" ; }; + String SC_OPCODE_VBD { Text = "VDB" ; }; + String SC_OPCODE_LAUFZ { Text = "DURATION" ; }; + String SC_OPCODE_LIA { Text = "SLN" ; }; + String SC_OPCODE_RMZ { Text = "PMT" ; }; + String SC_OPCODE_COLUMNS { Text = "COLUMNS" ; }; + String SC_OPCODE_ROWS { Text = "ROWS" ; }; + String SC_OPCODE_TABLES { Text = "SHEETS" ; }; + String SC_OPCODE_COLUMN { Text = "COLUMN" ; }; + String SC_OPCODE_ROW { Text = "ROW" ; }; + String SC_OPCODE_TABLE { Text = "SHEET" ; }; + String SC_OPCODE_ZGZ { Text = "ZGZ" ; }; + String SC_OPCODE_ZW { Text = "FV" ; }; + String SC_OPCODE_ZZR { Text = "NPER" ; }; + String SC_OPCODE_ZINS { Text = "RATE" ; }; + String SC_OPCODE_ZINS_Z { Text = "IPMT" ; }; + String SC_OPCODE_KAPZ { Text = "PPMT" ; }; + String SC_OPCODE_KUM_ZINS_Z { Text = "CUMIPMT" ; }; + String SC_OPCODE_KUM_KAP_Z { Text = "CUMPRINC" ; }; + String SC_OPCODE_EFFEKTIV { Text = "EFFECTIVE" ; }; + String SC_OPCODE_NOMINAL { Text = "NOMINAL" ; }; + String SC_OPCODE_SUB_TOTAL { Text = "SUBTOTAL" ; }; + String SC_OPCODE_DB_SUM { Text = "DSUM" ; }; + String SC_OPCODE_DB_COUNT { Text = "DCOUNT" ; }; + String SC_OPCODE_DB_COUNT_2 { Text = "DCOUNTA" ; }; + String SC_OPCODE_DB_AVERAGE { Text = "DAVERAGE" ; }; + String SC_OPCODE_DB_GET { Text = "DGET" ; }; + String SC_OPCODE_DB_MAX { Text = "DMAX" ; }; + String SC_OPCODE_DB_MIN { Text = "DMIN" ; }; + String SC_OPCODE_DB_PRODUCT { Text = "DPRODUCT" ; }; + String SC_OPCODE_DB_STD_DEV { Text = "DSTDEV" ; }; + String SC_OPCODE_DB_STD_DEV_P { Text = "DSTDEVP" ; }; + String SC_OPCODE_DB_VAR { Text = "DVAR" ; }; + String SC_OPCODE_DB_VAR_P { Text = "DVARP" ; }; + String SC_OPCODE_INDIRECT { Text = "INDIRECT" ; }; + String SC_OPCODE_ADDRESS { Text = "ADDRESS" ; }; + String SC_OPCODE_MATCH { Text = "MATCH" ; }; + String SC_OPCODE_COUNT_EMPTY_CELLS { Text = "COUNTBLANK" ; }; + String SC_OPCODE_COUNT_IF { Text = "COUNTIF" ; }; + String SC_OPCODE_SUM_IF { Text = "SUMIF" ; }; + String SC_OPCODE_LOOKUP { Text = "LOOKUP" ; }; + String SC_OPCODE_V_LOOKUP { Text = "VLOOKUP" ; }; + String SC_OPCODE_H_LOOKUP { Text = "HLOOKUP" ; }; + String SC_OPCODE_MULTI_AREA { Text = "MULTIRANGE" ; }; // legacy for range list (union) + String SC_OPCODE_OFFSET { Text = "OFFSET" ; }; + String SC_OPCODE_INDEX { Text = "INDEX" ; }; + String SC_OPCODE_AREAS { Text = "AREAS" ; }; + String SC_OPCODE_CURRENCY { Text = "DOLLAR" ; }; + String SC_OPCODE_REPLACE { Text = "REPLACE" ; }; + String SC_OPCODE_FIXED { Text = "FIXED" ; }; + String SC_OPCODE_FIND { Text = "FIND" ; }; + String SC_OPCODE_EXACT { Text = "EXACT" ; }; + String SC_OPCODE_LEFT { Text = "LEFT" ; }; + String SC_OPCODE_RIGHT { Text = "RIGHT" ; }; + String SC_OPCODE_SEARCH { Text = "SEARCH" ; }; + String SC_OPCODE_MID { Text = "MID" ; }; + String SC_OPCODE_TEXT { Text = "TEXT" ; }; + String SC_OPCODE_SUBSTITUTE { Text = "SUBSTITUTE" ; }; + String SC_OPCODE_REPT { Text = "REPT" ; }; + String SC_OPCODE_CONCAT { Text = "CONCATENATE" ; }; + String SC_OPCODE_MAT_VALUE { Text = "MVALUE" ; }; + String SC_OPCODE_MAT_DET { Text = "MDETERM" ; }; + String SC_OPCODE_MAT_INV { Text = "MINVERSE" ; }; + String SC_OPCODE_MAT_MULT { Text = "MMULT" ; }; + String SC_OPCODE_MAT_TRANS { Text = "TRANSPOSE" ; }; + String SC_OPCODE_MATRIX_UNIT { Text = "MUNIT" ; }; + String SC_OPCODE_BACK_SOLVER { Text = "GOALSEEK" ; }; + String SC_OPCODE_HYP_GEOM_DIST { Text = "HYPGEOMDIST" ; }; + String SC_OPCODE_LOG_NORM_DIST { Text = "LOGNORMDIST" ; }; + String SC_OPCODE_T_DIST { Text = "TDIST" ; }; + String SC_OPCODE_F_DIST { Text = "FDIST" ; }; + String SC_OPCODE_CHI_DIST { Text = "CHIDIST" ; }; + String SC_OPCODE_WEIBULL { Text = "WEIBULL" ; }; + String SC_OPCODE_NEG_BINOM_VERT { Text = "NEGBINOMDIST" ; }; + String SC_OPCODE_KRIT_BINOM { Text = "CRITBINOM" ; }; + String SC_OPCODE_KURT { Text = "KURT" ; }; + String SC_OPCODE_HAR_MEAN { Text = "HARMEAN" ; }; + String SC_OPCODE_GEO_MEAN { Text = "GEOMEAN" ; }; + String SC_OPCODE_STANDARD { Text = "STANDARDIZE" ; }; + String SC_OPCODE_AVE_DEV { Text = "AVEDEV" ; }; + String SC_OPCODE_SCHIEFE { Text = "SKEW" ; }; + String SC_OPCODE_DEV_SQ { Text = "DEVSQ" ; }; + String SC_OPCODE_MEDIAN { Text = "MEDIAN" ; }; + String SC_OPCODE_MODAL_VALUE { Text = "MODE" ; }; + String SC_OPCODE_Z_TEST { Text = "ZTEST" ; }; + String SC_OPCODE_T_TEST { Text = "TTEST" ; }; + String SC_OPCODE_RANK { Text = "RANK" ; }; + String SC_OPCODE_PERCENTILE { Text = "PERCENTILE" ; }; + String SC_OPCODE_PERCENT_RANK { Text = "PERCENTRANK" ; }; + String SC_OPCODE_LARGE { Text = "LARGE" ; }; + String SC_OPCODE_SMALL { Text = "SMALL" ; }; + String SC_OPCODE_FREQUENCY { Text = "FREQUENCY" ; }; + String SC_OPCODE_QUARTILE { Text = "QUARTILE" ; }; + String SC_OPCODE_NORM_INV { Text = "NORMINV" ; }; + String SC_OPCODE_CONFIDENCE { Text = "CONFIDENCE" ; }; + String SC_OPCODE_F_TEST { Text = "FTEST" ; }; + String SC_OPCODE_TRIM_MEAN { Text = "TRIMMEAN" ; }; + String SC_OPCODE_PROB { Text = "PROB" ; }; + String SC_OPCODE_CORREL { Text = "CORREL" ; }; + String SC_OPCODE_COVAR { Text = "COVAR" ; }; + String SC_OPCODE_PEARSON { Text = "PEARSON" ; }; + String SC_OPCODE_RSQ { Text = "RSQ" ; }; + String SC_OPCODE_STEYX { Text = "STEYX" ; }; + String SC_OPCODE_SLOPE { Text = "SLOPE" ; }; + String SC_OPCODE_INTERCEPT { Text = "INTERCEPT" ; }; + String SC_OPCODE_TREND { Text = "TREND" ; }; + String SC_OPCODE_GROWTH { Text = "GROWTH" ; }; + String SC_OPCODE_RGP { Text = "LINEST" ; }; + String SC_OPCODE_RKP { Text = "LOGEST" ; }; + String SC_OPCODE_FORECAST { Text = "FORECAST" ; }; + String SC_OPCODE_CHI_INV { Text = "CHIINV" ; }; + String SC_OPCODE_GAMMA_DIST { Text = "GAMMADIST" ; }; + String SC_OPCODE_GAMMA_INV { Text = "GAMMAINV" ; }; + String SC_OPCODE_T_INV { Text = "TINV" ; }; + String SC_OPCODE_F_INV { Text = "FINV" ; }; + String SC_OPCODE_CHI_TEST { Text = "CHITEST" ; }; + String SC_OPCODE_LOG_INV { Text = "LOGINV" ; }; + String SC_OPCODE_TABLE_OP { Text = "TABLE" ; }; + String SC_OPCODE_BETA_DIST { Text = "BETADIST" ; }; + String SC_OPCODE_BETA_INV { Text = "BETAINV" ; }; + String SC_OPCODE_WEEK { Text = "WEEKNUM" ; }; + String SC_OPCODE_EASTERSUNDAY { Text = "EASTERSUNDAY" ; }; + String SC_OPCODE_GET_DAY_OF_WEEK { Text = "WEEKDAY" ; }; + String SC_OPCODE_NO_NAME { Text = "#NAME!" ; }; + String SC_OPCODE_STYLE { Text = "STYLE" ; }; + String SC_OPCODE_DDE { Text = "DDE" ; }; + String SC_OPCODE_BASE { Text = "BASE" ; }; + String SC_OPCODE_DECIMAL { Text = "DECIMAL" ; }; + String SC_OPCODE_CONVERT { Text = "CONVERT" ; }; + String SC_OPCODE_ROMAN { Text = "ROMAN" ; }; + String SC_OPCODE_ARABIC { Text = "ARABIC" ; }; + String SC_OPCODE_HYPERLINK { Text = "HYPERLINK" ; }; + String SC_OPCODE_INFO { Text = "INFO" ; }; + String SC_OPCODE_BAHTTEXT { Text = "BAHTTEXT" ; }; + String SC_OPCODE_GET_PIVOT_DATA { Text = "GETPIVOTDATA" ; }; + String SC_OPCODE_EUROCONVERT { Text = "EUROCONVERT" ; }; + String SC_OPCODE_NUMBERVALUE { Text = "NUMBERVALUE" ; }; + String SC_OPCODE_GAMMA { Text = "GAMMA" ; }; + String SC_OPCODE_CHISQ_DIST { Text = "CHISQDIST" ; }; + String SC_OPCODE_CHISQ_INV { Text = "CHISQINV" ;}; + + /* BEGIN defined ERROR.TYPE() values. */ + String SC_OPCODE_ERROR_NULL { Text = "#NULL!" ; }; + String SC_OPCODE_ERROR_DIVZERO { Text = "#DIV/0!" ; }; + String SC_OPCODE_ERROR_VALUE { Text = "#VALUE!" ; }; + String SC_OPCODE_ERROR_REF { Text = "#REF!" ; }; + String SC_OPCODE_ERROR_NAME { Text = "#NAME?" ; }; + String SC_OPCODE_ERROR_NUM { Text = "#NUM!" ; }; + String SC_OPCODE_ERROR_NA { Text = "#N/A" ; }; + /* END defined ERROR.TYPE() values. */ +}; +Resource RID_STRLIST_FUNCTION_NAMES +{ + String SC_OPCODE_IF + { + Text [ en-US ] = "IF" ; + }; + String SC_OPCODE_CHOSE + { + Text [ en-US ] = "CHOOSE" ; + }; + String SC_OPCODE_OPEN { Text = "(" ; }; + String SC_OPCODE_CLOSE { Text = ")" ; }; + String SC_OPCODE_ARRAY_OPEN { Text = "{" ; }; + String SC_OPCODE_ARRAY_CLOSE { Text = "}" ; }; + String SC_OPCODE_ARRAY_ROW_SEP { Text = "|" ; }; + String SC_OPCODE_ARRAY_COL_SEP { Text = ";" ; }; + String SC_OPCODE_SEP { Text = ";" ; }; + String SC_OPCODE_PERCENT_SIGN { Text = "%" ; }; + String SC_OPCODE_ADD { Text = "+" ; }; + String SC_OPCODE_SUB { Text = "-" ; }; + String SC_OPCODE_MUL { Text = "*" ; }; + String SC_OPCODE_DIV { Text = "/" ; }; + String SC_OPCODE_AMPERSAND { Text = "&" ; }; + String SC_OPCODE_POW { Text = "^" ; }; + String SC_OPCODE_EQUAL { Text = "=" ; }; + String SC_OPCODE_NOT_EQUAL { Text = "<>" ; }; + String SC_OPCODE_LESS { Text = "<" ; }; + String SC_OPCODE_GREATER { Text = ">" ; }; + String SC_OPCODE_LESS_EQUAL { Text = "<=" ; }; + String SC_OPCODE_GREATER_EQUAL { Text = ">=" ; }; + String SC_OPCODE_AND + { + Text [ en-US ] = "AND" ; + }; + String SC_OPCODE_OR + { + Text [ en-US ] = "OR" ; + }; + String SC_OPCODE_INTERSECT { Text = "!" ; }; + String SC_OPCODE_UNION { Text = "~" ; }; + String SC_OPCODE_RANGE { Text = ":" ; }; + String SC_OPCODE_NOT + { + Text [ en-US ] = "NOT" ; + }; + String SC_OPCODE_NEG + { + Text [ en-US ] = "NEG"; + }; + String SC_OPCODE_NEG_SUB { Text = "-" ; }; + String SC_OPCODE_PI + { + // ??? + Text [ en-US ] = "PI" ; + }; + String SC_OPCODE_RANDOM + { + Text [ en-US ] = "RAND" ; + }; + String SC_OPCODE_TRUE + { + Text [ en-US ] = "TRUE" ; + }; + String SC_OPCODE_FALSE + { + Text [ en-US ] = "FALSE" ; + }; + String SC_OPCODE_GET_ACT_DATE + { + Text [ en-US ] = "TODAY" ; + }; + String SC_OPCODE_GET_ACT_TIME + { + Text [ en-US ] = "NOW" ; + }; + String SC_OPCODE_NO_VALUE + { + Text [ en-US ] = "NA" ; + }; + String SC_OPCODE_CURRENT + { + Text [ en-US ] = "CURRENT" ; + }; + String SC_OPCODE_DEG + { + Text [ en-US ] = "DEGREES" ; + }; + String SC_OPCODE_RAD + { + Text [ en-US ] = "RADIANS" ; + }; + String SC_OPCODE_SIN + { + Text [ en-US ] = "SIN" ; + }; + String SC_OPCODE_COS + { + Text [ en-US ] = "COS"; + }; + String SC_OPCODE_TAN + { + Text [ en-US ] = "TAN"; + }; + String SC_OPCODE_COT + { + Text [ en-US ] = "COT"; + }; + String SC_OPCODE_ARC_SIN + { + Text [ en-US ] = "ASIN" ; + }; + String SC_OPCODE_ARC_COS + { + Text [ en-US ] = "ACOS" ; + }; + String SC_OPCODE_ARC_TAN + { + Text [ en-US ] = "ATAN" ; + }; + String SC_OPCODE_ARC_COT + { + Text [ en-US ] = "ACOT" ; + }; + String SC_OPCODE_SIN_HYP + { + Text [ en-US ] = "SINH" ; + }; + String SC_OPCODE_COS_HYP + { + Text [ en-US ] = "COSH" ; + }; + String SC_OPCODE_TAN_HYP + { + Text [ en-US ] = "TANH" ; + }; + String SC_OPCODE_COT_HYP + { + Text [ en-US ] = "COTH" ; + }; + String SC_OPCODE_ARC_SIN_HYP + { + Text [ en-US ] = "ASINH" ; + }; + String SC_OPCODE_ARC_COS_HYP + { + Text [ en-US ] = "ACOSH" ; + }; + String SC_OPCODE_ARC_TAN_HYP + { + Text [ en-US ] = "ATANH" ; + }; + String SC_OPCODE_ARC_COT_HYP + { + Text [ en-US ] = "ACOTH" ; + }; + String SC_OPCODE_EXP + { + Text [ en-US ] = "EXP"; + }; + String SC_OPCODE_LN + { + Text [ en-US ] = "LN"; + }; + String SC_OPCODE_SQRT + { + Text [ en-US ] = "SQRT" ; + }; + String SC_OPCODE_FACT + { + Text [ en-US ] = "FACT" ; + }; + String SC_OPCODE_GET_YEAR + { + Text [ en-US ] = "YEAR" ; + }; + String SC_OPCODE_GET_MONTH + { + Text [ en-US ] = "MONTH" ; + }; + String SC_OPCODE_GET_DAY + { + Text [ en-US ] = "DAY" ; + }; + String SC_OPCODE_GET_HOUR + { + Text [ en-US ] = "HOUR" ; + }; + String SC_OPCODE_GET_MIN + { + Text [ en-US ] = "MINUTE" ; + }; + String SC_OPCODE_GET_SEC + { + Text [ en-US ] = "SECOND" ; + }; + String SC_OPCODE_PLUS_MINUS + { + Text [ en-US ] = "SIGN" ; + }; + String SC_OPCODE_ABS + { + Text [ en-US ] = "ABS" ; + }; + String SC_OPCODE_INT + { + Text [ en-US ] = "INT" ; + }; + String SC_OPCODE_PHI + { + Text [ en-US ] = "PHI"; + }; + String SC_OPCODE_GAUSS + { + Text [ en-US ] = "GAUSS"; + }; + String SC_OPCODE_IS_EMPTY + { + Text [ en-US ] = "ISBLANK" ; + }; + String SC_OPCODE_IS_STRING + { + Text [ en-US ] = "ISTEXT" ; + }; + String SC_OPCODE_IS_NON_STRING + { + Text [ en-US ] = "ISNONTEXT" ; + }; + String SC_OPCODE_IS_LOGICAL + { + Text [ en-US ] = "ISLOGICAL" ; + }; + String SC_OPCODE_TYPE + { + Text [ en-US ] = "TYPE" ; + }; + String SC_OPCODE_CELL + { + Text [ en-US ] = "CELL"; + }; + String SC_OPCODE_IS_REF + { + Text [ en-US ] = "ISREF" ; + }; + String SC_OPCODE_IS_VALUE + { + Text [ en-US ] = "ISNUMBER" ; + }; + String SC_OPCODE_IS_FORMULA + { + Text [ en-US ] = "ISFORMULA" ; + }; + String SC_OPCODE_IS_NV + { + Text [ en-US ] = "ISNA" ; + }; + String SC_OPCODE_IS_ERR + { + Text [ en-US ] = "ISERR" ; + }; + String SC_OPCODE_IS_ERROR + { + Text [ en-US ] = "ISERROR" ; + }; + String SC_OPCODE_IS_EVEN + { + Text [ en-US ] = "ISEVEN" ; + }; + String SC_OPCODE_IS_ODD + { + Text [ en-US ] = "ISODD" ; + }; + String SC_OPCODE_N + { + Text [ en-US ] = "N" ; + }; + String SC_OPCODE_GET_DATE_VALUE + { + Text [ en-US ] = "DATEVALUE" ; + }; + String SC_OPCODE_GET_TIME_VALUE + { + Text [ en-US ] = "TIMEVALUE" ; + }; + String SC_OPCODE_CODE + { + Text [ en-US ] = "CODE" ; + }; + String SC_OPCODE_TRIM + { + Text [ en-US ] = "TRIM" ; + }; + String SC_OPCODE_UPPER + { + Text [ en-US ] = "UPPER" ; + }; + String SC_OPCODE_PROPPER + { + Text [ en-US ] = "PROPER" ; + }; + String SC_OPCODE_LOWER + { + Text [ en-US ] = "LOWER" ; + }; + String SC_OPCODE_LEN + { + Text [ en-US ] = "LEN" ; + }; + String SC_OPCODE_T + { + Text [ en-US ] = "T"; + }; + String SC_OPCODE_VALUE + { + Text [ en-US ] = "VALUE" ; + }; + String SC_OPCODE_CLEAN + { + Text [ en-US ] = "CLEAN" ; + }; + String SC_OPCODE_CHAR + { + Text [ en-US ] = "CHAR" ; + }; + String SC_OPCODE_JIS + { + Text [ en-US ] = "JIS" ; + }; + String SC_OPCODE_ASC + { + Text [ en-US ] = "ASC" ; + }; + String SC_OPCODE_UNICODE + { + Text [ en-US ] = "UNICODE" ; + }; + String SC_OPCODE_UNICHAR + { + Text [ en-US ] = "UNICHAR" ; + }; + String SC_OPCODE_LOG10 + { + Text [ en-US ] = "LOG10"; + }; + String SC_OPCODE_EVEN + { + Text [ en-US ] = "EVEN" ; + }; + String SC_OPCODE_ODD + { + Text [ en-US ] = "ODD" ; + }; + String SC_OPCODE_STD_NORM_DIST + { + Text [ en-US ] = "NORMSDIST" ; + }; + String SC_OPCODE_FISHER + { + Text [ en-US ] = "FISHER"; + }; + String SC_OPCODE_FISHER_INV + { + Text [ en-US ] = "FISHERINV" ; + }; + String SC_OPCODE_S_NORM_INV + { + Text [ en-US ] = "NORMSINV" ; + }; + String SC_OPCODE_GAMMA_LN + { + Text [ en-US ] = "GAMMALN" ; + }; + String SC_OPCODE_ERROR_TYPE + { + Text [ en-US ] = "ERRORTYPE" ; + }; + String SC_OPCODE_ERR_CELL { Text = "ZellError" ; }; // TODO: ancient legacy only, remove? + String SC_OPCODE_FORMULA + { + Text [ en-US ] = "FORMULA" ; + }; + String SC_OPCODE_ARABIC + { + Text [ en-US ] = "ARABIC"; + }; + String SC_OPCODE_ARC_TAN_2 + { + Text [ en-US ] = "ATAN2" ; + }; + String SC_OPCODE_CEIL + { + Text [ en-US ] = "CEILING" ; + }; + String SC_OPCODE_FLOOR + { + Text [ en-US ] = "FLOOR" ; + }; + String SC_OPCODE_ROUND + { + Text [ en-US ] = "ROUND" ; + }; + String SC_OPCODE_ROUND_UP + { + Text [ en-US ] = "ROUNDUP" ; + }; + String SC_OPCODE_ROUND_DOWN + { + Text [ en-US ] = "ROUNDDOWN" ; + }; + String SC_OPCODE_TRUNC + { + Text [ en-US ] = "TRUNC" ; + }; + String SC_OPCODE_LOG + { + Text [ en-US ] = "LOG"; + }; + String SC_OPCODE_POWER + { + Text [ en-US ] = "POWER" ; + }; + String SC_OPCODE_GGT + { + Text [ en-US ] = "GCD" ; + }; + String SC_OPCODE_KGV + { + Text [ en-US ] = "LCM" ; + }; + String SC_OPCODE_MOD + { + Text [ en-US ] = "MOD" ; + }; + String SC_OPCODE_SUM_PRODUCT + { + Text [ en-US ] = "SUMPRODUCT" ; + }; + String SC_OPCODE_SUM_SQ + { + Text [ en-US ] = "SUMSQ" ; + }; + String SC_OPCODE_SUM_X2MY2 + { + Text [ en-US ] = "SUMX2MY2" ; + }; + String SC_OPCODE_SUM_X2DY2 + { + Text [ en-US ] = "SUMX2PY2" ; + }; + String SC_OPCODE_SUM_XMY2 + { + Text [ en-US ] = "SUMXMY2" ; + }; + String SC_OPCODE_GET_DATE + { + Text [ en-US ] = "DATE" ; + }; + String SC_OPCODE_GET_TIME + { + Text [ en-US ] = "TIME" ; + }; + String SC_OPCODE_GET_DIFF_DATE + { + Text [ en-US ] = "DAYS" ; + }; + String SC_OPCODE_GET_DIFF_DATE_360 + { + Text [ en-US ] = "DAYS360" ; + }; + String SC_OPCODE_MIN + { + Text [ en-US ] = "MIN" ; + }; + String SC_OPCODE_MIN_A + { + Text [ en-US ] = "MINA" ; + }; + String SC_OPCODE_MAX + { + Text [ en-US ] = "MAX" ; + }; + String SC_OPCODE_MAX_A + { + Text [ en-US ] = "MAXA" ; + }; + String SC_OPCODE_SUM + { + Text [ en-US ] = "SUM" ; + }; + String SC_OPCODE_PRODUCT + { + Text [ en-US ] = "PRODUCT" ; + }; + String SC_OPCODE_AVERAGE + { + Text [ en-US ] = "AVERAGE" ; + }; + String SC_OPCODE_AVERAGE_A + { + Text [ en-US ] = "AVERAGEA" ; + }; + String SC_OPCODE_COUNT + { + Text [ en-US ] = "COUNT" ; + }; + String SC_OPCODE_COUNT_2 + { + Text [ en-US ] = "COUNTA" ; + }; + String SC_OPCODE_NBW + { + Text [ en-US ] = "NPV" ; + }; + String SC_OPCODE_IKV + { + Text [ en-US ] = "IRR" ; + }; + String SC_OPCODE_MIRR + { + Text [ en-US ] = "MIRR"; + }; + String SC_OPCODE_ISPMT + { + Text [ en-US ] = "ISPMT"; + }; + String SC_OPCODE_VAR + { + Text [ en-US ] = "VAR" ; + }; + String SC_OPCODE_VAR_A + { + Text [ en-US ] = "VARA" ; + }; + String SC_OPCODE_VAR_P + { + Text [ en-US ] = "VARP" ; + }; + String SC_OPCODE_VAR_P_A + { + Text [ en-US ] = "VARPA" ; + }; + String SC_OPCODE_ST_DEV + { + Text [ en-US ] = "STDEV" ; + }; + String SC_OPCODE_ST_DEV_A + { + Text [ en-US ] = "STDEVA" ; + }; + String SC_OPCODE_ST_DEV_P + { + Text [ en-US ] = "STDEVP" ; + }; + String SC_OPCODE_ST_DEV_P_A + { + Text [ en-US ] = "STDEVPA" ; + }; + String SC_OPCODE_B + { + Text [ en-US ] = "B"; + }; + String SC_OPCODE_NORM_DIST + { + Text [ en-US ] = "NORMDIST" ; + }; + String SC_OPCODE_EXP_DIST + { + Text [ en-US ] = "EXPONDIST" ; + }; + String SC_OPCODE_BINOM_DIST + { + Text [ en-US ] = "BINOMDIST" ; + }; + String SC_OPCODE_POISSON_DIST + { + Text [ en-US ] = "POISSON" ; + }; + String SC_OPCODE_KOMBIN + { + Text [ en-US ] = "COMBIN" ; + }; + String SC_OPCODE_KOMBIN_2 + { + Text [ en-US ] = "COMBINA" ; + }; + String SC_OPCODE_VARIATIONEN + { + Text [ en-US ] = "PERMUT" ; + }; + String SC_OPCODE_VARIATIONEN_2 + { + Text [ en-US ] = "PERMUTATIONA" ; + }; + String SC_OPCODE_BW + { + Text [ en-US ] = "PV" ; + }; + String SC_OPCODE_DIA + { + Text [ en-US ] = "SYD" ; + }; + String SC_OPCODE_GDA + { + Text [ en-US ] = "DDB" ; + }; + String SC_OPCODE_GDA_2 + { + Text [ en-US ] = "DB" ; + }; + String SC_OPCODE_VBD + { + Text [ en-US ] = "VDB" ; + }; + String SC_OPCODE_LAUFZ + { + Text [ en-US ] = "DURATION" ; + }; + String SC_OPCODE_LIA + { + Text [ en-US ] = "SLN" ; + }; + String SC_OPCODE_RMZ + { + Text [ en-US ] = "PMT" ; + }; + String SC_OPCODE_COLUMNS + { + Text [ en-US ] = "COLUMNS" ; + }; + String SC_OPCODE_ROWS + { + Text [ en-US ] = "ROWS" ; + }; + String SC_OPCODE_TABLES + { + Text [ en-US ] = "SHEETS" ; + }; + String SC_OPCODE_COLUMN + { + Text [ en-US ] = "COLUMN" ; + }; + String SC_OPCODE_ROW + { + Text [ en-US ] = "ROW" ; + }; + String SC_OPCODE_TABLE + { + Text [ en-US ] = "SHEET" ; + }; + String SC_OPCODE_ZGZ + { + Text [ en-US ] = "RRI" ; + }; + String SC_OPCODE_ZW + { + Text [ en-US ] = "FV" ; + }; + String SC_OPCODE_ZZR + { + Text [ en-US ] = "NPER" ; + }; + String SC_OPCODE_ZINS + { + Text [ en-US ] = "RATE" ; + }; + String SC_OPCODE_ZINS_Z + { + Text [ en-US ] = "IPMT" ; + }; + String SC_OPCODE_KAPZ + { + Text [ en-US ] = "PPMT" ; + }; + String SC_OPCODE_KUM_ZINS_Z + { + Text [ en-US ] = "CUMIPMT" ; + }; + String SC_OPCODE_KUM_KAP_Z + { + Text [ en-US ] = "CUMPRINC" ; + }; + String SC_OPCODE_EFFEKTIV + { + Text [ en-US ] = "EFFECTIVE" ; + }; + String SC_OPCODE_NOMINAL + { + Text [ en-US ] = "NOMINAL" ; + }; + String SC_OPCODE_SUB_TOTAL + { + Text [ en-US ] = "SUBTOTAL" ; + }; + String SC_OPCODE_DB_SUM + { + Text [ en-US ] = "DSUM" ; + }; + String SC_OPCODE_DB_COUNT + { + Text [ en-US ] = "DCOUNT" ; + }; + String SC_OPCODE_DB_COUNT_2 + { + Text [ en-US ] = "DCOUNTA" ; + }; + String SC_OPCODE_DB_AVERAGE + { + Text [ en-US ] = "DAVERAGE" ; + }; + String SC_OPCODE_DB_GET + { + Text [ en-US ] = "DGET" ; + }; + String SC_OPCODE_DB_MAX + { + Text [ en-US ] = "DMAX" ; + }; + String SC_OPCODE_DB_MIN + { + Text [ en-US ] = "DMIN" ; + }; + String SC_OPCODE_DB_PRODUCT + { + Text [ en-US ] = "DPRODUCT" ; + }; + String SC_OPCODE_DB_STD_DEV + { + Text [ en-US ] = "DSTDEV" ; + }; + String SC_OPCODE_DB_STD_DEV_P + { + Text [ en-US ] = "DSTDEVP" ; + }; + String SC_OPCODE_DB_VAR + { + Text [ en-US ] = "DVAR" ; + }; + String SC_OPCODE_DB_VAR_P + { + Text [ en-US ] = "DVARP" ; + }; + String SC_OPCODE_INDIRECT + { + Text [ en-US ] = "INDIRECT" ; + }; + String SC_OPCODE_ADDRESS + { + Text [ en-US ] = "ADDRESS" ; + }; + String SC_OPCODE_MATCH + { + Text [ en-US ] = "MATCH" ; + }; + String SC_OPCODE_COUNT_EMPTY_CELLS + { + Text [ en-US ] = "COUNTBLANK" ; + }; + String SC_OPCODE_COUNT_IF + { + Text [ en-US ] = "COUNTIF" ; + }; + String SC_OPCODE_SUM_IF + { + Text [ en-US ] = "SUMIF" ; + }; + String SC_OPCODE_LOOKUP + { + Text [ en-US ] = "LOOKUP" ; + }; + String SC_OPCODE_V_LOOKUP + { + Text [ en-US ] = "VLOOKUP" ; + }; + String SC_OPCODE_H_LOOKUP + { + Text [ en-US ] = "HLOOKUP" ; + }; + String SC_OPCODE_MULTI_AREA // legacy for range list (union) + { + Text [ en-US ] = "MULTIRANGE" ; + }; + String SC_OPCODE_OFFSET + { + Text [ en-US ] = "OFFSET" ; + }; + String SC_OPCODE_INDEX + { + // ?? erstes Zeichen = I ?? + Text [ en-US ] = "INDEX" ; + }; + String SC_OPCODE_AREAS + { + Text [ en-US ] = "AREAS" ; + }; + String SC_OPCODE_CURRENCY + { + Text [ en-US ] = "DOLLAR" ; + }; + String SC_OPCODE_REPLACE + { + Text [ en-US ] = "REPLACE" ; + }; + String SC_OPCODE_FIXED + { + Text [ en-US ] = "FIXED" ; + }; + String SC_OPCODE_FIND + { + Text [ en-US ] = "FIND" ; + }; + String SC_OPCODE_EXACT + { + Text [ en-US ] = "EXACT" ; + }; + String SC_OPCODE_LEFT + { + Text [ en-US ] = "LEFT" ; + }; + String SC_OPCODE_RIGHT + { + Text [ en-US ] = "RIGHT" ; + }; + String SC_OPCODE_SEARCH + { + Text [ en-US ] = "SEARCH" ; + }; + String SC_OPCODE_MID + { + Text [ en-US ] = "MID" ; + }; + String SC_OPCODE_TEXT + { + Text [ en-US ] = "TEXT" ; + }; + String SC_OPCODE_SUBSTITUTE + { + Text [ en-US ] = "SUBSTITUTE" ; + }; + String SC_OPCODE_REPT + { + Text [ en-US ] = "REPT" ; + }; + String SC_OPCODE_CONCAT + { + Text [ en-US ] = "CONCATENATE" ; + }; + String SC_OPCODE_MAT_VALUE + { + Text [ en-US ] = "MVALUE" ; + }; + String SC_OPCODE_MAT_DET + { + Text [ en-US ] = "MDETERM" ; + }; + String SC_OPCODE_MAT_INV + { + Text [ en-US ] = "MINVERSE" ; + }; + String SC_OPCODE_MAT_MULT + { + Text [ en-US ] = "MMULT" ; + }; + String SC_OPCODE_MAT_TRANS + { + Text [ en-US ] = "TRANSPOSE" ; + }; + String SC_OPCODE_MATRIX_UNIT + { + Text [ en-US ] = "MUNIT" ; + }; + String SC_OPCODE_BACK_SOLVER + { + Text [ en-US ] = "GOALSEEK" ; + }; + String SC_OPCODE_HYP_GEOM_DIST + { + Text [ en-US ] = "HYPGEOMDIST" ; + }; + String SC_OPCODE_LOG_NORM_DIST + { + Text [ en-US ] = "LOGNORMDIST" ; + }; + String SC_OPCODE_T_DIST + { + Text [ en-US ] = "TDIST" ; + }; + String SC_OPCODE_F_DIST + { + Text [ en-US ] = "FDIST" ; + }; + String SC_OPCODE_CHI_DIST + { + Text [ en-US ] = "CHIDIST" ; + }; + String SC_OPCODE_WEIBULL + { + Text [ en-US ] = "WEIBULL" ; + }; + String SC_OPCODE_NEG_BINOM_VERT + { + Text [ en-US ] = "NEGBINOMDIST" ; + }; + String SC_OPCODE_KRIT_BINOM + { + Text [ en-US ] = "CRITBINOM" ; + }; + String SC_OPCODE_KURT + { + Text [ en-US ] = "KURT" ; + }; + String SC_OPCODE_HAR_MEAN + { + Text [ en-US ] = "HARMEAN" ; + }; + String SC_OPCODE_GEO_MEAN + { + Text [ en-US ] = "GEOMEAN" ; + }; + String SC_OPCODE_STANDARD + { + Text [ en-US ] = "STANDARDIZE" ; + }; + String SC_OPCODE_AVE_DEV + { + Text [ en-US ] = "AVEDEV" ; + }; + String SC_OPCODE_SCHIEFE + { + Text [ en-US ] = "SKEW" ; + }; + String SC_OPCODE_DEV_SQ + { + Text [ en-US ] = "DEVSQ" ; + }; + String SC_OPCODE_MEDIAN + { + Text [ en-US ] = "MEDIAN" ; + }; + String SC_OPCODE_MODAL_VALUE + { + Text [ en-US ] = "MODE" ; + }; + String SC_OPCODE_Z_TEST + { + Text [ en-US ] = "ZTEST" ; + }; + String SC_OPCODE_T_TEST + { + Text [ en-US ] = "TTEST" ; + }; + String SC_OPCODE_RANK + { + Text [ en-US ] = "RANK" ; + }; + String SC_OPCODE_PERCENTILE + { + Text [ en-US ] = "PERCENTILE" ; + }; + String SC_OPCODE_PERCENT_RANK + { + Text [ en-US ] = "PERCENTRANK" ; + }; + String SC_OPCODE_LARGE + { + Text [ en-US ] = "LARGE" ; + }; + String SC_OPCODE_SMALL + { + Text [ en-US ] = "SMALL" ; + }; + String SC_OPCODE_FREQUENCY + { + Text [ en-US ] = "FREQUENCY" ; + }; + String SC_OPCODE_QUARTILE + { + Text [ en-US ] = "QUARTILE" ; + }; + String SC_OPCODE_NORM_INV + { + Text [ en-US ] = "NORMINV" ; + }; + String SC_OPCODE_CONFIDENCE + { + Text [ en-US ] = "CONFIDENCE" ; + }; + String SC_OPCODE_F_TEST + { + Text [ en-US ] = "FTEST" ; + }; + String SC_OPCODE_TRIM_MEAN + { + Text [ en-US ] = "TRIMMEAN" ; + }; + String SC_OPCODE_PROB + { + Text [ en-US ] = "PROB" ; + }; + String SC_OPCODE_CORREL + { + Text [ en-US ] = "CORREL" ; + }; + String SC_OPCODE_COVAR + { + Text [ en-US ] = "COVAR" ; + }; + String SC_OPCODE_PEARSON + { + Text [ en-US ] = "PEARSON" ; + }; + String SC_OPCODE_RSQ + { + Text [ en-US ] = "RSQ" ; + }; + String SC_OPCODE_STEYX + { + Text [ en-US ] = "STEYX" ; + }; + String SC_OPCODE_SLOPE + { + Text [ en-US ] = "SLOPE" ; + }; + String SC_OPCODE_INTERCEPT + { + Text [ en-US ] = "INTERCEPT" ; + }; + String SC_OPCODE_TREND + { + Text [ en-US ] = "TREND" ; + }; + String SC_OPCODE_GROWTH + { + Text [ en-US ] = "GROWTH" ; + }; + String SC_OPCODE_RGP + { + Text [ en-US ] = "LINEST" ; + }; + String SC_OPCODE_RKP + { + Text [ en-US ] = "LOGEST" ; + }; + String SC_OPCODE_FORECAST + { + Text [ en-US ] = "FORECAST" ; + }; + String SC_OPCODE_CHI_INV + { + Text [ en-US ] = "CHIINV" ; + }; + String SC_OPCODE_GAMMA_DIST + { + Text [ en-US ] = "GAMMADIST" ; + }; + String SC_OPCODE_GAMMA_INV + { + Text [ en-US ] = "GAMMAINV" ; + }; + String SC_OPCODE_T_INV + { + Text [ en-US ] = "TINV" ; + }; + String SC_OPCODE_F_INV + { + Text [ en-US ] = "FINV" ; + }; + String SC_OPCODE_CHI_TEST + { + Text [ en-US ] = "CHITEST" ; + }; + String SC_OPCODE_LOG_INV + { + Text [ en-US ] = "LOGINV" ; + }; + String SC_OPCODE_TABLE_OP + { + Text [ en-US ] = "MULTIPLE.OPERATIONS" ; + }; + String SC_OPCODE_BETA_DIST + { + Text [ en-US ] = "BETADIST" ; + }; + String SC_OPCODE_BETA_INV + { + Text [ en-US ] = "BETAINV" ; + }; + String SC_OPCODE_WEEK + { + Text [ en-US ] = "WEEKNUM" ; + }; + String SC_OPCODE_EASTERSUNDAY + { + Text [ en-US ] = "EASTERSUNDAY" ; + }; + String SC_OPCODE_GET_DAY_OF_WEEK + { + Text [ en-US ] = "WEEKDAY" ; + }; + String SC_OPCODE_NO_NAME + { + Text [ en-US ] = "#NAME!" ; + }; + String SC_OPCODE_STYLE + { + Text [ en-US ] = "STYLE" ; + }; + String SC_OPCODE_DDE + { + Text [ en-US ] = "DDE"; + }; + String SC_OPCODE_BASE + { + Text [ en-US ] = "BASE" ; + }; + String SC_OPCODE_DECIMAL + { + Text [ en-US ] = "DECIMAL" ; + }; + String SC_OPCODE_CONVERT + { + Text [ en-US ] = "CONVERT"; + }; + String SC_OPCODE_ROMAN + { + Text [ en-US ] = "ROMAN"; + }; + String SC_OPCODE_HYPERLINK + { + Text[ en-US ] = "HYPERLINK"; + }; + String SC_OPCODE_INFO + { + Text [ en-US ] = "INFO"; + }; + String SC_OPCODE_BAHTTEXT + { + Text [ en-US ] = "BAHTTEXT"; + }; + String SC_OPCODE_GET_PIVOT_DATA + { + Text [ en-US ] = "GETPIVOTDATA"; + }; + String SC_OPCODE_EUROCONVERT + { + Text [ en-US ] = "EUROCONVERT"; + }; + String SC_OPCODE_NUMBERVALUE + { + Text [ en-US ] = "NUMBERVALUE" ; + }; + String SC_OPCODE_GAMMA + { + Text [ en-US ] = "GAMMA" ; + }; + String SC_OPCODE_CHISQ_DIST + { + Text [ en-US ] = "CHISQDIST" ; + }; + String SC_OPCODE_CHISQ_INV + { + Text [ en-US ] = "CHISQINV" ; + }; + /* BEGIN defined ERROR.TYPE() values. */ + /* ERROR.TYPE( #NULL! ) == 1 */ + String SC_OPCODE_ERROR_NULL + { + Text [ en-US ] = "#NULL!" ; + }; + /* ERROR.TYPE( #DIV/0! ) == 2 */ + String SC_OPCODE_ERROR_DIVZERO + { + Text [ en-US ] = "#DIV/0!" ; + }; + /* ERROR.TYPE( #VALUE! ) == 3 */ + String SC_OPCODE_ERROR_VALUE + { + Text [ en-US ] = "#VALUE!" ; + }; + /* ERROR.TYPE( #REF! ) == 4 */ + String SC_OPCODE_ERROR_REF + { + Text [ en-US ] = "#REF!" ; + }; + /* ERROR.TYPE( #NAME! ) == 5 */ + String SC_OPCODE_ERROR_NAME + { + Text [ en-US ] = "#NAME?" ; + }; + /* ERROR.TYPE( #NUM! ) == 6 */ + String SC_OPCODE_ERROR_NUM + { + Text [ en-US ] = "#NUM!" ; + }; + /* ERROR.TYPE( #N/A ) == 7 */ + String SC_OPCODE_ERROR_NA + { + Text [ en-US ] = "#N/A" ; + }; + /* END defined ERROR.TYPE() values. */ +}; + + diff --git a/formula/source/core/resource/makefile.mk b/formula/source/core/resource/makefile.mk new file mode 100644 index 000000000000..13744ad59b14 --- /dev/null +++ b/formula/source/core/resource/makefile.mk @@ -0,0 +1,52 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.4 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJINC=$(PRJ)$/source +PRJNAME=formula +TARGET=core_resource + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SRS1NAME=core_strings +SRC1FILES= \ + core_resource.src + +SLOFILES= $(SLO)$/core_resource.obj + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk diff --git a/formula/source/ui/dlg/ControlHelper.hxx b/formula/source/ui/dlg/ControlHelper.hxx new file mode 100644 index 000000000000..ba69ed947166 --- /dev/null +++ b/formula/source/ui/dlg/ControlHelper.hxx @@ -0,0 +1,196 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: funcutl.hxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef FORMULA_CONTROL_HELPER_HXX_INCLUDED +#define FORMULA_CONTROL_HELPER_HXX_INCLUDED + +#include "formula/funcutl.hxx" +#include <svtools/svmedit.hxx> +namespace formula +{ + +//============================================================================ +// class ValWnd +class ValWnd : public Window +{ +public: + ValWnd( Window* pParent, const ResId& rId ); + + void SetValue( const String& rStrVal ); + +protected: + virtual void Paint( const Rectangle& rRect ); + +private: + String aStrValue; + Rectangle aRectOut; +}; + +//============================================================================ +// class EditBox +class EditBox : public Control +{ +private: + + MultiLineEdit* pMEdit; + Link aSelChangedLink; + Selection aOldSel; + BOOL bMouseFlag; + DECL_LINK( ChangedHdl, EditBox* ); + +protected: + + virtual long PreNotify( NotifyEvent& rNEvt ); + virtual void SelectionChanged(); + virtual void Resize(); + virtual void GetFocus(); + + +public: + EditBox( Window* pParent, + WinBits nWinStyle = WB_LEFT | WB_BORDER ); + EditBox( Window* pParent, const ResId& rResId ); + + virtual ~EditBox(); + + MultiLineEdit* GetEdit() {return pMEdit;} + + void SetSelChangedHdl( const Link& rLink ) { aSelChangedLink = rLink; } + const Link& GetSelChangedHdl() const { return aSelChangedLink; } + + void UpdateOldSel(); +}; + +//============================================================================ +// class ArgEdit + +class ArgEdit : public RefEdit +{ +public: + ArgEdit( Window* pParent, const ResId& rResId ); + + void Init( ArgEdit* pPrevEdit, ArgEdit* pNextEdit, + ScrollBar& rArgSlider, USHORT nArgCount ); + +protected: + virtual void KeyInput( const KeyEvent& rKEvt ); + +private: + ArgEdit* pEdPrev; + ArgEdit* pEdNext; + ScrollBar* pSlider; + USHORT nArgs; +}; + + +//============================================================================ +// class ArgInput + +class ArgInput +{ +private: + + Link aFxClickLink; + Link aRefClickLink; + Link aFxFocusLink; + Link aRefFocusLink; + Link aEdFocusLink; + Link aEdModifyLink; + + FixedText* pFtArg; + ImageButton* pBtnFx; + ArgEdit* pEdArg; + RefButton* pRefBtn; + + DECL_LINK( FxBtnClickHdl, ImageButton* ); + DECL_LINK( RefBtnClickHdl,RefButton* ); + DECL_LINK( FxBtnFocusHdl, ImageButton* ); + DECL_LINK( RefBtnFocusHdl,RefButton* ); + DECL_LINK( EdFocusHdl, ArgEdit* ); + DECL_LINK( EdModifyHdl,ArgEdit* ); + +protected: + + virtual void FxClick(); + virtual void RefClick(); + virtual void FxFocus(); + virtual void RefFocus(); + virtual void EdFocus(); + virtual void EdModify(); + +public: + + ArgInput(); + + void InitArgInput ( FixedText* pftArg, + ImageButton* pbtnFx, + ArgEdit* pedArg, + RefButton* prefBtn); + + void SetArgName(const String &aArg); + String GetArgName(); + void SetArgNameFont(const Font&); + + void SetArgVal(const String &aVal); + String GetArgVal(); + + void SetArgSelection (const Selection& rSel ); + void ReplaceSelOfArg (const String& rStr ); + + Selection GetArgSelection(); + + + ArgEdit* GetArgEdPtr() {return pEdArg;} + + + void SetFxClickHdl( const Link& rLink ) { aFxClickLink = rLink; } + const Link& GetFxClickHdl() const { return aFxClickLink; } + + void SetRefClickHdl( const Link& rLink ) { aRefClickLink = rLink; } + const Link& GetRefClickHdl() const { return aRefClickLink; } + + void SetFxFocusHdl( const Link& rLink ) { aFxFocusLink = rLink; } + const Link& GetFxFocusHdl() const { return aFxFocusLink; } + + void SetRefFocusHdl( const Link& rLink ) { aRefFocusLink = rLink; } + const Link& GetRefFocusHdl() const { return aRefFocusLink; } + + void SetEdFocusHdl( const Link& rLink ) { aEdFocusLink = rLink; } + const Link& GetEdFocusHdl() const { return aEdFocusLink; } + + void SetEdModifyHdl( const Link& rLink ) { aEdModifyLink = rLink; } + const Link& GetEdModifyHdl() const { return aEdModifyLink; } + + void Hide(); + void Show(); + +}; + +} +#endif // FORMULA_FORMULA_HELPER_HXX_INCLUDED diff --git a/formula/source/ui/dlg/FormulaHelper.cxx b/formula/source/ui/dlg/FormulaHelper.cxx new file mode 100644 index 000000000000..148336a5c3d4 --- /dev/null +++ b/formula/source/ui/dlg/FormulaHelper.cxx @@ -0,0 +1,409 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: formula.hxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "precompiled_formula.hxx" + +#include "formula/formulahelper.hxx" +#include <unotools/charclass.hxx> +#include <svtools/syslocale.hxx> + +namespace formula +{ + + namespace + { + //============================================================================ + class OEmptyFunctionDescription : public IFunctionDescription + { + public: + OEmptyFunctionDescription(){} + virtual ~OEmptyFunctionDescription(){} + + virtual ::rtl::OUString getFunctionName() const { return ::rtl::OUString(); } + virtual const IFunctionCategory* getCategory() const { return NULL; } + virtual ::rtl::OUString getDescription() const { return ::rtl::OUString(); } + virtual xub_StrLen getSuppressedArgumentCount() const { return 0; } + virtual ::rtl::OUString getFormula(const ::std::vector< ::rtl::OUString >& ) const { return ::rtl::OUString(); } + virtual void fillVisibleArgumentMapping(::std::vector<USHORT>& ) const {} + virtual void initArgumentInfo() const {} + virtual ::rtl::OUString getSignature() const { return ::rtl::OUString(); } + virtual long getHelpId() const { return 0; } + virtual sal_uInt32 getParameterCount() const { return 0; } + virtual ::rtl::OUString getParameterName(sal_uInt32 ) const { return ::rtl::OUString(); } + virtual ::rtl::OUString getParameterDescription(sal_uInt32 ) const { return ::rtl::OUString(); } + virtual bool isParameterOptional(sal_uInt32 ) const { return sal_False; } + }; + } +//=================================================================== +// class FormulaHelper - statische Methoden +//=================================================================== + +#define FUNC_NOTFOUND 0xffff + +FormulaHelper::FormulaHelper(const IFunctionManager* _pFunctionManager) + :m_pSysLocale(new SvtSysLocale) + ,m_pFunctionManager(_pFunctionManager) + ,open(_pFunctionManager->getSingleToken(IFunctionManager::eOk)) + ,close(_pFunctionManager->getSingleToken(IFunctionManager::eClose)) + ,sep(_pFunctionManager->getSingleToken(IFunctionManager::eSep)) + ,arrayOpen(_pFunctionManager->getSingleToken(IFunctionManager::eArrayOpen)) + ,arrayClose(_pFunctionManager->getSingleToken(IFunctionManager::eArrayClose)) +{ + m_pCharClass = m_pSysLocale->GetCharClassPtr(); +} +BOOL FormulaHelper::GetNextFunc( const String& rFormula, + BOOL bBack, + xub_StrLen& rFStart, // Ein- und Ausgabe + xub_StrLen* pFEnd, // = NULL + const IFunctionDescription** ppFDesc, // = NULL + ::std::vector< ::rtl::OUString>* pArgs ) const // = NULL +{ + BOOL bFound = FALSE; + xub_StrLen nOldStart = rFStart; + String aFname; + + rFStart = GetFunctionStart( rFormula, rFStart, bBack, ppFDesc ? &aFname : NULL ); + bFound = ( rFStart != FUNC_NOTFOUND ); + + if ( bFound ) + { + if ( pFEnd ) + *pFEnd = GetFunctionEnd( rFormula, rFStart ); + + if ( ppFDesc ) + { + *ppFDesc = NULL; + const ::rtl::OUString sTemp( aFname ); + const sal_uInt32 nCategoryCount = m_pFunctionManager->getCount(); + for(sal_uInt32 j= 0; j < nCategoryCount && !*ppFDesc; ++j) + { + const IFunctionCategory* pCategory = m_pFunctionManager->getCategory(j); + const sal_uInt32 nCount = pCategory->getCount(); + for(sal_uInt32 i = 0 ; i < nCount; ++i) + { + const IFunctionDescription* pCurrent = pCategory->getFunction(i); + if ( pCurrent->getFunctionName().equalsIgnoreAsciiCase(sTemp) ) + { + *ppFDesc = pCurrent; + break; + } + } // for(sal_uInt32 i = 0 ; i < nCount; ++i) + } + if ( *ppFDesc && pArgs ) + { + GetArgStrings( *pArgs,rFormula, rFStart, static_cast<USHORT>((*ppFDesc)->getParameterCount() )); + } + else + { + static OEmptyFunctionDescription s_aFunctionDescription; + *ppFDesc = &s_aFunctionDescription; + } + } + } + else + rFStart = nOldStart; + + return bFound; +} + +//------------------------------------------------------------------------ + +void FormulaHelper::FillArgStrings( const String& rFormula, + xub_StrLen nFuncPos, + USHORT nArgs, + ::std::vector< ::rtl::OUString >& _rArgs ) const +{ + xub_StrLen nStart = 0; + xub_StrLen nEnd = 0; + USHORT i; + BOOL bLast = FALSE; + + for ( i=0; i<nArgs && !bLast; i++ ) + { + nStart = GetArgStart( rFormula, nFuncPos, i ); + + if ( i+1<nArgs ) // letztes Argument? + { + nEnd = GetArgStart( rFormula, nFuncPos, i+1 ); + + if ( nEnd != nStart ) + _rArgs.push_back(rFormula.Copy( nStart, nEnd-1-nStart )); + else + _rArgs.push_back(String()), bLast = TRUE; + } + else + { + nEnd = GetFunctionEnd( rFormula, nFuncPos )-1; + if ( nStart < nEnd ) + _rArgs.push_back( rFormula.Copy( nStart, nEnd-nStart ) ); + else + _rArgs.push_back(String()); + } + } + + if ( bLast ) + for ( ; i<nArgs; i++ ) + _rArgs.push_back(String()); +} + +//------------------------------------------------------------------------ + +void FormulaHelper::GetArgStrings( ::std::vector< ::rtl::OUString >& _rArgs + ,const String& rFormula, + xub_StrLen nFuncPos, + USHORT nArgs ) const +{ + if (nArgs) + { + FillArgStrings( rFormula, nFuncPos, nArgs, _rArgs ); + } +} + +//------------------------------------------------------------------------ + +inline BOOL IsFormulaText( const CharClass* _pCharClass,const String& rStr, xub_StrLen nPos ) +{ + if( _pCharClass->isLetterNumeric( rStr, nPos ) ) + return TRUE; + else + { // In internationalized versions function names may contain a dot + // and in every version also an underscore... ;-) + sal_Unicode c = rStr.GetChar(nPos); + return c == '.' || c == '_'; + } + +} + +xub_StrLen FormulaHelper::GetFunctionStart( const String& rFormula, + xub_StrLen nStart, + BOOL bBack, + String* pFuncName ) const +{ + xub_StrLen nStrLen = rFormula.Len(); + + if ( nStrLen < nStart ) + return nStart; + + xub_StrLen nFStart = FUNC_NOTFOUND; + xub_StrLen nParPos = nStart; + + BOOL bRepeat, bFound; + do + { + bFound = FALSE; + bRepeat = FALSE; + + if ( bBack ) + { + while ( !bFound && (nParPos > 0) ) + { + if ( rFormula.GetChar(nParPos) == '"' ) + { + nParPos--; + while ( (nParPos > 0) && rFormula.GetChar(nParPos) != '"' ) + nParPos--; + if (nParPos > 0) + nParPos--; + } + else if ( (bFound = ( rFormula.GetChar(nParPos) == '(' ) ) == FALSE ) + nParPos--; + } + } + else + { + while ( !bFound && (nParPos < nStrLen) ) + { + if ( rFormula.GetChar(nParPos) == '"' ) + { + nParPos++; + while ( (nParPos < nStrLen) && rFormula.GetChar(nParPos) != '"' ) + nParPos++; + nParPos++; + } + else if ( (bFound = ( rFormula.GetChar(nParPos) == '(' ) ) == FALSE ) + nParPos++; + } + } + + if ( bFound && (nParPos > 0) ) + { + nFStart = nParPos-1; + + while ( (nFStart > 0) && IsFormulaText(m_pCharClass, rFormula, nFStart )) + nFStart--; + } + + nFStart++; + + if ( bFound ) + { + if ( IsFormulaText( m_pCharClass,rFormula, nFStart ) ) + { + // Funktion gefunden + if ( pFuncName ) + *pFuncName = rFormula.Copy( nFStart, nParPos-nFStart ); + } + else // Klammern ohne Funktion -> weitersuchen + { + bRepeat = TRUE; + if ( !bBack ) + nParPos++; + else if (nParPos > 0) + nParPos--; + else + bRepeat = FALSE; + } + } + else // keine Klammern gefunden + { + nFStart = FUNC_NOTFOUND; + if ( pFuncName ) + pFuncName->Erase(); + } + } + while(bRepeat); + + return nFStart; +} + +//------------------------------------------------------------------------ + +xub_StrLen FormulaHelper::GetFunctionEnd( const String& rStr, xub_StrLen nStart ) const +{ + xub_StrLen nStrLen = rStr.Len(); + + if ( nStrLen < nStart ) + return nStart; + + short nParCount = 0; + bool bInArray = false; + BOOL bFound = FALSE; + + while ( !bFound && (nStart < nStrLen) ) + { + sal_Unicode c = rStr.GetChar(nStart); + + if ( c == '"' ) + { + nStart++; + while ( (nStart < nStrLen) && rStr.GetChar(nStart) != '"' ) + nStart++; + } + else if ( c == open ) + nParCount++; + else if ( c == close ) + { + nParCount--; + if ( nParCount == 0 ) + bFound = TRUE; + else if ( nParCount < 0 ) + { + bFound = TRUE; + nStart--; // einen zu weit gelesen + } + } + else if ( c == arrayOpen ) + { + bInArray = true; + } + else if ( c == arrayClose ) + { + bInArray = false; + } + else if ( c == sep ) + { + if ( !bInArray && nParCount == 0 ) + { + bFound = TRUE; + nStart--; // einen zu weit gelesen + } + } + nStart++; // hinter gefundene Position stellen + } + + return nStart; +} + +//------------------------------------------------------------------ + +xub_StrLen FormulaHelper::GetArgStart( const String& rStr, xub_StrLen nStart, USHORT nArg ) const +{ + xub_StrLen nStrLen = rStr.Len(); + + if ( nStrLen < nStart ) + return nStart; + + short nParCount = 0; + bool bInArray = false; + BOOL bFound = FALSE; + + while ( !bFound && (nStart < nStrLen) ) + { + sal_Unicode c = rStr.GetChar(nStart); + + if ( c == '"' ) + { + nStart++; + while ( (nStart < nStrLen) && rStr.GetChar(nStart) != '"' ) + nStart++; + } + else if ( c == open ) + { + bFound = ( nArg == 0 ); + nParCount++; + } + else if ( c == close ) + { + nParCount--; + bFound = ( nParCount == 0 ); + } + else if ( c == arrayOpen ) + { + bInArray = true; + } + else if ( c == arrayClose ) + { + bInArray = false; + } + else if ( c == sep ) + { + if ( !bInArray && nParCount == 1 ) + { + nArg--; + bFound = ( nArg == 0 ); + } + } + nStart++; + } + + return nStart; +} +// ============================================================================= +} // formula +// ============================================================================= diff --git a/formula/source/ui/dlg/formdlgs.hrc b/formula/source/ui/dlg/formdlgs.hrc new file mode 100644 index 000000000000..74e26c1cec0c --- /dev/null +++ b/formula/source/ui/dlg/formdlgs.hrc @@ -0,0 +1,83 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: formdlgs.hrc,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#define FT_RESULT 1 +#define WND_RESULT 2 +#define FT_EDITNAME 3 +#define STR_TITLE1 4 +#define STR_TITLE2 5 +#define BTN_HELP 6 +#define BTN_CANCEL 7 +#define BTN_BACKWARD 8 +#define BTN_FORWARD 9 +#define BTN_END 10 +#define BTN_MATRIX 11 +#define FT_FUNCNAME 12 +#define FT_FUNCDESC 13 +#define FT_HEADLINE 14 +#define GB_EDIT 15 +#define FT_FORMULA 16 +#define ED_FORMULA 17 +#define TC_FUNCTION 18 +#define ED_REF 19 +#define RB_REF 20 +#define FT_FORMULA_RESULT 21 +#define WND_FORMULA_RESULT 22 +#define STR_END 23 +// Fuer Tabpage +#define TP_FUNCTION 1 +#define TP_STRUCT 2 + +// Funktions-Tabpage +#define FT_FUNCTION 1 +#define FT_CATEGORY 2 +#define LB_CATEGORY 3 +#define LB_FUNCTION 4 + +// Struktur-Tabpage +#define FT_STRUCT 1 +#define TLB_STRUCT 2 + +// Bitmaps +#define BMP_STR_CLOSE 1 +#define BMP_STR_OPEN 2 +#define BMP_STR_END 3 +#define BMP_STR_ERROR 4 +#define BMP_STR_CLOSE_H 11 +#define BMP_STR_OPEN_H 12 +#define BMP_STR_END_H 13 +#define BMP_STR_ERROR_H 14 + +// Texte +#define STR_STRUCT_ERR1 1 +#define STR_STRUCT_ERR2 2 + + diff --git a/formula/source/ui/dlg/formdlgs.src b/formula/source/ui/dlg/formdlgs.src new file mode 100644 index 000000000000..1bed82d2068a --- /dev/null +++ b/formula/source/ui/dlg/formdlgs.src @@ -0,0 +1,539 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: formdlgs.src,v $ + * $Revision: 1.49 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "formdlgs.hrc" +#include "ForResId.hrc" +#include "helpids.hrc" + + +#define STD_MASKCOLOR Color { Red=0xFFFF; Green=0x0000; Blue=0xFFFF; } + //--------------------------------------------------------------------------- +TabPage RID_FORMULATAB_FUNCTION +{ + Hide = TRUE ; + Size = MAP_APPFONT ( 96 , 180 ) ; + HelpId = HID_FORMULATAB_FUNCTION ; + // Titel wird dynamisch gesetzt (s.u.) + // 1. Seite + ListBox LB_CATEGORY + { + HelpId = HID_FORMULA_LB_CATEGORY; + Border = TRUE ; + Pos = MAP_APPFONT ( 6 , 14 ) ; + Size = MAP_APPFONT ( 86 , 112 ) ; + DropDown = TRUE ; + StringList [ en-US ] = + { + < "Last Used" ; Default ; > ; + < "All" ; Default ; > ; + }; + // < "Database" ; Default ; > ; + // < "Date&Time" ; Default ; > ; + // < "Financial" ; Default ; > ; + // < "Information" ; Default ; > ; + // < "Logical" ; Default ; > ; + // < "Mathematical" ; Default ; > ; + // < "Array" ; Default ; > ; + // < "Statistical" ; Default ; > ; + // < "Spreadsheet" ; Default ; > ; + // < "Text" ; Default ; > ; + // < "Add-in" ; Default ; > ; + //}; + }; + ListBox LB_FUNCTION + { + HelpId = HID_FORMULA_LB_FUNCTION; + Border = TRUE ; + Pos = MAP_APPFONT ( 6 , 43 ) ; + Size = MAP_APPFONT ( 86 , 133 ) ; + Sort = TRUE; + }; + FixedText FT_CATEGORY + { + Pos = MAP_APPFONT ( 6 , 3 ) ; + Size = MAP_APPFONT ( 84 , 8 ) ; + Text [ en-US ] = "~Category" ; + }; + FixedText FT_FUNCTION + { + Pos = MAP_APPFONT ( 6 , 32 ) ; + Size = MAP_APPFONT ( 72 , 8 ) ; + Text [ en-US ] = "~Function" ; + }; +}; +TabPage RID_FORMULATAB_STRUCT +{ + Hide = TRUE ; + Size = MAP_APPFONT ( 96 , 180 ) ; + HelpId = HID_FORMULATAB_STRUCT ; + // Titel wird dynamisch gesetzt (s.u.) + // 1. Seite + Control TLB_STRUCT + { + Border = TRUE ; + TabStop = TRUE ; + Pos = MAP_APPFONT ( 6 , 14 ) ; + Size = MAP_APPFONT ( 86 , 162 ) ; + HelpId = HID_FORMULA_FAP_STRUCT ; + }; + FixedText FT_STRUCT + { + Pos = MAP_APPFONT ( 6 , 3 ) ; + Size = MAP_APPFONT ( 86 , 8 ) ; + Text [ en-US ] = "~Structure" ; + }; + Image BMP_STR_CLOSE + { + ImageBitmap = Bitmap { File = "fapclose.bmp"; }; + MaskColor = STD_MASKCOLOR; + }; + Image BMP_STR_CLOSE_H + { + ImageBitmap = Bitmap { File = "fapclose_h.bmp"; }; + MaskColor = STD_MASKCOLOR; + }; + Image BMP_STR_OPEN + { + ImageBitmap = Bitmap { File = "fapopen.bmp"; }; + MaskColor = STD_MASKCOLOR; + }; + Image BMP_STR_OPEN_H + { + ImageBitmap = Bitmap { File = "fapopen_h.bmp"; }; + MaskColor = STD_MASKCOLOR; + }; + Image BMP_STR_END + { + ImageBitmap = Bitmap { File = "fapok.bmp"; }; + MaskColor = STD_MASKCOLOR; + }; + Image BMP_STR_END_H + { + ImageBitmap = Bitmap { File = "fapok_h.bmp"; }; + MaskColor = STD_MASKCOLOR; + }; + Image BMP_STR_ERROR + { + ImageBitmap = Bitmap { File = "faperror.bmp"; }; + MaskColor = STD_MASKCOLOR; + }; + Image BMP_STR_ERROR_H + { + ImageBitmap = Bitmap { File = "faperror_h.bmp"; }; + MaskColor = STD_MASKCOLOR; + }; + String STR_STRUCT_ERR1 + { + Text [ en-US ] = "=?" ; + }; + String STR_STRUCT_ERR2 + { + Text [ en-US ] = "Error" ; + }; +}; +ModalDialog RID_FORMULADLG_FORMULA_MODAL +{ + SVLook = TRUE ; + Size = MAP_APPFONT ( 321 , 228 ) ; + HelpId = HID_FORMULADLG_FORMULA ; + Moveable = TRUE ; + TabControl TC_FUNCTION + { + Pos = MAP_APPFONT ( 6 , 5 ) ; + Size = MAP_APPFONT ( 102 , 199 ) ; + PageList = + { + PageItem + { + Identifier = TP_FUNCTION ; + Text [ en-US ] = "Functions" ; + }; + PageItem + { + Identifier = TP_STRUCT ; + Text [ en-US ] = "Structure" ; + }; + }; + }; + FixedText FT_HEADLINE + { + Pos = MAP_APPFONT ( 115 , 24 ) ; + Size = MAP_APPFONT ( 194 , 8 ) ; + WordBreak = TRUE ; + }; + FixedText FT_FUNCNAME + { + Pos = MAP_APPFONT ( 115 , 38 ) ; + Size = MAP_APPFONT ( 194 , 24 ) ; + WordBreak = TRUE ; + }; + FixedText FT_FUNCDESC + { + Pos = MAP_APPFONT ( 115 , 68 ) ; + Size = MAP_APPFONT ( 194 , 64 ) ; + WordBreak = TRUE ; + }; + FixedText FT_EDITNAME + { + Pos = MAP_APPFONT ( 113 , 6 ) ; + Size = MAP_APPFONT ( 83 , 10 ) ; + }; + GroupBox GB_EDIT + { + Pos = MAP_APPFONT ( 112 , 18 ) ; + Size = MAP_APPFONT ( 203 , 128 ) ; + }; + FixedText FT_FORMULA + { + Pos = MAP_APPFONT ( 112 , 151 ) ; + Size = MAP_APPFONT ( 50 , 10 ) ; + WordBreak = TRUE ; + Text [ en-US ] = "For~mula" ; + }; + Control ED_FORMULA + { + Border = TRUE ; + Pos = MAP_APPFONT ( 112 , 161 ) ; + Size = MAP_APPFONT ( 203 , 43 ) ; + HelpId = HID_FORMULA_FAP_FORMULA ; + }; + FixedText FT_RESULT + { + Pos = MAP_APPFONT ( 198 , 6 ) ; + Size = MAP_APPFONT ( 55 , 10 ) ; + Right = TRUE ; + Text [ en-US ] = "Function result" ; + }; + Window WND_RESULT + { + Border = TRUE ; + Pos = MAP_APPFONT ( 255 , 4 ) ; + Size = MAP_APPFONT ( 60 , 12 ) ; + }; + FixedText FT_FORMULA_RESULT + { + Pos = MAP_APPFONT ( 217 , 149 ) ; + Size = MAP_APPFONT ( 35 , 10 ) ; + Text [ en-US ] = "Result" ; + Right = TRUE ; + }; + Window WND_FORMULA_RESULT + { + Border = TRUE ; + Pos = MAP_APPFONT ( 255 , 147 ) ; + Size = MAP_APPFONT ( 60 , 12 ) ; + }; + CheckBox BTN_MATRIX + { + Pos = MAP_APPFONT ( 6 , 208 ) ; + Size = MAP_APPFONT ( 50 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Array" ; + }; + Edit ED_REF + { + Border = TRUE ; + Pos = MAP_APPFONT ( 76 , 205 ) ; + Size = MAP_APPFONT ( 66 , 12 ) ; + }; + ImageButton RB_REF + { + Pos = MAP_APPFONT ( 144 , 205 ) ; + Size = MAP_APPFONT ( 13 , 15 ) ; + TabStop = FALSE ; + QuickHelpText [ en-US ] = "Maximize" ; + }; + HelpButton BTN_HELP + { + Pos = MAP_APPFONT ( 72 , 208 ) ; + Size = MAP_APPFONT ( 45 , 14 ) ; + TabStop = TRUE ; + }; + CancelButton BTN_CANCEL + { + Pos = MAP_APPFONT ( 121 , 208 ) ; + Size = MAP_APPFONT ( 45 , 14 ) ; + TabStop = TRUE ; + }; + PushButton BTN_BACKWARD + { + Pos = MAP_APPFONT ( 171 , 208 ) ; + Size = MAP_APPFONT ( 45 , 14 ) ; + TabStop = TRUE ; + Text [ en-US ] = "<< ~Back" ; + }; + PushButton BTN_FORWARD + { + Pos = MAP_APPFONT ( 219 , 208 ) ; + Size = MAP_APPFONT ( 45 , 14 ) ; + TabStop = TRUE ; + Text [ en-US ] = "~Next >>" ; + }; + OKButton BTN_END + { + Pos = MAP_APPFONT ( 270 , 208 ) ; + Size = MAP_APPFONT ( 45 , 14 ) ; + TabStop = TRUE ; + DefButton = TRUE ; + }; + String STR_TITLE1 + { + Text [ en-US ] = "Function Wizard" ; + }; + String STR_TITLE2 + { + Text [ en-US ] = "Function Wizard -" ; + }; + String STR_END + { + Text [ en-US ] = "~End" ; + }; + +}; +ModelessDialog RID_FORMULADLG_FORMULA +{ + // OutputSize = TRUE ; + Hide = TRUE ; + SVLook = TRUE ; + Size = MAP_APPFONT ( 321 , 228 ) ; + HelpId = HID_FORMULADLG_FORMULA ; + Moveable = TRUE ; + TabControl TC_FUNCTION + { + Pos = MAP_APPFONT ( 6 , 5 ) ; + Size = MAP_APPFONT ( 102 , 199 ) ; + PageList = + { + PageItem + { + Identifier = TP_FUNCTION ; + Text [ en-US ] = "Functions" ; + }; + PageItem + { + Identifier = TP_STRUCT ; + Text [ en-US ] = "Structure" ; + }; + }; + }; + FixedText FT_HEADLINE + { + Pos = MAP_APPFONT ( 115 , 24 ) ; + Size = MAP_APPFONT ( 194 , 8 ) ; + WordBreak = TRUE ; + }; + FixedText FT_FUNCNAME + { + Pos = MAP_APPFONT ( 115 , 38 ) ; + Size = MAP_APPFONT ( 194 , 24 ) ; + WordBreak = TRUE ; + }; + FixedText FT_FUNCDESC + { + Pos = MAP_APPFONT ( 115 , 68 ) ; + Size = MAP_APPFONT ( 194 , 64 ) ; + WordBreak = TRUE ; + }; + FixedText FT_EDITNAME + { + Pos = MAP_APPFONT ( 113 , 6 ) ; + Size = MAP_APPFONT ( 83 , 10 ) ; + }; + GroupBox GB_EDIT + { + Pos = MAP_APPFONT ( 112 , 18 ) ; + Size = MAP_APPFONT ( 203 , 128 ) ; + }; + FixedText FT_FORMULA + { + Pos = MAP_APPFONT ( 112 , 151 ) ; + Size = MAP_APPFONT ( 50 , 10 ) ; + WordBreak = TRUE ; + Text [ en-US ] = "For~mula" ; + }; + Control ED_FORMULA + { + Border = TRUE ; + Pos = MAP_APPFONT ( 112 , 161 ) ; + Size = MAP_APPFONT ( 203 , 43 ) ; + HelpId = HID_FORMULA_FAP_FORMULA ; + }; + FixedText FT_RESULT + { + Pos = MAP_APPFONT ( 198 , 6 ) ; + Size = MAP_APPFONT ( 55 , 10 ) ; + Right = TRUE ; + Text [ en-US ] = "Function result" ; + }; + Window WND_RESULT + { + Border = TRUE ; + Pos = MAP_APPFONT ( 255 , 4 ) ; + Size = MAP_APPFONT ( 60 , 12 ) ; + }; + FixedText FT_FORMULA_RESULT + { + Pos = MAP_APPFONT ( 217 , 149 ) ; + Size = MAP_APPFONT ( 35 , 10 ) ; + Text [ en-US ] = "Result" ; + Right = TRUE ; + }; + Window WND_FORMULA_RESULT + { + Border = TRUE ; + Pos = MAP_APPFONT ( 255 , 147 ) ; + Size = MAP_APPFONT ( 60 , 12 ) ; + }; + CheckBox BTN_MATRIX + { + Pos = MAP_APPFONT ( 6 , 208 ) ; + Size = MAP_APPFONT ( 50 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Array" ; + }; + Edit ED_REF + { + Border = TRUE ; + Pos = MAP_APPFONT ( 76 , 205 ) ; + Size = MAP_APPFONT ( 66 , 12 ) ; + }; + ImageButton RB_REF + { + Pos = MAP_APPFONT ( 144 , 205 ) ; + Size = MAP_APPFONT ( 13 , 15 ) ; + TabStop = FALSE ; + QuickHelpText [ en-US ] = "Maximize" ; + }; + HelpButton BTN_HELP + { + Pos = MAP_APPFONT ( 72 , 208 ) ; + Size = MAP_APPFONT ( 45 , 14 ) ; + TabStop = TRUE ; + }; + CancelButton BTN_CANCEL + { + Pos = MAP_APPFONT ( 121 , 208 ) ; + Size = MAP_APPFONT ( 45 , 14 ) ; + TabStop = TRUE ; + }; + PushButton BTN_BACKWARD + { + Pos = MAP_APPFONT ( 171 , 208 ) ; + Size = MAP_APPFONT ( 45 , 14 ) ; + TabStop = TRUE ; + Text [ en-US ] = "<< ~Back" ; + }; + PushButton BTN_FORWARD + { + Pos = MAP_APPFONT ( 219 , 208 ) ; + Size = MAP_APPFONT ( 45 , 14 ) ; + TabStop = TRUE ; + Text [ en-US ] = "~Next >>" ; + }; + OKButton BTN_END + { + Pos = MAP_APPFONT ( 270 , 208 ) ; + Size = MAP_APPFONT ( 45 , 14 ) ; + TabStop = TRUE ; + DefButton = TRUE ; + }; + String STR_TITLE1 + { + Text [ en-US ] = "Function Wizard" ; + }; + String STR_TITLE2 + { + Text [ en-US ] = "Function Wizard -" ; + }; + String STR_END + { + Text [ en-US ] = "~End" ; + }; +}; + + +Image RID_BMP_REFBTN1 +{ + ImageBitmap = Bitmap + { + File = "refinp1.bmp"; + }; + MaskColor = STD_MASKCOLOR; +}; + +Image RID_BMP_REFBTN1_H +{ + ImageBitmap = Bitmap + { + File = "refinp1_h.bmp"; + }; + MaskColor = STD_MASKCOLOR; +}; + +Image RID_BMP_REFBTN2 +{ + ImageBitmap = Bitmap + { + File = "refinp2.bmp"; + }; + MaskColor = STD_MASKCOLOR; +}; + +Image RID_BMP_REFBTN2_H +{ + ImageBitmap = Bitmap + { + File = "refinp2_h.bmp"; + }; + MaskColor = STD_MASKCOLOR; +}; + + + + + + + + + + + + + + + + + + + + + + + diff --git a/formula/source/ui/dlg/formula.cxx b/formula/source/ui/dlg/formula.cxx new file mode 100644 index 000000000000..c19383a74f6b --- /dev/null +++ b/formula/source/ui/dlg/formula.cxx @@ -0,0 +1,2213 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: formula.cxx,v $ + * $Revision: 1.19 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_formula.hxx" + +//---------------------------------------------------------------------------- +#include <sfx2/dispatch.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/topfrm.hxx> +#include <vcl/svapp.hxx> +#include <vcl/mnemonic.hxx> +#include <vcl/tabpage.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/group.hxx> +#include <vcl/wall.hxx> + +#include <svtools/stdctrl.hxx> +#include <svtools/svmedit.hxx> +#include <svtools/svtreebx.hxx> +#include <svtools/stritem.hxx> +#include <svtools/zforlist.hxx> +#include <svtools/eitem.hxx> + +#include <unotools/charclass.hxx> +#include <tools/urlobj.hxx> + +#include "formdlgs.hrc" +#include "funcpage.hxx" +#include "formula/formula.hxx" +#include "formula/IFunctionDescription.hxx" +#include "formula/FormulaCompiler.hxx" +#include "formula/token.hxx" +#include "formula/tokenarray.hxx" +#include "formula/formdata.hxx" +#include "formula/formulahelper.hxx" +#include "structpg.hxx" +#include "parawin.hxx" +#include "ModuleHelper.hxx" +#include "ForResId.hrc" +#include <com/sun/star/sheet/FormulaToken.hpp> +#include <com/sun/star/sheet/FormulaLanguage.hpp> +#include <com/sun/star/sheet/FormulaMapGroup.hpp> +#include <com/sun/star/sheet/FormulaMapGroupSpecialOffset.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <boost/bind.hpp> +#include <comphelper/processfactory.hxx> +#include <map> + +#define TOKEN_OPEN 0 +#define TOKEN_CLOSE 1 +#define TOKEN_SEP 2 +namespace formula +{ + using namespace ::com::sun::star; + + class OFormulaToken : public IFormulaToken + { + sal_Int32 m_nParaCount; + bool m_bIsFunction; + + public: + OFormulaToken(bool _bFunction,sal_Int32 _nParaCount) : m_nParaCount(_nParaCount),m_bIsFunction(_bFunction){} + + virtual bool isFunction() const { return m_bIsFunction; } + virtual sal_uInt32 getArgumentCount() const { return m_nParaCount; } + }; + + + class FormulaDlg_Impl + { + public: + ::std::pair<RefButton*,RefEdit*> + RefInputStartBefore( RefEdit* pEdit, RefButton* pButton ); + void RefInputStartAfter( RefEdit* pEdit, RefButton* pButton ); + void RefInputDoneAfter( BOOL bForced ); + BOOL CalcValue( const String& rStrExp, String& rStrResult ); + BOOL CalcStruct( const String& rStrExp); + void UpdateValues(); + void DeleteArgs(); + xub_StrLen GetFunctionPos(xub_StrLen nPos); + void ClearAllParas(); + + void MakeTree(IStructHelper* _pTree,SvLBoxEntry* pParent,FormulaToken* _pToken,long Count); + void fillTree(IStructHelper* _pTree); + void UpdateTokenArray( const String& rStrExp); + String RepairFormula(const String& aFormula); + void FillDialog(BOOL nFlag=TRUE); + void EditNextFunc( BOOL bForward, xub_StrLen nFStart=NOT_FOUND ); + void EditThisFunc(xub_StrLen nFStart); + void EditFuncParas(xub_StrLen nEditPos); + + + void UpdateArgInput( USHORT nOffset, USHORT nInput ); + void Update(); + void Update(const String& _sExp); + + + void SaveArg( USHORT nEd ); + void UpdateSelection(); + void DoEnter( BOOL bOk ); + void UpdateFunctionDesc(); + void ResizeArgArr( const IFunctionDescription* pNewFunc ); + void FillListboxes(); + void FillControls(); + + FormulaDlgMode SetMeText(const String& _sText,xub_StrLen PrivStart, xub_StrLen PrivEnd,BOOL bMatrix,BOOL _bSelect,BOOL _bUpdate); + void SetMeText(const String& _sText); + BOOL CheckMatrix(String& aFormula /*IN/OUT*/); + + void SetEdSelection(); + + BOOL UpdateParaWin(Selection& _rSelection); + void UpdateParaWin(const Selection& _rSelection,const String& _sRefStr); + + void SetData(xub_StrLen nFStart,xub_StrLen nNextFStart,xub_StrLen nNextFEnd,xub_StrLen& PrivStart,xub_StrLen& PrivEnd); + void PreNotify( NotifyEvent& rNEvt ); + + RefEdit* GetCurrRefEdit(); + ULONG FindFocusWin(Window *pWin); + + const FormulaHelper& GetFormulaHelper() const; + uno::Reference< sheet::XFormulaOpCodeMapper > GetFormulaOpCodeMapper() const; + + DECL_LINK( ModifyHdl, ParaWin* ); + DECL_LINK( FxHdl, ParaWin* ); + + DECL_LINK( MatrixHdl, CheckBox *); + DECL_LINK( FormulaHdl, MultiLineEdit* ); + DECL_LINK( FormulaCursorHdl, EditBox*); + DECL_LINK( BtnHdl, PushButton* ); + DECL_LINK( GetEdFocusHdl, ArgInput* ); + DECL_LINK( GetFxFocusHdl, ArgInput* ); + DECL_LINK( DblClkHdl, FuncPage* ); + DECL_LINK( FuncSelHdl, FuncPage*); + DECL_LINK( StructSelHdl, StructPage * ); + public: + OModuleClient m_aModuleClient; + mutable uno::Reference< sheet::XFormulaOpCodeMapper> m_xOpCodeMapper; + uno::Sequence< sheet::FormulaToken > m_aTokenList; + ::std::auto_ptr<FormulaTokenArray> m_pTokenArray; + mutable uno::Sequence< sheet::FormulaOpCodeMapEntry > m_aSpecialOpCodes; + mutable const sheet::FormulaOpCodeMapEntry* m_pSpecialOpCodesEnd; + mutable uno::Sequence< sheet::FormulaToken > m_aSeparatorsOpCodes; + mutable uno::Sequence< sheet::FormulaOpCodeMapEntry > m_aFunctionOpCodes; + mutable const sheet::FormulaOpCodeMapEntry* m_pFunctionOpCodesEnd; + mutable uno::Sequence< sheet::FormulaOpCodeMapEntry > m_aUnaryOpCodes; + mutable const sheet::FormulaOpCodeMapEntry* m_pUnaryOpCodesEnd; + mutable uno::Sequence< sheet::FormulaOpCodeMapEntry > m_aBinaryOpCodes; + mutable const sheet::FormulaOpCodeMapEntry* m_pBinaryOpCodesEnd; + ::std::vector< ::boost::shared_ptr<OFormulaToken> > m_aTokens; + ::std::map<FormulaToken*,sheet::FormulaToken> m_aTokenMap; + IFormulaEditorHelper* m_pHelper; + Dialog* m_pParent; + IControlReferenceHandler* m_pDlg; + TabControl aTabCtrl; + GroupBox aGEdit; //! MUST be placed before pParaWin for initializing + ParaWin* pParaWin; + FixedText aFtHeadLine; + FixedInfo aFtFuncName; + FixedInfo aFtFuncDesc; + + FixedText aFtEditName; + //FixedInfo aFtEditDesc; + + FixedText aFtResult; + ValWnd aWndResult; + + FixedText aFtFormula; + EditBox aMEFormula; + + CheckBox aBtnMatrix; + HelpButton aBtnHelp; + CancelButton aBtnCancel; + + PushButton aBtnBackward; + PushButton aBtnForward; + OKButton aBtnEnd; + + RefEdit aEdRef; + RefButton aRefBtn; + + FixedText aFtFormResult; + ValWnd aWndFormResult; + + RefEdit* pTheRefEdit; + RefButton* pTheRefButton; + FuncPage* pFuncPage; + StructPage* pStructPage; + String aOldFormula; + BOOL bStructUpdate; + MultiLineEdit* pMEdit; + BOOL bUserMatrixFlag; + Timer aTimer; + + const String aTitle1; + const String aTitle2; + const String aTxtEnd; + const String aTxtOk; // hinter aBtnEnd + FormulaHelper + m_aFormulaHelper; + + SmartId m_aSmartEditHelpId; + + ULONG nOldHelp; + ULONG nOldUnique; + ULONG nActivWinId; + BOOL bIsShutDown; + + + + Font aFntBold; + Font aFntLight; + USHORT nEdFocus; + // Selection theCurSel; + BOOL bEditFlag; + const IFunctionDescription* pFuncDesc; + xub_StrLen nArgs; + ::std::vector< ::rtl::OUString > m_aArguments; + Selection aFuncSel; + + FormulaDlg_Impl(Dialog* pParent + , bool _bSupportFunctionResult + , bool _bSupportResult + , bool _bSupportMatrix + ,IFormulaEditorHelper* _pHelper + ,const IFunctionManager* _pFunctionMgr + ,IControlReferenceHandler* _pDlg); + ~FormulaDlg_Impl(); + + }; +FormulaDlg_Impl::FormulaDlg_Impl(Dialog* pParent + , bool _bSupportFunctionResult + , bool _bSupportResult + , bool _bSupportMatrix + ,IFormulaEditorHelper* _pHelper + ,const IFunctionManager* _pFunctionMgr + ,IControlReferenceHandler* _pDlg) + : + m_pHelper (_pHelper), + m_pParent (pParent), + m_pDlg (_pDlg), + aTabCtrl ( pParent, ModuleRes( TC_FUNCTION ) ), + aGEdit ( pParent, ModuleRes( GB_EDIT ) ), + aFtHeadLine ( pParent, ModuleRes( FT_HEADLINE ) ), + aFtFuncName ( pParent, ModuleRes( FT_FUNCNAME ) ), + aFtFuncDesc ( pParent, ModuleRes( FT_FUNCDESC ) ), + // + aFtEditName ( pParent, ModuleRes( FT_EDITNAME ) ), + aFtResult ( pParent, ModuleRes( FT_RESULT ) ), + aWndResult ( pParent, ModuleRes( WND_RESULT ) ), + + aFtFormula ( pParent, ModuleRes( FT_FORMULA ) ), + aMEFormula ( pParent, ModuleRes( ED_FORMULA ) ), + // + aBtnMatrix ( pParent, ModuleRes( BTN_MATRIX ) ), + aBtnHelp ( pParent, ModuleRes( BTN_HELP ) ), + aBtnCancel ( pParent, ModuleRes( BTN_CANCEL ) ), + aBtnBackward ( pParent, ModuleRes( BTN_BACKWARD ) ), + aBtnForward ( pParent, ModuleRes( BTN_FORWARD ) ), + aBtnEnd ( pParent, ModuleRes( BTN_END ) ), + aEdRef ( pParent, _pDlg, ModuleRes( ED_REF) ), + aRefBtn ( pParent, ModuleRes( RB_REF),&aEdRef,_pDlg ), + aFtFormResult ( pParent, ModuleRes( FT_FORMULA_RESULT)), + aWndFormResult ( pParent, ModuleRes( WND_FORMULA_RESULT)), + // + pTheRefEdit (NULL), + pMEdit (NULL), + bUserMatrixFlag (FALSE), + // + aTitle1 ( ModuleRes( STR_TITLE1 ) ), // lokale Resource + aTitle2 ( ModuleRes( STR_TITLE2 ) ), // lokale Resource + aTxtEnd ( ModuleRes( STR_END ) ), // lokale Resource + aTxtOk ( aBtnEnd.GetText() ), + m_aFormulaHelper(_pFunctionMgr), + // + nActivWinId (0), + bIsShutDown (FALSE), + nEdFocus (0), + pFuncDesc (NULL), + nArgs (0) +{ + pParaWin = new ParaWin( pParent,_pDlg, aGEdit.GetPosPixel()); + aGEdit.Hide(); + pParaWin->Hide(); + aFtEditName.Hide(); + aEdRef.Hide(); + aRefBtn.Hide(); + + pMEdit = aMEFormula.GetEdit(); + m_aSmartEditHelpId = pMEdit->GetSmartHelpId(); + pMEdit->SetSmartUniqueId(m_aSmartEditHelpId); + + bEditFlag=FALSE; + bStructUpdate=TRUE; + Point aPos=aGEdit.GetPosPixel(); + pParaWin->SetPosPixel(aPos); + pParaWin->SetArgModifiedHdl(LINK( this, FormulaDlg_Impl, ModifyHdl ) ); + pParaWin->SetFxHdl(LINK( this, FormulaDlg_Impl, FxHdl ) ); + + pFuncPage= new FuncPage( &aTabCtrl,_pFunctionMgr); + pStructPage= new StructPage( &aTabCtrl); + pFuncPage->Hide(); + pStructPage->Hide(); + aTabCtrl.SetTabPage( TP_FUNCTION, pFuncPage); + aTabCtrl.SetTabPage( TP_STRUCT, pStructPage); + + nOldHelp = pParent->GetHelpId(); // HelpId aus Resource immer fuer "Seite 1" + nOldUnique = pParent->GetUniqueId(); + + aFtResult.Show( _bSupportResult ); + aWndResult.Show( _bSupportResult ); + + aFtFormResult.Show( _bSupportFunctionResult ); + aWndFormResult.Show( _bSupportFunctionResult ); + + if ( _bSupportMatrix ) + aBtnMatrix.SetClickHdl(LINK( this, FormulaDlg_Impl, MatrixHdl ) ); + else + aBtnMatrix.Hide(); + + aBtnCancel .SetClickHdl( LINK( this, FormulaDlg_Impl, BtnHdl ) ); + aBtnEnd .SetClickHdl( LINK( this, FormulaDlg_Impl, BtnHdl ) ); + aBtnForward .SetClickHdl( LINK( this, FormulaDlg_Impl, BtnHdl ) ); + aBtnBackward.SetClickHdl( LINK( this, FormulaDlg_Impl, BtnHdl ) ); + + pFuncPage->SetDoubleClickHdl( LINK( this, FormulaDlg_Impl, DblClkHdl ) ); + pFuncPage->SetSelectHdl( LINK( this, FormulaDlg_Impl, FuncSelHdl) ); + pStructPage->SetSelectionHdl( LINK( this, FormulaDlg_Impl, StructSelHdl ) ); + pMEdit->SetModifyHdl( LINK( this, FormulaDlg_Impl, FormulaHdl ) ); + aMEFormula.SetSelChangedHdl( LINK( this, FormulaDlg_Impl, FormulaCursorHdl ) ); + + aFntLight = aFtFormula.GetFont(); + aFntLight.SetTransparent( TRUE ); + aFntBold = aFntLight; + aFntBold.SetWeight( WEIGHT_BOLD ); + + pParaWin->SetArgumentFonts(aFntBold,aFntLight); + + // function description for choosing a function is no longer in a different color + + aFtHeadLine.SetFont(aFntBold); + aFtFuncName.SetFont(aFntLight); + aFtFuncDesc.SetFont(aFntLight); +} +FormulaDlg_Impl::~FormulaDlg_Impl() +{ + if(aTimer.IsActive()) + { + aTimer.SetTimeoutHdl(Link()); + aTimer.Stop(); + } // if(aTimer.IsActive()) + bIsShutDown=TRUE;// Setzen, damit PreNotify keinen GetFocus speichert. + FormEditData* pData = m_pHelper->getFormEditData(); + if (pData) // wird nicht ueber Close zerstoert; + { + pData->SetFStart((xub_StrLen)pMEdit->GetSelection().Min()); + pData->SetSelection(pMEdit->GetSelection()); + + if(aTabCtrl.GetCurPageId()==TP_FUNCTION) + pData->SetMode( (USHORT) FORMULA_FORMDLG_FORMULA ); + else + pData->SetMode( (USHORT) FORMULA_FORMDLG_EDIT ); + pData->SetUndoStr(pMEdit->GetText()); + pData->SetMatrixFlag(aBtnMatrix.IsChecked()); + } + + aTabCtrl.RemovePage(TP_FUNCTION); + aTabCtrl.RemovePage(TP_STRUCT); + + delete pStructPage; + delete pFuncPage; + delete pParaWin; + DeleteArgs(); +} +// ----------------------------------------------------------------------------- +void FormulaDlg_Impl::PreNotify( NotifyEvent& rNEvt ) +{ + USHORT nSwitch=rNEvt.GetType(); + if(nSwitch==EVENT_GETFOCUS && !bIsShutDown) + { + Window* pWin=rNEvt.GetWindow(); + if(pWin!=NULL) + { + nActivWinId = pWin->GetUniqueId(); + if(nActivWinId==0) + { + Window* pParent=pWin->GetParent(); + while(pParent!=NULL) + { + nActivWinId=pParent->GetUniqueId(); + + if(nActivWinId!=0) break; + + pParent=pParent->GetParent(); + } + } + if(nActivWinId!=0) + { + + FormEditData* pData = m_pHelper->getFormEditData(); + + if (pData && !aTimer.IsActive()) // wird nicht ueber Close zerstoert; + { + pData->SetUniqueId(nActivWinId); + } + } + } + } +} +uno::Reference< sheet::XFormulaOpCodeMapper > FormulaDlg_Impl::GetFormulaOpCodeMapper() const +{ + if ( !m_xOpCodeMapper.is() ) + { + m_xOpCodeMapper = m_pHelper->getFormulaOpCodeMapper(); + m_aFunctionOpCodes = m_xOpCodeMapper->getAvailableMappings(sheet::FormulaLanguage::ODFF,sheet::FormulaMapGroup::FUNCTIONS); + m_pFunctionOpCodesEnd = m_aFunctionOpCodes.getConstArray() + m_aFunctionOpCodes.getLength(); + + m_aUnaryOpCodes = m_xOpCodeMapper->getAvailableMappings(sheet::FormulaLanguage::ODFF,sheet::FormulaMapGroup::UNARY_OPERATORS); + m_pUnaryOpCodesEnd = m_aUnaryOpCodes.getConstArray() + m_aUnaryOpCodes.getLength(); + + m_aBinaryOpCodes = m_xOpCodeMapper->getAvailableMappings(sheet::FormulaLanguage::ODFF,sheet::FormulaMapGroup::BINARY_OPERATORS); + m_pBinaryOpCodesEnd = m_aBinaryOpCodes.getConstArray() + m_aBinaryOpCodes.getLength(); + + uno::Sequence< ::rtl::OUString > aArgs(3); + aArgs[TOKEN_OPEN] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("(")); + aArgs[TOKEN_CLOSE] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")); + aArgs[TOKEN_SEP] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(";")); + m_aSeparatorsOpCodes = m_xOpCodeMapper->getMappings(aArgs,sheet::FormulaLanguage::ODFF); + + m_aSpecialOpCodes = m_xOpCodeMapper->getAvailableMappings(sheet::FormulaLanguage::ODFF,sheet::FormulaMapGroup::SPECIAL); + m_pSpecialOpCodesEnd = m_aSpecialOpCodes.getConstArray() + m_aSpecialOpCodes.getLength(); + } // if ( !m_xOpCodeMapper.is() ) + return m_xOpCodeMapper; +} + +void FormulaDlg_Impl::DeleteArgs() +{ + ::std::vector< ::rtl::OUString>().swap(m_aArguments); + nArgs = 0; +} +namespace +{ + // comparing two property instances + struct OpCodeCompare : public ::std::binary_function< sheet::FormulaOpCodeMapEntry, sal_Int32 , bool > + { + bool operator() (const sheet::FormulaOpCodeMapEntry& x, sal_Int32 y) const + { + return x.Token.OpCode == y; + } + }; +} +// ----------------------------------------------------------------------------- +xub_StrLen FormulaDlg_Impl::GetFunctionPos(xub_StrLen nPos) +{ + const sal_Unicode sep = m_pHelper->getFunctionManager()->getSingleToken(IFunctionManager::eSep); + + xub_StrLen nTokPos=1; + xub_StrLen nOldTokPos=1; + xub_StrLen nFuncPos=STRING_NOTFOUND; //@ Testweise + xub_StrLen nPrevFuncPos=1; + short nBracketCount=0; + BOOL bFlag=FALSE; + String aFormString = pMEdit->GetText(); + m_aFormulaHelper.GetCharClass()->toUpper( aFormString ); + + if ( m_aTokenList.getLength() ) + { + const uno::Reference< sheet::XFormulaParser > xParser(m_pHelper->getFormulaParser()); + + const sheet::FormulaToken* pIter = m_aTokenList.getConstArray(); + const sheet::FormulaToken* pEnd = pIter + m_aTokenList.getLength(); + //if ( pIter != pEnd && aFormString.GetChar(0) == '=' ) + // ++pIter; + try + { + while ( pIter != pEnd ) + { + const sal_Int32 eOp = pIter->OpCode; + uno::Sequence<sheet::FormulaToken> aArgs(1); + aArgs[0] = *pIter; + const String aString = xParser->printFormula(aArgs); + const sheet::FormulaToken* pNextToken = pIter + 1; + + if(!bUserMatrixFlag && FormulaCompiler::IsMatrixFunction((OpCode)eOp) ) + { + aBtnMatrix.Check(); + } + + if ( eOp == m_aSpecialOpCodes[sheet::FormulaMapGroupSpecialOffset::PUSH].Token.OpCode || eOp == m_aSpecialOpCodes[sheet::FormulaMapGroupSpecialOffset::SPACES].Token.OpCode ) + { + const xub_StrLen n1=aFormString.Search(sep, nTokPos); + const xub_StrLen n2=aFormString.Search(')',nTokPos); + xub_StrLen nXXX=nTokPos; + if(n1<n2) + { + nTokPos=n1; + } + else + { + nTokPos=n2; + } + if ( pNextToken != pEnd ) + { + aArgs[0] = *pNextToken; + const String a2String = xParser->printFormula(aArgs); + const xub_StrLen n3 = aFormString.Search(a2String,nXXX); + if ( n3 < nTokPos ) + nTokPos = n3; + } + } + else + { + nTokPos = sal::static_int_cast<xub_StrLen>( nTokPos + aString.Len() ); + } + + if ( eOp == m_aSeparatorsOpCodes[TOKEN_OPEN].OpCode ) + { + nBracketCount++; + bFlag=TRUE; + } + else if ( eOp == m_aSeparatorsOpCodes[TOKEN_CLOSE].OpCode ) + { + nBracketCount--; + bFlag=FALSE; + nFuncPos=nPrevFuncPos; + } + bool bIsFunction = ::std::find_if(m_aFunctionOpCodes.getConstArray(),m_pFunctionOpCodesEnd,::std::bind2nd(OpCodeCompare(),boost::cref(eOp))) != m_pFunctionOpCodesEnd; + + if ( bIsFunction && m_aSpecialOpCodes[sheet::FormulaMapGroupSpecialOffset::SPACES].Token.OpCode != eOp ) + { + nPrevFuncPos = nFuncPos; + nFuncPos = nOldTokPos; + } + + if ( nOldTokPos <= nPos && nPos < nTokPos ) + { + if ( !bIsFunction ) + { + if ( nBracketCount < 1 ) + { + nFuncPos= pMEdit->GetText().Len(); + } + else if ( !bFlag ) + { + nFuncPos=nPrevFuncPos; + } + } + break; + } + + pIter = pNextToken; + nOldTokPos = nTokPos; + } // while ( pIter != pEnd ) + } + catch(const uno::Exception& ) + { + DBG_ERROR("Exception caught!"); + } + } + + return nFuncPos; +} +// ----------------------------------------------------------------------------- +BOOL FormulaDlg_Impl::CalcValue( const String& rStrExp, String& rStrResult ) +{ + BOOL bResult = TRUE; + + if ( rStrExp.Len() > 0 ) + { + // nur, wenn keine Tastatureingabe mehr anliegt, den Wert berechnen: + + if ( !Application::AnyInput( INPUT_KEYBOARD ) ) + { + bResult = m_pHelper->calculateValue(rStrExp,rStrResult); + } + else + bResult = FALSE; + } + + return bResult; +} + +void FormulaDlg_Impl::UpdateValues() +{ + String aStrResult; + + if ( CalcValue( pFuncDesc->getFormula( m_aArguments ), aStrResult ) ) + aWndResult.SetValue( aStrResult ); + + aStrResult.Erase(); + if ( CalcValue(m_pHelper->getCurrentFormula(), aStrResult ) ) + aWndFormResult.SetValue( aStrResult ); + else + { + aStrResult.Erase(); + aWndFormResult.SetValue( aStrResult ); + } + CalcStruct(pMEdit->GetText()); +} + +BOOL FormulaDlg_Impl::CalcStruct( const String& rStrExp) +{ + BOOL bResult = TRUE; + xub_StrLen nLength=rStrExp.Len(); + + if ( rStrExp.Len() > 0 && aOldFormula!=rStrExp && bStructUpdate) + { + // nur, wenn keine Tastatureingabe mehr anliegt, den Wert berechnen: + + if ( !Application::AnyInput( INPUT_KEYBOARD ) ) + { + pStructPage->ClearStruct(); + + String aString=rStrExp; + if(rStrExp.GetChar(nLength-1)=='(') + { + aString.Erase((xub_StrLen)(nLength-1)); + } + + aString.EraseAllChars('\n'); + String aStrResult; + + if ( CalcValue(aString, aStrResult ) ) + aWndFormResult.SetValue( aStrResult ); + + UpdateTokenArray(aString); + fillTree(pStructPage); + + aOldFormula=rStrExp; + if(rStrExp.GetChar(nLength-1)=='(') + UpdateTokenArray(rStrExp); + } + else + bResult = FALSE; + } + return bResult; +} + +// ----------------------------------------------------------------------------- +void FormulaDlg_Impl::MakeTree(IStructHelper* _pTree,SvLBoxEntry* pParent,FormulaToken* _pToken,long Count) +{ + if( _pToken != NULL && Count > 0 ) + { + long nParas = _pToken->GetParamCount(); + OpCode eOp = _pToken->GetOpCode(); + + uno::Sequence<sheet::FormulaToken> aArgs(1); + aArgs[0] = m_aTokenMap.find(_pToken)->second; + const String aResult = m_pHelper->getFormulaParser()->printFormula(aArgs); + + if ( nParas > 0 ) + { + SvLBoxEntry* pEntry; + + String aTest=_pTree->GetEntryText(pParent); + + if(aTest==aResult && + (eOp==ocAdd || eOp==ocMul || + eOp==ocAmpersand)) + { + pEntry=pParent; + } + else + { + if(eOp==ocBad) + { + pEntry=_pTree->InsertEntry(aResult,pParent,STRUCT_ERROR,0,_pToken); + } + else + { + pEntry=_pTree->InsertEntry(aResult,pParent,STRUCT_FOLDER,0,_pToken); + } + } + + MakeTree(_pTree,pEntry,m_pTokenArray->PrevRPN(),nParas); + --Count; + m_pTokenArray->NextRPN(); + MakeTree(_pTree,pParent,m_pTokenArray->PrevRPN(),Count); + } + else + { + if(eOp==ocBad) + { + _pTree->InsertEntry(aResult,pParent,STRUCT_ERROR,0,_pToken); + } + else + { + _pTree->InsertEntry(aResult,pParent,STRUCT_END,0,_pToken); + } + --Count; + MakeTree(_pTree,pParent,m_pTokenArray->PrevRPN(),Count); + } + } +} + +void FormulaDlg_Impl::fillTree(IStructHelper* _pTree) +{ + GetFormulaOpCodeMapper(); + FormulaToken* pToken = m_pTokenArray->LastRPN(); + + if( pToken != NULL) + { + MakeTree(_pTree,NULL,pToken,1); + } +} +void FormulaDlg_Impl::UpdateTokenArray( const String& rStrExp) +{ + m_aTokenMap.clear(); + m_aTokenList.realloc(0); + m_aTokenList = m_pHelper->getFormulaParser()->parseFormula(rStrExp); + GetFormulaOpCodeMapper(); // just to get it initialized + m_pTokenArray = m_pHelper->convertToTokenArray(m_aTokenList); + const sal_Int32 nLen = static_cast<sal_Int32>(m_pTokenArray->GetLen()); + FormulaToken** pTokens = m_pTokenArray->GetArray(); + if ( pTokens && nLen == m_aTokenList.getLength() ) + { + for (sal_Int32 nPos=0; nPos<nLen; nPos++) + { + m_aTokenMap.insert(::std::map<FormulaToken*,sheet::FormulaToken>::value_type(pTokens[nPos],m_aTokenList[nPos])); + } + } // if ( pTokens && nLen == m_aTokenList.getLength() ) + + FormulaCompiler aCompiler(*m_pTokenArray.get()); + aCompiler.CompileTokenArray(); +} + +void FormulaDlg_Impl::FillDialog(BOOL nFlag) +{ + if ( nFlag ) + FillControls(); + FillListboxes(); + + String aStrResult; + + if ( CalcValue(m_pHelper->getCurrentFormula(), aStrResult ) ) + aWndFormResult.SetValue( aStrResult ); + else + { + aStrResult.Erase(); + aWndFormResult.SetValue( aStrResult ); + } +} + +// ----------------------------------------------------------------------------- +void FormulaDlg_Impl::FillListboxes() +{ + // Umschalten zwischen den "Seiten" + FormEditData* pData = m_pHelper->getFormEditData(); + String aNewTitle; + // 1. Seite: Funktion auswaehlen + if ( pFuncDesc && pFuncDesc->getCategory() ) + { + if( pFuncPage->GetCategory() != pFuncDesc->getCategory()->getNumber() + 1 ) + pFuncPage->SetCategory(static_cast<USHORT>(pFuncDesc->getCategory()->getNumber() + 1)); + + USHORT nPos=pFuncPage->GetFuncPos(pFuncDesc); + + pFuncPage->SetFunction(nPos); + } + else if ( pData ) + { + pFuncPage->SetCategory( pData->GetCatSel() ); + pFuncPage->SetFunction( pData->GetFuncSel() ); + } + FuncSelHdl(NULL); + + // ResizeArgArr jetzt schon in UpdateFunctionDesc + + + m_pHelper->setDispatcherLock( TRUE);// Modal-Modus einschalten + + aNewTitle = aTitle1; + + // HelpId fuer 1. Seite ist die aus der Resource + m_pParent->SetHelpId( nOldHelp ); + m_pParent->SetUniqueId( nOldUnique ); +} +// ----------------------------------------------------------------------------- +void FormulaDlg_Impl::FillControls() +{ + // Umschalten zwischen den "Seiten" + FormEditData* pData = m_pHelper->getFormEditData(); + if (!pData ) + return; + + String aNewTitle; + // 2. Seite oder Editieren: ausgewaehlte Funktion anzeigen + + xub_StrLen nFStart = pData->GetFStart(); + String aFormula = m_pHelper->getCurrentFormula(); + xub_StrLen nNextFStart = nFStart; + xub_StrLen nNextFEnd = 0; + + aFormula.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " )" )); + DeleteArgs(); + const IFunctionDescription* pOldFuncDesc = pFuncDesc; + BOOL bTestFlag = FALSE; + + if ( m_aFormulaHelper.GetNextFunc( aFormula, FALSE, + nNextFStart, &nNextFEnd, &pFuncDesc, &m_aArguments ) ) + { + bTestFlag = (pOldFuncDesc != pFuncDesc); + if(bTestFlag) + { + aFtHeadLine.Hide(); + aFtFuncName.Hide(); + aFtFuncDesc.Hide(); + pParaWin->SetFunctionDesc(pFuncDesc); + aFtEditName.SetText( pFuncDesc->getFunctionName() ); + aFtEditName.Show(); + pParaWin->Show(); + const long nHelpId = pFuncDesc->getHelpId(); + if ( nHelpId ) + pMEdit->SetSmartHelpId(SmartId(nHelpId)); + } + + xub_StrLen nOldStart, nOldEnd; + m_pHelper->getSelection( nOldStart, nOldEnd ); + if ( nOldStart != nNextFStart || nOldEnd != nNextFEnd ) + { + m_pHelper->setSelection( nNextFStart, nNextFEnd ); + } + aFuncSel.Min() = nNextFStart; + aFuncSel.Max() = nNextFEnd; + + if(!bEditFlag) + pMEdit->SetText(m_pHelper->getCurrentFormula()); + xub_StrLen PrivStart, PrivEnd; + m_pHelper->getSelection( PrivStart, PrivEnd); + if(!bEditFlag) + pMEdit->SetSelection( Selection(PrivStart, PrivEnd)); + + nArgs = pFuncDesc->getSuppressedArgumentCount(); + USHORT nOffset = pData->GetOffset(); + nEdFocus = pData->GetEdFocus(); + + // Verkettung der Edit's fuer Focus-Kontrolle + + if(bTestFlag) + pParaWin->SetArgumentOffset(nOffset); + USHORT nActiv=0; + xub_StrLen nArgPos= m_aFormulaHelper.GetArgStart( aFormula, nFStart, 0 ); + xub_StrLen nEditPos=(xub_StrLen) pMEdit->GetSelection().Min(); + BOOL bFlag=FALSE; + + for(USHORT i=0;i<nArgs;i++) + { + sal_Int32 nLength = m_aArguments[i].getLength()+1; + pParaWin->SetArgument(i,m_aArguments[i]); + if(nArgPos<=nEditPos && nEditPos<nArgPos+nLength) + { + nActiv=i; + bFlag=TRUE; + } + nArgPos = sal::static_int_cast<xub_StrLen>( nArgPos + nLength ); + } + pParaWin->UpdateParas(); + + if(bFlag) + { + pParaWin->SetActiveLine(nActiv); + } + + //pParaWin->SetEdFocus( nEdFocus ); + UpdateValues(); + } + else + { + aFtEditName.SetText(String()); + pMEdit->SetSmartHelpId(m_aSmartEditHelpId); + } + // Test, ob vorne/hinten noch mehr Funktionen sind + + xub_StrLen nTempStart = m_aFormulaHelper.GetArgStart( aFormula, nFStart, 0 ); + BOOL bNext = m_aFormulaHelper.GetNextFunc( aFormula, FALSE, nTempStart ); + nTempStart=(xub_StrLen)pMEdit->GetSelection().Min(); + pData->SetFStart(nTempStart); + BOOL bPrev = m_aFormulaHelper.GetNextFunc( aFormula, TRUE, nTempStart ); + aBtnBackward.Enable(bPrev); + aBtnForward.Enable(bNext); +} +// ----------------------------------------------------------------------------- + +void FormulaDlg_Impl::ClearAllParas() +{ + DeleteArgs(); + pFuncDesc = NULL; + pParaWin->ClearAll(); + aWndResult.SetValue(String()); + aFtFuncName.SetText(String()); + FuncSelHdl(NULL); + + if(pFuncPage->IsVisible()) + { + aFtEditName.Hide(); + pParaWin->Hide(); + + aBtnForward.Enable(TRUE); //@new + aFtHeadLine.Show(); + aFtFuncName.Show(); + aFtFuncDesc.Show(); + } +} +String FormulaDlg_Impl::RepairFormula(const String& aFormula) +{ + String aResult('='); + try + { + UpdateTokenArray(aFormula); + + if ( m_aTokenList.getLength() ) + { + const String sFormula(m_pHelper->getFormulaParser()->printFormula(m_aTokenList)); + if ( !sFormula.Len() || sFormula.GetChar(0) != '=' ) + aResult += sFormula; + else + aResult = sFormula; + + } + } + catch(const uno::Exception& ) + { + DBG_ERROR("Exception caught!"); + } + return aResult; +} + +void FormulaDlg_Impl::DoEnter(BOOL bOk) +{ + // Eingabe ins Dokument uebernehmen oder abbrechen + if ( bOk) + { + // ggf. Dummy-Argumente entfernen + String aInputFormula = m_pHelper->getCurrentFormula(); + String aString = RepairFormula(pMEdit->GetText()); + m_pHelper->setSelection(0, aInputFormula.Len()); + m_pHelper->setCurrentFormula(aString); + } + + m_pHelper->switchBack(); + + m_pHelper->dispatch(bOk,aBtnMatrix.IsChecked()); + // Daten loeschen + m_pHelper->deleteFormData(); + + // Dialog schliessen + m_pHelper->doClose(bOk); +} +// ----------------------------------------------------------------------------- + +IMPL_LINK( FormulaDlg_Impl, BtnHdl, PushButton*, pBtn ) +{ + if ( pBtn == &aBtnCancel ) + { + DoEnter(FALSE); // schliesst den Dialog + } + else if ( pBtn == &aBtnEnd ) + { + DoEnter(TRUE); // schliesst den Dialog + } + else if ( pBtn == &aBtnForward ) + { + //@pMEdit->GrabFocus(); // Damit die Selektion auch angezeigt wird. + const IFunctionDescription* pDesc =pFuncPage->GetFuncDesc( pFuncPage->GetFunction() ); + + if(pDesc==pFuncDesc || !pFuncPage->IsVisible()) + EditNextFunc( TRUE ); + else + { + DblClkHdl(pFuncPage); //new + aBtnForward.Enable(FALSE); //new + } + //@EditNextFunc( TRUE ); + } + else if ( pBtn == &aBtnBackward ) + { + bEditFlag=FALSE; + aBtnForward.Enable(TRUE); + EditNextFunc( FALSE ); + aMEFormula.Invalidate(); + aMEFormula.Update(); + } + //... + + return 0; +} +// ----------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------- +// Funktionen fuer 1. Seite +// -------------------------------------------------------------------------- + +void FormulaDlg_Impl::ResizeArgArr( const IFunctionDescription* pNewFunc ) +{ + if ( pFuncDesc != pNewFunc ) + { + DeleteArgs(); + + if ( pNewFunc ) + nArgs = pNewFunc->getSuppressedArgumentCount(); + + pFuncDesc = pNewFunc; + } +} +// ----------------------------------------------------------------------------- + +void FormulaDlg_Impl::UpdateFunctionDesc() +{ + FormEditData* pData = m_pHelper->getFormEditData(); + if (!pData) + return; + USHORT nCat = pFuncPage->GetCategory(); + if ( nCat == LISTBOX_ENTRY_NOTFOUND ) + nCat = 0; + pData->SetCatSel( nCat ); + USHORT nFunc = pFuncPage->GetFunction(); + if ( nFunc == LISTBOX_ENTRY_NOTFOUND ) + nFunc = 0; + pData->SetFuncSel( nFunc ); + + if ( (pFuncPage->GetFunctionEntryCount() > 0) + && (pFuncPage->GetFunction() != LISTBOX_ENTRY_NOTFOUND) ) + { + const IFunctionDescription* pDesc = pFuncPage->GetFuncDesc(pFuncPage->GetFunction() ); + if (pDesc) + { + pDesc->initArgumentInfo(); // full argument info is needed + + String aSig = pDesc->getSignature(); + + aFtFuncName.SetText( aSig ); + aFtFuncDesc.SetText( pDesc->getFunctionName() ); + ResizeArgArr( pDesc ); + + if ( !m_aArguments.empty() ) // noch Argumente da? + aSig = pDesc->getFormula( m_aArguments ); // fuer Eingabezeile + //@ m_pHelper->setCurrentFormula( aSig ); + } + } + else + { + aFtFuncName.SetText( String() ); + aFtFuncDesc.SetText( String() ); + + //ResizeArgArr( NULL ); + m_pHelper->setCurrentFormula( String() ); + } +} +// ----------------------------------------------------------------------------- + +// Handler fuer Listboxen + +IMPL_LINK( FormulaDlg_Impl, DblClkHdl, FuncPage*, EMPTYARG ) +{ + USHORT nFunc = pFuncPage->GetFunction(); + + // ex-UpdateLRUList + const IFunctionDescription* pDesc = pFuncPage->GetFuncDesc(nFunc); + m_pHelper->insertEntryToLRUList(pDesc); + + String aFuncName = pFuncPage->GetSelFunctionName(); + aFuncName.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" )); + m_pHelper->setCurrentFormula(aFuncName); + pMEdit->ReplaceSelected(aFuncName); + + Selection aSel=pMEdit->GetSelection(); + aSel.Max()=aSel.Max()-1; + pMEdit->SetSelection(aSel); + + FormulaHdl(pMEdit); + + aSel.Min()=aSel.Max(); + pMEdit->SetSelection(aSel); + + if(nArgs==0) + { + BtnHdl(&aBtnBackward); + } + + pParaWin->SetEdFocus(0); + aBtnForward.Enable(FALSE); //@New + + return 0; +} +// ----------------------------------------------------------------------------- + +// -------------------------------------------------------------------------- +// Funktionen fuer rechte Seite +// -------------------------------------------------------------------------- +void FormulaDlg_Impl::SetData(xub_StrLen nFStart,xub_StrLen nNextFStart,xub_StrLen nNextFEnd,xub_StrLen& PrivStart,xub_StrLen& PrivEnd) +{ + xub_StrLen nFEnd; + + // Selektion merken und neue setzen + m_pHelper->getSelection( nFStart, nFEnd ); + m_pHelper->setSelection( nNextFStart, nNextFEnd ); + if(!bEditFlag) + pMEdit->SetText(m_pHelper->getCurrentFormula()); + + + m_pHelper->getSelection( PrivStart, PrivEnd); + if(!bEditFlag) + { + pMEdit->SetSelection( Selection(PrivStart, PrivEnd)); + aMEFormula.UpdateOldSel(); + } + + FormEditData* pData = m_pHelper->getFormEditData(); + pData->SetFStart( nNextFStart ); + pData->SetOffset( 0 ); + pData->SetEdFocus( 0 ); + + FillDialog(); +} +// ----------------------------------------------------------------------------- +void FormulaDlg_Impl::EditThisFunc(xub_StrLen nFStart) +{ + FormEditData* pData = m_pHelper->getFormEditData(); + if (!pData) return; + + String aFormula = m_pHelper->getCurrentFormula(); + + if(nFStart==NOT_FOUND) + { + nFStart = pData->GetFStart(); + } + else + { + pData->SetFStart(nFStart); + } + + xub_StrLen nNextFStart = nFStart; + xub_StrLen nNextFEnd = 0; + + BOOL bFound; + + //@bFound = m_pHelper->getNextFunction( aFormula, FALSE, nNextFStart, &nNextFEnd, &pFuncDesc ); + + bFound = m_aFormulaHelper.GetNextFunc( aFormula, FALSE, nNextFStart, &nNextFEnd); + if ( bFound ) + { + xub_StrLen PrivStart, PrivEnd; + SetData(nFStart,nNextFStart,nNextFEnd,PrivStart, PrivEnd); + m_pHelper->showReference(aFormula.Copy(PrivStart, PrivEnd-PrivStart)); + } + else + { + ClearAllParas(); + } +} + +void FormulaDlg_Impl::EditNextFunc( BOOL bForward, xub_StrLen nFStart ) +{ + FormEditData* pData = m_pHelper->getFormEditData(); + if (!pData) + return; + + String aFormula = m_pHelper->getCurrentFormula(); + + if(nFStart==NOT_FOUND) + { + nFStart = pData->GetFStart(); + } + else + { + pData->SetFStart(nFStart); + } + + xub_StrLen nNextFStart = 0; + xub_StrLen nNextFEnd = 0; + + BOOL bFound; + if ( bForward ) + { + nNextFStart = m_aFormulaHelper.GetArgStart( aFormula, nFStart, 0 ); + //@bFound = m_pHelper->getNextFunction( aFormula, FALSE, nNextFStart, &nNextFEnd, &pFuncDesc ); + bFound = m_aFormulaHelper.GetNextFunc( aFormula, FALSE, nNextFStart, &nNextFEnd); + } + else + { + nNextFStart = nFStart; + //@bFound = m_pHelper->getNextFunction( aFormula, TRUE, nNextFStart, &nNextFEnd, &pFuncDesc ); + bFound = m_aFormulaHelper.GetNextFunc( aFormula, TRUE, nNextFStart, &nNextFEnd); + } + + if ( bFound ) + { + xub_StrLen PrivStart, PrivEnd; + SetData(nFStart,nNextFStart,nNextFEnd,PrivStart, PrivEnd); + } +} + +void FormulaDlg_Impl::EditFuncParas(xub_StrLen nEditPos) +{ + if(pFuncDesc!=NULL) + { + FormEditData* pData = m_pHelper->getFormEditData(); + if (!pData) return; + + String aFormula = m_pHelper->getCurrentFormula(); + aFormula +=')'; + xub_StrLen nFStart = pData->GetFStart(); + + DeleteArgs(); + + nArgs = pFuncDesc->getSuppressedArgumentCount(); + + sal_Int32 nArgPos=m_aFormulaHelper.GetArgStart( aFormula, nFStart, 0 ); + m_aFormulaHelper.GetArgStrings(m_aArguments,aFormula, nFStart, nArgs ); +// m_aArguments = ScFormulaUtil::GetArgStrings( aFormula, nFStart, nArgs ); + + USHORT nActiv=pParaWin->GetSliderPos(); + BOOL bFlag=FALSE; + ::std::vector< ::rtl::OUString >::iterator aIter = m_aArguments.begin(); + ::std::vector< ::rtl::OUString >::iterator aEnd = m_aArguments.end(); + for(USHORT i=0;aIter != aEnd;i++,++aIter) + { + sal_Int32 nLength=(*aIter).getLength(); + pParaWin->SetArgument(i,(*aIter)); + if(nArgPos<=nEditPos && nEditPos<nArgPos+nLength) + { + nActiv=i; + bFlag=TRUE; + } + nArgPos+=nLength+1; + } + + if(bFlag) + { + pParaWin->SetSliderPos(nActiv); + } + + pParaWin->UpdateParas(); + UpdateValues(); + } + +} + +void FormulaDlg_Impl::SaveArg( USHORT nEd ) +{ + if (nEd<nArgs) + { + USHORT i; + for(i=0;i<=nEd;i++) + { + if ( m_aArguments[i].getLength() == 0 ) + m_aArguments[i] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ")); + } + if(pParaWin->GetArgument(nEd).Len()!=0) + m_aArguments[nEd] = pParaWin->GetArgument(nEd); + + USHORT nClearPos=nEd+1; + for(i=nEd+1;i<nArgs;i++) + { + if(pParaWin->GetArgument(i).Len()!=0) + { + nClearPos=i+1; + } + } + + for(i=nClearPos;i<nArgs;i++) + { + m_aArguments[i] = ::rtl::OUString(); + } + } +} + +IMPL_LINK( FormulaDlg_Impl, FxHdl, ParaWin*, pPtr ) +{ + if(pPtr==pParaWin) + { + aBtnForward.Enable(TRUE); //@ Damit eine neue Fkt eingegeben werden kann. + aTabCtrl.SetCurPageId(TP_FUNCTION); + + String aUndoStr = m_pHelper->getCurrentFormula(); // bevor unten ein ";" eingefuegt wird + FormEditData* pData = m_pHelper->getFormEditData(); + if (!pData) return 0; + + USHORT nArgNo = pParaWin->GetActiveLine(); + nEdFocus=nArgNo; + + SaveArg(nArgNo); + UpdateSelection(); + + xub_StrLen nFormulaStrPos = pData->GetFStart(); + + String aFormula = m_pHelper->getCurrentFormula(); + xub_StrLen n1 = m_aFormulaHelper.GetArgStart( aFormula, nFormulaStrPos, nEdFocus+pData->GetOffset() ); + + pData->SetEdFocus( nEdFocus ); + pData->SaveValues(); + pData->SetMode( (USHORT) FORMULA_FORMDLG_FORMULA ); + pData->SetFStart( n1 ); + pData->SetUndoStr( aUndoStr ); + ClearAllParas(); + + FillDialog(FALSE); + pFuncPage->SetFocus(); //Da Parawin nicht mehr sichtbar + } + return 0; +} + +IMPL_LINK( FormulaDlg_Impl, ModifyHdl, ParaWin*, pPtr ) +{ + if(pPtr==pParaWin) + { + SaveArg(pParaWin->GetActiveLine()); + UpdateValues(); + + UpdateSelection(); + CalcStruct(pMEdit->GetText()); + } + return 0; +} + +IMPL_LINK( FormulaDlg_Impl, FormulaHdl, MultiLineEdit*, EMPTYARG ) +{ + + FormEditData* pData = m_pHelper->getFormEditData(); + if (!pData) return 0; + + bEditFlag=TRUE; + String aInputFormula=m_pHelper->getCurrentFormula(); + String aString=pMEdit->GetText(); + + Selection aSel =pMEdit->GetSelection(); + xub_StrLen nTest=0; + + if(aString.Len()==0) //falls alles geloescht wurde + { + aString +='='; + pMEdit->SetText(aString); + aSel .Min()=1; + aSel .Max()=1; + pMEdit->SetSelection(aSel); + } + else if(aString.GetChar(nTest)!='=') //falls ersetzt wurde; + { + aString.Insert( (sal_Unicode)'=', 0 ); + pMEdit->SetText(aString); + aSel .Min()+=1; + aSel .Max()+=1; + pMEdit->SetSelection(aSel); + } + + + m_pHelper->setSelection(0, aInputFormula.Len()); + m_pHelper->setCurrentFormula(aString); + m_pHelper->setSelection((xub_StrLen)aSel.Min(),(xub_StrLen)aSel.Max()); + + xub_StrLen nPos=(xub_StrLen)aSel.Min()-1; + + String aStrResult; + + if ( CalcValue(m_pHelper->getCurrentFormula(), aStrResult ) ) + aWndFormResult.SetValue( aStrResult ); + else + { + aStrResult.Erase(); + aWndFormResult.SetValue( aStrResult ); + } + CalcStruct(aString); + + nPos=GetFunctionPos(nPos); + + if(nPos<aSel.Min()-1) + { + xub_StrLen nPos1=aString.Search('(',nPos); + EditNextFunc( FALSE, nPos1); + } + else + { + ClearAllParas(); + } + + m_pHelper->setSelection((xub_StrLen)aSel.Min(),(xub_StrLen)aSel.Max()); + bEditFlag=FALSE; + return 0; +} + +IMPL_LINK( FormulaDlg_Impl, FormulaCursorHdl, EditBox*, EMPTYARG ) +{ + FormEditData* pData = m_pHelper->getFormEditData(); + if (!pData) return 0; + xub_StrLen nFStart = pData->GetFStart(); + + bEditFlag=TRUE; + + String aInputFormula=m_pHelper->getCurrentFormula(); + String aString=pMEdit->GetText(); + + Selection aSel =pMEdit->GetSelection(); + m_pHelper->setSelection((xub_StrLen)aSel.Min(),(xub_StrLen)aSel.Max()); + + if(aSel.Min()==0) + { + aSel.Min()=1; + pMEdit->SetSelection(aSel); + } + + if(aSel.Min()!=aString.Len()) + { + xub_StrLen nPos=(xub_StrLen)aSel.Min(); + + nFStart=GetFunctionPos(nPos - 1); + + if(nFStart<nPos) + { + xub_StrLen nPos1=m_aFormulaHelper.GetFunctionEnd(aString,nFStart); + + if(nPos1>nPos || nPos1==STRING_NOTFOUND) + { + EditThisFunc(nFStart); + } + else + { + xub_StrLen n=nPos; + short nCount=1; + while(n>0) + { + if(aString.GetChar(n)==')') + nCount++; + else if(aString.GetChar(n)=='(') + nCount--; + if(nCount==0) break; + n--; + } + if(nCount==0) + { + nFStart=m_aFormulaHelper.GetFunctionStart(aString,n,TRUE); + EditThisFunc(nFStart); + } + else + { + ClearAllParas(); + } + } + } + else + { + ClearAllParas(); + } + } + m_pHelper->setSelection((xub_StrLen)aSel.Min(),(xub_StrLen)aSel.Max()); + + bEditFlag=FALSE; + return 0; +} + +void FormulaDlg_Impl::UpdateSelection() +{ + m_pHelper->setSelection((xub_StrLen)aFuncSel.Min(),(xub_StrLen)aFuncSel.Max()); + m_pHelper->setCurrentFormula( pFuncDesc->getFormula( m_aArguments ) ); + pMEdit->SetText(m_pHelper->getCurrentFormula()); + xub_StrLen PrivStart, PrivEnd; + m_pHelper->getSelection( PrivStart, PrivEnd); + aFuncSel.Min()=PrivStart; + aFuncSel.Max()=PrivEnd; + + nArgs = pFuncDesc->getSuppressedArgumentCount(); + + String aFormula=pMEdit->GetText(); + sal_Int32 nArgPos=m_aFormulaHelper.GetArgStart( aFormula,PrivStart,0); + + USHORT nPos=pParaWin->GetActiveLine(); + + for(USHORT i=0;i<nPos;i++) + { + nArgPos += (m_aArguments[i].getLength() + 1); + } + sal_Int32 nLength= m_aArguments[nPos].getLength(); + + Selection aSel(nArgPos,nArgPos+nLength); + m_pHelper->setSelection((USHORT)nArgPos,(USHORT)(nArgPos+nLength)); + pMEdit->SetSelection(aSel); + aMEFormula.UpdateOldSel(); +} +::std::pair<RefButton*,RefEdit*> FormulaDlg_Impl::RefInputStartBefore( RefEdit* pEdit, RefButton* pButton ) +{ + aEdRef.Show(); + pTheRefEdit = pEdit; + pTheRefButton = pButton; + + if( pTheRefEdit ) + { + aEdRef.SetRefString( pTheRefEdit->GetText() ); + aEdRef.SetSelection( pTheRefEdit->GetSelection() ); + aEdRef.SetHelpId( pTheRefEdit->GetHelpId() ); + aEdRef.SetUniqueId( pTheRefEdit->GetUniqueId() ); + } + + aRefBtn.Show( pButton != NULL ); + + //m_pHelper->RefInputStart( &aEdRef, pButton ? &aRefBtn : NULL ); + ::std::pair<RefButton*,RefEdit*> aPair; + aPair.first = pButton ? &aRefBtn : NULL; + aPair.second = &aEdRef; + return aPair; +} +void FormulaDlg_Impl::RefInputStartAfter( RefEdit* /*pEdit*/, RefButton* /*pButton*/ ) +{ + aRefBtn.SetEndImage(); + + if( pTheRefEdit ) + { + String aStr = aTitle2; + aStr += ' '; + aStr += aFtEditName.GetText(); + aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "( " ) ); + if( pParaWin->GetActiveLine() > 0 ) + aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "...; " ) ); + aStr += pParaWin->GetActiveArgName(); + if( pParaWin->GetActiveLine() + 1 < nArgs ) + aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "; ..." )); + aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " )" ) ); + + m_pParent->SetText( MnemonicGenerator::EraseAllMnemonicChars( aStr ) ); + } +} +void FormulaDlg_Impl::RefInputDoneAfter( BOOL bForced ) +{ + aRefBtn.SetStartImage(); + if( bForced || !aRefBtn.IsVisible() ) + { + aEdRef.Hide(); + aRefBtn.Hide(); + if( pTheRefEdit ) + { + pTheRefEdit->SetRefString( aEdRef.GetText() ); + pTheRefEdit->GrabFocus(); + + if( pTheRefButton ) + pTheRefButton->SetStartImage(); + + USHORT nPrivActiv = pParaWin->GetActiveLine(); + pParaWin->SetArgument( nPrivActiv, aEdRef.GetText() ); + ModifyHdl( pParaWin ); + pTheRefEdit = NULL; + } + m_pParent->SetText( aTitle1 ); + } +} +RefEdit* FormulaDlg_Impl::GetCurrRefEdit() +{ + return aEdRef.IsVisible() ? &aEdRef : pParaWin->GetActiveEdit(); +} +void FormulaDlg_Impl::Update() +{ + FormEditData* pData = m_pHelper->getFormEditData(); + const String sExpression = pMEdit->GetText(); + UpdateTokenArray(sExpression); + FormulaCursorHdl(&aMEFormula); + CalcStruct(sExpression); + if(pData->GetMode() == FORMULA_FORMDLG_FORMULA) + aTabCtrl.SetCurPageId(TP_FUNCTION); + else + aTabCtrl.SetCurPageId(TP_STRUCT); + aBtnMatrix.Check(pData->GetMatrixFlag()); + /*aTimer.SetTimeout(200); + aTimer.SetTimeoutHdl(LINK( this, FormulaDlg_Impl, UpdateFocusHdl)); + aTimer.Start();*/ +} +void FormulaDlg_Impl::Update(const String& _sExp) +{ + CalcStruct(_sExp); + FillDialog(); + //aBtnForward.Enable(TRUE); //@New + FuncSelHdl(NULL); +} +void FormulaDlg_Impl::SetMeText(const String& _sText) +{ + FormEditData* pData = m_pHelper->getFormEditData(); + pMEdit->SetText(_sText); + pMEdit->SetSelection( pData->GetSelection()); + aMEFormula.UpdateOldSel(); +} +FormulaDlgMode FormulaDlg_Impl::SetMeText(const String& _sText,xub_StrLen PrivStart, xub_StrLen PrivEnd,BOOL bMatrix,BOOL _bSelect,BOOL _bUpdate) +{ + FormulaDlgMode eMode = FORMULA_FORMDLG_FORMULA; + if(!bEditFlag) + pMEdit->SetText(_sText); + + if ( _bSelect || !bEditFlag ) + pMEdit->SetSelection( Selection(PrivStart, PrivEnd)); + if ( _bUpdate ) + { + aMEFormula.UpdateOldSel(); + pMEdit->Invalidate(); + m_pHelper->showReference(pMEdit->GetSelected()); + eMode = FORMULA_FORMDLG_EDIT; + + aBtnMatrix.Check( bMatrix ); + } // if ( _bUpdate ) + return eMode; +} +BOOL FormulaDlg_Impl::CheckMatrix(String& aFormula) +{ + pMEdit->GrabFocus(); + xub_StrLen nLen = aFormula.Len(); + BOOL bMatrix = nLen > 3 // Matrix-Formel ? + && aFormula.GetChar(0) == '{' + && aFormula.GetChar(1) == '=' + && aFormula.GetChar(nLen-1) == '}'; + if ( bMatrix ) + { + aFormula.Erase( 0, 1 ); + aFormula.Erase( aFormula.Len()-1, 1); + aBtnMatrix.Check( bMatrix ); + aBtnMatrix.Disable(); + } // if ( bMatrix ) + + aTabCtrl.SetCurPageId(TP_STRUCT); + return bMatrix; +} +IMPL_LINK( FormulaDlg_Impl, StructSelHdl, StructPage*, pStruP ) +{ + bStructUpdate=FALSE; + if(pStructPage->IsVisible()) aBtnForward.Enable(FALSE); //@New + + if(pStructPage==pStruP) + { + /// TODO + //ScToken* pSelToken = pStructPage->GetSelectedToken(); + // ScToken* pOrigToken = ((pSelToken && pSelToken->GetType() == svFAP) ? + // pSelToken->GetFAPOrigToken() : pSelToken); + //xub_StrLen nTokPos=1; + + //if(pScTokA!=NULL) + //{ + // ScToken* pToken = pScTokA->First(); + + // while(pToken!=NULL) + // { + // String aString; + // if ( pToken == pOrigToken ) + // break; + // pComp->CreateStringFromToken( aString,pToken); + // nTokPos = sal::static_int_cast<xub_StrLen>( nTokPos + aString.Len() ); + // pToken=pScTokA->Next(); + // } + // EditThisFunc(nTokPos); + //} + + //if( pOrigToken ) + //{ + // String aStr; + // pComp->CreateStringFromToken( aStr, pOrigToken ); + // String aEntryTxt=pStructPage->GetSelectedEntryText(); + + // if(aEntryTxt!=aStr) + // ShowReference(aEntryTxt); + //} + + } + bStructUpdate=TRUE; + return 0; +} +IMPL_LINK( FormulaDlg_Impl, MatrixHdl, CheckBox *, EMPTYARG ) +{ + bUserMatrixFlag=TRUE; + return 0; +} + +IMPL_LINK( FormulaDlg_Impl, FuncSelHdl, FuncPage*, EMPTYARG ) +{ + USHORT nCat = pFuncPage->GetCategory(); + if ( nCat == LISTBOX_ENTRY_NOTFOUND ) nCat = 0; + USHORT nFunc = pFuncPage->GetFunction(); + if ( nFunc == LISTBOX_ENTRY_NOTFOUND ) nFunc = 0; + + if ( (pFuncPage->GetFunctionEntryCount() > 0) + && (pFuncPage->GetFunction() != LISTBOX_ENTRY_NOTFOUND) ) + { + const IFunctionDescription* pDesc =pFuncPage->GetFuncDesc( pFuncPage->GetFunction() ); + + if(pDesc!=pFuncDesc) aBtnForward.Enable(TRUE); //new + + if (pDesc) + { + pDesc->initArgumentInfo(); // full argument info is needed + + String aSig = pDesc->getSignature(); + aFtHeadLine.SetText( pDesc->getFunctionName() ); + aFtFuncName.SetText( aSig ); + aFtFuncDesc.SetText( pDesc->getFunctionName() ); + } + } + else + { + aFtHeadLine.SetText( String() ); + aFtFuncName.SetText( String() ); + aFtFuncDesc.SetText( String() ); + } + return 0; +} + +void FormulaDlg_Impl::UpdateParaWin(const Selection& _rSelection,const String& _sRefStr) +{ + Selection theSel = _rSelection; + aEdRef.ReplaceSelected( _sRefStr ); + theSel.Max() = theSel.Min() + _sRefStr.Len(); + aEdRef.SetSelection( theSel ); + + //------------------------------------- + // Manuelles Update der Ergebnisfelder: + //------------------------------------- + USHORT nPrivActiv = pParaWin->GetActiveLine(); + pParaWin->SetArgument(nPrivActiv,aEdRef.GetText()); + pParaWin->UpdateParas(); + + Edit* pEd = GetCurrRefEdit(); + if( pEd != NULL ) + pEd->SetSelection( theSel ); + + pParaWin->SetRefMode(FALSE); +} +BOOL FormulaDlg_Impl::UpdateParaWin(Selection& _rSelection) +{ + pParaWin->SetRefMode(TRUE); + + String aStrEd; + Edit* pEd = GetCurrRefEdit(); + if(pEd!=NULL && pTheRefEdit==NULL) + { + _rSelection=pEd->GetSelection(); + _rSelection.Justify(); + aStrEd=pEd->GetText(); + aEdRef.SetRefString(aStrEd); + aEdRef.SetSelection( _rSelection ); + } + else + { + _rSelection=aEdRef.GetSelection(); + _rSelection.Justify(); + aStrEd= aEdRef.GetText(); + } + return pTheRefEdit == NULL; +} +ULONG FormulaDlg_Impl::FindFocusWin(Window *pWin) +{ + ULONG nUniqueId=0; + if(pWin->HasFocus()) + { + nUniqueId=pWin->GetUniqueId(); + if(nUniqueId==0) + { + Window* pParent=pWin->GetParent(); + while(pParent!=NULL) + { + nUniqueId=pParent->GetUniqueId(); + + if(nUniqueId!=0) break; + + pParent=pParent->GetParent(); + } + } + } + else + { + USHORT nCount=pWin->GetChildCount(); + + for(USHORT i=0;i<nCount;i++) + { + Window* pChild=pWin->GetChild(i); + nUniqueId=FindFocusWin(pChild); + if(nUniqueId>0) break; + } + } + return nUniqueId; +} + +void FormulaDlg_Impl::SetEdSelection() +{ + Edit* pEd = GetCurrRefEdit()/*aScParaWin.GetActiveEdit()*/; + if( pEd ) + { + Selection theSel = aEdRef.GetSelection(); + // Edit may have the focus -> call ModifyHdl in addition + // to what's happening in GetFocus + pEd->GetModifyHdl().Call(pEd); + pEd->GrabFocus(); + pEd->SetSelection(theSel); + } // if( pEd ) +} +// ----------------------------------------------------------------------------- +const FormulaHelper& FormulaDlg_Impl::GetFormulaHelper() const +{ + return m_aFormulaHelper; +} +//============================================================================ +FormulaModalDialog::FormulaModalDialog( Window* pParent + , bool _bSupportFunctionResult + , bool _bSupportResult + , bool _bSupportMatrix + , IFormulaEditorHelper* _pHelper + , IFunctionManager* _pFunctionMgr + , IControlReferenceHandler* _pDlg ) : + ModalDialog( pParent, ModuleRes(RID_FORMULADLG_FORMULA_MODAL) ), + m_pImpl( new FormulaDlg_Impl(this,_bSupportFunctionResult + , _bSupportResult + , _bSupportMatrix + ,_pHelper,_pFunctionMgr,_pDlg)) +{ + FreeResource(); + SetText(m_pImpl->aTitle1); +} +FormulaModalDialog::~FormulaModalDialog() +{ +} +// ----------------------------------------------------------------------------- +void FormulaModalDialog::Update(const String& _sExp) +{ + m_pImpl->Update(_sExp); +} + +// ----------------------------------------------------------------------------- +void FormulaModalDialog::SetMeText(const String& _sText) +{ + m_pImpl->SetMeText(_sText); +} + +// ----------------------------------------------------------------------------- +FormulaDlgMode FormulaModalDialog::SetMeText(const String& _sText,xub_StrLen PrivStart, xub_StrLen PrivEnd,BOOL bMatrix,BOOL _bSelect,BOOL _bUpdate) +{ + return m_pImpl->SetMeText(_sText,PrivStart, PrivEnd,bMatrix,_bSelect,_bUpdate); +} +// ----------------------------------------------------------------------------- +void FormulaModalDialog::CheckMatrix() +{ + m_pImpl->aBtnMatrix.Check(); +} +// ----------------------------------------------------------------------------- +BOOL FormulaModalDialog::CheckMatrix(String& aFormula) +{ + return m_pImpl->CheckMatrix(aFormula); +} +// ----------------------------------------------------------------------------- +String FormulaModalDialog::GetMeText() const +{ + return m_pImpl->pMEdit->GetText(); +} +// ----------------------------------------------------------------------------- +void FormulaModalDialog::Update() +{ + m_pImpl->Update(); +} +// ----------------------------------------------------------------------------- +const FormulaHelper& FormulaModalDialog::GetFormulaHelper() const +{ + return m_pImpl->GetFormulaHelper(); +} +// ----------------------------------------------------------------------------- +BOOL FormulaModalDialog::isUserMatrix() const +{ + return m_pImpl->bUserMatrixFlag; +} +void FormulaModalDialog::DoEnter(BOOL _bOk) +{ + m_pImpl->DoEnter(_bOk); +} +::std::pair<RefButton*,RefEdit*> FormulaModalDialog::RefInputStartBefore( RefEdit* pEdit, RefButton* pButton ) +{ + return m_pImpl->RefInputStartBefore( pEdit, pButton ); +} +void FormulaModalDialog::RefInputStartAfter( RefEdit* pEdit, RefButton* pButton ) +{ + m_pImpl->RefInputStartAfter( pEdit, pButton ); +} +void FormulaModalDialog::RefInputDoneAfter( BOOL bForced ) +{ + m_pImpl->RefInputDoneAfter( bForced ); +} + +ULONG FormulaModalDialog::FindFocusWin(Window *pWin) +{ + return m_pImpl->FindFocusWin( pWin ); +} + +void FormulaModalDialog::SetFocusWin(Window *pWin,ULONG nUniqueId) +{ + if(pWin->GetUniqueId()==nUniqueId) + { + pWin->GrabFocus(); + } + else + { + USHORT nCount=pWin->GetChildCount(); + + for(USHORT i=0;i<nCount;i++) + { + Window* pChild=pWin->GetChild(i); + SetFocusWin(pChild,nUniqueId); + } + } +} + + +long FormulaModalDialog::PreNotify( NotifyEvent& rNEvt ) +{ + m_pImpl->PreNotify( rNEvt ); + + return ModalDialog::PreNotify(rNEvt); +} + +void FormulaModalDialog::HighlightFunctionParas(const String& aFormula) +{ + m_pImpl->m_pHelper->showReference(aFormula); +} + +void FormulaModalDialog::disableOk() +{ + m_pImpl->aBtnEnd.Disable(); +} +// ----------------------------------------------------------------------------- +const IFunctionDescription* FormulaModalDialog::getCurrentFunctionDescription() const +{ + OSL_VERIFY(!m_pImpl->pFuncDesc || m_pImpl->pFuncDesc->getSuppressedArgumentCount() == m_pImpl->nArgs); + return m_pImpl->pFuncDesc; +} +// ----------------------------------------------------------------------------- +void FormulaModalDialog::UpdateParaWin(const Selection& _rSelection,const String& _sRefStr) +{ + m_pImpl->UpdateParaWin(_rSelection,_sRefStr); +} +BOOL FormulaModalDialog::UpdateParaWin(Selection& _rSelection) +{ + return m_pImpl->UpdateParaWin(_rSelection); +} +// ----------------------------------------------------------------------------- +RefEdit* FormulaModalDialog::GetActiveEdit() +{ + return m_pImpl->pParaWin->GetActiveEdit(); +} +// ----------------------------------------------------------------------------- +void FormulaModalDialog::SetEdSelection() +{ + m_pImpl->SetEdSelection(); +} + +// -------------------------------------------------------------------------- +// Initialisierung / gemeinsaME Funktionen fuer Dialog +// -------------------------------------------------------------------------- +FormulaDlg::FormulaDlg( SfxBindings* pB, SfxChildWindow* pCW, + Window* pParent + , bool _bSupportFunctionResult + , bool _bSupportResult + , bool _bSupportMatrix + , IFormulaEditorHelper* _pHelper,IFunctionManager* _pFunctionMgr,IControlReferenceHandler* _pDlg ) : + SfxModelessDialog( pB, pCW, pParent, ModuleRes(RID_FORMULADLG_FORMULA) ), + m_pImpl( new FormulaDlg_Impl(this, _bSupportFunctionResult + , _bSupportResult + , _bSupportMatrix + ,_pHelper,_pFunctionMgr,_pDlg)) +{ + FreeResource(); + if(GetHelpId()==0) //Hack, da im SfxModelessDialog die HelpId + SetHelpId(GetUniqueId()); //fuer einen ModelessDialog entfernt und + //in eine UniqueId gewandelt wird, machen + //wir das an dieser Stelle rueckgaengig. + SetText(m_pImpl->aTitle1); +} + +FormulaDlg::~FormulaDlg() +{ +} +// ----------------------------------------------------------------------------- +void FormulaDlg::Update(const String& _sExp) +{ + m_pImpl->Update(_sExp); +} + +// ----------------------------------------------------------------------------- +void FormulaDlg::SetMeText(const String& _sText) +{ + m_pImpl->SetMeText(_sText); +} + +// ----------------------------------------------------------------------------- +FormulaDlgMode FormulaDlg::SetMeText(const String& _sText,xub_StrLen PrivStart, xub_StrLen PrivEnd,BOOL bMatrix,BOOL _bSelect,BOOL _bUpdate) +{ + return m_pImpl->SetMeText(_sText,PrivStart, PrivEnd,bMatrix,_bSelect,_bUpdate); +} +// ----------------------------------------------------------------------------- +void FormulaDlg::CheckMatrix() +{ + m_pImpl->aBtnMatrix.Check(); +} +// ----------------------------------------------------------------------------- +BOOL FormulaDlg::CheckMatrix(String& aFormula) +{ + return m_pImpl->CheckMatrix(aFormula); +} +// ----------------------------------------------------------------------------- +String FormulaDlg::GetMeText() const +{ + return m_pImpl->pMEdit->GetText(); +} +// ----------------------------------------------------------------------------- +void FormulaDlg::Update() +{ + m_pImpl->Update(); + m_pImpl->aTimer.SetTimeout(200); + m_pImpl->aTimer.SetTimeoutHdl(LINK( this, FormulaDlg, UpdateFocusHdl)); + m_pImpl->aTimer.Start(); +} + +// ----------------------------------------------------------------------------- +BOOL FormulaDlg::isUserMatrix() const +{ + return m_pImpl->bUserMatrixFlag; +} +void FormulaDlg::DoEnter(BOOL _bOk) +{ + m_pImpl->DoEnter(_bOk); +} +::std::pair<RefButton*,RefEdit*> FormulaDlg::RefInputStartBefore( RefEdit* pEdit, RefButton* pButton ) +{ + return m_pImpl->RefInputStartBefore( pEdit, pButton ); +} +void FormulaDlg::RefInputStartAfter( RefEdit* pEdit, RefButton* pButton ) +{ + m_pImpl->RefInputStartAfter( pEdit, pButton ); +} +void FormulaDlg::RefInputDoneAfter( BOOL bForced ) +{ + m_pImpl->RefInputDoneAfter( bForced ); +} + +ULONG FormulaDlg::FindFocusWin(Window *pWin) +{ + return m_pImpl->FindFocusWin( pWin ); +} + +void FormulaDlg::SetFocusWin(Window *pWin,ULONG nUniqueId) +{ + if(pWin->GetUniqueId()==nUniqueId) + { + pWin->GrabFocus(); + } + else + { + USHORT nCount=pWin->GetChildCount(); + + for(USHORT i=0;i<nCount;i++) + { + Window* pChild=pWin->GetChild(i); + SetFocusWin(pChild,nUniqueId); + } + } +} + + +long FormulaDlg::PreNotify( NotifyEvent& rNEvt ) +{ + m_pImpl->PreNotify( rNEvt ); + return SfxModelessDialog::PreNotify(rNEvt); +} + +void FormulaDlg::HighlightFunctionParas(const String& aFormula) +{ + m_pImpl->m_pHelper->showReference(aFormula); +} + +void FormulaDlg::disableOk() +{ + m_pImpl->aBtnEnd.Disable(); +} +// ----------------------------------------------------------------------------- +const IFunctionDescription* FormulaDlg::getCurrentFunctionDescription() const +{ + OSL_VERIFY(!m_pImpl->pFuncDesc || m_pImpl->pFuncDesc->getSuppressedArgumentCount() == m_pImpl->nArgs); + return m_pImpl->pFuncDesc; +} +// ----------------------------------------------------------------------------- +void FormulaDlg::UpdateParaWin(const Selection& _rSelection,const String& _sRefStr) +{ + m_pImpl->UpdateParaWin(_rSelection,_sRefStr); +} +BOOL FormulaDlg::UpdateParaWin(Selection& _rSelection) +{ + return m_pImpl->UpdateParaWin(_rSelection); +} +// ----------------------------------------------------------------------------- +RefEdit* FormulaDlg::GetActiveEdit() +{ + return m_pImpl->pParaWin->GetActiveEdit(); +} +// ----------------------------------------------------------------------------- +const FormulaHelper& FormulaDlg::GetFormulaHelper() const +{ + return m_pImpl->GetFormulaHelper(); +} +// ----------------------------------------------------------------------------- +void FormulaDlg::SetEdSelection() +{ + m_pImpl->SetEdSelection(); +} +IMPL_LINK( FormulaDlg, UpdateFocusHdl, Timer*, EMPTYARG ) +{ + FormEditData* pData = m_pImpl->m_pHelper->getFormEditData(); + + if (pData) // wird nicht ueber Close zerstoert; + { + m_pImpl->m_pHelper->setReferenceInput(pData); + ULONG nUniqueId=pData->GetUniqueId(); + SetFocusWin(this,nUniqueId); + } + return 0; +} + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +void FormEditData::SaveValues() +{ + FormEditData* pTemp = new FormEditData(*this); + + Reset(); + pParent = pTemp; +} +// ----------------------------------------------------------------------------- +void FormEditData::Reset() +{ + pParent = NULL; + nMode = 0; + nFStart = 0; + nCatSel = 1; //! oder 0 (zuletzt benutzte) + nFuncSel = 0; + nOffset = 0; + nEdFocus = 0; + bMatrix =FALSE; + nUniqueId=0; + aSelection.Min()=0; + aSelection.Max()=0; + aUndoStr.Erase(); +} +// ----------------------------------------------------------------------------- +void FormEditData::RestoreValues() +{ + FormEditData* pTemp = pParent; + DBG_ASSERT(pTemp,"RestoreValues ohne Parent"); + if (pTemp) + { + *this = *pTemp; + pTemp->pParent = NULL; // sonst wird der auch geloescht! + delete pTemp; + } +} +// ----------------------------------------------------------------------------- +const FormEditData& FormEditData::operator=( const FormEditData& r ) +{ + pParent = r.pParent; + nMode = r.nMode; + nFStart = r.nFStart; + nCatSel = r.nCatSel; + nFuncSel = r.nFuncSel; + nOffset = r.nOffset; + nEdFocus = r.nEdFocus; + aUndoStr = r.aUndoStr; + bMatrix = r.bMatrix ; + nUniqueId = r.nUniqueId; + aSelection = r.aSelection; + return *this; +} +// ----------------------------------------------------------------------------- +FormEditData::FormEditData() +{ + Reset(); +} + +FormEditData::~FormEditData() +{ + delete pParent; +} + +FormEditData::FormEditData( const FormEditData& r ) +{ + *this = r; +} + +// ----------------------------------------------------------------------------- +} // formula +// ----------------------------------------------------------------------------- diff --git a/formula/source/ui/dlg/funcpage.cxx b/formula/source/ui/dlg/funcpage.cxx new file mode 100644 index 000000000000..f056d221ac74 --- /dev/null +++ b/formula/source/ui/dlg/funcpage.cxx @@ -0,0 +1,264 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: funcpage.cxx,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_formula.hxx" + + + +//---------------------------------------------------------------------------- + +#include <sfx2/dispatch.hxx> +#include <sfx2/docfile.hxx> +#include <svtools/zforlist.hxx> +#include <svtools/stritem.hxx> +#include "formula/IFunctionDescription.hxx" + +#include "funcpage.hxx" +#include "formdlgs.hrc" +#include "ForResId.hrc" +#include "ModuleHelper.hxx" +//============================================================================ +namespace formula +{ + +FormulaListBox::FormulaListBox( Window* pParent, WinBits nWinStyle): + ListBox(pParent,nWinStyle) +{} + +FormulaListBox::FormulaListBox( Window* pParent, const ResId& rResId ): + ListBox(pParent,rResId) +{} + +void FormulaListBox::KeyInput( const KeyEvent& rKEvt ) +{ + KeyEvent aKEvt=rKEvt; + //ListBox::KeyInput(rKEvt); + + if(aKEvt.GetCharCode()==' ') + DoubleClick(); +} + +long FormulaListBox::PreNotify( NotifyEvent& rNEvt ) +{ + NotifyEvent aNotifyEvt=rNEvt; + + long nResult=ListBox::PreNotify(rNEvt); + + USHORT nSwitch=aNotifyEvt.GetType(); + if(nSwitch==EVENT_KEYINPUT) + { + KeyInput(*aNotifyEvt.GetKeyEvent()); + } + return nResult; +} + + + +//============================================================================ + +inline USHORT Lb2Cat( USHORT nLbPos ) +{ + // Kategorie 0 == LRU, sonst Categories == LbPos-1 + if ( nLbPos > 0 ) + nLbPos -= 1; + + return nLbPos; +} + +//============================================================================ + +FuncPage::FuncPage(Window* pParent,const IFunctionManager* _pFunctionManager): + TabPage(pParent,ModuleRes(RID_FORMULATAB_FUNCTION)), + // + aFtCategory ( this, ModuleRes( FT_CATEGORY ) ), + aLbCategory ( this, ModuleRes( LB_CATEGORY ) ), + aFtFunction ( this, ModuleRes( FT_FUNCTION ) ), + aLbFunction ( this, ModuleRes( LB_FUNCTION ) ), + m_pFunctionManager(_pFunctionManager) +{ + FreeResource(); + m_aSmartHelpId = aLbFunction.GetSmartHelpId(); + aLbFunction.SetSmartUniqueId(m_aSmartHelpId); + + InitLRUList(); + + const sal_uInt32 nCategoryCount = m_pFunctionManager->getCount(); + for(sal_uInt32 j= 0; j < nCategoryCount; ++j) + { + const IFunctionCategory* pCategory = m_pFunctionManager->getCategory(j); + aLbCategory.SetEntryData(aLbCategory.InsertEntry(pCategory->getName()),(void*)pCategory); + } + + aLbCategory.SelectEntryPos(1); + UpdateFunctionList(); + aLbCategory.SetSelectHdl( LINK( this, FuncPage, SelHdl ) ); + aLbFunction.SetSelectHdl( LINK( this, FuncPage, SelHdl ) ); + aLbFunction.SetDoubleClickHdl( LINK( this, FuncPage, DblClkHdl ) ); +} +// ----------------------------------------------------------------------------- +void FuncPage::impl_addFunctions(const IFunctionCategory* _pCategory) +{ + const sal_uInt32 nCount = _pCategory->getCount(); + for(sal_uInt32 i = 0 ; i < nCount; ++i) + { + TFunctionDesc pDesc(_pCategory->getFunction(i)); + aLbFunction.SetEntryData( + aLbFunction.InsertEntry(pDesc->getFunctionName() ),(void*)pDesc ); + } // for(sal_uInt32 i = 0 ; i < nCount; ++i) +} + +void FuncPage::UpdateFunctionList() +{ + USHORT nSelPos = aLbCategory.GetSelectEntryPos(); + const IFunctionCategory* pCategory = static_cast<const IFunctionCategory*>(aLbCategory.GetEntryData(nSelPos)); + USHORT nCategory = ( LISTBOX_ENTRY_NOTFOUND != nSelPos ) + ? Lb2Cat( nSelPos ) : 0; + + (void)nCategory; + + aLbFunction.Clear(); + aLbFunction.SetUpdateMode( FALSE ); + //------------------------------------------------------ + + if ( nSelPos > 0 ) + { + if ( pCategory == NULL ) + { + const sal_uInt32 nCount = m_pFunctionManager->getCount(); + for(sal_uInt32 i = 0 ; i < nCount; ++i) + { + impl_addFunctions(m_pFunctionManager->getCategory(i)); + } + } + else + { + impl_addFunctions(pCategory); + } + } + else // LRU-Liste + { + ::std::vector< TFunctionDesc >::iterator aIter = aLRUList.begin(); + ::std::vector< TFunctionDesc >::iterator aEnd = aLRUList.end(); + + for ( ; aIter != aEnd; ++aIter ) + { + aLbFunction.SetEntryData( + aLbFunction.InsertEntry( (*aIter)->getFunctionName() ),(void*)*aIter ); + } + } + + //------------------------------------------------------ + aLbFunction.SetUpdateMode( TRUE ); + aLbFunction.SelectEntryPos(0); + + if(IsVisible()) SelHdl(&aLbFunction); +} + +IMPL_LINK( FuncPage, SelHdl, ListBox*, pLb ) +{ + if(pLb==&aLbFunction) + { + const IFunctionDescription* pDesc = GetFuncDesc( GetFunction() ); + if ( pDesc ) + { + const long nHelpId = pDesc->getHelpId(); + if ( nHelpId ) + aLbFunction.SetSmartHelpId(SmartId(nHelpId)); + } + aSelectionLink.Call(this); + } + else + { + aLbFunction.SetSmartHelpId(m_aSmartHelpId); + UpdateFunctionList(); + } + return 0; +} + +IMPL_LINK( FuncPage, DblClkHdl, ListBox*, EMPTYARG ) +{ + aDoubleClickLink.Call(this); + return 0; +} + +void FuncPage::SetCategory(USHORT nCat) +{ + aLbCategory.SelectEntryPos(nCat); + UpdateFunctionList(); +} +USHORT FuncPage::GetFuncPos(const IFunctionDescription* _pDesc) +{ + return aLbFunction.GetEntryPos(_pDesc); +} +void FuncPage::SetFunction(USHORT nFunc) +{ + aLbFunction.SelectEntryPos(nFunc); +} + +void FuncPage::SetFocus() +{ + aLbFunction.GrabFocus(); +} + +USHORT FuncPage::GetCategory() +{ + return aLbCategory.GetSelectEntryPos(); +} + +USHORT FuncPage::GetFunction() +{ + return aLbFunction.GetSelectEntryPos(); +} + +USHORT FuncPage::GetFunctionEntryCount() +{ + return aLbFunction.GetSelectEntryCount(); +} + +String FuncPage::GetSelFunctionName() const +{ + return aLbFunction.GetSelectEntry(); +} +const IFunctionDescription* FuncPage::GetFuncDesc( USHORT nPos ) const +{ + // nicht schoen, aber hoffentlich selten + return (const IFunctionDescription*) aLbFunction.GetEntryData(nPos); +} + +void FuncPage::InitLRUList() +{ + ::std::vector< const IFunctionDescription*> aRUFunctions; + m_pFunctionManager->fillLastRecentlyUsedFunctions(aLRUList); +} + + +} // formula + diff --git a/formula/source/ui/dlg/funcpage.hxx b/formula/source/ui/dlg/funcpage.hxx new file mode 100644 index 000000000000..dffe65ae8d4b --- /dev/null +++ b/formula/source/ui/dlg/funcpage.hxx @@ -0,0 +1,126 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: funcpage.hxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FORMULA_FUNCPAGE_HXX +#define FORMULA_FUNCPAGE_HXX + +#include <svtools/stdctrl.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/group.hxx> +#include <svtools/svmedit.hxx> +#include <vcl/tabpage.hxx> + +#include <vcl/tabctrl.hxx> +#include <vcl/button.hxx> +#include <svtools/svtreebx.hxx> + +#include <boost/shared_ptr.hpp> +#include <vector> +#include "ModuleHelper.hxx" +//============================================================================ +namespace formula +{ + +class IFunctionDescription; +class IFunctionManager; +class IFunctionCategory; + +//============================================================================ +class FormulaListBox : public ListBox +{ +protected: + + virtual void KeyInput( const KeyEvent& rKEvt ); + virtual long PreNotify( NotifyEvent& rNEvt ); + +public: + FormulaListBox( Window* pParent, WinBits nWinStyle = WB_BORDER ); + + FormulaListBox( Window* pParent, const ResId& rResId ); + +}; + + + +typedef const IFunctionDescription* TFunctionDesc; +//============================================================================ +class FuncPage : public TabPage +{ +private: + OModuleClient m_aModuleClient; + Link aDoubleClickLink; + Link aSelectionLink; + FixedText aFtCategory; + ListBox aLbCategory; + FixedText aFtFunction; + ListBox aLbFunction; + const IFunctionManager* + m_pFunctionManager; + + ::std::vector< TFunctionDesc > aLRUList; + SmartId m_aSmartHelpId; + + + void impl_addFunctions(const IFunctionCategory* _pCategory); + DECL_LINK( SelHdl, ListBox* ); + DECL_LINK( DblClkHdl, ListBox* ); + +protected: + + void UpdateFunctionList(); + void InitLRUList(); + + +public: + + FuncPage( Window* pParent,const IFunctionManager* _pFunctionManager); + + void SetCategory(USHORT nCat); + void SetFunction(USHORT nFunc); + void SetFocus(); + USHORT GetCategory(); + USHORT GetFunction(); + USHORT GetFunctionEntryCount(); + + USHORT GetFuncPos(const IFunctionDescription* _pDesc); + const IFunctionDescription* GetFuncDesc( USHORT nPos ) const; + String GetSelFunctionName() const; + + void SetDoubleClickHdl( const Link& rLink ) { aDoubleClickLink = rLink; } + const Link& GetDoubleClickHdl() const { return aDoubleClickLink; } + + void SetSelectHdl( const Link& rLink ) { aSelectionLink = rLink; } + const Link& GetSelectHdl() const { return aSelectionLink; } + +}; + +} // formula +#endif + diff --git a/formula/source/ui/dlg/funcutl.cxx b/formula/source/ui/dlg/funcutl.cxx new file mode 100644 index 000000000000..23f0f2dc66ae --- /dev/null +++ b/formula/source/ui/dlg/funcutl.cxx @@ -0,0 +1,1109 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: funcutl.cxx,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_formula.hxx" + +//---------------------------------------------------------------------------- +#include <vcl/sound.hxx> +#include <vcl/svapp.hxx> +#include <vcl/scrbar.hxx> + +#include "formula/funcutl.hxx" +#include "formula/IControlReferenceHandler.hxx" +#include "ControlHelper.hxx" +#include "ModuleHelper.hxx" +#include "ForResId.hrc" + + +namespace formula +{ +//============================================================================ +// class ValWnd +//---------------------------------------------------------------------------- + +ValWnd::ValWnd( Window* pParent, const ResId& rId ) : Window( pParent, rId ) +{ + Font aFnt( GetFont() ); + aFnt.SetTransparent( TRUE ); + aFnt.SetWeight( WEIGHT_LIGHT ); + if ( pParent->IsBackground() ) + { + Wallpaper aBack = pParent->GetBackground(); + SetFillColor( aBack.GetColor() ); + SetBackground( aBack ); + aFnt.SetFillColor( aBack.GetColor() ); + } + else + { + SetFillColor(); + SetBackground(); + } + SetFont( aFnt ); + SetLineColor(); + + Size aSzWnd = GetOutputSizePixel(); + long nHeight = GetTextHeight(); + long nDiff = aSzWnd.Height()-nHeight; + + aRectOut = Rectangle( Point( 1, ( nDiff<2 ) ? 1 : nDiff/2), + Size ( aSzWnd.Width()-2, nHeight ) ); + SetClipRegion( Region( aRectOut ) ); +} + +//---------------------------------------------------------------------------- + +void __EXPORT ValWnd::Paint( const Rectangle& ) +{ + DrawText( aRectOut.TopLeft(), aStrValue ); +} + +//---------------------------------------------------------------------------- + +void ValWnd::SetValue( const String& rStrVal ) +{ + if ( aStrValue != rStrVal ) + { + aStrValue = rStrVal; + DrawRect( aRectOut ); // alten Text loeschen + Paint( aRectOut ); // und neu malen + } +} + +//============================================================================ +// class ArgEdit +//---------------------------------------------------------------------------- + +ArgEdit::ArgEdit( Window* pParent, const ResId& rResId ) + : RefEdit( pParent, rResId ), + pEdPrev ( NULL ), + pEdNext ( NULL ), + pSlider ( NULL ), + nArgs ( 0 ) +{ +} + +//---------------------------------------------------------------------------- + +void ArgEdit::Init( ArgEdit* pPrevEdit, ArgEdit* pNextEdit, + ScrollBar& rArgSlider, USHORT nArgCount ) +{ + pEdPrev = pPrevEdit; + pEdNext = pNextEdit; + pSlider = &rArgSlider; + nArgs = nArgCount; +} + +//---------------------------------------------------------------------------- + +// Cursorsteuerung fuer EditFelder im Argument-Dialog + +void __EXPORT ArgEdit::KeyInput( const KeyEvent& rKEvt ) +{ + KeyCode aCode = rKEvt.GetKeyCode(); + BOOL bUp = (aCode.GetCode() == KEY_UP); + BOOL bDown = (aCode.GetCode() == KEY_DOWN); + ArgEdit* pEd = NULL; + + if ( pSlider + && ( !aCode.IsShift() && !aCode.IsMod1() && !aCode.IsMod2() ) + && ( bUp || bDown ) ) + { + if ( nArgs > 1 ) + { + long nThumb = pSlider->GetThumbPos(); + BOOL bDoScroll = FALSE; + BOOL bChangeFocus = FALSE; + + if ( bDown ) + { + if ( nArgs > 4 ) + { + if ( !pEdNext ) + { + nThumb++; + bDoScroll = ( nThumb+3 < (long)nArgs ); + } + else + { + pEd = pEdNext; + bChangeFocus = TRUE; + } + } + else if ( pEdNext ) + { + pEd = pEdNext; + bChangeFocus = TRUE; + } + } + else // if ( bUp ) + { + if ( nArgs > 4 ) + { + if ( !pEdPrev ) + { + nThumb--; + bDoScroll = ( nThumb >= 0 ); + } + else + { + pEd = pEdPrev; + bChangeFocus = TRUE; + } + } + else if ( pEdPrev ) + { + pEd = pEdPrev; + bChangeFocus = TRUE; + } + } + + if ( bDoScroll ) + { + pSlider->SetThumbPos( nThumb ); + ((Link&)pSlider->GetEndScrollHdl()).Call( pSlider ); + } + else if ( bChangeFocus ) + { + pEd->GrabFocus(); + } + else + Sound::Beep(); + } + else + Sound::Beep(); + } + else + RefEdit::KeyInput( rKEvt ); +} + + + + +/************************************************************************* +#* Member: ArgInput Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Konstruktor der Klasse ArgInput +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ + +ArgInput::ArgInput() +{ + pFtArg=NULL; + pBtnFx=NULL; + pEdArg=NULL; + pRefBtn=NULL; +} + +/************************************************************************* +#* Member: InitArgInput Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Initialisiert die Pointer der Klasse +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ + +void ArgInput::InitArgInput(FixedText* pftArg, + ImageButton* pbtnFx, + ArgEdit* pedArg, + RefButton* prefBtn) +{ + pFtArg =pftArg; + pBtnFx =pbtnFx; + pEdArg =pedArg; + pRefBtn=prefBtn; + + if(pBtnFx!=NULL) + { + pBtnFx->SetClickHdl ( LINK( this, ArgInput, FxBtnClickHdl ) ); + pBtnFx->SetGetFocusHdl( LINK( this, ArgInput, FxBtnFocusHdl ) ); + } + if(pRefBtn!=NULL) + { + pRefBtn->SetClickHdl ( LINK( this, ArgInput, RefBtnClickHdl ) ); + pRefBtn->SetGetFocusHdl( LINK( this, ArgInput, RefBtnFocusHdl ) ); + } + if(pEdArg!=NULL) + { + pEdArg->SetGetFocusHdl ( LINK( this, ArgInput, EdFocusHdl ) ); + pEdArg->SetModifyHdl ( LINK( this, ArgInput, EdModifyHdl ) ); + } + +} + +/************************************************************************* +#* Member: SetArgName Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Setzt den Namen fuer das Argument +#* +#* Input: String +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::SetArgName(const String &aArg) +{ + if(pFtArg !=NULL) pFtArg->SetText(aArg ); +} + +/************************************************************************* +#* Member: GetArgName Datum:06.02.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Liefert den Namen fuer das Argument zurueck +#* +#* Input: String +#* +#* Output: --- +#* +#************************************************************************/ +String ArgInput::GetArgName() +{ + String aPrivArgName; + if(pFtArg !=NULL) + aPrivArgName=pFtArg->GetText(); + + return aPrivArgName; +} + + +/************************************************************************* +#* Member: SetArgName Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Setzt den Namen fuer das Argument +#* +#* Input: String +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::SetArgNameFont (const Font &aFont) +{ + if(pFtArg !=NULL) pFtArg->SetFont(aFont); +} + +/************************************************************************* +#* Member: SetArgSelection Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Stellt die Selection fuer die EditBox ein. +#* +#* Input: String +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::SetArgSelection (const Selection& rSel ) +{ + if(pEdArg !=NULL) pEdArg ->SetSelection(rSel ); +} + +/************************************************************************* +#* Member: SetArgSelection Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Liefert die Selection fuer die EditBox zurueck. +#* +#* Input: String +#* +#* Output: --- +#* +#************************************************************************/ +Selection ArgInput::GetArgSelection () +{ + Selection aSel; + if(pEdArg !=NULL) aSel=pEdArg ->GetSelection(); + return aSel; +} + +/************************************************************************* +#* Member: SetArgSelection Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Ersetzt die Selection in der EditBox. +#* +#* Input: String +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::ReplaceSelOfArg(const String& rStr ) +{ + if(pEdArg !=NULL) pEdArg ->ReplaceSelected(rStr ); +} + + + +/************************************************************************* +#* Member: SetArgVal Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Setzt den Wert fuer das Argument +#* +#* Input: String +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::SetArgVal(const String &aVal) +{ + if(pEdArg !=NULL) + { + pEdArg ->SetRefString(aVal ); + } +} + +/************************************************************************* +#* Member: SetArgName Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Liefert den Wert fuer das Argument +#* +#* Input: --- +#* +#* Output: String +#* +#************************************************************************/ +String ArgInput::GetArgVal() +{ + String aResult; + if(pEdArg!=NULL) + { + aResult=pEdArg->GetText(); + } + return aResult; +} + +/************************************************************************* +#* Member: SetArgName Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Versteckt die Controls +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::Hide() +{ + if ( pFtArg && pBtnFx && pEdArg && pRefBtn) + { + pFtArg->Hide(); + pBtnFx->Hide(); + pEdArg->Hide(); + pRefBtn->Hide(); + } +} + +/************************************************************************* +#* Member: SetArgName Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Zaubert die Controls wieder hervor. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::Show() +{ + if ( pFtArg && pBtnFx && pEdArg && pRefBtn) + { + pFtArg->Show(); + pBtnFx->Show(); + pEdArg->Show(); + pRefBtn->Show(); + } +} + +/************************************************************************* +#* Member: FxClick Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Gibt den Event weiter. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::FxClick() +{ + aFxClickLink.Call(this); +} + +/************************************************************************* +#* Member: RefClick Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Gibt den Event weiter. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::RefClick() +{ + aRefClickLink.Call(this); +} + +/************************************************************************* +#* Member: FxFocus Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Gibt den Event weiter. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::FxFocus() +{ + aFxFocusLink.Call(this); +} + +/************************************************************************* +#* Member: RefFocus Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Gibt den Event weiter. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::RefFocus() +{ + aRefFocusLink.Call(this); +} + +/************************************************************************* +#* Member: EdFocus Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Gibt den Event weiter. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::EdFocus() +{ + aEdFocusLink.Call(this); +} + +/************************************************************************* +#* Member: EdModify Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Gibt den Event weiter. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +void ArgInput::EdModify() +{ + aEdModifyLink.Call(this); +} + +/************************************************************************* +#* Handle: FxBtnHdl Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Handle fuer Fx-Button Click-Event. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +IMPL_LINK( ArgInput, FxBtnClickHdl, ImageButton*, pBtn ) +{ + if(pBtn==pBtnFx) FxClick(); + + return 0; +} + +/************************************************************************* +#* Handle: RefBtnClickHdl Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Handle fuer Fx-Button Click-Event. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +IMPL_LINK( ArgInput, RefBtnClickHdl,RefButton*, pBtn ) +{ + if(pRefBtn==pBtn) RefClick(); + + return 0; +} + +/************************************************************************* +#* Handle: FxBtnFocusHdl Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Handle fuer Fx-Button Focus-Event. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +IMPL_LINK( ArgInput, FxBtnFocusHdl, ImageButton*, pBtn ) +{ + if(pBtn==pBtnFx) FxFocus(); + + return 0; +} + +/************************************************************************* +#* Handle: RefBtnFocusHdl Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Handle fuer Fx-Button Focus-Event. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +IMPL_LINK( ArgInput, RefBtnFocusHdl,RefButton*, pBtn ) +{ + if(pRefBtn==pBtn) RefFocus(); + + return 0; +} + +/************************************************************************* +#* Handle: EdFocusHdl Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Handle fuer Fx-Button Focus-Event. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +IMPL_LINK( ArgInput, EdFocusHdl, ArgEdit*, pEd ) +{ + if(pEd==pEdArg) EdFocus(); + + return 0; +} + +/************************************************************************* +#* Handle: RefBtnClickHdl Datum:13.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: ArgInput +#* +#* Funktion: Handle fuer Fx-Button Focus-Event. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +IMPL_LINK( ArgInput, EdModifyHdl,ArgEdit*, pEd ) +{ + if(pEd==pEdArg) EdModify(); + + return 0; +} + +/************************************************************************* +#* Member: EditBox Datum:20.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: EditBox +#* +#* Funktion: Konstruktor der Klasse ArgInput +#* +#* Input: Parent, Window-Style +#* +#* Output: --- +#* +#************************************************************************/ +EditBox::EditBox( Window* pParent,WinBits nWinStyle) + :Control(pParent,nWinStyle|WB_DIALOGCONTROL) +{ + pMEdit=new MultiLineEdit(this,WB_LEFT | WB_VSCROLL | nWinStyle & WB_TABSTOP| + WB_NOBORDER | WB_NOHIDESELECTION |WB_IGNORETAB); + + pMEdit->Show(); + aOldSel=pMEdit->GetSelection(); +} + +/************************************************************************* +#* Member: EditBox Datum:20.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: EditBox +#* +#* Funktion: Konstruktor der Klasse ArgInput +#* +#* Input: Parent, Resource +#* +#* Output: --- +#* +#************************************************************************/ +EditBox::EditBox( Window* pParent, const ResId& rResId ) + :Control(pParent,rResId), + bMouseFlag(FALSE) +{ + WinBits nStyle=GetStyle(); + SetStyle( nStyle| WB_DIALOGCONTROL); + + pMEdit=new MultiLineEdit(this,WB_LEFT | WB_VSCROLL | nStyle & WB_TABSTOP| + WB_NOBORDER | WB_NOHIDESELECTION | WB_IGNORETAB); + pMEdit->Show(); + aOldSel=pMEdit->GetSelection(); + Resize(); + WinBits nWinStyle=GetStyle() | WB_DIALOGCONTROL; + SetStyle(nWinStyle); + + // #105582# the HelpId from the resource must be set for the MultiLineEdit, + // not for the control that contains it. + pMEdit->SetSmartHelpId( GetSmartHelpId() ); + SetSmartHelpId( SmartId() ); +} + +EditBox::~EditBox() +{ + MultiLineEdit* pTheEdit=pMEdit; + pMEdit->Disable(); + pMEdit=NULL; + delete pTheEdit; +} +/************************************************************************* +#* Member: EditBox Datum:20.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: EditBox +#* +#* Funktion: Wenn sich die Selektion geaendert hat, so wird +#* diese Funktion aufgerufen. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +void EditBox::SelectionChanged() +{ + aSelChangedLink.Call(this); +} + +/************************************************************************* +#* Member: EditBox Datum:20.05.98 +#*------------------------------------------------------------------------ +#* +#* Klasse: EditBox +#* +#* Funktion: Wenn sich die Groesse geaendert hat, so muss +#* auch der MultiLineEdit angepasst werden.. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +void EditBox::Resize() +{ + Size aSize=GetOutputSizePixel(); + if(pMEdit!=NULL) pMEdit->SetOutputSizePixel(aSize); +} + +/************************************************************************* +#* Member: GetFocus Datum:26.05.98 +#*------------------------------------------------------------------------ +#* +#* Klasse: EditBox +#* +#* Funktion: Wenn der Control aktiviert wird, so wird +#* die Selection aufgehoben und der Cursor ans +#* Ende gesetzt. +#* +#* Input: --- +#* +#* Output: --- +#* +#************************************************************************/ +void EditBox::GetFocus() +{ + if(pMEdit!=NULL) + { + pMEdit->GrabFocus(); + } +} + + + +/************************************************************************* +#* Member: EditBox Datum:20.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: EditBox +#* +#* Funktion: Wenn ein Event ausgeloest wird, so wird diese Routine +#* zuerst aufgerufen und ein PostUserEvent verschickt. +#* +#* Input: Notify-Event +#* +#* Output: --- +#* +#************************************************************************/ +long EditBox::PreNotify( NotifyEvent& rNEvt ) +{ + long nResult=TRUE; + + if(pMEdit==NULL) return nResult; + + USHORT nSwitch=rNEvt.GetType(); + if(nSwitch==EVENT_KEYINPUT)// || nSwitch==EVENT_KEYUP) + { + const KeyCode& aKeyCode=rNEvt.GetKeyEvent()->GetKeyCode(); + USHORT nKey=aKeyCode.GetCode(); + if(nKey==KEY_RETURN && !aKeyCode.IsShift() || nKey==KEY_TAB) + { + nResult=GetParent()->Notify(rNEvt); + } + else + { + nResult=Control::PreNotify(rNEvt); + Application::PostUserEvent( LINK( this, EditBox, ChangedHdl ) ); + } + + } + else + { + nResult=Control::PreNotify(rNEvt); + + if(nSwitch==EVENT_MOUSEBUTTONDOWN || nSwitch==EVENT_MOUSEBUTTONUP) + { + bMouseFlag=TRUE; + Application::PostUserEvent( LINK( this, EditBox, ChangedHdl ) ); + } + } + return nResult; +} + +/************************************************************************* +#* Member: EditBox Datum:21.01.97 +#*------------------------------------------------------------------------ +#* +#* Klasse: EditBox +#* +#* Funktion: Wenn ein Event ausgeloest wurde, so wird diese Routine +#* zuerst aufgerufen. +#* +#* Input: Key-Event +#* +#* Output: --- +#* +#************************************************************************/ +IMPL_LINK( EditBox, ChangedHdl, EditBox*, EMPTYARG ) +{ + if(pMEdit!=NULL) + { + Selection aNewSel=pMEdit->GetSelection(); + + if(aNewSel.Min()!=aOldSel.Min() || aNewSel.Max()!=aOldSel.Max()) + { + SelectionChanged(); + aOldSel=aNewSel; + } + } + return 0; +} + +void EditBox::UpdateOldSel() +{ + // if selection is set for editing a function, store it as aOldSel, + // so SelectionChanged isn't called in the next ChangedHdl call + + if (pMEdit) + aOldSel = pMEdit->GetSelection(); +} +//---------------------------------------------------------------------------- + +//============================================================================ +// class RefEdit +//---------------------------------------------------------------------------- + +#define SC_ENABLE_TIME 100 + +RefEdit::RefEdit( Window* _pParent,IControlReferenceHandler* pParent, const ResId& rResId ) : + Edit( _pParent, rResId ), + pAnyRefDlg( pParent ), + bSilentFocus( FALSE ) +{ + aTimer.SetTimeoutHdl( LINK( this, RefEdit, UpdateHdl ) ); + aTimer.SetTimeout( SC_ENABLE_TIME ); +} + +RefEdit::RefEdit( Window* pParent, const ResId& rResId ) : + Edit( pParent, rResId ), + pAnyRefDlg( NULL ), + bSilentFocus( FALSE ) +{ +} + +RefEdit::~RefEdit() +{ + aTimer.SetTimeoutHdl( Link() ); + aTimer.Stop(); +} + +void RefEdit::SetRefString( const XubString& rStr ) +{ + Edit::SetText( rStr ); +} + +void RefEdit::SetText( const XubString& rStr ) +{ + Edit::SetText( rStr ); + UpdateHdl( &aTimer ); +} + +void RefEdit::StartUpdateData() +{ + aTimer.Start(); +} + +void RefEdit::SilentGrabFocus() +{ + bSilentFocus = TRUE; + GrabFocus(); + bSilentFocus = FALSE; +} + +void RefEdit::SetRefDialog( IControlReferenceHandler* pDlg ) +{ + pAnyRefDlg = pDlg; + + if( pDlg ) + { + aTimer.SetTimeoutHdl( LINK( this, RefEdit, UpdateHdl ) ); + aTimer.SetTimeout( SC_ENABLE_TIME ); + } + else + { + aTimer.SetTimeoutHdl( Link() ); + aTimer.Stop(); + } +} + +void RefEdit::Modify() +{ + Edit::Modify(); + if( pAnyRefDlg ) + pAnyRefDlg->HideReference(); +} + +void RefEdit::KeyInput( const KeyEvent& rKEvt ) +{ + const KeyCode& rKeyCode = rKEvt.GetKeyCode(); + if( pAnyRefDlg && !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) ) + pAnyRefDlg->ReleaseFocus( this ); + else + Edit::KeyInput( rKEvt ); +} + +void RefEdit::GetFocus() +{ + Edit::GetFocus(); + if( !bSilentFocus ) + StartUpdateData(); +} + +void RefEdit::LoseFocus() +{ + Edit::LoseFocus(); + if( pAnyRefDlg ) + pAnyRefDlg->HideReference(); +} + +IMPL_LINK( RefEdit, UpdateHdl, Timer*, EMPTYARG ) +{ + if( pAnyRefDlg ) + pAnyRefDlg->ShowReference( GetText() ); + return 0; +} + + +//============================================================================ +// class RefButton +//---------------------------------------------------------------------------- +RefButton::RefButton( Window* _pParent, const ResId& rResId) : + ImageButton( _pParent, rResId ), + aImgRefStart( ModuleRes( RID_BMP_REFBTN1 ) ), + aImgRefStartHC( ModuleRes( RID_BMP_REFBTN1_H ) ), + aImgRefDone( ModuleRes( RID_BMP_REFBTN2 ) ), + aImgRefDoneHC( ModuleRes( RID_BMP_REFBTN2_H ) ), + pAnyRefDlg( NULL ), + pRefEdit( NULL ) +{ + SetStartImage(); +} + +RefButton::RefButton( Window* _pParent, const ResId& rResId, RefEdit* pEdit, IControlReferenceHandler* _pDlg ) : + ImageButton( _pParent, rResId ), + aImgRefStart( ModuleRes( RID_BMP_REFBTN1 ) ), + aImgRefStartHC( ModuleRes( RID_BMP_REFBTN1_H ) ), + aImgRefDone( ModuleRes( RID_BMP_REFBTN2 ) ), + aImgRefDoneHC( ModuleRes( RID_BMP_REFBTN2_H ) ), + pAnyRefDlg( _pDlg ), + pRefEdit( pEdit ) +{ + SetStartImage(); +} + +void RefButton::SetStartImage() +{ + SetModeImage( aImgRefStart ); + SetModeImage( aImgRefStartHC, BMP_COLOR_HIGHCONTRAST ); +} + +void RefButton::SetEndImage() +{ + SetModeImage( aImgRefDone ); + SetModeImage( aImgRefDoneHC, BMP_COLOR_HIGHCONTRAST ); +} + +void RefButton::SetReferences( IControlReferenceHandler* pDlg, RefEdit* pEdit ) +{ + pAnyRefDlg = pDlg; + pRefEdit = pEdit; +} + +//---------------------------------------------------------------------------- + +void RefButton::Click() +{ + if( pAnyRefDlg ) + pAnyRefDlg->ToggleCollapsed( pRefEdit, this ); +} + +void RefButton::KeyInput( const KeyEvent& rKEvt ) +{ + const KeyCode& rKeyCode = rKEvt.GetKeyCode(); + if( pAnyRefDlg && !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) ) + pAnyRefDlg->ReleaseFocus( pRefEdit ); + else + ImageButton::KeyInput( rKEvt ); +} + +void RefButton::GetFocus() +{ + ImageButton::GetFocus(); + if( pRefEdit ) + pRefEdit->StartUpdateData(); +} + +void RefButton::LoseFocus() +{ + ImageButton::LoseFocus(); + if( pRefEdit ) + pRefEdit->Modify(); +} + + +} // formula diff --git a/formula/source/ui/dlg/makefile.mk b/formula/source/ui/dlg/makefile.mk new file mode 100644 index 000000000000..04d19bb79aa1 --- /dev/null +++ b/formula/source/ui/dlg/makefile.mk @@ -0,0 +1,70 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=formula +TARGET=uidlg +IMGLST_SRS=$(SRS)$/$(TARGET).srs +BMP_IN=$(PRJ)$/res + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files ------------------------------------- + +# ... resource files ............................ + +SRS1NAME=$(TARGET) +SRC1FILES = \ + formdlgs.src \ + parawin.src + +# ... object files ............................ + +EXCEPTIONSFILES= \ + $(SLO)$/formula.obj \ + $(SLO)$/FormulaHelper.obj \ + $(SLO)$/parawin.obj \ + $(SLO)$/funcutl.obj \ + $(SLO)$/funcpage.obj \ + $(SLO)$/structpg.obj + +SLOFILES= \ + $(EXCEPTIONSFILES) + + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/formula/source/ui/dlg/parawin.cxx b/formula/source/ui/dlg/parawin.cxx new file mode 100644 index 000000000000..d4e76cf09762 --- /dev/null +++ b/formula/source/ui/dlg/parawin.cxx @@ -0,0 +1,603 @@ +/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: parawin.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_formula.hxx"
+
+
+
+//----------------------------------------------------------------------------
+
+#include <svtools/zforlist.hxx>
+#include <svtools/stritem.hxx>
+
+#include "parawin.hxx"
+#include "parawin.hrc"
+#include "helpids.hrc"
+#include "formula/formdata.hxx"
+#include "formula/IFunctionDescription.hxx"
+#include "ModuleHelper.hxx"
+#include "ForResId.hrc"
+
+#define VAR_ARGS 30
+namespace formula
+{
+//============================================================================
+
+ParaWin::ParaWin(Window* pParent,IControlReferenceHandler* _pDlg,Point aPos):
+ TabPage (pParent,ModuleRes(RID_FORMULATAB_PARAMETER)),
+ pFuncDesc ( NULL ),
+ pMyParent (_pDlg),
+ aFtEditDesc ( this, ModuleRes( FT_EDITDESC ) ),
+ aFtArgName ( this, ModuleRes( FT_PARNAME ) ),
+ aFtArgDesc ( this, ModuleRes( FT_PARDESC ) ),
+
+ aFtArg1 ( this, ModuleRes( FT_ARG1 ) ),
+ aFtArg2 ( this, ModuleRes( FT_ARG2 ) ),
+ aFtArg3 ( this, ModuleRes( FT_ARG3 ) ),
+ aFtArg4 ( this, ModuleRes( FT_ARG4 ) ),
+
+ aBtnFx1 ( this, ModuleRes( BTN_FX1 ) ),
+ aBtnFx2 ( this, ModuleRes( BTN_FX2 ) ),
+ aBtnFx3 ( this, ModuleRes( BTN_FX3 ) ),
+ aBtnFx4 ( this, ModuleRes( BTN_FX4 ) ),
+
+ aEdArg1 ( this, ModuleRes( ED_ARG1 ) ),
+ aEdArg2 ( this, ModuleRes( ED_ARG2 ) ),
+ aEdArg3 ( this, ModuleRes( ED_ARG3 ) ),
+ aEdArg4 ( this, ModuleRes( ED_ARG4 ) ),
+
+ aRefBtn1 ( this, ModuleRes( RB_ARG1 ) ),
+ aRefBtn2 ( this, ModuleRes( RB_ARG2 ) ),
+ aRefBtn3 ( this, ModuleRes( RB_ARG3 ) ),
+ aRefBtn4 ( this, ModuleRes( RB_ARG4 ) ),
+
+ aSlider ( this, ModuleRes( WND_SLIDER ) ),
+ m_sOptional ( ModuleRes( STR_OPTIONAL ) ),
+ m_sRequired ( ModuleRes( STR_REQUIRED ) ),
+ bRefMode (FALSE)
+{
+ Image aFxHC( ModuleRes( IMG_FX_H ) );
+ FreeResource();
+ aDefaultString=aFtEditDesc.GetText();
+
+ SetPosPixel(aPos);
+ nEdFocus=NOT_FOUND;
+ nActiveLine=0;
+ Size aSize = aSlider.GetSizePixel();
+ aSize.Width() = GetSettings().GetStyleSettings().GetScrollBarSize();
+ aSlider.SetSizePixel( aSize );
+ aSlider.SetEndScrollHdl( LINK( this, ParaWin, ScrollHdl ) );
+ aSlider.SetScrollHdl( LINK( this, ParaWin, ScrollHdl ) );
+
+ aBtnFx1.SetModeImage( aFxHC, BMP_COLOR_HIGHCONTRAST );
+ aBtnFx2.SetModeImage( aFxHC, BMP_COLOR_HIGHCONTRAST );
+ aBtnFx3.SetModeImage( aFxHC, BMP_COLOR_HIGHCONTRAST );
+ aBtnFx4.SetModeImage( aFxHC, BMP_COLOR_HIGHCONTRAST );
+
+ InitArgInput( 0, aFtArg1, aBtnFx1, aEdArg1, aRefBtn1);
+ InitArgInput( 1, aFtArg2, aBtnFx2, aEdArg2, aRefBtn2);
+ InitArgInput( 2, aFtArg3, aBtnFx3, aEdArg3, aRefBtn3);
+ InitArgInput( 3, aFtArg4, aBtnFx4, aEdArg4, aRefBtn4);
+ ClearAll();
+}
+
+void ParaWin::UpdateArgDesc( USHORT nArg )
+{
+ if (nArg==NOT_FOUND) return;
+
+ if ( nArgs > 4 )
+ nArg = sal::static_int_cast<USHORT>( nArg + GetSliderPos() );
+ //@ nArg += (USHORT)aSlider.GetThumbPos();
+
+ if ( (nArgs > 0) && (nArg<nArgs) )
+ {
+ String aArgDesc;
+ String aArgName;
+
+ SetArgumentDesc( String() );
+ SetArgumentText( String() );
+
+ if ( nArgs < VAR_ARGS )
+ {
+ USHORT nRealArg = (aVisibleArgMapping.size() < nArg) ? aVisibleArgMapping[nArg] : nArg;
+ aArgDesc = pFuncDesc->getParameterDescription(nRealArg);
+ aArgName = pFuncDesc->getParameterName(nRealArg);
+ aArgName += ' ';
+ aArgName += (pFuncDesc->isParameterOptional(nRealArg)) ? m_sOptional : m_sRequired ;
+ }
+ else
+ {
+ USHORT nFix = nArgs - VAR_ARGS;
+ USHORT nPos = ( nArg < nFix ? nArg : nFix );
+ USHORT nRealArg = (nPos < aVisibleArgMapping.size() ?
+ aVisibleArgMapping[nPos] : aVisibleArgMapping.back());
+ aArgDesc = pFuncDesc->getParameterDescription(nRealArg);
+ aArgName = pFuncDesc->getParameterName(nRealArg);
+ if ( nArg >= nFix )
+ aArgName += String::CreateFromInt32(nArg-nFix+1);
+ aArgName += ' ';
+
+ aArgName += (nArg > nFix || pFuncDesc->isParameterOptional(nRealArg)) ? m_sOptional : m_sRequired ;
+ }
+
+ SetArgumentDesc(aArgDesc);
+ SetArgumentText(aArgName);
+ }
+}
+
+void ParaWin::UpdateArgInput( USHORT nOffset, USHORT i )
+{
+ USHORT nArg = nOffset + i;
+ if ( nArgs < VAR_ARGS)
+ {
+ if(nArg<nArgs)
+ {
+ USHORT nRealArg = aVisibleArgMapping[nArg];
+ SetArgNameFont (i,(pFuncDesc->isParameterOptional(nRealArg))
+ ? aFntLight : aFntBold );
+ SetArgName (i,pFuncDesc->getParameterName(nRealArg));
+ }
+ }
+ else
+ {
+ USHORT nFix = nArgs - VAR_ARGS;
+ USHORT nPos = ( nArg < nFix ? nArg : nFix );
+ USHORT nRealArg = (nPos < aVisibleArgMapping.size() ?
+ aVisibleArgMapping[nPos] : aVisibleArgMapping.back());
+ SetArgNameFont( i,
+ (nArg > nFix || pFuncDesc->isParameterOptional(nRealArg)) ?
+ aFntLight : aFntBold );
+ if ( nArg >= nFix )
+ {
+ String aArgName( pFuncDesc->getParameterName(nRealArg) );
+ aArgName += String::CreateFromInt32(nArg-nFix+1);
+ SetArgName( i, aArgName );
+ }
+ else
+ SetArgName( i, pFuncDesc->getParameterName(nRealArg) );
+ }
+ if(nArg<nArgs) SetArgVal(i,aParaArray[nArg]);
+ //@ aArgInput[i].SetArgVal( *(pArgArr[nOffset+i]) );
+
+}
+
+ParaWin::~ParaWin()
+{
+ // #i66422# if the focus changes during destruction of the controls,
+ // don't call the focus handlers
+ Link aEmptyLink;
+ aBtnFx1.SetGetFocusHdl( aEmptyLink );
+ aBtnFx2.SetGetFocusHdl( aEmptyLink );
+ aBtnFx3.SetGetFocusHdl( aEmptyLink );
+ aBtnFx4.SetGetFocusHdl( aEmptyLink );
+}
+
+USHORT ParaWin::GetActiveLine()
+{
+ return nActiveLine;
+}
+
+void ParaWin::SetActiveLine(USHORT no)
+{
+ if(no<nArgs)
+ {
+ long nOffset = GetSliderPos();
+ nActiveLine=no;
+ long nNewEdPos=(long)nActiveLine-nOffset;
+ if(nNewEdPos<0 || nNewEdPos>3)
+ {
+ nOffset+=nNewEdPos;
+ SetSliderPos((USHORT) nOffset);
+ nOffset=GetSliderPos();
+ }
+ nEdFocus=no-(USHORT)nOffset;
+ UpdateArgDesc( nEdFocus );
+ }
+}
+
+RefEdit* ParaWin::GetActiveEdit()
+{
+ if(nArgs>0 && nEdFocus!=NOT_FOUND)
+ {
+ return aArgInput[nEdFocus].GetArgEdPtr();
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+
+String ParaWin::GetArgument(USHORT no)
+{
+ String aStr;
+ if(no<aParaArray.size())
+ {
+ aStr=aParaArray[no];
+ if(no==nActiveLine && aStr.Len()==0)
+ aStr+=' ';
+ }
+ return aStr;
+}
+
+String ParaWin::GetActiveArgName()
+{
+ String aStr;
+ if(nArgs>0 && nEdFocus!=NOT_FOUND)
+ {
+ aStr=aArgInput[nEdFocus].GetArgName();
+ }
+ return aStr;
+}
+
+
+void ParaWin::SetArgument(USHORT no, const String& aString)
+{
+ if(no<aParaArray.size())
+ {
+ aParaArray[no] = aString;
+ aParaArray[no].EraseLeadingChars();
+ }
+}
+
+void ParaWin::DelParaArray()
+{
+ ::std::vector<String>().swap(aParaArray);
+}
+
+void ParaWin::SetArgumentFonts(const Font&aBoldFont,const Font&aLightFont)
+{
+ aFntBold=aBoldFont;
+ aFntLight=aLightFont;
+}
+
+void ParaWin::SetFunctionDesc(const IFunctionDescription* pFDesc)
+{
+ pFuncDesc=pFDesc;
+
+ SetArgumentDesc( String() );
+ SetArgumentText( String() );
+ SetEditDesc( String() );
+ nArgs = 0;
+ if ( pFuncDesc!=NULL)
+ {
+ if ( pFuncDesc->getDescription().getLength() )
+ {
+ SetEditDesc(pFuncDesc->getDescription());
+ }
+ else
+ {
+ SetEditDesc(aDefaultString);
+ }
+ long nHelpId = pFuncDesc->getHelpId();
+ nArgs = pFuncDesc->getSuppressedArgumentCount();
+ pFuncDesc->fillVisibleArgumentMapping(aVisibleArgMapping);
+ aSlider.Hide();
+ SetHelpId( nHelpId );
+ aEdArg1.SetHelpId( nHelpId );
+ aEdArg2.SetHelpId( nHelpId );
+ aEdArg3.SetHelpId( nHelpId );
+ aEdArg4.SetHelpId( nHelpId );
+
+ // Unique-IDs muessen gleich bleiben fuer Automatisierung
+ SetUniqueId( HID_FORMULA_FAP_PAGE );
+ aEdArg1.SetUniqueId( HID_FORMULA_FAP_EDIT1 );
+ aEdArg2.SetUniqueId( HID_FORMULA_FAP_EDIT2 );
+ aEdArg3.SetUniqueId( HID_FORMULA_FAP_EDIT3 );
+ aEdArg4.SetUniqueId( HID_FORMULA_FAP_EDIT4 );
+ SetActiveLine(0);
+ }
+ else
+ {
+ nActiveLine=0;
+ }
+
+}
+
+void ParaWin::SetArgumentText(const String& aText)
+{
+ aFtArgName.SetText(aText);
+}
+
+void ParaWin::SetArgumentDesc(const String& aText)
+{
+ aFtArgDesc.SetText(aText);
+}
+
+void ParaWin::SetEditDesc(const String& aText)
+{
+ aFtEditDesc.SetText(aText);
+}
+
+void ParaWin::SetArgName(USHORT no,const String& aText)
+{
+ aArgInput[no].SetArgName(aText);
+}
+
+void ParaWin::SetArgNameFont(USHORT no,const Font& aFont)
+{
+ aArgInput[no].SetArgNameFont(aFont);
+}
+
+void ParaWin::SetArgVal(USHORT no,const String& aText)
+{
+ aArgInput[no].SetArgVal(aText);
+}
+
+void ParaWin::HideParaLine(USHORT no)
+{
+ aArgInput[no].Hide();
+}
+
+void ParaWin::ShowParaLine(USHORT no)
+{
+ aArgInput[no].Show();
+}
+
+void ParaWin::SetEdFocus(USHORT no)
+{
+ UpdateArgDesc(no);
+ if(no<4 && no<aParaArray.size())
+ aArgInput[no].GetArgEdPtr()->GrabFocus();
+}
+
+
+void ParaWin::InitArgInput( USHORT nPos, FixedText& rFtArg, ImageButton& rBtnFx,
+ ArgEdit& rEdArg, RefButton& rRefBtn)
+{
+
+ rRefBtn.SetReferences(pMyParent,&rEdArg);
+ rEdArg.SetRefDialog(pMyParent);
+
+ aArgInput[nPos].InitArgInput (&rFtArg,&rBtnFx,&rEdArg,&rRefBtn);
+
+ aArgInput[nPos].Hide();
+
+ aArgInput[nPos].SetFxClickHdl ( LINK( this, ParaWin, GetFxHdl ) );
+ aArgInput[nPos].SetFxFocusHdl ( LINK( this, ParaWin, GetFxFocusHdl ) );
+ aArgInput[nPos].SetEdFocusHdl ( LINK( this, ParaWin, GetEdFocusHdl ) );
+ aArgInput[nPos].SetEdModifyHdl ( LINK( this, ParaWin, ModifyHdl ) );
+}
+
+void ParaWin::ClearAll()
+{
+ SetFunctionDesc(NULL);
+ SetArgumentOffset(0);
+}
+
+void ParaWin::SetArgumentOffset(USHORT nOffset)
+{
+ DelParaArray();
+ aSlider.SetThumbPos(0);
+
+ aParaArray.resize(nArgs);
+
+ if ( nArgs > 0 )
+ {
+ for ( int i=0; i<4 && i<nArgs; i++ )
+ {
+ String aString;
+ aArgInput[i].SetArgVal(aString);
+ aArgInput[i].GetArgEdPtr()->Init(
+ (i==0) ? (ArgEdit *)NULL : aArgInput[i-1].GetArgEdPtr(),
+ (i==3 || i==nArgs-1) ? (ArgEdit *)NULL : aArgInput[i+1].GetArgEdPtr(),
+ aSlider, nArgs );
+ }
+ }
+
+ if ( nArgs < 5 )
+ {
+ aSlider.Hide();
+ }
+ else
+ {
+ //aSlider.SetEndScrollHdl( LINK( this, ScFormulaDlg, ScrollHdl ) );
+ aSlider.SetPageSize( 4 );
+ aSlider.SetVisibleSize( 4 );
+ aSlider.SetLineSize( 1 );
+ aSlider.SetRange( Range( 0, nArgs ) );
+ aSlider.SetThumbPos( nOffset );
+ aSlider.Show();
+ }
+
+ UpdateParas();
+}
+
+void ParaWin::UpdateParas()
+{
+ USHORT i;
+ USHORT nOffset = GetSliderPos();
+
+ if ( nArgs > 0 )
+ {
+ for ( i=0; (i<nArgs) && (i<4); i++ )
+ {
+ UpdateArgInput( nOffset, i );
+ ShowParaLine(i);
+ }
+ }
+
+ for ( i=nArgs; i<4; i++ ) HideParaLine(i);
+}
+
+
+USHORT ParaWin::GetSliderPos()
+{
+ return (USHORT) aSlider.GetThumbPos();
+}
+
+void ParaWin::SetSliderPos(USHORT nSliderPos)
+{
+ USHORT nOffset = GetSliderPos();
+
+ if(aSlider.IsVisible() && nOffset!=nSliderPos)
+ {
+ aSlider.SetThumbPos(nSliderPos);
+ for ( USHORT i=0; i<4; i++ )
+ {
+ UpdateArgInput( nSliderPos, i );
+ }
+ }
+}
+
+void ParaWin::SliderMoved()
+{
+ USHORT nOffset = GetSliderPos();
+
+ for ( USHORT i=0; i<4; i++ )
+ {
+ UpdateArgInput( nOffset, i );
+ }
+ if(nEdFocus!=NOT_FOUND)
+ {
+ UpdateArgDesc( nEdFocus );
+ aArgInput[nEdFocus].SetArgSelection(Selection(0,SELECTION_MAX ));
+ nActiveLine=nEdFocus+nOffset;
+ ArgumentModified();
+ }
+ aScrollLink.Call(this);
+}
+
+void ParaWin::ArgumentModified()
+{
+ aArgModifiedLink.Call(this);
+}
+
+void ParaWin::FxClick()
+{
+ aFxLink.Call(this);
+}
+
+
+IMPL_LINK( ParaWin, GetFxHdl, ArgInput*, pPtr )
+{
+ USHORT nOffset = GetSliderPos();
+ nEdFocus=NOT_FOUND;
+ for ( USHORT nPos=0; nPos<5;nPos++)
+ {
+ if(pPtr == &aArgInput[nPos])
+ {
+ nEdFocus=nPos;
+ break;
+ }
+ }
+
+ if(nEdFocus!=NOT_FOUND)
+ {
+ aArgInput[nEdFocus].SetArgSelection(Selection(0,SELECTION_MAX ));
+ nActiveLine=nEdFocus+nOffset;
+ FxClick();
+ }
+ return 0;
+}
+
+IMPL_LINK( ParaWin, GetFxFocusHdl, ArgInput*, pPtr )
+{
+ USHORT nOffset = GetSliderPos();
+ nEdFocus=NOT_FOUND;
+ for ( USHORT nPos=0; nPos<5;nPos++)
+ {
+ if(pPtr == &aArgInput[nPos])
+ {
+ nEdFocus=nPos;
+ break;
+ }
+ }
+
+ if(nEdFocus!=NOT_FOUND)
+ {
+ aArgInput[nEdFocus].SetArgSelection(Selection(0,SELECTION_MAX ));
+ UpdateArgDesc( nEdFocus );
+ nActiveLine=nEdFocus+nOffset;
+ }
+ return 0;
+}
+
+
+
+IMPL_LINK( ParaWin, GetEdFocusHdl, ArgInput*, pPtr )
+{
+ USHORT nOffset = GetSliderPos();
+ nEdFocus=NOT_FOUND;
+ for ( USHORT nPos=0; nPos<5;nPos++)
+ {
+ if(pPtr == &aArgInput[nPos])
+ {
+ nEdFocus=nPos;
+ break;
+ }
+ }
+
+ if(nEdFocus!=NOT_FOUND)
+ {
+ aArgInput[nEdFocus].SetArgSelection(Selection(0,SELECTION_MAX ));
+ UpdateArgDesc( nEdFocus );
+ nActiveLine=nEdFocus+nOffset;
+ ArgumentModified();
+ }
+
+ return 0;
+}
+
+
+IMPL_LINK( ParaWin, ScrollHdl, ScrollBar*, EMPTYARG )
+{
+ SliderMoved();
+
+ return 0;
+}
+
+IMPL_LINK( ParaWin, ModifyHdl, ArgInput*, pPtr )
+{
+ USHORT nOffset = GetSliderPos();
+ nEdFocus=NOT_FOUND;
+ for ( USHORT nPos=0; nPos<5;nPos++)
+ {
+ if(pPtr == &aArgInput[nPos])
+ {
+ nEdFocus=nPos;
+ break;
+ }
+ }
+ if(nEdFocus!=NOT_FOUND)
+ {
+ aParaArray[nEdFocus+nOffset] = aArgInput[nEdFocus].GetArgVal();
+ UpdateArgDesc( nEdFocus);
+ nActiveLine=nEdFocus+nOffset;
+ }
+
+ ArgumentModified();
+ return 0;
+}
+
+
+
+} // formula
diff --git a/formula/source/ui/dlg/parawin.hrc b/formula/source/ui/dlg/parawin.hrc new file mode 100644 index 000000000000..4873760b24d8 --- /dev/null +++ b/formula/source/ui/dlg/parawin.hrc @@ -0,0 +1,57 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: parawin.hrc,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// #define RID_SCTAB_PARAMETER 256 + +#define FT_PARNAME 1 +#define FT_PARDESC 2 +#define FT_EDITDESC 3 +#define FT_ARG1 4 +#define FT_ARG2 5 +#define FT_ARG3 6 +#define FT_ARG4 7 +#define BTN_FX1 8 +#define BTN_FX2 9 +#define BTN_FX3 10 +#define BTN_FX4 11 +#define ED_ARG1 12 +#define ED_ARG2 13 +#define ED_ARG3 14 +#define ED_ARG4 15 +#define RB_ARG1 16 +#define RB_ARG2 17 +#define RB_ARG3 18 +#define RB_ARG4 19 +#define WND_SLIDER 20 +#define IMG_FX_H 30 + +#define STR_OPTIONAL 1 +#define STR_REQUIRED 2 + diff --git a/formula/source/ui/dlg/parawin.hxx b/formula/source/ui/dlg/parawin.hxx new file mode 100644 index 000000000000..a4dc90c29e84 --- /dev/null +++ b/formula/source/ui/dlg/parawin.hxx @@ -0,0 +1,177 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: parawin.hxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FORMULA_PARAWIN_HXX +#define FORMULA_PARAWIN_HXX + +#include <svtools/stdctrl.hxx> +#include <svtools/svmedit.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/group.hxx> +#include <vcl/tabpage.hxx> +#include <vcl/tabctrl.hxx> +#include <vcl/scrbar.hxx> + +#include <vector> +#include "formula/funcutl.hxx" +#include "ControlHelper.hxx" +#include "ModuleHelper.hxx" + +namespace formula +{ +//============================================================================ +#define NOT_FOUND 0xffff +//============================================================================ +class IFunctionDescription; +class IControlReferenceHandler; + +class ParaWin : public TabPage +{ +private: + OModuleClient m_aModuleClient; + Link aScrollLink; + Link aFxLink; + Link aArgModifiedLink; + + ::std::vector<USHORT> aVisibleArgMapping; + const IFunctionDescription* pFuncDesc; + IControlReferenceHandler* pMyParent; + USHORT nArgs; // unsuppressed arguments + Font aFntBold; + Font aFntLight; + + FixedInfo aFtEditDesc; + FixedText aFtArgName; + FixedInfo aFtArgDesc; + + FixedText aFtArg1; + FixedText aFtArg2; + FixedText aFtArg3; + FixedText aFtArg4; + + ImageButton aBtnFx1; + ImageButton aBtnFx2; + ImageButton aBtnFx3; + ImageButton aBtnFx4; + + ArgEdit aEdArg1; + ArgEdit aEdArg2; + ArgEdit aEdArg3; + ArgEdit aEdArg4; + + RefButton aRefBtn1; + RefButton aRefBtn2; + RefButton aRefBtn3; + RefButton aRefBtn4; + + ScrollBar aSlider; + String m_sOptional; + String m_sRequired; + BOOL bRefMode; + + USHORT nEdFocus; + USHORT nActiveLine; + + ArgInput aArgInput[4]; + String aDefaultString; + ::std::vector<String> + aParaArray; + + DECL_LINK( ScrollHdl, ScrollBar* ); + DECL_LINK( ModifyHdl, ArgInput* ); + DECL_LINK( GetEdFocusHdl, ArgInput* ); + DECL_LINK( GetFxFocusHdl, ArgInput* ); + DECL_LINK( GetFxHdl, ArgInput* ); + +protected: + + virtual void SliderMoved(); + virtual void ArgumentModified(); + virtual void FxClick(); + + void InitArgInput( USHORT nPos, FixedText& rFtArg, ImageButton& rBtnFx, + ArgEdit& rEdArg, RefButton& rRefBtn); + + void DelParaArray(); + void SetArgumentDesc(const String& aText); + void SetArgumentText(const String& aText); + + + void SetArgName (USHORT no,const String &aArg); + void SetArgNameFont (USHORT no,const Font&); + void SetArgVal (USHORT no,const String &aArg); + + void HideParaLine(USHORT no); + void ShowParaLine(USHORT no); + void UpdateArgDesc( USHORT nArg ); + void UpdateArgInput( USHORT nOffset, USHORT i ); + +public: + ParaWin(Window* pParent,IControlReferenceHandler* _pDlg,Point aPos); + ~ParaWin(); + + void SetFunctionDesc(const IFunctionDescription* pFDesc); + void SetArgumentOffset(USHORT nOffset); + void SetEditDesc(const String& aText); + void UpdateParas(); + void ClearAll(); + + BOOL IsRefMode() {return bRefMode;} + void SetRefMode(BOOL bFlag) {bRefMode=bFlag;} + + USHORT GetActiveLine(); + void SetActiveLine(USHORT no); + RefEdit* GetActiveEdit(); + String GetActiveArgName(); + + String GetArgument(USHORT no); + void SetArgument(USHORT no, const String& aString); + void SetArgumentFonts(const Font&aBoldFont,const Font&aLightFont); + + void SetEdFocus(USHORT nEditLine); //Sichtbare Editzeilen + USHORT GetSliderPos(); + void SetSliderPos(USHORT nSliderPos); + + void SetScrollHdl( const Link& rLink ) { aScrollLink = rLink; } + const Link& GetScrollHdl() const { return aScrollLink; } + + void SetArgModifiedHdl( const Link& rLink ) { aArgModifiedLink = rLink; } + const Link& GetArgModifiedHdl() const { return aArgModifiedLink; } + + void SetFxHdl( const Link& rLink ) { aFxLink = rLink; } + const Link& GetFxHdl() const { return aFxLink; } +}; + + + +} // formula + +#endif // FORMULA_PARAWIN_HXX + diff --git a/formula/source/ui/dlg/parawin.src b/formula/source/ui/dlg/parawin.src new file mode 100644 index 000000000000..00998de14bc9 --- /dev/null +++ b/formula/source/ui/dlg/parawin.src @@ -0,0 +1,192 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: parawin.src,v $ + * $Revision: 1.30 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "parawin.hrc" +#include "ForResId.hrc" +#include "helpids.hrc" + +#define STD_MASKCOLOR Color { Red=0xFFFF; Green=0x0000; Blue=0xFFFF; } + //--------------------------------------------------------------------------- + +#define FT_ARGBLOCK( y ) \ + Pos = MAP_APPFONT (6 , y ) ; \ + Size = MAP_APPFONT ( 74 , 8 ) ; \ + Right = TRUE ; + +#define FXBUTTONBLOCK( y ) \ + Pos = MAP_APPFONT (83 , y-1 ) ; \ + Size = MAP_APPFONT ( 13 , 15 ) ; \ + TabStop = TRUE ; \ + ButtonImage = Image\ + {\ + ImageBitmap = Bitmap\ + {\ + File = "fx.bmp" ; \ + };\ + MaskColor = STD_MASKCOLOR;\ + }; + +#define ED_ARGBLOCK( y ) \ + Border = TRUE; \ + Pos = MAP_APPFONT( 98, y ); \ + Size = MAP_APPFONT( 66, 12 ); \ + TabStop = TRUE; + +#define RB_ARGBLOCK( y ) \ + Pos = MAP_APPFONT ( 166 , y-1 ) ; \ + Size = MAP_APPFONT ( 13 , 15 ) ; \ + TabStop = FALSE ; \ + QuickHelpText [ en-US ] = "Select"; \ + + //--------------------------------------------------------------------------- + + // jetzt alles zusammen + +TabPage RID_FORMULATAB_PARAMETER +{ + Border = FALSE; + Size = MAP_APPFONT( 203, 128 ); + DialogControl = TRUE; + SVLook = TRUE; + + FixedText FT_EDITDESC + { + Pos = MAP_APPFONT (3 , 6 ) ; + Size = MAP_APPFONT ( 198 , 20 ) ; + WordBreak = TRUE ; + Text [ en-US ] = "Function not known"; + }; + + FixedText FT_PARNAME + { + Pos = MAP_APPFONT ( 3, 29) ; + Size = MAP_APPFONT ( 198 , 10 ) ; + }; + FixedText FT_PARDESC + { + Pos = MAP_APPFONT ( 3, 42 ) ; + Size = MAP_APPFONT ( 198 , 20 ) ; + WordBreak = TRUE ; + }; + + FixedText FT_ARG1 { FT_ARGBLOCK ( 66 ) }; + FixedText FT_ARG2 { FT_ARGBLOCK ( 81 ) }; + FixedText FT_ARG3 { FT_ARGBLOCK ( 96 ) }; + FixedText FT_ARG4 { FT_ARGBLOCK ( 111 ) }; + + ImageButton BTN_FX1 + { + HelpId=HID_FORMULA_FAP_BTN_FX1; + FXBUTTONBLOCK ( 64 ) + }; + ImageButton BTN_FX2 + { + HelpId=HID_FORMULA_FAP_BTN_FX2; + FXBUTTONBLOCK ( 79 ) + }; + + ImageButton BTN_FX3 + { + HelpId=HID_FORMULA_FAP_BTN_FX3; + FXBUTTONBLOCK ( 94 ) + }; + ImageButton BTN_FX4 + { + HelpId=HID_FORMULA_FAP_BTN_FX4; + FXBUTTONBLOCK ( 109 ) + }; + Edit ED_ARG1 { ED_ARGBLOCK ( 64 ) }; + Edit ED_ARG2 { ED_ARGBLOCK ( 79 ) }; + Edit ED_ARG3 { ED_ARGBLOCK ( 94 ) }; + Edit ED_ARG4 { ED_ARGBLOCK ( 109 ) }; + + ImageButton RB_ARG1 + { + HelpId=HID_FORMULA_FAP_BTN_REF1; + RB_ARGBLOCK ( 64 ) + }; + + ImageButton RB_ARG2 + { + HelpId=HID_FORMULA_FAP_BTN_REF2; + RB_ARGBLOCK ( 79 ) + }; + ImageButton RB_ARG3 + { + HelpId=HID_FORMULA_FAP_BTN_REF3; + RB_ARGBLOCK ( 94 ) + }; + ImageButton RB_ARG4 + { + HelpId=HID_FORMULA_FAP_BTN_REF4; + RB_ARGBLOCK ( 109 ) + }; + + ScrollBar WND_SLIDER + { + Pos = MAP_APPFONT ( 183, 63 ) ; + Size = MAP_APPFONT ( 8 , 59 ) ; + VScroll = TRUE ; + }; + + String STR_OPTIONAL + { + Text [ en-US ] = "(optional)" ; + }; + String STR_REQUIRED + { + Text [ en-US ] = "(required)" ; + }; + + Image IMG_FX_H + { + ImageBitmap = Bitmap { File = "fx_h.bmp" ; }; + MaskColor = STD_MASKCOLOR; + }; + +}; + + + + + + + + + + + + + + + + + + diff --git a/formula/source/ui/dlg/structpg.cxx b/formula/source/ui/dlg/structpg.cxx new file mode 100644 index 000000000000..3d9c467357ae --- /dev/null +++ b/formula/source/ui/dlg/structpg.cxx @@ -0,0 +1,230 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: structpg.cxx,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_formula.hxx" + + + +//---------------------------------------------------------------------------- + +#include <svtools/zforlist.hxx> +#include <svtools/stritem.hxx> + +#include "structpg.hxx" +#include "formdlgs.hrc" +#include "formula/formdata.hxx" +#include "formula/formula.hxx" +#include "ModuleHelper.hxx" +#include "formula/IFunctionDescription.hxx" +#include "ForResId.hrc" + +//---------------------------------------------------------------------------- +namespace formula +{ +StructListBox::StructListBox(Window* pParent, const ResId& rResId ): + SvTreeListBox(pParent,rResId ) +{ + bActiveFlag=FALSE; + + Font aFont( GetFont() ); + Size aSize = aFont.GetSize(); + aSize.Height() -= 2; + aFont.SetSize( aSize ); + SetFont( aFont ); +} + +SvLBoxEntry* StructListBox::InsertStaticEntry( + const XubString& rText, + const Image& rEntryImg, const Image& rEntryImgHC, + SvLBoxEntry* pParent, ULONG nPos, IFormulaToken* pToken ) +{ + SvLBoxEntry* pEntry = InsertEntry( rText, rEntryImg, rEntryImg, pParent, FALSE, nPos, pToken ); + SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) ); + DBG_ASSERT( pBmpItem, "StructListBox::InsertStaticEntry - missing item" ); + pBmpItem->SetBitmap1( rEntryImgHC, BMP_COLOR_HIGHCONTRAST ); + pBmpItem->SetBitmap2( rEntryImgHC, BMP_COLOR_HIGHCONTRAST ); + return pEntry; +} + +void StructListBox::SetActiveFlag(BOOL bFlag) +{ + bActiveFlag=bFlag; +} + +BOOL StructListBox::GetActiveFlag() +{ + return bActiveFlag; +} + +void StructListBox::MouseButtonDown( const MouseEvent& rMEvt ) +{ + bActiveFlag=TRUE; + SvTreeListBox::MouseButtonDown(rMEvt); +} + +void StructListBox::GetFocus() +{ + bActiveFlag=TRUE; + SvTreeListBox::GetFocus(); +} + +void StructListBox::LoseFocus() +{ + bActiveFlag=FALSE; + SvTreeListBox::LoseFocus(); +} + +//============================================================================== + +StructPage::StructPage(Window* pParent): + TabPage(pParent,ModuleRes(RID_FORMULATAB_STRUCT)), + // + aFtStruct ( this, ModuleRes( FT_STRUCT ) ), + aTlbStruct ( this, ModuleRes( TLB_STRUCT ) ), + maImgEnd ( ModuleRes( BMP_STR_END ) ), + maImgError ( ModuleRes( BMP_STR_ERROR ) ), + maImgEndHC ( ModuleRes( BMP_STR_END_H ) ), + maImgErrorHC ( ModuleRes( BMP_STR_ERROR_H ) ), + pSelectedToken ( NULL ) +{ + aTlbStruct.SetWindowBits(WB_HASLINES|WB_CLIPCHILDREN| + WB_HASBUTTONS|WB_HSCROLL|WB_NOINITIALSELECTION); + + aTlbStruct.SetNodeDefaultImages(); + aTlbStruct.SetDefaultExpandedEntryBmp( Image( ModuleRes( BMP_STR_OPEN ) ) ); + aTlbStruct.SetDefaultCollapsedEntryBmp( Image( ModuleRes( BMP_STR_CLOSE ) ) ); + aTlbStruct.SetDefaultExpandedEntryBmp( Image( ModuleRes( BMP_STR_OPEN_H ) ), BMP_COLOR_HIGHCONTRAST ); + aTlbStruct.SetDefaultCollapsedEntryBmp( Image( ModuleRes( BMP_STR_CLOSE_H ) ), BMP_COLOR_HIGHCONTRAST ); + + FreeResource(); + + aTlbStruct.SetSelectHdl(LINK( this, StructPage, SelectHdl ) ); +} + +void StructPage::ClearStruct() +{ + aTlbStruct.SetActiveFlag(FALSE); + aTlbStruct.Clear(); +} + +SvLBoxEntry* StructPage::InsertEntry( const XubString& rText, SvLBoxEntry* pParent, + USHORT nFlag,ULONG nPos,IFormulaToken* pIFormulaToken) +{ + aTlbStruct.SetActiveFlag( FALSE ); + + SvLBoxEntry* pEntry = NULL; + switch( nFlag ) + { + case STRUCT_FOLDER: + pEntry = aTlbStruct.InsertEntry( rText, pParent, FALSE, nPos, pIFormulaToken ); + break; + case STRUCT_END: + pEntry = aTlbStruct.InsertStaticEntry( rText, maImgEnd, maImgEndHC, pParent, nPos, pIFormulaToken ); + break; + case STRUCT_ERROR: + pEntry = aTlbStruct.InsertStaticEntry( rText, maImgError, maImgErrorHC, pParent, nPos, pIFormulaToken ); + break; + } + + if( pEntry && pParent ) + aTlbStruct.Expand( pParent ); + return pEntry; +} + +String StructPage::GetEntryText(SvLBoxEntry* pEntry) const +{ + String aString; + if(pEntry!=NULL) + aString=aTlbStruct.GetEntryText(pEntry); + return aString; +} + +SvLBoxEntry* StructPage::GetParent(SvLBoxEntry* pEntry) const +{ + return aTlbStruct.GetParent(pEntry); +} +IFormulaToken* StructPage::GetFunctionEntry(SvLBoxEntry* pEntry) +{ + if(pEntry!=NULL) + { + IFormulaToken * pToken=(IFormulaToken *)pEntry->GetUserData(); + if(pToken!=NULL) + { + if ( !(pToken->isFunction() || pToken->getArgumentCount() > 1 ) ) + { + return GetFunctionEntry(aTlbStruct.GetParent(pEntry)); + } + else + { + return pToken; + } + } + } + return NULL; +} + +IMPL_LINK( StructPage, SelectHdl, SvTreeListBox*, pTlb ) +{ + if(aTlbStruct.GetActiveFlag()) + { + if(pTlb==&aTlbStruct) + { + SvLBoxEntry* pCurEntry=aTlbStruct.GetCurEntry(); + if(pCurEntry!=NULL) + { + pSelectedToken=(IFormulaToken *)pCurEntry->GetUserData(); + if(pSelectedToken!=NULL) + { + if ( !(pSelectedToken->isFunction() || pSelectedToken->getArgumentCount() > 1) ) + { + pSelectedToken = GetFunctionEntry(pCurEntry); + } + } + } + } + + aSelLink.Call(this); + } + return 0; +} + +IFormulaToken* StructPage::GetSelectedToken() +{ + return pSelectedToken; +} + +String StructPage::GetSelectedEntryText() +{ + return aTlbStruct.GetEntryText(aTlbStruct.GetCurEntry()); +} + +} // formula + diff --git a/formula/source/ui/dlg/structpg.hxx b/formula/source/ui/dlg/structpg.hxx new file mode 100644 index 000000000000..1d9c7b0281d0 --- /dev/null +++ b/formula/source/ui/dlg/structpg.hxx @@ -0,0 +1,124 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: structpg.hxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_STRUCTPG_HXX +#define SC_STRUCTPG_HXX + +#include <svtools/stdctrl.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/group.hxx> +#include <svtools/svmedit.hxx> +#include <vcl/tabpage.hxx> +#include <vcl/tabctrl.hxx> +#include <svtools/svtreebx.hxx> +#include "formula/IFunctionDescription.hxx" +#include "ModuleHelper.hxx" + +//============================================================================ + +//============================================================================ +namespace formula +{ + +class IFormulaToken; +class StructListBox : public SvTreeListBox +{ +private: + + BOOL bActiveFlag; + +protected: + virtual void MouseButtonDown( const MouseEvent& rMEvt ); + +public: + + StructListBox(Window* pParent, const ResId& rResId ); + + /** Inserts an entry with static image (no difference between collapsed/expanded). */ + SvLBoxEntry* InsertStaticEntry( + const XubString& rText, + const Image& rEntryImg, + const Image& rEntryImgHC, + SvLBoxEntry* pParent = NULL, + ULONG nPos = LIST_APPEND, + IFormulaToken* pToken = NULL ); + + void SetActiveFlag(BOOL bFlag=TRUE); + BOOL GetActiveFlag(); + void GetFocus(); + void LoseFocus(); +}; + +//============================================================================ + +class StructPage : public TabPage + , public IStructHelper +{ +private: + OModuleClient m_aModuleClient; + Link aSelLink; + + FixedText aFtStruct; + StructListBox aTlbStruct; + Image maImgEnd; + Image maImgError; + Image maImgEndHC; + Image maImgErrorHC; + + IFormulaToken* pSelectedToken; + + DECL_LINK( SelectHdl, SvTreeListBox* ); + +protected: + + IFormulaToken* GetFunctionEntry(SvLBoxEntry* pEntry); + +public: + + StructPage( Window* pParent); + + void ClearStruct(); + virtual SvLBoxEntry* InsertEntry(const XubString& rText, SvLBoxEntry* pParent, + USHORT nFlag,ULONG nPos=0,IFormulaToken* pScToken=NULL); + + virtual String GetEntryText(SvLBoxEntry* pEntry) const; + virtual SvLBoxEntry* GetParent(SvLBoxEntry* pEntry) const; + + String GetSelectedEntryText(); + IFormulaToken* GetSelectedToken(); + + void SetSelectionHdl( const Link& rLink ) { aSelLink = rLink; } + const Link& GetSelectionHdl() const { return aSelLink; } +}; + +} // formula + +#endif + diff --git a/formula/source/ui/inc/ForResId.hrc b/formula/source/ui/inc/ForResId.hrc new file mode 100644 index 000000000000..99ce947a0560 --- /dev/null +++ b/formula/source/ui/inc/ForResId.hrc @@ -0,0 +1,77 @@ +/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: RptResId.hrc,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef FORMULA_FORRESID_HRC
+#define FORMULA_FORRESID_HRC
+
+// include -----------------------------------------------------------
+
+#ifndef _SOLAR_HRC
+#include <svtools/solar.hrc>
+#endif
+
+#define RID_DIALOG_START RID_FORMULA_START
+#define RID_PAGE_START RID_FORMULA_START
+#define RID_ERRORBOX_START RID_FORMULA_START
+#define RID_QUERYBOX_START RID_FORMULA_START
+#define RID_TOOLBOX_START RID_FORMULA_START
+#define RID_BITMAP_START RID_FORMULA_START
+#define RID_IMAGE_START RID_FORMULA_START
+#define RID_IMAGELIST_START RID_FORMULA_START
+#define RID_MENU_START RID_FORMULA_START
+#define RID_STRING_START RID_FORMULA_START
+#define RID_UNTYPED_START RID_FORMULA_START
+#define RID_WARN_START RID_FORMULA_START
+#define RID_CONTROL_START RID_FORMULA_START
+#define RID_MISC_START RID_FORMULA_START
+
+// Dialog Control Id's -----------------------------------------------------------
+
+// strings
+
+// bitmap
+#define RID_BMP_REFBTN1 (RID_BITMAP_START + 0)
+#define RID_BMP_REFBTN1_H (RID_BITMAP_START + 1)
+#define RID_BMP_REFBTN2 (RID_BITMAP_START + 2)
+#define RID_BMP_REFBTN2_H (RID_BITMAP_START + 3)
+
+
+// pages
+#define RID_FORMULATAB_STRUCT (RID_PAGE_START + 0)
+#define RID_FORMULATAB_FUNCTION (RID_PAGE_START + 1)
+#define RID_FORMULADLG_FORMULA (RID_PAGE_START + 2)
+#define RID_FORMULATAB_PARAMETER (RID_PAGE_START + 3)
+#define RID_FORMULADLG_FORMULA_MODAL (RID_PAGE_START + 4)
+
+// misc
+
+// -----------------------------------------------------------------------
+
+#endif // FORMULA_FORRESID_HRC
diff --git a/formula/source/ui/inc/ModuleHelper.hxx b/formula/source/ui/inc/ModuleHelper.hxx new file mode 100644 index 000000000000..b7d0d7d4dd0b --- /dev/null +++ b/formula/source/ui/inc/ModuleHelper.hxx @@ -0,0 +1,102 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ModuleHelper.hxx,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FORMULA_MODULE_HELPER_RPT_HXX_ +#define FORMULA_MODULE_HELPER_RPT_HXX_ + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <tools/resmgr.hxx> +#include "formula/formuladllapi.h" +//......................................................................... +namespace formula +{ +//......................................................................... + //========================================================================= + //= OModule + //========================================================================= + class OModuleImpl; + class FORMULA_DLLPUBLIC OModule + { + friend class OModuleClient; + + private: + OModule(); + // not implemented. OModule is a static class + + protected: + static ::osl::Mutex s_aMutex; /// access safety + static sal_Int32 s_nClients; /// number of registered clients + static OModuleImpl* s_pImpl; /// impl class. lives as long as at least one client for the module is registered + + public: + /// get the vcl res manager of the module + static ResMgr* getResManager(); + protected: + /// register a client for the module + static void registerClient(); + /// revoke a client for the module + static void revokeClient(); + + private: + /** ensure that the impl class exists + @precond m_aMutex is guarded when this method gets called + */ + static void ensureImpl(); + }; + + //========================================================================= + //= OModuleClient + //========================================================================= + /** base class for objects which uses any global module-specific ressources + */ + class FORMULA_DLLPUBLIC OModuleClient + { + public: + OModuleClient() { OModule::registerClient(); } + ~OModuleClient() { OModule::revokeClient(); } + }; + + //========================================================================= + //= ModuleRes + //========================================================================= + /** specialized ResId, using the ressource manager provided by the global module + */ + class FORMULA_DLLPUBLIC ModuleRes : public ::ResId + { + public: + ModuleRes(USHORT _nId) : ResId(_nId, *OModule::getResManager()) { } + }; +//......................................................................... +} // namespace formula +//......................................................................... + +#endif // FORMULA_MODULE_HELPER_RPT_HXX_ + + diff --git a/formula/source/ui/resource/ModuleHelper.cxx b/formula/source/ui/resource/ModuleHelper.cxx new file mode 100644 index 000000000000..b6ede64b0226 --- /dev/null +++ b/formula/source/ui/resource/ModuleHelper.cxx @@ -0,0 +1,145 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ModuleHelper.cxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "ModuleHelper.hxx" +#include <comphelper/configurationhelper.hxx> +#include <comphelper/processfactory.hxx> +#include <osl/thread.h> +#include <com/sun/star/util/XMacroExpander.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <rtl/uri.hxx> +#include <tools/debug.hxx> +#ifndef _SOLAR_HRC +#include <svtools/solar.hrc> +#endif + +#define EXPAND_PROTOCOL "vnd.sun.star.expand:" +#define ENTER_MOD_METHOD() \ + ::osl::MutexGuard aGuard(s_aMutex); \ + ensureImpl() + +//......................................................................... +namespace formula +{ +//......................................................................... + using namespace ::com::sun::star; +//========================================================================= +//= OModuleImpl +//========================================================================= +/** implementation for <type>OModule</type>. not threadsafe, has to be guarded by it's owner +*/ +class OModuleImpl +{ + ResMgr* m_pRessources; + +public: + /// ctor + OModuleImpl(); + ~OModuleImpl(); + + /// get the manager for the ressources of the module + ResMgr* getResManager(); +}; + +DBG_NAME( rpt_OModuleImpl ) +//------------------------------------------------------------------------- +OModuleImpl::OModuleImpl() + :m_pRessources(NULL) +{ + DBG_CTOR( rpt_OModuleImpl,NULL); + +} + +//------------------------------------------------------------------------- +OModuleImpl::~OModuleImpl() +{ + if (m_pRessources) + delete m_pRessources; + + DBG_DTOR( rpt_OModuleImpl,NULL); +} + +//------------------------------------------------------------------------- +ResMgr* OModuleImpl::getResManager() +{ + // note that this method is not threadsafe, which counts for the whole class ! + + if (!m_pRessources) + { + // create a manager with a fixed prefix + rtl::OString sName = rtl::OString( "forui" ); + m_pRessources = ResMgr::CreateResMgr(sName); + } + return m_pRessources; +} + +//========================================================================= +//= OModule +//========================================================================= +::osl::Mutex OModule::s_aMutex; +sal_Int32 OModule::s_nClients = 0; +OModuleImpl* OModule::s_pImpl = NULL; +//------------------------------------------------------------------------- +ResMgr* OModule::getResManager() +{ + ENTER_MOD_METHOD(); + return s_pImpl->getResManager(); +} + +//------------------------------------------------------------------------- +void OModule::registerClient() +{ + ::osl::MutexGuard aGuard(s_aMutex); + ++s_nClients; +} + +//------------------------------------------------------------------------- +void OModule::revokeClient() +{ + ::osl::MutexGuard aGuard(s_aMutex); + if (!--s_nClients && s_pImpl) + { + delete s_pImpl; + s_pImpl = NULL; + } +} + +//------------------------------------------------------------------------- +void OModule::ensureImpl() +{ + if (s_pImpl) + return; + s_pImpl = new OModuleImpl(); +} + +//......................................................................... +} // namespace formula +//......................................................................... + diff --git a/formula/source/ui/resource/makefile.mk b/formula/source/ui/resource/makefile.mk new file mode 100644 index 000000000000..d9a6039ae77d --- /dev/null +++ b/formula/source/ui/resource/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJINC=$(PRJ)$/source +PRJNAME=formula +TARGET=ui_resource +ENABLE_EXCEPTIONS=TRUE +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +#SRS1NAME=ui_res +#SRC1FILES= \ +# ui_resource.src + + +SLOFILES= $(SLO)$/ModuleHelper.obj \ + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk |