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