xref: /aoo4110/main/sc/source/core/data/global.cxx (revision b1cdbd2c)
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