| /************************************************************** |
| * |
| * 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 <vcl/svapp.hxx> |
| #include "scitems.hxx" |
| #include <svx/algitem.hxx> |
| #include <editeng/brshitem.hxx> |
| #include <editeng/editobj.hxx> |
| #include <editeng/scripttypeitem.hxx> |
| #include <svl/srchitem.hxx> |
| #include <editeng/langitem.hxx> |
| #include <sfx2/docfile.hxx> |
| #include <sfx2/dispatch.hxx> |
| #include <sfx2/objsh.hxx> |
| #include <sfx2/viewfrm.hxx> |
| #include <sfx2/viewsh.hxx> |
| #include <svl/stritem.hxx> |
| #include <svl/zforlist.hxx> |
| #include <svl/zformat.hxx> |
| #include <vcl/image.hxx> |
| #include <vcl/virdev.hxx> |
| #include <tools/rcid.h> |
| #include <unotools/charclass.hxx> |
| #include <stdlib.h> |
| #include <time.h> |
| #include <ctype.h> |
| #include <numeric> |
| |
| |
| #include <i18npool/mslangid.hxx> |
| #include <com/sun/star/lang/Locale.hpp> |
| #include <comphelper/processfactory.hxx> |
| #include <unotools/calendarwrapper.hxx> |
| #include <unotools/collatorwrapper.hxx> |
| #include <com/sun/star/i18n/CollatorOptions.hpp> |
| #include <unotools/intlwrapper.hxx> |
| #include <unotools/syslocale.hxx> |
| #include <unotools/transliterationwrapper.hxx> |
| |
| #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<sal_Bool>(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_uInt16 nParCount = pObj1->GetParagraphCount(); |
| if ( nParCount != pObj2->GetParagraphCount() ) |
| return sal_False; |
| for (sal_uInt16 nPar=0; nPar<nParCount; nPar++) |
| if ( pObj1->GetText(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<OpCode>( 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<ScResourcePublisher> 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 themselfs 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; nFunc<nUnoCount; nFunc++) |
| { |
| pDesc = new ScFuncDesc; |
| pDesc->nFIndex = 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<nArgs; i++ ) |
| { |
| delete ppDefArgNames[i]; |
| delete ppDefArgDescs[i]; |
| } |
| delete [] ppDefArgNames; |
| delete [] ppDefArgDescs; |
| delete [] pDefArgFlags; |
| } |
| nArgCount = 0; |
| ppDefArgNames = NULL; |
| ppDefArgDescs = NULL; |
| pDefArgFlags = NULL; |
| |
| delete pFuncName; |
| pFuncName = NULL; |
| |
| delete pFuncDesc; |
| pFuncDesc = NULL; |
| |
| nFIndex = 0; |
| nCategory = 0; |
| sHelpId = ""; |
| bIncomplete = false; |
| bHasSuppressedArgs = false; |
| } |
| |
| //------------------------------------------------------------------------ |
| |
| String ScFuncDesc::GetParamList() const |
| { |
| const String& sep = ScCompiler::GetNativeSymbol(ocSep); |
| |
| String aSig; |
| |
| if ( nArgCount > 0 ) |
| { |
| if ( nArgCount < VAR_ARGS ) |
| { |
| sal_uInt16 nLastSuppressed = nArgCount; |
| sal_uInt16 nLastAdded = nArgCount; |
| for ( sal_uInt16 i=0; i<nArgCount; i++ ) |
| { |
| if (pDefArgFlags[i].bSuppress) |
| nLastSuppressed = i; |
| else |
| { |
| nLastAdded = i; |
| aSig += *(ppDefArgNames[i]); |
| if ( i != nArgCount-1 ) |
| { |
| aSig.Append(sep); |
| aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " )); |
| } |
| } |
| } |
| // If only suppressed parameters follow the last added parameter, |
| // remove one "; " |
| if (nLastSuppressed < nArgCount && nLastAdded < nLastSuppressed && |
| aSig.Len() >= 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<sal_uInt16>& _rArguments) const |
| { |
| if (!bHasSuppressedArgs || !pDefArgFlags) |
| { |
| _rArguments.resize( nArgCount); |
| ::std::vector<sal_uInt16>::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<ScFuncDesc*>(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; i<MAX_FUNCCAT; i++ ) // Kategorie-Listen erstellen |
| aCatLists[i] = new List; |
| |
| pRootList = aCatLists[0]; // Gesamtliste ("Alle") erstellen |
| CollatorWrapper* pCaseCollator = ScGlobal::GetCaseCollator(); |
| for ( n=0; n<nCount; n++ ) |
| { |
| sal_uLong nTmpCnt=0; |
| pDesc = pFuncList->GetFunction(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; n<nCount; n++ ) // in Gruppenlisten kopieren |
| { |
| pDesc = (const ScFuncDesc*)pRootList->GetObject(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<ScFunctionMgr*>(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<nLRUFuncCount; i++ ) |
| _rLastRUFunctions.push_back( Get( pLRUListIds[i] ) ); |
| } |
| } |
| // ----------------------------------------------------------------------------- |
| String ScFunctionMgr::GetCategoryName(sal_uInt32 _nCategoryNumber ) |
| { |
| if ( _nCategoryNumber > SC_FUNCGROUP_COUNT ) |
| { |
| DBG_ERROR("Invalid category number!"); |
| return String(); |
| } // if ( _nCategoryNumber >= SC_FUNCGROUP_COUNT ) |
| |
| ::std::auto_ptr<ScResourcePublisher> 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; |
| } |
| |