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