1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: global.cxx,v $
10 * $Revision: 1.56.102.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
37 #include <vcl/svapp.hxx>
38 #include "scitems.hxx"
39 #include <svx/algitem.hxx>
40 #include <svx/brshitem.hxx>
41 #include <svx/editobj.hxx>
42 #include <svx/scripttypeitem.hxx>
43 #include <svx/srchitem.hxx>
44 #include <svx/langitem.hxx>
45 #include <sfx2/docfile.hxx>
46 #include <sfx2/dispatch.hxx>
47 #include <sfx2/objsh.hxx>
48 #include <sfx2/viewfrm.hxx>
49 #include <sfx2/viewsh.hxx>
50 #include <svtools/stritem.hxx>
51 #include <svtools/zforlist.hxx>
52 #include <svtools/zformat.hxx>
53 #include <vcl/image.hxx>
54 #include <vcl/virdev.hxx>
55 #include <tools/rcid.h>
56 #include <unotools/charclass.hxx>
63 #include <i18npool/mslangid.hxx>
64 #include <com/sun/star/lang/Locale.hpp>
65 #include <comphelper/processfactory.hxx>
66 #include <unotools/calendarwrapper.hxx>
67 #include <unotools/collatorwrapper.hxx>
68 #include <com/sun/star/i18n/CollatorOptions.hpp>
69 #include <unotools/intlwrapper.hxx>
70 #include <svtools/syslocale.hxx>
71 #include <unotools/transliterationwrapper.hxx>
74 #include "scresid.hxx"
75 #include "autoform.hxx"
76 #include "document.hxx"
77 #include "patattr.hxx"
78 #include "addincol.hxx"
79 #include "adiasync.hxx"
80 #include "userlist.hxx"
81 #include "interpre.hxx"
82 #include "strload.hxx"
83 #include "docpool.hxx"
84 #include "unitconv.hxx"
85 #include "compiler.hxx"
86 #include "parclass.hxx"
87 #include "funcdesc.hxx"
88 #include "globstr.hrc"
89 #include "scfuncs.hrc"
92 #include "appoptio.hxx"
94 // -----------------------------------------------------------------------
96 #define CLIPST_AVAILABLE 0
97 #define CLIPST_CAPTURED 1
98 #define CLIPST_DELETE 2
101 ScDocShellRef
* ScGlobal::pDrawClipDocShellRef
= NULL
;
102 SvxSearchItem
* ScGlobal::pSearchItem
= NULL
;
103 ScAutoFormat
* ScGlobal::pAutoFormat
= NULL
;
104 FuncCollection
* ScGlobal::pFuncCollection
= NULL
;
105 ScUnoAddInCollection
* ScGlobal::pAddInCollection
= NULL
;
106 ScUserList
* ScGlobal::pUserList
= NULL
;
107 String
** ScGlobal::ppRscString
= NULL
;
108 LanguageType
ScGlobal::eLnge
= LANGUAGE_SYSTEM
;
109 ::com::sun::star::lang::Locale
* ScGlobal::pLocale
= NULL
;
110 SvtSysLocale
* ScGlobal::pSysLocale
= NULL
;
111 const CharClass
* ScGlobal::pCharClass
= NULL
;
112 const LocaleDataWrapper
* ScGlobal::pLocaleData
= NULL
;
113 CalendarWrapper
* ScGlobal::pCalendar
= NULL
;
114 CollatorWrapper
* ScGlobal::pCollator
= NULL
;
115 CollatorWrapper
* ScGlobal::pCaseCollator
= NULL
;
116 ::utl::TransliterationWrapper
* ScGlobal::pTransliteration
= NULL
;
117 ::utl::TransliterationWrapper
* ScGlobal::pCaseTransliteration
= NULL
;
118 ::com::sun::star::uno::Reference
< ::com::sun::star::i18n::XOrdinalSuffix
> ScGlobal::xOrdinalSuffix
= NULL
;
119 IntlWrapper
* ScGlobal::pScIntlWrapper
= NULL
;
120 sal_Unicode
ScGlobal::cListDelimiter
= ',';
121 String
* ScGlobal::pEmptyString
= NULL
;
122 String
* ScGlobal::pStrClipDocName
= NULL
;
124 SvxBrushItem
* ScGlobal::pEmptyBrushItem
= NULL
;
125 SvxBrushItem
* ScGlobal::pButtonBrushItem
= NULL
;
126 SvxBrushItem
* ScGlobal::pEmbeddedBrushItem
= NULL
;
127 SvxBrushItem
* ScGlobal::pProtectedBrushItem
= NULL
;
129 ImageList
* ScGlobal::pOutlineBitmaps
= NULL
;
130 ImageList
* ScGlobal::pOutlineBitmapsHC
= NULL
;
132 ScFunctionList
* ScGlobal::pStarCalcFunctionList
= NULL
;
133 ScFunctionMgr
* ScGlobal::pStarCalcFunctionMgr
= NULL
;
135 ScUnitConverter
* ScGlobal::pUnitConverter
= NULL
;
136 SvNumberFormatter
* ScGlobal::pEnglishFormatter
= NULL
;
138 double ScGlobal::nScreenPPTX
= 96.0;
139 double ScGlobal::nScreenPPTY
= 96.0;
141 USHORT
ScGlobal::nDefFontHeight
= 240;
142 USHORT
ScGlobal::nStdRowHeight
= 257;
144 long ScGlobal::nLastRowHeightExtra
= 0;
145 long ScGlobal::nLastColWidthExtra
= STD_EXTRA_WIDTH
;
147 static USHORT nPPTZoom
= 0; // ScreenZoom used to determine nScreenPPTX/Y
154 bool SC_DLLPUBLIC
ScGetWriteTeamInfo()
160 SfxViewShell
* pScActiveViewShell
= NULL
; //! als Member !!!!!
161 USHORT nScClickMouseModifier
= 0; //! dito
162 USHORT nScFillModeMouseModifier
= 0; //! dito
164 // Hack: ScGlobal::GetUserList() muss InitAppOptions in der UI aufrufen,
165 // damit UserList aus Cfg geladen wird
167 void global_InitAppOptions();
169 //========================================================================
171 // statische Funktionen
173 //========================================================================
175 BOOL
ScGlobal::HasAttrChanged( const SfxItemSet
& rNewAttrs
,
176 const SfxItemSet
& rOldAttrs
,
177 const USHORT nWhich
)
179 BOOL bInvalidate
= FALSE
;
180 const SfxItemState eNewState
= rNewAttrs
.GetItemState( nWhich
);
181 const SfxItemState eOldState
= rOldAttrs
.GetItemState( nWhich
);
183 //----------------------------------------------------------
185 if ( eNewState
== eOldState
)
187 // beide Items gesetzt
188 // PoolItems, d.h. Pointer-Vergleich zulaessig
189 if ( SFX_ITEM_SET
== eOldState
)
190 bInvalidate
= (&rNewAttrs
.Get( nWhich
) != &rOldAttrs
.Get( nWhich
));
194 // ein Default-Item dabei
195 // PoolItems, d.h. Item-Vergleich noetig
197 const SfxPoolItem
& rOldItem
= ( SFX_ITEM_SET
== eOldState
)
198 ? rOldAttrs
.Get( nWhich
)
199 : rOldAttrs
.GetPool()->GetDefaultItem( nWhich
);
201 const SfxPoolItem
& rNewItem
= ( SFX_ITEM_SET
== eNewState
)
202 ? rNewAttrs
.Get( nWhich
)
203 : rNewAttrs
.GetPool()->GetDefaultItem( nWhich
);
205 bInvalidate
= sal::static_int_cast
<BOOL
>(rNewItem
!= rOldItem
);
211 ULONG
ScGlobal::GetStandardFormat( SvNumberFormatter
& rFormatter
,
212 ULONG nFormat
, short nType
)
214 const SvNumberformat
* pFormat
= rFormatter
.GetEntry( nFormat
);
216 return rFormatter
.GetStandardFormat( nFormat
, nType
, pFormat
->GetLanguage() );
217 return rFormatter
.GetStandardFormat( nType
, eLnge
);
220 ULONG
ScGlobal::GetStandardFormat( double fNumber
, SvNumberFormatter
& rFormatter
,
221 ULONG nFormat
, short nType
)
223 const SvNumberformat
* pFormat
= rFormatter
.GetEntry( nFormat
);
225 return rFormatter
.GetStandardFormat( fNumber
, nFormat
, nType
,
226 pFormat
->GetLanguage() );
227 return rFormatter
.GetStandardFormat( nType
, eLnge
);
232 SvNumberFormatter
* ScGlobal::GetEnglishFormatter()
234 if ( !pEnglishFormatter
)
236 pEnglishFormatter
= new SvNumberFormatter(
237 ::comphelper::getProcessServiceFactory(), LANGUAGE_ENGLISH_US
);
238 pEnglishFormatter
->SetEvalDateFormat( NF_EVALDATEFORMAT_INTL_FORMAT
);
240 return pEnglishFormatter
;
244 //------------------------------------------------------------------------
246 BOOL
ScGlobal::CheckWidthInvalidate( BOOL
& bNumFormatChanged
,
247 const SfxItemSet
& rNewAttrs
,
248 const SfxItemSet
& rOldAttrs
)
250 // Ueberpruefen, ob Attributaenderungen in rNewAttrs gegnueber
251 // rOldAttrs die Textbreite an einer Zelle ungueltig machen
254 HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_VALUE_FORMAT
);
255 return ( bNumFormatChanged
256 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_LANGUAGE_FORMAT
)
257 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_FONT
)
258 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_CJK_FONT
)
259 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_CTL_FONT
)
260 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_FONT_HEIGHT
)
261 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_CJK_FONT_HEIGHT
)
262 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_CTL_FONT_HEIGHT
)
263 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_FONT_WEIGHT
)
264 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_CJK_FONT_WEIGHT
)
265 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_CTL_FONT_WEIGHT
)
266 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_FONT_POSTURE
)
267 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_CJK_FONT_POSTURE
)
268 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_CTL_FONT_POSTURE
)
269 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_FONT_UNDERLINE
)
270 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_FONT_OVERLINE
)
271 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_FONT_CROSSEDOUT
)
272 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_FONT_CONTOUR
)
273 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_FONT_SHADOWED
)
274 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_STACKED
)
275 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_ROTATE_VALUE
)
276 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_ROTATE_MODE
)
277 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_LINEBREAK
)
278 || HasAttrChanged( rNewAttrs
, rOldAttrs
, ATTR_MARGIN
)
282 const SvxSearchItem
& ScGlobal::GetSearchItem()
286 pSearchItem
= new SvxSearchItem( SID_SEARCH_ITEM
);
287 pSearchItem
->SetAppFlag( SVX_SEARCHAPP_CALC
);
292 void ScGlobal::SetSearchItem( const SvxSearchItem
& rNew
)
294 // Hier waere ein Zuweisungsoperator ganz nett:
296 pSearchItem
= (SvxSearchItem
*)rNew
.Clone();
298 pSearchItem
->SetWhich( SID_SEARCH_ITEM
);
301 void ScGlobal::ClearAutoFormat()
303 if (pAutoFormat
!=NULL
)
310 ScAutoFormat
* ScGlobal::GetAutoFormat()
314 pAutoFormat
= new ScAutoFormat
;
321 FuncCollection
* ScGlobal::GetFuncCollection()
323 if (!pFuncCollection
)
324 pFuncCollection
= new FuncCollection();
325 return pFuncCollection
;
328 ScUnoAddInCollection
* ScGlobal::GetAddInCollection()
330 if (!pAddInCollection
)
331 pAddInCollection
= new ScUnoAddInCollection();
332 return pAddInCollection
;
335 ScUserList
* ScGlobal::GetUserList()
337 // Hack: Cfg-Item an der App ggF. laden
339 global_InitAppOptions();
342 pUserList
= new ScUserList();
346 void ScGlobal::SetUserList( const ScUserList
* pNewList
)
351 pUserList
= new ScUserList( *pNewList
);
353 *pUserList
= *pNewList
;
362 const String
& ScGlobal::GetRscString( USHORT nIndex
)
364 DBG_ASSERT( nIndex
< STR_COUNT
, "ScGlobal::GetRscString - invalid string index");
365 if( !ppRscString
[ nIndex
] )
368 // Map former globstr.src strings moved to compiler.src
383 case STR_NO_NAME_REF
:
396 ppRscString
[ nIndex
] = new String(
397 ScCompiler::GetNativeSymbol( eOp
));
399 ppRscString
[ nIndex
] = new String(
400 ScRscStrLoader( RID_GLOBSTR
, nIndex
).GetString());
402 return *ppRscString
[ nIndex
];
405 String
ScGlobal::GetErrorString(USHORT nErrNumber
)
410 case NOTAVAILABLE
: nErrNumber
= STR_NV_STR
; break;
411 case errNoRef
: nErrNumber
= STR_NO_REF_TABLE
; break;
412 case errNoName
: nErrNumber
= STR_NO_NAME_REF
; break;
413 case errNoAddin
: nErrNumber
= STR_NO_ADDIN
; break;
414 case errNoMacro
: nErrNumber
= STR_NO_MACRO
; break;
416 case errNoValue
: nErrNumber
= STR_NO_VALUE
; break;
417 case errNoCode
: nErrNumber
= STR_NULL_ERROR
; break;
418 case errDivisionByZero
: nErrNumber
= STR_DIV_ZERO
; break;
419 case errIllegalFPOperation
: nErrNumber
= STR_NUM_ERROR
; break;
421 default : sResStr
= GetRscString(STR_ERROR_STR
);
422 sResStr
+= String::CreateFromInt32( nErrNumber
);
427 sResStr
= GetRscString( nErrNumber
);
431 String
ScGlobal::GetLongErrorString(USHORT nErrNumber
)
438 case errIllegalArgument
:
439 nErrNumber
= STR_LONG_ERR_ILL_ARG
;
445 case errIllegalFPOperation
:
446 nErrNumber
= STR_LONG_ERR_ILL_FPO
;
449 nErrNumber
= STR_LONG_ERR_ILL_CHAR
;
451 case errIllegalParameter
:
452 nErrNumber
= STR_LONG_ERR_ILL_PAR
;
455 nErrNumber
= STR_LONG_ERR_ILL_SEP
;
458 case errPairExpected
:
459 nErrNumber
= STR_LONG_ERR_PAIR
;
461 case errOperatorExpected
:
462 nErrNumber
= STR_LONG_ERR_OP_EXP
;
464 case errVariableExpected
:
465 case errParameterExpected
:
466 nErrNumber
= STR_LONG_ERR_VAR_EXP
;
468 case errCodeOverflow
:
469 nErrNumber
= STR_LONG_ERR_CODE_OVF
;
471 case errStringOverflow
:
472 nErrNumber
= STR_LONG_ERR_STR_OVF
;
474 case errStackOverflow
:
475 case errInterpOverflow
:
476 nErrNumber
= STR_LONG_ERR_STACK_OVF
;
479 case errUnknownState
:
480 case errUnknownVariable
:
481 case errUnknownOpCode
:
482 case errUnknownStackVariable
:
483 case errUnknownToken
:
486 nErrNumber
= STR_LONG_ERR_SYNTAX
;
488 case errCircularReference
:
489 nErrNumber
= STR_LONG_ERR_CIRC_REF
;
491 case errNoConvergence
:
492 nErrNumber
= STR_LONG_ERR_NO_CONV
;
495 nErrNumber
= STR_LONG_ERR_NO_REF
;
498 nErrNumber
= STR_LONG_ERR_NO_NAME
;
501 nErrNumber
= STR_LONG_ERR_NO_ADDIN
;
504 nErrNumber
= STR_LONG_ERR_NO_MACRO
;
506 case errDivisionByZero
:
507 nErrNumber
= STR_LONG_ERR_DIV_ZERO
;
510 nErrNumber
= STR_ERR_LONG_NESTED_ARRAY
;
513 nErrNumber
= STR_LONG_ERR_NO_VALUE
;
516 nErrNumber
= STR_LONG_ERR_NV
;
519 nErrNumber
= STR_ERROR_STR
;
522 String
aRes( GetRscString( nErrNumber
) );
525 String
aOderSo( GetRscString( STR_ODER_SO
) );
526 aOderSo
.SearchAndReplace( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("%s")), aRes
);
532 SvxBrushItem
* ScGlobal::GetButtonBrushItem()
534 pButtonBrushItem
->SetColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
535 return pButtonBrushItem
;
538 const String
& ScGlobal::GetEmptyString()
540 return *pEmptyString
;
543 ImageList
* ScGlobal::GetOutlineSymbols( bool bHC
)
545 ImageList
*& rpImageList
= bHC
? pOutlineBitmapsHC
: pOutlineBitmaps
;
547 rpImageList
= new ImageList( ScResId( bHC
? RID_OUTLINEBITMAPS_H
: RID_OUTLINEBITMAPS
) );
551 void ScGlobal::Init()
553 pEmptyString
= new String
;
555 // Die Default-Sprache fuer Zahlenformate (ScGlobal::eLnge)
556 // muss immer LANGUAGE_SYSTEM sein
557 //! Dann kann auch die Variable raus
558 eLnge
= LANGUAGE_SYSTEM
;
560 //! Wenn Sortierung etc. von der Sprache der installierten Offfice-Version
561 //! abhaengen sollen, hier "Application::GetSettings().GetUILanguage()"
562 LanguageType eOfficeLanguage
= Application::GetSettings().GetLanguage();
563 pLocale
= new ::com::sun::star::lang::Locale( Application::GetSettings().GetLocale());
564 pSysLocale
= new SvtSysLocale
;
565 pCharClass
= pSysLocale
->GetCharClassPtr();
566 pLocaleData
= pSysLocale
->GetLocaleDataPtr();
567 pCalendar
= new CalendarWrapper( ::comphelper::getProcessServiceFactory() );
568 pCalendar
->loadDefaultCalendar( *pLocale
);
569 pCollator
= new CollatorWrapper( ::comphelper::getProcessServiceFactory() );
570 pCollator
->loadDefaultCollator( *pLocale
, SC_COLLATOR_IGNORES
);
571 pCaseCollator
= new CollatorWrapper( ::comphelper::getProcessServiceFactory() );
572 pCaseCollator
->loadDefaultCollator( *pLocale
, 0 );
573 pTransliteration
= new ::utl::TransliterationWrapper(
574 ::comphelper::getProcessServiceFactory(), SC_TRANSLITERATION_IGNORECASE
);
575 pTransliteration
->loadModuleIfNeeded( eOfficeLanguage
);
576 pCaseTransliteration
= new ::utl::TransliterationWrapper(
577 ::comphelper::getProcessServiceFactory(), SC_TRANSLITERATION_CASESENSE
);
578 pCaseTransliteration
->loadModuleIfNeeded( eOfficeLanguage
);
579 pScIntlWrapper
= new IntlWrapper( ::comphelper::getProcessServiceFactory(), *pLocale
);
581 ppRscString
= new String
*[ STR_COUNT
];
582 for( USHORT nC
= 0 ; nC
< STR_COUNT
; nC
++ ) ppRscString
[ nC
] = NULL
;
584 pEmptyBrushItem
= new SvxBrushItem( Color( COL_TRANSPARENT
), ATTR_BACKGROUND
);
585 pButtonBrushItem
= new SvxBrushItem( Color(), ATTR_BACKGROUND
);
586 pEmbeddedBrushItem
= new SvxBrushItem( Color( COL_LIGHTCYAN
), ATTR_BACKGROUND
);
587 pProtectedBrushItem
= new SvxBrushItem( Color( COL_LIGHTGRAY
), ATTR_BACKGROUND
);
590 //ScCompiler::InitSymbolsNative();
591 // ScParameterClassification _after_ Compiler, needs function resources if
592 // arguments are to be merged in, which in turn need strings of function
593 // names from the compiler.
594 ScParameterClassification::Init();
595 srand( (unsigned) time( NULL
) ); // Random Seed Init fuer Interpreter
599 pStrClipDocName
= new String( ScResId( SCSTR_NONAME
) );
600 *pStrClipDocName
+= '1';
602 // ScDocumentPool::InitVersionMaps() ist schon vorher gerufen worden
605 void ScGlobal::UpdatePPT( OutputDevice
* pDev
)
607 USHORT nCurrentZoom
= Application::GetSettings().GetStyleSettings().GetScreenZoom();
608 if ( nCurrentZoom
!= nPPTZoom
)
610 // Screen PPT values must be updated when ScreenZoom has changed.
611 // If called from Window::DataChanged, the window is passed as pDev,
612 // to make sure LogicToPixel uses a device which already uses the new zoom.
613 // For the initial settings, NULL is passed and GetDefaultDevice used.
616 pDev
= Application::GetDefaultDevice();
617 Point aPix1000
= pDev
->LogicToPixel( Point(1000,1000), MAP_TWIP
);
618 nScreenPPTX
= aPix1000
.X() / 1000.0;
619 nScreenPPTY
= aPix1000
.Y() / 1000.0;
620 nPPTZoom
= nCurrentZoom
;
624 const String
& ScGlobal::GetClipDocName()
626 return *pStrClipDocName
;
629 void ScGlobal::SetClipDocName( const String
& rNew
)
631 *pStrClipDocName
= rNew
;
635 void ScGlobal::InitTextHeight(SfxItemPool
* pPool
)
639 DBG_ERROR("kein Pool bei ScGlobal::InitTextHeight");
643 const ScPatternAttr
* pPattern
= (const ScPatternAttr
*)&pPool
->GetDefaultItem(ATTR_PATTERN
);
646 DBG_ERROR("kein Default-Pattern bei ScGlobal::InitTextHeight");
650 // String aTestString('X');
651 OutputDevice
* pDefaultDev
= Application::GetDefaultDevice();
652 VirtualDevice
aVirtWindow( *pDefaultDev
);
653 aVirtWindow
.SetMapMode(MAP_PIXEL
);
655 pPattern
->GetFont(aDefFont
, SC_AUTOCOL_BLACK
, &aVirtWindow
); // font color doesn't matter here
656 aVirtWindow
.SetFont(aDefFont
);
657 nDefFontHeight
= (USHORT
) aVirtWindow
.PixelToLogic(Size(0, aVirtWindow
.GetTextHeight()),
660 const SvxMarginItem
* pMargin
= (const SvxMarginItem
*)&pPattern
->GetItem(ATTR_MARGIN
);
662 nStdRowHeight
= (USHORT
) ( nDefFontHeight
+
663 pMargin
->GetTopMargin() + pMargin
->GetBottomMargin()
664 - STD_ROWHEIGHT_DIFF
);
667 void ScGlobal::Clear()
669 // asyncs _vor_ ExitExternalFunc zerstoeren!
670 theAddInAsyncTbl
.DeleteAndDestroy( 0, theAddInAsyncTbl
.Count() );
672 DELETEZ(pAutoFormat
);
673 DELETEZ(pSearchItem
);
674 DELETEZ(pFuncCollection
);
675 DELETEZ(pAddInCollection
);
678 for( USHORT nC
= 0 ; nC
< STR_COUNT
; nC
++ )
679 if( ppRscString
) delete ppRscString
[ nC
];
680 delete[] ppRscString
;
683 DELETEZ(pStarCalcFunctionList
); // vor ResMgr zerstoeren!
684 DELETEZ(pStarCalcFunctionMgr
);
685 ScParameterClassification::Exit();
686 ScCompiler::DeInit();
687 ScInterpreter::GlobalExit(); // statischen Stack loeschen
689 DELETEZ(pEmptyBrushItem
);
690 DELETEZ(pButtonBrushItem
);
691 DELETEZ(pEmbeddedBrushItem
);
692 DELETEZ(pProtectedBrushItem
);
693 DELETEZ(pOutlineBitmaps
);
694 DELETEZ(pOutlineBitmapsHC
);
695 // DELETEZ(pAnchorBitmap);
696 // DELETEZ(pGrayAnchorBitmap);
697 DELETEZ(pEnglishFormatter
);
698 DELETEZ(pCaseTransliteration
);
699 DELETEZ(pTransliteration
);
700 DELETEZ(pCaseCollator
);
703 //! do NOT delete pCharClass since it is a pointer to the single SvtSysLocale instance
705 //! do NOT delete pLocaleData since it is a pointer to the single SvtSysLocale instance
709 DELETEZ(pScIntlWrapper
);
710 DELETEZ(pStrClipDocName
);
712 DELETEZ(pUnitConverter
);
714 ScDocumentPool::DeleteVersionMaps();
716 DELETEZ(pEmptyString
);
719 //------------------------------------------------------------------------
722 CharSet
ScGlobal::GetCharsetValue( const String
& rCharSet
)
724 // new TextEncoding values
725 if ( CharClass::isAsciiNumeric( rCharSet
) )
727 sal_Int32 nVal
= rCharSet
.ToInt32();
728 if ( !nVal
|| nVal
== RTL_TEXTENCODING_DONTKNOW
)
729 return gsl_getSystemTextEncoding();
730 return (CharSet
) nVal
;
732 // old CharSet values for compatibility
733 else if (rCharSet
.EqualsIgnoreCaseAscii("ANSI") ) return RTL_TEXTENCODING_MS_1252
;
734 else if (rCharSet
.EqualsIgnoreCaseAscii("MAC") ) return RTL_TEXTENCODING_APPLE_ROMAN
;
735 else if (rCharSet
.EqualsIgnoreCaseAscii("IBMPC") ) return RTL_TEXTENCODING_IBM_850
;
736 else if (rCharSet
.EqualsIgnoreCaseAscii("IBMPC_437")) return RTL_TEXTENCODING_IBM_437
;
737 else if (rCharSet
.EqualsIgnoreCaseAscii("IBMPC_850")) return RTL_TEXTENCODING_IBM_850
;
738 else if (rCharSet
.EqualsIgnoreCaseAscii("IBMPC_860")) return RTL_TEXTENCODING_IBM_860
;
739 else if (rCharSet
.EqualsIgnoreCaseAscii("IBMPC_861")) return RTL_TEXTENCODING_IBM_861
;
740 else if (rCharSet
.EqualsIgnoreCaseAscii("IBMPC_863")) return RTL_TEXTENCODING_IBM_863
;
741 else if (rCharSet
.EqualsIgnoreCaseAscii("IBMPC_865")) return RTL_TEXTENCODING_IBM_865
;
742 // else if (rCharSet.EqualsIgnoreCaseAscii("SYSTEM") ) return gsl_getSystemTextEncoding();
743 else return gsl_getSystemTextEncoding();
746 //------------------------------------------------------------------------
749 String
ScGlobal::GetCharsetString( CharSet eVal
)
751 const sal_Char
* pChar
;
754 // old CharSet strings for compatibility
755 case RTL_TEXTENCODING_MS_1252
: pChar
= "ANSI"; break;
756 case RTL_TEXTENCODING_APPLE_ROMAN
: pChar
= "MAC"; break;
757 // IBMPC == IBMPC_850
758 case RTL_TEXTENCODING_IBM_437
: pChar
= "IBMPC_437"; break;
759 case RTL_TEXTENCODING_IBM_850
: pChar
= "IBMPC_850"; break;
760 case RTL_TEXTENCODING_IBM_860
: pChar
= "IBMPC_860"; break;
761 case RTL_TEXTENCODING_IBM_861
: pChar
= "IBMPC_861"; break;
762 case RTL_TEXTENCODING_IBM_863
: pChar
= "IBMPC_863"; break;
763 case RTL_TEXTENCODING_IBM_865
: pChar
= "IBMPC_865"; break;
764 case RTL_TEXTENCODING_DONTKNOW
: pChar
= "SYSTEM"; break;
765 // new string of TextEncoding value
767 return String::CreateFromInt32( eVal
);
769 return String::CreateFromAscii(pChar
);
772 //------------------------------------------------------------------------
774 bool ScGlobal::HasStarCalcFunctionList()
776 return ( pStarCalcFunctionList
!= NULL
);
779 ScFunctionList
* ScGlobal::GetStarCalcFunctionList()
781 if ( !pStarCalcFunctionList
)
782 pStarCalcFunctionList
= new ScFunctionList
;
784 return pStarCalcFunctionList
;
787 //------------------------------------------------------------------------
789 ScFunctionMgr
* ScGlobal::GetStarCalcFunctionMgr()
791 if ( !pStarCalcFunctionMgr
)
792 pStarCalcFunctionMgr
= new ScFunctionMgr
;
794 return pStarCalcFunctionMgr
;
797 void ScGlobal::ResetFunctionList()
799 // FunctionMgr has pointers into FunctionList, must also be updated
801 DELETEZ( pStarCalcFunctionMgr
);
802 DELETEZ( pStarCalcFunctionList
);
805 //------------------------------------------------------------------------
808 ScUnitConverter
* ScGlobal::GetUnitConverter()
810 if ( !pUnitConverter
)
811 pUnitConverter
= new ScUnitConverter
;
813 return pUnitConverter
;
817 //------------------------------------------------------------------------
820 const sal_Unicode
* ScGlobal::UnicodeStrChr( const sal_Unicode
* pStr
,
834 // ----------------------------------------------------------------------------
836 void ScGlobal::AddToken( String
& rTokenList
, const String
& rToken
, sal_Unicode cSep
, xub_StrLen nSepCount
, bool bForceSep
)
838 if( bForceSep
|| (rToken
.Len() && rTokenList
.Len()) )
839 rTokenList
.Expand( rTokenList
.Len() + nSepCount
, cSep
);
840 rTokenList
.Append( rToken
);
843 bool ScGlobal::IsQuoted( const String
& rString
, sal_Unicode cQuote
)
845 return (rString
.Len() >= 2) && (rString
.GetChar( 0 ) == cQuote
) && (rString
.GetChar( rString
.Len() - 1 ) == cQuote
);
848 void ScGlobal::AddQuotes( String
& rString
, sal_Unicode cQuote
, bool bEscapeEmbedded
)
853 pQ
[0] = pQ
[1] = cQuote
;
855 String
aQuotes( pQ
);
856 rString
.SearchAndReplaceAll( cQuote
, aQuotes
);
858 rString
.Insert( cQuote
, 0 ).Append( cQuote
);
861 void ScGlobal::EraseQuotes( String
& rString
, sal_Unicode cQuote
, bool bUnescapeEmbedded
)
863 if ( IsQuoted( rString
, cQuote
) )
865 rString
.Erase( rString
.Len() - 1 ).Erase( 0, 1 );
866 if (bUnescapeEmbedded
)
869 pQ
[0] = pQ
[1] = cQuote
;
871 String
aQuotes( pQ
);
872 rString
.SearchAndReplaceAll( aQuotes
, cQuote
);
877 xub_StrLen
ScGlobal::FindUnquoted( const String
& rString
, sal_Unicode cChar
, xub_StrLen nStart
, sal_Unicode cQuote
)
879 const sal_Unicode
* const pStart
= rString
.GetBuffer();
880 const sal_Unicode
* const pStop
= pStart
+ rString
.Len();
881 const sal_Unicode
* p
= pStart
+ nStart
;
882 bool bQuoted
= false;
885 if (*p
== cChar
&& !bQuoted
)
886 return sal::static_int_cast
< xub_StrLen
>( p
- pStart
);
887 else if (*p
== cQuote
)
891 else if (p
< pStop
-1 && *(p
+1) == cQuote
)
898 return STRING_NOTFOUND
;
901 const sal_Unicode
* ScGlobal::FindUnquoted( const sal_Unicode
* pString
, sal_Unicode cChar
, sal_Unicode cQuote
)
903 const sal_Unicode
* p
= pString
;
904 bool bQuoted
= false;
907 if (*p
== cChar
&& !bQuoted
)
909 else if (*p
== cQuote
)
913 else if (*(p
+1) == cQuote
)
923 //------------------------------------------------------------------------
925 BOOL
ScGlobal::EETextObjEqual( const EditTextObject
* pObj1
,
926 const EditTextObject
* pObj2
)
928 if ( pObj1
== pObj2
) // both empty or the same object
931 if ( pObj1
&& pObj2
)
933 // first test for equal text content
934 USHORT nParCount
= pObj1
->GetParagraphCount();
935 if ( nParCount
!= pObj2
->GetParagraphCount() )
937 for (USHORT nPar
=0; nPar
<nParCount
; nPar
++)
938 if ( pObj1
->GetText(nPar
) != pObj2
->GetText(nPar
) )
941 SvMemoryStream aStream1
;
942 SvMemoryStream aStream2
;
943 pObj1
->Store( aStream1
);
944 pObj2
->Store( aStream2
);
945 ULONG nSize
= aStream1
.Tell();
946 if ( aStream2
.Tell() == nSize
)
947 if ( !memcmp( aStream1
.GetData(), aStream2
.GetData(), (USHORT
) nSize
) )
954 void ScGlobal::OpenURL( const String
& rURL
, const String
& rTarget
)
956 // OpenURL wird immer ueber irgendwelche Umwege durch Mausklicks im GridWindow
957 // aufgerufen, darum stimmen pScActiveViewShell und nScClickMouseModifier.
959 SfxStringItem
aUrl( SID_FILE_NAME
, rURL
);
960 SfxStringItem
aTarget( SID_TARGETNAME
, rTarget
);
962 if ( nScClickMouseModifier
& KEY_MOD1
) // control-click -> into new window
964 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("_blank")) );
966 SfxViewFrame
* pFrame
= NULL
;
968 if ( pScActiveViewShell
)
970 pFrame
= pScActiveViewShell
->GetViewFrame();
971 SfxMedium
* pMed
= pFrame
->GetObjectShell()->GetMedium();
973 aReferName
= pMed
->GetName();
976 SfxFrameItem
aFrm( SID_DOCFRAME
, pFrame
);
977 SfxStringItem
aReferer( SID_REFERER
, aReferName
);
979 SfxBoolItem
aNewView( SID_OPEN_NEW_VIEW
, FALSE
);
980 SfxBoolItem
aBrowsing( SID_BROWSE
, TRUE
);
982 // kein SID_SILENT mehr wegen Bug #42525# (war angeblich sowieso falsch)
984 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
986 pViewFrm
->GetDispatcher()->Execute( SID_OPENDOC
,
987 SFX_CALLMODE_ASYNCHRON
| SFX_CALLMODE_RECORD
,
990 &aNewView
, &aBrowsing
,
994 //------------------------------------------------------------------------
996 BOOL
ScGlobal::IsSystemRTL()
998 return MsLangId::isRightToLeft( Application::GetSettings().GetLanguage() );
1001 BYTE
ScGlobal::GetDefaultScriptType()
1003 // Used when text contains only WEAK characters.
1004 // Script type of office language is used then (same as GetEditDefaultLanguage,
1005 // to get consistent behavior of text in simple cells and EditEngine,
1006 // also same as GetAppLanguage() in Writer)
1008 return (BYTE
) SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguage() );
1011 LanguageType
ScGlobal::GetEditDefaultLanguage()
1013 // used for EditEngine::SetDefaultLanguage
1015 return Application::GetSettings().GetLanguage();
1018 USHORT
ScGlobal::GetScriptedWhichID( BYTE nScriptType
, USHORT nWhich
)
1020 switch ( nScriptType
)
1022 case SCRIPTTYPE_LATIN
:
1023 case SCRIPTTYPE_ASIAN
:
1024 case SCRIPTTYPE_COMPLEX
:
1025 break; // take exact matches
1026 default: // prefer one, first COMPLEX, then ASIAN
1027 if ( nScriptType
& SCRIPTTYPE_COMPLEX
)
1028 nScriptType
= SCRIPTTYPE_COMPLEX
;
1029 else if ( nScriptType
& SCRIPTTYPE_ASIAN
)
1030 nScriptType
= SCRIPTTYPE_ASIAN
;
1032 switch ( nScriptType
)
1034 case SCRIPTTYPE_COMPLEX
:
1040 nWhich
= ATTR_CTL_FONT
;
1042 case ATTR_FONT_HEIGHT
:
1043 case ATTR_CJK_FONT_HEIGHT
:
1044 nWhich
= ATTR_CTL_FONT_HEIGHT
;
1046 case ATTR_FONT_WEIGHT
:
1047 case ATTR_CJK_FONT_WEIGHT
:
1048 nWhich
= ATTR_CTL_FONT_WEIGHT
;
1050 case ATTR_FONT_POSTURE
:
1051 case ATTR_CJK_FONT_POSTURE
:
1052 nWhich
= ATTR_CTL_FONT_POSTURE
;
1057 case SCRIPTTYPE_ASIAN
:
1063 nWhich
= ATTR_CJK_FONT
;
1065 case ATTR_FONT_HEIGHT
:
1066 case ATTR_CTL_FONT_HEIGHT
:
1067 nWhich
= ATTR_CJK_FONT_HEIGHT
;
1069 case ATTR_FONT_WEIGHT
:
1070 case ATTR_CTL_FONT_WEIGHT
:
1071 nWhich
= ATTR_CJK_FONT_WEIGHT
;
1073 case ATTR_FONT_POSTURE
:
1074 case ATTR_CTL_FONT_POSTURE
:
1075 nWhich
= ATTR_CJK_FONT_POSTURE
;
1088 case ATTR_CTL_FONT_HEIGHT
:
1089 case ATTR_CJK_FONT_HEIGHT
:
1090 nWhich
= ATTR_FONT_HEIGHT
;
1092 case ATTR_CTL_FONT_WEIGHT
:
1093 case ATTR_CJK_FONT_WEIGHT
:
1094 nWhich
= ATTR_FONT_WEIGHT
;
1096 case ATTR_CTL_FONT_POSTURE
:
1097 case ATTR_CJK_FONT_POSTURE
:
1098 nWhich
= ATTR_FONT_POSTURE
;
1106 //------------------------------------------------------------------------
1108 void ScGlobal::AddLanguage( SfxItemSet
& rSet
, SvNumberFormatter
& rFormatter
)
1110 DBG_ASSERT( rSet
.GetItemState( ATTR_LANGUAGE_FORMAT
, FALSE
) == SFX_ITEM_DEFAULT
,
1111 "ScGlobal::AddLanguage - language already added");
1113 const SfxPoolItem
* pHardItem
;
1114 if ( rSet
.GetItemState( ATTR_VALUE_FORMAT
, FALSE
, &pHardItem
) == SFX_ITEM_SET
)
1116 const SvNumberformat
* pHardFormat
= rFormatter
.GetEntry(
1117 ((const SfxUInt32Item
*)pHardItem
)->GetValue() );
1119 ULONG nParentFmt
= 0; // pool default
1120 const SfxItemSet
* pParent
= rSet
.GetParent();
1122 nParentFmt
= ((const SfxUInt32Item
&)pParent
->Get( ATTR_VALUE_FORMAT
)).GetValue();
1123 const SvNumberformat
* pParFormat
= rFormatter
.GetEntry( nParentFmt
);
1125 if ( pHardFormat
&& pParFormat
&&
1126 (pHardFormat
->GetLanguage() != pParFormat
->GetLanguage()) )
1127 rSet
.Put( SvxLanguageItem( pHardFormat
->GetLanguage(), ATTR_LANGUAGE_FORMAT
) );
1135 //===================================================================
1136 // class ScFunctionList:
1137 //===================================================================
1139 //===================================================================
1141 // fuer temporaere Objekte zum Holen der Resourcen
1143 class ScFuncRes
: public Resource
1146 ScFuncRes( ResId
&, ScFuncDesc
*, bool & rbSuppressed
);
1152 //--------------------------------------------------------------------
1154 ScFuncRes::ScFuncRes( ResId
&aRes
, ScFuncDesc
* pDesc
, bool & rbSuppressed
)
1157 rbSuppressed
= (bool)GetNum();
1158 pDesc
->nCategory
= GetNum();
1159 pDesc
->nHelpId
= GetNum() + 32768; //! Hack, see scfuncs.src
1160 pDesc
->nArgCount
= GetNum();
1161 USHORT nArgs
= pDesc
->nArgCount
;
1162 if (nArgs
>= VAR_ARGS
)
1163 nArgs
-= VAR_ARGS
- 1;
1166 pDesc
->pDefArgFlags
= new ScFuncDesc::ParameterFlags
[nArgs
];
1167 for (USHORT i
= 0; i
< nArgs
; i
++)
1169 pDesc
->pDefArgFlags
[i
].bOptional
= (bool)GetNum();
1172 // Need to read the value from the resource even if nArgs==0 to advance the
1173 // resource position pointer, so this can't be in the if(nArgs) block above.
1174 USHORT nSuppressed
= GetNum();
1177 if (nSuppressed
> nArgs
)
1179 DBG_ERROR3( "ScFuncRes: suppressed parameters count mismatch on OpCode %u: suppressed %d > params %d",
1180 aRes
.GetId(), (int)nSuppressed
, (int)nArgs
);
1181 nSuppressed
= nArgs
; // sanitize
1183 for (USHORT i
=0; i
< nSuppressed
; ++i
)
1185 USHORT nParam
= GetNum();
1188 if (pDesc
->nArgCount
>= VAR_ARGS
&& nParam
== nArgs
-1)
1190 DBG_ERROR3( "ScFuncRes: VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d == arg %d-1",
1191 aRes
.GetId(), (int)nParam
, (int)nArgs
);
1195 pDesc
->pDefArgFlags
[nParam
].bSuppress
= true;
1196 pDesc
->bHasSuppressedArgs
= true;
1201 DBG_ERROR3( "ScFuncRes: suppressed parameter exceeds count on OpCode %u: param %d >= args %d",
1202 aRes
.GetId(), (int)nParam
, (int)nArgs
);
1207 pDesc
->pFuncName
= new String( ScCompiler::GetNativeSymbol( static_cast<OpCode
>( aRes
.GetId())));
1208 pDesc
->pFuncDesc
= new String(ScResId(1));
1212 pDesc
->ppDefArgNames
= new String
*[nArgs
];
1213 pDesc
->ppDefArgDescs
= new String
*[nArgs
];
1214 for (USHORT i
= 0; i
< nArgs
; i
++)
1216 pDesc
->ppDefArgNames
[i
] = new String(ScResId(2*(i
+1) ));
1217 pDesc
->ppDefArgDescs
[i
] = new String(ScResId(2*(i
+1)+1));
1224 //------------------------------------------------------------------------
1226 USHORT
ScFuncRes::GetNum()
1228 return ReadShortRes();
1231 //=========================================================================
1233 // um an die protected von Resource ranzukommen
1234 class ScResourcePublisher
: public Resource
1237 void FreeResource() { Resource::FreeResource(); }
1239 ScResourcePublisher( const ScResId
& rId
) : Resource( rId
) {}
1240 ~ScResourcePublisher() { FreeResource(); }
1241 BOOL
IsAvailableRes( const ResId
& rId
) const
1242 { return Resource::IsAvailableRes( rId
); }
1247 ScFunctionList::ScFunctionList() :
1248 nMaxFuncNameLen ( 0 )
1250 ScFuncDesc
* pDesc
= NULL
;
1251 xub_StrLen nStrLen
= 0;
1252 FuncCollection
* pFuncColl
;
1254 USHORT nDescBlock
[] =
1256 RID_SC_FUNCTION_DESCRIPTIONS1
,
1257 RID_SC_FUNCTION_DESCRIPTIONS2
1259 const USHORT nBlocks
= sizeof(nDescBlock
) / sizeof(USHORT
);
1261 aFunctionList
.Clear();
1263 for ( USHORT k
= 0; k
< nBlocks
; k
++ )
1265 ::std::auto_ptr
<ScResourcePublisher
> pBlock( new ScResourcePublisher( ScResId( nDescBlock
[k
] ) ) );
1266 // Browse for all possible OpCodes. This is not the fastest method, but
1267 // otherwise the sub resources within the resource blocks and the
1268 // resource blocks themselfs would had to be ordered according to
1269 // OpCodes, which is utopian..
1270 for (i
= 0; i
<= SC_OPCODE_LAST_OPCODE_ID
; i
++)
1273 aRes
.SetRT(RSC_RESOURCE
);
1274 // Sub resource of OpCode available?
1275 if (pBlock
->IsAvailableRes(aRes
))
1277 pDesc
= new ScFuncDesc
;
1278 bool bSuppressed
= false;
1279 ScFuncRes
aSubRes( aRes
, pDesc
, bSuppressed
);
1280 // Instead of dealing with this exceptional case at 1001 places
1281 // we simply don't add an entirely suppressed function to the
1282 // list and delete it.
1288 aFunctionList
.Insert( pDesc
, LIST_APPEND
);
1290 nStrLen
= (*(pDesc
->pFuncName
)).Len();
1291 if (nStrLen
> nMaxFuncNameLen
)
1292 nMaxFuncNameLen
= nStrLen
;
1298 USHORT nNextId
= SC_OPCODE_LAST_OPCODE_ID
+ 1; // FuncID for AddIn functions
1300 // Auswertung AddIn-Liste
1301 String
aDefArgNameValue(RTL_CONSTASCII_STRINGPARAM("value"));
1302 String
aDefArgNameString(RTL_CONSTASCII_STRINGPARAM("string"));
1303 String
aDefArgNameValues(RTL_CONSTASCII_STRINGPARAM("values"));
1304 String
aDefArgNameStrings(RTL_CONSTASCII_STRINGPARAM("strings"));
1305 String
aDefArgNameCells(RTL_CONSTASCII_STRINGPARAM("cells"));
1306 String
aDefArgNameNone(RTL_CONSTASCII_STRINGPARAM("none"));
1307 String
aDefArgDescValue(RTL_CONSTASCII_STRINGPARAM("a value"));
1308 String
aDefArgDescString(RTL_CONSTASCII_STRINGPARAM("a string"));
1309 String
aDefArgDescValues(RTL_CONSTASCII_STRINGPARAM("array of values"));
1310 String
aDefArgDescStrings(RTL_CONSTASCII_STRINGPARAM("array of strings"));
1311 String
aDefArgDescCells(RTL_CONSTASCII_STRINGPARAM("range of cells"));
1312 String
aDefArgDescNone(RTL_CONSTASCII_STRINGPARAM("none"));
1313 String aArgName
, aArgDesc
;
1314 pFuncColl
= ScGlobal::GetFuncCollection();
1315 for (i
= 0; i
< pFuncColl
->GetCount(); i
++)
1317 pDesc
= new ScFuncDesc
;
1318 FuncData
*pAddInFuncData
= (FuncData
*)pFuncColl
->At(i
);
1319 USHORT nArgs
= pAddInFuncData
->GetParamCount() - 1;
1320 pAddInFuncData
->GetParamDesc( aArgName
, aArgDesc
, 0 );
1321 pDesc
->nFIndex
= nNextId
++; // ??? OpCode vergeben
1322 pDesc
->nCategory
= ID_FUNCTION_GRP_ADDINS
;
1323 pDesc
->pFuncName
= new String(pAddInFuncData
->GetInternalName());
1324 pDesc
->pFuncName
->ToUpperAscii();
1325 pDesc
->pFuncDesc
= new String( aArgDesc
);
1326 *(pDesc
->pFuncDesc
) += '\n';
1327 pDesc
->pFuncDesc
->AppendAscii(RTL_CONSTASCII_STRINGPARAM( "( AddIn: " ));
1328 *(pDesc
->pFuncDesc
) += pAddInFuncData
->GetModuleName();
1329 pDesc
->pFuncDesc
->AppendAscii(RTL_CONSTASCII_STRINGPARAM( " )" ));
1330 pDesc
->nArgCount
= nArgs
;
1333 pDesc
->pDefArgFlags
= new ScFuncDesc::ParameterFlags
[nArgs
];
1334 pDesc
->ppDefArgNames
= new String
*[nArgs
];
1335 pDesc
->ppDefArgDescs
= new String
*[nArgs
];
1336 for (j
= 0; j
< nArgs
; j
++)
1338 pDesc
->pDefArgFlags
[j
].bOptional
= false;
1339 pDesc
->pDefArgFlags
[j
].bSuppress
= false;
1340 pAddInFuncData
->GetParamDesc( aArgName
, aArgDesc
, j
+1 );
1341 if ( aArgName
.Len() )
1342 pDesc
->ppDefArgNames
[j
] = new String( aArgName
);
1345 switch (pAddInFuncData
->GetParamType(j
+1))
1348 pDesc
->ppDefArgNames
[j
] = new String( aDefArgNameValue
);
1351 pDesc
->ppDefArgNames
[j
] = new String( aDefArgNameString
);
1353 case PTR_DOUBLE_ARR
:
1354 pDesc
->ppDefArgNames
[j
] = new String( aDefArgNameValues
);
1356 case PTR_STRING_ARR
:
1357 pDesc
->ppDefArgNames
[j
] = new String( aDefArgNameStrings
);
1360 pDesc
->ppDefArgNames
[j
] = new String( aDefArgNameCells
);
1363 pDesc
->ppDefArgNames
[j
] = new String( aDefArgNameNone
);
1367 if ( aArgDesc
.Len() )
1368 pDesc
->ppDefArgDescs
[j
] = new String( aArgDesc
);
1371 switch (pAddInFuncData
->GetParamType(j
+1))
1374 pDesc
->ppDefArgDescs
[j
] = new String( aDefArgDescValue
);
1377 pDesc
->ppDefArgDescs
[j
] = new String( aDefArgDescString
);
1379 case PTR_DOUBLE_ARR
:
1380 pDesc
->ppDefArgDescs
[j
] = new String( aDefArgDescValues
);
1382 case PTR_STRING_ARR
:
1383 pDesc
->ppDefArgDescs
[j
] = new String( aDefArgDescStrings
);
1386 pDesc
->ppDefArgDescs
[j
] = new String( aDefArgDescCells
);
1389 pDesc
->ppDefArgDescs
[j
] = new String( aDefArgDescNone
);
1395 // pDesc->nHelpId = 0;
1397 aFunctionList
.Insert(pDesc
, LIST_APPEND
);
1398 nStrLen
= (*(pDesc
->pFuncName
)).Len();
1399 if ( nStrLen
> nMaxFuncNameLen
)
1400 nMaxFuncNameLen
= nStrLen
;
1405 ScUnoAddInCollection
* pUnoAddIns
= ScGlobal::GetAddInCollection();
1406 long nUnoCount
= pUnoAddIns
->GetFuncCount();
1407 for (long nFunc
=0; nFunc
<nUnoCount
; nFunc
++)
1409 pDesc
= new ScFuncDesc
;
1410 pDesc
->nFIndex
= nNextId
++;
1412 if ( pUnoAddIns
->FillFunctionDesc( nFunc
, *pDesc
) )
1414 aFunctionList
.Insert(pDesc
, LIST_APPEND
);
1415 nStrLen
= (*(pDesc
->pFuncName
)).Len();
1416 if (nStrLen
> nMaxFuncNameLen
)
1417 nMaxFuncNameLen
= nStrLen
;
1424 //------------------------------------------------------------------------
1426 ScFunctionList::~ScFunctionList()
1428 const ScFuncDesc
* pDesc
= First();
1437 //========================================================================
1438 // class ScFuncDesc:
1440 ScFuncDesc::ScFuncDesc() :
1443 ppDefArgNames (NULL
),
1444 ppDefArgDescs (NULL
),
1445 pDefArgFlags (NULL
),
1450 bIncomplete (false),
1451 bHasSuppressedArgs(false)
1454 //------------------------------------------------------------------------
1456 ScFuncDesc::~ScFuncDesc()
1461 //------------------------------------------------------------------------
1463 void ScFuncDesc::Clear()
1465 USHORT nArgs
= nArgCount
;
1466 if (nArgs
>= VAR_ARGS
) nArgs
-= VAR_ARGS
-1;
1469 for (USHORT i
=0; i
<nArgs
; i
++ )
1471 delete ppDefArgNames
[i
];
1472 delete ppDefArgDescs
[i
];
1474 delete [] ppDefArgNames
;
1475 delete [] ppDefArgDescs
;
1476 delete [] pDefArgFlags
;
1479 ppDefArgNames
= NULL
;
1480 ppDefArgDescs
= NULL
;
1481 pDefArgFlags
= NULL
;
1492 bIncomplete
= false;
1493 bHasSuppressedArgs
= false;
1496 //------------------------------------------------------------------------
1498 String
ScFuncDesc::GetParamList() const
1500 const String
& sep
= ScCompiler::GetNativeSymbol(ocSep
);
1504 if ( nArgCount
> 0 )
1506 if ( nArgCount
< VAR_ARGS
)
1508 USHORT nLastSuppressed
= nArgCount
;
1509 USHORT nLastAdded
= nArgCount
;
1510 for ( USHORT i
=0; i
<nArgCount
; i
++ )
1512 if (pDefArgFlags
[i
].bSuppress
)
1513 nLastSuppressed
= i
;
1517 aSig
+= *(ppDefArgNames
[i
]);
1518 if ( i
!= nArgCount
-1 )
1521 aSig
.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " ));
1525 // If only suppressed parameters follow the last added parameter,
1527 if (nLastSuppressed
< nArgCount
&& nLastAdded
< nLastSuppressed
&&
1529 aSig
.Erase( aSig
.Len() - 2 );
1533 USHORT nFix
= nArgCount
- VAR_ARGS
;
1534 for ( USHORT nArg
= 0; nArg
< nFix
; nArg
++ )
1536 if (!pDefArgFlags
[nArg
].bSuppress
)
1538 aSig
+= *(ppDefArgNames
[nArg
]);
1540 aSig
.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " ));
1543 /* NOTE: Currently there are no suppressed var args parameters. If
1544 * there were, we'd have to cope with it here and above for the fix
1545 * parameters. For now parameters are always added, so no special
1546 * treatment of a trailing "; " necessary. */
1547 aSig
+= *(ppDefArgNames
[nFix
]);
1550 aSig
.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " " ));
1551 aSig
+= *(ppDefArgNames
[nFix
]);
1554 aSig
.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ... " ));
1561 //------------------------------------------------------------------------
1563 String
ScFuncDesc::GetSignature() const
1571 String
aParamList( GetParamList() );
1572 if( aParamList
.Len() )
1574 aSig
.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "( " ));
1575 aSig
.Append( aParamList
);
1576 // U+00A0 (NBSP) prevents automatic line break
1577 aSig
.Append( static_cast< sal_Unicode
>(0xA0) ).Append( ')' );
1580 aSig
.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));
1585 //------------------------------------------------------------------------
1587 ::rtl::OUString
ScFuncDesc::getFormula( const ::std::vector
< ::rtl::OUString
>& _aArguments
) const
1589 const String
& sep
= ScCompiler::GetNativeSymbol(ocSep
);
1591 ::rtl::OUStringBuffer aFormula
;
1595 aFormula
.append( *pFuncName
);
1597 aFormula
.appendAscii( "(" );
1598 ::std::vector
< ::rtl::OUString
>::const_iterator aIter
= _aArguments
.begin();
1599 ::std::vector
< ::rtl::OUString
>::const_iterator aEnd
= _aArguments
.end();
1601 if ( nArgCount
> 0 && aIter
!= aEnd
)
1603 BOOL bLastArg
= ( aIter
->getLength() == 0 );
1605 while( aIter
!= aEnd
&& !bLastArg
)
1607 aFormula
.append( *(aIter
) );
1608 if ( aIter
!= (aEnd
-1) )
1610 bLastArg
= !( (aIter
+1)->getLength() > 0 );
1612 aFormula
.append( sep
);
1619 aFormula
.appendAscii( ")" );
1621 return aFormula
.makeStringAndClear();
1624 //------------------------------------------------------------------------
1626 USHORT
ScFuncDesc::GetSuppressedArgCount() const
1628 if (!bHasSuppressedArgs
|| !pDefArgFlags
)
1631 USHORT nArgs
= nArgCount
;
1632 if (nArgs
>= VAR_ARGS
)
1633 nArgs
-= VAR_ARGS
- 1;
1634 USHORT nCount
= nArgs
;
1635 for (USHORT i
=0; i
< nArgs
; ++i
)
1637 if (pDefArgFlags
[i
].bSuppress
)
1640 if (nArgCount
>= VAR_ARGS
)
1641 nCount
+= VAR_ARGS
- 1;
1645 //------------------------------------------------------------------------
1647 ::rtl::OUString
ScFuncDesc::getFunctionName() const
1649 ::rtl::OUString sRet
;
1654 // -----------------------------------------------------------------------------
1655 const formula::IFunctionCategory
* ScFuncDesc::getCategory() const
1657 return ScGlobal::GetStarCalcFunctionMgr()->getCategory(nCategory
);
1659 // -----------------------------------------------------------------------------
1660 ::rtl::OUString
ScFuncDesc::getDescription() const
1662 ::rtl::OUString sRet
;
1667 // -----------------------------------------------------------------------------
1668 // GetSuppressedArgCount
1669 xub_StrLen
ScFuncDesc::getSuppressedArgumentCount() const
1671 return GetSuppressedArgCount();
1673 // -----------------------------------------------------------------------------
1675 void ScFuncDesc::fillVisibleArgumentMapping(::std::vector
<USHORT
>& _rArguments
) const
1677 if (!bHasSuppressedArgs
|| !pDefArgFlags
)
1679 _rArguments
.resize( nArgCount
);
1680 ::std::iota( _rArguments
.begin(), _rArguments
.end(), 0);
1683 _rArguments
.reserve( nArgCount
);
1684 USHORT nArgs
= nArgCount
;
1685 if (nArgs
>= VAR_ARGS
)
1686 nArgs
-= VAR_ARGS
- 1;
1687 for (USHORT i
=0; i
< nArgs
; ++i
)
1689 if (!pDefArgFlags
[i
].bSuppress
)
1690 _rArguments
.push_back(i
);
1693 // -----------------------------------------------------------------------------
1694 void ScFuncDesc::initArgumentInfo() const
1696 // get the full argument description
1697 // (add-in has to be instantiated to get the type information)
1699 if ( bIncomplete
&& pFuncName
)
1701 ScUnoAddInCollection
& rAddIns
= *ScGlobal::GetAddInCollection();
1702 String aIntName
= rAddIns
.FindFunction( *pFuncName
, TRUE
); // pFuncName is upper-case
1704 if ( aIntName
.Len() )
1706 // GetFuncData with bComplete=true loads the component and updates
1707 // the global function list if needed.
1709 rAddIns
.GetFuncData( aIntName
, true );
1714 DBG_ERRORFILE( "couldn't initialize add-in function" );
1715 const_cast<ScFuncDesc
*>(this)->bIncomplete
= FALSE
; // even if there was an error, don't try again
1719 // -----------------------------------------------------------------------------
1720 ::rtl::OUString
ScFuncDesc::getSignature() const
1722 return GetSignature();
1724 // -----------------------------------------------------------------------------
1725 long ScFuncDesc::getHelpId() const
1729 // -----------------------------------------------------------------------------
1732 sal_uInt32
ScFuncDesc::getParameterCount() const
1736 // -----------------------------------------------------------------------------
1737 ::rtl::OUString
ScFuncDesc::getParameterName(sal_uInt32 _nPos
) const
1739 return *(ppDefArgNames
[_nPos
]);
1741 // -----------------------------------------------------------------------------
1742 ::rtl::OUString
ScFuncDesc::getParameterDescription(sal_uInt32 _nPos
) const
1744 return *(ppDefArgDescs
[_nPos
]);
1746 // -----------------------------------------------------------------------------
1747 bool ScFuncDesc::isParameterOptional(sal_uInt32 _nPos
) const
1749 return pDefArgFlags
[_nPos
].bOptional
;
1751 // -----------------------------------------------------------------------------
1752 //========================================================================
1753 // class ScFunctionMgr:
1755 ScFunctionMgr::ScFunctionMgr()
1756 : pFuncList ( ScGlobal::GetStarCalcFunctionList() ),
1757 pCurCatList ( NULL
)
1759 DBG_ASSERT( pFuncList
, "Funktionsliste nicht gefunden." );
1760 ULONG nCount
= pFuncList
->GetCount();
1761 const ScFuncDesc
* pDesc
;
1765 for ( USHORT i
=0; i
<MAX_FUNCCAT
; i
++ ) // Kategorie-Listen erstellen
1766 aCatLists
[i
] = new List
;
1768 pRootList
= aCatLists
[0]; // Gesamtliste ("Alle") erstellen
1769 for ( n
=0; n
<nCount
; n
++ )
1772 pDesc
= pFuncList
->GetFunction(n
);
1773 for (nTmpCnt
= 0; nTmpCnt
< n
; nTmpCnt
++)
1775 // ist zwar case-sensitiv, aber Umlaute muessen richtig einsortiert werden
1777 const ScFuncDesc
* pTmpDesc
= (const ScFuncDesc
*)pRootList
->GetObject(nTmpCnt
);
1778 if ( ScGlobal::pCaseCollator
->compareString(
1779 *pDesc
->pFuncName
, *pTmpDesc
->pFuncName
) == COMPARE_LESS
)
1782 pRootList
->Insert((void*)pDesc
, nTmpCnt
); // Einsortieren
1785 for ( n
=0; n
<nCount
; n
++ ) // in Gruppenlisten kopieren
1787 pDesc
= (const ScFuncDesc
*)pRootList
->GetObject(n
);
1788 DBG_ASSERT((pDesc
->nCategory
) < MAX_FUNCCAT
, "Unbekannte Kategorie");
1789 if ((pDesc
->nCategory
) < MAX_FUNCCAT
)
1790 aCatLists
[pDesc
->nCategory
]->Insert((void*)pDesc
, LIST_APPEND
);
1794 //------------------------------------------------------------------------
1796 ScFunctionMgr::~ScFunctionMgr()
1798 for (USHORT i
= 0; i
< MAX_FUNCCAT
; i
++)
1799 delete aCatLists
[i
];
1800 // delete pFuncList; // Macht spaeter die App
1803 //------------------------------------------------------------------------
1805 const ScFuncDesc
* ScFunctionMgr::Get( const String
& rFName
) const
1807 const ScFuncDesc
* pDesc
= NULL
;
1808 if (rFName
.Len() <= pFuncList
->GetMaxFuncNameLen())
1809 for (pDesc
= First(0); pDesc
; pDesc
= Next())
1810 if (rFName
.EqualsIgnoreCaseAscii(*(pDesc
->pFuncName
)))
1815 //------------------------------------------------------------------------
1817 const ScFuncDesc
* ScFunctionMgr::Get( USHORT nFIndex
) const
1819 const ScFuncDesc
* pDesc
;
1820 for (pDesc
= First(0); pDesc
; pDesc
= Next())
1821 if (pDesc
->nFIndex
== nFIndex
)
1826 //------------------------------------------------------------------------
1828 const ScFuncDesc
* ScFunctionMgr::First( USHORT nCategory
) const
1830 DBG_ASSERT( nCategory
< MAX_FUNCCAT
, "Unbekannte Kategorie" );
1832 if ( nCategory
< MAX_FUNCCAT
)
1834 pCurCatList
= aCatLists
[nCategory
];
1835 return (const ScFuncDesc
*)pCurCatList
->First();
1844 //------------------------------------------------------------------------
1846 const ScFuncDesc
* ScFunctionMgr::Next() const
1849 return (const ScFuncDesc
*)pCurCatList
->Next();
1853 sal_uInt32
ScFunctionMgr::getCount() const
1855 return MAX_FUNCCAT
- 1;
1857 const formula::IFunctionCategory
* ScFunctionMgr::getCategory(sal_uInt32 nCategory
) const
1859 formula::IFunctionCategory
* pRet
= NULL
;
1860 if ( nCategory
< (MAX_FUNCCAT
-1) )
1862 pRet
= new ScFunctionCategory(const_cast<ScFunctionMgr
*>(this),aCatLists
[nCategory
+1],nCategory
); // aCatLists[0] is "all"
1866 // -----------------------------------------------------------------------------
1867 const formula::IFunctionDescription
* ScFunctionMgr::getFunctionByName(const ::rtl::OUString
& _sFunctionName
) const
1869 return Get(_sFunctionName
);
1871 // -----------------------------------------------------------------------------
1872 void ScFunctionMgr::fillLastRecentlyUsedFunctions(::std::vector
< const formula::IFunctionDescription
*>& _rLastRUFunctions
) const
1876 const ScAppOptions
& rAppOpt
= SC_MOD()->GetAppOptions();
1877 USHORT nLRUFuncCount
= Min( rAppOpt
.GetLRUFuncListCount(), (USHORT
)LRU_MAX
);
1878 USHORT
* pLRUListIds
= rAppOpt
.GetLRUFuncList();
1882 for ( USHORT i
=0; i
<nLRUFuncCount
; i
++ )
1883 _rLastRUFunctions
.push_back( Get( pLRUListIds
[i
] ) );
1886 // -----------------------------------------------------------------------------
1887 String
ScFunctionMgr::GetCategoryName(sal_uInt32 _nCategoryNumber
)
1889 if ( _nCategoryNumber
> SC_FUNCGROUP_COUNT
)
1891 DBG_ERROR("Invalid category number!");
1893 } // if ( _nCategoryNumber >= SC_FUNCGROUP_COUNT )
1895 ::std::auto_ptr
<ScResourcePublisher
> pCategories( new ScResourcePublisher( ScResId( RID_FUNCTION_CATEGORIES
) ) );
1896 return String(ScResId((USHORT
)_nCategoryNumber
));
1898 sal_Unicode
ScFunctionMgr::getSingleToken(const formula::IFunctionManager::EToken _eToken
) const
1903 return ScCompiler::GetNativeSymbol(ocOpen
).GetChar(0);
1905 return ScCompiler::GetNativeSymbol(ocClose
).GetChar(0);
1907 return ScCompiler::GetNativeSymbol(ocSep
).GetChar(0);
1909 return ScCompiler::GetNativeSymbol(ocArrayOpen
).GetChar(0);
1911 return ScCompiler::GetNativeSymbol(ocArrayClose
).GetChar(0);
1912 } // switch(_eToken)
1915 // -----------------------------------------------------------------------------
1916 sal_uInt32
ScFunctionCategory::getCount() const
1918 return m_pCategory
->Count();
1920 // -----------------------------------------------------------------------------
1921 const formula::IFunctionManager
* ScFunctionCategory::getFunctionManager() const
1925 // -----------------------------------------------------------------------------
1926 ::rtl::OUString
ScFunctionCategory::getName() const
1928 if ( !m_sName
.getLength() )
1929 m_sName
= ScFunctionMgr::GetCategoryName(m_nCategory
+1);
1932 // -----------------------------------------------------------------------------
1933 const formula::IFunctionDescription
* ScFunctionCategory::getFunction(sal_uInt32 _nPos
) const
1935 const ScFuncDesc
* pDesc
= NULL
;
1937 for (pDesc
= (const ScFuncDesc
*)m_pCategory
->First(); i
< _nPos
&& pDesc
; pDesc
= (const ScFuncDesc
*)m_pCategory
->Next(),++i
)
1941 // -----------------------------------------------------------------------------
1942 sal_uInt32
ScFunctionCategory::getNumber() const
1946 // -----------------------------------------------------------------------------
1948 //------------------------------------------------------------------------
1950 utl::TransliterationWrapper
* ScGlobal::GetpTransliteration() //add by CHINA001
1954 "ScGlobal::GetpTransliteration() called before ScGlobal::Init()");
1955 return pTransliteration
;
1958 const LocaleDataWrapper
* ScGlobal::GetpLocaleData()
1962 "ScGlobal::GetpLocaleData() called before ScGlobal::Init()");