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
HasAttrChanged(const SfxItemSet & rNewAttrs,const SfxItemSet & rOldAttrs,const sal_uInt16 nWhich)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
GetStandardFormat(SvNumberFormatter & rFormatter,sal_uLong nFormat,short nType)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
GetStandardFormat(double fNumber,SvNumberFormatter & rFormatter,sal_uLong nFormat,short nType)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
GetEnglishFormatter()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
CheckWidthInvalidate(sal_Bool & bNumFormatChanged,const SfxItemSet & rNewAttrs,const SfxItemSet & rOldAttrs)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
GetSearchItem()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
SetSearchItem(const SvxSearchItem & rNew)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
ClearAutoFormat()286 void ScGlobal::ClearAutoFormat()
287 {
288 if (pAutoFormat!=NULL)
289 {
290 delete pAutoFormat;
291 pAutoFormat=NULL;
292 }
293 }
294
GetAutoFormat()295 ScAutoFormat* ScGlobal::GetAutoFormat()
296 {
297 if ( !pAutoFormat )
298 {
299 pAutoFormat = new ScAutoFormat;
300 pAutoFormat->Load();
301 }
302
303 return pAutoFormat;
304 }
305
GetFuncCollection()306 FuncCollection* ScGlobal::GetFuncCollection()
307 {
308 if (!pFuncCollection)
309 pFuncCollection = new FuncCollection();
310 return pFuncCollection;
311 }
312
GetAddInCollection()313 ScUnoAddInCollection* ScGlobal::GetAddInCollection()
314 {
315 if (!pAddInCollection)
316 pAddInCollection = new ScUnoAddInCollection();
317 return pAddInCollection;
318 }
319
GetUserList()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
SetUserList(const ScUserList * pNewList)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
GetRscString(sal_uInt16 nIndex)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
GetErrorString(sal_uInt16 nErrNumber)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
GetLongErrorString(sal_uInt16 nErrNumber)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
GetButtonBrushItem()511 SvxBrushItem* ScGlobal::GetButtonBrushItem()
512 {
513 pButtonBrushItem->SetColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
514 return pButtonBrushItem;
515 }
516
GetEmptyString()517 const String& ScGlobal::GetEmptyString()
518 {
519 return *pEmptyString;
520 }
521
GetOutlineSymbols(bool bHC)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
Init()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
UpdatePPT(OutputDevice * pDev)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
GetClipDocName()588 const String& ScGlobal::GetClipDocName()
589 {
590 return *pStrClipDocName;
591 }
592
SetClipDocName(const String & rNew)593 void ScGlobal::SetClipDocName( const String& rNew )
594 {
595 *pStrClipDocName = rNew;
596 }
597
598
InitTextHeight(SfxItemPool * pPool)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
Clear()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
GetCharsetValue(const String & rCharSet)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
GetCharsetString(CharSet eVal)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
HasStarCalcFunctionList()738 bool ScGlobal::HasStarCalcFunctionList()
739 {
740 return ( pStarCalcFunctionList != NULL );
741 }
742
GetStarCalcFunctionList()743 ScFunctionList* ScGlobal::GetStarCalcFunctionList()
744 {
745 if ( !pStarCalcFunctionList )
746 pStarCalcFunctionList = new ScFunctionList;
747
748 return pStarCalcFunctionList;
749 }
750
751 //------------------------------------------------------------------------
752
GetStarCalcFunctionMgr()753 ScFunctionMgr* ScGlobal::GetStarCalcFunctionMgr()
754 {
755 if ( !pStarCalcFunctionMgr )
756 pStarCalcFunctionMgr = new ScFunctionMgr;
757
758 return pStarCalcFunctionMgr;
759 }
760
ResetFunctionList()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
GetUnitConverter()772 ScUnitConverter* ScGlobal::GetUnitConverter()
773 {
774 if ( !pUnitConverter )
775 pUnitConverter = new ScUnitConverter;
776
777 return pUnitConverter;
778 }
779
780
781 //------------------------------------------------------------------------
782
783 // static
UnicodeStrChr(const sal_Unicode * pStr,sal_Unicode c)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
AddToken(String & rTokenList,const String & rToken,sal_Unicode cSep,xub_StrLen nSepCount,bool bForceSep)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
IsQuoted(const String & rString,sal_Unicode cQuote)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
AddQuotes(String & rString,sal_Unicode cQuote,bool bEscapeEmbedded)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
EraseQuotes(String & rString,sal_Unicode cQuote,bool bUnescapeEmbedded)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
FindUnquoted(const String & rString,sal_Unicode cChar,xub_StrLen nStart,sal_Unicode cQuote)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
FindUnquoted(const sal_Unicode * pString,sal_Unicode cChar,sal_Unicode cQuote)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
EETextObjEqual(const EditTextObject * pObj1,const EditTextObject * pObj2)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
OpenURL(const String & rURL,const String & rTarget)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
IsSystemRTL()960 sal_Bool ScGlobal::IsSystemRTL()
961 {
962 return MsLangId::isRightToLeft( Application::GetSettings().GetLanguage() );
963 }
964
GetDefaultScriptType()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
GetEditDefaultLanguage()975 LanguageType ScGlobal::GetEditDefaultLanguage()
976 {
977 // used for EditEngine::SetDefaultLanguage
978
979 return Application::GetSettings().GetLanguage();
980 }
981
GetScriptedWhichID(sal_uInt8 nScriptType,sal_uInt16 nWhich)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
AddLanguage(SfxItemSet & rSet,SvNumberFormatter & rFormatter)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
ScFuncRes(ResId & aRes,ScFuncDesc * pDesc,bool & rbSuppressed)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
GetNum()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:
FreeResource()1208 void FreeResource() { Resource::FreeResource(); }
1209 public:
ScResourcePublisher(const ScResId & rId)1210 ScResourcePublisher( const ScResId& rId ) : Resource( rId ) {}
~ScResourcePublisher()1211 ~ScResourcePublisher() { FreeResource(); }
IsAvailableRes(const ResId & rId) const1212 sal_Bool IsAvailableRes( const ResId& rId ) const
1213 { return Resource::IsAvailableRes( rId ); }
1214
1215 };
1216
1217
ScFunctionList()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 themselfs 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
~ScFunctionList()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
ScFuncDesc()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
~ScFuncDesc()1426 ScFuncDesc::~ScFuncDesc()
1427 {
1428 Clear();
1429 }
1430
1431 //------------------------------------------------------------------------
1432
Clear()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
GetParamList() const1469 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
GetSignature() const1562 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
getFormula(const::std::vector<::rtl::OUString> & _aArguments) const1586 ::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
GetSuppressedArgCount() const1625 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
getFunctionName() const1650 ::rtl::OUString ScFuncDesc::getFunctionName() const
1651 {
1652 ::rtl::OUString sRet;
1653 if ( pFuncName )
1654 sRet = *pFuncName;
1655 return sRet;
1656 }
1657 // -----------------------------------------------------------------------------
getCategory() const1658 const formula::IFunctionCategory* ScFuncDesc::getCategory() const
1659 {
1660 return ScGlobal::GetStarCalcFunctionMgr()->getCategory(nCategory);
1661 }
1662 // -----------------------------------------------------------------------------
getDescription() const1663 ::rtl::OUString ScFuncDesc::getDescription() const
1664 {
1665 ::rtl::OUString sRet;
1666 if ( pFuncDesc )
1667 sRet = *pFuncDesc;
1668 return sRet;
1669 }
1670 // -----------------------------------------------------------------------------
1671 // GetSuppressedArgCount
getSuppressedArgumentCount() const1672 xub_StrLen ScFuncDesc::getSuppressedArgumentCount() const
1673 {
1674 return GetSuppressedArgCount();
1675 }
1676 // -----------------------------------------------------------------------------
1677 //
fillVisibleArgumentMapping(::std::vector<sal_uInt16> & _rArguments) const1678 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 // -----------------------------------------------------------------------------
initArgumentInfo() const1701 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 // -----------------------------------------------------------------------------
getSignature() const1727 ::rtl::OUString ScFuncDesc::getSignature() const
1728 {
1729 return GetSignature();
1730 }
1731 // -----------------------------------------------------------------------------
getHelpId() const1732 rtl::OString ScFuncDesc::getHelpId() const
1733 {
1734 return sHelpId;
1735 }
1736 // -----------------------------------------------------------------------------
1737
1738 // parameter
getParameterCount() const1739 sal_uInt32 ScFuncDesc::getParameterCount() const
1740 {
1741 return nArgCount;
1742 }
1743 // -----------------------------------------------------------------------------
getParameterName(sal_uInt32 _nPos) const1744 ::rtl::OUString ScFuncDesc::getParameterName(sal_uInt32 _nPos) const
1745 {
1746 return *(ppDefArgNames[_nPos]);
1747 }
1748 // -----------------------------------------------------------------------------
getParameterDescription(sal_uInt32 _nPos) const1749 ::rtl::OUString ScFuncDesc::getParameterDescription(sal_uInt32 _nPos) const
1750 {
1751 return *(ppDefArgDescs[_nPos]);
1752 }
1753 // -----------------------------------------------------------------------------
isParameterOptional(sal_uInt32 _nPos) const1754 bool ScFuncDesc::isParameterOptional(sal_uInt32 _nPos) const
1755 {
1756 return pDefArgFlags[_nPos].bOptional;
1757 }
1758 // -----------------------------------------------------------------------------
1759 //========================================================================
1760 // class ScFunctionMgr:
1761
ScFunctionMgr()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
~ScFunctionMgr()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
Get(const String & rFName) const1812 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
Get(sal_uInt16 nFIndex) const1824 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
First(sal_uInt16 nCategory) const1835 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
Next() const1853 const ScFuncDesc* ScFunctionMgr::Next() const
1854 {
1855 if ( pCurCatList )
1856 return (const ScFuncDesc*)pCurCatList->Next();
1857 else
1858 return NULL;
1859 }
getCount() const1860 sal_uInt32 ScFunctionMgr::getCount() const
1861 {
1862 return MAX_FUNCCAT - 1;
1863 }
getCategory(sal_uInt32 nCategory) const1864 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 // -----------------------------------------------------------------------------
getFunctionByName(const::rtl::OUString & _sFunctionName) const1874 const formula::IFunctionDescription* ScFunctionMgr::getFunctionByName(const ::rtl::OUString& _sFunctionName) const
1875 {
1876 return Get(_sFunctionName);
1877 }
1878 // -----------------------------------------------------------------------------
fillLastRecentlyUsedFunctions(::std::vector<const formula::IFunctionDescription * > & _rLastRUFunctions) const1879 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 // -----------------------------------------------------------------------------
GetCategoryName(sal_uInt32 _nCategoryNumber)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 }
getSingleToken(const formula::IFunctionManager::EToken _eToken) const1905 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 // -----------------------------------------------------------------------------
getCount() const1923 sal_uInt32 ScFunctionCategory::getCount() const
1924 {
1925 return m_pCategory->Count();
1926 }
1927 // -----------------------------------------------------------------------------
getFunctionManager() const1928 const formula::IFunctionManager* ScFunctionCategory::getFunctionManager() const
1929 {
1930 return m_pMgr;
1931 }
1932 // -----------------------------------------------------------------------------
getName() const1933 ::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 // -----------------------------------------------------------------------------
getFunction(sal_uInt32 _nPos) const1940 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 // -----------------------------------------------------------------------------
getNumber() const1949 sal_uInt32 ScFunctionCategory::getNumber() const
1950 {
1951 return m_nCategory;
1952 }
1953 // -----------------------------------------------------------------------------
1954
1955 //------------------------------------------------------------------------
1956
GetpTransliteration()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
GetpLocaleData()1972 const LocaleDataWrapper* ScGlobal::GetpLocaleData()
1973 {
1974 DBG_ASSERT(
1975 pLocaleData,
1976 "ScGlobal::GetpLocaleData() called before ScGlobal::Init()");
1977 return pLocaleData;
1978 }
GetCalendar()1979 CalendarWrapper* ScGlobal::GetCalendar()
1980 {
1981 if ( !pCalendar )
1982 {
1983 pCalendar = new CalendarWrapper( ::comphelper::getProcessServiceFactory() );
1984 pCalendar->loadDefaultCalendar( *GetLocale() );
1985 }
1986 return pCalendar;
1987 }
GetCollator()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 }
GetCaseCollator()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 }
GetCaseTransliteration()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 }
GetScIntlWrapper()2016 IntlWrapper* ScGlobal::GetScIntlWrapper()
2017 {
2018 if ( !pScIntlWrapper )
2019 {
2020 pScIntlWrapper = new IntlWrapper( ::comphelper::getProcessServiceFactory(), *GetLocale() );
2021 }
2022 return pScIntlWrapper;
2023 }
GetLocale()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