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: formula.hxx,v $
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 ************************************************************************/
30 #include "precompiled_formula.hxx"
32 #include "formula/formulahelper.hxx"
33 #include <unotools/charclass.hxx>
34 #include <svtools/syslocale.hxx>
41 //============================================================================
42 class OEmptyFunctionDescription
: public IFunctionDescription
45 OEmptyFunctionDescription(){}
46 virtual ~OEmptyFunctionDescription(){}
48 virtual ::rtl::OUString
getFunctionName() const { return ::rtl::OUString(); }
49 virtual const IFunctionCategory
* getCategory() const { return NULL
; }
50 virtual ::rtl::OUString
getDescription() const { return ::rtl::OUString(); }
51 virtual xub_StrLen
getSuppressedArgumentCount() const { return 0; }
52 virtual ::rtl::OUString
getFormula(const ::std::vector
< ::rtl::OUString
>& ) const { return ::rtl::OUString(); }
53 virtual void fillVisibleArgumentMapping(::std::vector
<USHORT
>& ) const {}
54 virtual void initArgumentInfo() const {}
55 virtual ::rtl::OUString
getSignature() const { return ::rtl::OUString(); }
56 virtual long getHelpId() const { return 0; }
57 virtual sal_uInt32
getParameterCount() const { return 0; }
58 virtual ::rtl::OUString
getParameterName(sal_uInt32
) const { return ::rtl::OUString(); }
59 virtual ::rtl::OUString
getParameterDescription(sal_uInt32
) const { return ::rtl::OUString(); }
60 virtual bool isParameterOptional(sal_uInt32
) const { return sal_False
; }
63 //===================================================================
64 // class FormulaHelper - statische Methoden
65 //===================================================================
67 #define FUNC_NOTFOUND 0xffff
69 FormulaHelper::FormulaHelper(const IFunctionManager
* _pFunctionManager
)
70 :m_pSysLocale(new SvtSysLocale
)
71 ,m_pFunctionManager(_pFunctionManager
)
72 ,open(_pFunctionManager
->getSingleToken(IFunctionManager::eOk
))
73 ,close(_pFunctionManager
->getSingleToken(IFunctionManager::eClose
))
74 ,sep(_pFunctionManager
->getSingleToken(IFunctionManager::eSep
))
75 ,arrayOpen(_pFunctionManager
->getSingleToken(IFunctionManager::eArrayOpen
))
76 ,arrayClose(_pFunctionManager
->getSingleToken(IFunctionManager::eArrayClose
))
78 m_pCharClass
= m_pSysLocale
->GetCharClassPtr();
80 BOOL
FormulaHelper::GetNextFunc( const String
& rFormula
,
82 xub_StrLen
& rFStart
, // Ein- und Ausgabe
83 xub_StrLen
* pFEnd
, // = NULL
84 const IFunctionDescription
** ppFDesc
, // = NULL
85 ::std::vector
< ::rtl::OUString
>* pArgs
) const // = NULL
88 xub_StrLen nOldStart
= rFStart
;
91 rFStart
= GetFunctionStart( rFormula
, rFStart
, bBack
, ppFDesc
? &aFname
: NULL
);
92 bFound
= ( rFStart
!= FUNC_NOTFOUND
);
97 *pFEnd
= GetFunctionEnd( rFormula
, rFStart
);
102 const ::rtl::OUString
sTemp( aFname
);
103 const sal_uInt32 nCategoryCount
= m_pFunctionManager
->getCount();
104 for(sal_uInt32 j
= 0; j
< nCategoryCount
&& !*ppFDesc
; ++j
)
106 const IFunctionCategory
* pCategory
= m_pFunctionManager
->getCategory(j
);
107 const sal_uInt32 nCount
= pCategory
->getCount();
108 for(sal_uInt32 i
= 0 ; i
< nCount
; ++i
)
110 const IFunctionDescription
* pCurrent
= pCategory
->getFunction(i
);
111 if ( pCurrent
->getFunctionName().equalsIgnoreAsciiCase(sTemp
) )
116 } // for(sal_uInt32 i = 0 ; i < nCount; ++i)
118 if ( *ppFDesc
&& pArgs
)
120 GetArgStrings( *pArgs
,rFormula
, rFStart
, static_cast<USHORT
>((*ppFDesc
)->getParameterCount() ));
124 static OEmptyFunctionDescription s_aFunctionDescription
;
125 *ppFDesc
= &s_aFunctionDescription
;
135 //------------------------------------------------------------------------
137 void FormulaHelper::FillArgStrings( const String
& rFormula
,
140 ::std::vector
< ::rtl::OUString
>& _rArgs
) const
142 xub_StrLen nStart
= 0;
147 for ( i
=0; i
<nArgs
&& !bLast
; i
++ )
149 nStart
= GetArgStart( rFormula
, nFuncPos
, i
);
151 if ( i
+1<nArgs
) // letztes Argument?
153 nEnd
= GetArgStart( rFormula
, nFuncPos
, i
+1 );
155 if ( nEnd
!= nStart
)
156 _rArgs
.push_back(rFormula
.Copy( nStart
, nEnd
-1-nStart
));
158 _rArgs
.push_back(String()), bLast
= TRUE
;
162 nEnd
= GetFunctionEnd( rFormula
, nFuncPos
)-1;
164 _rArgs
.push_back( rFormula
.Copy( nStart
, nEnd
-nStart
) );
166 _rArgs
.push_back(String());
171 for ( ; i
<nArgs
; i
++ )
172 _rArgs
.push_back(String());
175 //------------------------------------------------------------------------
177 void FormulaHelper::GetArgStrings( ::std::vector
< ::rtl::OUString
>& _rArgs
178 ,const String
& rFormula
,
184 FillArgStrings( rFormula
, nFuncPos
, nArgs
, _rArgs
);
188 //------------------------------------------------------------------------
190 inline BOOL
IsFormulaText( const CharClass
* _pCharClass
,const String
& rStr
, xub_StrLen nPos
)
192 if( _pCharClass
->isLetterNumeric( rStr
, nPos
) )
195 { // In internationalized versions function names may contain a dot
196 // and in every version also an underscore... ;-)
197 sal_Unicode c
= rStr
.GetChar(nPos
);
198 return c
== '.' || c
== '_';
203 xub_StrLen
FormulaHelper::GetFunctionStart( const String
& rFormula
,
206 String
* pFuncName
) const
208 xub_StrLen nStrLen
= rFormula
.Len();
210 if ( nStrLen
< nStart
)
213 xub_StrLen nFStart
= FUNC_NOTFOUND
;
214 xub_StrLen nParPos
= nStart
;
216 BOOL bRepeat
, bFound
;
224 while ( !bFound
&& (nParPos
> 0) )
226 if ( rFormula
.GetChar(nParPos
) == '"' )
229 while ( (nParPos
> 0) && rFormula
.GetChar(nParPos
) != '"' )
234 else if ( (bFound
= ( rFormula
.GetChar(nParPos
) == '(' ) ) == FALSE
)
240 while ( !bFound
&& (nParPos
< nStrLen
) )
242 if ( rFormula
.GetChar(nParPos
) == '"' )
245 while ( (nParPos
< nStrLen
) && rFormula
.GetChar(nParPos
) != '"' )
249 else if ( (bFound
= ( rFormula
.GetChar(nParPos
) == '(' ) ) == FALSE
)
254 if ( bFound
&& (nParPos
> 0) )
258 while ( (nFStart
> 0) && IsFormulaText(m_pCharClass
, rFormula
, nFStart
))
266 if ( IsFormulaText( m_pCharClass
,rFormula
, nFStart
) )
270 *pFuncName
= rFormula
.Copy( nFStart
, nParPos
-nFStart
);
272 else // Klammern ohne Funktion -> weitersuchen
277 else if (nParPos
> 0)
283 else // keine Klammern gefunden
285 nFStart
= FUNC_NOTFOUND
;
295 //------------------------------------------------------------------------
297 xub_StrLen
FormulaHelper::GetFunctionEnd( const String
& rStr
, xub_StrLen nStart
) const
299 xub_StrLen nStrLen
= rStr
.Len();
301 if ( nStrLen
< nStart
)
305 bool bInArray
= false;
308 while ( !bFound
&& (nStart
< nStrLen
) )
310 sal_Unicode c
= rStr
.GetChar(nStart
);
315 while ( (nStart
< nStrLen
) && rStr
.GetChar(nStart
) != '"' )
318 else if ( c
== open
)
320 else if ( c
== close
)
323 if ( nParCount
== 0 )
325 else if ( nParCount
< 0 )
328 nStart
--; // einen zu weit gelesen
331 else if ( c
== arrayOpen
)
335 else if ( c
== arrayClose
)
341 if ( !bInArray
&& nParCount
== 0 )
344 nStart
--; // einen zu weit gelesen
347 nStart
++; // hinter gefundene Position stellen
353 //------------------------------------------------------------------
355 xub_StrLen
FormulaHelper::GetArgStart( const String
& rStr
, xub_StrLen nStart
, USHORT nArg
) const
357 xub_StrLen nStrLen
= rStr
.Len();
359 if ( nStrLen
< nStart
)
363 bool bInArray
= false;
366 while ( !bFound
&& (nStart
< nStrLen
) )
368 sal_Unicode c
= rStr
.GetChar(nStart
);
373 while ( (nStart
< nStrLen
) && rStr
.GetChar(nStart
) != '"' )
376 else if ( c
== open
)
378 bFound
= ( nArg
== 0 );
381 else if ( c
== close
)
384 bFound
= ( nParCount
== 0 );
386 else if ( c
== arrayOpen
)
390 else if ( c
== arrayClose
)
396 if ( !bInArray
&& nParCount
== 1 )
399 bFound
= ( nArg
== 0 );
407 // =============================================================================
409 // =============================================================================