/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" // INCLUDE --------------------------------------------------------------- #include #include "scitems.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.hxx" #include "scresid.hxx" #include "autoform.hxx" #include "document.hxx" #include "patattr.hxx" #include "addincol.hxx" #include "adiasync.hxx" #include "userlist.hxx" #include "interpre.hxx" #include "strload.hxx" #include "docpool.hxx" #include "unitconv.hxx" #include "compiler.hxx" #include "parclass.hxx" #include "funcdesc.hxx" #include "globstr.hrc" #include "scfuncs.hrc" #include "sc.hrc" #include "scmod.hxx" #include "appoptio.hxx" // ----------------------------------------------------------------------- #define CLIPST_AVAILABLE 0 #define CLIPST_CAPTURED 1 #define CLIPST_DELETE 2 #define CLIPST_DRAW 3 ScDocShellRef* ScGlobal::pDrawClipDocShellRef = NULL; SvxSearchItem* ScGlobal::pSearchItem = NULL; ScAutoFormat* ScGlobal::pAutoFormat = NULL; FuncCollection* ScGlobal::pFuncCollection = NULL; ScUnoAddInCollection* ScGlobal::pAddInCollection = NULL; ScUserList* ScGlobal::pUserList = NULL; String** ScGlobal::ppRscString = NULL; LanguageType ScGlobal::eLnge = LANGUAGE_SYSTEM; ::com::sun::star::lang::Locale* ScGlobal::pLocale = NULL; SvtSysLocale* ScGlobal::pSysLocale = NULL; const CharClass* ScGlobal::pCharClass = NULL; const LocaleDataWrapper* ScGlobal::pLocaleData = NULL; CalendarWrapper* ScGlobal::pCalendar = NULL; CollatorWrapper* ScGlobal::pCollator = NULL; CollatorWrapper* ScGlobal::pCaseCollator = NULL; ::utl::TransliterationWrapper* ScGlobal::pTransliteration = NULL; ::utl::TransliterationWrapper* ScGlobal::pCaseTransliteration = NULL; ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XOrdinalSuffix> ScGlobal::xOrdinalSuffix = NULL; IntlWrapper* ScGlobal::pScIntlWrapper = NULL; sal_Unicode ScGlobal::cListDelimiter = ','; String* ScGlobal::pEmptyString = NULL; String* ScGlobal::pStrClipDocName = NULL; SvxBrushItem* ScGlobal::pEmptyBrushItem = NULL; SvxBrushItem* ScGlobal::pButtonBrushItem = NULL; SvxBrushItem* ScGlobal::pEmbeddedBrushItem = NULL; SvxBrushItem* ScGlobal::pProtectedBrushItem = NULL; ImageList* ScGlobal::pOutlineBitmaps = NULL; ImageList* ScGlobal::pOutlineBitmapsHC = NULL; ScFunctionList* ScGlobal::pStarCalcFunctionList = NULL; ScFunctionMgr* ScGlobal::pStarCalcFunctionMgr = NULL; ScUnitConverter* ScGlobal::pUnitConverter = NULL; SvNumberFormatter* ScGlobal::pEnglishFormatter = NULL; double ScGlobal::nScreenPPTX = 96.0; double ScGlobal::nScreenPPTY = 96.0; sal_uInt16 ScGlobal::nDefFontHeight = 240; sal_uInt16 ScGlobal::nStdRowHeight = 257; long ScGlobal::nLastRowHeightExtra = 0; long ScGlobal::nLastColWidthExtra = STD_EXTRA_WIDTH; static sal_uInt16 nPPTZoom = 0; // ScreenZoom used to determine nScreenPPTX/Y class SfxViewShell; SfxViewShell* pScActiveViewShell = NULL; //! als Member !!!!! sal_uInt16 nScClickMouseModifier = 0; //! dito sal_uInt16 nScFillModeMouseModifier = 0; //! dito // Hack: ScGlobal::GetUserList() muss InitAppOptions in der UI aufrufen, // damit UserList aus Cfg geladen wird void global_InitAppOptions(); //======================================================================== // // statische Funktionen // //======================================================================== sal_Bool ScGlobal::HasAttrChanged( const SfxItemSet& rNewAttrs, const SfxItemSet& rOldAttrs, const sal_uInt16 nWhich ) { sal_Bool bInvalidate = sal_False; const SfxItemState eNewState = rNewAttrs.GetItemState( nWhich ); const SfxItemState eOldState = rOldAttrs.GetItemState( nWhich ); //---------------------------------------------------------- if ( eNewState == eOldState ) { // beide Items gesetzt // PoolItems, d.h. Pointer-Vergleich zulaessig if ( SFX_ITEM_SET == eOldState ) bInvalidate = (&rNewAttrs.Get( nWhich ) != &rOldAttrs.Get( nWhich )); } else { // ein Default-Item dabei // PoolItems, d.h. Item-Vergleich noetig const SfxPoolItem& rOldItem = ( SFX_ITEM_SET == eOldState ) ? rOldAttrs.Get( nWhich ) : rOldAttrs.GetPool()->GetDefaultItem( nWhich ); const SfxPoolItem& rNewItem = ( SFX_ITEM_SET == eNewState ) ? rNewAttrs.Get( nWhich ) : rNewAttrs.GetPool()->GetDefaultItem( nWhich ); bInvalidate = sal::static_int_cast(rNewItem != rOldItem); } return bInvalidate; } sal_uLong ScGlobal::GetStandardFormat( SvNumberFormatter& rFormatter, sal_uLong nFormat, short nType ) { const SvNumberformat* pFormat = rFormatter.GetEntry( nFormat ); if ( pFormat ) return rFormatter.GetStandardFormat( nFormat, nType, pFormat->GetLanguage() ); return rFormatter.GetStandardFormat( nType, eLnge ); } sal_uLong ScGlobal::GetStandardFormat( double fNumber, SvNumberFormatter& rFormatter, sal_uLong nFormat, short nType ) { const SvNumberformat* pFormat = rFormatter.GetEntry( nFormat ); if ( pFormat ) return rFormatter.GetStandardFormat( fNumber, nFormat, nType, pFormat->GetLanguage() ); return rFormatter.GetStandardFormat( nType, eLnge ); } // static SvNumberFormatter* ScGlobal::GetEnglishFormatter() { if ( !pEnglishFormatter ) { pEnglishFormatter = new SvNumberFormatter( ::comphelper::getProcessServiceFactory(), LANGUAGE_ENGLISH_US ); pEnglishFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_INTL_FORMAT ); } return pEnglishFormatter; } //------------------------------------------------------------------------ sal_Bool ScGlobal::CheckWidthInvalidate( sal_Bool& bNumFormatChanged, const SfxItemSet& rNewAttrs, const SfxItemSet& rOldAttrs ) { // Ueberpruefen, ob Attributaenderungen in rNewAttrs gegnueber // rOldAttrs die Textbreite an einer Zelle ungueltig machen bNumFormatChanged = HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_VALUE_FORMAT ); return ( bNumFormatChanged || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_LANGUAGE_FORMAT ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CJK_FONT ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CTL_FONT ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_HEIGHT ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CJK_FONT_HEIGHT ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CTL_FONT_HEIGHT ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_WEIGHT ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CJK_FONT_WEIGHT ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CTL_FONT_WEIGHT ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_POSTURE ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CJK_FONT_POSTURE ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CTL_FONT_POSTURE ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_UNDERLINE ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_OVERLINE ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_CROSSEDOUT ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_CONTOUR ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_SHADOWED ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_STACKED ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_ROTATE_VALUE ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_ROTATE_MODE ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_LINEBREAK ) || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_MARGIN ) ); } const SvxSearchItem& ScGlobal::GetSearchItem() { if (!pSearchItem) { pSearchItem = new SvxSearchItem( SID_SEARCH_ITEM ); pSearchItem->SetAppFlag( SVX_SEARCHAPP_CALC ); } return *pSearchItem; } void ScGlobal::SetSearchItem( const SvxSearchItem& rNew ) { // Hier waere ein Zuweisungsoperator ganz nett: delete pSearchItem; pSearchItem = (SvxSearchItem*)rNew.Clone(); pSearchItem->SetWhich( SID_SEARCH_ITEM ); pSearchItem->SetAppFlag( SVX_SEARCHAPP_CALC ); } void ScGlobal::ClearAutoFormat() { if (pAutoFormat!=NULL) { delete pAutoFormat; pAutoFormat=NULL; } } ScAutoFormat* ScGlobal::GetAutoFormat() { if ( !pAutoFormat ) { pAutoFormat = new ScAutoFormat; pAutoFormat->Load(); } return pAutoFormat; } FuncCollection* ScGlobal::GetFuncCollection() { if (!pFuncCollection) pFuncCollection = new FuncCollection(); return pFuncCollection; } ScUnoAddInCollection* ScGlobal::GetAddInCollection() { if (!pAddInCollection) pAddInCollection = new ScUnoAddInCollection(); return pAddInCollection; } ScUserList* ScGlobal::GetUserList() { // Hack: Cfg-Item an der App ggF. laden global_InitAppOptions(); if (!pUserList) pUserList = new ScUserList(); return pUserList; } void ScGlobal::SetUserList( const ScUserList* pNewList ) { if ( pNewList ) { if ( !pUserList ) pUserList = new ScUserList( *pNewList ); else *pUserList = *pNewList; } else { delete pUserList; pUserList = NULL; } } const String& ScGlobal::GetRscString( sal_uInt16 nIndex ) { DBG_ASSERT( nIndex < STR_COUNT, "ScGlobal::GetRscString - invalid string index"); if( !ppRscString[ nIndex ] ) { OpCode eOp = ocNone; // Map former globstr.src strings moved to compiler.src switch (nIndex) { case STR_NULL_ERROR: eOp = ocErrNull; break; case STR_DIV_ZERO: eOp = ocErrDivZero; break; case STR_NO_VALUE: eOp = ocErrValue; break; case STR_NOREF_STR: eOp = ocErrRef; break; case STR_NO_NAME_REF: eOp = ocErrName; break; case STR_NUM_ERROR: eOp = ocErrNum; break; case STR_NV_STR: eOp = ocErrNA; break; default: ; // nothing } if (eOp != ocNone) ppRscString[ nIndex ] = new String( ScCompiler::GetNativeSymbol( eOp)); else ppRscString[ nIndex ] = new String( ScRscStrLoader( RID_GLOBSTR, nIndex ).GetString()); } return *ppRscString[ nIndex ]; } String ScGlobal::GetErrorString(sal_uInt16 nErrNumber) { String sResStr; switch (nErrNumber) { case NOTAVAILABLE : nErrNumber = STR_NV_STR; break; case errNoRef : nErrNumber = STR_NO_REF_TABLE; break; case errNoName : nErrNumber = STR_NO_NAME_REF; break; case errNoAddin : nErrNumber = STR_NO_ADDIN; break; case errNoMacro : nErrNumber = STR_NO_MACRO; break; case errDoubleRef : case errNoValue : nErrNumber = STR_NO_VALUE; break; case errNoCode : nErrNumber = STR_NULL_ERROR; break; case errDivisionByZero : nErrNumber = STR_DIV_ZERO; break; case errIllegalFPOperation : nErrNumber = STR_NUM_ERROR; break; default : sResStr = GetRscString(STR_ERROR_STR); sResStr += String::CreateFromInt32( nErrNumber ); nErrNumber = 0; break; } if( nErrNumber ) sResStr = GetRscString( nErrNumber ); return sResStr; } String ScGlobal::GetLongErrorString(sal_uInt16 nErrNumber) { switch (nErrNumber) { case 0: break; case 1: case errIllegalArgument: nErrNumber = STR_LONG_ERR_ILL_ARG; break; case 2: case 3: case 4: case 5: case errIllegalFPOperation: nErrNumber = STR_LONG_ERR_ILL_FPO; break; case errIllegalChar: nErrNumber = STR_LONG_ERR_ILL_CHAR; break; case errIllegalParameter: nErrNumber = STR_LONG_ERR_ILL_PAR; break; case errSeparator: nErrNumber = STR_LONG_ERR_ILL_SEP; break; case errPair: case errPairExpected: nErrNumber = STR_LONG_ERR_PAIR; break; case errOperatorExpected: nErrNumber = STR_LONG_ERR_OP_EXP; break; case errVariableExpected: case errParameterExpected: nErrNumber = STR_LONG_ERR_VAR_EXP; break; case errCodeOverflow: nErrNumber = STR_LONG_ERR_CODE_OVF; break; case errStringOverflow: nErrNumber = STR_LONG_ERR_STR_OVF; break; case errStackOverflow: case errInterpOverflow: nErrNumber = STR_LONG_ERR_STACK_OVF; break; case errIllegalJump: case errUnknownState: case errUnknownVariable: case errUnknownOpCode: case errUnknownStackVariable: case errUnknownToken: case errNoCode: case errDoubleRef: nErrNumber = STR_LONG_ERR_SYNTAX; break; case errCircularReference: nErrNumber = STR_LONG_ERR_CIRC_REF; break; case errNoConvergence: nErrNumber = STR_LONG_ERR_NO_CONV; break; case errNoRef: nErrNumber = STR_LONG_ERR_NO_REF; break; case errNoName: nErrNumber = STR_LONG_ERR_NO_NAME; break; case errNoAddin: nErrNumber = STR_LONG_ERR_NO_ADDIN; break; case errNoMacro: nErrNumber = STR_LONG_ERR_NO_MACRO; break; case errDivisionByZero: nErrNumber = STR_LONG_ERR_DIV_ZERO; break; case errNestedArray: nErrNumber = STR_ERR_LONG_NESTED_ARRAY; break; case errNoValue: nErrNumber = STR_LONG_ERR_NO_VALUE; break; case NOTAVAILABLE: nErrNumber = STR_LONG_ERR_NV; break; default: nErrNumber = STR_ERROR_STR; break; } String aRes( GetRscString( nErrNumber ) ); return aRes; } SvxBrushItem* ScGlobal::GetButtonBrushItem() { pButtonBrushItem->SetColor( Application::GetSettings().GetStyleSettings().GetFaceColor() ); return pButtonBrushItem; } const String& ScGlobal::GetEmptyString() { return *pEmptyString; } ImageList* ScGlobal::GetOutlineSymbols( bool bHC ) { ImageList*& rpImageList = bHC ? pOutlineBitmapsHC : pOutlineBitmaps; if( !rpImageList ) rpImageList = new ImageList( ScResId( bHC ? RID_OUTLINEBITMAPS_H : RID_OUTLINEBITMAPS ) ); return rpImageList; } void ScGlobal::Init() { pEmptyString = new String; // Die Default-Sprache fuer Zahlenformate (ScGlobal::eLnge) // muss immer LANGUAGE_SYSTEM sein //! Dann kann auch die Variable raus eLnge = LANGUAGE_SYSTEM; //! Wenn Sortierung etc. von der Sprache der installierten Offfice-Version //! abhaengen sollen, hier "Application::GetSettings().GetUILanguage()" pSysLocale = new SvtSysLocale; pCharClass = pSysLocale->GetCharClassPtr(); pLocaleData = pSysLocale->GetLocaleDataPtr(); ppRscString = new String *[ STR_COUNT ]; for( sal_uInt16 nC = 0 ; nC < STR_COUNT ; nC++ ) ppRscString[ nC ] = NULL; pEmptyBrushItem = new SvxBrushItem( Color( COL_TRANSPARENT ), ATTR_BACKGROUND ); pButtonBrushItem = new SvxBrushItem( Color(), ATTR_BACKGROUND ); pEmbeddedBrushItem = new SvxBrushItem( Color( COL_LIGHTCYAN ), ATTR_BACKGROUND ); pProtectedBrushItem = new SvxBrushItem( Color( COL_LIGHTGRAY ), ATTR_BACKGROUND ); UpdatePPT(NULL); //ScCompiler::InitSymbolsNative(); // ScParameterClassification _after_ Compiler, needs function resources if // arguments are to be merged in, which in turn need strings of function // names from the compiler. ScParameterClassification::Init(); srand( (unsigned) time( NULL ) ); // Random Seed Init fuer Interpreter InitAddIns(); pStrClipDocName = new String( ScResId( SCSTR_NONAME ) ); *pStrClipDocName += '1'; // ScDocumentPool::InitVersionMaps() ist schon vorher gerufen worden } void ScGlobal::UpdatePPT( OutputDevice* pDev ) { sal_uInt16 nCurrentZoom = Application::GetSettings().GetStyleSettings().GetScreenZoom(); if ( nCurrentZoom != nPPTZoom ) { // Screen PPT values must be updated when ScreenZoom has changed. // If called from Window::DataChanged, the window is passed as pDev, // to make sure LogicToPixel uses a device which already uses the new zoom. // For the initial settings, NULL is passed and GetDefaultDevice used. if ( !pDev ) pDev = Application::GetDefaultDevice(); Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP ); nScreenPPTX = aPix1000.X() / 1000.0; nScreenPPTY = aPix1000.Y() / 1000.0; nPPTZoom = nCurrentZoom; } } const String& ScGlobal::GetClipDocName() { return *pStrClipDocName; } void ScGlobal::SetClipDocName( const String& rNew ) { *pStrClipDocName = rNew; } void ScGlobal::InitTextHeight(SfxItemPool* pPool) { if (!pPool) { DBG_ERROR("kein Pool bei ScGlobal::InitTextHeight"); return; } const ScPatternAttr* pPattern = (const ScPatternAttr*)&pPool->GetDefaultItem(ATTR_PATTERN); if (!pPattern) { DBG_ERROR("kein Default-Pattern bei ScGlobal::InitTextHeight"); return; } // String aTestString('X'); OutputDevice* pDefaultDev = Application::GetDefaultDevice(); VirtualDevice aVirtWindow( *pDefaultDev ); aVirtWindow.SetMapMode(MAP_PIXEL); Font aDefFont; pPattern->GetFont(aDefFont, SC_AUTOCOL_BLACK, &aVirtWindow); // font color doesn't matter here aVirtWindow.SetFont(aDefFont); nDefFontHeight = (sal_uInt16) aVirtWindow.PixelToLogic(Size(0, aVirtWindow.GetTextHeight()), MAP_TWIP).Height(); const SvxMarginItem* pMargin = (const SvxMarginItem*)&pPattern->GetItem(ATTR_MARGIN); nStdRowHeight = (sal_uInt16) ( nDefFontHeight + pMargin->GetTopMargin() + pMargin->GetBottomMargin() - STD_ROWHEIGHT_DIFF ); } void ScGlobal::Clear() { // asyncs _vor_ ExitExternalFunc zerstoeren! theAddInAsyncTbl.DeleteAndDestroy( 0, theAddInAsyncTbl.Count() ); ExitExternalFunc(); DELETEZ(pAutoFormat); DELETEZ(pSearchItem); DELETEZ(pFuncCollection); DELETEZ(pAddInCollection); DELETEZ(pUserList); for( sal_uInt16 nC = 0 ; nC < STR_COUNT ; nC++ ) if( ppRscString ) delete ppRscString[ nC ]; delete[] ppRscString; ppRscString = NULL; DELETEZ(pStarCalcFunctionList); // vor ResMgr zerstoeren! DELETEZ(pStarCalcFunctionMgr); ScParameterClassification::Exit(); ScCompiler::DeInit(); ScInterpreter::GlobalExit(); // statischen Stack loeschen DELETEZ(pEmptyBrushItem); DELETEZ(pButtonBrushItem); DELETEZ(pEmbeddedBrushItem); DELETEZ(pProtectedBrushItem); DELETEZ(pOutlineBitmaps); DELETEZ(pOutlineBitmapsHC); // DELETEZ(pAnchorBitmap); // DELETEZ(pGrayAnchorBitmap); DELETEZ(pEnglishFormatter); DELETEZ(pCaseTransliteration); DELETEZ(pTransliteration); DELETEZ(pCaseCollator); DELETEZ(pCollator); DELETEZ(pCalendar); //! do NOT delete pCharClass since it is a pointer to the single SvtSysLocale instance pCharClass = NULL; //! do NOT delete pLocaleData since it is a pointer to the single SvtSysLocale instance pLocaleData = NULL; DELETEZ(pSysLocale); DELETEZ(pLocale); DELETEZ(pScIntlWrapper); DELETEZ(pStrClipDocName); DELETEZ(pUnitConverter); ScDocumentPool::DeleteVersionMaps(); DELETEZ(pEmptyString); } //------------------------------------------------------------------------ // static CharSet ScGlobal::GetCharsetValue( const String& rCharSet ) { // new TextEncoding values if ( CharClass::isAsciiNumeric( rCharSet ) ) { sal_Int32 nVal = rCharSet.ToInt32(); if ( !nVal || nVal == RTL_TEXTENCODING_DONTKNOW ) return gsl_getSystemTextEncoding(); return (CharSet) nVal; } // old CharSet values for compatibility else if (rCharSet.EqualsIgnoreCaseAscii("ANSI") ) return RTL_TEXTENCODING_MS_1252; else if (rCharSet.EqualsIgnoreCaseAscii("MAC") ) return RTL_TEXTENCODING_APPLE_ROMAN; else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC") ) return RTL_TEXTENCODING_IBM_850; else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_437")) return RTL_TEXTENCODING_IBM_437; else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_850")) return RTL_TEXTENCODING_IBM_850; else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_860")) return RTL_TEXTENCODING_IBM_860; else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_861")) return RTL_TEXTENCODING_IBM_861; else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_863")) return RTL_TEXTENCODING_IBM_863; else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_865")) return RTL_TEXTENCODING_IBM_865; // else if (rCharSet.EqualsIgnoreCaseAscii("SYSTEM") ) return gsl_getSystemTextEncoding(); else return gsl_getSystemTextEncoding(); } //------------------------------------------------------------------------ // static String ScGlobal::GetCharsetString( CharSet eVal ) { const sal_Char* pChar; switch ( eVal ) { // old CharSet strings for compatibility case RTL_TEXTENCODING_MS_1252: pChar = "ANSI"; break; case RTL_TEXTENCODING_APPLE_ROMAN: pChar = "MAC"; break; // IBMPC == IBMPC_850 case RTL_TEXTENCODING_IBM_437: pChar = "IBMPC_437"; break; case RTL_TEXTENCODING_IBM_850: pChar = "IBMPC_850"; break; case RTL_TEXTENCODING_IBM_860: pChar = "IBMPC_860"; break; case RTL_TEXTENCODING_IBM_861: pChar = "IBMPC_861"; break; case RTL_TEXTENCODING_IBM_863: pChar = "IBMPC_863"; break; case RTL_TEXTENCODING_IBM_865: pChar = "IBMPC_865"; break; case RTL_TEXTENCODING_DONTKNOW: pChar = "SYSTEM"; break; // new string of TextEncoding value default: return String::CreateFromInt32( eVal ); } return String::CreateFromAscii(pChar); } //------------------------------------------------------------------------ bool ScGlobal::HasStarCalcFunctionList() { return ( pStarCalcFunctionList != NULL ); } ScFunctionList* ScGlobal::GetStarCalcFunctionList() { if ( !pStarCalcFunctionList ) pStarCalcFunctionList = new ScFunctionList; return pStarCalcFunctionList; } //------------------------------------------------------------------------ ScFunctionMgr* ScGlobal::GetStarCalcFunctionMgr() { if ( !pStarCalcFunctionMgr ) pStarCalcFunctionMgr = new ScFunctionMgr; return pStarCalcFunctionMgr; } void ScGlobal::ResetFunctionList() { // FunctionMgr has pointers into FunctionList, must also be updated DELETEZ( pStarCalcFunctionMgr ); DELETEZ( pStarCalcFunctionList ); } //------------------------------------------------------------------------ // static ScUnitConverter* ScGlobal::GetUnitConverter() { if ( !pUnitConverter ) pUnitConverter = new ScUnitConverter; return pUnitConverter; } //------------------------------------------------------------------------ // static const sal_Unicode* ScGlobal::UnicodeStrChr( const sal_Unicode* pStr, sal_Unicode c ) { if ( !pStr ) return NULL; while ( *pStr ) { if ( *pStr == c ) return pStr; pStr++; } return NULL; } // ---------------------------------------------------------------------------- void ScGlobal::AddToken( String& rTokenList, const String& rToken, sal_Unicode cSep, xub_StrLen nSepCount, bool bForceSep ) { if( bForceSep || (rToken.Len() && rTokenList.Len()) ) rTokenList.Expand( rTokenList.Len() + nSepCount, cSep ); rTokenList.Append( rToken ); } bool ScGlobal::IsQuoted( const String& rString, sal_Unicode cQuote ) { return (rString.Len() >= 2) && (rString.GetChar( 0 ) == cQuote) && (rString.GetChar( rString.Len() - 1 ) == cQuote); } void ScGlobal::AddQuotes( String& rString, sal_Unicode cQuote, bool bEscapeEmbedded ) { if (bEscapeEmbedded) { sal_Unicode pQ[3]; pQ[0] = pQ[1] = cQuote; pQ[2] = 0; String aQuotes( pQ ); rString.SearchAndReplaceAll( cQuote, aQuotes); } rString.Insert( cQuote, 0 ).Append( cQuote ); } void ScGlobal::EraseQuotes( String& rString, sal_Unicode cQuote, bool bUnescapeEmbedded ) { if ( IsQuoted( rString, cQuote ) ) { rString.Erase( rString.Len() - 1 ).Erase( 0, 1 ); if (bUnescapeEmbedded) { sal_Unicode pQ[3]; pQ[0] = pQ[1] = cQuote; pQ[2] = 0; String aQuotes( pQ ); rString.SearchAndReplaceAll( aQuotes, cQuote); } } } xub_StrLen ScGlobal::FindUnquoted( const String& rString, sal_Unicode cChar, xub_StrLen nStart, sal_Unicode cQuote ) { const sal_Unicode* const pStart = rString.GetBuffer(); const sal_Unicode* const pStop = pStart + rString.Len(); const sal_Unicode* p = pStart + nStart; bool bQuoted = false; while (p < pStop) { if (*p == cChar && !bQuoted) return sal::static_int_cast< xub_StrLen >( p - pStart ); else if (*p == cQuote) { if (!bQuoted) bQuoted = true; else if (p < pStop-1 && *(p+1) == cQuote) ++p; else bQuoted = false; } ++p; } return STRING_NOTFOUND; } const sal_Unicode* ScGlobal::FindUnquoted( const sal_Unicode* pString, sal_Unicode cChar, sal_Unicode cQuote ) { const sal_Unicode* p = pString; bool bQuoted = false; while (*p) { if (*p == cChar && !bQuoted) return p; else if (*p == cQuote) { if (!bQuoted) bQuoted = true; else if (*(p+1) == cQuote) ++p; else bQuoted = false; } ++p; } return NULL; } //------------------------------------------------------------------------ sal_Bool ScGlobal::EETextObjEqual( const EditTextObject* pObj1, const EditTextObject* pObj2 ) { if ( pObj1 == pObj2 ) // both empty or the same object return sal_True; if ( pObj1 && pObj2 ) { // first test for equal text content sal_uInt32 nParCount = pObj1->GetParagraphCount(); if ( nParCount != pObj2->GetParagraphCount() ) return sal_False; for (sal_uInt32 nPar=0; nParGetText(nPar) != pObj2->GetText(nPar) ) return sal_False; SvMemoryStream aStream1; SvMemoryStream aStream2; pObj1->Store( aStream1 ); pObj2->Store( aStream2 ); sal_uLong nSize = aStream1.Tell(); if ( aStream2.Tell() == nSize ) if ( !memcmp( aStream1.GetData(), aStream2.GetData(), (sal_uInt16) nSize ) ) return sal_True; } return sal_False; } void ScGlobal::OpenURL( const String& rURL, const String& rTarget ) { // OpenURL wird immer ueber irgendwelche Umwege durch Mausklicks im GridWindow // aufgerufen, darum stimmen pScActiveViewShell und nScClickMouseModifier. SfxStringItem aUrl( SID_FILE_NAME, rURL ); SfxStringItem aTarget( SID_TARGETNAME, rTarget ); if ( nScClickMouseModifier & KEY_MOD1 ) // control-click -> into new window aTarget.SetValue( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("_blank")) ); SfxViewFrame* pFrame = NULL; String aReferName; if ( pScActiveViewShell ) { pFrame = pScActiveViewShell->GetViewFrame(); SfxMedium* pMed = pFrame->GetObjectShell()->GetMedium(); if (pMed) aReferName = pMed->GetName(); } SfxFrameItem aFrm( SID_DOCFRAME, pFrame ); SfxStringItem aReferer( SID_REFERER, aReferName ); SfxBoolItem aNewView( SID_OPEN_NEW_VIEW, sal_False ); SfxBoolItem aBrowsing( SID_BROWSE, sal_True ); // kein SID_SILENT mehr wegen Bug #42525# (war angeblich sowieso falsch) SfxViewFrame* pViewFrm = SfxViewFrame::Current(); if (pViewFrm) pViewFrm->GetDispatcher()->Execute( SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aUrl, &aTarget, &aFrm, &aReferer, &aNewView, &aBrowsing, 0L ); } //------------------------------------------------------------------------ sal_Bool ScGlobal::IsSystemRTL() { return MsLangId::isRightToLeft( Application::GetSettings().GetLanguage() ); } sal_uInt8 ScGlobal::GetDefaultScriptType() { // Used when text contains only WEAK characters. // Script type of office language is used then (same as GetEditDefaultLanguage, // to get consistent behavior of text in simple cells and EditEngine, // also same as GetAppLanguage() in Writer) return (sal_uInt8) SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguage() ); } LanguageType ScGlobal::GetEditDefaultLanguage() { // used for EditEngine::SetDefaultLanguage return Application::GetSettings().GetLanguage(); } sal_uInt16 ScGlobal::GetScriptedWhichID( sal_uInt8 nScriptType, sal_uInt16 nWhich ) { switch ( nScriptType ) { case SCRIPTTYPE_LATIN: case SCRIPTTYPE_ASIAN: case SCRIPTTYPE_COMPLEX: break; // take exact matches default: // prefer one, first COMPLEX, then ASIAN if ( nScriptType & SCRIPTTYPE_COMPLEX ) nScriptType = SCRIPTTYPE_COMPLEX; else if ( nScriptType & SCRIPTTYPE_ASIAN ) nScriptType = SCRIPTTYPE_ASIAN; } switch ( nScriptType ) { case SCRIPTTYPE_COMPLEX: { switch ( nWhich ) { case ATTR_FONT: case ATTR_CJK_FONT: nWhich = ATTR_CTL_FONT; break; case ATTR_FONT_HEIGHT: case ATTR_CJK_FONT_HEIGHT: nWhich = ATTR_CTL_FONT_HEIGHT; break; case ATTR_FONT_WEIGHT: case ATTR_CJK_FONT_WEIGHT: nWhich = ATTR_CTL_FONT_WEIGHT; break; case ATTR_FONT_POSTURE: case ATTR_CJK_FONT_POSTURE: nWhich = ATTR_CTL_FONT_POSTURE; break; } } break; case SCRIPTTYPE_ASIAN: { switch ( nWhich ) { case ATTR_FONT: case ATTR_CTL_FONT: nWhich = ATTR_CJK_FONT; break; case ATTR_FONT_HEIGHT: case ATTR_CTL_FONT_HEIGHT: nWhich = ATTR_CJK_FONT_HEIGHT; break; case ATTR_FONT_WEIGHT: case ATTR_CTL_FONT_WEIGHT: nWhich = ATTR_CJK_FONT_WEIGHT; break; case ATTR_FONT_POSTURE: case ATTR_CTL_FONT_POSTURE: nWhich = ATTR_CJK_FONT_POSTURE; break; } } break; default: { switch ( nWhich ) { case ATTR_CTL_FONT: case ATTR_CJK_FONT: nWhich = ATTR_FONT; break; case ATTR_CTL_FONT_HEIGHT: case ATTR_CJK_FONT_HEIGHT: nWhich = ATTR_FONT_HEIGHT; break; case ATTR_CTL_FONT_WEIGHT: case ATTR_CJK_FONT_WEIGHT: nWhich = ATTR_FONT_WEIGHT; break; case ATTR_CTL_FONT_POSTURE: case ATTR_CJK_FONT_POSTURE: nWhich = ATTR_FONT_POSTURE; break; } } } return nWhich; } //------------------------------------------------------------------------ void ScGlobal::AddLanguage( SfxItemSet& rSet, SvNumberFormatter& rFormatter ) { DBG_ASSERT( rSet.GetItemState( ATTR_LANGUAGE_FORMAT, sal_False ) == SFX_ITEM_DEFAULT, "ScGlobal::AddLanguage - language already added"); const SfxPoolItem* pHardItem; if ( rSet.GetItemState( ATTR_VALUE_FORMAT, sal_False, &pHardItem ) == SFX_ITEM_SET ) { const SvNumberformat* pHardFormat = rFormatter.GetEntry( ((const SfxUInt32Item*)pHardItem)->GetValue() ); sal_uLong nParentFmt = 0; // pool default const SfxItemSet* pParent = rSet.GetParent(); if ( pParent ) nParentFmt = ((const SfxUInt32Item&)pParent->Get( ATTR_VALUE_FORMAT )).GetValue(); const SvNumberformat* pParFormat = rFormatter.GetEntry( nParentFmt ); if ( pHardFormat && pParFormat && (pHardFormat->GetLanguage() != pParFormat->GetLanguage()) ) rSet.Put( SvxLanguageItem( pHardFormat->GetLanguage(), ATTR_LANGUAGE_FORMAT ) ); } } //=================================================================== // class ScFunctionList: //=================================================================== //=================================================================== // class ScFuncRes // fuer temporaere Objekte zum Holen der Resourcen class ScFuncRes : public Resource { public: ScFuncRes( ResId&, ScFuncDesc*, bool & rbSuppressed ); private: sal_uInt16 GetNum(); }; //-------------------------------------------------------------------- ScFuncRes::ScFuncRes( ResId &aRes, ScFuncDesc* pDesc, bool & rbSuppressed ) : Resource(aRes) { rbSuppressed = (bool)GetNum(); pDesc->nCategory = GetNum(); pDesc->sHelpId = ReadByteStringRes(); //! Hack, see scfuncs.src pDesc->nArgCount = GetNum(); sal_uInt16 nArgs = pDesc->nArgCount; if (nArgs >= PAIRED_VAR_ARGS) nArgs -= PAIRED_VAR_ARGS - 2; else if (nArgs >= VAR_ARGS) nArgs -= VAR_ARGS - 1; if (nArgs) { pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs]; for (sal_uInt16 i = 0; i < nArgs; i++) { pDesc->pDefArgFlags[i].bOptional = (bool)GetNum(); } } // Need to read the value from the resource even if nArgs==0 to advance the // resource position pointer, so this can't be in the if(nArgs) block above. sal_uInt16 nSuppressed = GetNum(); if (nSuppressed) { if (nSuppressed > nArgs) { DBG_ERROR3( "ScFuncRes: suppressed parameters count mismatch on OpCode %u: suppressed %d > params %d", aRes.GetId(), (int)nSuppressed, (int)nArgs); nSuppressed = nArgs; // sanitize } for (sal_uInt16 i=0; i < nSuppressed; ++i) { sal_uInt16 nParam = GetNum(); if (nParam < nArgs) { if (pDesc->nArgCount >= PAIRED_VAR_ARGS && nParam >= nArgs-2) { DBG_ERROR3( "ScFuncRes: PAIRED_VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d >= arg %d-2", aRes.GetId(), (int)nParam, (int)nArgs); } else if (pDesc->nArgCount >= VAR_ARGS && nParam == nArgs-1) { DBG_ERROR3( "ScFuncRes: VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d == arg %d-1", aRes.GetId(), (int)nParam, (int)nArgs); } else { pDesc->pDefArgFlags[nParam].bSuppress = true; pDesc->bHasSuppressedArgs = true; } } else { DBG_ERROR3( "ScFuncRes: suppressed parameter exceeds count on OpCode %u: param %d >= args %d", aRes.GetId(), (int)nParam, (int)nArgs); } } } pDesc->pFuncName = new String( ScCompiler::GetNativeSymbol( static_cast( aRes.GetId()))); pDesc->pFuncDesc = new String(ScResId(1)); if (nArgs) { pDesc->ppDefArgNames = new String*[nArgs]; pDesc->ppDefArgDescs = new String*[nArgs]; for (sal_uInt16 i = 0; i < nArgs; i++) { pDesc->ppDefArgNames[i] = new String(ScResId(2*(i+1) )); pDesc->ppDefArgDescs[i] = new String(ScResId(2*(i+1)+1)); } } FreeResource(); } //------------------------------------------------------------------------ sal_uInt16 ScFuncRes::GetNum() { return ReadShortRes(); } //========================================================================= // um an die protected von Resource ranzukommen class ScResourcePublisher : public Resource { private: void FreeResource() { Resource::FreeResource(); } public: ScResourcePublisher( const ScResId& rId ) : Resource( rId ) {} ~ScResourcePublisher() { FreeResource(); } sal_Bool IsAvailableRes( const ResId& rId ) const { return Resource::IsAvailableRes( rId ); } }; ScFunctionList::ScFunctionList() : nMaxFuncNameLen ( 0 ) { ScFuncDesc* pDesc = NULL; xub_StrLen nStrLen = 0; FuncCollection* pFuncColl; sal_uInt16 i,j; sal_uInt16 nDescBlock[] = { RID_SC_FUNCTION_DESCRIPTIONS1, RID_SC_FUNCTION_DESCRIPTIONS2 }; const sal_uInt16 nBlocks = sizeof(nDescBlock) / sizeof(sal_uInt16); aFunctionList.Clear(); for ( sal_uInt16 k = 0; k < nBlocks; k++ ) { ::std::auto_ptr pBlock( new ScResourcePublisher( ScResId( nDescBlock[k] ) ) ); // Browse for all possible OpCodes. This is not the fastest method, but // otherwise the sub resources within the resource blocks and the // resource blocks themselves would had to be ordered according to // OpCodes, which is utopian.. for (i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; i++) { ScResId aRes(i); aRes.SetRT(RSC_RESOURCE); // Sub resource of OpCode available? if (pBlock->IsAvailableRes(aRes)) { pDesc = new ScFuncDesc; bool bSuppressed = false; ScFuncRes aSubRes( aRes, pDesc, bSuppressed); // Instead of dealing with this exceptional case at 1001 places // we simply don't add an entirely suppressed function to the // list and delete it. if (bSuppressed) delete pDesc; else { pDesc->nFIndex = i; aFunctionList.Insert( pDesc, LIST_APPEND ); nStrLen = (*(pDesc->pFuncName)).Len(); if (nStrLen > nMaxFuncNameLen) nMaxFuncNameLen = nStrLen; } } } } sal_uInt16 nNextId = SC_OPCODE_LAST_OPCODE_ID + 1; // FuncID for AddIn functions // Auswertung AddIn-Liste String aDefArgNameValue(RTL_CONSTASCII_STRINGPARAM("value")); String aDefArgNameString(RTL_CONSTASCII_STRINGPARAM("string")); String aDefArgNameValues(RTL_CONSTASCII_STRINGPARAM("values")); String aDefArgNameStrings(RTL_CONSTASCII_STRINGPARAM("strings")); String aDefArgNameCells(RTL_CONSTASCII_STRINGPARAM("cells")); String aDefArgNameNone(RTL_CONSTASCII_STRINGPARAM("none")); String aDefArgDescValue(RTL_CONSTASCII_STRINGPARAM("a value")); String aDefArgDescString(RTL_CONSTASCII_STRINGPARAM("a string")); String aDefArgDescValues(RTL_CONSTASCII_STRINGPARAM("array of values")); String aDefArgDescStrings(RTL_CONSTASCII_STRINGPARAM("array of strings")); String aDefArgDescCells(RTL_CONSTASCII_STRINGPARAM("range of cells")); String aDefArgDescNone(RTL_CONSTASCII_STRINGPARAM("none")); String aArgName, aArgDesc; pFuncColl = ScGlobal::GetFuncCollection(); for (i = 0; i < pFuncColl->GetCount(); i++) { pDesc = new ScFuncDesc; FuncData *pAddInFuncData = (FuncData*)pFuncColl->At(i); sal_uInt16 nArgs = pAddInFuncData->GetParamCount() - 1; pAddInFuncData->GetParamDesc( aArgName, aArgDesc, 0 ); pDesc->nFIndex = nNextId++; // ??? OpCode vergeben pDesc->nCategory = ID_FUNCTION_GRP_ADDINS; pDesc->pFuncName = new String(pAddInFuncData->GetInternalName()); pDesc->pFuncName->ToUpperAscii(); pDesc->pFuncDesc = new String( aArgDesc ); *(pDesc->pFuncDesc) += '\n'; pDesc->pFuncDesc->AppendAscii(RTL_CONSTASCII_STRINGPARAM( "( AddIn: " )); *(pDesc->pFuncDesc) += pAddInFuncData->GetModuleName(); pDesc->pFuncDesc->AppendAscii(RTL_CONSTASCII_STRINGPARAM( " )" )); pDesc->nArgCount = nArgs; if (nArgs) { pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs]; pDesc->ppDefArgNames = new String*[nArgs]; pDesc->ppDefArgDescs = new String*[nArgs]; for (j = 0; j < nArgs; j++) { pDesc->pDefArgFlags[j].bOptional = false; pDesc->pDefArgFlags[j].bSuppress = false; pAddInFuncData->GetParamDesc( aArgName, aArgDesc, j+1 ); if ( aArgName.Len() ) pDesc->ppDefArgNames[j] = new String( aArgName ); else { switch (pAddInFuncData->GetParamType(j+1)) { case PTR_DOUBLE: pDesc->ppDefArgNames[j] = new String( aDefArgNameValue ); break; case PTR_STRING: pDesc->ppDefArgNames[j] = new String( aDefArgNameString ); break; case PTR_DOUBLE_ARR: pDesc->ppDefArgNames[j] = new String( aDefArgNameValues ); break; case PTR_STRING_ARR: pDesc->ppDefArgNames[j] = new String( aDefArgNameStrings ); break; case PTR_CELL_ARR: pDesc->ppDefArgNames[j] = new String( aDefArgNameCells ); break; default: pDesc->ppDefArgNames[j] = new String( aDefArgNameNone ); break; } } if ( aArgDesc.Len() ) pDesc->ppDefArgDescs[j] = new String( aArgDesc ); else { switch (pAddInFuncData->GetParamType(j+1)) { case PTR_DOUBLE: pDesc->ppDefArgDescs[j] = new String( aDefArgDescValue ); break; case PTR_STRING: pDesc->ppDefArgDescs[j] = new String( aDefArgDescString ); break; case PTR_DOUBLE_ARR: pDesc->ppDefArgDescs[j] = new String( aDefArgDescValues ); break; case PTR_STRING_ARR: pDesc->ppDefArgDescs[j] = new String( aDefArgDescStrings ); break; case PTR_CELL_ARR: pDesc->ppDefArgDescs[j] = new String( aDefArgDescCells ); break; default: pDesc->ppDefArgDescs[j] = new String( aDefArgDescNone ); break; } } } } // pDesc->nHelpId = 0; aFunctionList.Insert(pDesc, LIST_APPEND); nStrLen = (*(pDesc->pFuncName)).Len(); if ( nStrLen > nMaxFuncNameLen) nMaxFuncNameLen = nStrLen; } // StarOne AddIns ScUnoAddInCollection* pUnoAddIns = ScGlobal::GetAddInCollection(); long nUnoCount = pUnoAddIns->GetFuncCount(); for (long nFunc=0; nFuncnFIndex = nNextId++; if ( pUnoAddIns->FillFunctionDesc( nFunc, *pDesc ) ) { aFunctionList.Insert(pDesc, LIST_APPEND); nStrLen = (*(pDesc->pFuncName)).Len(); if (nStrLen > nMaxFuncNameLen) nMaxFuncNameLen = nStrLen; } else delete pDesc; } } //------------------------------------------------------------------------ ScFunctionList::~ScFunctionList() { const ScFuncDesc* pDesc = First(); while (pDesc) { delete pDesc; pDesc = Next(); } } //======================================================================== // class ScFuncDesc: ScFuncDesc::ScFuncDesc() : pFuncName (NULL), pFuncDesc (NULL), ppDefArgNames (NULL), ppDefArgDescs (NULL), pDefArgFlags (NULL), nFIndex (0), nCategory (0), nArgCount (0), bIncomplete (false), bHasSuppressedArgs(false) {} //------------------------------------------------------------------------ ScFuncDesc::~ScFuncDesc() { Clear(); } //------------------------------------------------------------------------ void ScFuncDesc::Clear() { sal_uInt16 nArgs = nArgCount; if (nArgs >= PAIRED_VAR_ARGS) nArgs -= PAIRED_VAR_ARGS - 2; else if (nArgs >= VAR_ARGS) nArgs -= VAR_ARGS - 1; if (nArgs) { for (sal_uInt16 i=0; i 0 ) { if ( nArgCount < VAR_ARGS ) { sal_uInt16 nLastSuppressed = nArgCount; sal_uInt16 nLastAdded = nArgCount; for ( sal_uInt16 i=0; i= 2) aSig.Erase( aSig.Len() - 2 ); } else if ( nArgCount < PAIRED_VAR_ARGS) { sal_uInt16 nFix = nArgCount - VAR_ARGS; for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ ) { if (!pDefArgFlags[nArg].bSuppress) { aSig += *(ppDefArgNames[nArg]); aSig.Append(sep); aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " )); } } /* NOTE: Currently there are no suppressed var args parameters. If * there were, we'd have to cope with it here and above for the fix * parameters. For now parameters are always added, so no special * treatment of a trailing "; " necessary. */ aSig += *(ppDefArgNames[nFix]); aSig += '1'; aSig.Append(sep); aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " )); aSig += *(ppDefArgNames[nFix]); aSig += '2'; aSig.Append(sep); aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ... " )); } else { sal_uInt16 nFix = nArgCount - PAIRED_VAR_ARGS; for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ ) { if (!pDefArgFlags[nArg].bSuppress) { aSig += *(ppDefArgNames[nArg]); aSig.Append(sep); aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " )); } } aSig += *(ppDefArgNames[nFix]); aSig += '1'; aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ", " )); aSig += *(ppDefArgNames[nFix+1]); aSig += '1'; aSig.Append(sep); aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " )); aSig += *(ppDefArgNames[nFix]); aSig += '2'; aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ", " )); aSig += *(ppDefArgNames[nFix+1]); aSig += '2'; aSig.Append(sep); aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ... " )); } } return aSig; } //------------------------------------------------------------------------ String ScFuncDesc::GetSignature() const { String aSig; if(pFuncName) { aSig = *pFuncName; String aParamList( GetParamList() ); if( aParamList.Len() ) { aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "( " )); aSig.Append( aParamList ); // U+00A0 (NBSP) prevents automatic line break aSig.Append( static_cast< sal_Unicode >(0xA0) ).Append( ')' ); } else aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" )); } return aSig; } //------------------------------------------------------------------------ ::rtl::OUString ScFuncDesc::getFormula( const ::std::vector< ::rtl::OUString >& _aArguments ) const { const String& sep = ScCompiler::GetNativeSymbol(ocSep); ::rtl::OUStringBuffer aFormula; if(pFuncName) { aFormula.append( *pFuncName ); aFormula.appendAscii( "(" ); ::std::vector< ::rtl::OUString >::const_iterator aIter = _aArguments.begin(); ::std::vector< ::rtl::OUString >::const_iterator aEnd = _aArguments.end(); if ( nArgCount > 0 && aIter != aEnd ) { sal_Bool bLastArg = ( aIter->getLength() == 0 ); while( aIter != aEnd && !bLastArg ) { aFormula.append( *(aIter) ); if ( aIter != (aEnd-1) ) { bLastArg = !( (aIter+1)->getLength() > 0 ); if ( !bLastArg ) aFormula.append( sep ); } ++aIter; } } aFormula.appendAscii( ")" ); } return aFormula.makeStringAndClear(); } //------------------------------------------------------------------------ sal_uInt16 ScFuncDesc::GetSuppressedArgCount() const { if (!bHasSuppressedArgs || !pDefArgFlags) return nArgCount; sal_uInt16 nArgs = nArgCount; if (nArgs >= PAIRED_VAR_ARGS) nArgs -= PAIRED_VAR_ARGS - 2; else if (nArgs >= VAR_ARGS) nArgs -= VAR_ARGS - 1; sal_uInt16 nCount = nArgs; for (sal_uInt16 i=0; i < nArgs; ++i) { if (pDefArgFlags[i].bSuppress) --nCount; } if (nArgCount >= PAIRED_VAR_ARGS) nCount += PAIRED_VAR_ARGS - 2; else if (nArgCount >= VAR_ARGS) nCount += VAR_ARGS - 1; return nCount; } //------------------------------------------------------------------------ ::rtl::OUString ScFuncDesc::getFunctionName() const { ::rtl::OUString sRet; if ( pFuncName ) sRet = *pFuncName; return sRet; } // ----------------------------------------------------------------------------- const formula::IFunctionCategory* ScFuncDesc::getCategory() const { return ScGlobal::GetStarCalcFunctionMgr()->getCategory(nCategory); } // ----------------------------------------------------------------------------- ::rtl::OUString ScFuncDesc::getDescription() const { ::rtl::OUString sRet; if ( pFuncDesc ) sRet = *pFuncDesc; return sRet; } // ----------------------------------------------------------------------------- // GetSuppressedArgCount xub_StrLen ScFuncDesc::getSuppressedArgumentCount() const { return GetSuppressedArgCount(); } // ----------------------------------------------------------------------------- // void ScFuncDesc::fillVisibleArgumentMapping(::std::vector& _rArguments) const { if (!bHasSuppressedArgs || !pDefArgFlags) { _rArguments.resize( nArgCount); ::std::vector::iterator it = _rArguments.begin(); for( sal_uInt16 n = 0; n < nArgCount; ++n, ++it ) *it = n; } _rArguments.reserve( nArgCount); sal_uInt16 nArgs = nArgCount; if (nArgs >= PAIRED_VAR_ARGS) nArgs -= PAIRED_VAR_ARGS - 2; else if (nArgs >= VAR_ARGS) nArgs -= VAR_ARGS - 1; for (sal_uInt16 i=0; i < nArgs; ++i) { if (!pDefArgFlags[i].bSuppress) _rArguments.push_back(i); } } // ----------------------------------------------------------------------------- void ScFuncDesc::initArgumentInfo() const { // get the full argument description // (add-in has to be instantiated to get the type information) if ( bIncomplete && pFuncName ) { ScUnoAddInCollection& rAddIns = *ScGlobal::GetAddInCollection(); String aIntName = rAddIns.FindFunction( *pFuncName, sal_True ); // pFuncName is upper-case if ( aIntName.Len() ) { // GetFuncData with bComplete=true loads the component and updates // the global function list if needed. rAddIns.GetFuncData( aIntName, true ); } if ( bIncomplete ) { DBG_ERRORFILE( "couldn't initialize add-in function" ); const_cast(this)->bIncomplete = sal_False; // even if there was an error, don't try again } } } // ----------------------------------------------------------------------------- ::rtl::OUString ScFuncDesc::getSignature() const { return GetSignature(); } // ----------------------------------------------------------------------------- rtl::OString ScFuncDesc::getHelpId() const { return sHelpId; } // ----------------------------------------------------------------------------- // parameter sal_uInt32 ScFuncDesc::getParameterCount() const { return nArgCount; } // ----------------------------------------------------------------------------- ::rtl::OUString ScFuncDesc::getParameterName(sal_uInt32 _nPos) const { return *(ppDefArgNames[_nPos]); } // ----------------------------------------------------------------------------- ::rtl::OUString ScFuncDesc::getParameterDescription(sal_uInt32 _nPos) const { return *(ppDefArgDescs[_nPos]); } // ----------------------------------------------------------------------------- bool ScFuncDesc::isParameterOptional(sal_uInt32 _nPos) const { return pDefArgFlags[_nPos].bOptional; } // ----------------------------------------------------------------------------- //======================================================================== // class ScFunctionMgr: ScFunctionMgr::ScFunctionMgr() : pFuncList ( ScGlobal::GetStarCalcFunctionList() ), pCurCatList ( NULL ) { DBG_ASSERT( pFuncList, "Funktionsliste nicht gefunden." ); sal_uLong nCount = pFuncList->GetCount(); const ScFuncDesc* pDesc; List* pRootList; sal_uLong n; for ( sal_uInt16 i=0; iGetFunction(n); for (nTmpCnt = 0; nTmpCnt < n; nTmpCnt++) { // ist zwar case-sensitiv, aber Umlaute muessen richtig einsortiert werden const ScFuncDesc* pTmpDesc = (const ScFuncDesc*)pRootList->GetObject(nTmpCnt); if ( pCaseCollator->compareString(*pDesc->pFuncName, *pTmpDesc->pFuncName ) == COMPARE_LESS ) break; } pRootList->Insert((void*)pDesc, nTmpCnt); // Einsortieren } for ( n=0; nGetObject(n); DBG_ASSERT((pDesc->nCategory) < MAX_FUNCCAT, "Unbekannte Kategorie"); if ((pDesc->nCategory) < MAX_FUNCCAT) aCatLists[pDesc->nCategory]->Insert((void*)pDesc, LIST_APPEND); } } //------------------------------------------------------------------------ ScFunctionMgr::~ScFunctionMgr() { for (sal_uInt16 i = 0; i < MAX_FUNCCAT; i++) delete aCatLists[i]; // delete pFuncList; // Macht spaeter die App } //------------------------------------------------------------------------ const ScFuncDesc* ScFunctionMgr::Get( const String& rFName ) const { const ScFuncDesc* pDesc = NULL; if (rFName.Len() <= pFuncList->GetMaxFuncNameLen()) for (pDesc = First(0); pDesc; pDesc = Next()) if (rFName.EqualsIgnoreCaseAscii(*(pDesc->pFuncName))) break; return pDesc; } //------------------------------------------------------------------------ const ScFuncDesc* ScFunctionMgr::Get( sal_uInt16 nFIndex ) const { const ScFuncDesc* pDesc; for (pDesc = First(0); pDesc; pDesc = Next()) if (pDesc->nFIndex == nFIndex) break; return pDesc; } //------------------------------------------------------------------------ const ScFuncDesc* ScFunctionMgr::First( sal_uInt16 nCategory ) const { DBG_ASSERT( nCategory < MAX_FUNCCAT, "Unbekannte Kategorie" ); if ( nCategory < MAX_FUNCCAT ) { pCurCatList = aCatLists[nCategory]; return (const ScFuncDesc*)pCurCatList->First(); } else { pCurCatList = NULL; return NULL; } } //------------------------------------------------------------------------ const ScFuncDesc* ScFunctionMgr::Next() const { if ( pCurCatList ) return (const ScFuncDesc*)pCurCatList->Next(); else return NULL; } sal_uInt32 ScFunctionMgr::getCount() const { return MAX_FUNCCAT - 1; } const formula::IFunctionCategory* ScFunctionMgr::getCategory(sal_uInt32 nCategory) const { formula::IFunctionCategory* pRet = NULL; if ( nCategory < (MAX_FUNCCAT-1) ) { pRet = new ScFunctionCategory(const_cast(this),aCatLists[nCategory+1],nCategory); // aCatLists[0] is "all" } return pRet; } // ----------------------------------------------------------------------------- const formula::IFunctionDescription* ScFunctionMgr::getFunctionByName(const ::rtl::OUString& _sFunctionName) const { return Get(_sFunctionName); } // ----------------------------------------------------------------------------- void ScFunctionMgr::fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& _rLastRUFunctions) const { #define LRU_MAX 10 const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions(); sal_uInt16 nLRUFuncCount = Min( rAppOpt.GetLRUFuncListCount(), (sal_uInt16)LRU_MAX ); sal_uInt16* pLRUListIds = rAppOpt.GetLRUFuncList(); if ( pLRUListIds ) { for ( sal_uInt16 i=0; i SC_FUNCGROUP_COUNT ) { DBG_ERROR("Invalid category number!"); return String(); } // if ( _nCategoryNumber >= SC_FUNCGROUP_COUNT ) ::std::auto_ptr pCategories( new ScResourcePublisher( ScResId( RID_FUNCTION_CATEGORIES ) ) ); return String(ScResId((sal_uInt16)_nCategoryNumber)); } sal_Unicode ScFunctionMgr::getSingleToken(const formula::IFunctionManager::EToken _eToken) const { switch(_eToken) { case eOk: return ScCompiler::GetNativeSymbol(ocOpen).GetChar(0); case eClose: return ScCompiler::GetNativeSymbol(ocClose).GetChar(0); case eSep: return ScCompiler::GetNativeSymbol(ocSep).GetChar(0); case eArrayOpen: return ScCompiler::GetNativeSymbol(ocArrayOpen).GetChar(0); case eArrayClose: return ScCompiler::GetNativeSymbol(ocArrayClose).GetChar(0); } // switch(_eToken) return 0; } // ----------------------------------------------------------------------------- sal_uInt32 ScFunctionCategory::getCount() const { return m_pCategory->Count(); } // ----------------------------------------------------------------------------- const formula::IFunctionManager* ScFunctionCategory::getFunctionManager() const { return m_pMgr; } // ----------------------------------------------------------------------------- ::rtl::OUString ScFunctionCategory::getName() const { if ( !m_sName.getLength() ) m_sName = ScFunctionMgr::GetCategoryName(m_nCategory+1); return m_sName; } // ----------------------------------------------------------------------------- const formula::IFunctionDescription* ScFunctionCategory::getFunction(sal_uInt32 _nPos) const { const ScFuncDesc* pDesc = NULL; sal_uInt32 i = 0; for (pDesc = (const ScFuncDesc*)m_pCategory->First(); i < _nPos && pDesc; pDesc = (const ScFuncDesc*)m_pCategory->Next(),++i) ; return pDesc; } // ----------------------------------------------------------------------------- sal_uInt32 ScFunctionCategory::getNumber() const { return m_nCategory; } // ----------------------------------------------------------------------------- //------------------------------------------------------------------------ utl::TransliterationWrapper* ScGlobal::GetpTransliteration() //add by CHINA001 { if ( !pTransliteration ) { const LanguageType eOfficeLanguage = Application::GetSettings().GetLanguage(); pTransliteration = new ::utl::TransliterationWrapper( ::comphelper::getProcessServiceFactory(), SC_TRANSLITERATION_IGNORECASE ); pTransliteration->loadModuleIfNeeded( eOfficeLanguage ); } DBG_ASSERT( pTransliteration, "ScGlobal::GetpTransliteration() called before ScGlobal::Init()"); return pTransliteration; } const LocaleDataWrapper* ScGlobal::GetpLocaleData() { DBG_ASSERT( pLocaleData, "ScGlobal::GetpLocaleData() called before ScGlobal::Init()"); return pLocaleData; } CalendarWrapper* ScGlobal::GetCalendar() { if ( !pCalendar ) { pCalendar = new CalendarWrapper( ::comphelper::getProcessServiceFactory() ); pCalendar->loadDefaultCalendar( *GetLocale() ); } return pCalendar; } CollatorWrapper* ScGlobal::GetCollator() { if ( !pCollator ) { pCollator = new CollatorWrapper( ::comphelper::getProcessServiceFactory() ); pCollator->loadDefaultCollator( *GetLocale(), SC_COLLATOR_IGNORES ); } // if ( !pCollator ) return pCollator; } CollatorWrapper* ScGlobal::GetCaseCollator() { if ( !pCaseCollator ) { pCaseCollator = new CollatorWrapper( ::comphelper::getProcessServiceFactory() ); pCaseCollator->loadDefaultCollator( *GetLocale(), 0 ); } // if ( !pCaseCollator ) return pCaseCollator; } ::utl::TransliterationWrapper* ScGlobal::GetCaseTransliteration() { if ( !pCaseTransliteration ) { const LanguageType eOfficeLanguage = Application::GetSettings().GetLanguage(); pCaseTransliteration = new ::utl::TransliterationWrapper(::comphelper::getProcessServiceFactory(), SC_TRANSLITERATION_CASESENSE ); pCaseTransliteration->loadModuleIfNeeded( eOfficeLanguage ); } // if ( !pCaseTransliteration ) return pCaseTransliteration; } IntlWrapper* ScGlobal::GetScIntlWrapper() { if ( !pScIntlWrapper ) { pScIntlWrapper = new IntlWrapper( ::comphelper::getProcessServiceFactory(), *GetLocale() ); } return pScIntlWrapper; } ::com::sun::star::lang::Locale* ScGlobal::GetLocale() { if ( !pLocale ) { pLocale = new ::com::sun::star::lang::Locale( Application::GetSettings().GetLocale()); } return pLocale; }