1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sfx2/dispatch.hxx>
21 #include <sfx2/docfile.hxx>
22 #include <sfx2/viewfrm.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/mnemonic.hxx>
25 #include <vcl/tabpage.hxx>
26 #include <vcl/tabctrl.hxx>
27 #include <vcl/lstbox.hxx>
28 #include <vcl/group.hxx>
29 #include <vcl/wall.hxx>
31 #include <svtools/stdctrl.hxx>
32 #include <svtools/svmedit.hxx>
33 #include <svtools/treelistbox.hxx>
34 #include <svl/stritem.hxx>
35 #include <svl/zforlist.hxx>
36 #include <svl/eitem.hxx>
38 #include <unotools/charclass.hxx>
39 #include <tools/diagnose_ex.h>
41 #include "formdlgs.hrc"
42 #include "funcpage.hxx"
43 #include "formula/formula.hxx"
44 #include "formula/IFunctionDescription.hxx"
45 #include "formula/FormulaCompiler.hxx"
46 #include "formula/token.hxx"
47 #include "formula/tokenarray.hxx"
48 #include "formula/formdata.hxx"
49 #include "formula/formulahelper.hxx"
50 #include "structpg.hxx"
51 #include "parawin.hxx"
52 #include "ModuleHelper.hxx"
53 #include "ForResId.hrc"
54 #include <com/sun/star/sheet/FormulaToken.hpp>
55 #include <com/sun/star/sheet/FormulaLanguage.hpp>
56 #include <com/sun/star/sheet/FormulaMapGroup.hpp>
57 #include <com/sun/star/sheet/FormulaMapGroupSpecialOffset.hpp>
58 #include <com/sun/star/beans/XPropertySet.hpp>
59 #include <boost/ref.hpp>
60 #include <boost/shared_ptr.hpp>
61 #include <comphelper/processfactory.hxx>
62 #include <comphelper/string.hxx>
70 using namespace ::com::sun::star
;
72 class OFormulaToken
: public IFormulaToken
74 sal_Int32 m_nParaCount
;
78 OFormulaToken(bool _bFunction
,sal_Int32 _nParaCount
) : m_nParaCount(_nParaCount
),m_bIsFunction(_bFunction
){}
80 virtual ~OFormulaToken() {}
82 virtual bool isFunction() const { return m_bIsFunction
; }
83 virtual sal_uInt32
getArgumentCount() const { return m_nParaCount
; }
90 ::std::pair
<RefButton
*,RefEdit
*>
91 RefInputStartBefore( RefEdit
* pEdit
, RefButton
* pButton
);
92 void RefInputStartAfter( RefEdit
* pEdit
, RefButton
* pButton
);
93 void RefInputDoneAfter( sal_Bool bForced
);
94 sal_Bool
CalcValue( const String
& rStrExp
, String
& rStrResult
);
95 sal_Bool
CalcStruct( const String
& rStrExp
);
98 xub_StrLen
GetFunctionPos(xub_StrLen nPos
);
101 void MakeTree(IStructHelper
* _pTree
,SvTreeListEntry
* pParent
,FormulaToken
* _pToken
,long Count
);
102 void fillTree(IStructHelper
* _pTree
);
103 void UpdateTokenArray( const String
& rStrExp
);
104 String
RepairFormula(const String
& aFormula
);
105 void FillDialog(sal_Bool nFlag
=sal_True
);
106 void EditNextFunc( sal_Bool bForward
, xub_StrLen nFStart
=NOT_FOUND
);
107 void EditThisFunc(xub_StrLen nFStart
);
109 void StoreFormEditData(FormEditData
* pEditData
);
111 void UpdateArgInput( sal_uInt16 nOffset
, sal_uInt16 nInput
);
113 void Update(const String
& _sExp
);
115 void SaveArg( sal_uInt16 nEd
);
116 void UpdateSelection();
117 void DoEnter( sal_Bool bOk
);
118 void FillListboxes();
119 void FillControls(sal_Bool
&rbNext
, sal_Bool
&rbPrev
);
121 FormulaDlgMode
SetMeText(const String
& _sText
,xub_StrLen PrivStart
, xub_StrLen PrivEnd
,sal_Bool bMatrix
,sal_Bool _bSelect
,sal_Bool _bUpdate
);
122 void SetMeText(const String
& _sText
);
123 sal_Bool
CheckMatrix(String
& aFormula
/*IN/OUT*/);
125 void SetEdSelection();
127 sal_Bool
UpdateParaWin(Selection
& _rSelection
);
128 void UpdateParaWin(const Selection
& _rSelection
,const String
& _sRefStr
);
130 void SetData(xub_StrLen nFStart
,xub_StrLen nNextFStart
,xub_StrLen nNextFEnd
,xub_StrLen
& PrivStart
,xub_StrLen
& PrivEnd
);
131 void PreNotify( NotifyEvent
& rNEvt
);
133 RefEdit
* GetCurrRefEdit();
135 const FormulaHelper
& GetFormulaHelper() const;
136 uno::Reference
< sheet::XFormulaOpCodeMapper
> GetFormulaOpCodeMapper() const;
138 DECL_LINK( ModifyHdl
, ParaWin
* );
139 DECL_LINK( FxHdl
, ParaWin
* );
141 DECL_LINK(MatrixHdl
, void *);
142 DECL_LINK(FormulaHdl
, void *);
143 DECL_LINK(FormulaCursorHdl
, void *);
144 DECL_LINK( BtnHdl
, PushButton
* );
145 DECL_LINK( GetEdFocusHdl
, ArgInput
* );
146 DECL_LINK( GetFxFocusHdl
, ArgInput
* );
147 DECL_LINK(DblClkHdl
, void *);
148 DECL_LINK(FuncSelHdl
, void *);
149 DECL_LINK(StructSelHdl
, void *);
151 mutable uno::Reference
< sheet::XFormulaOpCodeMapper
> m_xOpCodeMapper
;
152 uno::Sequence
< sheet::FormulaToken
> m_aTokenList
;
153 ::std::auto_ptr
<FormulaTokenArray
> m_pTokenArray
;
154 mutable uno::Sequence
< sheet::FormulaOpCodeMapEntry
> m_aSpecialOpCodes
;
155 mutable const sheet::FormulaOpCodeMapEntry
* m_pSpecialOpCodesEnd
;
156 mutable uno::Sequence
< sheet::FormulaToken
> m_aSeparatorsOpCodes
;
157 mutable uno::Sequence
< sheet::FormulaOpCodeMapEntry
> m_aFunctionOpCodes
;
158 mutable const sheet::FormulaOpCodeMapEntry
* m_pFunctionOpCodesEnd
;
159 mutable uno::Sequence
< sheet::FormulaOpCodeMapEntry
> m_aUnaryOpCodes
;
160 mutable const sheet::FormulaOpCodeMapEntry
* m_pUnaryOpCodesEnd
;
161 mutable uno::Sequence
< sheet::FormulaOpCodeMapEntry
> m_aBinaryOpCodes
;
162 mutable const sheet::FormulaOpCodeMapEntry
* m_pBinaryOpCodesEnd
;
163 ::std::vector
< ::boost::shared_ptr
<OFormulaToken
> > m_aTokens
;
164 ::std::map
<FormulaToken
*,sheet::FormulaToken
> m_aTokenMap
;
165 IFormulaEditorHelper
* m_pHelper
;
167 IControlReferenceHandler
* m_pDlg
;
169 GroupBox aGEdit
; //! MUST be placed before pParaWin for initializing
171 FixedText aFtHeadLine
;
172 FixedInfo aFtFuncName
;
173 FixedInfo aFtFuncDesc
;
175 FixedText aFtEditName
;
180 FixedText aFtFormula
;
185 CancelButton aBtnCancel
;
187 PushButton aBtnBackward
;
188 PushButton aBtnForward
;
194 FixedText aFtFormResult
;
195 ValWnd aWndFormResult
;
197 RefEdit
* pTheRefEdit
;
198 RefButton
* pTheRefButton
;
200 StructPage
* pStructPage
;
202 sal_Bool bStructUpdate
;
203 MultiLineEdit
* pMEdit
;
204 sal_Bool bUserMatrixFlag
;
207 const String aTitle1
;
208 const String aTitle2
;
209 const String aTxtEnd
;
210 const String aTxtOk
; // behind aBtnEnd
214 rtl::OString m_aEditHelpId
;
216 rtl::OString aOldHelp
;
217 rtl::OString aOldUnique
;
218 rtl::OString aActivWinId
;
219 sal_Bool bIsShutDown
;
225 const IFunctionDescription
* pFuncDesc
;
227 ::std::vector
< ::rtl::OUString
> m_aArguments
;
230 FormulaDlg_Impl(Dialog
* pParent
231 , bool _bSupportFunctionResult
232 , bool _bSupportResult
233 , bool _bSupportMatrix
234 ,IFormulaEditorHelper
* _pHelper
235 ,const IFunctionManager
* _pFunctionMgr
236 ,IControlReferenceHandler
* _pDlg
);
240 FormulaDlg_Impl::FormulaDlg_Impl(Dialog
* pParent
241 , bool _bSupportFunctionResult
242 , bool _bSupportResult
243 , bool _bSupportMatrix
244 ,IFormulaEditorHelper
* _pHelper
245 ,const IFunctionManager
* _pFunctionMgr
246 ,IControlReferenceHandler
* _pDlg
)
248 m_pHelper (_pHelper
),
251 aTabCtrl ( pParent
, ModuleRes( TC_FUNCTION
) ),
252 aGEdit ( pParent
, ModuleRes( GB_EDIT
) ),
253 aFtHeadLine ( pParent
, ModuleRes( FT_HEADLINE
) ),
254 aFtFuncName ( pParent
, ModuleRes( FT_FUNCNAME
) ),
255 aFtFuncDesc ( pParent
, ModuleRes( FT_FUNCDESC
) ),
256 aFtEditName ( pParent
, ModuleRes( FT_EDITNAME
) ),
257 aFtResult ( pParent
, ModuleRes( FT_RESULT
) ),
258 aWndResult ( pParent
, ModuleRes( WND_RESULT
) ),
260 aFtFormula ( pParent
, ModuleRes( FT_FORMULA
) ),
261 aMEFormula ( pParent
, ModuleRes( ED_FORMULA
) ),
262 aBtnMatrix ( pParent
, ModuleRes( BTN_MATRIX
) ),
263 aBtnHelp ( pParent
, ModuleRes( BTN_HELP
) ),
264 aBtnCancel ( pParent
, ModuleRes( BTN_CANCEL
) ),
265 aBtnBackward ( pParent
, ModuleRes( BTN_BACKWARD
) ),
266 aBtnForward ( pParent
, ModuleRes( BTN_FORWARD
) ),
267 aBtnEnd ( pParent
, ModuleRes( BTN_END
) ),
268 aEdRef ( pParent
, _pDlg
, ModuleRes( ED_REF
) ),
269 aRefBtn ( pParent
, ModuleRes( RB_REF
),&aEdRef
,_pDlg
),
270 aFtFormResult ( pParent
, ModuleRes( FT_FORMULA_RESULT
)),
271 aWndFormResult ( pParent
, ModuleRes( WND_FORMULA_RESULT
)),
274 bUserMatrixFlag (sal_False
),
275 aTitle1 ( ModuleRes( STR_TITLE1
) ), // local resource
276 aTitle2 ( ModuleRes( STR_TITLE2
) ), // local resource
277 aTxtEnd ( ModuleRes( STR_END
) ), // local resource
278 aTxtOk ( aBtnEnd
.GetText() ),
279 m_aFormulaHelper(_pFunctionMgr
),
280 bIsShutDown (sal_False
),
285 pParaWin
= new ParaWin( pParent
,_pDlg
, aGEdit
.GetPosPixel());
292 pMEdit
= aMEFormula
.GetEdit();
294 aMEFormula
.SetAccessibleName(aFtFormula
.GetText());
296 pMEdit
->SetAccessibleName(aFtFormula
.GetText());
298 m_aEditHelpId
= pMEdit
->GetHelpId();
299 pMEdit
->SetUniqueId( m_aEditHelpId
);
302 bStructUpdate
=sal_True
;
303 Point aPos
=aGEdit
.GetPosPixel();
304 pParaWin
->SetPosPixel(aPos
);
305 pParaWin
->SetArgModifiedHdl(LINK( this, FormulaDlg_Impl
, ModifyHdl
) );
306 pParaWin
->SetFxHdl(LINK( this, FormulaDlg_Impl
, FxHdl
) );
308 pFuncPage
= new FuncPage( &aTabCtrl
,_pFunctionMgr
);
309 pStructPage
= new StructPage( &aTabCtrl
);
312 aTabCtrl
.SetTabPage( TP_FUNCTION
, pFuncPage
);
313 aTabCtrl
.SetTabPage( TP_STRUCT
, pStructPage
);
315 aOldHelp
= pParent
->GetHelpId(); // HelpId from resource always for "Page 1"
316 aOldUnique
= pParent
->GetUniqueId();
318 aFtResult
.Show( _bSupportResult
);
319 aWndResult
.Show( _bSupportResult
);
321 aFtFormResult
.Show( _bSupportFunctionResult
);
322 aWndFormResult
.Show( _bSupportFunctionResult
);
324 if ( _bSupportMatrix
)
325 aBtnMatrix
.SetClickHdl(LINK( this, FormulaDlg_Impl
, MatrixHdl
) );
329 aBtnCancel
.SetClickHdl( LINK( this, FormulaDlg_Impl
, BtnHdl
) );
330 aBtnEnd
.SetClickHdl( LINK( this, FormulaDlg_Impl
, BtnHdl
) );
331 aBtnForward
.SetClickHdl( LINK( this, FormulaDlg_Impl
, BtnHdl
) );
332 aBtnBackward
.SetClickHdl( LINK( this, FormulaDlg_Impl
, BtnHdl
) );
334 pFuncPage
->SetDoubleClickHdl( LINK( this, FormulaDlg_Impl
, DblClkHdl
) );
335 pFuncPage
->SetSelectHdl( LINK( this, FormulaDlg_Impl
, FuncSelHdl
) );
336 pStructPage
->SetSelectionHdl( LINK( this, FormulaDlg_Impl
, StructSelHdl
) );
337 pMEdit
->SetModifyHdl( LINK( this, FormulaDlg_Impl
, FormulaHdl
) );
338 aMEFormula
.SetSelChangedHdl( LINK( this, FormulaDlg_Impl
, FormulaCursorHdl
) );
340 aFntLight
= aFtFormula
.GetFont();
341 aFntLight
.SetTransparent( sal_True
);
342 aFntBold
= aFntLight
;
343 aFntBold
.SetWeight( WEIGHT_BOLD
);
345 pParaWin
->SetArgumentFonts(aFntBold
,aFntLight
);
347 // function description for choosing a function is no longer in a different color
349 aFtHeadLine
.SetFont(aFntBold
);
350 aFtFuncName
.SetFont(aFntLight
);
351 aFtFuncDesc
.SetFont(aFntLight
);
353 FormulaDlg_Impl::~FormulaDlg_Impl()
355 if(aTimer
.IsActive())
357 aTimer
.SetTimeoutHdl(Link());
359 }// if(aTimer.IsActive())
360 bIsShutDown
=sal_True
;// Set it in order to PreNotify not to save GetFocus.
362 aTabCtrl
.RemovePage(TP_FUNCTION
);
363 aTabCtrl
.RemovePage(TP_STRUCT
);
371 void FormulaDlg_Impl::StoreFormEditData(FormEditData
* pData
)
373 if (pData
) // it won't be destroyed over Close;
375 pData
->SetFStart((xub_StrLen
)pMEdit
->GetSelection().Min());
376 pData
->SetSelection(pMEdit
->GetSelection());
378 if(aTabCtrl
.GetCurPageId()==TP_FUNCTION
)
379 pData
->SetMode( (sal_uInt16
) FORMULA_FORMDLG_FORMULA
);
381 pData
->SetMode( (sal_uInt16
) FORMULA_FORMDLG_EDIT
);
382 pData
->SetUndoStr(pMEdit
->GetText());
383 pData
->SetMatrixFlag(aBtnMatrix
.IsChecked());
387 // -----------------------------------------------------------------------------
388 void FormulaDlg_Impl::PreNotify( NotifyEvent
& rNEvt
)
390 sal_uInt16 nSwitch
=rNEvt
.GetType();
391 if(nSwitch
==EVENT_GETFOCUS
&& !bIsShutDown
)
393 Window
* pWin
=rNEvt
.GetWindow();
396 aActivWinId
= pWin
->GetUniqueId();
397 if(aActivWinId
.isEmpty())
399 Window
* pParent
=pWin
->GetParent();
402 aActivWinId
=pParent
->GetUniqueId();
404 if(!aActivWinId
.isEmpty()) break;
406 pParent
=pParent
->GetParent();
409 if(!aActivWinId
.isEmpty())
412 FormEditData
* pData
= m_pHelper
->getFormEditData();
414 if (pData
&& !aTimer
.IsActive()) // it won't be destroyed over Close;
416 pData
->SetUniqueId(aActivWinId
);
422 uno::Reference
< sheet::XFormulaOpCodeMapper
> FormulaDlg_Impl::GetFormulaOpCodeMapper() const
424 if ( !m_xOpCodeMapper
.is() )
426 m_xOpCodeMapper
= m_pHelper
->getFormulaOpCodeMapper();
427 m_aFunctionOpCodes
= m_xOpCodeMapper
->getAvailableMappings(sheet::FormulaLanguage::ODFF
,sheet::FormulaMapGroup::FUNCTIONS
);
428 m_pFunctionOpCodesEnd
= m_aFunctionOpCodes
.getConstArray() + m_aFunctionOpCodes
.getLength();
430 m_aUnaryOpCodes
= m_xOpCodeMapper
->getAvailableMappings(sheet::FormulaLanguage::ODFF
,sheet::FormulaMapGroup::UNARY_OPERATORS
);
431 m_pUnaryOpCodesEnd
= m_aUnaryOpCodes
.getConstArray() + m_aUnaryOpCodes
.getLength();
433 m_aBinaryOpCodes
= m_xOpCodeMapper
->getAvailableMappings(sheet::FormulaLanguage::ODFF
,sheet::FormulaMapGroup::BINARY_OPERATORS
);
434 m_pBinaryOpCodesEnd
= m_aBinaryOpCodes
.getConstArray() + m_aBinaryOpCodes
.getLength();
436 uno::Sequence
< ::rtl::OUString
> aArgs(3);
437 aArgs
[TOKEN_OPEN
] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("("));
438 aArgs
[TOKEN_CLOSE
] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
439 aArgs
[TOKEN_SEP
] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(";"));
440 m_aSeparatorsOpCodes
= m_xOpCodeMapper
->getMappings(aArgs
,sheet::FormulaLanguage::ODFF
);
442 m_aSpecialOpCodes
= m_xOpCodeMapper
->getAvailableMappings(sheet::FormulaLanguage::ODFF
,sheet::FormulaMapGroup::SPECIAL
);
443 m_pSpecialOpCodesEnd
= m_aSpecialOpCodes
.getConstArray() + m_aSpecialOpCodes
.getLength();
444 } // if ( !m_xOpCodeMapper.is() )
445 return m_xOpCodeMapper
;
448 void FormulaDlg_Impl::DeleteArgs()
450 ::std::vector
< ::rtl::OUString
>().swap(m_aArguments
);
455 // comparing two property instances
456 struct OpCodeCompare
: public ::std::binary_function
< sheet::FormulaOpCodeMapEntry
, sal_Int32
, bool >
458 bool operator() (const sheet::FormulaOpCodeMapEntry
& x
, sal_Int32 y
) const
460 return x
.Token
.OpCode
== y
;
464 // -----------------------------------------------------------------------------
465 xub_StrLen
FormulaDlg_Impl::GetFunctionPos(xub_StrLen nPos
)
467 const sal_Unicode sep
= m_pHelper
->getFunctionManager()->getSingleToken(IFunctionManager::eSep
);
469 xub_StrLen nFuncPos
=STRING_NOTFOUND
; //@ Testwise
470 sal_Bool bFlag
=sal_False
;
471 String aFormString
= m_aFormulaHelper
.GetCharClass()->uppercase(pMEdit
->GetText());
473 if ( m_aTokenList
.getLength() )
475 const uno::Reference
< sheet::XFormulaParser
> xParser(m_pHelper
->getFormulaParser());
476 const table::CellAddress
aRefPos(m_pHelper
->getReferencePosition());
478 const sheet::FormulaToken
* pIter
= m_aTokenList
.getConstArray();
479 const sheet::FormulaToken
* pEnd
= pIter
+ m_aTokenList
.getLength();
482 xub_StrLen nTokPos
=1;
483 xub_StrLen nOldTokPos
=1;
484 xub_StrLen nPrevFuncPos
= 1;
485 short nBracketCount
= 0;
486 while ( pIter
!= pEnd
)
488 const sal_Int32 eOp
= pIter
->OpCode
;
489 uno::Sequence
<sheet::FormulaToken
> aArgs(1);
491 const String aString
= xParser
->printFormula(aArgs
, aRefPos
);
492 const sheet::FormulaToken
* pNextToken
= pIter
+ 1;
494 if(!bUserMatrixFlag
&& FormulaCompiler::IsMatrixFunction((OpCode
)eOp
) )
499 if ( eOp
== m_aSpecialOpCodes
[sheet::FormulaMapGroupSpecialOffset::PUSH
].Token
.OpCode
||
500 eOp
== m_aSpecialOpCodes
[sheet::FormulaMapGroupSpecialOffset::SPACES
].Token
.OpCode
)
502 const xub_StrLen n1
=aFormString
.Search(sep
, nTokPos
);
503 const xub_StrLen n2
=aFormString
.Search(')',nTokPos
);
504 xub_StrLen nXXX
=nTokPos
;
513 if ( pNextToken
!= pEnd
)
515 aArgs
[0] = *pNextToken
;
516 const String a2String
= xParser
->printFormula(aArgs
, aRefPos
);
517 const xub_StrLen n3
= aFormString
.Search(a2String
,nXXX
);
524 nTokPos
= sal::static_int_cast
<xub_StrLen
>( nTokPos
+ aString
.Len() );
527 if ( eOp
== m_aSeparatorsOpCodes
[TOKEN_OPEN
].OpCode
)
532 else if ( eOp
== m_aSeparatorsOpCodes
[TOKEN_CLOSE
].OpCode
)
536 nFuncPos
=nPrevFuncPos
;
538 bool bIsFunction
= ::std::find_if(m_aFunctionOpCodes
.getConstArray(),m_pFunctionOpCodesEnd
,::std::bind2nd(OpCodeCompare(),boost::cref(eOp
))) != m_pFunctionOpCodesEnd
;
540 if ( bIsFunction
&& m_aSpecialOpCodes
[sheet::FormulaMapGroupSpecialOffset::SPACES
].Token
.OpCode
!= eOp
)
542 nPrevFuncPos
= nFuncPos
;
543 nFuncPos
= nOldTokPos
;
546 if ( nOldTokPos
<= nPos
&& nPos
< nTokPos
)
550 if ( nBracketCount
< 1 )
552 nFuncPos
= pMEdit
->GetText().Len();
556 nFuncPos
=nPrevFuncPos
;
563 nOldTokPos
= nTokPos
;
564 } // while ( pIter != pEnd )
566 catch(const uno::Exception
& )
568 OSL_FAIL("Exception caught!");
574 // -----------------------------------------------------------------------------
575 sal_Bool
FormulaDlg_Impl::CalcValue( const String
& rStrExp
, String
& rStrResult
)
577 sal_Bool bResult
= sal_True
;
579 if ( rStrExp
.Len() > 0 )
581 // Only calculate the value when there isn't any more keyboard input:
583 if ( !Application::AnyInput( VCL_INPUT_KEYBOARD
) )
585 bResult
= m_pHelper
->calculateValue(rStrExp
,rStrResult
);
594 void FormulaDlg_Impl::UpdateValues()
598 if ( CalcValue( pFuncDesc
->getFormula( m_aArguments
), aStrResult
) )
599 aWndResult
.SetValue( aStrResult
);
602 if ( CalcValue(m_pHelper
->getCurrentFormula(), aStrResult
) )
603 aWndFormResult
.SetValue( aStrResult
);
607 aWndFormResult
.SetValue( aStrResult
);
609 CalcStruct(pMEdit
->GetText());
612 sal_Bool
FormulaDlg_Impl::CalcStruct( const String
& rStrExp
)
614 sal_Bool bResult
= sal_True
;
615 xub_StrLen nLength
=rStrExp
.Len();
617 if ( rStrExp
.Len() > 0 && aOldFormula
!=rStrExp
&& bStructUpdate
)
619 // Only calculate the value when there isn't any more keyboard input:
621 if ( !Application::AnyInput( VCL_INPUT_KEYBOARD
) )
623 pStructPage
->ClearStruct();
625 String aString
=rStrExp
;
626 if(rStrExp
.GetChar(nLength
-1)=='(')
628 aString
.Erase((xub_StrLen
)(nLength
-1));
631 aString
= comphelper::string::remove(aString
, '\n');
634 if ( CalcValue(aString
, aStrResult
) )
635 aWndFormResult
.SetValue( aStrResult
);
637 UpdateTokenArray(aString
);
638 fillTree(pStructPage
);
641 if(rStrExp
.GetChar(nLength
-1)=='(')
642 UpdateTokenArray(rStrExp
);
650 // -----------------------------------------------------------------------------
651 void FormulaDlg_Impl::MakeTree(IStructHelper
* _pTree
,SvTreeListEntry
* pParent
,FormulaToken
* _pToken
,long Count
)
653 if( _pToken
!= NULL
&& Count
> 0 )
655 long nParas
= _pToken
->GetParamCount();
656 OpCode eOp
= _pToken
->GetOpCode();
658 // #i101512# for output, the original token is needed
659 FormulaToken
* pOrigToken
= (_pToken
->GetType() == svFAP
) ? _pToken
->GetFAPOrigToken() : _pToken
;
660 uno::Sequence
<sheet::FormulaToken
> aArgs(1);
661 ::std::map
<FormulaToken
*,sheet::FormulaToken
>::const_iterator itr
= m_aTokenMap
.find(pOrigToken
);
662 if (itr
== m_aTokenMap
.end())
665 aArgs
[0] = itr
->second
;
668 const table::CellAddress
aRefPos(m_pHelper
->getReferencePosition());
669 const String aResult
= m_pHelper
->getFormulaParser()->printFormula(aArgs
, aRefPos
);
673 SvTreeListEntry
* pEntry
;
675 String aTest
=_pTree
->GetEntryText(pParent
);
678 (eOp
==ocAdd
|| eOp
==ocMul
||
687 pEntry
=_pTree
->InsertEntry(aResult
,pParent
,STRUCT_ERROR
,0,_pToken
);
691 pEntry
=_pTree
->InsertEntry(aResult
,pParent
,STRUCT_FOLDER
,0,_pToken
);
695 MakeTree(_pTree
,pEntry
,m_pTokenArray
->PrevRPN(),nParas
);
697 m_pTokenArray
->NextRPN();
698 MakeTree(_pTree
,pParent
,m_pTokenArray
->PrevRPN(),Count
);
704 _pTree
->InsertEntry(aResult
,pParent
,STRUCT_ERROR
,0,_pToken
);
708 _pTree
->InsertEntry(aResult
,pParent
,STRUCT_END
,0,_pToken
);
711 MakeTree(_pTree
,pParent
,m_pTokenArray
->PrevRPN(),Count
);
714 catch(const uno::Exception
&)
716 DBG_UNHANDLED_EXCEPTION();
721 void FormulaDlg_Impl::fillTree(IStructHelper
* _pTree
)
723 GetFormulaOpCodeMapper();
724 FormulaToken
* pToken
= m_pTokenArray
->LastRPN();
728 MakeTree(_pTree
,NULL
,pToken
,1);
731 void FormulaDlg_Impl::UpdateTokenArray( const String
& rStrExp
)
734 m_aTokenList
.realloc(0);
737 const table::CellAddress
aRefPos(m_pHelper
->getReferencePosition());
738 m_aTokenList
= m_pHelper
->getFormulaParser()->parseFormula(rStrExp
, aRefPos
);
740 catch(const uno::Exception
&)
742 DBG_UNHANDLED_EXCEPTION();
744 GetFormulaOpCodeMapper(); // just to get it initialized
745 m_pTokenArray
= m_pHelper
->convertToTokenArray(m_aTokenList
);
746 const sal_Int32 nLen
= static_cast<sal_Int32
>(m_pTokenArray
->GetLen());
747 FormulaToken
** pTokens
= m_pTokenArray
->GetArray();
748 if ( pTokens
&& nLen
== m_aTokenList
.getLength() )
750 for (sal_Int32 nPos
=0; nPos
<nLen
; nPos
++)
752 m_aTokenMap
.insert(::std::map
<FormulaToken
*,sheet::FormulaToken
>::value_type(pTokens
[nPos
],m_aTokenList
[nPos
]));
754 } // if ( pTokens && nLen == m_aTokenList.getLength() )
756 FormulaCompiler
aCompiler(*m_pTokenArray
.get());
757 aCompiler
.SetCompileForFAP(sal_True
); // #i101512# special handling is needed
758 aCompiler
.CompileTokenArray();
761 void FormulaDlg_Impl::FillDialog(sal_Bool nFlag
)
763 sal_Bool bNext
=sal_True
, bPrev
=sal_True
;
765 FillControls(bNext
, bPrev
);
769 aBtnBackward
.Enable(bPrev
);
770 aBtnForward
.Enable(bNext
);
775 if ( CalcValue(m_pHelper
->getCurrentFormula(), aStrResult
) )
776 aWndFormResult
.SetValue( aStrResult
);
780 aWndFormResult
.SetValue( aStrResult
);
784 // -----------------------------------------------------------------------------
785 void FormulaDlg_Impl::FillListboxes()
787 // Switch between the "Pages"
788 FormEditData
* pData
= m_pHelper
->getFormEditData();
790 // 1. Page: select function
791 if ( pFuncDesc
&& pFuncDesc
->getCategory() )
793 if( pFuncPage
->GetCategory() != pFuncDesc
->getCategory()->getNumber() + 1 )
794 pFuncPage
->SetCategory(static_cast<sal_uInt16
>(pFuncDesc
->getCategory()->getNumber() + 1));
796 sal_uInt16 nPos
=pFuncPage
->GetFuncPos(pFuncDesc
);
798 pFuncPage
->SetFunction(nPos
);
802 pFuncPage
->SetCategory( pData
->GetCatSel() );
803 pFuncPage
->SetFunction( pData
->GetFuncSel() );
807 m_pHelper
->setDispatcherLock( sal_True
);// Activate Modal-Mode
811 // HelpId for 1. page is the one from the resource
812 m_pParent
->SetHelpId( aOldHelp
);
813 m_pParent
->SetUniqueId( aOldUnique
);
815 // -----------------------------------------------------------------------------
816 void FormulaDlg_Impl::FillControls(sal_Bool
&rbNext
, sal_Bool
&rbPrev
)
818 // Switch between the "Pages"
819 FormEditData
* pData
= m_pHelper
->getFormEditData();
824 // 2. Page or Edit: show selected function
826 xub_StrLen nFStart
= pData
->GetFStart();
827 String aFormula
= m_pHelper
->getCurrentFormula();
828 xub_StrLen nNextFStart
= nFStart
;
829 xub_StrLen nNextFEnd
= 0;
831 aFormula
.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " )" ));
833 const IFunctionDescription
* pOldFuncDesc
= pFuncDesc
;
834 sal_Bool bTestFlag
= sal_False
;
836 if ( m_aFormulaHelper
.GetNextFunc( aFormula
, sal_False
,
837 nNextFStart
, &nNextFEnd
, &pFuncDesc
, &m_aArguments
) )
839 bTestFlag
= (pOldFuncDesc
!= pFuncDesc
);
845 pParaWin
->SetFunctionDesc(pFuncDesc
);
846 aFtEditName
.SetText( pFuncDesc
->getFunctionName() );
849 const rtl::OString aHelpId
= pFuncDesc
->getHelpId();
850 if ( !aHelpId
.isEmpty() )
851 pMEdit
->SetHelpId(aHelpId
);
854 xub_StrLen nOldStart
, nOldEnd
;
855 m_pHelper
->getSelection( nOldStart
, nOldEnd
);
856 if ( nOldStart
!= nNextFStart
|| nOldEnd
!= nNextFEnd
)
858 m_pHelper
->setSelection( nNextFStart
, nNextFEnd
);
860 aFuncSel
.Min() = nNextFStart
;
861 aFuncSel
.Max() = nNextFEnd
;
864 pMEdit
->SetText(m_pHelper
->getCurrentFormula());
865 xub_StrLen PrivStart
, PrivEnd
;
866 m_pHelper
->getSelection( PrivStart
, PrivEnd
);
868 pMEdit
->SetSelection( Selection(PrivStart
, PrivEnd
));
870 nArgs
= pFuncDesc
->getSuppressedArgumentCount();
871 sal_uInt16 nOffset
= pData
->GetOffset();
872 nEdFocus
= pData
->GetEdFocus();
874 // Concatenate the Edit's for Focus-Control
877 pParaWin
->SetArgumentOffset(nOffset
);
879 xub_StrLen nArgPos
= m_aFormulaHelper
.GetArgStart( aFormula
, nFStart
, 0 );
880 xub_StrLen nEditPos
=(xub_StrLen
) pMEdit
->GetSelection().Min();
881 sal_Bool bFlag
=sal_False
;
883 for(sal_uInt16 i
=0;i
<nArgs
;i
++)
885 sal_Int32 nLength
= m_aArguments
[i
].getLength()+1;
886 pParaWin
->SetArgument(i
,m_aArguments
[i
]);
887 if(nArgPos
<=nEditPos
&& nEditPos
<nArgPos
+nLength
)
892 nArgPos
= sal::static_int_cast
<xub_StrLen
>( nArgPos
+ nLength
);
894 pParaWin
->UpdateParas();
898 pParaWin
->SetActiveLine(nActiv
);
905 aFtEditName
.SetText(String());
906 pMEdit
->SetHelpId( m_aEditHelpId
);
908 // Test, ob vorne/hinten noch mehr Funktionen sind
910 xub_StrLen nTempStart
= m_aFormulaHelper
.GetArgStart( aFormula
, nFStart
, 0 );
911 rbNext
= m_aFormulaHelper
.GetNextFunc( aFormula
, sal_False
, nTempStart
);
912 nTempStart
=(xub_StrLen
)pMEdit
->GetSelection().Min();
913 pData
->SetFStart(nTempStart
);
914 rbPrev
= m_aFormulaHelper
.GetNextFunc( aFormula
, sal_True
, nTempStart
);
916 // -----------------------------------------------------------------------------
918 void FormulaDlg_Impl::ClearAllParas()
922 pParaWin
->ClearAll();
923 aWndResult
.SetValue(String());
924 aFtFuncName
.SetText(String());
927 if(pFuncPage
->IsVisible())
932 aBtnForward
.Enable(sal_True
); //@new
938 String
FormulaDlg_Impl::RepairFormula(const String
& aFormula
)
940 rtl::OUString
aResult('=');
943 UpdateTokenArray(aFormula
);
945 if ( m_aTokenList
.getLength() )
947 const table::CellAddress
aRefPos(m_pHelper
->getReferencePosition());
948 const String
sFormula(m_pHelper
->getFormulaParser()->printFormula(m_aTokenList
, aRefPos
));
949 if ( !sFormula
.Len() || sFormula
.GetChar(0) != '=' )
956 catch(const uno::Exception
& )
958 OSL_FAIL("Exception caught!");
963 void FormulaDlg_Impl::DoEnter(sal_Bool bOk
)
965 // Accept input to the document or cancel
968 // remove dummy arguments
969 String aInputFormula
= m_pHelper
->getCurrentFormula();
970 String aString
= RepairFormula(pMEdit
->GetText());
971 m_pHelper
->setSelection(0, aInputFormula
.Len());
972 m_pHelper
->setCurrentFormula(aString
);
975 m_pHelper
->switchBack();
977 m_pHelper
->dispatch(bOk
,aBtnMatrix
.IsChecked());
979 m_pHelper
->deleteFormData();
982 m_pHelper
->doClose(bOk
);
984 // -----------------------------------------------------------------------------
986 IMPL_LINK( FormulaDlg_Impl
, BtnHdl
, PushButton
*, pBtn
)
988 if ( pBtn
== &aBtnCancel
)
990 DoEnter(sal_False
); // closes the Dialog
992 else if ( pBtn
== &aBtnEnd
)
994 DoEnter(sal_True
); // closes the Dialog
996 else if ( pBtn
== &aBtnForward
)
998 const IFunctionDescription
* pDesc
=pFuncPage
->GetFuncDesc( pFuncPage
->GetFunction() );
1000 if(pDesc
==pFuncDesc
|| !pFuncPage
->IsVisible())
1001 EditNextFunc( sal_True
);
1004 DblClkHdl(pFuncPage
); //new
1005 aBtnForward
.Enable(sal_False
); //new
1008 else if ( pBtn
== &aBtnBackward
)
1010 bEditFlag
=sal_False
;
1011 aBtnForward
.Enable(sal_True
);
1012 EditNextFunc( sal_False
);
1013 aMEFormula
.Invalidate();
1014 aMEFormula
.Update();
1020 // -----------------------------------------------------------------------------
1023 // --------------------------------------------------------------------------
1024 // Functions for 1. Page
1025 // --------------------------------------------------------------------------
1027 // -----------------------------------------------------------------------------
1029 // Handler for Listboxes
1031 IMPL_LINK_NOARG(FormulaDlg_Impl
, DblClkHdl
)
1033 sal_uInt16 nFunc
= pFuncPage
->GetFunction();
1036 const IFunctionDescription
* pDesc
= pFuncPage
->GetFuncDesc(nFunc
);
1037 m_pHelper
->insertEntryToLRUList(pDesc
);
1039 String aFuncName
= pFuncPage
->GetSelFunctionName();
1040 aFuncName
.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));
1041 m_pHelper
->setCurrentFormula(aFuncName
);
1042 pMEdit
->ReplaceSelected(aFuncName
);
1044 Selection aSel
=pMEdit
->GetSelection();
1045 aSel
.Max()=aSel
.Max()-1;
1046 pMEdit
->SetSelection(aSel
);
1050 aSel
.Min()=aSel
.Max();
1051 pMEdit
->SetSelection(aSel
);
1055 BtnHdl(&aBtnBackward
);
1058 pParaWin
->SetEdFocus(0);
1059 aBtnForward
.Enable(sal_False
); //@New
1063 // -----------------------------------------------------------------------------
1065 // --------------------------------------------------------------------------
1066 // Functions for right Page
1067 // --------------------------------------------------------------------------
1068 void FormulaDlg_Impl::SetData(xub_StrLen nFStart
,xub_StrLen nNextFStart
,xub_StrLen nNextFEnd
,xub_StrLen
& PrivStart
,xub_StrLen
& PrivEnd
)
1072 // Notice and set new selection
1073 m_pHelper
->getSelection( nFStart
, nFEnd
);
1074 m_pHelper
->setSelection( nNextFStart
, nNextFEnd
);
1076 pMEdit
->SetText(m_pHelper
->getCurrentFormula());
1079 m_pHelper
->getSelection( PrivStart
, PrivEnd
);
1082 pMEdit
->SetSelection( Selection(PrivStart
, PrivEnd
));
1083 aMEFormula
.UpdateOldSel();
1086 FormEditData
* pData
= m_pHelper
->getFormEditData();
1087 pData
->SetFStart( nNextFStart
);
1088 pData
->SetOffset( 0 );
1089 pData
->SetEdFocus( 0 );
1093 // -----------------------------------------------------------------------------
1094 void FormulaDlg_Impl::EditThisFunc(xub_StrLen nFStart
)
1096 FormEditData
* pData
= m_pHelper
->getFormEditData();
1099 String aFormula
= m_pHelper
->getCurrentFormula();
1101 if(nFStart
==NOT_FOUND
)
1103 nFStart
= pData
->GetFStart();
1107 pData
->SetFStart(nFStart
);
1110 xub_StrLen nNextFStart
= nFStart
;
1111 xub_StrLen nNextFEnd
= 0;
1115 bFound
= m_aFormulaHelper
.GetNextFunc( aFormula
, sal_False
, nNextFStart
, &nNextFEnd
);
1118 xub_StrLen PrivStart
, PrivEnd
;
1119 SetData(nFStart
,nNextFStart
,nNextFEnd
,PrivStart
, PrivEnd
);
1120 m_pHelper
->showReference(aFormula
.Copy(PrivStart
, PrivEnd
-PrivStart
));
1128 void FormulaDlg_Impl::EditNextFunc( sal_Bool bForward
, xub_StrLen nFStart
)
1130 FormEditData
* pData
= m_pHelper
->getFormEditData();
1134 String aFormula
= m_pHelper
->getCurrentFormula();
1136 if(nFStart
==NOT_FOUND
)
1138 nFStart
= pData
->GetFStart();
1142 pData
->SetFStart(nFStart
);
1145 xub_StrLen nNextFStart
= 0;
1146 xub_StrLen nNextFEnd
= 0;
1151 nNextFStart
= m_aFormulaHelper
.GetArgStart( aFormula
, nFStart
, 0 );
1152 bFound
= m_aFormulaHelper
.GetNextFunc( aFormula
, sal_False
, nNextFStart
, &nNextFEnd
);
1156 nNextFStart
= nFStart
;
1157 bFound
= m_aFormulaHelper
.GetNextFunc( aFormula
, sal_True
, nNextFStart
, &nNextFEnd
);
1162 xub_StrLen PrivStart
, PrivEnd
;
1163 SetData(nFStart
,nNextFStart
,nNextFEnd
,PrivStart
, PrivEnd
);
1167 void FormulaDlg_Impl::SaveArg( sal_uInt16 nEd
)
1174 if ( m_aArguments
[i
].isEmpty() )
1175 m_aArguments
[i
] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" "));
1177 if(pParaWin
->GetArgument(nEd
).Len()!=0)
1178 m_aArguments
[nEd
] = pParaWin
->GetArgument(nEd
);
1180 sal_uInt16 nClearPos
=nEd
+1;
1181 for(i
=nEd
+1;i
<nArgs
;i
++)
1183 if(pParaWin
->GetArgument(i
).Len()!=0)
1189 for(i
=nClearPos
;i
<nArgs
;i
++)
1191 m_aArguments
[i
] = ::rtl::OUString();
1196 IMPL_LINK( FormulaDlg_Impl
, FxHdl
, ParaWin
*, pPtr
)
1200 aBtnForward
.Enable(sal_True
); //@ In order to be able to input another function.
1201 aTabCtrl
.SetCurPageId(TP_FUNCTION
);
1203 String aUndoStr
= m_pHelper
->getCurrentFormula(); // it will be added before a ";"
1204 FormEditData
* pData
= m_pHelper
->getFormEditData();
1205 if (!pData
) return 0;
1207 sal_uInt16 nArgNo
= pParaWin
->GetActiveLine();
1213 xub_StrLen nFormulaStrPos
= pData
->GetFStart();
1215 String aFormula
= m_pHelper
->getCurrentFormula();
1216 xub_StrLen n1
= m_aFormulaHelper
.GetArgStart( aFormula
, nFormulaStrPos
, nEdFocus
+pData
->GetOffset() );
1218 pData
->SetEdFocus( nEdFocus
);
1219 pData
->SaveValues();
1220 pData
->SetMode( (sal_uInt16
) FORMULA_FORMDLG_FORMULA
);
1221 pData
->SetFStart( n1
);
1222 pData
->SetUndoStr( aUndoStr
);
1225 FillDialog(sal_False
);
1226 pFuncPage
->SetFocus(); //There Parawin is not visible anymore
1231 IMPL_LINK( FormulaDlg_Impl
, ModifyHdl
, ParaWin
*, pPtr
)
1235 SaveArg(pParaWin
->GetActiveLine());
1239 CalcStruct(pMEdit
->GetText());
1244 IMPL_LINK_NOARG(FormulaDlg_Impl
, FormulaHdl
)
1247 FormEditData
* pData
= m_pHelper
->getFormEditData();
1248 if (!pData
) return 0;
1251 String aInputFormula
=m_pHelper
->getCurrentFormula();
1252 String aString
=pMEdit
->GetText();
1254 Selection aSel
=pMEdit
->GetSelection();
1257 if(aString
.Len()==0) //in case everything was cleared
1260 pMEdit
->SetText(aString
);
1263 pMEdit
->SetSelection(aSel
);
1265 else if(aString
.GetChar(nTest
)!='=') //in case it's replaced;
1267 aString
.Insert( (sal_Unicode
)'=', 0 );
1268 pMEdit
->SetText(aString
);
1271 pMEdit
->SetSelection(aSel
);
1275 m_pHelper
->setSelection(0, aInputFormula
.Len());
1276 m_pHelper
->setCurrentFormula(aString
);
1277 m_pHelper
->setSelection((xub_StrLen
)aSel
.Min(),(xub_StrLen
)aSel
.Max());
1279 xub_StrLen nPos
=(xub_StrLen
)aSel
.Min()-1;
1283 if ( CalcValue(m_pHelper
->getCurrentFormula(), aStrResult
) )
1284 aWndFormResult
.SetValue( aStrResult
);
1288 aWndFormResult
.SetValue( aStrResult
);
1290 CalcStruct(aString
);
1292 nPos
=GetFunctionPos(nPos
);
1294 if(nPos
<aSel
.Min()-1)
1296 xub_StrLen nPos1
=aString
.Search('(',nPos
);
1297 EditNextFunc( sal_False
, nPos1
);
1304 m_pHelper
->setSelection((xub_StrLen
)aSel
.Min(),(xub_StrLen
)aSel
.Max());
1305 bEditFlag
=sal_False
;
1309 IMPL_LINK_NOARG(FormulaDlg_Impl
, FormulaCursorHdl
)
1311 FormEditData
* pData
= m_pHelper
->getFormEditData();
1312 if (!pData
) return 0;
1313 xub_StrLen nFStart
= pData
->GetFStart();
1317 String aInputFormula
=m_pHelper
->getCurrentFormula();
1318 String aString
=pMEdit
->GetText();
1320 Selection aSel
=pMEdit
->GetSelection();
1321 m_pHelper
->setSelection((xub_StrLen
)aSel
.Min(),(xub_StrLen
)aSel
.Max());
1326 pMEdit
->SetSelection(aSel
);
1329 if(aSel
.Min()!=aString
.Len())
1331 xub_StrLen nPos
=(xub_StrLen
)aSel
.Min();
1333 nFStart
=GetFunctionPos(nPos
- 1);
1337 xub_StrLen nPos1
=m_aFormulaHelper
.GetFunctionEnd(aString
,nFStart
);
1339 if(nPos1
>nPos
|| nPos1
==STRING_NOTFOUND
)
1341 EditThisFunc(nFStart
);
1349 if(aString
.GetChar(n
)==')')
1351 else if(aString
.GetChar(n
)=='(')
1353 if(nCount
==0) break;
1358 nFStart
=m_aFormulaHelper
.GetFunctionStart(aString
,n
,sal_True
);
1359 EditThisFunc(nFStart
);
1372 m_pHelper
->setSelection((xub_StrLen
)aSel
.Min(),(xub_StrLen
)aSel
.Max());
1374 bEditFlag
=sal_False
;
1378 void FormulaDlg_Impl::UpdateSelection()
1380 m_pHelper
->setSelection((xub_StrLen
)aFuncSel
.Min(),(xub_StrLen
)aFuncSel
.Max());
1381 m_pHelper
->setCurrentFormula( pFuncDesc
->getFormula( m_aArguments
) );
1382 pMEdit
->SetText(m_pHelper
->getCurrentFormula());
1383 xub_StrLen PrivStart
, PrivEnd
;
1384 m_pHelper
->getSelection( PrivStart
, PrivEnd
);
1385 aFuncSel
.Min()=PrivStart
;
1386 aFuncSel
.Max()=PrivEnd
;
1388 nArgs
= pFuncDesc
->getSuppressedArgumentCount();
1390 String aFormula
=pMEdit
->GetText();
1391 sal_Int32 nArgPos
=m_aFormulaHelper
.GetArgStart( aFormula
,PrivStart
,0);
1393 sal_uInt16 nPos
=pParaWin
->GetActiveLine();
1395 for(sal_uInt16 i
=0;i
<nPos
;i
++)
1397 nArgPos
+= (m_aArguments
[i
].getLength() + 1);
1399 sal_Int32 nLength
= m_aArguments
[nPos
].getLength();
1401 Selection
aSel(nArgPos
,nArgPos
+nLength
);
1402 m_pHelper
->setSelection((sal_uInt16
)nArgPos
,(sal_uInt16
)(nArgPos
+nLength
));
1403 pMEdit
->SetSelection(aSel
);
1404 aMEFormula
.UpdateOldSel();
1406 ::std::pair
<RefButton
*,RefEdit
*> FormulaDlg_Impl::RefInputStartBefore( RefEdit
* pEdit
, RefButton
* pButton
)
1409 pTheRefEdit
= pEdit
;
1410 pTheRefButton
= pButton
;
1414 aEdRef
.SetRefString( pTheRefEdit
->GetText() );
1415 aEdRef
.SetSelection( pTheRefEdit
->GetSelection() );
1416 aEdRef
.SetHelpId( pTheRefEdit
->GetHelpId() );
1417 aEdRef
.SetUniqueId( pTheRefEdit
->GetUniqueId() );
1420 aRefBtn
.Show( pButton
!= NULL
);
1422 ::std::pair
<RefButton
*,RefEdit
*> aPair
;
1423 aPair
.first
= pButton
? &aRefBtn
: NULL
;
1424 aPair
.second
= &aEdRef
;
1427 void FormulaDlg_Impl::RefInputStartAfter( RefEdit
* /*pEdit*/, RefButton
* /*pButton*/ )
1429 aRefBtn
.SetEndImage();
1433 String aStr
= aTitle2
;
1435 aStr
+= aFtEditName
.GetText();
1436 aStr
.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "( " ) );
1437 if( pParaWin
->GetActiveLine() > 0 )
1438 aStr
.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "...; " ) );
1439 aStr
+= pParaWin
->GetActiveArgName();
1440 if( pParaWin
->GetActiveLine() + 1 < nArgs
)
1441 aStr
.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "; ..." ));
1442 aStr
.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " )" ) );
1444 m_pParent
->SetText( MnemonicGenerator::EraseAllMnemonicChars( aStr
) );
1447 void FormulaDlg_Impl::RefInputDoneAfter( sal_Bool bForced
)
1449 aRefBtn
.SetStartImage();
1450 if( bForced
|| !aRefBtn
.IsVisible() )
1456 pTheRefEdit
->SetRefString( aEdRef
.GetText() );
1457 pTheRefEdit
->GrabFocus();
1460 pTheRefButton
->SetStartImage();
1462 sal_uInt16 nPrivActiv
= pParaWin
->GetActiveLine();
1463 pParaWin
->SetArgument( nPrivActiv
, aEdRef
.GetText() );
1464 ModifyHdl( pParaWin
);
1467 m_pParent
->SetText( aTitle1
);
1470 RefEdit
* FormulaDlg_Impl::GetCurrRefEdit()
1472 return aEdRef
.IsVisible() ? &aEdRef
: pParaWin
->GetActiveEdit();
1474 void FormulaDlg_Impl::Update()
1476 FormEditData
* pData
= m_pHelper
->getFormEditData();
1477 const String sExpression
= pMEdit
->GetText();
1478 aOldFormula
= String();
1479 UpdateTokenArray(sExpression
);
1480 FormulaCursorHdl(&aMEFormula
);
1481 CalcStruct(sExpression
);
1482 if(pData
->GetMode() == FORMULA_FORMDLG_FORMULA
)
1483 aTabCtrl
.SetCurPageId(TP_FUNCTION
);
1485 aTabCtrl
.SetCurPageId(TP_STRUCT
);
1486 aBtnMatrix
.Check(pData
->GetMatrixFlag());
1488 void FormulaDlg_Impl::Update(const String
& _sExp
)
1494 void FormulaDlg_Impl::SetMeText(const String
& _sText
)
1496 FormEditData
* pData
= m_pHelper
->getFormEditData();
1497 pMEdit
->SetText(_sText
);
1498 pMEdit
->SetSelection( pData
->GetSelection());
1499 aMEFormula
.UpdateOldSel();
1501 FormulaDlgMode
FormulaDlg_Impl::SetMeText(const String
& _sText
,xub_StrLen PrivStart
, xub_StrLen PrivEnd
,sal_Bool bMatrix
,sal_Bool _bSelect
,sal_Bool _bUpdate
)
1503 FormulaDlgMode eMode
= FORMULA_FORMDLG_FORMULA
;
1505 pMEdit
->SetText(_sText
);
1507 if ( _bSelect
|| !bEditFlag
)
1508 pMEdit
->SetSelection( Selection(PrivStart
, PrivEnd
));
1511 aMEFormula
.UpdateOldSel();
1512 pMEdit
->Invalidate();
1513 m_pHelper
->showReference(pMEdit
->GetSelected());
1514 eMode
= FORMULA_FORMDLG_EDIT
;
1516 aBtnMatrix
.Check( bMatrix
);
1517 } // if ( _bUpdate )
1520 sal_Bool
FormulaDlg_Impl::CheckMatrix(String
& aFormula
)
1522 pMEdit
->GrabFocus();
1523 xub_StrLen nLen
= aFormula
.Len();
1524 sal_Bool bMatrix
= nLen
> 3 // Matrix-Formula
1525 && aFormula
.GetChar(0) == '{'
1526 && aFormula
.GetChar(1) == '='
1527 && aFormula
.GetChar(nLen
-1) == '}';
1530 aFormula
.Erase( 0, 1 );
1531 aFormula
.Erase( aFormula
.Len()-1, 1);
1532 aBtnMatrix
.Check( bMatrix
);
1533 aBtnMatrix
.Disable();
1536 aTabCtrl
.SetCurPageId(TP_STRUCT
);
1539 IMPL_LINK_NOARG(FormulaDlg_Impl
, StructSelHdl
)
1541 bStructUpdate
=sal_False
;
1542 if(pStructPage
->IsVisible()) aBtnForward
.Enable(sal_False
); //@New
1544 bStructUpdate
=sal_True
;
1547 IMPL_LINK_NOARG(FormulaDlg_Impl
, MatrixHdl
)
1549 bUserMatrixFlag
=sal_True
;
1553 IMPL_LINK_NOARG(FormulaDlg_Impl
, FuncSelHdl
)
1555 sal_uInt16 nCat
= pFuncPage
->GetCategory();
1556 if ( nCat
== LISTBOX_ENTRY_NOTFOUND
) nCat
= 0;
1557 sal_uInt16 nFunc
= pFuncPage
->GetFunction();
1558 if ( nFunc
== LISTBOX_ENTRY_NOTFOUND
) nFunc
= 0;
1560 if ( (pFuncPage
->GetFunctionEntryCount() > 0)
1561 && (pFuncPage
->GetFunction() != LISTBOX_ENTRY_NOTFOUND
) )
1563 const IFunctionDescription
* pDesc
=pFuncPage
->GetFuncDesc( pFuncPage
->GetFunction() );
1565 if(pDesc
!=pFuncDesc
) aBtnForward
.Enable(sal_True
); //new
1569 pDesc
->initArgumentInfo(); // full argument info is needed
1571 String aSig
= pDesc
->getSignature();
1572 aFtHeadLine
.SetText( pDesc
->getFunctionName() );
1573 aFtFuncName
.SetText( aSig
);
1574 aFtFuncDesc
.SetText( pDesc
->getDescription() );
1579 aFtHeadLine
.SetText( String() );
1580 aFtFuncName
.SetText( String() );
1581 aFtFuncDesc
.SetText( String() );
1586 void FormulaDlg_Impl::UpdateParaWin(const Selection
& _rSelection
,const String
& _sRefStr
)
1588 Selection theSel
= _rSelection
;
1589 aEdRef
.ReplaceSelected( _sRefStr
);
1590 theSel
.Max() = theSel
.Min() + _sRefStr
.Len();
1591 aEdRef
.SetSelection( theSel
);
1593 //-------------------------------------
1594 // Manual Update of the results' fields:
1595 //-------------------------------------
1596 sal_uInt16 nPrivActiv
= pParaWin
->GetActiveLine();
1597 pParaWin
->SetArgument(nPrivActiv
,aEdRef
.GetText());
1598 pParaWin
->UpdateParas();
1600 Edit
* pEd
= GetCurrRefEdit();
1602 pEd
->SetSelection( theSel
);
1604 pParaWin
->SetRefMode(sal_False
);
1606 sal_Bool
FormulaDlg_Impl::UpdateParaWin(Selection
& _rSelection
)
1608 pParaWin
->SetRefMode(sal_True
);
1611 Edit
* pEd
= GetCurrRefEdit();
1612 if(pEd
!=NULL
&& pTheRefEdit
==NULL
)
1614 _rSelection
=pEd
->GetSelection();
1615 _rSelection
.Justify();
1616 aStrEd
=pEd
->GetText();
1617 aEdRef
.SetRefString(aStrEd
);
1618 aEdRef
.SetSelection( _rSelection
);
1622 _rSelection
=aEdRef
.GetSelection();
1623 _rSelection
.Justify();
1624 aStrEd
= aEdRef
.GetText();
1626 return pTheRefEdit
== NULL
;
1629 void FormulaDlg_Impl::SetEdSelection()
1631 Edit
* pEd
= GetCurrRefEdit()/*aScParaWin.GetActiveEdit()*/;
1634 Selection theSel
= aEdRef
.GetSelection();
1635 // Edit may have the focus -> call ModifyHdl in addition
1636 // to what's happening in GetFocus
1637 pEd
->GetModifyHdl().Call(pEd
);
1639 pEd
->SetSelection(theSel
);
1642 // -----------------------------------------------------------------------------
1643 const FormulaHelper
& FormulaDlg_Impl::GetFormulaHelper() const
1645 return m_aFormulaHelper
;
1647 //============================================================================
1648 FormulaModalDialog::FormulaModalDialog( Window
* pParent
1649 , bool _bSupportFunctionResult
1650 , bool _bSupportResult
1651 , bool _bSupportMatrix
1652 , IFunctionManager
* _pFunctionMgr
1653 , IControlReferenceHandler
* _pDlg
) :
1654 ModalDialog( pParent
, ModuleRes(RID_FORMULADLG_FORMULA_MODAL
) ),
1655 m_pImpl( new FormulaDlg_Impl(this,_bSupportFunctionResult
1658 ,this,_pFunctionMgr
,_pDlg
))
1661 SetText(m_pImpl
->aTitle1
);
1663 FormulaModalDialog::~FormulaModalDialog()
1666 // -----------------------------------------------------------------------------
1667 void FormulaModalDialog::Update(const String
& _sExp
)
1669 m_pImpl
->Update(_sExp
);
1672 // -----------------------------------------------------------------------------
1673 void FormulaModalDialog::SetMeText(const String
& _sText
)
1675 m_pImpl
->SetMeText(_sText
);
1678 // -----------------------------------------------------------------------------
1679 sal_Bool
FormulaModalDialog::CheckMatrix(String
& aFormula
)
1681 return m_pImpl
->CheckMatrix(aFormula
);
1683 // -----------------------------------------------------------------------------
1684 void FormulaModalDialog::Update()
1688 ::std::pair
<RefButton
*,RefEdit
*> FormulaModalDialog::RefInputStartBefore( RefEdit
* pEdit
, RefButton
* pButton
)
1690 return m_pImpl
->RefInputStartBefore( pEdit
, pButton
);
1692 void FormulaModalDialog::RefInputStartAfter( RefEdit
* pEdit
, RefButton
* pButton
)
1694 m_pImpl
->RefInputStartAfter( pEdit
, pButton
);
1696 void FormulaModalDialog::RefInputDoneAfter( sal_Bool bForced
)
1698 m_pImpl
->RefInputDoneAfter( bForced
);
1701 void FormulaModalDialog::SetFocusWin(Window
*pWin
,const rtl::OString
& nUniqueId
)
1703 if(pWin
->GetUniqueId()==nUniqueId
)
1709 sal_uInt16 nCount
=pWin
->GetChildCount();
1711 for(sal_uInt16 i
=0;i
<nCount
;i
++)
1713 Window
* pChild
=pWin
->GetChild(i
);
1714 SetFocusWin(pChild
,nUniqueId
);
1719 long FormulaModalDialog::PreNotify( NotifyEvent
& rNEvt
)
1721 m_pImpl
->PreNotify( rNEvt
);
1723 return ModalDialog::PreNotify(rNEvt
);
1726 void FormulaModalDialog::StoreFormEditData(FormEditData
* pData
)
1728 m_pImpl
->StoreFormEditData(pData
);
1731 // --------------------------------------------------------------------------
1732 // Initialisation / General functions for Dialog
1733 // --------------------------------------------------------------------------
1734 FormulaDlg::FormulaDlg( SfxBindings
* pB
, SfxChildWindow
* pCW
,
1736 , bool _bSupportFunctionResult
1737 , bool _bSupportResult
1738 , bool _bSupportMatrix
1739 , IFunctionManager
* _pFunctionMgr
, IControlReferenceHandler
* _pDlg
) :
1740 SfxModelessDialog( pB
, pCW
, pParent
, ModuleRes(RID_FORMULADLG_FORMULA
) ),
1741 m_pImpl( new FormulaDlg_Impl(this, _bSupportFunctionResult
1744 , this, _pFunctionMgr
, _pDlg
))
1747 if(GetHelpId().isEmpty()) //Hack which hides the HelpId for a model Dialog in SfxModelessDialog
1748 SetHelpId(GetUniqueId()); //and will be changed in a UniqueId,
1749 //at this point we reverse it.
1750 SetText(m_pImpl
->aTitle1
);
1753 FormulaDlg::~FormulaDlg()
1756 // -----------------------------------------------------------------------------
1757 void FormulaDlg::Update(const String
& _sExp
)
1759 m_pImpl
->Update(_sExp
);
1762 // -----------------------------------------------------------------------------
1763 void FormulaDlg::SetMeText(const String
& _sText
)
1765 m_pImpl
->SetMeText(_sText
);
1768 // -----------------------------------------------------------------------------
1769 FormulaDlgMode
FormulaDlg::SetMeText(const String
& _sText
,xub_StrLen PrivStart
, xub_StrLen PrivEnd
,sal_Bool bMatrix
,sal_Bool _bSelect
,sal_Bool _bUpdate
)
1771 return m_pImpl
->SetMeText(_sText
,PrivStart
, PrivEnd
,bMatrix
,_bSelect
,_bUpdate
);
1773 // -----------------------------------------------------------------------------
1774 void FormulaDlg::CheckMatrix()
1776 m_pImpl
->aBtnMatrix
.Check();
1778 // -----------------------------------------------------------------------------
1779 sal_Bool
FormulaDlg::CheckMatrix(String
& aFormula
)
1781 return m_pImpl
->CheckMatrix(aFormula
);
1783 // -----------------------------------------------------------------------------
1784 String
FormulaDlg::GetMeText() const
1786 return m_pImpl
->pMEdit
->GetText();
1788 // -----------------------------------------------------------------------------
1789 void FormulaDlg::Update()
1792 m_pImpl
->aTimer
.SetTimeout(200);
1793 m_pImpl
->aTimer
.SetTimeoutHdl(LINK( this, FormulaDlg
, UpdateFocusHdl
));
1794 m_pImpl
->aTimer
.Start();
1797 // -----------------------------------------------------------------------------
1798 sal_Bool
FormulaDlg::isUserMatrix() const
1800 return m_pImpl
->bUserMatrixFlag
;
1802 void FormulaDlg::DoEnter(sal_Bool _bOk
)
1804 m_pImpl
->DoEnter(_bOk
);
1806 ::std::pair
<RefButton
*,RefEdit
*> FormulaDlg::RefInputStartBefore( RefEdit
* pEdit
, RefButton
* pButton
)
1808 return m_pImpl
->RefInputStartBefore( pEdit
, pButton
);
1810 void FormulaDlg::RefInputStartAfter( RefEdit
* pEdit
, RefButton
* pButton
)
1812 m_pImpl
->RefInputStartAfter( pEdit
, pButton
);
1814 void FormulaDlg::RefInputDoneAfter( sal_Bool bForced
)
1816 m_pImpl
->RefInputDoneAfter( bForced
);
1819 void FormulaDlg::SetFocusWin(Window
*pWin
,const rtl::OString
& nUniqueId
)
1821 if(pWin
->GetUniqueId()==nUniqueId
)
1827 sal_uInt16 nCount
=pWin
->GetChildCount();
1829 for(sal_uInt16 i
=0;i
<nCount
;i
++)
1831 Window
* pChild
=pWin
->GetChild(i
);
1832 SetFocusWin(pChild
,nUniqueId
);
1838 long FormulaDlg::PreNotify( NotifyEvent
& rNEvt
)
1840 m_pImpl
->PreNotify( rNEvt
);
1841 return SfxModelessDialog::PreNotify(rNEvt
);
1844 void FormulaDlg::disableOk()
1846 m_pImpl
->aBtnEnd
.Disable();
1849 void FormulaDlg::StoreFormEditData(FormEditData
* pData
)
1851 m_pImpl
->StoreFormEditData(pData
);
1854 // -----------------------------------------------------------------------------
1855 const IFunctionDescription
* FormulaDlg::getCurrentFunctionDescription() const
1857 OSL_VERIFY(!m_pImpl
->pFuncDesc
|| m_pImpl
->pFuncDesc
->getSuppressedArgumentCount() == m_pImpl
->nArgs
);
1858 return m_pImpl
->pFuncDesc
;
1860 // -----------------------------------------------------------------------------
1861 void FormulaDlg::UpdateParaWin(const Selection
& _rSelection
,const String
& _sRefStr
)
1863 m_pImpl
->UpdateParaWin(_rSelection
,_sRefStr
);
1865 sal_Bool
FormulaDlg::UpdateParaWin(Selection
& _rSelection
)
1867 return m_pImpl
->UpdateParaWin(_rSelection
);
1869 // -----------------------------------------------------------------------------
1870 RefEdit
* FormulaDlg::GetActiveEdit()
1872 return m_pImpl
->pParaWin
->GetActiveEdit();
1874 // -----------------------------------------------------------------------------
1875 const FormulaHelper
& FormulaDlg::GetFormulaHelper() const
1877 return m_pImpl
->GetFormulaHelper();
1879 // -----------------------------------------------------------------------------
1880 void FormulaDlg::SetEdSelection()
1882 m_pImpl
->SetEdSelection();
1884 IMPL_LINK_NOARG(FormulaDlg
, UpdateFocusHdl
)
1886 FormEditData
* pData
= m_pImpl
->m_pHelper
->getFormEditData();
1888 if (pData
) // won't be destroyed over Close;
1890 m_pImpl
->m_pHelper
->setReferenceInput(pData
);
1891 rtl::OString
nUniqueId(pData
->GetUniqueId());
1892 SetFocusWin(this,nUniqueId
);
1897 // -----------------------------------------------------------------------------
1898 void FormEditData::SaveValues()
1900 FormEditData
* pTemp
= new FormEditData(*this);
1905 // -----------------------------------------------------------------------------
1906 void FormEditData::Reset()
1911 nCatSel
= 1; //! oder 0 (zuletzt benutzte)
1916 aUniqueId
=rtl::OString();
1921 // -----------------------------------------------------------------------------
1922 const FormEditData
& FormEditData::operator=( const FormEditData
& r
)
1924 pParent
= r
.pParent
;
1926 nFStart
= r
.nFStart
;
1927 nCatSel
= r
.nCatSel
;
1928 nFuncSel
= r
.nFuncSel
;
1929 nOffset
= r
.nOffset
;
1930 nEdFocus
= r
.nEdFocus
;
1931 aUndoStr
= r
.aUndoStr
;
1932 bMatrix
= r
.bMatrix
;
1933 aUniqueId
= r
.aUniqueId
;
1934 aSelection
= r
.aSelection
;
1937 // -----------------------------------------------------------------------------
1938 FormEditData::FormEditData()
1943 FormEditData::~FormEditData()
1948 FormEditData::FormEditData( const FormEditData
& r
)
1953 // -----------------------------------------------------------------------------
1955 // -----------------------------------------------------------------------------
1957 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */