update dev300-m58
[ooovba.git] / formula / source / ui / dlg / FormulaHelper.cxx
blobf5ba200853272f615d5a4e1cbdd59cf1f48175ee
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: formula.hxx,v $
10 * $Revision: 1.5 $
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>
36 namespace formula
39 namespace
41 //============================================================================
42 class OEmptyFunctionDescription : public IFunctionDescription
44 public:
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,
81 BOOL bBack,
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
87 BOOL bFound = FALSE;
88 xub_StrLen nOldStart = rFStart;
89 String aFname;
91 rFStart = GetFunctionStart( rFormula, rFStart, bBack, ppFDesc ? &aFname : NULL );
92 bFound = ( rFStart != FUNC_NOTFOUND );
94 if ( bFound )
96 if ( pFEnd )
97 *pFEnd = GetFunctionEnd( rFormula, rFStart );
99 if ( ppFDesc )
101 *ppFDesc = NULL;
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) )
113 *ppFDesc = pCurrent;
114 break;
116 } // for(sal_uInt32 i = 0 ; i < nCount; ++i)
118 if ( *ppFDesc && pArgs )
120 GetArgStrings( *pArgs,rFormula, rFStart, static_cast<USHORT>((*ppFDesc)->getParameterCount() ));
122 else
124 static OEmptyFunctionDescription s_aFunctionDescription;
125 *ppFDesc = &s_aFunctionDescription;
129 else
130 rFStart = nOldStart;
132 return bFound;
135 //------------------------------------------------------------------------
137 void FormulaHelper::FillArgStrings( const String& rFormula,
138 xub_StrLen nFuncPos,
139 USHORT nArgs,
140 ::std::vector< ::rtl::OUString >& _rArgs ) const
142 xub_StrLen nStart = 0;
143 xub_StrLen nEnd = 0;
144 USHORT i;
145 BOOL bLast = FALSE;
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 ));
157 else
158 _rArgs.push_back(String()), bLast = TRUE;
160 else
162 nEnd = GetFunctionEnd( rFormula, nFuncPos )-1;
163 if ( nStart < nEnd )
164 _rArgs.push_back( rFormula.Copy( nStart, nEnd-nStart ) );
165 else
166 _rArgs.push_back(String());
170 if ( bLast )
171 for ( ; i<nArgs; i++ )
172 _rArgs.push_back(String());
175 //------------------------------------------------------------------------
177 void FormulaHelper::GetArgStrings( ::std::vector< ::rtl::OUString >& _rArgs
178 ,const String& rFormula,
179 xub_StrLen nFuncPos,
180 USHORT nArgs ) const
182 if (nArgs)
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 ) )
193 return TRUE;
194 else
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,
204 xub_StrLen nStart,
205 BOOL bBack,
206 String* pFuncName ) const
208 xub_StrLen nStrLen = rFormula.Len();
210 if ( nStrLen < nStart )
211 return nStart;
213 xub_StrLen nFStart = FUNC_NOTFOUND;
214 xub_StrLen nParPos = nStart;
216 BOOL bRepeat, bFound;
219 bFound = FALSE;
220 bRepeat = FALSE;
222 if ( bBack )
224 while ( !bFound && (nParPos > 0) )
226 if ( rFormula.GetChar(nParPos) == '"' )
228 nParPos--;
229 while ( (nParPos > 0) && rFormula.GetChar(nParPos) != '"' )
230 nParPos--;
231 if (nParPos > 0)
232 nParPos--;
234 else if ( (bFound = ( rFormula.GetChar(nParPos) == '(' ) ) == FALSE )
235 nParPos--;
238 else
240 while ( !bFound && (nParPos < nStrLen) )
242 if ( rFormula.GetChar(nParPos) == '"' )
244 nParPos++;
245 while ( (nParPos < nStrLen) && rFormula.GetChar(nParPos) != '"' )
246 nParPos++;
247 nParPos++;
249 else if ( (bFound = ( rFormula.GetChar(nParPos) == '(' ) ) == FALSE )
250 nParPos++;
254 if ( bFound && (nParPos > 0) )
256 nFStart = nParPos-1;
258 while ( (nFStart > 0) && IsFormulaText(m_pCharClass, rFormula, nFStart ))
259 nFStart--;
262 nFStart++;
264 if ( bFound )
266 if ( IsFormulaText( m_pCharClass,rFormula, nFStart ) )
268 // Funktion gefunden
269 if ( pFuncName )
270 *pFuncName = rFormula.Copy( nFStart, nParPos-nFStart );
272 else // Klammern ohne Funktion -> weitersuchen
274 bRepeat = TRUE;
275 if ( !bBack )
276 nParPos++;
277 else if (nParPos > 0)
278 nParPos--;
279 else
280 bRepeat = FALSE;
283 else // keine Klammern gefunden
285 nFStart = FUNC_NOTFOUND;
286 if ( pFuncName )
287 pFuncName->Erase();
290 while(bRepeat);
292 return nFStart;
295 //------------------------------------------------------------------------
297 xub_StrLen FormulaHelper::GetFunctionEnd( const String& rStr, xub_StrLen nStart ) const
299 xub_StrLen nStrLen = rStr.Len();
301 if ( nStrLen < nStart )
302 return nStart;
304 short nParCount = 0;
305 bool bInArray = false;
306 BOOL bFound = FALSE;
308 while ( !bFound && (nStart < nStrLen) )
310 sal_Unicode c = rStr.GetChar(nStart);
312 if ( c == '"' )
314 nStart++;
315 while ( (nStart < nStrLen) && rStr.GetChar(nStart) != '"' )
316 nStart++;
318 else if ( c == open )
319 nParCount++;
320 else if ( c == close )
322 nParCount--;
323 if ( nParCount == 0 )
324 bFound = TRUE;
325 else if ( nParCount < 0 )
327 bFound = TRUE;
328 nStart--; // einen zu weit gelesen
331 else if ( c == arrayOpen )
333 bInArray = true;
335 else if ( c == arrayClose )
337 bInArray = false;
339 else if ( c == sep )
341 if ( !bInArray && nParCount == 0 )
343 bFound = TRUE;
344 nStart--; // einen zu weit gelesen
347 nStart++; // hinter gefundene Position stellen
350 return nStart;
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 )
360 return nStart;
362 short nParCount = 0;
363 bool bInArray = false;
364 BOOL bFound = FALSE;
366 while ( !bFound && (nStart < nStrLen) )
368 sal_Unicode c = rStr.GetChar(nStart);
370 if ( c == '"' )
372 nStart++;
373 while ( (nStart < nStrLen) && rStr.GetChar(nStart) != '"' )
374 nStart++;
376 else if ( c == open )
378 bFound = ( nArg == 0 );
379 nParCount++;
381 else if ( c == close )
383 nParCount--;
384 bFound = ( nParCount == 0 );
386 else if ( c == arrayOpen )
388 bInArray = true;
390 else if ( c == arrayClose )
392 bInArray = false;
394 else if ( c == sep )
396 if ( !bInArray && nParCount == 1 )
398 nArg--;
399 bFound = ( nArg == 0 );
402 nStart++;
405 return nStart;
407 // =============================================================================
408 } // formula
409 // =============================================================================