xref: /aoo42x/main/formula/source/ui/dlg/formula.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_formula.hxx"
30 
31 //----------------------------------------------------------------------------
32 #include <sfx2/dispatch.hxx>
33 #include <sfx2/docfile.hxx>
34 #include <sfx2/viewfrm.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/mnemonic.hxx>
37 #include <vcl/tabpage.hxx>
38 #include <vcl/tabctrl.hxx>
39 #include <vcl/lstbox.hxx>
40 #include <vcl/group.hxx>
41 #include <vcl/wall.hxx>
42 
43 #include <svtools/stdctrl.hxx>
44 #include <svtools/svmedit.hxx>
45 #include <svtools/svtreebx.hxx>
46 #include <svl/stritem.hxx>
47 #include <svl/zforlist.hxx>
48 #include <svl/eitem.hxx>
49 
50 #include <unotools/charclass.hxx>
51 #include <tools/urlobj.hxx>
52 #include <tools/diagnose_ex.h>
53 
54 #include "formdlgs.hrc"
55 #include "funcpage.hxx"
56 #include "formula/formula.hxx"
57 #include "formula/IFunctionDescription.hxx"
58 #include "formula/FormulaCompiler.hxx"
59 #include "formula/token.hxx"
60 #include "formula/tokenarray.hxx"
61 #include "formula/formdata.hxx"
62 #include "formula/formulahelper.hxx"
63 #include "structpg.hxx"
64 #include "parawin.hxx"
65 #include "ModuleHelper.hxx"
66 #include "ForResId.hrc"
67 #include <com/sun/star/sheet/FormulaToken.hpp>
68 #include <com/sun/star/sheet/FormulaLanguage.hpp>
69 #include <com/sun/star/sheet/FormulaMapGroup.hpp>
70 #include <com/sun/star/sheet/FormulaMapGroupSpecialOffset.hpp>
71 #include <com/sun/star/beans/XPropertySet.hpp>
72 #include <boost/bind.hpp>
73 #include <comphelper/processfactory.hxx>
74 #include <map>
75 
76 #define TOKEN_OPEN  0
77 #define TOKEN_CLOSE 1
78 #define TOKEN_SEP   2
79 namespace formula
80 {
81     using namespace ::com::sun::star;
82 
83     class OFormulaToken : public IFormulaToken
84     {
85         sal_Int32   m_nParaCount;
86         bool        m_bIsFunction;
87 
88     public:
89         OFormulaToken(bool _bFunction,sal_Int32 _nParaCount) : m_nParaCount(_nParaCount),m_bIsFunction(_bFunction){}
90 
91         virtual bool isFunction() const { return m_bIsFunction; }
92         virtual sal_uInt32 getArgumentCount() const { return m_nParaCount; }
93     };
94 
95 
96     class FormulaDlg_Impl
97     {
98     public:
99         ::std::pair<RefButton*,RefEdit*>
100                         RefInputStartBefore( RefEdit* pEdit, RefButton* pButton );
101         void            RefInputStartAfter( RefEdit* pEdit, RefButton* pButton );
102         void            RefInputDoneAfter( sal_Bool bForced );
103         sal_Bool			CalcValue( const String& rStrExp, String& rStrResult );
104         sal_Bool			CalcStruct( const String& rStrExp);
105         void			UpdateValues();
106         void			DeleteArgs();
107         xub_StrLen      GetFunctionPos(xub_StrLen nPos);
108         void			ClearAllParas();
109 
110         void            MakeTree(IStructHelper* _pTree,SvLBoxEntry* pParent,FormulaToken* _pToken,long Count);
111         void            fillTree(IStructHelper* _pTree);
112         void            UpdateTokenArray( const String& rStrExp);
113         String          RepairFormula(const String& aFormula);
114 	    void			FillDialog(sal_Bool nFlag=sal_True);
115 	    void			EditNextFunc( sal_Bool bForward, xub_StrLen nFStart=NOT_FOUND );
116 	    void			EditThisFunc(xub_StrLen nFStart);
117 	    void			EditFuncParas(xub_StrLen nEditPos);
118 
119 
120 	    void			UpdateArgInput( sal_uInt16 nOffset, sal_uInt16 nInput );
121         void			Update();
122         void            Update(const String& _sExp);
123 
124 
125 	    void			SaveArg( sal_uInt16 nEd );
126 	    void			UpdateSelection();
127 	    void			DoEnter( sal_Bool bOk );
128 	    void			UpdateFunctionDesc();
129 	    void			ResizeArgArr( const IFunctionDescription* pNewFunc );
130 	    void			FillListboxes();
131 	    void			FillControls(sal_Bool &rbNext, sal_Bool &rbPrev);
132 
133         FormulaDlgMode  SetMeText(const String& _sText,xub_StrLen PrivStart, xub_StrLen PrivEnd,sal_Bool bMatrix,sal_Bool _bSelect,sal_Bool _bUpdate);
134         void            SetMeText(const String& _sText);
135         sal_Bool            CheckMatrix(String& aFormula /*IN/OUT*/);
136 
137         void            SetEdSelection();
138 
139         sal_Bool            UpdateParaWin(Selection& _rSelection);
140         void            UpdateParaWin(const Selection& _rSelection,const String& _sRefStr);
141 
142         void            SetData(xub_StrLen nFStart,xub_StrLen nNextFStart,xub_StrLen nNextFEnd,xub_StrLen& PrivStart,xub_StrLen& PrivEnd);
143         void            PreNotify( NotifyEvent& rNEvt );
144 
145         RefEdit*        GetCurrRefEdit();
146         rtl::OString    FindFocusWin(Window *pWin);
147 
148         const FormulaHelper& GetFormulaHelper() const;
149         uno::Reference< sheet::XFormulaOpCodeMapper > GetFormulaOpCodeMapper() const;
150 
151 	    DECL_LINK( ModifyHdl, ParaWin* );
152 	    DECL_LINK( FxHdl, ParaWin* );
153 
154 	    DECL_LINK( MatrixHdl, CheckBox *);
155 	    DECL_LINK( FormulaHdl, MultiLineEdit* );
156 	    DECL_LINK( FormulaCursorHdl, EditBox*);
157 	    DECL_LINK( BtnHdl, PushButton* );
158 	    DECL_LINK( GetEdFocusHdl, ArgInput* );
159 	    DECL_LINK( GetFxFocusHdl, ArgInput* );
160 	    DECL_LINK( DblClkHdl, FuncPage* );
161 	    DECL_LINK( FuncSelHdl, FuncPage*);
162 	    DECL_LINK( StructSelHdl, StructPage * );
163     public:
164         OModuleClient                                           m_aModuleClient;
165         mutable uno::Reference< sheet::XFormulaOpCodeMapper>    m_xOpCodeMapper;
166         uno::Sequence< sheet::FormulaToken >                    m_aTokenList;
167         ::std::auto_ptr<FormulaTokenArray>                      m_pTokenArray;
168         mutable uno::Sequence< sheet::FormulaOpCodeMapEntry >   m_aSpecialOpCodes;
169         mutable const sheet::FormulaOpCodeMapEntry*             m_pSpecialOpCodesEnd;
170         mutable uno::Sequence< sheet::FormulaToken >            m_aSeparatorsOpCodes;
171         mutable uno::Sequence< sheet::FormulaOpCodeMapEntry >   m_aFunctionOpCodes;
172         mutable const sheet::FormulaOpCodeMapEntry*             m_pFunctionOpCodesEnd;
173         mutable uno::Sequence< sheet::FormulaOpCodeMapEntry >   m_aUnaryOpCodes;
174         mutable const sheet::FormulaOpCodeMapEntry*             m_pUnaryOpCodesEnd;
175         mutable uno::Sequence< sheet::FormulaOpCodeMapEntry >   m_aBinaryOpCodes;
176         mutable const sheet::FormulaOpCodeMapEntry*             m_pBinaryOpCodesEnd;
177         ::std::vector< ::boost::shared_ptr<OFormulaToken> >     m_aTokens;
178         ::std::map<FormulaToken*,sheet::FormulaToken>           m_aTokenMap;
179         IFormulaEditorHelper*                                   m_pHelper;
180         Dialog*  m_pParent;
181         IControlReferenceHandler*  m_pDlg;
182 	    TabControl		aTabCtrl;
183 	    GroupBox		aGEdit;		//! MUST be placed before pParaWin for initializing
184 	    ParaWin*		pParaWin;
185 	    FixedText		aFtHeadLine;
186 	    FixedInfo		aFtFuncName;
187 	    FixedInfo		aFtFuncDesc;
188 
189 	    FixedText		aFtEditName;
190 	    //FixedInfo		aFtEditDesc;
191 
192 	    FixedText		aFtResult;
193 	    ValWnd			aWndResult;
194 
195 	    FixedText		aFtFormula;
196 	    EditBox		    aMEFormula;
197 
198 	    CheckBox		aBtnMatrix;
199 	    HelpButton		aBtnHelp;
200 	    CancelButton	aBtnCancel;
201 
202 	    PushButton		aBtnBackward;
203 	    PushButton		aBtnForward;
204 	    OKButton		aBtnEnd;
205 
206 	    RefEdit		aEdRef;
207 	    RefButton	aRefBtn;
208 
209 	    FixedText		aFtFormResult;
210 	    ValWnd			aWndFormResult;
211 
212 	    RefEdit*		pTheRefEdit;
213 	    RefButton*	pTheRefButton;
214 	    FuncPage*	pFuncPage;
215 	    StructPage*	pStructPage;
216 	    String			aOldFormula;
217 	    sal_Bool			bStructUpdate;
218 	    MultiLineEdit*  pMEdit;
219 	    sal_Bool			bUserMatrixFlag;
220 	    Timer			aTimer;
221 
222 	    const String	aTitle1;
223 	    const String	aTitle2;
224 	    const String	aTxtEnd;
225 	    const String	aTxtOk;		// hinter aBtnEnd
226         FormulaHelper
227                         m_aFormulaHelper;
228 
229         rtl::OString    m_aEditHelpId;
230 
231         rtl::OString	aOldHelp;
232 	    rtl::OString    aOldUnique;
233 	    rtl::OString    aActivWinId;
234 	    sal_Bool			bIsShutDown;
235 
236 
237 
238 	    Font			aFntBold;
239 	    Font			aFntLight;
240 	    sal_uInt16			nEdFocus;
241     //    Selection       theCurSel;
242 	    sal_Bool			bEditFlag;
243 	    const IFunctionDescription*	pFuncDesc;
244 	    xub_StrLen		nArgs;
245         ::std::vector< ::rtl::OUString > m_aArguments;
246 	    Selection		aFuncSel;
247 
248         FormulaDlg_Impl(Dialog* pParent
249                         , bool _bSupportFunctionResult
250                         , bool _bSupportResult
251                         , bool _bSupportMatrix
252                         ,IFormulaEditorHelper* _pHelper
253                         ,const IFunctionManager* _pFunctionMgr
254                         ,IControlReferenceHandler* _pDlg);
255         ~FormulaDlg_Impl();
256 
257     };
258 FormulaDlg_Impl::FormulaDlg_Impl(Dialog* pParent
259                                         , bool _bSupportFunctionResult
260                                         , bool _bSupportResult
261                                         , bool _bSupportMatrix
262                                         ,IFormulaEditorHelper* _pHelper
263                                         ,const IFunctionManager* _pFunctionMgr
264                                         ,IControlReferenceHandler* _pDlg)
265     :
266     m_pHelper       (_pHelper),
267     m_pParent       (pParent),
268     m_pDlg          (_pDlg),
269     aTabCtrl		( pParent, ModuleRes( TC_FUNCTION ) ),
270     aGEdit			( pParent, ModuleRes( GB_EDIT ) ),
271     aFtHeadLine		( pParent, ModuleRes( FT_HEADLINE ) ),
272     aFtFuncName		( pParent, ModuleRes( FT_FUNCNAME ) ),
273     aFtFuncDesc		( pParent, ModuleRes( FT_FUNCDESC ) ),
274     //
275     aFtEditName		( pParent, ModuleRes( FT_EDITNAME ) ),
276     aFtResult		( pParent, ModuleRes( FT_RESULT ) ),
277     aWndResult		( pParent, ModuleRes( WND_RESULT ) ),
278 
279     aFtFormula		( pParent, ModuleRes( FT_FORMULA ) ),
280     aMEFormula		( pParent, ModuleRes( ED_FORMULA ) ),
281     //
282     aBtnMatrix		( pParent, ModuleRes( BTN_MATRIX ) ),
283     aBtnHelp		( pParent, ModuleRes( BTN_HELP ) ),
284     aBtnCancel		( pParent, ModuleRes( BTN_CANCEL ) ),
285     aBtnBackward	( pParent, ModuleRes( BTN_BACKWARD ) ),
286     aBtnForward		( pParent, ModuleRes( BTN_FORWARD ) ),
287     aBtnEnd			( pParent, ModuleRes( BTN_END ) ),
288     aEdRef			( pParent, _pDlg, ModuleRes( ED_REF) ),
289     aRefBtn			( pParent, ModuleRes( RB_REF),&aEdRef,_pDlg ),
290     aFtFormResult	( pParent, ModuleRes( FT_FORMULA_RESULT)),
291     aWndFormResult	( pParent, ModuleRes( WND_FORMULA_RESULT)),
292     //
293     pTheRefEdit		(NULL),
294     pMEdit			(NULL),
295     bUserMatrixFlag	(sal_False),
296     //
297     aTitle1			( ModuleRes( STR_TITLE1 ) ),		// lokale Resource
298     aTitle2			( ModuleRes( STR_TITLE2 ) ),		// lokale Resource
299     aTxtEnd			( ModuleRes( STR_END ) ),		    // lokale Resource
300     aTxtOk			( aBtnEnd.GetText() ),
301     m_aFormulaHelper(_pFunctionMgr),
302     //
303     bIsShutDown		(sal_False),
304     nEdFocus		(0),
305     pFuncDesc		(NULL),
306     nArgs			(0)
307 {
308     pParaWin = new ParaWin( pParent,_pDlg, aGEdit.GetPosPixel());
309     aGEdit.Hide();
310     pParaWin->Hide();
311     aFtEditName.Hide();
312     aEdRef.Hide();
313     aRefBtn.Hide();
314 
315     pMEdit = aMEFormula.GetEdit();
316 	//IAccessibility2 Implementation 2009-----
317 	aMEFormula.SetAccessibleName(aFtFormula.GetText());
318 	if (pMEdit)
319 		pMEdit->SetAccessibleName(aFtFormula.GetText());
320 	//-----IAccessibility2 Implementation 2009
321     m_aEditHelpId = pMEdit->GetHelpId();
322     pMEdit->SetUniqueId( m_aEditHelpId );
323 
324     bEditFlag=sal_False;
325     bStructUpdate=sal_True;
326     Point aPos=aGEdit.GetPosPixel();
327     pParaWin->SetPosPixel(aPos);
328     pParaWin->SetArgModifiedHdl(LINK( this, FormulaDlg_Impl, ModifyHdl ) );
329     pParaWin->SetFxHdl(LINK( this, FormulaDlg_Impl, FxHdl ) );
330 
331     pFuncPage= new FuncPage( &aTabCtrl,_pFunctionMgr);
332     pStructPage= new StructPage( &aTabCtrl);
333     pFuncPage->Hide();
334     pStructPage->Hide();
335     aTabCtrl.SetTabPage( TP_FUNCTION, pFuncPage);
336     aTabCtrl.SetTabPage( TP_STRUCT, pStructPage);
337 
338     aOldHelp = pParent->GetHelpId();				// HelpId aus Resource immer fuer "Seite 1"
339     aOldUnique = pParent->GetUniqueId();
340 
341     aFtResult.Show( _bSupportResult );
342     aWndResult.Show( _bSupportResult );
343 
344     aFtFormResult.Show( _bSupportFunctionResult );
345     aWndFormResult.Show( _bSupportFunctionResult );
346 
347     if ( _bSupportMatrix )
348         aBtnMatrix.SetClickHdl(LINK( this, FormulaDlg_Impl, MatrixHdl ) );
349     else
350         aBtnMatrix.Hide();
351 
352     aBtnCancel	.SetClickHdl( LINK( this, FormulaDlg_Impl, BtnHdl ) );
353     aBtnEnd 	.SetClickHdl( LINK( this, FormulaDlg_Impl, BtnHdl ) );
354     aBtnForward	.SetClickHdl( LINK( this, FormulaDlg_Impl, BtnHdl ) );
355     aBtnBackward.SetClickHdl( LINK( this, FormulaDlg_Impl, BtnHdl ) );
356 
357     pFuncPage->SetDoubleClickHdl( LINK( this, FormulaDlg_Impl, DblClkHdl ) );
358     pFuncPage->SetSelectHdl( LINK( this, FormulaDlg_Impl, FuncSelHdl) );
359     pStructPage->SetSelectionHdl( LINK( this, FormulaDlg_Impl, StructSelHdl ) );
360     pMEdit->SetModifyHdl( LINK( this, FormulaDlg_Impl, FormulaHdl ) );
361     aMEFormula.SetSelChangedHdl( LINK( this, FormulaDlg_Impl, FormulaCursorHdl ) );
362 
363     aFntLight = aFtFormula.GetFont();
364     aFntLight.SetTransparent( sal_True );
365     aFntBold = aFntLight;
366     aFntBold.SetWeight( WEIGHT_BOLD );
367 
368     pParaWin->SetArgumentFonts(aFntBold,aFntLight);
369 
370     //	function description for choosing a function is no longer in a different color
371 
372     aFtHeadLine.SetFont(aFntBold);
373     aFtFuncName.SetFont(aFntLight);
374     aFtFuncDesc.SetFont(aFntLight);
375 }
376 FormulaDlg_Impl::~FormulaDlg_Impl()
377 {
378     if(aTimer.IsActive())
379 	{
380 		aTimer.SetTimeoutHdl(Link());
381 		aTimer.Stop();
382 	} // if(aTimer.IsActive())
383     bIsShutDown=sal_True;// Setzen, damit PreNotify keinen GetFocus speichert.
384     FormEditData* pData = m_pHelper->getFormEditData();
385     if (pData) // wird nicht ueber Close zerstoert;
386 	{
387 		pData->SetFStart((xub_StrLen)pMEdit->GetSelection().Min());
388 		pData->SetSelection(pMEdit->GetSelection());
389 
390 		if(aTabCtrl.GetCurPageId()==TP_FUNCTION)
391 			pData->SetMode( (sal_uInt16) FORMULA_FORMDLG_FORMULA );
392 		else
393 			pData->SetMode( (sal_uInt16) FORMULA_FORMDLG_EDIT );
394 		pData->SetUndoStr(pMEdit->GetText());
395 		pData->SetMatrixFlag(aBtnMatrix.IsChecked());
396 	}
397 
398 	aTabCtrl.RemovePage(TP_FUNCTION);
399 	aTabCtrl.RemovePage(TP_STRUCT);
400 
401 	delete pStructPage;
402 	delete pFuncPage;
403     delete pParaWin;
404 	DeleteArgs();
405 }
406 // -----------------------------------------------------------------------------
407 void FormulaDlg_Impl::PreNotify( NotifyEvent& rNEvt )
408 {
409 	sal_uInt16 nSwitch=rNEvt.GetType();
410 	if(nSwitch==EVENT_GETFOCUS && !bIsShutDown)
411 	{
412 		Window* pWin=rNEvt.GetWindow();
413 		if(pWin!=NULL)
414 		{
415 			aActivWinId = pWin->GetUniqueId();
416 			if(aActivWinId.getLength()==0)
417 			{
418 				Window* pParent=pWin->GetParent();
419 				while(pParent!=NULL)
420 				{
421 					aActivWinId=pParent->GetUniqueId();
422 
423 					if(aActivWinId.getLength()!=0) break;
424 
425 					pParent=pParent->GetParent();
426 				}
427 			}
428 			if(aActivWinId.getLength())
429 			{
430 
431 				FormEditData* pData = m_pHelper->getFormEditData();
432 
433 				if (pData && !aTimer.IsActive()) // wird nicht ueber Close zerstoert;
434 				{
435 					pData->SetUniqueId(aActivWinId);
436 				}
437 			}
438 		}
439 	}
440 }
441 uno::Reference< sheet::XFormulaOpCodeMapper > FormulaDlg_Impl::GetFormulaOpCodeMapper() const
442 {
443     if ( !m_xOpCodeMapper.is() )
444     {
445         m_xOpCodeMapper = m_pHelper->getFormulaOpCodeMapper();
446         m_aFunctionOpCodes = m_xOpCodeMapper->getAvailableMappings(sheet::FormulaLanguage::ODFF,sheet::FormulaMapGroup::FUNCTIONS);
447         m_pFunctionOpCodesEnd = m_aFunctionOpCodes.getConstArray() + m_aFunctionOpCodes.getLength();
448 
449         m_aUnaryOpCodes = m_xOpCodeMapper->getAvailableMappings(sheet::FormulaLanguage::ODFF,sheet::FormulaMapGroup::UNARY_OPERATORS);
450         m_pUnaryOpCodesEnd = m_aUnaryOpCodes.getConstArray() + m_aUnaryOpCodes.getLength();
451 
452         m_aBinaryOpCodes = m_xOpCodeMapper->getAvailableMappings(sheet::FormulaLanguage::ODFF,sheet::FormulaMapGroup::BINARY_OPERATORS);
453         m_pBinaryOpCodesEnd = m_aBinaryOpCodes.getConstArray() + m_aBinaryOpCodes.getLength();
454 
455         uno::Sequence< ::rtl::OUString > aArgs(3);
456         aArgs[TOKEN_OPEN]   = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("("));
457         aArgs[TOKEN_CLOSE]  = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
458         aArgs[TOKEN_SEP]    = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(";"));
459         m_aSeparatorsOpCodes = m_xOpCodeMapper->getMappings(aArgs,sheet::FormulaLanguage::ODFF);
460 
461         m_aSpecialOpCodes = m_xOpCodeMapper->getAvailableMappings(sheet::FormulaLanguage::ODFF,sheet::FormulaMapGroup::SPECIAL);
462         m_pSpecialOpCodesEnd = m_aSpecialOpCodes.getConstArray() + m_aSpecialOpCodes.getLength();
463     } // if ( !m_xOpCodeMapper.is() )
464     return m_xOpCodeMapper;
465 }
466 
467 void FormulaDlg_Impl::DeleteArgs()
468 {
469     ::std::vector< ::rtl::OUString>().swap(m_aArguments);
470     nArgs = 0;
471 }
472 namespace
473 {
474     // comparing two property instances
475     struct OpCodeCompare : public ::std::binary_function< sheet::FormulaOpCodeMapEntry, sal_Int32 , bool >
476     {
477 	    bool operator() (const sheet::FormulaOpCodeMapEntry& x, sal_Int32 y) const
478 	    {
479 		    return x.Token.OpCode == y;
480 	    }
481     };
482 }
483 // -----------------------------------------------------------------------------
484 xub_StrLen FormulaDlg_Impl::GetFunctionPos(xub_StrLen nPos)
485 {
486     const sal_Unicode sep = m_pHelper->getFunctionManager()->getSingleToken(IFunctionManager::eSep);
487 
488 	xub_StrLen nTokPos=1;
489 	xub_StrLen nOldTokPos=1;
490 	xub_StrLen nFuncPos=STRING_NOTFOUND;    //@ Testweise
491 	xub_StrLen nPrevFuncPos=1;
492 	short  nBracketCount=0;
493 	sal_Bool   bFlag=sal_False;
494 	String aFormString = pMEdit->GetText();
495 	m_aFormulaHelper.GetCharClass()->toUpper( aFormString );
496 
497 	if ( m_aTokenList.getLength() )
498 	{
499         const uno::Reference< sheet::XFormulaParser > xParser(m_pHelper->getFormulaParser());
500         const table::CellAddress aRefPos(m_pHelper->getReferencePosition());
501 
502         const sheet::FormulaToken* pIter = m_aTokenList.getConstArray();
503         const sheet::FormulaToken* pEnd = pIter + m_aTokenList.getLength();
504         //if ( pIter != pEnd && aFormString.GetChar(0) == '=' )
505         //    ++pIter;
506         try
507         {
508             while ( pIter != pEnd )
509 		    {
510 			    const sal_Int32 eOp = pIter->OpCode;
511                 uno::Sequence<sheet::FormulaToken> aArgs(1);
512                 aArgs[0] = *pIter;
513                 const String aString = xParser->printFormula(aArgs, aRefPos);
514 			    const sheet::FormulaToken* pNextToken = pIter + 1;
515 
516                 if(!bUserMatrixFlag && FormulaCompiler::IsMatrixFunction((OpCode)eOp) )
517 			    {
518 				    aBtnMatrix.Check();
519 			    }
520 
521                 if ( eOp == m_aSpecialOpCodes[sheet::FormulaMapGroupSpecialOffset::PUSH].Token.OpCode || eOp == m_aSpecialOpCodes[sheet::FormulaMapGroupSpecialOffset::SPACES].Token.OpCode )
522 			    {
523 				    const xub_StrLen n1=aFormString.Search(sep, nTokPos);
524 				    const xub_StrLen n2=aFormString.Search(')',nTokPos);
525 				    xub_StrLen nXXX=nTokPos;
526 				    if(n1<n2)
527 				    {
528 					    nTokPos=n1;
529 				    }
530 				    else
531 				    {
532 					    nTokPos=n2;
533 				    }
534 				    if ( pNextToken != pEnd )
535 				    {
536                         aArgs[0] = *pNextToken;
537                         const String a2String = xParser->printFormula(aArgs, aRefPos);
538 					    const xub_StrLen n3 = aFormString.Search(a2String,nXXX);
539 				        if ( n3 < nTokPos )
540                             nTokPos = n3;
541 				    }
542 			    }
543 			    else
544 			    {
545                     nTokPos = sal::static_int_cast<xub_StrLen>( nTokPos + aString.Len() );
546 			    }
547 
548 			    if ( eOp == m_aSeparatorsOpCodes[TOKEN_OPEN].OpCode )
549 			    {
550 				    nBracketCount++;
551 				    bFlag=sal_True;
552 			    }
553 			    else if ( eOp == m_aSeparatorsOpCodes[TOKEN_CLOSE].OpCode )
554 			    {
555 				    nBracketCount--;
556 				    bFlag=sal_False;
557 				    nFuncPos=nPrevFuncPos;
558 			    }
559                 bool bIsFunction = ::std::find_if(m_aFunctionOpCodes.getConstArray(),m_pFunctionOpCodesEnd,::std::bind2nd(OpCodeCompare(),boost::cref(eOp))) != m_pFunctionOpCodesEnd;
560 
561 			    if ( bIsFunction && m_aSpecialOpCodes[sheet::FormulaMapGroupSpecialOffset::SPACES].Token.OpCode != eOp )
562 			    {
563 				    nPrevFuncPos = nFuncPos;
564 				    nFuncPos = nOldTokPos;
565 			    }
566 
567 			    if ( nOldTokPos <= nPos && nPos < nTokPos )
568 			    {
569 				    if ( !bIsFunction )
570 				    {
571 					    if ( nBracketCount < 1 )
572 					    {
573 						    nFuncPos= pMEdit->GetText().Len();
574 					    }
575 					    else if ( !bFlag )
576 					    {
577 						    nFuncPos=nPrevFuncPos;
578 					    }
579 				    }
580 				    break;
581 			    }
582 
583 			    pIter = pNextToken;
584 			    nOldTokPos = nTokPos;
585 		    } // while ( pIter != pEnd )
586         }
587         catch(const uno::Exception& )
588         {
589             DBG_ERROR("Exception caught!");
590         }
591 	}
592 
593 	return nFuncPos;
594 }
595 // -----------------------------------------------------------------------------
596 sal_Bool FormulaDlg_Impl::CalcValue( const String& rStrExp, String& rStrResult )
597 {
598 	sal_Bool bResult = sal_True;
599 
600 	if ( rStrExp.Len() > 0 )
601 	{
602 		// nur, wenn keine Tastatureingabe mehr anliegt, den Wert berechnen:
603 
604 		if ( !Application::AnyInput( INPUT_KEYBOARD ) )
605 		{
606 			bResult = m_pHelper->calculateValue(rStrExp,rStrResult);
607 		}
608 		else
609 			bResult = sal_False;
610 	}
611 
612 	return bResult;
613 }
614 
615 void FormulaDlg_Impl::UpdateValues()
616 {
617 	String aStrResult;
618 
619 	if ( CalcValue( pFuncDesc->getFormula( m_aArguments ), aStrResult ) )
620 		aWndResult.SetValue( aStrResult );
621 
622 	aStrResult.Erase();
623 	if ( CalcValue(m_pHelper->getCurrentFormula(), aStrResult ) )
624 		aWndFormResult.SetValue( aStrResult );
625 	else
626 	{
627 		aStrResult.Erase();
628 		aWndFormResult.SetValue( aStrResult );
629 	}
630 	CalcStruct(pMEdit->GetText());
631 }
632 
633 sal_Bool FormulaDlg_Impl::CalcStruct( const String& rStrExp)
634 {
635 	sal_Bool bResult = sal_True;
636 	xub_StrLen nLength=rStrExp.Len();
637 
638 	if ( rStrExp.Len() > 0 && aOldFormula!=rStrExp && bStructUpdate)
639 	{
640 		// nur, wenn keine Tastatureingabe mehr anliegt, den Wert berechnen:
641 
642 		if ( !Application::AnyInput( INPUT_KEYBOARD ) )
643 		{
644 			pStructPage->ClearStruct();
645 
646 			String aString=rStrExp;
647 			if(rStrExp.GetChar(nLength-1)=='(')
648 			{
649 				aString.Erase((xub_StrLen)(nLength-1));
650 			}
651 
652 			aString.EraseAllChars('\n');
653 			String aStrResult;
654 
655 			if ( CalcValue(aString, aStrResult ) )
656 				aWndFormResult.SetValue( aStrResult );
657 
658 			UpdateTokenArray(aString);
659             fillTree(pStructPage);
660 
661 			aOldFormula=rStrExp;
662 			if(rStrExp.GetChar(nLength-1)=='(')
663 				UpdateTokenArray(rStrExp);
664 		}
665 		else
666 			bResult = sal_False;
667 	}
668 	return bResult;
669 }
670 
671 // -----------------------------------------------------------------------------
672 void FormulaDlg_Impl::MakeTree(IStructHelper* _pTree,SvLBoxEntry* pParent,FormulaToken* _pToken,long Count)
673 {
674 	if( _pToken != NULL && Count > 0 )
675 	{
676 		long nParas = _pToken->GetParamCount();
677 		OpCode eOp = _pToken->GetOpCode();
678 
679         // #i101512# for output, the original token is needed
680         FormulaToken* pOrigToken = (_pToken->GetType() == svFAP) ? _pToken->GetFAPOrigToken() : _pToken;
681         uno::Sequence<sheet::FormulaToken> aArgs(1);
682         aArgs[0] = m_aTokenMap.find(pOrigToken)->second;
683         try
684         {
685             const table::CellAddress aRefPos(m_pHelper->getReferencePosition());
686             const String aResult = m_pHelper->getFormulaParser()->printFormula(aArgs, aRefPos);
687 
688 		    if ( nParas > 0 )
689 		    {
690 			    SvLBoxEntry* pEntry;
691 
692 			    String aTest=_pTree->GetEntryText(pParent);
693 
694 			    if(aTest==aResult &&
695 				    (eOp==ocAdd || eOp==ocMul ||
696 				     eOp==ocAmpersand))
697 			    {
698 				    pEntry=pParent;
699 			    }
700 			    else
701 			    {
702 				    if(eOp==ocBad)
703 				    {
704 					    pEntry=_pTree->InsertEntry(aResult,pParent,STRUCT_ERROR,0,_pToken);
705 				    }
706 				    else
707 				    {
708 					    pEntry=_pTree->InsertEntry(aResult,pParent,STRUCT_FOLDER,0,_pToken);
709 				    }
710 			    }
711 
712 			    MakeTree(_pTree,pEntry,m_pTokenArray->PrevRPN(),nParas);
713 			    --Count;
714 			    m_pTokenArray->NextRPN();
715 			    MakeTree(_pTree,pParent,m_pTokenArray->PrevRPN(),Count);
716 		    }
717 		    else
718 		    {
719 			    if(eOp==ocBad)
720 			    {
721 				    _pTree->InsertEntry(aResult,pParent,STRUCT_ERROR,0,_pToken);
722 			    }
723 			    else
724 			    {
725 				    _pTree->InsertEntry(aResult,pParent,STRUCT_END,0,_pToken);
726 			    }
727 			    --Count;
728 			    MakeTree(_pTree,pParent,m_pTokenArray->PrevRPN(),Count);
729 		    }
730         }
731         catch(uno::Exception&)
732         {
733             DBG_UNHANDLED_EXCEPTION();
734         }
735 	}
736 }
737 
738 void FormulaDlg_Impl::fillTree(IStructHelper* _pTree)
739 {
740     GetFormulaOpCodeMapper();
741     FormulaToken* pToken = m_pTokenArray->LastRPN();
742 
743 	if( pToken != NULL)
744 	{
745 		MakeTree(_pTree,NULL,pToken,1);
746 	}
747 }
748 void FormulaDlg_Impl::UpdateTokenArray( const String& rStrExp)
749 {
750     m_aTokenMap.clear();
751     m_aTokenList.realloc(0);
752     try
753     {
754         const table::CellAddress aRefPos(m_pHelper->getReferencePosition());
755         m_aTokenList = m_pHelper->getFormulaParser()->parseFormula(rStrExp, aRefPos);
756     }
757     catch(const uno::Exception&)
758     {
759         DBG_UNHANDLED_EXCEPTION();
760     }
761     GetFormulaOpCodeMapper(); // just to get it initialized
762 	m_pTokenArray = m_pHelper->convertToTokenArray(m_aTokenList);
763     const sal_Int32 nLen = static_cast<sal_Int32>(m_pTokenArray->GetLen());
764     FormulaToken** pTokens = m_pTokenArray->GetArray();
765     if ( pTokens && nLen == m_aTokenList.getLength() )
766     {
767         for (sal_Int32 nPos=0; nPos<nLen; nPos++)
768         {
769             m_aTokenMap.insert(::std::map<FormulaToken*,sheet::FormulaToken>::value_type(pTokens[nPos],m_aTokenList[nPos]));
770         }
771     } // if ( pTokens && nLen == m_aTokenList.getLength() )
772 
773     FormulaCompiler aCompiler(*m_pTokenArray.get());
774     aCompiler.SetCompileForFAP(sal_True);   // #i101512# special handling is needed
775     aCompiler.CompileTokenArray();
776 }
777 
778 void FormulaDlg_Impl::FillDialog(sal_Bool nFlag)
779 {
780 	sal_Bool bNext=sal_True, bPrev=sal_True;
781 	if(nFlag)
782 		FillControls(bNext, bPrev);
783 	FillListboxes();
784 	if(nFlag)
785 	{
786 		aBtnBackward.Enable(bPrev);
787 		aBtnForward.Enable(bNext);
788 	}
789 
790 	String aStrResult;
791 
792 	if ( CalcValue(m_pHelper->getCurrentFormula(), aStrResult ) )
793 		aWndFormResult.SetValue( aStrResult );
794 	else
795 	{
796 		aStrResult.Erase();
797 		aWndFormResult.SetValue( aStrResult );
798 	}
799 }
800 
801 // -----------------------------------------------------------------------------
802 void FormulaDlg_Impl::FillListboxes()
803 {
804 	//	Umschalten zwischen den "Seiten"
805     FormEditData* pData = m_pHelper->getFormEditData();
806 	String aNewTitle;
807 	//	1. Seite: Funktion auswaehlen
808 	if ( pFuncDesc && pFuncDesc->getCategory() )
809 	{
810 		if( pFuncPage->GetCategory() != pFuncDesc->getCategory()->getNumber() + 1 )
811 			pFuncPage->SetCategory(static_cast<sal_uInt16>(pFuncDesc->getCategory()->getNumber() + 1));
812 
813 		sal_uInt16 nPos=pFuncPage->GetFuncPos(pFuncDesc);
814 
815 		pFuncPage->SetFunction(nPos);
816 	}
817 	else if ( pData )
818 	{
819 		pFuncPage->SetCategory( pData->GetCatSel() );
820 		pFuncPage->SetFunction( pData->GetFuncSel() );
821 	}
822 	FuncSelHdl(NULL);
823 
824 	//	ResizeArgArr jetzt schon in UpdateFunctionDesc
825 
826 
827     m_pHelper->setDispatcherLock( sal_True);// Modal-Modus einschalten
828 
829 	aNewTitle = aTitle1;
830 
831 	//	HelpId fuer 1. Seite ist die aus der Resource
832 	m_pParent->SetHelpId( aOldHelp );
833 	m_pParent->SetUniqueId( aOldUnique );
834 }
835 // -----------------------------------------------------------------------------
836 void FormulaDlg_Impl::FillControls(sal_Bool &rbNext, sal_Bool &rbPrev)
837 {
838 	//	Umschalten zwischen den "Seiten"
839     FormEditData* pData = m_pHelper->getFormEditData();
840 	if (!pData )
841         return;
842 
843 	String aNewTitle;
844 	//	2. Seite oder Editieren: ausgewaehlte Funktion anzeigen
845 
846 	xub_StrLen nFStart	   = pData->GetFStart();
847 	String aFormula		   = m_pHelper->getCurrentFormula();
848 	xub_StrLen nNextFStart = nFStart;
849 	xub_StrLen nNextFEnd   = 0;
850 
851 	aFormula.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " )" ));
852 	DeleteArgs();
853 	const IFunctionDescription* pOldFuncDesc = pFuncDesc;
854 	sal_Bool bTestFlag = sal_False;
855 
856 	if ( m_aFormulaHelper.GetNextFunc( aFormula, sal_False,
857 									 nNextFStart, &nNextFEnd, &pFuncDesc, &m_aArguments ) )
858 	{
859 		bTestFlag = (pOldFuncDesc != pFuncDesc);
860 		if(bTestFlag)
861 		{
862 			aFtHeadLine.Hide();
863 			aFtFuncName.Hide();
864 			aFtFuncDesc.Hide();
865 			pParaWin->SetFunctionDesc(pFuncDesc);
866 			aFtEditName.SetText( pFuncDesc->getFunctionName() );
867             aFtEditName.Show();
868             pParaWin->Show();
869             const rtl::OString aHelpId = pFuncDesc->getHelpId();
870             if ( aHelpId.getLength() )
871                 pMEdit->SetHelpId(aHelpId);
872 		}
873 
874 		xub_StrLen nOldStart, nOldEnd;
875 		m_pHelper->getSelection( nOldStart, nOldEnd );
876 		if ( nOldStart != nNextFStart || nOldEnd != nNextFEnd )
877 		{
878 			m_pHelper->setSelection( nNextFStart, nNextFEnd );
879 		}
880 		aFuncSel.Min() = nNextFStart;
881 		aFuncSel.Max() = nNextFEnd;
882 
883 		if(!bEditFlag)
884 			pMEdit->SetText(m_pHelper->getCurrentFormula());
885 		xub_StrLen PrivStart, PrivEnd;
886         m_pHelper->getSelection( PrivStart, PrivEnd);
887 		if(!bEditFlag)
888 			pMEdit->SetSelection( Selection(PrivStart, PrivEnd));
889 
890 		nArgs = pFuncDesc->getSuppressedArgumentCount();
891 		sal_uInt16 nOffset = pData->GetOffset();
892 		nEdFocus = pData->GetEdFocus();
893 
894 		//	Verkettung der Edit's fuer Focus-Kontrolle
895 
896 		if(bTestFlag)
897             pParaWin->SetArgumentOffset(nOffset);
898 		sal_uInt16 nActiv=0;
899 		xub_StrLen nArgPos= m_aFormulaHelper.GetArgStart( aFormula, nFStart, 0 );
900 		xub_StrLen nEditPos=(xub_StrLen) pMEdit->GetSelection().Min();
901 		sal_Bool	bFlag=sal_False;
902 
903 		for(sal_uInt16 i=0;i<nArgs;i++)
904 		{
905 			sal_Int32 nLength = m_aArguments[i].getLength()+1;
906 			pParaWin->SetArgument(i,m_aArguments[i]);
907 			if(nArgPos<=nEditPos && nEditPos<nArgPos+nLength)
908 			{
909 				nActiv=i;
910 				bFlag=sal_True;
911 			}
912             nArgPos = sal::static_int_cast<xub_StrLen>( nArgPos + nLength );
913 		}
914 		pParaWin->UpdateParas();
915 
916 		if(bFlag)
917 		{
918 			pParaWin->SetActiveLine(nActiv);
919 		}
920 
921 		//pParaWin->SetEdFocus( nEdFocus );
922 		UpdateValues();
923 	}
924 	else
925 	{
926 		aFtEditName.SetText(String());
927         pMEdit->SetHelpId( m_aEditHelpId );
928 	}
929 		//	Test, ob vorne/hinten noch mehr Funktionen sind
930 
931 	xub_StrLen nTempStart = m_aFormulaHelper.GetArgStart( aFormula, nFStart, 0 );
932 	rbNext = m_aFormulaHelper.GetNextFunc( aFormula, sal_False, nTempStart );
933 	nTempStart=(xub_StrLen)pMEdit->GetSelection().Min();
934 	pData->SetFStart(nTempStart);
935 	rbPrev = m_aFormulaHelper.GetNextFunc( aFormula, sal_True, nTempStart );
936 }
937 // -----------------------------------------------------------------------------
938 
939 void FormulaDlg_Impl::ClearAllParas()
940 {
941 	DeleteArgs();
942 	pFuncDesc = NULL;
943 	pParaWin->ClearAll();
944 	aWndResult.SetValue(String());
945 	aFtFuncName.SetText(String());
946 	FuncSelHdl(NULL);
947 
948 	if(pFuncPage->IsVisible())
949 	{
950         aFtEditName.Hide();
951         pParaWin->Hide();
952 
953 		aBtnForward.Enable(sal_True); //@new
954 		aFtHeadLine.Show();
955 		aFtFuncName.Show();
956 		aFtFuncDesc.Show();
957 	}
958 }
959 String FormulaDlg_Impl::RepairFormula(const String& aFormula)
960 {
961 	String aResult('=');
962     try
963     {
964 	    UpdateTokenArray(aFormula);
965 
966         if ( m_aTokenList.getLength() )
967 	    {
968             const table::CellAddress aRefPos(m_pHelper->getReferencePosition());
969             const String sFormula(m_pHelper->getFormulaParser()->printFormula(m_aTokenList, aRefPos));
970             if ( !sFormula.Len() || sFormula.GetChar(0) != '=' )
971                 aResult += sFormula;
972             else
973                 aResult = sFormula;
974 
975 	    }
976     }
977     catch(const uno::Exception& )
978     {
979         DBG_ERROR("Exception caught!");
980     }
981 	return aResult;
982 }
983 
984 void FormulaDlg_Impl::DoEnter(sal_Bool bOk)
985 {
986 	//	Eingabe ins Dokument uebernehmen oder abbrechen
987 	if ( bOk)
988 	{
989 		//	ggf. Dummy-Argumente entfernen
990 		String	aInputFormula = m_pHelper->getCurrentFormula();
991 		String	aString = RepairFormula(pMEdit->GetText());
992 		m_pHelper->setSelection(0, aInputFormula.Len());
993 		m_pHelper->setCurrentFormula(aString);
994 	}
995 
996 	m_pHelper->switchBack();
997 
998     m_pHelper->dispatch(bOk,aBtnMatrix.IsChecked());
999 	//	Daten loeschen
1000     m_pHelper->deleteFormData();
1001 
1002 	//	Dialog schliessen
1003 	m_pHelper->doClose(bOk);
1004 }
1005 // -----------------------------------------------------------------------------
1006 
1007 IMPL_LINK( FormulaDlg_Impl, BtnHdl, PushButton*, pBtn )
1008 {
1009 	if ( pBtn == &aBtnCancel )
1010 	{
1011 		DoEnter(sal_False);					// schliesst den Dialog
1012 	}
1013 	else if ( pBtn == &aBtnEnd )
1014 	{
1015 		DoEnter(sal_True);					// schliesst den Dialog
1016 	}
1017 	else if ( pBtn == &aBtnForward )
1018 	{
1019 		//@pMEdit->GrabFocus();			// Damit die Selektion auch angezeigt wird.
1020 		const IFunctionDescription* pDesc =pFuncPage->GetFuncDesc( pFuncPage->GetFunction() );
1021 
1022 		if(pDesc==pFuncDesc || !pFuncPage->IsVisible())
1023 			EditNextFunc( sal_True );
1024 		else
1025 		{
1026 			DblClkHdl(pFuncPage);	   //new
1027 			aBtnForward.Enable(sal_False); //new
1028 		}
1029 		//@EditNextFunc( sal_True );
1030 	}
1031 	else if ( pBtn == &aBtnBackward )
1032 	{
1033 		bEditFlag=sal_False;
1034 		aBtnForward.Enable(sal_True);
1035 		EditNextFunc( sal_False );
1036 		aMEFormula.Invalidate();
1037 		aMEFormula.Update();
1038 	}
1039 	//...
1040 
1041 	return 0;
1042 }
1043 // -----------------------------------------------------------------------------
1044 
1045 
1046 //	--------------------------------------------------------------------------
1047 //							Funktionen fuer 1. Seite
1048 //	--------------------------------------------------------------------------
1049 
1050 void FormulaDlg_Impl::ResizeArgArr( const IFunctionDescription* pNewFunc )
1051 {
1052 	if ( pFuncDesc != pNewFunc )
1053 	{
1054 		DeleteArgs();
1055 
1056 		if ( pNewFunc )
1057 			nArgs = pNewFunc->getSuppressedArgumentCount();
1058 
1059 		pFuncDesc = pNewFunc;
1060 	}
1061 }
1062 // -----------------------------------------------------------------------------
1063 
1064 void FormulaDlg_Impl::UpdateFunctionDesc()
1065 {
1066 	FormEditData* pData = m_pHelper->getFormEditData();
1067 	if (!pData)
1068         return;
1069 	sal_uInt16 nCat = pFuncPage->GetCategory();
1070 	if ( nCat == LISTBOX_ENTRY_NOTFOUND )
1071         nCat = 0;
1072 	pData->SetCatSel( nCat );
1073 	sal_uInt16 nFunc = pFuncPage->GetFunction();
1074 	if ( nFunc == LISTBOX_ENTRY_NOTFOUND )
1075         nFunc = 0;
1076 	pData->SetFuncSel( nFunc );
1077 
1078 	if (   (pFuncPage->GetFunctionEntryCount() > 0)
1079 		&& (pFuncPage->GetFunction() != LISTBOX_ENTRY_NOTFOUND) )
1080 	{
1081 		const IFunctionDescription* pDesc = pFuncPage->GetFuncDesc(pFuncPage->GetFunction() );
1082 		if (pDesc)
1083 		{
1084             pDesc->initArgumentInfo();      // full argument info is needed
1085 
1086 			String aSig = pDesc->getSignature();
1087 
1088 			aFtFuncName.SetText( aSig );
1089 			aFtFuncDesc.SetText( pDesc->getDescription() );
1090 			ResizeArgArr( pDesc );
1091 
1092 			if ( !m_aArguments.empty() )		// noch Argumente da?
1093 				aSig = pDesc->getFormula( m_aArguments );			// fuer Eingabezeile
1094 			//@ m_pHelper->setCurrentFormula( aSig );
1095 		}
1096 	}
1097 	else
1098 	{
1099 		aFtFuncName.SetText( String() );
1100 		aFtFuncDesc.SetText( String() );
1101 
1102 		//ResizeArgArr( NULL );
1103 		m_pHelper->setCurrentFormula( String() );
1104 	}
1105 }
1106 // -----------------------------------------------------------------------------
1107 
1108 // Handler fuer Listboxen
1109 
1110 IMPL_LINK( FormulaDlg_Impl, DblClkHdl, FuncPage*, EMPTYARG )
1111 {
1112 	sal_uInt16 nFunc = pFuncPage->GetFunction();
1113 
1114 	//	ex-UpdateLRUList
1115 	const IFunctionDescription*	pDesc = pFuncPage->GetFuncDesc(nFunc);
1116     m_pHelper->insertEntryToLRUList(pDesc);
1117 
1118 	String aFuncName = pFuncPage->GetSelFunctionName();
1119 	aFuncName.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));
1120 	m_pHelper->setCurrentFormula(aFuncName);
1121 	pMEdit->ReplaceSelected(aFuncName);
1122 
1123 	Selection aSel=pMEdit->GetSelection();
1124 	aSel.Max()=aSel.Max()-1;
1125 	pMEdit->SetSelection(aSel);
1126 
1127 	FormulaHdl(pMEdit);
1128 
1129 	aSel.Min()=aSel.Max();
1130 	pMEdit->SetSelection(aSel);
1131 
1132 	if(nArgs==0)
1133 	{
1134 		BtnHdl(&aBtnBackward);
1135 	}
1136 
1137 	pParaWin->SetEdFocus(0);
1138 	aBtnForward.Enable(sal_False); //@New
1139 
1140 	return 0;
1141 }
1142 // -----------------------------------------------------------------------------
1143 
1144 //	--------------------------------------------------------------------------
1145 //							Funktionen fuer rechte Seite
1146 //	--------------------------------------------------------------------------
1147 void FormulaDlg_Impl::SetData(xub_StrLen nFStart,xub_StrLen nNextFStart,xub_StrLen nNextFEnd,xub_StrLen& PrivStart,xub_StrLen& PrivEnd)
1148 {
1149     xub_StrLen nFEnd;
1150 
1151 	// Selektion merken und neue setzen
1152 	m_pHelper->getSelection( nFStart, nFEnd );
1153 	m_pHelper->setSelection( nNextFStart, nNextFEnd );
1154 	if(!bEditFlag)
1155 		pMEdit->SetText(m_pHelper->getCurrentFormula());
1156 
1157 
1158 	m_pHelper->getSelection( PrivStart, PrivEnd);
1159 	if(!bEditFlag)
1160 	{
1161 		pMEdit->SetSelection( Selection(PrivStart, PrivEnd));
1162 		aMEFormula.UpdateOldSel();
1163 	}
1164 
1165     FormEditData* pData = m_pHelper->getFormEditData();
1166 	pData->SetFStart( nNextFStart );
1167 	pData->SetOffset( 0 );
1168 	pData->SetEdFocus( 0 );
1169 
1170     FillDialog();
1171 }
1172 // -----------------------------------------------------------------------------
1173 void FormulaDlg_Impl::EditThisFunc(xub_StrLen nFStart)
1174 {
1175 	FormEditData* pData = m_pHelper->getFormEditData();
1176 	if (!pData) return;
1177 
1178 	String aFormula = m_pHelper->getCurrentFormula();
1179 
1180 	if(nFStart==NOT_FOUND)
1181 	{
1182 		nFStart = pData->GetFStart();
1183 	}
1184 	else
1185 	{
1186 		pData->SetFStart(nFStart);
1187 	}
1188 
1189 	xub_StrLen nNextFStart	= nFStart;
1190 	xub_StrLen nNextFEnd	= 0;
1191 
1192 	sal_Bool bFound;
1193 
1194 	//@bFound = m_pHelper->getNextFunction( aFormula, sal_False, nNextFStart, &nNextFEnd, &pFuncDesc );
1195 
1196 	bFound = m_aFormulaHelper.GetNextFunc( aFormula, sal_False, nNextFStart, &nNextFEnd);
1197 	if ( bFound )
1198 	{
1199         xub_StrLen PrivStart, PrivEnd;
1200         SetData(nFStart,nNextFStart,nNextFEnd,PrivStart, PrivEnd);
1201 		m_pHelper->showReference(aFormula.Copy(PrivStart, PrivEnd-PrivStart));
1202 	}
1203 	else
1204 	{
1205 		ClearAllParas();
1206 	}
1207 }
1208 
1209 void FormulaDlg_Impl::EditNextFunc( sal_Bool bForward, xub_StrLen nFStart )
1210 {
1211 	FormEditData* pData = m_pHelper->getFormEditData();
1212 	if (!pData)
1213         return;
1214 
1215 	String aFormula = m_pHelper->getCurrentFormula();
1216 
1217 	if(nFStart==NOT_FOUND)
1218 	{
1219 		nFStart = pData->GetFStart();
1220 	}
1221 	else
1222 	{
1223 		pData->SetFStart(nFStart);
1224 	}
1225 
1226 	xub_StrLen nNextFStart	= 0;
1227 	xub_StrLen nNextFEnd	= 0;
1228 
1229 	sal_Bool bFound;
1230 	if ( bForward )
1231 	{
1232 		nNextFStart	= m_aFormulaHelper.GetArgStart( aFormula, nFStart, 0 );
1233 		//@bFound = m_pHelper->getNextFunction( aFormula, sal_False, nNextFStart, &nNextFEnd, &pFuncDesc );
1234 		bFound = m_aFormulaHelper.GetNextFunc( aFormula, sal_False, nNextFStart, &nNextFEnd);
1235 	}
1236 	else
1237 	{
1238 		nNextFStart	= nFStart;
1239 		//@bFound = m_pHelper->getNextFunction( aFormula, sal_True, nNextFStart, &nNextFEnd, &pFuncDesc );
1240 		bFound = m_aFormulaHelper.GetNextFunc( aFormula, sal_True, nNextFStart, &nNextFEnd);
1241 	}
1242 
1243 	if ( bFound )
1244 	{
1245         xub_StrLen PrivStart, PrivEnd;
1246         SetData(nFStart,nNextFStart,nNextFEnd,PrivStart, PrivEnd);
1247 	}
1248 }
1249 
1250 void FormulaDlg_Impl::EditFuncParas(xub_StrLen nEditPos)
1251 {
1252 	if(pFuncDesc!=NULL)
1253 	{
1254 		FormEditData* pData = m_pHelper->getFormEditData();
1255 		if (!pData) return;
1256 
1257 		String aFormula = m_pHelper->getCurrentFormula();
1258 		aFormula +=')';
1259 		xub_StrLen nFStart = pData->GetFStart();
1260 
1261 		DeleteArgs();
1262 
1263 		nArgs = pFuncDesc->getSuppressedArgumentCount();
1264 
1265 		sal_Int32 nArgPos=m_aFormulaHelper.GetArgStart( aFormula, nFStart, 0 );
1266         m_aFormulaHelper.GetArgStrings(m_aArguments,aFormula, nFStart, nArgs );
1267 // 		m_aArguments = ScFormulaUtil::GetArgStrings( aFormula, nFStart, nArgs );
1268 
1269 		sal_uInt16 nActiv=pParaWin->GetSliderPos();
1270 		sal_Bool	bFlag=sal_False;
1271         ::std::vector< ::rtl::OUString >::iterator aIter = m_aArguments.begin();
1272         ::std::vector< ::rtl::OUString >::iterator aEnd = m_aArguments.end();
1273 		for(sal_uInt16 i=0;aIter != aEnd;i++,++aIter)
1274 		{
1275 			sal_Int32 nLength=(*aIter).getLength();
1276 			pParaWin->SetArgument(i,(*aIter));
1277 			if(nArgPos<=nEditPos && nEditPos<nArgPos+nLength)
1278 			{
1279 				nActiv=i;
1280 				bFlag=sal_True;
1281 			}
1282 			nArgPos+=nLength+1;
1283 		}
1284 
1285 		if(bFlag)
1286 		{
1287 			pParaWin->SetSliderPos(nActiv);
1288 		}
1289 
1290 		pParaWin->UpdateParas();
1291 		UpdateValues();
1292 	}
1293 
1294 }
1295 
1296 void FormulaDlg_Impl::SaveArg( sal_uInt16 nEd )
1297 {
1298 	if (nEd<nArgs)
1299 	{
1300 		sal_uInt16 i;
1301 		for(i=0;i<=nEd;i++)
1302 		{
1303 			if ( m_aArguments[i].getLength() == 0 )
1304 				m_aArguments[i] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" "));
1305 		}
1306 		if(pParaWin->GetArgument(nEd).Len()!=0)
1307 			m_aArguments[nEd] = pParaWin->GetArgument(nEd);
1308 
1309 		sal_uInt16 nClearPos=nEd+1;
1310 		for(i=nEd+1;i<nArgs;i++)
1311 		{
1312 			if(pParaWin->GetArgument(i).Len()!=0)
1313 			{
1314 				nClearPos=i+1;
1315 			}
1316 		}
1317 
1318 		for(i=nClearPos;i<nArgs;i++)
1319 		{
1320 			m_aArguments[i] = ::rtl::OUString();
1321 		}
1322 	}
1323 }
1324 
1325 IMPL_LINK( FormulaDlg_Impl, FxHdl, ParaWin*, pPtr )
1326 {
1327 	if(pPtr==pParaWin)
1328 	{
1329 		aBtnForward.Enable(sal_True); //@ Damit eine neue Fkt eingegeben werden kann.
1330 		aTabCtrl.SetCurPageId(TP_FUNCTION);
1331 
1332 		String aUndoStr = m_pHelper->getCurrentFormula();		// bevor unten ein ";" eingefuegt wird
1333 		FormEditData* pData = m_pHelper->getFormEditData();
1334 		if (!pData) return 0;
1335 
1336 		sal_uInt16 nArgNo = pParaWin->GetActiveLine();
1337 		nEdFocus=nArgNo;
1338 
1339 		SaveArg(nArgNo);
1340 		UpdateSelection();
1341 
1342 		xub_StrLen nFormulaStrPos = pData->GetFStart();
1343 
1344 		String aFormula = m_pHelper->getCurrentFormula();
1345 		xub_StrLen n1 = m_aFormulaHelper.GetArgStart( aFormula, nFormulaStrPos, nEdFocus+pData->GetOffset() );
1346 
1347 		pData->SetEdFocus( nEdFocus );
1348 		pData->SaveValues();
1349 		pData->SetMode( (sal_uInt16) FORMULA_FORMDLG_FORMULA );
1350 		pData->SetFStart( n1 );
1351 		pData->SetUndoStr( aUndoStr );
1352 		ClearAllParas();
1353 
1354 		FillDialog(sal_False);
1355 		pFuncPage->SetFocus(); //Da Parawin nicht mehr sichtbar
1356 	}
1357 	return 0;
1358 }
1359 
1360 IMPL_LINK( FormulaDlg_Impl, ModifyHdl, ParaWin*, pPtr )
1361 {
1362 	if(pPtr==pParaWin)
1363 	{
1364 		SaveArg(pParaWin->GetActiveLine());
1365 		UpdateValues();
1366 
1367 		UpdateSelection();
1368 		CalcStruct(pMEdit->GetText());
1369 	}
1370 	return 0;
1371 }
1372 
1373 IMPL_LINK( FormulaDlg_Impl, FormulaHdl, MultiLineEdit*, EMPTYARG )
1374 {
1375 
1376 	FormEditData* pData = m_pHelper->getFormEditData();
1377 	if (!pData) return 0;
1378 
1379 	bEditFlag=sal_True;
1380 	String		aInputFormula=m_pHelper->getCurrentFormula();
1381 	String		aString=pMEdit->GetText();
1382 
1383 	Selection	aSel =pMEdit->GetSelection();
1384 	xub_StrLen nTest=0;
1385 
1386 	if(aString.Len()==0) //falls alles geloescht wurde
1387 	{
1388 		aString +='=';
1389 		pMEdit->SetText(aString);
1390 		aSel .Min()=1;
1391 		aSel .Max()=1;
1392 		pMEdit->SetSelection(aSel);
1393 	}
1394 	else if(aString.GetChar(nTest)!='=') //falls ersetzt wurde;
1395 	{
1396 		aString.Insert( (sal_Unicode)'=', 0 );
1397 		pMEdit->SetText(aString);
1398 		aSel .Min()+=1;
1399 		aSel .Max()+=1;
1400 		pMEdit->SetSelection(aSel);
1401 	}
1402 
1403 
1404 	m_pHelper->setSelection(0, aInputFormula.Len());
1405 	m_pHelper->setCurrentFormula(aString);
1406 	m_pHelper->setSelection((xub_StrLen)aSel.Min(),(xub_StrLen)aSel.Max());
1407 
1408 	xub_StrLen nPos=(xub_StrLen)aSel.Min()-1;
1409 
1410 	String aStrResult;
1411 
1412 	if ( CalcValue(m_pHelper->getCurrentFormula(), aStrResult ) )
1413 		aWndFormResult.SetValue( aStrResult );
1414 	else
1415 	{
1416 		aStrResult.Erase();
1417         aWndFormResult.SetValue( aStrResult );
1418 	}
1419 	CalcStruct(aString);
1420 
1421 	nPos=GetFunctionPos(nPos);
1422 
1423 	if(nPos<aSel.Min()-1)
1424 	{
1425 		xub_StrLen nPos1=aString.Search('(',nPos);
1426 		EditNextFunc( sal_False, nPos1);
1427 	}
1428 	else
1429 	{
1430 		ClearAllParas();
1431 	}
1432 
1433 	m_pHelper->setSelection((xub_StrLen)aSel.Min(),(xub_StrLen)aSel.Max());
1434 	bEditFlag=sal_False;
1435 	return 0;
1436 }
1437 
1438 IMPL_LINK( FormulaDlg_Impl, FormulaCursorHdl, EditBox*, EMPTYARG )
1439 {
1440 	FormEditData* pData = m_pHelper->getFormEditData();
1441 	if (!pData) return 0;
1442 	xub_StrLen nFStart = pData->GetFStart();
1443 
1444 	bEditFlag=sal_True;
1445 
1446 	String		aInputFormula=m_pHelper->getCurrentFormula();
1447 	String		aString=pMEdit->GetText();
1448 
1449 	Selection	aSel =pMEdit->GetSelection();
1450 	m_pHelper->setSelection((xub_StrLen)aSel.Min(),(xub_StrLen)aSel.Max());
1451 
1452 	if(aSel.Min()==0)
1453 	{
1454 		aSel.Min()=1;
1455 		pMEdit->SetSelection(aSel);
1456 	}
1457 
1458 	if(aSel.Min()!=aString.Len())
1459 	{
1460 		xub_StrLen nPos=(xub_StrLen)aSel.Min();
1461 
1462 		nFStart=GetFunctionPos(nPos - 1);
1463 
1464 		if(nFStart<nPos)
1465 		{
1466 			xub_StrLen nPos1=m_aFormulaHelper.GetFunctionEnd(aString,nFStart);
1467 
1468 			if(nPos1>nPos || nPos1==STRING_NOTFOUND)
1469 			{
1470 				EditThisFunc(nFStart);
1471 			}
1472 			else
1473 			{
1474 				xub_StrLen n=nPos;
1475 				short nCount=1;
1476 				while(n>0)
1477 				{
1478 				   if(aString.GetChar(n)==')')
1479 					   nCount++;
1480 				   else if(aString.GetChar(n)=='(')
1481 					   nCount--;
1482 				   if(nCount==0) break;
1483 				   n--;
1484 				}
1485 				if(nCount==0)
1486 				{
1487 					nFStart=m_aFormulaHelper.GetFunctionStart(aString,n,sal_True);
1488 					EditThisFunc(nFStart);
1489 				}
1490 				else
1491 				{
1492 					ClearAllParas();
1493 				}
1494 			}
1495 		}
1496 		else
1497 		{
1498 			ClearAllParas();
1499 		}
1500 	}
1501 	m_pHelper->setSelection((xub_StrLen)aSel.Min(),(xub_StrLen)aSel.Max());
1502 
1503 	bEditFlag=sal_False;
1504 	return 0;
1505 }
1506 
1507 void FormulaDlg_Impl::UpdateSelection()
1508 {
1509 	m_pHelper->setSelection((xub_StrLen)aFuncSel.Min(),(xub_StrLen)aFuncSel.Max());
1510 	m_pHelper->setCurrentFormula( pFuncDesc->getFormula( m_aArguments ) );
1511 	pMEdit->SetText(m_pHelper->getCurrentFormula());
1512 	xub_StrLen PrivStart, PrivEnd;
1513 	m_pHelper->getSelection( PrivStart, PrivEnd);
1514 	aFuncSel.Min()=PrivStart;
1515 	aFuncSel.Max()=PrivEnd;
1516 
1517 	nArgs = pFuncDesc->getSuppressedArgumentCount();
1518 
1519 	String aFormula=pMEdit->GetText();
1520 	sal_Int32 nArgPos=m_aFormulaHelper.GetArgStart( aFormula,PrivStart,0);
1521 
1522 	sal_uInt16 nPos=pParaWin->GetActiveLine();
1523 
1524 	for(sal_uInt16 i=0;i<nPos;i++)
1525 	{
1526 		nArgPos += (m_aArguments[i].getLength() + 1);
1527 	}
1528 	sal_Int32 nLength= m_aArguments[nPos].getLength();
1529 
1530 	Selection aSel(nArgPos,nArgPos+nLength);
1531 	m_pHelper->setSelection((sal_uInt16)nArgPos,(sal_uInt16)(nArgPos+nLength));
1532 	pMEdit->SetSelection(aSel);
1533 	aMEFormula.UpdateOldSel();
1534 }
1535 ::std::pair<RefButton*,RefEdit*> FormulaDlg_Impl::RefInputStartBefore( RefEdit* pEdit, RefButton* pButton )
1536 {
1537     aEdRef.Show();
1538     pTheRefEdit = pEdit;
1539     pTheRefButton = pButton;
1540 
1541     if( pTheRefEdit )
1542     {
1543         aEdRef.SetRefString( pTheRefEdit->GetText() );
1544         aEdRef.SetSelection( pTheRefEdit->GetSelection() );
1545         aEdRef.SetHelpId( pTheRefEdit->GetHelpId() );
1546         aEdRef.SetUniqueId( pTheRefEdit->GetUniqueId() );
1547     }
1548 
1549     aRefBtn.Show( pButton != NULL );
1550 
1551     //m_pHelper->RefInputStart( &aEdRef, pButton ? &aRefBtn : NULL );
1552     ::std::pair<RefButton*,RefEdit*> aPair;
1553     aPair.first = pButton ? &aRefBtn : NULL;
1554     aPair.second = &aEdRef;
1555     return aPair;
1556 }
1557 void FormulaDlg_Impl::RefInputStartAfter( RefEdit* /*pEdit*/, RefButton* /*pButton*/ )
1558 {
1559     aRefBtn.SetEndImage();
1560 
1561     if( pTheRefEdit )
1562     {
1563         String aStr = aTitle2;
1564         aStr += ' ';
1565         aStr += aFtEditName.GetText();
1566         aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "( " ) );
1567         if( pParaWin->GetActiveLine() > 0 )
1568             aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "...; " ) );
1569         aStr += pParaWin->GetActiveArgName();
1570         if( pParaWin->GetActiveLine() + 1 < nArgs )
1571             aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "; ..." ));
1572         aStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " )" ) );
1573 
1574         m_pParent->SetText( MnemonicGenerator::EraseAllMnemonicChars( aStr ) );
1575     }
1576 }
1577 void FormulaDlg_Impl::RefInputDoneAfter( sal_Bool bForced )
1578 {
1579     aRefBtn.SetStartImage();
1580     if( bForced || !aRefBtn.IsVisible() )
1581     {
1582         aEdRef.Hide();
1583         aRefBtn.Hide();
1584         if( pTheRefEdit )
1585         {
1586             pTheRefEdit->SetRefString( aEdRef.GetText() );
1587             pTheRefEdit->GrabFocus();
1588 
1589             if( pTheRefButton )
1590                 pTheRefButton->SetStartImage();
1591 
1592             sal_uInt16 nPrivActiv = pParaWin->GetActiveLine();
1593             pParaWin->SetArgument( nPrivActiv, aEdRef.GetText() );
1594             ModifyHdl( pParaWin );
1595             pTheRefEdit = NULL;
1596         }
1597         m_pParent->SetText( aTitle1 );
1598     }
1599 }
1600 RefEdit* FormulaDlg_Impl::GetCurrRefEdit()
1601 {
1602     return aEdRef.IsVisible() ? &aEdRef : pParaWin->GetActiveEdit();
1603 }
1604 void FormulaDlg_Impl::Update()
1605 {
1606     FormEditData* pData = m_pHelper->getFormEditData();
1607     const String sExpression = pMEdit->GetText();
1608     aOldFormula = String();
1609     UpdateTokenArray(sExpression);
1610 	FormulaCursorHdl(&aMEFormula);
1611 	CalcStruct(sExpression);
1612 	if(pData->GetMode() == FORMULA_FORMDLG_FORMULA)
1613 		aTabCtrl.SetCurPageId(TP_FUNCTION);
1614 	else
1615 		aTabCtrl.SetCurPageId(TP_STRUCT);
1616 	aBtnMatrix.Check(pData->GetMatrixFlag());
1617 	/*aTimer.SetTimeout(200);
1618 	aTimer.SetTimeoutHdl(LINK( this, FormulaDlg_Impl, UpdateFocusHdl));
1619 	aTimer.Start();*/
1620 }
1621 void FormulaDlg_Impl::Update(const String& _sExp)
1622 {
1623     CalcStruct(_sExp);
1624 	FillDialog();
1625 	//aBtnForward.Enable(sal_True); //@New
1626 	FuncSelHdl(NULL);
1627 }
1628 void FormulaDlg_Impl::SetMeText(const String& _sText)
1629 {
1630     FormEditData* pData = m_pHelper->getFormEditData();
1631     pMEdit->SetText(_sText);
1632 	pMEdit->SetSelection( pData->GetSelection());
1633 	aMEFormula.UpdateOldSel();
1634 }
1635 FormulaDlgMode FormulaDlg_Impl::SetMeText(const String& _sText,xub_StrLen PrivStart, xub_StrLen PrivEnd,sal_Bool bMatrix,sal_Bool _bSelect,sal_Bool _bUpdate)
1636 {
1637     FormulaDlgMode eMode = FORMULA_FORMDLG_FORMULA;
1638     if(!bEditFlag)
1639 		pMEdit->SetText(_sText);
1640 
1641 	if ( _bSelect || !bEditFlag )
1642 	    pMEdit->SetSelection( Selection(PrivStart, PrivEnd));
1643     if ( _bUpdate )
1644     {
1645 	    aMEFormula.UpdateOldSel();
1646 	    pMEdit->Invalidate();
1647 	    m_pHelper->showReference(pMEdit->GetSelected());
1648 	    eMode = FORMULA_FORMDLG_EDIT;
1649 
1650 	    aBtnMatrix.Check( bMatrix );
1651     } // if ( _bUpdate )
1652     return eMode;
1653 }
1654 sal_Bool FormulaDlg_Impl::CheckMatrix(String& aFormula)
1655 {
1656     pMEdit->GrabFocus();
1657 	xub_StrLen nLen = aFormula.Len();
1658 	sal_Bool bMatrix =  nLen > 3 					// Matrix-Formel ?
1659 			&& aFormula.GetChar(0) == '{'
1660 			&& aFormula.GetChar(1) == '='
1661 			&& aFormula.GetChar(nLen-1) == '}';
1662 	if ( bMatrix )
1663 	{
1664 		aFormula.Erase( 0, 1 );
1665 		aFormula.Erase( aFormula.Len()-1, 1);
1666 		aBtnMatrix.Check( bMatrix );
1667 		aBtnMatrix.Disable();
1668 	} // if ( bMatrix )
1669 
1670     aTabCtrl.SetCurPageId(TP_STRUCT);
1671     return bMatrix;
1672 }
1673 IMPL_LINK( FormulaDlg_Impl, StructSelHdl, StructPage*, pStruP )
1674 {
1675 	bStructUpdate=sal_False;
1676 	if(pStructPage->IsVisible())	aBtnForward.Enable(sal_False); //@New
1677 
1678 	if(pStructPage==pStruP)
1679 	{
1680         /// TODO
1681 		//ScToken* pSelToken = pStructPage->GetSelectedToken();
1682   //      ScToken* pOrigToken = ((pSelToken && pSelToken->GetType() == svFAP) ?
1683   //              pSelToken->GetFAPOrigToken() : pSelToken);
1684 		//xub_StrLen nTokPos=1;
1685 
1686 		//if(pScTokA!=NULL)
1687 		//{
1688 		//	ScToken* pToken = pScTokA->First();
1689 
1690 		//	while(pToken!=NULL)
1691 		//	{
1692 		//		String aString;
1693   //              if ( pToken == pOrigToken )
1694   //                  break;
1695 		//		pComp->CreateStringFromToken( aString,pToken);
1696   //              nTokPos = sal::static_int_cast<xub_StrLen>( nTokPos + aString.Len() );
1697 		//		pToken=pScTokA->Next();
1698 		//	}
1699 		//	EditThisFunc(nTokPos);
1700 		//}
1701 
1702 		//if( pOrigToken )
1703 		//{
1704 		//	String aStr;
1705 		//	pComp->CreateStringFromToken( aStr, pOrigToken );
1706 		//	String aEntryTxt=pStructPage->GetSelectedEntryText();
1707 
1708 		//	if(aEntryTxt!=aStr)
1709 		//		ShowReference(aEntryTxt);
1710 		//}
1711 
1712 	}
1713 	bStructUpdate=sal_True;
1714 	return 0;
1715 }
1716 IMPL_LINK( FormulaDlg_Impl, MatrixHdl, CheckBox *, EMPTYARG )
1717 {
1718 	bUserMatrixFlag=sal_True;
1719 	return 0;
1720 }
1721 
1722 IMPL_LINK( FormulaDlg_Impl, FuncSelHdl, FuncPage*, EMPTYARG )
1723 {
1724 	sal_uInt16 nCat = pFuncPage->GetCategory();
1725 	if ( nCat == LISTBOX_ENTRY_NOTFOUND ) nCat = 0;
1726 	sal_uInt16 nFunc = pFuncPage->GetFunction();
1727 	if ( nFunc == LISTBOX_ENTRY_NOTFOUND ) nFunc = 0;
1728 
1729 	if (   (pFuncPage->GetFunctionEntryCount() > 0)
1730 		&& (pFuncPage->GetFunction() != LISTBOX_ENTRY_NOTFOUND) )
1731 	{
1732 		const IFunctionDescription* pDesc =pFuncPage->GetFuncDesc( pFuncPage->GetFunction() );
1733 
1734 		if(pDesc!=pFuncDesc) aBtnForward.Enable(sal_True); //new
1735 
1736 		if (pDesc)
1737 		{
1738             pDesc->initArgumentInfo();      // full argument info is needed
1739 
1740 			String aSig = pDesc->getSignature();
1741 			aFtHeadLine.SetText( pDesc->getFunctionName() );
1742 			aFtFuncName.SetText( aSig );
1743 			aFtFuncDesc.SetText( pDesc->getDescription() );
1744 		}
1745 	}
1746 	else
1747 	{
1748 		aFtHeadLine.SetText( String() );
1749 		aFtFuncName.SetText( String() );
1750 		aFtFuncDesc.SetText( String() );
1751 	}
1752 	return 0;
1753 }
1754 
1755 void FormulaDlg_Impl::UpdateParaWin(const Selection& _rSelection,const String& _sRefStr)
1756 {
1757     Selection theSel = _rSelection;
1758     aEdRef.ReplaceSelected( _sRefStr );
1759 	theSel.Max() = theSel.Min() + _sRefStr.Len();
1760 	aEdRef.SetSelection( theSel );
1761 
1762 	//-------------------------------------
1763 	// Manuelles Update der Ergebnisfelder:
1764 	//-------------------------------------
1765 	sal_uInt16 nPrivActiv = pParaWin->GetActiveLine();
1766 	pParaWin->SetArgument(nPrivActiv,aEdRef.GetText());
1767 	pParaWin->UpdateParas();
1768 
1769     Edit* pEd = GetCurrRefEdit();
1770 	if( pEd != NULL )
1771         pEd->SetSelection( theSel );
1772 
1773 	pParaWin->SetRefMode(sal_False);
1774 }
1775 sal_Bool FormulaDlg_Impl::UpdateParaWin(Selection& _rSelection)
1776 {
1777     pParaWin->SetRefMode(sal_True);
1778 
1779 	String		aStrEd;
1780     Edit* pEd = GetCurrRefEdit();
1781 	if(pEd!=NULL && pTheRefEdit==NULL)
1782 	{
1783 		_rSelection=pEd->GetSelection();
1784         _rSelection.Justify();
1785 		aStrEd=pEd->GetText();
1786 		aEdRef.SetRefString(aStrEd);
1787 		aEdRef.SetSelection( _rSelection );
1788 	}
1789 	else
1790 	{
1791 		_rSelection=aEdRef.GetSelection();
1792         _rSelection.Justify();
1793 		aStrEd= aEdRef.GetText();
1794 	}
1795     return pTheRefEdit == NULL;
1796 }
1797 rtl::OString FormulaDlg_Impl::FindFocusWin(Window *pWin)
1798 {
1799     rtl::OString aUniqueId;
1800 	if(pWin->HasFocus())
1801 	{
1802 		aUniqueId=pWin->GetUniqueId();
1803 		if(aUniqueId.getLength()==0)
1804 		{
1805 			Window* pParent=pWin->GetParent();
1806 			while(pParent!=NULL)
1807 			{
1808 				aUniqueId=pParent->GetUniqueId();
1809 
1810 				if(aUniqueId.getLength()!=0) break;
1811 
1812 				pParent=pParent->GetParent();
1813 			}
1814 		}
1815 	}
1816 	else
1817 	{
1818 		sal_uInt16 nCount=pWin->GetChildCount();
1819 
1820 		for(sal_uInt16 i=0;i<nCount;i++)
1821 		{
1822 			Window* pChild=pWin->GetChild(i);
1823 			aUniqueId=FindFocusWin(pChild);
1824 			if(aUniqueId.getLength()>0) break;
1825 		}
1826 	}
1827 	return aUniqueId;
1828 }
1829 
1830 void FormulaDlg_Impl::SetEdSelection()
1831 {
1832     Edit* pEd = GetCurrRefEdit()/*aScParaWin.GetActiveEdit()*/;
1833     if( pEd )
1834 	{
1835 		Selection theSel = aEdRef.GetSelection();
1836 		//	Edit may have the focus -> call ModifyHdl in addition
1837 		//	to what's happening in GetFocus
1838 		pEd->GetModifyHdl().Call(pEd);
1839 		pEd->GrabFocus();
1840 		pEd->SetSelection(theSel);
1841 	} // if( pEd )
1842 }
1843 // -----------------------------------------------------------------------------
1844 const FormulaHelper& FormulaDlg_Impl::GetFormulaHelper()  const
1845 {
1846     return m_aFormulaHelper;
1847 }
1848 //============================================================================
1849 FormulaModalDialog::FormulaModalDialog( Window* pParent
1850                                             , bool _bSupportFunctionResult
1851                                             , bool _bSupportResult
1852                                             , bool _bSupportMatrix
1853                                             , IFormulaEditorHelper* _pHelper
1854                                             , IFunctionManager* _pFunctionMgr
1855                                             , IControlReferenceHandler* _pDlg ) :
1856 		ModalDialog( pParent, ModuleRes(RID_FORMULADLG_FORMULA_MODAL) ),
1857         m_pImpl( new FormulaDlg_Impl(this,_bSupportFunctionResult
1858                                             , _bSupportResult
1859                                             , _bSupportMatrix
1860                                             ,_pHelper,_pFunctionMgr,_pDlg))
1861 {
1862     FreeResource();
1863 	SetText(m_pImpl->aTitle1);
1864 }
1865 FormulaModalDialog::~FormulaModalDialog()
1866 {
1867 }
1868 // -----------------------------------------------------------------------------
1869 void FormulaModalDialog::Update(const String& _sExp)
1870 {
1871     m_pImpl->Update(_sExp);
1872 }
1873 
1874 // -----------------------------------------------------------------------------
1875 void FormulaModalDialog::SetMeText(const String& _sText)
1876 {
1877     m_pImpl->SetMeText(_sText);
1878 }
1879 
1880 // -----------------------------------------------------------------------------
1881 FormulaDlgMode FormulaModalDialog::SetMeText(const String& _sText,xub_StrLen PrivStart, xub_StrLen PrivEnd,sal_Bool bMatrix,sal_Bool _bSelect,sal_Bool _bUpdate)
1882 {
1883     return m_pImpl->SetMeText(_sText,PrivStart, PrivEnd,bMatrix,_bSelect,_bUpdate);
1884 }
1885 // -----------------------------------------------------------------------------
1886 void FormulaModalDialog::CheckMatrix()
1887 {
1888     m_pImpl->aBtnMatrix.Check();
1889 }
1890 // -----------------------------------------------------------------------------
1891 sal_Bool FormulaModalDialog::CheckMatrix(String& aFormula)
1892 {
1893     return m_pImpl->CheckMatrix(aFormula);
1894 }
1895 // -----------------------------------------------------------------------------
1896 String FormulaModalDialog::GetMeText() const
1897 {
1898     return m_pImpl->pMEdit->GetText();
1899 }
1900 // -----------------------------------------------------------------------------
1901 void FormulaModalDialog::Update()
1902 {
1903     m_pImpl->Update();
1904 }
1905 // -----------------------------------------------------------------------------
1906 const FormulaHelper& FormulaModalDialog::GetFormulaHelper() const
1907 {
1908     return m_pImpl->GetFormulaHelper();
1909 }
1910 // -----------------------------------------------------------------------------
1911 sal_Bool FormulaModalDialog::isUserMatrix() const
1912 {
1913     return m_pImpl->bUserMatrixFlag;
1914 }
1915 void FormulaModalDialog::DoEnter(sal_Bool _bOk)
1916 {
1917     m_pImpl->DoEnter(_bOk);
1918 }
1919 ::std::pair<RefButton*,RefEdit*> FormulaModalDialog::RefInputStartBefore( RefEdit* pEdit, RefButton* pButton )
1920 {
1921     return m_pImpl->RefInputStartBefore( pEdit, pButton );
1922 }
1923 void FormulaModalDialog::RefInputStartAfter( RefEdit* pEdit, RefButton* pButton )
1924 {
1925     m_pImpl->RefInputStartAfter( pEdit, pButton );
1926 }
1927 void FormulaModalDialog::RefInputDoneAfter( sal_Bool bForced )
1928 {
1929     m_pImpl->RefInputDoneAfter( bForced );
1930 }
1931 
1932 rtl::OString FormulaModalDialog::FindFocusWin(Window *pWin)
1933 {
1934     return m_pImpl->FindFocusWin( pWin );
1935 }
1936 
1937 void FormulaModalDialog::SetFocusWin(Window *pWin,const rtl::OString& nUniqueId)
1938 {
1939 	if(pWin->GetUniqueId()==nUniqueId)
1940 	{
1941 		pWin->GrabFocus();
1942 	}
1943 	else
1944 	{
1945 		sal_uInt16 nCount=pWin->GetChildCount();
1946 
1947 		for(sal_uInt16 i=0;i<nCount;i++)
1948 		{
1949 			Window* pChild=pWin->GetChild(i);
1950 			SetFocusWin(pChild,nUniqueId);
1951 		}
1952 	}
1953 }
1954 
1955 
1956 long FormulaModalDialog::PreNotify( NotifyEvent& rNEvt )
1957 {
1958     m_pImpl->PreNotify( rNEvt );
1959 
1960 	return ModalDialog::PreNotify(rNEvt);
1961 }
1962 
1963 void FormulaModalDialog::HighlightFunctionParas(const String& aFormula)
1964 {
1965 	m_pImpl->m_pHelper->showReference(aFormula);
1966 }
1967 
1968 void FormulaModalDialog::disableOk()
1969 {
1970     m_pImpl->aBtnEnd.Disable();
1971 }
1972 // -----------------------------------------------------------------------------
1973 const IFunctionDescription*	FormulaModalDialog::getCurrentFunctionDescription() const
1974 {
1975     OSL_VERIFY(!m_pImpl->pFuncDesc || m_pImpl->pFuncDesc->getSuppressedArgumentCount() == m_pImpl->nArgs);
1976     return m_pImpl->pFuncDesc;
1977 }
1978 // -----------------------------------------------------------------------------
1979 void FormulaModalDialog::UpdateParaWin(const Selection& _rSelection,const String& _sRefStr)
1980 {
1981     m_pImpl->UpdateParaWin(_rSelection,_sRefStr);
1982 }
1983 sal_Bool FormulaModalDialog::UpdateParaWin(Selection& _rSelection)
1984 {
1985     return m_pImpl->UpdateParaWin(_rSelection);
1986 }
1987 // -----------------------------------------------------------------------------
1988 RefEdit*	FormulaModalDialog::GetActiveEdit()
1989 {
1990     return m_pImpl->pParaWin->GetActiveEdit();
1991 }
1992 // -----------------------------------------------------------------------------
1993 void FormulaModalDialog::SetEdSelection()
1994 {
1995     m_pImpl->SetEdSelection();
1996 }
1997 
1998 //	--------------------------------------------------------------------------
1999 //		Initialisierung / gemeinsaME Funktionen  fuer Dialog
2000 //	--------------------------------------------------------------------------
2001 FormulaDlg::FormulaDlg( SfxBindings* pB, SfxChildWindow* pCW,
2002 							 Window* pParent
2003                             , bool _bSupportFunctionResult
2004                             , bool _bSupportResult
2005                             , bool _bSupportMatrix
2006                             , IFormulaEditorHelper* _pHelper,IFunctionManager* _pFunctionMgr,IControlReferenceHandler* _pDlg ) :
2007 		SfxModelessDialog( pB, pCW, pParent, ModuleRes(RID_FORMULADLG_FORMULA) ),
2008         m_pImpl( new FormulaDlg_Impl(this, _bSupportFunctionResult
2009                                             , _bSupportResult
2010                                             , _bSupportMatrix
2011                                             ,_pHelper,_pFunctionMgr,_pDlg))
2012 {
2013     FreeResource();
2014     if(!GetHelpId().getLength())				//Hack, da im SfxModelessDialog die HelpId
2015 		SetHelpId(GetUniqueId());	//fuer einen ModelessDialog entfernt und
2016 									//in eine UniqueId gewandelt wird, machen
2017 									//wir das an dieser Stelle rueckgaengig.
2018 	SetText(m_pImpl->aTitle1);
2019 }
2020 
2021 FormulaDlg::~FormulaDlg()
2022 {
2023 }
2024 // -----------------------------------------------------------------------------
2025 void FormulaDlg::Update(const String& _sExp)
2026 {
2027     m_pImpl->Update(_sExp);
2028 }
2029 
2030 // -----------------------------------------------------------------------------
2031 void FormulaDlg::SetMeText(const String& _sText)
2032 {
2033     m_pImpl->SetMeText(_sText);
2034 }
2035 
2036 // -----------------------------------------------------------------------------
2037 FormulaDlgMode FormulaDlg::SetMeText(const String& _sText,xub_StrLen PrivStart, xub_StrLen PrivEnd,sal_Bool bMatrix,sal_Bool _bSelect,sal_Bool _bUpdate)
2038 {
2039     return m_pImpl->SetMeText(_sText,PrivStart, PrivEnd,bMatrix,_bSelect,_bUpdate);
2040 }
2041 // -----------------------------------------------------------------------------
2042 void FormulaDlg::CheckMatrix()
2043 {
2044     m_pImpl->aBtnMatrix.Check();
2045 }
2046 // -----------------------------------------------------------------------------
2047 sal_Bool FormulaDlg::CheckMatrix(String& aFormula)
2048 {
2049     return m_pImpl->CheckMatrix(aFormula);
2050 }
2051 // -----------------------------------------------------------------------------
2052 String FormulaDlg::GetMeText() const
2053 {
2054     return m_pImpl->pMEdit->GetText();
2055 }
2056 // -----------------------------------------------------------------------------
2057 void FormulaDlg::Update()
2058 {
2059     m_pImpl->Update();
2060     m_pImpl->aTimer.SetTimeout(200);
2061 	m_pImpl->aTimer.SetTimeoutHdl(LINK( this, FormulaDlg, UpdateFocusHdl));
2062 	m_pImpl->aTimer.Start();
2063 }
2064 
2065 // -----------------------------------------------------------------------------
2066 sal_Bool FormulaDlg::isUserMatrix() const
2067 {
2068     return m_pImpl->bUserMatrixFlag;
2069 }
2070 void FormulaDlg::DoEnter(sal_Bool _bOk)
2071 {
2072     m_pImpl->DoEnter(_bOk);
2073 }
2074 ::std::pair<RefButton*,RefEdit*> FormulaDlg::RefInputStartBefore( RefEdit* pEdit, RefButton* pButton )
2075 {
2076     return m_pImpl->RefInputStartBefore( pEdit, pButton );
2077 }
2078 void FormulaDlg::RefInputStartAfter( RefEdit* pEdit, RefButton* pButton )
2079 {
2080     m_pImpl->RefInputStartAfter( pEdit, pButton );
2081 }
2082 void FormulaDlg::RefInputDoneAfter( sal_Bool bForced )
2083 {
2084     m_pImpl->RefInputDoneAfter( bForced );
2085 }
2086 
2087 rtl::OString FormulaDlg::FindFocusWin(Window *pWin)
2088 {
2089     return m_pImpl->FindFocusWin( pWin );
2090 }
2091 
2092 void FormulaDlg::SetFocusWin(Window *pWin,const rtl::OString& nUniqueId)
2093 {
2094 	if(pWin->GetUniqueId()==nUniqueId)
2095 	{
2096 		pWin->GrabFocus();
2097 	}
2098 	else
2099 	{
2100 		sal_uInt16 nCount=pWin->GetChildCount();
2101 
2102 		for(sal_uInt16 i=0;i<nCount;i++)
2103 		{
2104 			Window* pChild=pWin->GetChild(i);
2105 			SetFocusWin(pChild,nUniqueId);
2106 		}
2107 	}
2108 }
2109 
2110 
2111 long FormulaDlg::PreNotify( NotifyEvent& rNEvt )
2112 {
2113 	m_pImpl->PreNotify( rNEvt );
2114 	return SfxModelessDialog::PreNotify(rNEvt);
2115 }
2116 
2117 void FormulaDlg::HighlightFunctionParas(const String& aFormula)
2118 {
2119 	m_pImpl->m_pHelper->showReference(aFormula);
2120 }
2121 
2122 void FormulaDlg::disableOk()
2123 {
2124     m_pImpl->aBtnEnd.Disable();
2125 }
2126 // -----------------------------------------------------------------------------
2127 const IFunctionDescription*	FormulaDlg::getCurrentFunctionDescription() const
2128 {
2129     OSL_VERIFY(!m_pImpl->pFuncDesc || m_pImpl->pFuncDesc->getSuppressedArgumentCount() == m_pImpl->nArgs);
2130     return m_pImpl->pFuncDesc;
2131 }
2132 // -----------------------------------------------------------------------------
2133 void FormulaDlg::UpdateParaWin(const Selection& _rSelection,const String& _sRefStr)
2134 {
2135     m_pImpl->UpdateParaWin(_rSelection,_sRefStr);
2136 }
2137 sal_Bool FormulaDlg::UpdateParaWin(Selection& _rSelection)
2138 {
2139     return m_pImpl->UpdateParaWin(_rSelection);
2140 }
2141 // -----------------------------------------------------------------------------
2142 RefEdit*	FormulaDlg::GetActiveEdit()
2143 {
2144     return m_pImpl->pParaWin->GetActiveEdit();
2145 }
2146 // -----------------------------------------------------------------------------
2147 const FormulaHelper& FormulaDlg::GetFormulaHelper() const
2148 {
2149     return m_pImpl->GetFormulaHelper();
2150 }
2151 // -----------------------------------------------------------------------------
2152 void FormulaDlg::SetEdSelection()
2153 {
2154     m_pImpl->SetEdSelection();
2155 }
2156 IMPL_LINK( FormulaDlg, UpdateFocusHdl, Timer*, EMPTYARG )
2157 {
2158 	FormEditData* pData = m_pImpl->m_pHelper->getFormEditData();
2159 
2160 	if (pData) // wird nicht ueber Close zerstoert;
2161 	{
2162         m_pImpl->m_pHelper->setReferenceInput(pData);
2163         rtl::OString nUniqueId(pData->GetUniqueId());
2164 		SetFocusWin(this,nUniqueId);
2165 	}
2166 	return 0;
2167 }
2168 
2169 // -----------------------------------------------------------------------------
2170 // -----------------------------------------------------------------------------
2171 void FormEditData::SaveValues()
2172 {
2173 	FormEditData* pTemp = new FormEditData(*this);
2174 
2175 	Reset();
2176 	pParent = pTemp;
2177 }
2178 // -----------------------------------------------------------------------------
2179 void FormEditData::Reset()
2180 {
2181 	pParent = NULL;
2182 	nMode = 0;
2183 	nFStart = 0;
2184 	nCatSel = 1;		//!	oder 0 (zuletzt benutzte)
2185 	nFuncSel = 0;
2186 	nOffset = 0;
2187 	nEdFocus = 0;
2188 	bMatrix	=sal_False;
2189 	aUniqueId=rtl::OString();
2190 	aSelection.Min()=0;
2191 	aSelection.Max()=0;
2192 	aUndoStr.Erase();
2193 }
2194 // -----------------------------------------------------------------------------
2195 void FormEditData::RestoreValues()
2196 {
2197 	FormEditData* pTemp = pParent;
2198 	DBG_ASSERT(pTemp,"RestoreValues ohne Parent");
2199 	if (pTemp)
2200 	{
2201 		*this = *pTemp;
2202 		pTemp->pParent = NULL;		// sonst wird der auch geloescht!
2203 		delete pTemp;
2204 	}
2205 }
2206 // -----------------------------------------------------------------------------
2207 const FormEditData& FormEditData::operator=( const FormEditData& r )
2208 {
2209 	pParent			= r.pParent;
2210 	nMode			= r.nMode;
2211 	nFStart			= r.nFStart;
2212 	nCatSel			= r.nCatSel;
2213 	nFuncSel		= r.nFuncSel;
2214 	nOffset			= r.nOffset;
2215 	nEdFocus		= r.nEdFocus;
2216 	aUndoStr		= r.aUndoStr;
2217 	bMatrix			= r.bMatrix	;
2218 	aUniqueId		= r.aUniqueId;
2219 	aSelection		= r.aSelection;
2220 	return *this;
2221 }
2222 // -----------------------------------------------------------------------------
2223 FormEditData::FormEditData()
2224 {
2225 	Reset();
2226 }
2227 
2228 FormEditData::~FormEditData()
2229 {
2230 	delete pParent;
2231 }
2232 
2233 FormEditData::FormEditData( const FormEditData& r )
2234 {
2235 	*this = r;
2236 }
2237 
2238 // -----------------------------------------------------------------------------
2239 } // formula
2240 // -----------------------------------------------------------------------------
2241