xref: /AOO41X/main/formula/source/ui/dlg/formula.cxx (revision 8809db7a87f97847b57a57f4cd2b0104b2b83182)
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