1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 32 33 // INCLUDE --------------------------------------------------------------- 34 #include <vcl/svapp.hxx> 35 #include "scitems.hxx" 36 #include <svx/algitem.hxx> 37 #include <editeng/brshitem.hxx> 38 #include <editeng/editobj.hxx> 39 #include <editeng/scripttypeitem.hxx> 40 #include <svl/srchitem.hxx> 41 #include <editeng/langitem.hxx> 42 #include <sfx2/docfile.hxx> 43 #include <sfx2/dispatch.hxx> 44 #include <sfx2/objsh.hxx> 45 #include <sfx2/viewfrm.hxx> 46 #include <sfx2/viewsh.hxx> 47 #include <svl/stritem.hxx> 48 #include <svl/zforlist.hxx> 49 #include <svl/zformat.hxx> 50 #include <vcl/image.hxx> 51 #include <vcl/virdev.hxx> 52 #include <tools/rcid.h> 53 #include <unotools/charclass.hxx> 54 #include <stdlib.h> 55 #include <time.h> 56 #include <ctype.h> 57 #include <numeric> 58 59 60 #include <i18npool/mslangid.hxx> 61 #include <com/sun/star/lang/Locale.hpp> 62 #include <comphelper/processfactory.hxx> 63 #include <unotools/calendarwrapper.hxx> 64 #include <unotools/collatorwrapper.hxx> 65 #include <com/sun/star/i18n/CollatorOptions.hpp> 66 #include <unotools/intlwrapper.hxx> 67 #include <unotools/syslocale.hxx> 68 #include <unotools/transliterationwrapper.hxx> 69 70 #include "global.hxx" 71 #include "scresid.hxx" 72 #include "autoform.hxx" 73 #include "document.hxx" 74 #include "patattr.hxx" 75 #include "addincol.hxx" 76 #include "adiasync.hxx" 77 #include "userlist.hxx" 78 #include "interpre.hxx" 79 #include "strload.hxx" 80 #include "docpool.hxx" 81 #include "unitconv.hxx" 82 #include "compiler.hxx" 83 #include "parclass.hxx" 84 #include "funcdesc.hxx" 85 #include "globstr.hrc" 86 #include "scfuncs.hrc" 87 #include "sc.hrc" 88 #include "scmod.hxx" 89 #include "appoptio.hxx" 90 91 // ----------------------------------------------------------------------- 92 93 #define CLIPST_AVAILABLE 0 94 #define CLIPST_CAPTURED 1 95 #define CLIPST_DELETE 2 96 #define CLIPST_DRAW 3 97 98 ScDocShellRef* ScGlobal::pDrawClipDocShellRef = NULL; 99 SvxSearchItem* ScGlobal::pSearchItem = NULL; 100 ScAutoFormat* ScGlobal::pAutoFormat = NULL; 101 FuncCollection* ScGlobal::pFuncCollection = NULL; 102 ScUnoAddInCollection* ScGlobal::pAddInCollection = NULL; 103 ScUserList* ScGlobal::pUserList = NULL; 104 String** ScGlobal::ppRscString = NULL; 105 LanguageType ScGlobal::eLnge = LANGUAGE_SYSTEM; 106 ::com::sun::star::lang::Locale* ScGlobal::pLocale = NULL; 107 SvtSysLocale* ScGlobal::pSysLocale = NULL; 108 const CharClass* ScGlobal::pCharClass = NULL; 109 const LocaleDataWrapper* ScGlobal::pLocaleData = NULL; 110 CalendarWrapper* ScGlobal::pCalendar = NULL; 111 CollatorWrapper* ScGlobal::pCollator = NULL; 112 CollatorWrapper* ScGlobal::pCaseCollator = NULL; 113 ::utl::TransliterationWrapper* ScGlobal::pTransliteration = NULL; 114 ::utl::TransliterationWrapper* ScGlobal::pCaseTransliteration = NULL; 115 ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XOrdinalSuffix> ScGlobal::xOrdinalSuffix = NULL; 116 IntlWrapper* ScGlobal::pScIntlWrapper = NULL; 117 sal_Unicode ScGlobal::cListDelimiter = ','; 118 String* ScGlobal::pEmptyString = NULL; 119 String* ScGlobal::pStrClipDocName = NULL; 120 121 SvxBrushItem* ScGlobal::pEmptyBrushItem = NULL; 122 SvxBrushItem* ScGlobal::pButtonBrushItem = NULL; 123 SvxBrushItem* ScGlobal::pEmbeddedBrushItem = NULL; 124 SvxBrushItem* ScGlobal::pProtectedBrushItem = NULL; 125 126 ImageList* ScGlobal::pOutlineBitmaps = NULL; 127 ImageList* ScGlobal::pOutlineBitmapsHC = NULL; 128 129 ScFunctionList* ScGlobal::pStarCalcFunctionList = NULL; 130 ScFunctionMgr* ScGlobal::pStarCalcFunctionMgr = NULL; 131 132 ScUnitConverter* ScGlobal::pUnitConverter = NULL; 133 SvNumberFormatter* ScGlobal::pEnglishFormatter = NULL; 134 135 double ScGlobal::nScreenPPTX = 96.0; 136 double ScGlobal::nScreenPPTY = 96.0; 137 138 sal_uInt16 ScGlobal::nDefFontHeight = 240; 139 sal_uInt16 ScGlobal::nStdRowHeight = 257; 140 141 long ScGlobal::nLastRowHeightExtra = 0; 142 long ScGlobal::nLastColWidthExtra = STD_EXTRA_WIDTH; 143 144 static sal_uInt16 nPPTZoom = 0; // ScreenZoom used to determine nScreenPPTX/Y 145 146 147 class SfxViewShell; 148 SfxViewShell* pScActiveViewShell = NULL; //! als Member !!!!! 149 sal_uInt16 nScClickMouseModifier = 0; //! dito 150 sal_uInt16 nScFillModeMouseModifier = 0; //! dito 151 152 // Hack: ScGlobal::GetUserList() muss InitAppOptions in der UI aufrufen, 153 // damit UserList aus Cfg geladen wird 154 155 void global_InitAppOptions(); 156 157 //======================================================================== 158 // 159 // statische Funktionen 160 // 161 //======================================================================== 162 163 sal_Bool ScGlobal::HasAttrChanged( const SfxItemSet& rNewAttrs, 164 const SfxItemSet& rOldAttrs, 165 const sal_uInt16 nWhich ) 166 { 167 sal_Bool bInvalidate = sal_False; 168 const SfxItemState eNewState = rNewAttrs.GetItemState( nWhich ); 169 const SfxItemState eOldState = rOldAttrs.GetItemState( nWhich ); 170 171 //---------------------------------------------------------- 172 173 if ( eNewState == eOldState ) 174 { 175 // beide Items gesetzt 176 // PoolItems, d.h. Pointer-Vergleich zulaessig 177 if ( SFX_ITEM_SET == eOldState ) 178 bInvalidate = (&rNewAttrs.Get( nWhich ) != &rOldAttrs.Get( nWhich )); 179 } 180 else 181 { 182 // ein Default-Item dabei 183 // PoolItems, d.h. Item-Vergleich noetig 184 185 const SfxPoolItem& rOldItem = ( SFX_ITEM_SET == eOldState ) 186 ? rOldAttrs.Get( nWhich ) 187 : rOldAttrs.GetPool()->GetDefaultItem( nWhich ); 188 189 const SfxPoolItem& rNewItem = ( SFX_ITEM_SET == eNewState ) 190 ? rNewAttrs.Get( nWhich ) 191 : rNewAttrs.GetPool()->GetDefaultItem( nWhich ); 192 193 bInvalidate = sal::static_int_cast<sal_Bool>(rNewItem != rOldItem); 194 } 195 196 return bInvalidate; 197 } 198 199 sal_uLong ScGlobal::GetStandardFormat( SvNumberFormatter& rFormatter, 200 sal_uLong nFormat, short nType ) 201 { 202 const SvNumberformat* pFormat = rFormatter.GetEntry( nFormat ); 203 if ( pFormat ) 204 return rFormatter.GetStandardFormat( nFormat, nType, pFormat->GetLanguage() ); 205 return rFormatter.GetStandardFormat( nType, eLnge ); 206 } 207 208 sal_uLong ScGlobal::GetStandardFormat( double fNumber, SvNumberFormatter& rFormatter, 209 sal_uLong nFormat, short nType ) 210 { 211 const SvNumberformat* pFormat = rFormatter.GetEntry( nFormat ); 212 if ( pFormat ) 213 return rFormatter.GetStandardFormat( fNumber, nFormat, nType, 214 pFormat->GetLanguage() ); 215 return rFormatter.GetStandardFormat( nType, eLnge ); 216 } 217 218 219 // static 220 SvNumberFormatter* ScGlobal::GetEnglishFormatter() 221 { 222 if ( !pEnglishFormatter ) 223 { 224 pEnglishFormatter = new SvNumberFormatter( 225 ::comphelper::getProcessServiceFactory(), LANGUAGE_ENGLISH_US ); 226 pEnglishFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_INTL_FORMAT ); 227 } 228 return pEnglishFormatter; 229 } 230 231 232 //------------------------------------------------------------------------ 233 234 sal_Bool ScGlobal::CheckWidthInvalidate( sal_Bool& bNumFormatChanged, 235 const SfxItemSet& rNewAttrs, 236 const SfxItemSet& rOldAttrs ) 237 { 238 // Ueberpruefen, ob Attributaenderungen in rNewAttrs gegnueber 239 // rOldAttrs die Textbreite an einer Zelle ungueltig machen 240 241 bNumFormatChanged = 242 HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_VALUE_FORMAT ); 243 return ( bNumFormatChanged 244 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_LANGUAGE_FORMAT ) 245 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT ) 246 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CJK_FONT ) 247 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CTL_FONT ) 248 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_HEIGHT ) 249 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CJK_FONT_HEIGHT ) 250 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CTL_FONT_HEIGHT ) 251 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_WEIGHT ) 252 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CJK_FONT_WEIGHT ) 253 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CTL_FONT_WEIGHT ) 254 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_POSTURE ) 255 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CJK_FONT_POSTURE ) 256 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_CTL_FONT_POSTURE ) 257 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_UNDERLINE ) 258 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_OVERLINE ) 259 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_CROSSEDOUT ) 260 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_CONTOUR ) 261 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_FONT_SHADOWED ) 262 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_STACKED ) 263 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_ROTATE_VALUE ) 264 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_ROTATE_MODE ) 265 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_LINEBREAK ) 266 || HasAttrChanged( rNewAttrs, rOldAttrs, ATTR_MARGIN ) 267 ); 268 } 269 270 const SvxSearchItem& ScGlobal::GetSearchItem() 271 { 272 if (!pSearchItem) 273 { 274 pSearchItem = new SvxSearchItem( SID_SEARCH_ITEM ); 275 pSearchItem->SetAppFlag( SVX_SEARCHAPP_CALC ); 276 } 277 return *pSearchItem; 278 } 279 280 void ScGlobal::SetSearchItem( const SvxSearchItem& rNew ) 281 { 282 // Hier waere ein Zuweisungsoperator ganz nett: 283 delete pSearchItem; 284 pSearchItem = (SvxSearchItem*)rNew.Clone(); 285 286 pSearchItem->SetWhich( SID_SEARCH_ITEM ); 287 pSearchItem->SetAppFlag( SVX_SEARCHAPP_CALC ); 288 } 289 290 void ScGlobal::ClearAutoFormat() 291 { 292 if (pAutoFormat!=NULL) 293 { 294 delete pAutoFormat; 295 pAutoFormat=NULL; 296 } 297 } 298 299 ScAutoFormat* ScGlobal::GetAutoFormat() 300 { 301 if ( !pAutoFormat ) 302 { 303 pAutoFormat = new ScAutoFormat; 304 pAutoFormat->Load(); 305 } 306 307 return pAutoFormat; 308 } 309 310 FuncCollection* ScGlobal::GetFuncCollection() 311 { 312 if (!pFuncCollection) 313 pFuncCollection = new FuncCollection(); 314 return pFuncCollection; 315 } 316 317 ScUnoAddInCollection* ScGlobal::GetAddInCollection() 318 { 319 if (!pAddInCollection) 320 pAddInCollection = new ScUnoAddInCollection(); 321 return pAddInCollection; 322 } 323 324 ScUserList* ScGlobal::GetUserList() 325 { 326 // Hack: Cfg-Item an der App ggF. laden 327 328 global_InitAppOptions(); 329 330 if (!pUserList) 331 pUserList = new ScUserList(); 332 return pUserList; 333 } 334 335 void ScGlobal::SetUserList( const ScUserList* pNewList ) 336 { 337 if ( pNewList ) 338 { 339 if ( !pUserList ) 340 pUserList = new ScUserList( *pNewList ); 341 else 342 *pUserList = *pNewList; 343 } 344 else 345 { 346 delete pUserList; 347 pUserList = NULL; 348 } 349 } 350 351 const String& ScGlobal::GetRscString( sal_uInt16 nIndex ) 352 { 353 DBG_ASSERT( nIndex < STR_COUNT, "ScGlobal::GetRscString - invalid string index"); 354 if( !ppRscString[ nIndex ] ) 355 { 356 OpCode eOp = ocNone; 357 // Map former globstr.src strings moved to compiler.src 358 switch (nIndex) 359 { 360 case STR_NULL_ERROR: 361 eOp = ocErrNull; 362 break; 363 case STR_DIV_ZERO: 364 eOp = ocErrDivZero; 365 break; 366 case STR_NO_VALUE: 367 eOp = ocErrValue; 368 break; 369 case STR_NOREF_STR: 370 eOp = ocErrRef; 371 break; 372 case STR_NO_NAME_REF: 373 eOp = ocErrName; 374 break; 375 case STR_NUM_ERROR: 376 eOp = ocErrNum; 377 break; 378 case STR_NV_STR: 379 eOp = ocErrNA; 380 break; 381 default: 382 ; // nothing 383 } 384 if (eOp != ocNone) 385 ppRscString[ nIndex ] = new String( 386 ScCompiler::GetNativeSymbol( eOp)); 387 else 388 ppRscString[ nIndex ] = new String( 389 ScRscStrLoader( RID_GLOBSTR, nIndex ).GetString()); 390 } 391 return *ppRscString[ nIndex ]; 392 } 393 394 String ScGlobal::GetErrorString(sal_uInt16 nErrNumber) 395 { 396 String sResStr; 397 switch (nErrNumber) 398 { 399 case NOTAVAILABLE : nErrNumber = STR_NV_STR; break; 400 case errNoRef : nErrNumber = STR_NO_REF_TABLE; break; 401 case errNoName : nErrNumber = STR_NO_NAME_REF; break; 402 case errNoAddin : nErrNumber = STR_NO_ADDIN; break; 403 case errNoMacro : nErrNumber = STR_NO_MACRO; break; 404 case errDoubleRef : 405 case errNoValue : nErrNumber = STR_NO_VALUE; break; 406 case errNoCode : nErrNumber = STR_NULL_ERROR; break; 407 case errDivisionByZero : nErrNumber = STR_DIV_ZERO; break; 408 case errIllegalFPOperation : nErrNumber = STR_NUM_ERROR; break; 409 410 default : sResStr = GetRscString(STR_ERROR_STR); 411 sResStr += String::CreateFromInt32( nErrNumber ); 412 nErrNumber = 0; 413 break; 414 } 415 if( nErrNumber ) 416 sResStr = GetRscString( nErrNumber ); 417 return sResStr; 418 } 419 420 String ScGlobal::GetLongErrorString(sal_uInt16 nErrNumber) 421 { 422 switch (nErrNumber) 423 { 424 case 0: 425 break; 426 case 1: 427 case errIllegalArgument: 428 nErrNumber = STR_LONG_ERR_ILL_ARG; 429 break; 430 case 2: 431 case 3: 432 case 4: 433 case 5: 434 case errIllegalFPOperation: 435 nErrNumber = STR_LONG_ERR_ILL_FPO; 436 break; 437 case errIllegalChar: 438 nErrNumber = STR_LONG_ERR_ILL_CHAR; 439 break; 440 case errIllegalParameter: 441 nErrNumber = STR_LONG_ERR_ILL_PAR; 442 break; 443 case errSeparator: 444 nErrNumber = STR_LONG_ERR_ILL_SEP; 445 break; 446 case errPair: 447 case errPairExpected: 448 nErrNumber = STR_LONG_ERR_PAIR; 449 break; 450 case errOperatorExpected: 451 nErrNumber = STR_LONG_ERR_OP_EXP; 452 break; 453 case errVariableExpected: 454 case errParameterExpected: 455 nErrNumber = STR_LONG_ERR_VAR_EXP; 456 break; 457 case errCodeOverflow: 458 nErrNumber = STR_LONG_ERR_CODE_OVF; 459 break; 460 case errStringOverflow: 461 nErrNumber = STR_LONG_ERR_STR_OVF; 462 break; 463 case errStackOverflow: 464 case errInterpOverflow: 465 nErrNumber = STR_LONG_ERR_STACK_OVF; 466 break; 467 case errIllegalJump: 468 case errUnknownState: 469 case errUnknownVariable: 470 case errUnknownOpCode: 471 case errUnknownStackVariable: 472 case errUnknownToken: 473 case errNoCode: 474 case errDoubleRef: 475 nErrNumber = STR_LONG_ERR_SYNTAX; 476 break; 477 case errCircularReference: 478 nErrNumber = STR_LONG_ERR_CIRC_REF; 479 break; 480 case errNoConvergence: 481 nErrNumber = STR_LONG_ERR_NO_CONV; 482 break; 483 case errNoRef: 484 nErrNumber = STR_LONG_ERR_NO_REF; 485 break; 486 case errNoName: 487 nErrNumber = STR_LONG_ERR_NO_NAME; 488 break; 489 case errNoAddin: 490 nErrNumber = STR_LONG_ERR_NO_ADDIN; 491 break; 492 case errNoMacro: 493 nErrNumber = STR_LONG_ERR_NO_MACRO; 494 break; 495 case errDivisionByZero: 496 nErrNumber = STR_LONG_ERR_DIV_ZERO; 497 break; 498 case errNestedArray: 499 nErrNumber = STR_ERR_LONG_NESTED_ARRAY; 500 break; 501 case errNoValue: 502 nErrNumber = STR_LONG_ERR_NO_VALUE; 503 break; 504 case NOTAVAILABLE: 505 nErrNumber = STR_LONG_ERR_NV; 506 break; 507 default: 508 nErrNumber = STR_ERROR_STR; 509 break; 510 } 511 String aRes( GetRscString( nErrNumber ) ); 512 return aRes; 513 } 514 515 SvxBrushItem* ScGlobal::GetButtonBrushItem() 516 { 517 pButtonBrushItem->SetColor( Application::GetSettings().GetStyleSettings().GetFaceColor() ); 518 return pButtonBrushItem; 519 } 520 521 const String& ScGlobal::GetEmptyString() 522 { 523 return *pEmptyString; 524 } 525 526 ImageList* ScGlobal::GetOutlineSymbols( bool bHC ) 527 { 528 ImageList*& rpImageList = bHC ? pOutlineBitmapsHC : pOutlineBitmaps; 529 if( !rpImageList ) 530 rpImageList = new ImageList( ScResId( bHC ? RID_OUTLINEBITMAPS_H : RID_OUTLINEBITMAPS ) ); 531 return rpImageList; 532 } 533 534 void ScGlobal::Init() 535 { 536 pEmptyString = new String; 537 538 // Die Default-Sprache fuer Zahlenformate (ScGlobal::eLnge) 539 // muss immer LANGUAGE_SYSTEM sein 540 //! Dann kann auch die Variable raus 541 eLnge = LANGUAGE_SYSTEM; 542 543 //! Wenn Sortierung etc. von der Sprache der installierten Offfice-Version 544 //! abhaengen sollen, hier "Application::GetSettings().GetUILanguage()" 545 pSysLocale = new SvtSysLocale; 546 pCharClass = pSysLocale->GetCharClassPtr(); 547 pLocaleData = pSysLocale->GetLocaleDataPtr(); 548 549 ppRscString = new String *[ STR_COUNT ]; 550 for( sal_uInt16 nC = 0 ; nC < STR_COUNT ; nC++ ) ppRscString[ nC ] = NULL; 551 552 pEmptyBrushItem = new SvxBrushItem( Color( COL_TRANSPARENT ), ATTR_BACKGROUND ); 553 pButtonBrushItem = new SvxBrushItem( Color(), ATTR_BACKGROUND ); 554 pEmbeddedBrushItem = new SvxBrushItem( Color( COL_LIGHTCYAN ), ATTR_BACKGROUND ); 555 pProtectedBrushItem = new SvxBrushItem( Color( COL_LIGHTGRAY ), ATTR_BACKGROUND ); 556 557 UpdatePPT(NULL); 558 //ScCompiler::InitSymbolsNative(); 559 // ScParameterClassification _after_ Compiler, needs function resources if 560 // arguments are to be merged in, which in turn need strings of function 561 // names from the compiler. 562 ScParameterClassification::Init(); 563 srand( (unsigned) time( NULL ) ); // Random Seed Init fuer Interpreter 564 565 InitAddIns(); 566 567 pStrClipDocName = new String( ScResId( SCSTR_NONAME ) ); 568 *pStrClipDocName += '1'; 569 570 // ScDocumentPool::InitVersionMaps() ist schon vorher gerufen worden 571 } 572 573 void ScGlobal::UpdatePPT( OutputDevice* pDev ) 574 { 575 sal_uInt16 nCurrentZoom = Application::GetSettings().GetStyleSettings().GetScreenZoom(); 576 if ( nCurrentZoom != nPPTZoom ) 577 { 578 // Screen PPT values must be updated when ScreenZoom has changed. 579 // If called from Window::DataChanged, the window is passed as pDev, 580 // to make sure LogicToPixel uses a device which already uses the new zoom. 581 // For the initial settings, NULL is passed and GetDefaultDevice used. 582 583 if ( !pDev ) 584 pDev = Application::GetDefaultDevice(); 585 Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP ); 586 nScreenPPTX = aPix1000.X() / 1000.0; 587 nScreenPPTY = aPix1000.Y() / 1000.0; 588 nPPTZoom = nCurrentZoom; 589 } 590 } 591 592 const String& ScGlobal::GetClipDocName() 593 { 594 return *pStrClipDocName; 595 } 596 597 void ScGlobal::SetClipDocName( const String& rNew ) 598 { 599 *pStrClipDocName = rNew; 600 } 601 602 603 void ScGlobal::InitTextHeight(SfxItemPool* pPool) 604 { 605 if (!pPool) 606 { 607 DBG_ERROR("kein Pool bei ScGlobal::InitTextHeight"); 608 return; 609 } 610 611 const ScPatternAttr* pPattern = (const ScPatternAttr*)&pPool->GetDefaultItem(ATTR_PATTERN); 612 if (!pPattern) 613 { 614 DBG_ERROR("kein Default-Pattern bei ScGlobal::InitTextHeight"); 615 return; 616 } 617 618 // String aTestString('X'); 619 OutputDevice* pDefaultDev = Application::GetDefaultDevice(); 620 VirtualDevice aVirtWindow( *pDefaultDev ); 621 aVirtWindow.SetMapMode(MAP_PIXEL); 622 Font aDefFont; 623 pPattern->GetFont(aDefFont, SC_AUTOCOL_BLACK, &aVirtWindow); // font color doesn't matter here 624 aVirtWindow.SetFont(aDefFont); 625 nDefFontHeight = (sal_uInt16) aVirtWindow.PixelToLogic(Size(0, aVirtWindow.GetTextHeight()), 626 MAP_TWIP).Height(); 627 628 const SvxMarginItem* pMargin = (const SvxMarginItem*)&pPattern->GetItem(ATTR_MARGIN); 629 630 nStdRowHeight = (sal_uInt16) ( nDefFontHeight + 631 pMargin->GetTopMargin() + pMargin->GetBottomMargin() 632 - STD_ROWHEIGHT_DIFF ); 633 } 634 635 void ScGlobal::Clear() 636 { 637 // asyncs _vor_ ExitExternalFunc zerstoeren! 638 theAddInAsyncTbl.DeleteAndDestroy( 0, theAddInAsyncTbl.Count() ); 639 ExitExternalFunc(); 640 DELETEZ(pAutoFormat); 641 DELETEZ(pSearchItem); 642 DELETEZ(pFuncCollection); 643 DELETEZ(pAddInCollection); 644 DELETEZ(pUserList); 645 646 for( sal_uInt16 nC = 0 ; nC < STR_COUNT ; nC++ ) 647 if( ppRscString ) delete ppRscString[ nC ]; 648 delete[] ppRscString; 649 ppRscString = NULL; 650 651 DELETEZ(pStarCalcFunctionList); // vor ResMgr zerstoeren! 652 DELETEZ(pStarCalcFunctionMgr); 653 ScParameterClassification::Exit(); 654 ScCompiler::DeInit(); 655 ScInterpreter::GlobalExit(); // statischen Stack loeschen 656 657 DELETEZ(pEmptyBrushItem); 658 DELETEZ(pButtonBrushItem); 659 DELETEZ(pEmbeddedBrushItem); 660 DELETEZ(pProtectedBrushItem); 661 DELETEZ(pOutlineBitmaps); 662 DELETEZ(pOutlineBitmapsHC); 663 // DELETEZ(pAnchorBitmap); 664 // DELETEZ(pGrayAnchorBitmap); 665 DELETEZ(pEnglishFormatter); 666 DELETEZ(pCaseTransliteration); 667 DELETEZ(pTransliteration); 668 DELETEZ(pCaseCollator); 669 DELETEZ(pCollator); 670 DELETEZ(pCalendar); 671 //! do NOT delete pCharClass since it is a pointer to the single SvtSysLocale instance 672 pCharClass = NULL; 673 //! do NOT delete pLocaleData since it is a pointer to the single SvtSysLocale instance 674 pLocaleData = NULL; 675 DELETEZ(pSysLocale); 676 DELETEZ(pLocale); 677 DELETEZ(pScIntlWrapper); 678 DELETEZ(pStrClipDocName); 679 680 DELETEZ(pUnitConverter); 681 682 ScDocumentPool::DeleteVersionMaps(); 683 684 DELETEZ(pEmptyString); 685 } 686 687 //------------------------------------------------------------------------ 688 689 // static 690 CharSet ScGlobal::GetCharsetValue( const String& rCharSet ) 691 { 692 // new TextEncoding values 693 if ( CharClass::isAsciiNumeric( rCharSet ) ) 694 { 695 sal_Int32 nVal = rCharSet.ToInt32(); 696 if ( !nVal || nVal == RTL_TEXTENCODING_DONTKNOW ) 697 return gsl_getSystemTextEncoding(); 698 return (CharSet) nVal; 699 } 700 // old CharSet values for compatibility 701 else if (rCharSet.EqualsIgnoreCaseAscii("ANSI") ) return RTL_TEXTENCODING_MS_1252; 702 else if (rCharSet.EqualsIgnoreCaseAscii("MAC") ) return RTL_TEXTENCODING_APPLE_ROMAN; 703 else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC") ) return RTL_TEXTENCODING_IBM_850; 704 else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_437")) return RTL_TEXTENCODING_IBM_437; 705 else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_850")) return RTL_TEXTENCODING_IBM_850; 706 else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_860")) return RTL_TEXTENCODING_IBM_860; 707 else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_861")) return RTL_TEXTENCODING_IBM_861; 708 else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_863")) return RTL_TEXTENCODING_IBM_863; 709 else if (rCharSet.EqualsIgnoreCaseAscii("IBMPC_865")) return RTL_TEXTENCODING_IBM_865; 710 // else if (rCharSet.EqualsIgnoreCaseAscii("SYSTEM") ) return gsl_getSystemTextEncoding(); 711 else return gsl_getSystemTextEncoding(); 712 } 713 714 //------------------------------------------------------------------------ 715 716 // static 717 String ScGlobal::GetCharsetString( CharSet eVal ) 718 { 719 const sal_Char* pChar; 720 switch ( eVal ) 721 { 722 // old CharSet strings for compatibility 723 case RTL_TEXTENCODING_MS_1252: pChar = "ANSI"; break; 724 case RTL_TEXTENCODING_APPLE_ROMAN: pChar = "MAC"; break; 725 // IBMPC == IBMPC_850 726 case RTL_TEXTENCODING_IBM_437: pChar = "IBMPC_437"; break; 727 case RTL_TEXTENCODING_IBM_850: pChar = "IBMPC_850"; break; 728 case RTL_TEXTENCODING_IBM_860: pChar = "IBMPC_860"; break; 729 case RTL_TEXTENCODING_IBM_861: pChar = "IBMPC_861"; break; 730 case RTL_TEXTENCODING_IBM_863: pChar = "IBMPC_863"; break; 731 case RTL_TEXTENCODING_IBM_865: pChar = "IBMPC_865"; break; 732 case RTL_TEXTENCODING_DONTKNOW: pChar = "SYSTEM"; break; 733 // new string of TextEncoding value 734 default: 735 return String::CreateFromInt32( eVal ); 736 } 737 return String::CreateFromAscii(pChar); 738 } 739 740 //------------------------------------------------------------------------ 741 742 bool ScGlobal::HasStarCalcFunctionList() 743 { 744 return ( pStarCalcFunctionList != NULL ); 745 } 746 747 ScFunctionList* ScGlobal::GetStarCalcFunctionList() 748 { 749 if ( !pStarCalcFunctionList ) 750 pStarCalcFunctionList = new ScFunctionList; 751 752 return pStarCalcFunctionList; 753 } 754 755 //------------------------------------------------------------------------ 756 757 ScFunctionMgr* ScGlobal::GetStarCalcFunctionMgr() 758 { 759 if ( !pStarCalcFunctionMgr ) 760 pStarCalcFunctionMgr = new ScFunctionMgr; 761 762 return pStarCalcFunctionMgr; 763 } 764 765 void ScGlobal::ResetFunctionList() 766 { 767 // FunctionMgr has pointers into FunctionList, must also be updated 768 769 DELETEZ( pStarCalcFunctionMgr ); 770 DELETEZ( pStarCalcFunctionList ); 771 } 772 773 //------------------------------------------------------------------------ 774 775 // static 776 ScUnitConverter* ScGlobal::GetUnitConverter() 777 { 778 if ( !pUnitConverter ) 779 pUnitConverter = new ScUnitConverter; 780 781 return pUnitConverter; 782 } 783 784 785 //------------------------------------------------------------------------ 786 787 // static 788 const sal_Unicode* ScGlobal::UnicodeStrChr( const sal_Unicode* pStr, 789 sal_Unicode c ) 790 { 791 if ( !pStr ) 792 return NULL; 793 while ( *pStr ) 794 { 795 if ( *pStr == c ) 796 return pStr; 797 pStr++; 798 } 799 return NULL; 800 } 801 802 // ---------------------------------------------------------------------------- 803 804 void ScGlobal::AddToken( String& rTokenList, const String& rToken, sal_Unicode cSep, xub_StrLen nSepCount, bool bForceSep ) 805 { 806 if( bForceSep || (rToken.Len() && rTokenList.Len()) ) 807 rTokenList.Expand( rTokenList.Len() + nSepCount, cSep ); 808 rTokenList.Append( rToken ); 809 } 810 811 bool ScGlobal::IsQuoted( const String& rString, sal_Unicode cQuote ) 812 { 813 return (rString.Len() >= 2) && (rString.GetChar( 0 ) == cQuote) && (rString.GetChar( rString.Len() - 1 ) == cQuote); 814 } 815 816 void ScGlobal::AddQuotes( String& rString, sal_Unicode cQuote, bool bEscapeEmbedded ) 817 { 818 if (bEscapeEmbedded) 819 { 820 sal_Unicode pQ[3]; 821 pQ[0] = pQ[1] = cQuote; 822 pQ[2] = 0; 823 String aQuotes( pQ ); 824 rString.SearchAndReplaceAll( cQuote, aQuotes); 825 } 826 rString.Insert( cQuote, 0 ).Append( cQuote ); 827 } 828 829 void ScGlobal::EraseQuotes( String& rString, sal_Unicode cQuote, bool bUnescapeEmbedded ) 830 { 831 if ( IsQuoted( rString, cQuote ) ) 832 { 833 rString.Erase( rString.Len() - 1 ).Erase( 0, 1 ); 834 if (bUnescapeEmbedded) 835 { 836 sal_Unicode pQ[3]; 837 pQ[0] = pQ[1] = cQuote; 838 pQ[2] = 0; 839 String aQuotes( pQ ); 840 rString.SearchAndReplaceAll( aQuotes, cQuote); 841 } 842 } 843 } 844 845 xub_StrLen ScGlobal::FindUnquoted( const String& rString, sal_Unicode cChar, xub_StrLen nStart, sal_Unicode cQuote ) 846 { 847 const sal_Unicode* const pStart = rString.GetBuffer(); 848 const sal_Unicode* const pStop = pStart + rString.Len(); 849 const sal_Unicode* p = pStart + nStart; 850 bool bQuoted = false; 851 while (p < pStop) 852 { 853 if (*p == cChar && !bQuoted) 854 return sal::static_int_cast< xub_StrLen >( p - pStart ); 855 else if (*p == cQuote) 856 { 857 if (!bQuoted) 858 bQuoted = true; 859 else if (p < pStop-1 && *(p+1) == cQuote) 860 ++p; 861 else 862 bQuoted = false; 863 } 864 ++p; 865 } 866 return STRING_NOTFOUND; 867 } 868 869 const sal_Unicode* ScGlobal::FindUnquoted( const sal_Unicode* pString, sal_Unicode cChar, sal_Unicode cQuote ) 870 { 871 const sal_Unicode* p = pString; 872 bool bQuoted = false; 873 while (*p) 874 { 875 if (*p == cChar && !bQuoted) 876 return p; 877 else if (*p == cQuote) 878 { 879 if (!bQuoted) 880 bQuoted = true; 881 else if (*(p+1) == cQuote) 882 ++p; 883 else 884 bQuoted = false; 885 } 886 ++p; 887 } 888 return NULL; 889 } 890 891 //------------------------------------------------------------------------ 892 893 sal_Bool ScGlobal::EETextObjEqual( const EditTextObject* pObj1, 894 const EditTextObject* pObj2 ) 895 { 896 if ( pObj1 == pObj2 ) // both empty or the same object 897 return sal_True; 898 899 if ( pObj1 && pObj2 ) 900 { 901 // first test for equal text content 902 sal_uInt16 nParCount = pObj1->GetParagraphCount(); 903 if ( nParCount != pObj2->GetParagraphCount() ) 904 return sal_False; 905 for (sal_uInt16 nPar=0; nPar<nParCount; nPar++) 906 if ( pObj1->GetText(nPar) != pObj2->GetText(nPar) ) 907 return sal_False; 908 909 SvMemoryStream aStream1; 910 SvMemoryStream aStream2; 911 pObj1->Store( aStream1 ); 912 pObj2->Store( aStream2 ); 913 sal_uLong nSize = aStream1.Tell(); 914 if ( aStream2.Tell() == nSize ) 915 if ( !memcmp( aStream1.GetData(), aStream2.GetData(), (sal_uInt16) nSize ) ) 916 return sal_True; 917 } 918 919 return sal_False; 920 } 921 922 void ScGlobal::OpenURL( const String& rURL, const String& rTarget ) 923 { 924 // OpenURL wird immer ueber irgendwelche Umwege durch Mausklicks im GridWindow 925 // aufgerufen, darum stimmen pScActiveViewShell und nScClickMouseModifier. 926 927 SfxStringItem aUrl( SID_FILE_NAME, rURL ); 928 SfxStringItem aTarget( SID_TARGETNAME, rTarget ); 929 930 if ( nScClickMouseModifier & KEY_MOD1 ) // control-click -> into new window 931 aTarget.SetValue( 932 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("_blank")) ); 933 934 SfxViewFrame* pFrame = NULL; 935 String aReferName; 936 if ( pScActiveViewShell ) 937 { 938 pFrame = pScActiveViewShell->GetViewFrame(); 939 SfxMedium* pMed = pFrame->GetObjectShell()->GetMedium(); 940 if (pMed) 941 aReferName = pMed->GetName(); 942 } 943 944 SfxFrameItem aFrm( SID_DOCFRAME, pFrame ); 945 SfxStringItem aReferer( SID_REFERER, aReferName ); 946 947 SfxBoolItem aNewView( SID_OPEN_NEW_VIEW, sal_False ); 948 SfxBoolItem aBrowsing( SID_BROWSE, sal_True ); 949 950 // kein SID_SILENT mehr wegen Bug #42525# (war angeblich sowieso falsch) 951 952 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 953 if (pViewFrm) 954 pViewFrm->GetDispatcher()->Execute( SID_OPENDOC, 955 SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, 956 &aUrl, &aTarget, 957 &aFrm, &aReferer, 958 &aNewView, &aBrowsing, 959 0L ); 960 } 961 962 //------------------------------------------------------------------------ 963 964 sal_Bool ScGlobal::IsSystemRTL() 965 { 966 return MsLangId::isRightToLeft( Application::GetSettings().GetLanguage() ); 967 } 968 969 sal_uInt8 ScGlobal::GetDefaultScriptType() 970 { 971 // Used when text contains only WEAK characters. 972 // Script type of office language is used then (same as GetEditDefaultLanguage, 973 // to get consistent behavior of text in simple cells and EditEngine, 974 // also same as GetAppLanguage() in Writer) 975 976 return (sal_uInt8) SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguage() ); 977 } 978 979 LanguageType ScGlobal::GetEditDefaultLanguage() 980 { 981 // used for EditEngine::SetDefaultLanguage 982 983 return Application::GetSettings().GetLanguage(); 984 } 985 986 sal_uInt16 ScGlobal::GetScriptedWhichID( sal_uInt8 nScriptType, sal_uInt16 nWhich ) 987 { 988 switch ( nScriptType ) 989 { 990 case SCRIPTTYPE_LATIN: 991 case SCRIPTTYPE_ASIAN: 992 case SCRIPTTYPE_COMPLEX: 993 break; // take exact matches 994 default: // prefer one, first COMPLEX, then ASIAN 995 if ( nScriptType & SCRIPTTYPE_COMPLEX ) 996 nScriptType = SCRIPTTYPE_COMPLEX; 997 else if ( nScriptType & SCRIPTTYPE_ASIAN ) 998 nScriptType = SCRIPTTYPE_ASIAN; 999 } 1000 switch ( nScriptType ) 1001 { 1002 case SCRIPTTYPE_COMPLEX: 1003 { 1004 switch ( nWhich ) 1005 { 1006 case ATTR_FONT: 1007 case ATTR_CJK_FONT: 1008 nWhich = ATTR_CTL_FONT; 1009 break; 1010 case ATTR_FONT_HEIGHT: 1011 case ATTR_CJK_FONT_HEIGHT: 1012 nWhich = ATTR_CTL_FONT_HEIGHT; 1013 break; 1014 case ATTR_FONT_WEIGHT: 1015 case ATTR_CJK_FONT_WEIGHT: 1016 nWhich = ATTR_CTL_FONT_WEIGHT; 1017 break; 1018 case ATTR_FONT_POSTURE: 1019 case ATTR_CJK_FONT_POSTURE: 1020 nWhich = ATTR_CTL_FONT_POSTURE; 1021 break; 1022 } 1023 } 1024 break; 1025 case SCRIPTTYPE_ASIAN: 1026 { 1027 switch ( nWhich ) 1028 { 1029 case ATTR_FONT: 1030 case ATTR_CTL_FONT: 1031 nWhich = ATTR_CJK_FONT; 1032 break; 1033 case ATTR_FONT_HEIGHT: 1034 case ATTR_CTL_FONT_HEIGHT: 1035 nWhich = ATTR_CJK_FONT_HEIGHT; 1036 break; 1037 case ATTR_FONT_WEIGHT: 1038 case ATTR_CTL_FONT_WEIGHT: 1039 nWhich = ATTR_CJK_FONT_WEIGHT; 1040 break; 1041 case ATTR_FONT_POSTURE: 1042 case ATTR_CTL_FONT_POSTURE: 1043 nWhich = ATTR_CJK_FONT_POSTURE; 1044 break; 1045 } 1046 } 1047 break; 1048 default: 1049 { 1050 switch ( nWhich ) 1051 { 1052 case ATTR_CTL_FONT: 1053 case ATTR_CJK_FONT: 1054 nWhich = ATTR_FONT; 1055 break; 1056 case ATTR_CTL_FONT_HEIGHT: 1057 case ATTR_CJK_FONT_HEIGHT: 1058 nWhich = ATTR_FONT_HEIGHT; 1059 break; 1060 case ATTR_CTL_FONT_WEIGHT: 1061 case ATTR_CJK_FONT_WEIGHT: 1062 nWhich = ATTR_FONT_WEIGHT; 1063 break; 1064 case ATTR_CTL_FONT_POSTURE: 1065 case ATTR_CJK_FONT_POSTURE: 1066 nWhich = ATTR_FONT_POSTURE; 1067 break; 1068 } 1069 } 1070 } 1071 return nWhich; 1072 } 1073 1074 //------------------------------------------------------------------------ 1075 1076 void ScGlobal::AddLanguage( SfxItemSet& rSet, SvNumberFormatter& rFormatter ) 1077 { 1078 DBG_ASSERT( rSet.GetItemState( ATTR_LANGUAGE_FORMAT, sal_False ) == SFX_ITEM_DEFAULT, 1079 "ScGlobal::AddLanguage - language already added"); 1080 1081 const SfxPoolItem* pHardItem; 1082 if ( rSet.GetItemState( ATTR_VALUE_FORMAT, sal_False, &pHardItem ) == SFX_ITEM_SET ) 1083 { 1084 const SvNumberformat* pHardFormat = rFormatter.GetEntry( 1085 ((const SfxUInt32Item*)pHardItem)->GetValue() ); 1086 1087 sal_uLong nParentFmt = 0; // pool default 1088 const SfxItemSet* pParent = rSet.GetParent(); 1089 if ( pParent ) 1090 nParentFmt = ((const SfxUInt32Item&)pParent->Get( ATTR_VALUE_FORMAT )).GetValue(); 1091 const SvNumberformat* pParFormat = rFormatter.GetEntry( nParentFmt ); 1092 1093 if ( pHardFormat && pParFormat && 1094 (pHardFormat->GetLanguage() != pParFormat->GetLanguage()) ) 1095 rSet.Put( SvxLanguageItem( pHardFormat->GetLanguage(), ATTR_LANGUAGE_FORMAT ) ); 1096 } 1097 } 1098 1099 1100 1101 1102 1103 //=================================================================== 1104 // class ScFunctionList: 1105 //=================================================================== 1106 1107 //=================================================================== 1108 // class ScFuncRes 1109 // fuer temporaere Objekte zum Holen der Resourcen 1110 1111 class ScFuncRes : public Resource 1112 { 1113 public: 1114 ScFuncRes( ResId&, ScFuncDesc*, bool & rbSuppressed ); 1115 1116 private: 1117 sal_uInt16 GetNum(); 1118 }; 1119 1120 //-------------------------------------------------------------------- 1121 1122 ScFuncRes::ScFuncRes( ResId &aRes, ScFuncDesc* pDesc, bool & rbSuppressed ) 1123 : Resource(aRes) 1124 { 1125 rbSuppressed = (bool)GetNum(); 1126 pDesc->nCategory = GetNum(); 1127 pDesc->sHelpId = ReadByteStringRes(); //! Hack, see scfuncs.src 1128 pDesc->nArgCount = GetNum(); 1129 sal_uInt16 nArgs = pDesc->nArgCount; 1130 if (nArgs >= VAR_ARGS) 1131 nArgs -= VAR_ARGS - 1; 1132 if (nArgs) 1133 { 1134 pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs]; 1135 for (sal_uInt16 i = 0; i < nArgs; i++) 1136 { 1137 pDesc->pDefArgFlags[i].bOptional = (bool)GetNum(); 1138 } 1139 } 1140 // Need to read the value from the resource even if nArgs==0 to advance the 1141 // resource position pointer, so this can't be in the if(nArgs) block above. 1142 sal_uInt16 nSuppressed = GetNum(); 1143 if (nSuppressed) 1144 { 1145 if (nSuppressed > nArgs) 1146 { 1147 DBG_ERROR3( "ScFuncRes: suppressed parameters count mismatch on OpCode %u: suppressed %d > params %d", 1148 aRes.GetId(), (int)nSuppressed, (int)nArgs); 1149 nSuppressed = nArgs; // sanitize 1150 } 1151 for (sal_uInt16 i=0; i < nSuppressed; ++i) 1152 { 1153 sal_uInt16 nParam = GetNum(); 1154 if (nParam < nArgs) 1155 { 1156 if (pDesc->nArgCount >= VAR_ARGS && nParam == nArgs-1) 1157 { 1158 DBG_ERROR3( "ScFuncRes: VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d == arg %d-1", 1159 aRes.GetId(), (int)nParam, (int)nArgs); 1160 } 1161 else 1162 { 1163 pDesc->pDefArgFlags[nParam].bSuppress = true; 1164 pDesc->bHasSuppressedArgs = true; 1165 } 1166 } 1167 else 1168 { 1169 DBG_ERROR3( "ScFuncRes: suppressed parameter exceeds count on OpCode %u: param %d >= args %d", 1170 aRes.GetId(), (int)nParam, (int)nArgs); 1171 } 1172 } 1173 } 1174 1175 pDesc->pFuncName = new String( ScCompiler::GetNativeSymbol( static_cast<OpCode>( aRes.GetId()))); 1176 pDesc->pFuncDesc = new String(ScResId(1)); 1177 1178 if (nArgs) 1179 { 1180 pDesc->ppDefArgNames = new String*[nArgs]; 1181 pDesc->ppDefArgDescs = new String*[nArgs]; 1182 for (sal_uInt16 i = 0; i < nArgs; i++) 1183 { 1184 pDesc->ppDefArgNames[i] = new String(ScResId(2*(i+1) )); 1185 pDesc->ppDefArgDescs[i] = new String(ScResId(2*(i+1)+1)); 1186 } 1187 } 1188 1189 FreeResource(); 1190 } 1191 1192 //------------------------------------------------------------------------ 1193 1194 sal_uInt16 ScFuncRes::GetNum() 1195 { 1196 return ReadShortRes(); 1197 } 1198 1199 //========================================================================= 1200 1201 // um an die protected von Resource ranzukommen 1202 class ScResourcePublisher : public Resource 1203 { 1204 private: 1205 void FreeResource() { Resource::FreeResource(); } 1206 public: 1207 ScResourcePublisher( const ScResId& rId ) : Resource( rId ) {} 1208 ~ScResourcePublisher() { FreeResource(); } 1209 sal_Bool IsAvailableRes( const ResId& rId ) const 1210 { return Resource::IsAvailableRes( rId ); } 1211 1212 }; 1213 1214 1215 ScFunctionList::ScFunctionList() : 1216 nMaxFuncNameLen ( 0 ) 1217 { 1218 ScFuncDesc* pDesc = NULL; 1219 xub_StrLen nStrLen = 0; 1220 FuncCollection* pFuncColl; 1221 sal_uInt16 i,j; 1222 sal_uInt16 nDescBlock[] = 1223 { 1224 RID_SC_FUNCTION_DESCRIPTIONS1, 1225 RID_SC_FUNCTION_DESCRIPTIONS2 1226 }; 1227 const sal_uInt16 nBlocks = sizeof(nDescBlock) / sizeof(sal_uInt16); 1228 1229 aFunctionList.Clear(); 1230 1231 for ( sal_uInt16 k = 0; k < nBlocks; k++ ) 1232 { 1233 ::std::auto_ptr<ScResourcePublisher> pBlock( new ScResourcePublisher( ScResId( nDescBlock[k] ) ) ); 1234 // Browse for all possible OpCodes. This is not the fastest method, but 1235 // otherwise the sub resources within the resource blocks and the 1236 // resource blocks themselfs would had to be ordered according to 1237 // OpCodes, which is utopian.. 1238 for (i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; i++) 1239 { 1240 ScResId aRes(i); 1241 aRes.SetRT(RSC_RESOURCE); 1242 // Sub resource of OpCode available? 1243 if (pBlock->IsAvailableRes(aRes)) 1244 { 1245 pDesc = new ScFuncDesc; 1246 bool bSuppressed = false; 1247 ScFuncRes aSubRes( aRes, pDesc, bSuppressed); 1248 // Instead of dealing with this exceptional case at 1001 places 1249 // we simply don't add an entirely suppressed function to the 1250 // list and delete it. 1251 if (bSuppressed) 1252 delete pDesc; 1253 else 1254 { 1255 pDesc->nFIndex = i; 1256 aFunctionList.Insert( pDesc, LIST_APPEND ); 1257 1258 nStrLen = (*(pDesc->pFuncName)).Len(); 1259 if (nStrLen > nMaxFuncNameLen) 1260 nMaxFuncNameLen = nStrLen; 1261 } 1262 } 1263 } 1264 } 1265 1266 sal_uInt16 nNextId = SC_OPCODE_LAST_OPCODE_ID + 1; // FuncID for AddIn functions 1267 1268 // Auswertung AddIn-Liste 1269 String aDefArgNameValue(RTL_CONSTASCII_STRINGPARAM("value")); 1270 String aDefArgNameString(RTL_CONSTASCII_STRINGPARAM("string")); 1271 String aDefArgNameValues(RTL_CONSTASCII_STRINGPARAM("values")); 1272 String aDefArgNameStrings(RTL_CONSTASCII_STRINGPARAM("strings")); 1273 String aDefArgNameCells(RTL_CONSTASCII_STRINGPARAM("cells")); 1274 String aDefArgNameNone(RTL_CONSTASCII_STRINGPARAM("none")); 1275 String aDefArgDescValue(RTL_CONSTASCII_STRINGPARAM("a value")); 1276 String aDefArgDescString(RTL_CONSTASCII_STRINGPARAM("a string")); 1277 String aDefArgDescValues(RTL_CONSTASCII_STRINGPARAM("array of values")); 1278 String aDefArgDescStrings(RTL_CONSTASCII_STRINGPARAM("array of strings")); 1279 String aDefArgDescCells(RTL_CONSTASCII_STRINGPARAM("range of cells")); 1280 String aDefArgDescNone(RTL_CONSTASCII_STRINGPARAM("none")); 1281 String aArgName, aArgDesc; 1282 pFuncColl = ScGlobal::GetFuncCollection(); 1283 for (i = 0; i < pFuncColl->GetCount(); i++) 1284 { 1285 pDesc = new ScFuncDesc; 1286 FuncData *pAddInFuncData = (FuncData*)pFuncColl->At(i); 1287 sal_uInt16 nArgs = pAddInFuncData->GetParamCount() - 1; 1288 pAddInFuncData->GetParamDesc( aArgName, aArgDesc, 0 ); 1289 pDesc->nFIndex = nNextId++; // ??? OpCode vergeben 1290 pDesc->nCategory = ID_FUNCTION_GRP_ADDINS; 1291 pDesc->pFuncName = new String(pAddInFuncData->GetInternalName()); 1292 pDesc->pFuncName->ToUpperAscii(); 1293 pDesc->pFuncDesc = new String( aArgDesc ); 1294 *(pDesc->pFuncDesc) += '\n'; 1295 pDesc->pFuncDesc->AppendAscii(RTL_CONSTASCII_STRINGPARAM( "( AddIn: " )); 1296 *(pDesc->pFuncDesc) += pAddInFuncData->GetModuleName(); 1297 pDesc->pFuncDesc->AppendAscii(RTL_CONSTASCII_STRINGPARAM( " )" )); 1298 pDesc->nArgCount = nArgs; 1299 if (nArgs) 1300 { 1301 pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs]; 1302 pDesc->ppDefArgNames = new String*[nArgs]; 1303 pDesc->ppDefArgDescs = new String*[nArgs]; 1304 for (j = 0; j < nArgs; j++) 1305 { 1306 pDesc->pDefArgFlags[j].bOptional = false; 1307 pDesc->pDefArgFlags[j].bSuppress = false; 1308 pAddInFuncData->GetParamDesc( aArgName, aArgDesc, j+1 ); 1309 if ( aArgName.Len() ) 1310 pDesc->ppDefArgNames[j] = new String( aArgName ); 1311 else 1312 { 1313 switch (pAddInFuncData->GetParamType(j+1)) 1314 { 1315 case PTR_DOUBLE: 1316 pDesc->ppDefArgNames[j] = new String( aDefArgNameValue ); 1317 break; 1318 case PTR_STRING: 1319 pDesc->ppDefArgNames[j] = new String( aDefArgNameString ); 1320 break; 1321 case PTR_DOUBLE_ARR: 1322 pDesc->ppDefArgNames[j] = new String( aDefArgNameValues ); 1323 break; 1324 case PTR_STRING_ARR: 1325 pDesc->ppDefArgNames[j] = new String( aDefArgNameStrings ); 1326 break; 1327 case PTR_CELL_ARR: 1328 pDesc->ppDefArgNames[j] = new String( aDefArgNameCells ); 1329 break; 1330 default: 1331 pDesc->ppDefArgNames[j] = new String( aDefArgNameNone ); 1332 break; 1333 } 1334 } 1335 if ( aArgDesc.Len() ) 1336 pDesc->ppDefArgDescs[j] = new String( aArgDesc ); 1337 else 1338 { 1339 switch (pAddInFuncData->GetParamType(j+1)) 1340 { 1341 case PTR_DOUBLE: 1342 pDesc->ppDefArgDescs[j] = new String( aDefArgDescValue ); 1343 break; 1344 case PTR_STRING: 1345 pDesc->ppDefArgDescs[j] = new String( aDefArgDescString ); 1346 break; 1347 case PTR_DOUBLE_ARR: 1348 pDesc->ppDefArgDescs[j] = new String( aDefArgDescValues ); 1349 break; 1350 case PTR_STRING_ARR: 1351 pDesc->ppDefArgDescs[j] = new String( aDefArgDescStrings ); 1352 break; 1353 case PTR_CELL_ARR: 1354 pDesc->ppDefArgDescs[j] = new String( aDefArgDescCells ); 1355 break; 1356 default: 1357 pDesc->ppDefArgDescs[j] = new String( aDefArgDescNone ); 1358 break; 1359 } 1360 } 1361 } 1362 } 1363 // pDesc->nHelpId = 0; 1364 1365 aFunctionList.Insert(pDesc, LIST_APPEND); 1366 nStrLen = (*(pDesc->pFuncName)).Len(); 1367 if ( nStrLen > nMaxFuncNameLen) 1368 nMaxFuncNameLen = nStrLen; 1369 } 1370 1371 // StarOne AddIns 1372 1373 ScUnoAddInCollection* pUnoAddIns = ScGlobal::GetAddInCollection(); 1374 long nUnoCount = pUnoAddIns->GetFuncCount(); 1375 for (long nFunc=0; nFunc<nUnoCount; nFunc++) 1376 { 1377 pDesc = new ScFuncDesc; 1378 pDesc->nFIndex = nNextId++; 1379 1380 if ( pUnoAddIns->FillFunctionDesc( nFunc, *pDesc ) ) 1381 { 1382 aFunctionList.Insert(pDesc, LIST_APPEND); 1383 nStrLen = (*(pDesc->pFuncName)).Len(); 1384 if (nStrLen > nMaxFuncNameLen) 1385 nMaxFuncNameLen = nStrLen; 1386 } 1387 else 1388 delete pDesc; 1389 } 1390 } 1391 1392 //------------------------------------------------------------------------ 1393 1394 ScFunctionList::~ScFunctionList() 1395 { 1396 const ScFuncDesc* pDesc = First(); 1397 while (pDesc) 1398 { 1399 delete pDesc; 1400 pDesc = Next(); 1401 } 1402 } 1403 1404 1405 //======================================================================== 1406 // class ScFuncDesc: 1407 1408 ScFuncDesc::ScFuncDesc() : 1409 pFuncName (NULL), 1410 pFuncDesc (NULL), 1411 ppDefArgNames (NULL), 1412 ppDefArgDescs (NULL), 1413 pDefArgFlags (NULL), 1414 nFIndex (0), 1415 nCategory (0), 1416 nArgCount (0), 1417 bIncomplete (false), 1418 bHasSuppressedArgs(false) 1419 {} 1420 1421 //------------------------------------------------------------------------ 1422 1423 ScFuncDesc::~ScFuncDesc() 1424 { 1425 Clear(); 1426 } 1427 1428 //------------------------------------------------------------------------ 1429 1430 void ScFuncDesc::Clear() 1431 { 1432 sal_uInt16 nArgs = nArgCount; 1433 if (nArgs >= VAR_ARGS) nArgs -= VAR_ARGS-1; 1434 if (nArgs) 1435 { 1436 for (sal_uInt16 i=0; i<nArgs; i++ ) 1437 { 1438 delete ppDefArgNames[i]; 1439 delete ppDefArgDescs[i]; 1440 } 1441 delete [] ppDefArgNames; 1442 delete [] ppDefArgDescs; 1443 delete [] pDefArgFlags; 1444 } 1445 nArgCount = 0; 1446 ppDefArgNames = NULL; 1447 ppDefArgDescs = NULL; 1448 pDefArgFlags = NULL; 1449 1450 delete pFuncName; 1451 pFuncName = NULL; 1452 1453 delete pFuncDesc; 1454 pFuncDesc = NULL; 1455 1456 nFIndex = 0; 1457 nCategory = 0; 1458 sHelpId = ""; 1459 bIncomplete = false; 1460 bHasSuppressedArgs = false; 1461 } 1462 1463 //------------------------------------------------------------------------ 1464 1465 String ScFuncDesc::GetParamList() const 1466 { 1467 const String& sep = ScCompiler::GetNativeSymbol(ocSep); 1468 1469 String aSig; 1470 1471 if ( nArgCount > 0 ) 1472 { 1473 if ( nArgCount < VAR_ARGS ) 1474 { 1475 sal_uInt16 nLastSuppressed = nArgCount; 1476 sal_uInt16 nLastAdded = nArgCount; 1477 for ( sal_uInt16 i=0; i<nArgCount; i++ ) 1478 { 1479 if (pDefArgFlags[i].bSuppress) 1480 nLastSuppressed = i; 1481 else 1482 { 1483 nLastAdded = i; 1484 aSig += *(ppDefArgNames[i]); 1485 if ( i != nArgCount-1 ) 1486 { 1487 aSig.Append(sep); 1488 aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " )); 1489 } 1490 } 1491 } 1492 // If only suppressed parameters follow the last added parameter, 1493 // remove one "; " 1494 if (nLastSuppressed < nArgCount && nLastAdded < nLastSuppressed && 1495 aSig.Len() >= 2) 1496 aSig.Erase( aSig.Len() - 2 ); 1497 } 1498 else 1499 { 1500 sal_uInt16 nFix = nArgCount - VAR_ARGS; 1501 for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ ) 1502 { 1503 if (!pDefArgFlags[nArg].bSuppress) 1504 { 1505 aSig += *(ppDefArgNames[nArg]); 1506 aSig.Append(sep); 1507 aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " )); 1508 } 1509 } 1510 /* NOTE: Currently there are no suppressed var args parameters. If 1511 * there were, we'd have to cope with it here and above for the fix 1512 * parameters. For now parameters are always added, so no special 1513 * treatment of a trailing "; " necessary. */ 1514 aSig += *(ppDefArgNames[nFix]); 1515 aSig += '1'; 1516 aSig.Append(sep); 1517 aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " )); 1518 aSig += *(ppDefArgNames[nFix]); 1519 aSig += '2'; 1520 aSig.Append(sep); 1521 aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ... " )); 1522 } 1523 } 1524 1525 return aSig; 1526 } 1527 1528 //------------------------------------------------------------------------ 1529 1530 String ScFuncDesc::GetSignature() const 1531 { 1532 String aSig; 1533 1534 if(pFuncName) 1535 { 1536 aSig = *pFuncName; 1537 1538 String aParamList( GetParamList() ); 1539 if( aParamList.Len() ) 1540 { 1541 aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "( " )); 1542 aSig.Append( aParamList ); 1543 // U+00A0 (NBSP) prevents automatic line break 1544 aSig.Append( static_cast< sal_Unicode >(0xA0) ).Append( ')' ); 1545 } 1546 else 1547 aSig.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" )); 1548 } 1549 return aSig; 1550 } 1551 1552 //------------------------------------------------------------------------ 1553 1554 ::rtl::OUString ScFuncDesc::getFormula( const ::std::vector< ::rtl::OUString >& _aArguments ) const 1555 { 1556 const String& sep = ScCompiler::GetNativeSymbol(ocSep); 1557 1558 ::rtl::OUStringBuffer aFormula; 1559 1560 if(pFuncName) 1561 { 1562 aFormula.append( *pFuncName ); 1563 1564 aFormula.appendAscii( "(" ); 1565 ::std::vector< ::rtl::OUString >::const_iterator aIter = _aArguments.begin(); 1566 ::std::vector< ::rtl::OUString >::const_iterator aEnd = _aArguments.end(); 1567 1568 if ( nArgCount > 0 && aIter != aEnd ) 1569 { 1570 sal_Bool bLastArg = ( aIter->getLength() == 0 ); 1571 1572 while( aIter != aEnd && !bLastArg ) 1573 { 1574 aFormula.append( *(aIter) ); 1575 if ( aIter != (aEnd-1) ) 1576 { 1577 bLastArg = !( (aIter+1)->getLength() > 0 ); 1578 if ( !bLastArg ) 1579 aFormula.append( sep ); 1580 } 1581 1582 ++aIter; 1583 } 1584 } 1585 1586 aFormula.appendAscii( ")" ); 1587 } 1588 return aFormula.makeStringAndClear(); 1589 } 1590 1591 //------------------------------------------------------------------------ 1592 1593 sal_uInt16 ScFuncDesc::GetSuppressedArgCount() const 1594 { 1595 if (!bHasSuppressedArgs || !pDefArgFlags) 1596 return nArgCount; 1597 1598 sal_uInt16 nArgs = nArgCount; 1599 if (nArgs >= VAR_ARGS) 1600 nArgs -= VAR_ARGS - 1; 1601 sal_uInt16 nCount = nArgs; 1602 for (sal_uInt16 i=0; i < nArgs; ++i) 1603 { 1604 if (pDefArgFlags[i].bSuppress) 1605 --nCount; 1606 } 1607 if (nArgCount >= VAR_ARGS) 1608 nCount += VAR_ARGS - 1; 1609 return nCount; 1610 } 1611 1612 //------------------------------------------------------------------------ 1613 1614 ::rtl::OUString ScFuncDesc::getFunctionName() const 1615 { 1616 ::rtl::OUString sRet; 1617 if ( pFuncName ) 1618 sRet = *pFuncName; 1619 return sRet; 1620 } 1621 // ----------------------------------------------------------------------------- 1622 const formula::IFunctionCategory* ScFuncDesc::getCategory() const 1623 { 1624 return ScGlobal::GetStarCalcFunctionMgr()->getCategory(nCategory); 1625 } 1626 // ----------------------------------------------------------------------------- 1627 ::rtl::OUString ScFuncDesc::getDescription() const 1628 { 1629 ::rtl::OUString sRet; 1630 if ( pFuncDesc ) 1631 sRet = *pFuncDesc; 1632 return sRet; 1633 } 1634 // ----------------------------------------------------------------------------- 1635 // GetSuppressedArgCount 1636 xub_StrLen ScFuncDesc::getSuppressedArgumentCount() const 1637 { 1638 return GetSuppressedArgCount(); 1639 } 1640 // ----------------------------------------------------------------------------- 1641 // 1642 void ScFuncDesc::fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const 1643 { 1644 if (!bHasSuppressedArgs || !pDefArgFlags) 1645 { 1646 _rArguments.resize( nArgCount); 1647 ::std::iota( _rArguments.begin(), _rArguments.end(), 0); 1648 } 1649 1650 _rArguments.reserve( nArgCount); 1651 sal_uInt16 nArgs = nArgCount; 1652 if (nArgs >= VAR_ARGS) 1653 nArgs -= VAR_ARGS - 1; 1654 for (sal_uInt16 i=0; i < nArgs; ++i) 1655 { 1656 if (!pDefArgFlags[i].bSuppress) 1657 _rArguments.push_back(i); 1658 } 1659 } 1660 // ----------------------------------------------------------------------------- 1661 void ScFuncDesc::initArgumentInfo() const 1662 { 1663 // get the full argument description 1664 // (add-in has to be instantiated to get the type information) 1665 1666 if ( bIncomplete && pFuncName ) 1667 { 1668 ScUnoAddInCollection& rAddIns = *ScGlobal::GetAddInCollection(); 1669 String aIntName = rAddIns.FindFunction( *pFuncName, sal_True ); // pFuncName is upper-case 1670 1671 if ( aIntName.Len() ) 1672 { 1673 // GetFuncData with bComplete=true loads the component and updates 1674 // the global function list if needed. 1675 1676 rAddIns.GetFuncData( aIntName, true ); 1677 } 1678 1679 if ( bIncomplete ) 1680 { 1681 DBG_ERRORFILE( "couldn't initialize add-in function" ); 1682 const_cast<ScFuncDesc*>(this)->bIncomplete = sal_False; // even if there was an error, don't try again 1683 } 1684 } 1685 } 1686 // ----------------------------------------------------------------------------- 1687 ::rtl::OUString ScFuncDesc::getSignature() const 1688 { 1689 return GetSignature(); 1690 } 1691 // ----------------------------------------------------------------------------- 1692 rtl::OString ScFuncDesc::getHelpId() const 1693 { 1694 return sHelpId; 1695 } 1696 // ----------------------------------------------------------------------------- 1697 1698 // parameter 1699 sal_uInt32 ScFuncDesc::getParameterCount() const 1700 { 1701 return nArgCount; 1702 } 1703 // ----------------------------------------------------------------------------- 1704 ::rtl::OUString ScFuncDesc::getParameterName(sal_uInt32 _nPos) const 1705 { 1706 return *(ppDefArgNames[_nPos]); 1707 } 1708 // ----------------------------------------------------------------------------- 1709 ::rtl::OUString ScFuncDesc::getParameterDescription(sal_uInt32 _nPos) const 1710 { 1711 return *(ppDefArgDescs[_nPos]); 1712 } 1713 // ----------------------------------------------------------------------------- 1714 bool ScFuncDesc::isParameterOptional(sal_uInt32 _nPos) const 1715 { 1716 return pDefArgFlags[_nPos].bOptional; 1717 } 1718 // ----------------------------------------------------------------------------- 1719 //======================================================================== 1720 // class ScFunctionMgr: 1721 1722 ScFunctionMgr::ScFunctionMgr() 1723 : pFuncList ( ScGlobal::GetStarCalcFunctionList() ), 1724 pCurCatList ( NULL ) 1725 { 1726 DBG_ASSERT( pFuncList, "Funktionsliste nicht gefunden." ); 1727 sal_uLong nCount = pFuncList->GetCount(); 1728 const ScFuncDesc* pDesc; 1729 List* pRootList; 1730 sal_uLong n; 1731 1732 for ( sal_uInt16 i=0; i<MAX_FUNCCAT; i++ ) // Kategorie-Listen erstellen 1733 aCatLists[i] = new List; 1734 1735 pRootList = aCatLists[0]; // Gesamtliste ("Alle") erstellen 1736 CollatorWrapper* pCaseCollator = ScGlobal::GetCaseCollator(); 1737 for ( n=0; n<nCount; n++ ) 1738 { 1739 sal_uLong nTmpCnt=0; 1740 pDesc = pFuncList->GetFunction(n); 1741 for (nTmpCnt = 0; nTmpCnt < n; nTmpCnt++) 1742 { 1743 // ist zwar case-sensitiv, aber Umlaute muessen richtig einsortiert werden 1744 1745 const ScFuncDesc* pTmpDesc = (const ScFuncDesc*)pRootList->GetObject(nTmpCnt); 1746 if ( pCaseCollator->compareString(*pDesc->pFuncName, *pTmpDesc->pFuncName ) == COMPARE_LESS ) 1747 break; 1748 } 1749 pRootList->Insert((void*)pDesc, nTmpCnt); // Einsortieren 1750 } 1751 1752 for ( n=0; n<nCount; n++ ) // in Gruppenlisten kopieren 1753 { 1754 pDesc = (const ScFuncDesc*)pRootList->GetObject(n); 1755 DBG_ASSERT((pDesc->nCategory) < MAX_FUNCCAT, "Unbekannte Kategorie"); 1756 if ((pDesc->nCategory) < MAX_FUNCCAT) 1757 aCatLists[pDesc->nCategory]->Insert((void*)pDesc, LIST_APPEND); 1758 } 1759 } 1760 1761 //------------------------------------------------------------------------ 1762 1763 ScFunctionMgr::~ScFunctionMgr() 1764 { 1765 for (sal_uInt16 i = 0; i < MAX_FUNCCAT; i++) 1766 delete aCatLists[i]; 1767 // delete pFuncList; // Macht spaeter die App 1768 } 1769 1770 //------------------------------------------------------------------------ 1771 1772 const ScFuncDesc* ScFunctionMgr::Get( const String& rFName ) const 1773 { 1774 const ScFuncDesc* pDesc = NULL; 1775 if (rFName.Len() <= pFuncList->GetMaxFuncNameLen()) 1776 for (pDesc = First(0); pDesc; pDesc = Next()) 1777 if (rFName.EqualsIgnoreCaseAscii(*(pDesc->pFuncName))) 1778 break; 1779 return pDesc; 1780 } 1781 1782 //------------------------------------------------------------------------ 1783 1784 const ScFuncDesc* ScFunctionMgr::Get( sal_uInt16 nFIndex ) const 1785 { 1786 const ScFuncDesc* pDesc; 1787 for (pDesc = First(0); pDesc; pDesc = Next()) 1788 if (pDesc->nFIndex == nFIndex) 1789 break; 1790 return pDesc; 1791 } 1792 1793 //------------------------------------------------------------------------ 1794 1795 const ScFuncDesc* ScFunctionMgr::First( sal_uInt16 nCategory ) const 1796 { 1797 DBG_ASSERT( nCategory < MAX_FUNCCAT, "Unbekannte Kategorie" ); 1798 1799 if ( nCategory < MAX_FUNCCAT ) 1800 { 1801 pCurCatList = aCatLists[nCategory]; 1802 return (const ScFuncDesc*)pCurCatList->First(); 1803 } 1804 else 1805 { 1806 pCurCatList = NULL; 1807 return NULL; 1808 } 1809 } 1810 1811 //------------------------------------------------------------------------ 1812 1813 const ScFuncDesc* ScFunctionMgr::Next() const 1814 { 1815 if ( pCurCatList ) 1816 return (const ScFuncDesc*)pCurCatList->Next(); 1817 else 1818 return NULL; 1819 } 1820 sal_uInt32 ScFunctionMgr::getCount() const 1821 { 1822 return MAX_FUNCCAT - 1; 1823 } 1824 const formula::IFunctionCategory* ScFunctionMgr::getCategory(sal_uInt32 nCategory) const 1825 { 1826 formula::IFunctionCategory* pRet = NULL; 1827 if ( nCategory < (MAX_FUNCCAT-1) ) 1828 { 1829 pRet = new ScFunctionCategory(const_cast<ScFunctionMgr*>(this),aCatLists[nCategory+1],nCategory); // aCatLists[0] is "all" 1830 } 1831 return pRet; 1832 } 1833 // ----------------------------------------------------------------------------- 1834 const formula::IFunctionDescription* ScFunctionMgr::getFunctionByName(const ::rtl::OUString& _sFunctionName) const 1835 { 1836 return Get(_sFunctionName); 1837 } 1838 // ----------------------------------------------------------------------------- 1839 void ScFunctionMgr::fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& _rLastRUFunctions) const 1840 { 1841 #define LRU_MAX 10 1842 1843 const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions(); 1844 sal_uInt16 nLRUFuncCount = Min( rAppOpt.GetLRUFuncListCount(), (sal_uInt16)LRU_MAX ); 1845 sal_uInt16* pLRUListIds = rAppOpt.GetLRUFuncList(); 1846 1847 if ( pLRUListIds ) 1848 { 1849 for ( sal_uInt16 i=0; i<nLRUFuncCount; i++ ) 1850 _rLastRUFunctions.push_back( Get( pLRUListIds[i] ) ); 1851 } 1852 } 1853 // ----------------------------------------------------------------------------- 1854 String ScFunctionMgr::GetCategoryName(sal_uInt32 _nCategoryNumber ) 1855 { 1856 if ( _nCategoryNumber > SC_FUNCGROUP_COUNT ) 1857 { 1858 DBG_ERROR("Invalid category number!"); 1859 return String(); 1860 } // if ( _nCategoryNumber >= SC_FUNCGROUP_COUNT ) 1861 1862 ::std::auto_ptr<ScResourcePublisher> pCategories( new ScResourcePublisher( ScResId( RID_FUNCTION_CATEGORIES ) ) ); 1863 return String(ScResId((sal_uInt16)_nCategoryNumber)); 1864 } 1865 sal_Unicode ScFunctionMgr::getSingleToken(const formula::IFunctionManager::EToken _eToken) const 1866 { 1867 switch(_eToken) 1868 { 1869 case eOk: 1870 return ScCompiler::GetNativeSymbol(ocOpen).GetChar(0); 1871 case eClose: 1872 return ScCompiler::GetNativeSymbol(ocClose).GetChar(0); 1873 case eSep: 1874 return ScCompiler::GetNativeSymbol(ocSep).GetChar(0); 1875 case eArrayOpen: 1876 return ScCompiler::GetNativeSymbol(ocArrayOpen).GetChar(0); 1877 case eArrayClose: 1878 return ScCompiler::GetNativeSymbol(ocArrayClose).GetChar(0); 1879 } // switch(_eToken) 1880 return 0; 1881 } 1882 // ----------------------------------------------------------------------------- 1883 sal_uInt32 ScFunctionCategory::getCount() const 1884 { 1885 return m_pCategory->Count(); 1886 } 1887 // ----------------------------------------------------------------------------- 1888 const formula::IFunctionManager* ScFunctionCategory::getFunctionManager() const 1889 { 1890 return m_pMgr; 1891 } 1892 // ----------------------------------------------------------------------------- 1893 ::rtl::OUString ScFunctionCategory::getName() const 1894 { 1895 if ( !m_sName.getLength() ) 1896 m_sName = ScFunctionMgr::GetCategoryName(m_nCategory+1); 1897 return m_sName; 1898 } 1899 // ----------------------------------------------------------------------------- 1900 const formula::IFunctionDescription* ScFunctionCategory::getFunction(sal_uInt32 _nPos) const 1901 { 1902 const ScFuncDesc* pDesc = NULL; 1903 sal_uInt32 i = 0; 1904 for (pDesc = (const ScFuncDesc*)m_pCategory->First(); i < _nPos && pDesc; pDesc = (const ScFuncDesc*)m_pCategory->Next(),++i) 1905 ; 1906 return pDesc; 1907 } 1908 // ----------------------------------------------------------------------------- 1909 sal_uInt32 ScFunctionCategory::getNumber() const 1910 { 1911 return m_nCategory; 1912 } 1913 // ----------------------------------------------------------------------------- 1914 1915 //------------------------------------------------------------------------ 1916 1917 utl::TransliterationWrapper* ScGlobal::GetpTransliteration() //add by CHINA001 1918 { 1919 if ( !pTransliteration ) 1920 { 1921 const LanguageType eOfficeLanguage = Application::GetSettings().GetLanguage(); 1922 pTransliteration = new ::utl::TransliterationWrapper( 1923 ::comphelper::getProcessServiceFactory(), SC_TRANSLITERATION_IGNORECASE ); 1924 pTransliteration->loadModuleIfNeeded( eOfficeLanguage ); 1925 } 1926 DBG_ASSERT( 1927 pTransliteration, 1928 "ScGlobal::GetpTransliteration() called before ScGlobal::Init()"); 1929 return pTransliteration; 1930 } 1931 1932 const LocaleDataWrapper* ScGlobal::GetpLocaleData() 1933 { 1934 DBG_ASSERT( 1935 pLocaleData, 1936 "ScGlobal::GetpLocaleData() called before ScGlobal::Init()"); 1937 return pLocaleData; 1938 } 1939 CalendarWrapper* ScGlobal::GetCalendar() 1940 { 1941 if ( !pCalendar ) 1942 { 1943 pCalendar = new CalendarWrapper( ::comphelper::getProcessServiceFactory() ); 1944 pCalendar->loadDefaultCalendar( *GetLocale() ); 1945 } 1946 return pCalendar; 1947 } 1948 CollatorWrapper* ScGlobal::GetCollator() 1949 { 1950 if ( !pCollator ) 1951 { 1952 pCollator = new CollatorWrapper( ::comphelper::getProcessServiceFactory() ); 1953 pCollator->loadDefaultCollator( *GetLocale(), SC_COLLATOR_IGNORES ); 1954 } // if ( !pCollator ) 1955 return pCollator; 1956 } 1957 CollatorWrapper* ScGlobal::GetCaseCollator() 1958 { 1959 if ( !pCaseCollator ) 1960 { 1961 pCaseCollator = new CollatorWrapper( ::comphelper::getProcessServiceFactory() ); 1962 pCaseCollator->loadDefaultCollator( *GetLocale(), 0 ); 1963 } // if ( !pCaseCollator ) 1964 return pCaseCollator; 1965 } 1966 ::utl::TransliterationWrapper* ScGlobal::GetCaseTransliteration() 1967 { 1968 if ( !pCaseTransliteration ) 1969 { 1970 const LanguageType eOfficeLanguage = Application::GetSettings().GetLanguage(); 1971 pCaseTransliteration = new ::utl::TransliterationWrapper(::comphelper::getProcessServiceFactory(), SC_TRANSLITERATION_CASESENSE ); 1972 pCaseTransliteration->loadModuleIfNeeded( eOfficeLanguage ); 1973 } // if ( !pCaseTransliteration ) 1974 return pCaseTransliteration; 1975 } 1976 IntlWrapper* ScGlobal::GetScIntlWrapper() 1977 { 1978 if ( !pScIntlWrapper ) 1979 { 1980 pScIntlWrapper = new IntlWrapper( ::comphelper::getProcessServiceFactory(), *GetLocale() ); 1981 } 1982 return pScIntlWrapper; 1983 } 1984 ::com::sun::star::lang::Locale* ScGlobal::GetLocale() 1985 { 1986 if ( !pLocale ) 1987 { 1988 pLocale = new ::com::sun::star::lang::Locale( Application::GetSettings().GetLocale()); 1989 } 1990 return pLocale; 1991 } 1992 1993