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