fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / formula / source / ui / dlg / FormulaHelper.cxx
blob529b42a952b861a8d1eab85a795ffc7b944be491
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "formula/formulahelper.hxx"
21 #include <unotools/charclass.hxx>
22 #include <unotools/syslocale.hxx>
24 namespace formula
27 namespace
29 //============================================================================
30 class OEmptyFunctionDescription : public IFunctionDescription
32 public:
33 OEmptyFunctionDescription(){}
34 virtual ~OEmptyFunctionDescription(){}
36 virtual OUString getFunctionName() const { return OUString(); }
37 virtual const IFunctionCategory* getCategory() const { return NULL; }
38 virtual OUString getDescription() const { return OUString(); }
39 virtual xub_StrLen getSuppressedArgumentCount() const { return 0; }
40 virtual OUString getFormula(const ::std::vector< OUString >& ) const { return OUString(); }
41 virtual void fillVisibleArgumentMapping(::std::vector<sal_uInt16>& ) const {}
42 virtual void initArgumentInfo() const {}
43 virtual OUString getSignature() const { return OUString(); }
44 virtual OString getHelpId() const { return ""; }
45 virtual sal_uInt32 getParameterCount() const { return 0; }
46 virtual OUString getParameterName(sal_uInt32 ) const { return OUString(); }
47 virtual OUString getParameterDescription(sal_uInt32 ) const { return OUString(); }
48 virtual bool isParameterOptional(sal_uInt32 ) const { return sal_False; }
51 //===================================================================
52 // class FormulaHelper - static Method
53 //===================================================================
55 #define FUNC_NOTFOUND 0xffff
57 FormulaHelper::FormulaHelper(const IFunctionManager* _pFunctionManager)
58 :m_pSysLocale(new SvtSysLocale)
59 ,m_pFunctionManager(_pFunctionManager)
60 ,open(_pFunctionManager->getSingleToken(IFunctionManager::eOk))
61 ,close(_pFunctionManager->getSingleToken(IFunctionManager::eClose))
62 ,sep(_pFunctionManager->getSingleToken(IFunctionManager::eSep))
63 ,arrayOpen(_pFunctionManager->getSingleToken(IFunctionManager::eArrayOpen))
64 ,arrayClose(_pFunctionManager->getSingleToken(IFunctionManager::eArrayClose))
66 m_pCharClass = m_pSysLocale->GetCharClassPtr();
68 sal_Bool FormulaHelper::GetNextFunc( const String& rFormula,
69 sal_Bool bBack,
70 xub_StrLen& rFStart, // Input and output
71 xub_StrLen* pFEnd, // = NULL
72 const IFunctionDescription** ppFDesc, // = NULL
73 ::std::vector< OUString>* pArgs ) const // = NULL
75 xub_StrLen nOldStart = rFStart;
76 String aFname;
78 rFStart = GetFunctionStart( rFormula, rFStart, bBack, ppFDesc ? &aFname : NULL );
79 sal_Bool bFound = ( rFStart != FUNC_NOTFOUND );
81 if ( bFound )
83 if ( pFEnd )
84 *pFEnd = GetFunctionEnd( rFormula, rFStart );
86 if ( ppFDesc )
88 *ppFDesc = NULL;
89 const OUString sTemp( aFname );
90 const sal_uInt32 nCategoryCount = m_pFunctionManager->getCount();
91 for(sal_uInt32 j= 0; j < nCategoryCount && !*ppFDesc; ++j)
93 const IFunctionCategory* pCategory = m_pFunctionManager->getCategory(j);
94 const sal_uInt32 nCount = pCategory->getCount();
95 for(sal_uInt32 i = 0 ; i < nCount; ++i)
97 const IFunctionDescription* pCurrent = pCategory->getFunction(i);
98 if ( pCurrent->getFunctionName().equalsIgnoreAsciiCase(sTemp) )
100 *ppFDesc = pCurrent;
101 break;
103 }// for(sal_uInt32 i = 0 ; i < nCount; ++i)
105 if ( *ppFDesc && pArgs )
107 GetArgStrings( *pArgs,rFormula, rFStart, static_cast<sal_uInt16>((*ppFDesc)->getParameterCount() ));
109 else
111 static OEmptyFunctionDescription s_aFunctionDescription;
112 *ppFDesc = &s_aFunctionDescription;
116 else
117 rFStart = nOldStart;
119 return bFound;
122 //------------------------------------------------------------------------
124 void FormulaHelper::FillArgStrings( const String& rFormula,
125 xub_StrLen nFuncPos,
126 sal_uInt16 nArgs,
127 ::std::vector< OUString >& _rArgs ) const
129 xub_StrLen nStart = 0;
130 xub_StrLen nEnd = 0;
131 sal_uInt16 i;
132 sal_Bool bLast = sal_False;
134 for ( i=0; i<nArgs && !bLast; i++ )
136 nStart = GetArgStart( rFormula, nFuncPos, i );
138 if ( i+1<nArgs ) // last argument?
140 nEnd = GetArgStart( rFormula, nFuncPos, i+1 );
142 if ( nEnd != nStart )
143 _rArgs.push_back(rFormula.Copy( nStart, nEnd-1-nStart ));
144 else
145 _rArgs.push_back(String()), bLast = sal_True;
147 else
149 nEnd = GetFunctionEnd( rFormula, nFuncPos )-1;
150 if ( nStart < nEnd )
151 _rArgs.push_back( rFormula.Copy( nStart, nEnd-nStart ) );
152 else
153 _rArgs.push_back(String());
157 if ( bLast )
158 for ( ; i<nArgs; i++ )
159 _rArgs.push_back(String());
162 //------------------------------------------------------------------------
164 void FormulaHelper::GetArgStrings( ::std::vector< OUString >& _rArgs
165 ,const String& rFormula,
166 xub_StrLen nFuncPos,
167 sal_uInt16 nArgs ) const
169 if (nArgs)
171 FillArgStrings( rFormula, nFuncPos, nArgs, _rArgs );
175 //------------------------------------------------------------------------
177 inline sal_Bool IsFormulaText( const CharClass* _pCharClass,const String& rStr, xub_StrLen nPos )
179 if( _pCharClass->isLetterNumeric( rStr, nPos ) )
180 return sal_True;
181 else
182 { // In internationalized versions function names may contain a dot
183 // and in every version also an underscore... ;-)
184 sal_Unicode c = rStr.GetChar(nPos);
185 return c == '.' || c == '_';
190 xub_StrLen FormulaHelper::GetFunctionStart( const String& rFormula,
191 xub_StrLen nStart,
192 sal_Bool bBack,
193 String* pFuncName ) const
195 xub_StrLen nStrLen = rFormula.Len();
197 if ( nStrLen < nStart )
198 return nStart;
200 xub_StrLen nFStart = FUNC_NOTFOUND;
201 xub_StrLen nParPos = nStart;
203 sal_Bool bRepeat, bFound;
206 bFound = sal_False;
207 bRepeat = sal_False;
209 if ( bBack )
211 while ( !bFound && (nParPos > 0) )
213 if ( rFormula.GetChar(nParPos) == '"' )
215 nParPos--;
216 while ( (nParPos > 0) && rFormula.GetChar(nParPos) != '"' )
217 nParPos--;
218 if (nParPos > 0)
219 nParPos--;
221 else if ( (bFound = ( rFormula.GetChar(nParPos) == '(' ) ) == sal_False )
222 nParPos--;
225 else
227 while ( !bFound && (nParPos < nStrLen) )
229 if ( rFormula.GetChar(nParPos) == '"' )
231 nParPos++;
232 while ( (nParPos < nStrLen) && rFormula.GetChar(nParPos) != '"' )
233 nParPos++;
234 nParPos++;
236 else if ( (bFound = ( rFormula.GetChar(nParPos) == '(' ) ) == sal_False )
237 nParPos++;
241 if ( bFound && (nParPos > 0) )
243 nFStart = nParPos-1;
245 while ( (nFStart > 0) && IsFormulaText(m_pCharClass, rFormula, nFStart ))
246 nFStart--;
249 nFStart++;
251 if ( bFound )
253 if ( IsFormulaText( m_pCharClass,rFormula, nFStart ) )
255 // Function found
256 if ( pFuncName )
257 *pFuncName = rFormula.Copy( nFStart, nParPos-nFStart );
259 else // Brackets without function -> keep searching
261 bRepeat = sal_True;
262 if ( !bBack )
263 nParPos++;
264 else if (nParPos > 0)
265 nParPos--;
266 else
267 bRepeat = sal_False;
270 else // No brackets found
272 nFStart = FUNC_NOTFOUND;
273 if ( pFuncName )
274 pFuncName->Erase();
277 while(bRepeat);
279 return nFStart;
282 //------------------------------------------------------------------------
284 xub_StrLen FormulaHelper::GetFunctionEnd( const String& rStr, xub_StrLen nStart ) const
286 xub_StrLen nStrLen = rStr.Len();
288 if ( nStrLen < nStart )
289 return nStart;
291 short nParCount = 0;
292 bool bInArray = false;
293 sal_Bool bFound = sal_False;
295 while ( !bFound && (nStart < nStrLen) )
297 sal_Unicode c = rStr.GetChar(nStart);
299 if ( c == '"' )
301 nStart++;
302 while ( (nStart < nStrLen) && rStr.GetChar(nStart) != '"' )
303 nStart++;
305 else if ( c == open )
306 nParCount++;
307 else if ( c == close )
309 nParCount--;
310 if ( nParCount == 0 )
311 bFound = sal_True;
312 else if ( nParCount < 0 )
314 bFound = sal_True;
315 nStart--; // read one too far
318 else if ( c == arrayOpen )
320 bInArray = true;
322 else if ( c == arrayClose )
324 bInArray = false;
326 else if ( c == sep )
328 if ( !bInArray && nParCount == 0 )
330 bFound = sal_True;
331 nStart--; // read one too far
334 nStart++; // Set behind found position
337 return nStart;
340 //------------------------------------------------------------------
342 xub_StrLen FormulaHelper::GetArgStart( const String& rStr, xub_StrLen nStart, sal_uInt16 nArg ) const
344 xub_StrLen nStrLen = rStr.Len();
346 if ( nStrLen < nStart )
347 return nStart;
349 short nParCount = 0;
350 bool bInArray = false;
351 sal_Bool bFound = sal_False;
353 while ( !bFound && (nStart < nStrLen) )
355 sal_Unicode c = rStr.GetChar(nStart);
357 if ( c == '"' )
359 nStart++;
360 while ( (nStart < nStrLen) && rStr.GetChar(nStart) != '"' )
361 nStart++;
363 else if ( c == open )
365 bFound = ( nArg == 0 );
366 nParCount++;
368 else if ( c == close )
370 nParCount--;
371 bFound = ( nParCount == 0 );
373 else if ( c == arrayOpen )
375 bInArray = true;
377 else if ( c == arrayClose )
379 bInArray = false;
381 else if ( c == sep )
383 if ( !bInArray && nParCount == 1 )
385 nArg--;
386 bFound = ( nArg == 0 );
389 nStart++;
392 return nStart;
394 // =============================================================================
395 } // formula
396 // =============================================================================
398 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */