LibreOffice Module formula (master) 1
formula.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <memory>
21#include <sfx2/viewfrm.hxx>
22#include <vcl/svapp.hxx>
23#include <vcl/weld.hxx>
24
25#include <sal/log.hxx>
26
29
30#include "funcpage.hxx"
31#include <formula/formula.hxx>
34#include <formula/token.hxx>
36#include <formula/formdata.hxx>
38#include "structpg.hxx"
39#include "parawin.hxx"
40#include <strings.hrc>
41#include <core_resource.hxx>
42#include <com/sun/star/sheet/FormulaToken.hpp>
43#include <com/sun/star/sheet/FormulaLanguage.hpp>
44#include <com/sun/star/sheet/FormulaMapGroup.hpp>
45#include <com/sun/star/sheet/FormulaMapGroupSpecialOffset.hpp>
46#include <com/sun/star/sheet/XFormulaOpCodeMapper.hpp>
47#include <com/sun/star/sheet/XFormulaParser.hpp>
48#include <map>
49
50// For tab page
51#define TOKEN_OPEN 0
52#define TOKEN_CLOSE 1
53namespace formula
54{
55
56using namespace ::com::sun::star;
57
59{
60public:
61 ::std::pair<RefButton*, RefEdit*>
62 RefInputStartBefore( RefEdit* pEdit, RefButton* pButton );
63 void RefInputStartAfter();
64 void RefInputDoneAfter( bool bForced );
65 bool CalcValue( const OUString& rStrExp, OUString& rStrResult, bool bForceMatrixFormula = false );
66 void CalcStruct( const OUString& rStrExp, bool bForceRecalcStruct = false );
67 void UpdateValues( bool bForceRecalcStruct = false );
68 void DeleteArgs();
69 sal_Int32 GetFunctionPos(sal_Int32 nPos);
70 void ClearAllParas();
71
72 void MakeTree(StructPage* _pTree, weld::TreeIter* pParent, const FormulaToken* pFuncToken,
73 const FormulaToken* _pToken, tools::Long Count);
74 void fillTree(StructPage* _pTree);
75 void UpdateTokenArray( const OUString& rStrExp);
76 OUString RepairFormula(const OUString& aFormula);
77 void FillDialog(bool bFlag = true);
78 bool EditNextFunc( bool bForward, sal_Int32 nFStart = NOT_FOUND );
79 void EditThisFunc(sal_Int32 nFStart);
80
81 OUString GetPrevFuncExpression( bool bStartFromEnd );
82
83 void StoreFormEditData(FormEditData* pEditData);
84
85 void Update();
86 void Update(const OUString& _sExp);
87
88 void SaveArg( sal_uInt16 nEd );
89 void UpdateSelection();
90 void DoEnter( bool bOk );
91 void FillListboxes();
92 void FillControls( bool &rbNext, bool &rbPrev);
93
94 FormulaDlgMode SetMeText( const OUString& _sText, sal_Int32 PrivStart, sal_Int32 PrivEnd, bool bMatrix, bool _bSelect, bool _bUpdate);
95 void SetMeText(const OUString& _sText);
96 bool CheckMatrix(OUString& aFormula /*IN/OUT*/);
97
98 void SetEdSelection();
99
100 bool UpdateParaWin(Selection& _rSelection);
101 void UpdateParaWin( const Selection& _rSelection, const OUString& _sRefStr);
102
103 void SetData( sal_Int32 nFStart, sal_Int32 nNextFStart, sal_Int32 nNextFEnd, sal_Int32& PrivStart, sal_Int32& PrivEnd);
104
106
109
110 void UpdateOldSel();
111 void FormulaCursor();
112
113 DECL_LINK( ModifyHdl, ParaWin&, void );
114 DECL_LINK( FxHdl, ParaWin&, void );
115
116 DECL_LINK( MatrixHdl, weld::Toggleable&, void );
117 DECL_LINK( FormulaHdl, weld::TextView&, void);
118 DECL_LINK( FormulaCursorHdl, weld::TextView&, void );
119 DECL_LINK( BtnHdl, weld::Button&, void );
120 DECL_LINK( DblClkHdl, FuncPage&, void );
121 DECL_LINK( FuncSelHdl, FuncPage&, void );
122 DECL_LINK( StructSelHdl, StructPage&, void );
123public:
126 ::std::unique_ptr<FormulaTokenArray> m_pTokenArray;
127 ::std::optional<FormulaTokenArrayPlainIterator> m_oTokenArrayIterator;
131 mutable const sheet::FormulaOpCodeMapEntry* m_pFunctionOpCodesEnd;
132 ::std::map<const FormulaToken*, sheet::FormulaToken> m_aTokenMap;
135
139
140 const OUString m_aTitle1;
141 const OUString m_aTitle2;
143
145
146 OUString m_aOldHelp;
147 bool m_bMakingTree; // in method of constructing tree
148
151 sal_Int32 m_nArgs;
152 ::std::vector< OUString > m_aArguments;
154
155 sal_Int32 m_nFuncExpStart;
156
159
162
163 std::unique_ptr<weld::Notebook> m_xTabCtrl;
164 std::unique_ptr<weld::Container> m_xParaWinBox;
165 std::unique_ptr<ParaWin> m_xParaWin;
166 std::unique_ptr<weld::Label> m_xFtHeadLine;
167 std::unique_ptr<weld::Label> m_xFtFuncName;
168 std::unique_ptr<weld::Label> m_xFtFuncDesc;
169
170 std::unique_ptr<weld::Label> m_xFtEditName;
171
172 std::unique_ptr<weld::Label> m_xFtResult;
173 std::unique_ptr<weld::Entry> m_xWndResult;
174
175 std::unique_ptr<weld::Label> m_xFtFormula;
176 std::unique_ptr<weld::TextView> m_xMEdit;
177
178 std::unique_ptr<weld::CheckButton> m_xBtnMatrix;
179 std::unique_ptr<weld::Button> m_xBtnCancel;
180
181 std::unique_ptr<weld::Button> m_xBtnBackward;
182 std::unique_ptr<weld::Button> m_xBtnForward;
183 std::unique_ptr<weld::Button> m_xBtnEnd;
184
185 std::unique_ptr<weld::Label> m_xFtFormResult;
186 std::unique_ptr<weld::Entry> m_xWndFormResult;
187
188 std::unique_ptr<RefEdit> m_xEdRef;
189 std::unique_ptr<RefButton> m_xRefBtn;
190
191 std::unique_ptr<FuncPage> m_xFuncPage;
192 std::unique_ptr<StructPage> m_xStructPage;
193
195 weld::Builder& rBuilder,
196 bool _bSupportFunctionResult,
197 bool _bSupportResult,
198 bool _bSupportMatrix,
199 IFormulaEditorHelper* _pHelper,
200 const IFunctionManager* _pFunctionMgr,
203};
204
206 weld::Builder& rBuilder,
207 bool _bSupportFunctionResult,
208 bool _bSupportResult,
209 bool _bSupportMatrix,
210 IFormulaEditorHelper* _pHelper,
211 const IFunctionManager* _pFunctionMgr,
213 : m_pFunctionOpCodesEnd(nullptr)
214 , m_pHelper(_pHelper)
215 , m_rDialog(rDialog)
216 , m_bUserMatrixFlag(false)
217 , m_aTitle1( ForResId( STR_TITLE1 ) )
218 , m_aTitle2( ForResId( STR_TITLE2 ) )
219 , m_aFormulaHelper(_pFunctionMgr)
220 , m_bMakingTree(false)
221 , m_pFuncDesc(nullptr)
222 , m_nArgs(0)
223 , m_nFuncExpStart(0)
224 , m_nSelectionStart(-1)
225 , m_nSelectionEnd(-1)
226 , m_pTheRefEdit(nullptr)
227 , m_pTheRefButton(nullptr)
228 , m_xTabCtrl(rBuilder.weld_notebook("tabcontrol"))
229 , m_xParaWinBox(rBuilder.weld_container("BOX"))
230 , m_xFtHeadLine(rBuilder.weld_label("headline"))
231 , m_xFtFuncName(rBuilder.weld_label("funcname"))
232 , m_xFtFuncDesc(rBuilder.weld_label("funcdesc"))
233 , m_xFtEditName(rBuilder.weld_label("editname"))
234 , m_xFtResult(rBuilder.weld_label("label2"))
235 , m_xWndResult(rBuilder.weld_entry("result"))
236 , m_xFtFormula(rBuilder.weld_label("formula"))
237 , m_xMEdit(rBuilder.weld_text_view("ed_formula"))
238 , m_xBtnMatrix(rBuilder.weld_check_button("array"))
239 , m_xBtnCancel(rBuilder.weld_button("cancel"))
240 , m_xBtnBackward(rBuilder.weld_button("back"))
241 , m_xBtnForward(rBuilder.weld_button("next"))
242 , m_xBtnEnd(rBuilder.weld_button("ok"))
243 , m_xFtFormResult(rBuilder.weld_label("label1"))
244 , m_xWndFormResult(rBuilder.weld_entry("formula_result"))
245 , m_xEdRef(new RefEdit(rBuilder.weld_entry("ED_REF")))
246 , m_xRefBtn(new RefButton(rBuilder.weld_button("RB_REF")))
247{
248 auto nWidth = m_xMEdit->get_approximate_digit_width() * 62;
249
250 //Space for two lines of text
251 m_xFtHeadLine->set_label("X\nX\n");
252 auto nHeight = m_xFtHeadLine->get_preferred_size().Height();
253 m_xFtHeadLine->set_size_request(nWidth, nHeight);
254 m_xFtHeadLine->set_label("");
255
256 m_xFtFuncName->set_label("X\nX\n");
257 nHeight = m_xFtFuncName->get_preferred_size().Height();
258 m_xFtFuncName->set_size_request(nWidth, nHeight);
259 m_xFtFuncDesc->set_size_request(nWidth, nHeight);
260 m_xFtFuncName->set_label("");
261
262 m_xMEdit->set_size_request(nWidth,
263 m_xMEdit->get_height_rows(5));
264
265 m_xEdRef->SetReferences(_pDlg, m_xFtEditName.get());
266 m_xRefBtn->SetReferences(_pDlg, m_xEdRef.get());
267
268 m_xParaWin.reset(new ParaWin(m_xParaWinBox.get(), _pDlg));
269 m_xParaWin->Show();
270 m_xParaWinBox->hide();
271 m_xFtEditName->hide();
272 m_xEdRef->GetWidget()->hide();
273 m_xRefBtn->GetWidget()->hide();
274
275 m_xMEdit->set_accessible_name(m_xFtFormula->get_label());
276
277 m_aEditHelpId = m_xMEdit->get_help_id();
278
279 m_bEditFlag =false;
280 m_bStructUpdate =true;
281 m_xParaWin->SetArgModifiedHdl( LINK( this, FormulaDlg_Impl, ModifyHdl ) );
282 m_xParaWin->SetFxHdl( LINK( this, FormulaDlg_Impl, FxHdl ) );
283
284 m_xFuncPage.reset(new FuncPage(m_xTabCtrl->get_page("functiontab"), _pFunctionMgr));
285 m_xStructPage.reset(new StructPage(m_xTabCtrl->get_page("structtab")));
286 m_xTabCtrl->set_current_page("functiontab");
287
288 m_aOldHelp = m_rDialog.get_help_id(); // HelpId from resource always for "Page 1"
289
290 m_xFtResult->set_visible( _bSupportResult );
291 m_xWndResult->set_visible( _bSupportResult );
292
293 m_xFtFormResult->set_visible( _bSupportFunctionResult );
294 m_xWndFormResult->set_visible( _bSupportFunctionResult );
295
296 if ( _bSupportMatrix )
297 m_xBtnMatrix->connect_toggled( LINK( this, FormulaDlg_Impl, MatrixHdl ) );
298 else
299 m_xBtnMatrix->hide();
300
301 m_xBtnCancel->connect_clicked( LINK( this, FormulaDlg_Impl, BtnHdl ) );
302 m_xBtnEnd->connect_clicked( LINK( this, FormulaDlg_Impl, BtnHdl ) );
303 m_xBtnForward->connect_clicked( LINK( this, FormulaDlg_Impl, BtnHdl ) );
304 m_xBtnBackward->connect_clicked( LINK( this, FormulaDlg_Impl, BtnHdl ) );
305
306 m_xFuncPage->SetDoubleClickHdl( LINK( this, FormulaDlg_Impl, DblClkHdl ) );
307 m_xFuncPage->SetSelectHdl( LINK( this, FormulaDlg_Impl, FuncSelHdl) );
308 m_xStructPage->SetSelectionHdl( LINK( this, FormulaDlg_Impl, StructSelHdl ) );
309 m_xMEdit->connect_changed( LINK( this, FormulaDlg_Impl, FormulaHdl ) );
310 m_xMEdit->connect_cursor_position( LINK( this, FormulaDlg_Impl, FormulaCursorHdl ) );
311
312 vcl::Font aFntLight = m_xFtFormula->get_font();
313 vcl::Font aFntBold = aFntLight;
314 aFntBold.SetWeight( WEIGHT_BOLD );
315
316 m_xParaWin->SetArgumentFonts( aFntBold, aFntLight);
317}
318
320{
321 m_xTabCtrl->remove_page("functiontab");
322 m_xTabCtrl->remove_page("structtab");
323
324 DeleteArgs();
325}
326
328{
329 if (!pData) // it won't be destroyed via Close
330 return;
331
332 int nStartPos, nEndPos;
333 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
334 if (nStartPos > nEndPos)
335 std::swap(nStartPos, nEndPos);
336
337 pData->SetFStart(nStartPos);
338 pData->SetSelection(Selection(nStartPos, nEndPos));
339
340 if (m_xTabCtrl->get_current_page_ident() == "functiontab")
341 pData->SetMode( FormulaDlgMode::Formula );
342 else
343 pData->SetMode( FormulaDlgMode::Edit );
344 pData->SetUndoStr(m_xMEdit->get_text());
345 pData->SetMatrixFlag(m_xBtnMatrix->get_active());
346}
347
349{
350 if ( m_xOpCodeMapper.is() )
351 return;
352
354 m_aFunctionOpCodes = m_xOpCodeMapper->getAvailableMappings( sheet::FormulaLanguage::ODFF, sheet::FormulaMapGroup::FUNCTIONS);
355 m_pFunctionOpCodesEnd = m_aFunctionOpCodes.getConstArray() + m_aFunctionOpCodes.getLength();
356
357 // 0:TOKEN_OPEN, 1:TOKEN_CLOSE, 2:TOKEN_SEP
358 uno::Sequence< OUString > aArgs { "(", ")", ";" };
359 m_aSeparatorsOpCodes = m_xOpCodeMapper->getMappings( aArgs, sheet::FormulaLanguage::ODFF);
360
361 m_aSpecialOpCodes = m_xOpCodeMapper->getAvailableMappings( sheet::FormulaLanguage::ODFF, sheet::FormulaMapGroup::SPECIAL);
362}
363
365{
366 ::std::vector< OUString>().swap(m_aArguments);
367 m_nArgs = 0;
368}
369
370sal_Int32 FormulaDlg_Impl::GetFunctionPos(sal_Int32 nPos)
371{
372 if ( !m_aTokenList.hasElements() )
373 return SAL_MAX_INT32;
374
376
377 sal_Int32 nFuncPos = SAL_MAX_INT32;
378 OUString aFormString = m_aFormulaHelper.GetCharClass().uppercase(m_xMEdit->get_text());
379
381 const table::CellAddress aRefPos(m_pHelper->getReferencePosition());
382
383 const sheet::FormulaToken* pIter = m_aTokenList.getConstArray();
384 const sheet::FormulaToken* pEnd = pIter + m_aTokenList.getLength();
385 try
386 {
387 bool bFlag = false;
388 sal_Int32 nTokPos = 1;
389 sal_Int32 nOldTokPos = 1;
390 sal_Int32 nPrevFuncPos = 1;
391 short nBracketCount = 0;
392 const sal_Int32 nOpPush = m_aSpecialOpCodes[sheet::FormulaMapGroupSpecialOffset::PUSH].Token.OpCode;
393 const sal_Int32 nOpSpaces = m_aSpecialOpCodes[sheet::FormulaMapGroupSpecialOffset::SPACES].Token.OpCode;
394 const sal_Int32 nOpWhitespace = m_aSpecialOpCodes[sheet::FormulaMapGroupSpecialOffset::WHITESPACE].Token.OpCode;
395 while ( pIter != pEnd )
396 {
397 const sal_Int32 eOp = pIter->OpCode;
398 uno::Sequence<sheet::FormulaToken> aArgs { *pIter };
399 const OUString aString = xParser->printFormula( aArgs, aRefPos);
400 const sheet::FormulaToken* pNextToken = pIter + 1;
401
403 {
404 m_xBtnMatrix->set_active(true);
405 }
406
407 if (eOp == nOpPush || eOp == nOpSpaces || eOp == nOpWhitespace)
408 {
409 const sal_Int32 n1 = nTokPos < 0 ? -1 : aFormString.indexOf( sep, nTokPos);
410 const sal_Int32 n2 = nTokPos < 0 ? -1 : aFormString.indexOf( ')', nTokPos);
411 sal_Int32 nXXX = nTokPos;
412 if ( n1 < n2 && n1 != -1 )
413 {
414 nTokPos = n1;
415 }
416 else
417 {
418 nTokPos = n2;
419 }
420 if ( pNextToken != pEnd )
421 {
422 aArgs.getArray()[0] = *pNextToken;
423 const OUString a2String = xParser->printFormula( aArgs, aRefPos);
424 const sal_Int32 n3 = nXXX < 0 ? -1 : aFormString.indexOf( a2String, nXXX);
425 if (n3 < nTokPos && n3 != -1)
426 nTokPos = n3;
427 }
428 }
429 else
430 {
431 nTokPos = nTokPos + aString.getLength();
432 }
433
435 {
436 nBracketCount++;
437 bFlag = true;
438 }
439 else if ( eOp == m_aSeparatorsOpCodes[TOKEN_CLOSE].OpCode )
440 {
441 nBracketCount--;
442 bFlag = false;
443 nFuncPos = nPrevFuncPos;
444 }
445 bool bIsFunction = std::any_of( m_aFunctionOpCodes.getConstArray(),
447 [&eOp](const sheet::FormulaOpCodeMapEntry& aEntry) { return aEntry.Token.OpCode == eOp; });
448
449 if ( bIsFunction && nOpSpaces != eOp && nOpWhitespace != eOp )
450 {
451 nPrevFuncPos = nFuncPos;
452 nFuncPos = nOldTokPos;
453 }
454
455 if ( nOldTokPos <= nPos && nPos < nTokPos )
456 {
457 if ( !bIsFunction )
458 {
459 if ( nBracketCount < 1 )
460 {
461 nFuncPos = m_xMEdit->get_text().getLength();
462 }
463 else if ( !bFlag )
464 {
465 nFuncPos = nPrevFuncPos;
466 }
467 }
468 break;
469 }
470
471 pIter = pNextToken;
472 nOldTokPos = nTokPos;
473 } // while ( pIter != pEnd )
474 }
475 catch ( const uno::Exception& )
476 {
477 TOOLS_WARN_EXCEPTION("formula.ui", "FormulaDlg_Impl::GetFunctionPos");
478 }
479
480 return nFuncPos;
481}
482
483bool FormulaDlg_Impl::CalcValue( const OUString& rStrExp, OUString& rStrResult, bool bForceMatrixFormula )
484{
485 bool bResult = true;
486
487 if ( !rStrExp.isEmpty() )
488 {
489 // Only calculate the value when there isn't any more keyboard input:
490
491 // Make this debuggable by assigning to a variable that can be changed
492 // from within the debugger.
493 bool bInput = Application::AnyInput( VclInputFlags::KEYBOARD );
494 if ( !bInput )
495 {
496 bResult = m_pHelper->calculateValue( rStrExp, rStrResult, bForceMatrixFormula || m_xBtnMatrix->get_active());
497 }
498 else
499 bResult = false;
500 }
501
502 return bResult;
503}
504
505void FormulaDlg_Impl::UpdateValues( bool bForceRecalcStruct )
506{
507 // Take a force-array context into account. RPN creation propagated those
508 // to tokens that are ref-counted so also available in the token array.
509 bool bForceArray = false;
510 // Only necessary if it's not a matrix formula anyway and matrix evaluation
511 // is supported, i.e. the button is visible.
512 if (m_xBtnMatrix->get_visible() && !m_xBtnMatrix->get_active())
513 {
514 std::unique_ptr<FormulaCompiler> pCompiler(m_pHelper->createCompiler(*m_pTokenArray));
515 // In the case of the reportdesign dialog there is no currently active
516 // OpCode symbol mapping that could be used to create strings from
517 // tokens, it's all dreaded API mapping. However, in that case there's
518 // no array/matrix support anyway, but ensure checking.
519 if (pCompiler->GetCurrentOpCodeMap())
520 {
521 const sal_Int32 nPos = m_aFuncSel.Min();
522 assert( 0 <= nPos && nPos < m_pHelper->getCurrentFormula().getLength());
523 OUStringBuffer aBuf;
524 const FormulaToken* pToken = nullptr;
525 for (pToken = m_oTokenArrayIterator->First(); pToken; pToken = m_oTokenArrayIterator->Next())
526 {
527 pCompiler->CreateStringFromToken( aBuf, pToken);
528 if (nPos < aBuf.getLength())
529 break;
530 }
531 if (pToken && nPos < aBuf.getLength())
532 bForceArray = pToken->IsInForceArray();
533 }
534 }
535
536 OUString aStrResult;
537 if (m_pFuncDesc && CalcValue( m_pFuncDesc->getFormula( m_aArguments), aStrResult, bForceArray))
538 m_xWndResult->set_text( aStrResult );
539
540 if (m_bMakingTree)
541 return;
542
543 aStrResult.clear();
544 if ( CalcValue( m_pHelper->getCurrentFormula(), aStrResult ) )
545 m_xWndFormResult->set_text( aStrResult );
546 else
547 {
548 aStrResult.clear();
549 m_xWndFormResult->set_text( aStrResult );
550 }
551 CalcStruct( m_xMEdit->get_text(), bForceRecalcStruct);
552}
553
554void FormulaDlg_Impl::CalcStruct( const OUString& rStrExp, bool bForceRecalcStruct )
555{
556 sal_Int32 nLength = rStrExp.getLength();
557
558 if ( !(!rStrExp.isEmpty() && (bForceRecalcStruct || m_aOldFormula != rStrExp) && m_bStructUpdate))
559 return;
560
561 m_xStructPage->ClearStruct();
562
563 OUString aString = rStrExp;
564 if (rStrExp[nLength-1] == '(')
565 {
566 aString = aString.copy( 0, nLength-1);
567 }
568
569 aString = aString.replaceAll( "\n", "");
570 OUString aStrResult;
571
572 if ( CalcValue( aString, aStrResult ) )
573 m_xWndFormResult->set_text(aStrResult);
574
575 UpdateTokenArray(aString);
576 fillTree(m_xStructPage.get());
577
578 m_aOldFormula = rStrExp;
579 if (rStrExp[nLength-1] == '(')
580 UpdateTokenArray(rStrExp);
581}
582
583void FormulaDlg_Impl::MakeTree(StructPage* _pTree, weld::TreeIter* pParent, const FormulaToken* pFuncToken,
584 const FormulaToken* _pToken, tools::Long Count)
585{
586 if ( _pToken == nullptr || Count <= 0 )
587 return;
588
589 tools::Long nParas = _pToken->GetParamCount();
590 OpCode eOp = _pToken->GetOpCode();
591
592 // #i101512# for output, the original token is needed
593 const FormulaToken* pOrigToken = (_pToken->GetType() == svFAP) ? _pToken->GetFAPOrigToken() : _pToken;
594 ::std::map<const FormulaToken*, sheet::FormulaToken>::const_iterator itr = m_aTokenMap.find(pOrigToken);
595 if (itr == m_aTokenMap.end())
596 return;
597
598 uno::Sequence<sheet::FormulaToken> aArgs { itr->second };
599 try
600 {
601 const table::CellAddress aRefPos(m_pHelper->getReferencePosition());
602 const OUString aResult = m_pHelper->getFormulaParser()->printFormula( aArgs, aRefPos);
603
604 if ( nParas > 0 || (nParas == 0 && _pToken->IsFunction()) )
605 {
606 std::unique_ptr<weld::TreeIter> xEntry;
607 weld::TreeIter* pEntry;
608
609 bool bCalcSubformula = false;
610 OUString aTest = _pTree->GetEntryText(pParent);
611
612 if (aTest == aResult && (eOp == ocAdd || eOp == ocMul || eOp == ocAmpersand))
613 {
614 pEntry = pParent;
615 }
616 else
617 {
618 xEntry = m_xStructPage->GetTlbStruct().make_iterator();
619
620 if (eOp == ocBad)
621 {
622 _pTree->InsertEntry(aResult, pParent, STRUCT_ERROR, 0, _pToken, *xEntry);
623 }
624 else if (!((SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP) ||
626 {
627 // Not a binary or unary operator.
628 bCalcSubformula = true;
629 _pTree->InsertEntry(aResult, pParent, STRUCT_FOLDER, 0, _pToken, *xEntry);
630 }
631 else
632 {
633 /* TODO: question remains, why not sub calculate operators? */
634 _pTree->InsertEntry(aResult, pParent, STRUCT_FOLDER, 0, _pToken, *xEntry);
635 }
636
637 pEntry = xEntry.get();
638 }
639
640 MakeTree(_pTree, pEntry, _pToken, m_oTokenArrayIterator->PrevRPN(), nParas);
641
642 if (bCalcSubformula)
643 {
644 OUString aFormula;
645
646 if (!m_bMakingTree)
647 {
648 // gets the last subformula result
649 m_bMakingTree = true;
650 aFormula = GetPrevFuncExpression( true);
651 }
652 else
653 {
654 // gets subsequent subformula results (from the back)
655 aFormula = GetPrevFuncExpression( false);
656 }
657
658 OUString aStr;
659 if (CalcValue( aFormula, aStr, _pToken->IsInForceArray()))
660 m_xWndResult->set_text( aStr );
661 aStr = m_xWndResult->get_text();
662 m_xStructPage->GetTlbStruct().set_text(*pEntry, aResult + " = " + aStr);
663 }
664
665 --Count;
666 m_oTokenArrayIterator->NextRPN(); /* TODO: what's this to be? ThisRPN()? */
667 MakeTree( _pTree, pParent, _pToken, m_oTokenArrayIterator->PrevRPN(), Count);
668 }
669 else
670 {
671 std::unique_ptr<weld::TreeIter> xEntry(m_xStructPage->GetTlbStruct().make_iterator());
672 if (eOp == ocBad)
673 {
674 _pTree->InsertEntry( aResult, pParent, STRUCT_ERROR, 0, _pToken, *xEntry);
675 }
676 else if (eOp == ocPush)
677 {
678 // Interpret range reference in matrix context to resolve
679 // as array elements. Depending on parameter classification
680 // a scalar value (non-array context) is calculated first.
681 OUString aUnforcedResult;
682 bool bForceMatrix = (!m_xBtnMatrix->get_active() &&
683 (_pToken->GetType() == svDoubleRef || _pToken->GetType() == svExternalDoubleRef));
684 if (bForceMatrix && pFuncToken)
685 {
687 if (pFuncToken->IsInForceArray())
688 eParamClass = ParamClass::ForceArray;
689 else
690 {
691 std::shared_ptr<FormulaCompiler> pCompiler = m_pHelper->getCompiler();
692 if (pCompiler)
693 eParamClass = pCompiler->GetForceArrayParameter( pFuncToken, Count - 1);
694 }
695 switch (eParamClass)
696 {
700 if (CalcValue( "=" + aResult, aUnforcedResult, false) && aUnforcedResult != aResult)
701 aUnforcedResult += " ";
702 else
703 aUnforcedResult.clear();
704 break;
712 ; // nothing, only as array/matrix
713 // no default to get compiler warning
714 }
715 }
716 OUString aCellResult;
717 if (CalcValue( "=" + aResult, aCellResult, bForceMatrix) && aCellResult != aResult)
718 {
719 // Cell is a formula, print subformula.
720 // With scalar values prints "A1:A3 = 2 {1;2;3}"
721 _pTree->InsertEntry( aResult + " = " + aUnforcedResult + aCellResult,
722 pParent, STRUCT_END, 0, _pToken, *xEntry);
723 }
724 else
725 _pTree->InsertEntry(aResult, pParent, STRUCT_END, 0, _pToken, *xEntry);
726 }
727 else
728 {
729 _pTree->InsertEntry(aResult, pParent, STRUCT_END, 0, _pToken, *xEntry);
730 }
731 --Count;
732 MakeTree( _pTree, pParent, _pToken, m_oTokenArrayIterator->PrevRPN(), Count);
733 }
734 }
735 catch (const uno::Exception&)
736 {
737 DBG_UNHANDLED_EXCEPTION("formula.ui");
738 }
739}
740
742{
744 FormulaToken* pToken = m_oTokenArrayIterator->LastRPN();
745
746 if ( pToken != nullptr)
747 {
748 MakeTree( _pTree, nullptr, nullptr, pToken, 1);
749 m_bMakingTree = false;
750 }
751}
752
753void FormulaDlg_Impl::UpdateTokenArray( const OUString& rStrExp)
754{
755 m_aTokenMap.clear();
756 m_aTokenList.realloc(0);
757 try
758 {
759 const table::CellAddress aRefPos(m_pHelper->getReferencePosition());
760 m_aTokenList = m_pHelper->getFormulaParser()->parseFormula( rStrExp, aRefPos);
761 }
762 catch (const uno::Exception&)
763 {
764 DBG_UNHANDLED_EXCEPTION("formula.ui");
765 }
769 const sal_Int32 nLen = static_cast<sal_Int32>(m_pTokenArray->GetLen());
770 FormulaToken** pTokens = m_pTokenArray->GetArray();
771 if ( pTokens && nLen == m_aTokenList.getLength() )
772 {
773 for (sal_Int32 nPos = 0; nPos < nLen; nPos++)
774 {
775 m_aTokenMap.emplace( pTokens[nPos], m_aTokenList[nPos] );
776 }
777 } // if ( pTokens && nLen == m_aTokenList.getLength() )
778
779 std::unique_ptr<FormulaCompiler> pCompiler(m_pHelper->createCompiler(*m_pTokenArray));
780 // #i101512# Disable special handling of jump commands.
781 pCompiler->EnableJumpCommandReorder(false);
782 pCompiler->EnableStopOnError(false);
783 pCompiler->SetComputeIIFlag(true);
784 pCompiler->SetMatrixFlag(m_bUserMatrixFlag);
785 pCompiler->CompileTokenArray();
786}
787
789{
790 bool bNext = true, bPrev = true;
791 if (bFlag)
792 FillControls( bNext, bPrev);
794 if (bFlag)
795 {
796 m_xBtnBackward->set_sensitive(bPrev);
797 m_xBtnForward->set_sensitive(bNext);
798 }
799
800 OUString aStrResult;
801
802 if ( CalcValue( m_pHelper->getCurrentFormula(), aStrResult ) )
803 m_xWndFormResult->set_text( aStrResult );
804 else
805 {
806 aStrResult.clear();
807 m_xWndFormResult->set_text( aStrResult );
808 }
809}
810
812{
813 // Switch between the "Pages"
815 // 1. Page: select function
817 {
818 // We'll never have more than int32 max categories so this is safe ...
819 // Category listbox holds additional entries for Last Used and All, so
820 // the offset should be two but hard coded numbers are ugly...
821 const sal_Int32 nCategoryOffset = m_xFuncPage->GetCategoryEntryCount() - m_aFormulaHelper.GetCategoryCount();
822 if ( m_xFuncPage->GetCategory() != static_cast<sal_Int32>(m_pFuncDesc->getCategory()->getNumber() + nCategoryOffset) )
823 m_xFuncPage->SetCategory(m_pFuncDesc->getCategory()->getNumber() + nCategoryOffset);
824
825 sal_Int32 nPos = m_xFuncPage->GetFuncPos(m_pFuncDesc);
826
827 m_xFuncPage->SetFunction(nPos);
828 }
829 else if ( pData )
830 {
831 // tdf#104487 - remember last used function category
833 m_xFuncPage->SetFunction( -1 );
834 }
835 FuncSelHdl(*m_xFuncPage);
836
837 m_pHelper->setDispatcherLock( true ); // Activate Modal-Mode
838
839 // HelpId for 1. page is the one from the resource
841}
842
843void FormulaDlg_Impl::FillControls( bool &rbNext, bool &rbPrev)
844{
845 // Switch between the "Pages"
847 if (!pData )
848 return;
849
850 // 2. Page or Edit: show selected function
851
852 sal_Int32 nFStart = pData->GetFStart();
853 OUString aFormula = m_pHelper->getCurrentFormula() + " )";
854 sal_Int32 nNextFStart = nFStart;
855 sal_Int32 nNextFEnd = 0;
856
857 DeleteArgs();
858 const IFunctionDescription* pOldFuncDesc = m_pFuncDesc;
859
860 if ( m_aFormulaHelper.GetNextFunc( aFormula, false,
861 nNextFStart, &nNextFEnd, &m_pFuncDesc, &m_aArguments ) )
862 {
863 const bool bTestFlag = (pOldFuncDesc != m_pFuncDesc);
864 if (bTestFlag)
865 {
866 m_xFtHeadLine->hide();
867 m_xFtFuncName->hide();
868 m_xFtFuncDesc->hide();
869 m_xParaWin->SetFunctionDesc(m_pFuncDesc);
871 m_xFtEditName->show();
872 m_xParaWinBox->show();
873 const OUString aHelpId = m_pFuncDesc->getHelpId();
874 if ( !aHelpId.isEmpty() )
875 m_xMEdit->set_help_id(aHelpId);
876 }
877
878 sal_Int32 nOldStart, nOldEnd;
879 m_pHelper->getSelection( nOldStart, nOldEnd );
880 if ( nOldStart != nNextFStart || nOldEnd != nNextFEnd )
881 {
882 m_pHelper->setSelection( nNextFStart, nNextFEnd );
883 }
884 m_aFuncSel.Min() = nNextFStart;
885 m_aFuncSel.Max() = nNextFEnd;
886
887 if (!m_bEditFlag)
889 sal_Int32 PrivStart, PrivEnd;
890 m_pHelper->getSelection( PrivStart, PrivEnd);
891 if (!m_bEditFlag)
892 m_xMEdit->select_region(PrivStart, PrivEnd);
893
895 sal_uInt16 nOffset = pData->GetOffset();
896
897 // Concatenate the Edit's for Focus-Control
898
899 if (bTestFlag)
900 m_xParaWin->SetArgumentOffset(nOffset);
901 sal_uInt16 nActiv = 0;
902 sal_Int32 nArgPos = m_aFormulaHelper.GetArgStart( aFormula, nFStart, 0 );
903
904 int nStartPos, nEndPos;
905 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
906 if (nStartPos > nEndPos)
907 std::swap(nStartPos, nEndPos);
908
909 sal_Int32 nEditPos = nStartPos;
910 bool bFlag = false;
911
912 for (sal_Int32 i = 0; i < m_nArgs; i++)
913 {
914 sal_Int32 nLength = m_aArguments[i].getLength()+1;
915 m_xParaWin->SetArgument( i, m_aArguments[i]);
916 if (nArgPos <= nEditPos && nEditPos < nArgPos+nLength)
917 {
918 nActiv = i;
919 bFlag = true;
920 }
921 nArgPos = nArgPos + nLength;
922 }
923 m_xParaWin->UpdateParas();
924
925 if (bFlag)
926 {
927 m_xParaWin->SetActiveLine(nActiv);
928 }
929
930 UpdateValues();
931 }
932 else
933 {
934 m_xFtEditName->set_label("");
935 m_xMEdit->set_help_id(m_aEditHelpId);
936 }
937 // test if before/after are anymore functions
938
939 sal_Int32 nTempStart = m_aFormulaHelper.GetArgStart( aFormula, nFStart, 0 );
940 rbNext = m_aFormulaHelper.GetNextFunc( aFormula, false, nTempStart );
941
942 int nStartPos, nEndPos;
943 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
944 if (nStartPos > nEndPos)
945 std::swap(nStartPos, nEndPos);
946
947 nTempStart = nStartPos;
948 pData->SetFStart(nTempStart);
949 rbPrev = m_aFormulaHelper.GetNextFunc( aFormula, true, nTempStart );
950}
951
952
954{
955 DeleteArgs();
956 m_pFuncDesc = nullptr;
957 m_xParaWin->ClearAll();
958 m_xWndResult->set_text(OUString());
959 m_xFtFuncName->set_label(OUString());
960 FuncSelHdl(*m_xFuncPage);
961
962 if (m_xFuncPage->IsVisible())
963 {
964 m_xFtEditName->hide();
965 m_xParaWinBox->hide();
966
967 m_xBtnForward->set_sensitive(true); //@new
968 m_xFtHeadLine->show();
969 m_xFtFuncName->show();
970 m_xFtFuncDesc->show();
971 }
972}
973
974OUString FormulaDlg_Impl::RepairFormula(const OUString& aFormula)
975{
976 OUString aResult('=');
977 try
978 {
979 UpdateTokenArray(aFormula);
980
981 if ( m_aTokenList.hasElements() )
982 {
983 const table::CellAddress aRefPos(m_pHelper->getReferencePosition());
984 const OUString sFormula( m_pHelper->getFormulaParser()->printFormula( m_aTokenList, aRefPos));
985 if ( sFormula.isEmpty() || sFormula[0] != '=' )
986 aResult += sFormula;
987 else
988 aResult = sFormula;
989
990 }
991 }
992 catch ( const uno::Exception& )
993 {
994 TOOLS_WARN_EXCEPTION("formula.ui", "FormulaDlg_Impl::RepairFormula");
995 }
996 return aResult;
997}
998
1000{
1001 // Accept input to the document or cancel
1002 if ( bOk)
1003 {
1004 // remove dummy arguments
1005 OUString aInputFormula = m_pHelper->getCurrentFormula();
1006 OUString aString = RepairFormula(m_xMEdit->get_text());
1007 m_pHelper->setSelection( 0, aInputFormula.getLength());
1008 m_pHelper->setCurrentFormula(aString);
1009 }
1010
1012
1013 m_pHelper->dispatch( bOk, m_xBtnMatrix->get_active());
1014 // Clear data
1016
1017 // Close dialog
1018 m_pHelper->doClose(bOk);
1019}
1020
1021
1023{
1024 if (&rBtn == m_xBtnCancel.get())
1025 {
1026 DoEnter(false); // closes the Dialog
1027 }
1028 else if (&rBtn == m_xBtnEnd.get())
1029 {
1030 DoEnter(true); // closes the Dialog
1031 }
1032 else if (&rBtn == m_xBtnForward.get())
1033 {
1034 const IFunctionDescription* pDesc;
1035 sal_Int32 nSelFunc = m_xFuncPage->GetFunction();
1036 if (nSelFunc != -1)
1037 pDesc = m_xFuncPage->GetFuncDesc( nSelFunc );
1038 else
1039 {
1040 // Do not overwrite the selected formula expression, just edit the
1041 // unlisted function.
1042 m_pFuncDesc = pDesc = nullptr;
1043 }
1044
1045 if (pDesc == m_pFuncDesc || !m_xFuncPage->IsVisible())
1046 EditNextFunc( true );
1047 else
1048 {
1049 DblClkHdl(*m_xFuncPage); //new
1050 m_xBtnForward->set_sensitive(false); //new
1051 }
1052 }
1053 else if (&rBtn == m_xBtnBackward.get())
1054 {
1055 m_bEditFlag = false;
1056 m_xBtnForward->set_sensitive(true);
1057 EditNextFunc( false );
1058 }
1059}
1060
1061// Functions for 1. Page
1062
1063// Handler for Listboxes
1064
1066{
1067 sal_Int32 nFunc = m_xFuncPage->GetFunction();
1068
1069 // ex-UpdateLRUList
1070 const IFunctionDescription* pDesc = m_xFuncPage->GetFuncDesc(nFunc);
1071 m_pHelper->insertEntryToLRUList(pDesc);
1072
1073 OUString aFuncName = m_xFuncPage->GetSelFunctionName() + "()";
1074 m_pHelper->setCurrentFormula(aFuncName);
1075 m_xMEdit->replace_selection(aFuncName);
1076
1077 int nStartPos, nEndPos;
1078 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
1079 if (nStartPos > nEndPos)
1080 std::swap(nStartPos, nEndPos);
1081
1082 nEndPos = nEndPos - 1;
1083 m_xMEdit->select_region(nStartPos, nEndPos);
1084
1085 FormulaHdl(*m_xMEdit);
1086
1087 nStartPos = nEndPos;
1088 m_xMEdit->select_region(nStartPos, nEndPos);
1089
1090 if (m_nArgs == 0)
1091 {
1092 BtnHdl(*m_xBtnBackward);
1093 }
1094
1095 m_xParaWin->SetEdFocus();
1096 m_xBtnForward->set_sensitive(false); //@New
1097}
1098
1099// Functions for right Page
1100
1101void FormulaDlg_Impl::SetData( sal_Int32 nFStart, sal_Int32 nNextFStart, sal_Int32 nNextFEnd, sal_Int32& PrivStart, sal_Int32& PrivEnd)
1102{
1103 sal_Int32 nFEnd;
1104
1105 // Notice and set new selection
1106 m_pHelper->getSelection( nFStart, nFEnd );
1107 m_pHelper->setSelection( nNextFStart, nNextFEnd );
1108 if (!m_bEditFlag)
1109 m_xMEdit->set_text(m_pHelper->getCurrentFormula());
1110
1111
1112 m_pHelper->getSelection( PrivStart, PrivEnd);
1113 if (!m_bEditFlag)
1114 {
1115 m_xMEdit->select_region(PrivStart, PrivEnd);
1116 UpdateOldSel();
1117 }
1118
1120 pData->SetFStart( nNextFStart );
1121 pData->SetOffset( 0 );
1122
1123 FillDialog();
1124}
1125
1126void FormulaDlg_Impl::EditThisFunc(sal_Int32 nFStart)
1127{
1129 if (!pData)
1130 return;
1131
1132 OUString aFormula = m_pHelper->getCurrentFormula();
1133
1134 if (nFStart == NOT_FOUND)
1135 {
1136 nFStart = pData->GetFStart();
1137 }
1138 else
1139 {
1140 pData->SetFStart(nFStart);
1141 }
1142
1143 sal_Int32 nNextFStart = nFStart;
1144 sal_Int32 nNextFEnd = 0;
1145
1146 bool bFound;
1147
1148 bFound = m_aFormulaHelper.GetNextFunc( aFormula, false, nNextFStart, &nNextFEnd);
1149 if ( bFound )
1150 {
1151 sal_Int32 PrivStart, PrivEnd;
1152 SetData( nFStart, nNextFStart, nNextFEnd, PrivStart, PrivEnd);
1153 m_pHelper->showReference( aFormula.copy( PrivStart, PrivEnd-PrivStart));
1154 }
1155 else
1156 {
1157 ClearAllParas();
1158 }
1159}
1160
1161bool FormulaDlg_Impl::EditNextFunc( bool bForward, sal_Int32 nFStart )
1162{
1164 if (!pData)
1165 return false;
1166
1167 OUString aFormula = m_pHelper->getCurrentFormula();
1168
1169 if (nFStart == NOT_FOUND)
1170 {
1171 nFStart = pData->GetFStart();
1172 }
1173 else
1174 {
1175 pData->SetFStart(nFStart);
1176 }
1177
1178 sal_Int32 nNextFStart = 0;
1179 sal_Int32 nNextFEnd = 0;
1180
1181 bool bFound;
1182 if ( bForward )
1183 {
1184 nNextFStart = m_aFormulaHelper.GetArgStart( aFormula, nFStart, 0 );
1185 bFound = m_aFormulaHelper.GetNextFunc( aFormula, false, nNextFStart, &nNextFEnd);
1186 }
1187 else
1188 {
1189 nNextFStart = nFStart;
1190 bFound = m_aFormulaHelper.GetNextFunc( aFormula, true, nNextFStart, &nNextFEnd);
1191 }
1192
1193 if ( bFound )
1194 {
1195 sal_Int32 PrivStart, PrivEnd;
1196 SetData( nFStart, nNextFStart, nNextFEnd, PrivStart, PrivEnd);
1197 }
1198
1199 return bFound;
1200}
1201
1202OUString FormulaDlg_Impl::GetPrevFuncExpression( bool bStartFromEnd )
1203{
1204 OUString aExpression;
1205
1206 OUString aFormula( m_pHelper->getCurrentFormula());
1207 if (aFormula.isEmpty())
1208 return aExpression;
1209
1210 if (bStartFromEnd || m_nFuncExpStart >= aFormula.getLength())
1211 m_nFuncExpStart = aFormula.getLength() - 1;
1212
1213 sal_Int32 nFStart = m_nFuncExpStart;
1214 sal_Int32 nFEnd = 0;
1215 if (m_aFormulaHelper.GetNextFunc( aFormula, true, nFStart, &nFEnd))
1216 {
1217 aExpression = aFormula.copy( nFStart, nFEnd - nFStart); // nFEnd is exclusive
1218 m_nFuncExpStart = nFStart;
1219 }
1220
1221 return aExpression;
1222}
1223
1224void FormulaDlg_Impl::SaveArg( sal_uInt16 nEd )
1225{
1226 if (nEd >= m_nArgs)
1227 return;
1228
1229 for (sal_uInt16 i = 0; i <= nEd; i++)
1230 {
1231 if ( m_aArguments[i].isEmpty() )
1232 m_aArguments[i] = " ";
1233 }
1234 if (!m_xParaWin->GetArgument(nEd).isEmpty())
1235 m_aArguments[nEd] = m_xParaWin->GetArgument(nEd);
1236
1237 sal_uInt16 nClearPos = nEd+1;
1238 for (sal_Int32 i = nEd+1; i < m_nArgs; i++)
1239 {
1240 if ( !m_xParaWin->GetArgument(i).isEmpty() )
1241 {
1242 nClearPos = i+1;
1243 }
1244 }
1245
1246 for (sal_Int32 i = nClearPos; i < m_nArgs; i++)
1247 {
1248 m_aArguments[i].clear();
1249 }
1250}
1251
1252IMPL_LINK( FormulaDlg_Impl, FxHdl, ParaWin&, rPtr, void )
1253{
1254 if (&rPtr != m_xParaWin.get())
1255 return;
1256
1257 m_xBtnForward->set_sensitive(true); //@ In order to be able to input another function.
1258 m_xTabCtrl->set_current_page("functiontab");
1259
1260 OUString aUndoStr = m_pHelper->getCurrentFormula(); // it will be added before a ";"
1261 FormEditData* pData = m_pHelper->getFormEditData();
1262 if (!pData)
1263 return;
1264
1265 sal_uInt16 nArgNo = m_xParaWin->GetActiveLine();
1266 sal_uInt16 nEdFocus = nArgNo;
1267
1268 SaveArg(nArgNo);
1269 UpdateSelection();
1270
1271 sal_Int32 nFormulaStrPos = pData->GetFStart();
1272
1273 OUString aFormula = m_pHelper->getCurrentFormula();
1274 sal_Int32 n1 = m_aFormulaHelper.GetArgStart( aFormula, nFormulaStrPos, nEdFocus + pData->GetOffset() );
1275
1276 pData->SaveValues();
1277 pData->SetMode( FormulaDlgMode::Formula );
1278 pData->SetFStart( n1 );
1279 pData->SetUndoStr( aUndoStr );
1280 ClearAllParas();
1281
1282 FillDialog(false);
1283 m_xFuncPage->SetFocus(); //There Parawin is not visible anymore
1284}
1285
1286IMPL_LINK( FormulaDlg_Impl, ModifyHdl, ParaWin&, rPtr, void )
1287{
1288 if (&rPtr == m_xParaWin.get())
1289 {
1290 SaveArg(m_xParaWin->GetActiveLine());
1291 UpdateValues();
1292
1293 UpdateSelection();
1294 CalcStruct(m_xMEdit->get_text());
1295 }
1296}
1297
1299{
1300
1301 FormEditData* pData = m_pHelper->getFormEditData();
1302 if (!pData)
1303 return;
1304
1305 m_bEditFlag = true;
1306 OUString aInputFormula = m_pHelper->getCurrentFormula();
1307 OUString aString = m_xMEdit->get_text();
1308
1309 int nStartPos, nEndPos;
1310 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
1311 if (nStartPos > nEndPos)
1312 std::swap(nStartPos, nEndPos);
1313
1314 if (aString.isEmpty()) // in case everything was cleared
1315 {
1316 aString += "=";
1317 m_xMEdit->set_text(aString);
1318 nStartPos = 1;
1319 nEndPos = 1;
1320 m_xMEdit->select_region(nStartPos, nEndPos);
1321 }
1322 else if (aString[0]!='=') // in case it's replaced
1323 {
1324 aString = "=" + aString;
1325 m_xMEdit->set_text(aString);
1326 nStartPos += 1;
1327 nEndPos += 1;
1328 m_xMEdit->select_region(nStartPos, nEndPos);
1329 }
1330
1331 m_pHelper->setSelection( 0, aInputFormula.getLength());
1332 m_pHelper->setCurrentFormula(aString);
1333 m_pHelper->setSelection(nStartPos, nEndPos);
1334
1335 sal_Int32 nPos = nStartPos - 1;
1336
1337 OUString aStrResult;
1338
1339 if ( CalcValue( m_pHelper->getCurrentFormula(), aStrResult ) )
1340 m_xWndFormResult->set_text( aStrResult );
1341 else
1342 {
1343 aStrResult.clear();
1344 m_xWndFormResult->set_text( aStrResult );
1345 }
1346 CalcStruct(aString);
1347
1348 nPos = GetFunctionPos(nPos);
1349
1350 if (nPos < nStartPos - 1)
1351 {
1352 sal_Int32 nPos1 = aString.indexOf( '(', nPos);
1353 EditNextFunc( false, nPos1);
1354 }
1355 else
1356 {
1357 ClearAllParas();
1358 }
1359
1360 m_pHelper->setSelection(nStartPos, nEndPos);
1361 m_bEditFlag = false;
1362}
1363
1365{
1367 if (!pData)
1368 return;
1369
1370 m_bEditFlag = true;
1371
1372 OUString aString = m_xMEdit->get_text();
1373
1374 int nStartPos, nEndPos;
1375 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
1376 if (nStartPos > nEndPos)
1377 std::swap(nStartPos, nEndPos);
1378
1379 m_pHelper->setSelection(nStartPos, nEndPos);
1380
1381 if (nStartPos == 0)
1382 {
1383 nStartPos = 1;
1384 m_xMEdit->select_region(nStartPos, nEndPos);
1385 }
1386 if (nStartPos != aString.getLength())
1387 {
1388 sal_Int32 nPos = nStartPos;
1389
1390 sal_Int32 nFStart = GetFunctionPos(nPos - 1);
1391
1392 if (nFStart < nPos)
1393 {
1394 sal_Int32 nPos1 = m_aFormulaHelper.GetFunctionEnd( aString, nFStart);
1395
1396 if (nPos1 > nPos)
1397 {
1398 EditThisFunc(nFStart);
1399 }
1400 else
1401 {
1402 sal_Int32 n = nPos;
1403 short nCount = 1;
1404 while(n > 0)
1405 {
1406 if (aString[n]==')')
1407 nCount++;
1408 else if (aString[n]=='(')
1409 nCount--;
1410 if (nCount == 0)
1411 break;
1412 n--;
1413 }
1414 if (nCount == 0)
1415 {
1416 nFStart = m_aFormulaHelper.GetFunctionStart( aString, n, true);
1417 EditThisFunc(nFStart);
1418 }
1419 else
1420 {
1421 ClearAllParas();
1422 }
1423 }
1424 }
1425 else
1426 {
1427 ClearAllParas();
1428 }
1429 }
1430 m_pHelper->setSelection(nStartPos, nEndPos);
1431
1432 m_bEditFlag = false;
1433}
1434
1436{
1437 m_xMEdit->get_selection_bounds(m_nSelectionStart, m_nSelectionEnd);
1440}
1441
1443{
1444 int nStartPos, nEndPos;
1445 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
1446 if (nStartPos > nEndPos)
1447 std::swap(nStartPos, nEndPos);
1448
1449 if (nStartPos != m_nSelectionStart || nEndPos != m_nSelectionEnd)
1450 {
1451 m_nSelectionStart = nStartPos;
1452 m_nSelectionEnd = nEndPos;
1453 FormulaCursor();
1454 }
1455}
1456
1458{
1460 if (m_pFuncDesc)
1461 {
1464 }
1465 else
1466 {
1468 m_nArgs = 0;
1469 }
1470
1471 m_xMEdit->set_text(m_pHelper->getCurrentFormula());
1472 sal_Int32 PrivStart, PrivEnd;
1473 m_pHelper->getSelection( PrivStart, PrivEnd);
1474 m_aFuncSel.Min() = PrivStart;
1475 m_aFuncSel.Max() = PrivEnd;
1476
1477 OUString aFormula = m_xMEdit->get_text();
1478 sal_Int32 nArgPos = m_aFormulaHelper.GetArgStart( aFormula, PrivStart, 0);
1479
1480 sal_uInt16 nPos = m_xParaWin->GetActiveLine();
1481 if (nPos >= m_aArguments.size())
1482 {
1483 SAL_WARN("formula.ui","FormulaDlg_Impl::UpdateSelection - shot in foot: nPos " <<
1484 nPos << " >= m_aArguments.size() " << m_aArguments.size() <<
1485 " for aFormula '" << aFormula << "'");
1486 nPos = m_aArguments.size();
1487 if (nPos)
1488 --nPos;
1489 }
1490
1491 for (sal_uInt16 i = 0; i < nPos; i++)
1492 {
1493 nArgPos += (m_aArguments[i].getLength() + 1);
1494 }
1495 sal_Int32 nLength = (nPos < m_aArguments.size()) ? m_aArguments[nPos].getLength() : 0;
1496
1497 m_pHelper->setSelection(nArgPos, nArgPos + nLength);
1498 m_xMEdit->select_region(nArgPos, nArgPos + nLength);
1499 UpdateOldSel();
1500}
1501
1502::std::pair<RefButton*, RefEdit*> FormulaDlg_Impl::RefInputStartBefore(RefEdit* pEdit, RefButton* pButton)
1503{
1504 m_pTheRefEdit = pEdit;
1505 m_pTheRefButton = pButton;
1506
1507 Selection aOrigSelection;
1508 if (m_pTheRefEdit)
1509 {
1510 // grab selection before showing next widget in case the selection is blown away
1511 // by it appearing
1512 aOrigSelection = m_pTheRefEdit->GetSelection();
1513 }
1514
1515 // because its initially hidden, give it its optimal size so clicking the
1516 // refbutton has an initial size to work when retro-fitting this to .ui
1517 m_xEdRef->GetWidget()->set_size_request(m_xEdRef->GetWidget()->get_preferred_size().Width(), -1);
1518 m_xEdRef->GetWidget()->show();
1519
1520 if ( m_pTheRefEdit )
1521 {
1522 m_xEdRef->SetRefString(m_pTheRefEdit->GetText());
1523 m_xEdRef->SetSelection(aOrigSelection);
1524 m_xEdRef->GetWidget()->set_help_id(m_pTheRefEdit->GetWidget()->get_help_id());
1525 }
1526
1527 m_xRefBtn->GetWidget()->set_visible(pButton != nullptr);
1528
1529 ::std::pair<RefButton*, RefEdit*> aPair;
1530 aPair.first = pButton ? m_xRefBtn.get() : nullptr;
1531 aPair.second = m_xEdRef.get();
1532 return aPair;
1533}
1534
1536{
1537 m_xRefBtn->SetEndImage();
1538
1539 if (!m_pTheRefEdit)
1540 return;
1541
1542 OUString aStr = m_aTitle2 + " " + m_xFtEditName->get_label() + "( ";
1543
1544 if ( m_xParaWin->GetActiveLine() > 0 )
1545 aStr += "...; ";
1546 aStr += m_xParaWin->GetActiveArgName();
1547 if ( m_xParaWin->GetActiveLine() + 1 < m_nArgs )
1548 aStr += "; ...";
1549 aStr += " )";
1550
1552}
1553
1555{
1556 m_xRefBtn->SetStartImage();
1557 if (!bForced && m_xRefBtn->GetWidget()->get_visible())
1558 return;
1559
1560 m_xEdRef->GetWidget()->hide();
1561 m_xRefBtn->GetWidget()->hide();
1562 if ( m_pTheRefEdit )
1563 {
1564 m_pTheRefEdit->SetRefString( m_xEdRef->GetText() );
1566
1567 if ( m_pTheRefButton )
1569
1570 sal_uInt16 nPrivActiv = m_xParaWin->GetActiveLine();
1571 m_xParaWin->SetArgument( nPrivActiv, m_xEdRef->GetText() );
1572 ModifyHdl( *m_xParaWin );
1573 m_pTheRefEdit = nullptr;
1574 }
1576}
1577
1579{
1580 return m_xEdRef->GetWidget()->get_visible() ? m_xEdRef.get() : m_xParaWin->GetActiveEdit();
1581}
1582
1584{
1586 const OUString sExpression = m_xMEdit->get_text();
1587 m_aOldFormula.clear();
1588 UpdateTokenArray(sExpression);
1589 FormulaCursor();
1590 CalcStruct(sExpression);
1591 if (pData->GetMode() == FormulaDlgMode::Formula)
1592 m_xTabCtrl->set_current_page("functiontab");
1593 else
1594 m_xTabCtrl->set_current_page("structtab");
1595 m_xBtnMatrix->set_active(pData->GetMatrixFlag());
1596}
1597
1598void FormulaDlg_Impl::Update(const OUString& _sExp)
1599{
1600 CalcStruct(_sExp);
1601 FillDialog();
1602 FuncSelHdl(*m_xFuncPage);
1603}
1604
1605void FormulaDlg_Impl::SetMeText(const OUString& _sText)
1606{
1608 m_xMEdit->set_text(_sText);
1609 auto aSelection = pData->GetSelection();
1610 m_xMEdit->select_region(aSelection.Min(), aSelection.Max());
1611 UpdateOldSel();
1612}
1613
1614FormulaDlgMode FormulaDlg_Impl::SetMeText( const OUString& _sText, sal_Int32 PrivStart, sal_Int32 PrivEnd, bool bMatrix, bool _bSelect, bool _bUpdate)
1615{
1617 if (!m_bEditFlag)
1618 m_xMEdit->set_text(_sText);
1619
1620 if ( _bSelect || !m_bEditFlag )
1621 m_xMEdit->select_region(PrivStart, PrivEnd);
1622 if ( _bUpdate )
1623 {
1624 UpdateOldSel();
1625 int nStartPos, nEndPos;
1626 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
1627 if (nStartPos > nEndPos)
1628 std::swap(nStartPos, nEndPos);
1629 m_pHelper->showReference(m_xMEdit->get_text().copy(nStartPos, nEndPos - nStartPos));
1631
1632 m_xBtnMatrix->set_active( bMatrix );
1633 } // if ( _bUpdate )
1634 return eMode;
1635}
1636
1637bool FormulaDlg_Impl::CheckMatrix(OUString& aFormula)
1638{
1639 m_xMEdit->grab_focus();
1640 sal_Int32 nLen = aFormula.getLength();
1641 bool bMatrix = nLen > 3 // Matrix-Formula
1642 && aFormula[0] == '{'
1643 && aFormula[1] == '='
1644 && aFormula[nLen-1] == '}';
1645 if ( bMatrix )
1646 {
1647 aFormula = aFormula.copy( 1, aFormula.getLength()-2 );
1648 m_xBtnMatrix->set_active( bMatrix );
1649 m_xBtnMatrix->set_sensitive(false);
1650 } // if ( bMatrix )
1651
1652 m_xTabCtrl->set_current_page("structtab");
1653 return bMatrix;
1654}
1655
1657{
1658 m_bStructUpdate = false;
1659 if (m_xStructPage->IsVisible())
1660 m_xBtnForward->set_sensitive(false); //@New
1661 m_bStructUpdate = true;
1662}
1663
1665{
1666 m_bUserMatrixFlag = true;
1667 UpdateValues(true);
1668}
1669
1671{
1672 if ( (m_xFuncPage->GetFunctionEntryCount() > 0)
1673 && (m_xFuncPage->GetFunction() != -1) )
1674 {
1675 const IFunctionDescription* pDesc = m_xFuncPage->GetFuncDesc( m_xFuncPage->GetFunction() );
1676
1677 if (pDesc != m_pFuncDesc)
1678 m_xBtnForward->set_sensitive(true); //new
1679
1680 if (pDesc)
1681 {
1682 pDesc->initArgumentInfo(); // full argument info is needed
1683
1684 OUString aSig = pDesc->getSignature();
1685 m_xFtHeadLine->set_label( pDesc->getFunctionName() );
1686 m_xFtFuncName->set_label( aSig );
1687 m_xFtFuncDesc->set_label( pDesc->getDescription() );
1688 }
1689 }
1690 else
1691 {
1692 m_xFtHeadLine->set_label( OUString() );
1693 m_xFtFuncName->set_label( OUString() );
1694 m_xFtFuncDesc->set_label( OUString() );
1695 }
1696}
1697
1698void FormulaDlg_Impl::UpdateParaWin( const Selection& _rSelection, const OUString& _sRefStr)
1699{
1700 Selection theSel = _rSelection;
1701 m_xEdRef->GetWidget()->replace_selection(_sRefStr);
1702 theSel.Max() = theSel.Min() + _sRefStr.getLength();
1703 m_xEdRef->SetSelection( theSel );
1704
1705
1706 // Manual Update of the results' fields:
1707
1708 sal_uInt16 nPrivActiv = m_xParaWin->GetActiveLine();
1709 m_xParaWin->SetArgument( nPrivActiv, m_xEdRef->GetText());
1710 m_xParaWin->UpdateParas();
1711
1712 RefEdit* pEd = GetCurrRefEdit();
1713 if (pEd)
1714 pEd->SetSelection( theSel );
1715}
1716
1718{
1719 OUString aStrEd;
1720 RefEdit* pEd = GetCurrRefEdit();
1721 if (pEd && !m_pTheRefEdit)
1722 {
1723 _rSelection = pEd->GetSelection();
1724 _rSelection.Normalize();
1725 aStrEd = pEd->GetText();
1726 m_xEdRef->SetRefString(aStrEd);
1727 m_xEdRef->SetSelection( _rSelection );
1728 }
1729 else
1730 {
1731 _rSelection = m_xEdRef->GetSelection();
1732 _rSelection.Normalize();
1733 aStrEd = m_xEdRef->GetText();
1734 }
1735 return m_pTheRefEdit == nullptr;
1736}
1737
1739{
1740 RefEdit* pEd = GetCurrRefEdit()/*aScParaWin.GetActiveEdit()*/;
1741 if (pEd)
1742 {
1743 Selection theSel = m_xEdRef->GetSelection();
1744 // Edit may have the focus -> call ModifyHdl in addition
1745 // to what's happening in GetFocus
1746 pEd->GetModifyHdl().Call(*pEd);
1747 pEd->GrabFocus();
1748 pEd->SetSelection(theSel);
1749 } // if ( pEd )
1750}
1751
1753 IFunctionManager const * _pFunctionMgr,
1755 : GenericDialogController(pParent, "formula/ui/formuladialog.ui", "FormulaDialog")
1756 , m_pImpl(new FormulaDlg_Impl(*m_xDialog, *m_xBuilder, false/*_bSupportFunctionResult*/,
1757 false/*_bSupportResult*/, false/*_bSupportMatrix*/,
1758 this, _pFunctionMgr, _pDlg))
1759{
1760 m_xDialog->set_title(m_pImpl->m_aTitle1);
1761}
1762
1764
1765void FormulaModalDialog::Update(const OUString& _sExp)
1766{
1767 m_pImpl->Update(_sExp);
1768}
1769
1770void FormulaModalDialog::SetMeText(const OUString& _sText)
1771{
1772 m_pImpl->SetMeText(_sText);
1773}
1774
1775void FormulaModalDialog::CheckMatrix(OUString& aFormula)
1776{
1777 m_pImpl->CheckMatrix(aFormula);
1778}
1779
1781{
1782 m_pImpl->Update();
1783}
1784
1785::std::pair<RefButton*, RefEdit*> FormulaModalDialog::RefInputStartBefore( RefEdit* pEdit, RefButton* pButton )
1786{
1787 return m_pImpl->RefInputStartBefore( pEdit, pButton );
1788}
1789
1791{
1792 m_pImpl->RefInputStartAfter();
1793}
1794
1796{
1797 m_pImpl->RefInputDoneAfter( true/*bForced*/ );
1798}
1799
1801{
1802 m_pImpl->StoreFormEditData(pData);
1803}
1804
1805// Initialisation / General functions for Dialog
1807 weld::Window* pParent,
1808 IFunctionManager const * _pFunctionMgr, IControlReferenceHandler* _pDlg)
1809 : SfxModelessDialogController( pB, pCW, pParent, "formula/ui/formuladialog.ui", "FormulaDialog")
1810 , m_pImpl(new FormulaDlg_Impl(*m_xDialog, *m_xBuilder, true/*_bSupportFunctionResult*/
1811 , true/*_bSupportResult*/
1812 , true/*_bSupportMatrix*/
1813 , this, _pFunctionMgr, _pDlg))
1814{
1815 m_xDialog->set_title(m_pImpl->m_aTitle1);
1816}
1817
1819{
1820}
1821
1822void FormulaDlg::Update(const OUString& _sExp)
1823{
1824 m_pImpl->Update(_sExp);
1825}
1826
1827void FormulaDlg::SetMeText(const OUString& _sText)
1828{
1829 m_pImpl->SetMeText(_sText);
1830}
1831
1832FormulaDlgMode FormulaDlg::SetMeText( const OUString& _sText, sal_Int32 PrivStart, sal_Int32 PrivEnd, bool bMatrix, bool _bSelect, bool _bUpdate)
1833{
1834 return m_pImpl->SetMeText( _sText, PrivStart, PrivEnd, bMatrix, _bSelect, _bUpdate);
1835}
1836
1837bool FormulaDlg::CheckMatrix(OUString& aFormula)
1838{
1839 return m_pImpl->CheckMatrix(aFormula);
1840}
1841
1843{
1844 return m_pImpl->m_xMEdit->get_text();
1845}
1846
1848{
1849 m_pImpl->Update();
1850}
1851
1853{
1854 m_pImpl->DoEnter(false);
1855}
1856
1857::std::pair<RefButton*, RefEdit*> FormulaDlg::RefInputStartBefore( RefEdit* pEdit, RefButton* pButton )
1858{
1859 return m_pImpl->RefInputStartBefore( pEdit, pButton );
1860}
1861
1863{
1864 m_pImpl->RefInputStartAfter();
1865}
1866
1868{
1869 m_pImpl->RefInputDoneAfter( bForced );
1870}
1871
1873{
1874 m_pImpl->m_xBtnEnd->set_sensitive(false);
1875}
1876
1878{
1879 m_pImpl->StoreFormEditData(pData);
1880}
1881
1883{
1884 SAL_WARN_IF( (m_pImpl->m_pFuncDesc && m_pImpl->m_pFuncDesc->getSuppressedArgumentCount() != m_pImpl->m_nArgs),
1885 "formula.ui", "FormulaDlg::getCurrentFunctionDescription: getSuppressedArgumentCount " <<
1886 m_pImpl->m_pFuncDesc->getSuppressedArgumentCount() << " != m_nArgs " << m_pImpl->m_nArgs << " for " <<
1887 m_pImpl->m_pFuncDesc->getFunctionName());
1888 return m_pImpl->m_pFuncDesc;
1889}
1890
1891void FormulaDlg::UpdateParaWin( const Selection& _rSelection, const OUString& _sRefStr)
1892{
1893 m_pImpl->UpdateParaWin( _rSelection, _sRefStr);
1894}
1895
1897{
1898 return m_pImpl->UpdateParaWin(_rSelection);
1899}
1900
1902{
1903 return m_pImpl->m_xParaWin->GetActiveEdit();
1904}
1905
1907{
1908 return m_pImpl->GetFormulaHelper();
1909}
1910
1912{
1913 m_pImpl->SetEdSelection();
1914}
1915
1917{
1918 Reset();
1919}
1920
1922{
1924 nFStart = 0;
1925 nOffset = 0;
1926 bMatrix = false;
1927 aSelection.Min() = 0;
1928 aSelection.Max() = 0;
1929 aUndoStr.clear();
1930}
1931
1933{
1934 nMode = r.nMode;
1935 nFStart = r.nFStart;
1936 nOffset = r.nOffset;
1937 aUndoStr = r.aUndoStr;
1938 bMatrix = r.bMatrix ;
1940 return *this;
1941}
1942
1944{
1945 Reset();
1946}
1947
1949{
1950}
1951
1953{
1954 *this = r;
1955}
1956
1957
1958} // formula
1959
1960
1961/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
Reference< XExecutableDialog > m_xDialog
static bool AnyInput(VclInputFlags nType=VCL_INPUT_ANY)
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
tools::Long Min() const
void Normalize()
tools::Long Max() const
virtual void SaveValues()
Definition: formula.cxx:1916
FormEditData & operator=(const FormEditData &r)
Definition: formula.cxx:1932
FormulaDlgMode nMode
Definition: formdata.hxx:59
sal_uInt16 nOffset
Definition: formdata.hxx:61
virtual ~FormEditData()
Definition: formula.cxx:1948
Selection aSelection
Definition: formdata.hxx:64
static bool IsMatrixFunction(OpCode _eOpCode)
DECL_LINK(StructSelHdl, StructPage &, void)
void MakeTree(StructPage *_pTree, weld::TreeIter *pParent, const FormulaToken *pFuncToken, const FormulaToken *_pToken, tools::Long Count)
Definition: formula.cxx:583
std::unique_ptr< RefButton > m_xRefBtn
Definition: formula.cxx:189
void UpdateValues(bool bForceRecalcStruct=false)
Definition: formula.cxx:505
std::unique_ptr< weld::Label > m_xFtFuncName
Definition: formula.cxx:167
const FormulaHelper & GetFormulaHelper() const
Definition: formula.cxx:107
FormulaDlgMode SetMeText(const OUString &_sText, sal_Int32 PrivStart, sal_Int32 PrivEnd, bool bMatrix, bool _bSelect, bool _bUpdate)
Definition: formula.cxx:1614
::std::optional< FormulaTokenArrayPlainIterator > m_oTokenArrayIterator
Definition: formula.cxx:127
std::unique_ptr< weld::Entry > m_xWndResult
Definition: formula.cxx:173
void DoEnter(bool bOk)
Definition: formula.cxx:999
void fillTree(StructPage *_pTree)
Definition: formula.cxx:741
DECL_LINK(FuncSelHdl, FuncPage &, void)
void CalcStruct(const OUString &rStrExp, bool bForceRecalcStruct=false)
Definition: formula.cxx:554
void SaveArg(sal_uInt16 nEd)
Definition: formula.cxx:1224
const OUString m_aTitle2
Definition: formula.cxx:141
void EditThisFunc(sal_Int32 nFStart)
Definition: formula.cxx:1126
weld::Dialog & m_rDialog
Definition: formula.cxx:134
std::unique_ptr< weld::Label > m_xFtEditName
Definition: formula.cxx:170
bool CalcValue(const OUString &rStrExp, OUString &rStrResult, bool bForceMatrixFormula=false)
Definition: formula.cxx:483
OUString RepairFormula(const OUString &aFormula)
Definition: formula.cxx:974
void UpdateTokenArray(const OUString &rStrExp)
Definition: formula.cxx:753
FormulaHelper m_aFormulaHelper
Definition: formula.cxx:142
std::unique_ptr< weld::Button > m_xBtnForward
Definition: formula.cxx:182
const sheet::FormulaOpCodeMapEntry * m_pFunctionOpCodesEnd
Definition: formula.cxx:131
DECL_LINK(FxHdl, ParaWin &, void)
void FillDialog(bool bFlag=true)
Definition: formula.cxx:788
sal_Int32 m_nFuncExpStart
current formula position for treeview results
Definition: formula.cxx:155
std::unique_ptr< RefEdit > m_xEdRef
Definition: formula.cxx:188
::std::pair< RefButton *, RefEdit * > RefInputStartBefore(RefEdit *pEdit, RefButton *pButton)
Definition: formula.cxx:1502
uno::Reference< sheet::XFormulaOpCodeMapper > m_xOpCodeMapper
Definition: formula.cxx:124
std::unique_ptr< weld::Label > m_xFtHeadLine
Definition: formula.cxx:166
const IFunctionDescription * m_pFuncDesc
Definition: formula.cxx:150
void SetData(sal_Int32 nFStart, sal_Int32 nNextFStart, sal_Int32 nNextFEnd, sal_Int32 &PrivStart, sal_Int32 &PrivEnd)
Definition: formula.cxx:1101
std::unique_ptr< weld::Label > m_xFtFuncDesc
Definition: formula.cxx:168
const OUString m_aTitle1
Definition: formula.cxx:140
std::unique_ptr< weld::Button > m_xBtnCancel
Definition: formula.cxx:179
FormulaDlg_Impl(weld::Dialog &rDialog, weld::Builder &rBuilder, bool _bSupportFunctionResult, bool _bSupportResult, bool _bSupportMatrix, IFormulaEditorHelper *_pHelper, const IFunctionManager *_pFunctionMgr, IControlReferenceHandler *_pDlg)
Definition: formula.cxx:205
sal_Int32 GetFunctionPos(sal_Int32 nPos)
Definition: formula.cxx:370
RefEdit * GetCurrRefEdit()
Definition: formula.cxx:1578
std::unique_ptr< FuncPage > m_xFuncPage
Definition: formula.cxx:191
DECL_LINK(DblClkHdl, FuncPage &, void)
std::unique_ptr< weld::CheckButton > m_xBtnMatrix
Definition: formula.cxx:178
DECL_LINK(ModifyHdl, ParaWin &, void)
std::unique_ptr< weld::Button > m_xBtnEnd
Definition: formula.cxx:183
std::unique_ptr< weld::Label > m_xFtFormula
Definition: formula.cxx:175
DECL_LINK(FormulaCursorHdl, weld::TextView &, void)
::std::vector< OUString > m_aArguments
Definition: formula.cxx:152
uno::Sequence< sheet::FormulaToken > m_aTokenList
Definition: formula.cxx:125
IFormulaEditorHelper * m_pHelper
Definition: formula.cxx:133
std::unique_ptr< weld::TextView > m_xMEdit
Definition: formula.cxx:176
std::unique_ptr< weld::Entry > m_xWndFormResult
Definition: formula.cxx:186
void FillControls(bool &rbNext, bool &rbPrev)
Definition: formula.cxx:843
RefButton * m_pTheRefButton
Definition: formula.cxx:161
OUString GetPrevFuncExpression(bool bStartFromEnd)
Definition: formula.cxx:1202
bool UpdateParaWin(Selection &_rSelection)
Definition: formula.cxx:1717
bool CheckMatrix(OUString &aFormula)
Definition: formula.cxx:1637
std::unique_ptr< weld::Label > m_xFtFormResult
Definition: formula.cxx:185
std::unique_ptr< StructPage > m_xStructPage
Definition: formula.cxx:192
void RefInputDoneAfter(bool bForced)
Definition: formula.cxx:1554
uno::Sequence< sheet::FormulaOpCodeMapEntry > m_aSpecialOpCodes
Definition: formula.cxx:128
std::unique_ptr< ParaWin > m_xParaWin
Definition: formula.cxx:165
std::unique_ptr< weld::Button > m_xBtnBackward
Definition: formula.cxx:181
std::unique_ptr< weld::Notebook > m_xTabCtrl
Definition: formula.cxx:163
uno::Sequence< sheet::FormulaOpCodeMapEntry > m_aFunctionOpCodes
Definition: formula.cxx:130
void StoreFormEditData(FormEditData *pEditData)
Definition: formula.cxx:327
bool EditNextFunc(bool bForward, sal_Int32 nFStart=NOT_FOUND)
Definition: formula.cxx:1161
std::unique_ptr< weld::Container > m_xParaWinBox
Definition: formula.cxx:164
DECL_LINK(BtnHdl, weld::Button &, void)
std::unique_ptr< weld::Label > m_xFtResult
Definition: formula.cxx:172
uno::Sequence< sheet::FormulaToken > m_aSeparatorsOpCodes
Definition: formula.cxx:129
DECL_LINK(MatrixHdl, weld::Toggleable &, void)
::std::unique_ptr< FormulaTokenArray > m_pTokenArray
Definition: formula.cxx:126
DECL_LINK(FormulaHdl, weld::TextView &, void)
::std::map< const FormulaToken *, sheet::FormulaToken > m_aTokenMap
Definition: formula.cxx:132
const FormulaHelper & GetFormulaHelper() const
Definition: formula.cxx:1906
void SetMeText(const OUString &_sText)
Definition: formula.cxx:1827
RefEdit * GetActiveEdit()
Definition: formula.cxx:1901
::std::pair< RefButton *, RefEdit * > RefInputStartBefore(RefEdit *pEdit, RefButton *pButton)
Definition: formula.cxx:1857
void RefInputStartAfter()
Definition: formula.cxx:1862
bool UpdateParaWin(Selection &_rSelection)
Definition: formula.cxx:1896
OUString GetMeText() const
Definition: formula.cxx:1842
bool CheckMatrix(OUString &aFormula)
Definition: formula.cxx:1837
std::unique_ptr< FormulaDlg_Impl, o3tl::default_delete< FormulaDlg_Impl > > m_pImpl
Definition: formula.hxx:92
const IFunctionDescription * getCurrentFunctionDescription() const
Definition: formula.cxx:1882
FormulaDlg(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, IFunctionManager const *_pFunctionMgr, IControlReferenceHandler *_pDlg)
Definition: formula.cxx:1806
virtual ~FormulaDlg() override
Definition: formula.cxx:1818
void StoreFormEditData(FormEditData *pData)
Definition: formula.cxx:1877
void RefInputDoneAfter(bool bForced)
Definition: formula.cxx:1867
sal_Int32 GetFunctionEnd(std::u16string_view rFormula, sal_Int32 nStart) const
bool GetNextFunc(const OUString &rFormula, bool bBack, sal_Int32 &rFStart, sal_Int32 *pFEnd=nullptr, const IFunctionDescription **ppFDesc=nullptr, ::std::vector< OUString > *pArgs=nullptr) const
const CharClass & GetCharClass() const
sal_Int32 GetFunctionStart(const OUString &rFormula, sal_Int32 nStart, bool bBack, OUString *pFuncName=nullptr) const
sal_Int32 GetArgStart(std::u16string_view rFormula, sal_Int32 nStart, sal_uInt16 nArg) const
sal_Int32 GetCategoryCount() const
void StoreFormEditData(FormEditData *pData)
Definition: formula.cxx:1800
void SetMeText(const OUString &_sText)
Definition: formula.cxx:1770
std::unique_ptr< FormulaDlg_Impl, o3tl::default_delete< FormulaDlg_Impl > > m_pImpl
Definition: formula.hxx:65
FormulaModalDialog(weld::Window *pParent, IFunctionManager const *_pFunctionMgr, IControlReferenceHandler *_pDlg)
Definition: formula.cxx:1752
::std::pair< RefButton *, RefEdit * > RefInputStartBefore(RefEdit *pEdit, RefButton *pButton)
Definition: formula.cxx:1785
virtual ~FormulaModalDialog() override
Definition: formula.cxx:1763
void CheckMatrix(OUString &aFormula)
Definition: formula.cxx:1775
virtual FormulaToken * GetFAPOrigToken() const
Definition: token.cxx:266
bool IsFunction() const
Definition: token.cxx:71
bool IsInForceArray() const
Definition: token.cxx:146
OpCode GetOpCode() const
Definition: token.hxx:158
StackVar GetType() const
Definition: token.hxx:138
sal_uInt8 GetParamCount() const
Definition: token.cxx:89
static sal_Int32 GetRememeberdFunctionCategory()
Definition: funcpage.hxx:78
virtual void deleteFormData()=0
virtual std::unique_ptr< FormulaCompiler > createCompiler(FormulaTokenArray &rArray) const =0
Create an application specific FormulaCompiler instance with FormulaTokenArray.
virtual css::table::CellAddress getReferencePosition() const =0
virtual OUString getCurrentFormula() const =0
virtual void getSelection(sal_Int32 &_nStart, sal_Int32 &_nEnd) const =0
virtual std::shared_ptr< FormulaCompiler > getCompiler() const =0
Obtain a resident FormulaCompiler instance, created without FormulaTokenArray and reused but being ap...
virtual css::uno::Reference< css::sheet::XFormulaOpCodeMapper > getFormulaOpCodeMapper() const =0
virtual void showReference(const OUString &_sFormula)=0
virtual IFunctionManager * getFunctionManager()=0
virtual bool calculateValue(const OUString &_sExpression, OUString &_rResult, bool bMatrixFormula)=0
virtual void setDispatcherLock(bool bLock)=0
virtual void setCurrentFormula(const OUString &_sReplacement)=0
virtual void setSelection(sal_Int32 _nStart, sal_Int32 _nEnd)=0
virtual void dispatch(bool _bOK, bool _bMatrixChecked)=0
virtual css::uno::Reference< css::sheet::XFormulaParser > getFormulaParser() const =0
virtual void doClose(bool _bOk)=0
virtual ::std::unique_ptr< FormulaTokenArray > convertToTokenArray(const css::uno::Sequence< css::sheet::FormulaToken > &_aTokenList)=0
virtual FormEditData * getFormEditData() const =0
virtual sal_uInt32 getNumber() const =0
virtual OUString getFormula(const ::std::vector< OUString > &_aArguments) const =0
virtual const IFunctionCategory * getCategory() const =0
virtual void initArgumentInfo() const =0
virtual OUString getFunctionName() const =0
virtual OUString getSignature() const =0
virtual sal_Int32 getSuppressedArgumentCount() const =0
virtual OUString getDescription() const =0
virtual OUString getHelpId() const =0
virtual sal_Unicode getSingleToken(const EToken _eToken) const =0
void SetStartImage()
Definition: funcutl.cxx:426
void SetSelection(const Selection &rSelection)
Definition: funcutl.hxx:106
void GrabFocus()
Definition: funcutl.hxx:96
weld::Entry * GetWidget() const
Definition: funcutl.hxx:70
const Link< RefEdit &, void > & GetModifyHdl() const
Definition: funcutl.hxx:141
Selection GetSelection() const
Definition: funcutl.hxx:116
void SetRefString(const OUString &rStr)
Definition: funcutl.cxx:289
OUString GetText() const
Definition: funcutl.hxx:82
OUString GetEntryText(const weld::TreeIter *pEntry) const
Definition: structpg.cxx:97
bool InsertEntry(const OUString &rText, const weld::TreeIter *pParent, sal_uInt16 nFlag, int nPos, const FormulaToken *pIFormulaToken, weld::TreeIter &rRet)
Definition: structpg.cxx:60
void SetWeight(FontWeight)
std::shared_ptr< weld::Dialog > m_xDialog
virtual void set_help_id(const OUString &rName)=0
virtual OUString strip_mnemonic(const OUString &rLabel) const=0
virtual OUString get_help_id() const=0
virtual void set_title(const OUString &rTitle)=0
#define SC_OPCODE_STOP_BIN_OP
Definition: compiler.hxx:95
#define SC_OPCODE_STOP_UN_OP
Definition: compiler.hxx:102
#define SC_OPCODE_START_UN_OP
Definition: compiler.hxx:100
#define SC_OPCODE_START_BIN_OP
Definition: compiler.hxx:77
OUString ForResId(TranslateId aId)
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
OString sFormula
WEIGHT_BOLD
#define TOKEN_CLOSE
Definition: formula.cxx:52
#define TOKEN_OPEN
Definition: formula.cxx:51
#define STRUCT_FOLDER
Definition: formula.hxx:42
#define STRUCT_ERROR
Definition: formula.hxx:43
#define STRUCT_END
Definition: formula.hxx:41
Mode eMode
sal_Int64 n
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
aStr
aBuf
std::unique_ptr< sal_Int32[]> pData
int n2
int n1
sal_uInt32 n3
double getLength(const B2DPolygon &rCandidate)
@ Bounds
Out of bounds, function doesn't expect that many parameters.
Definition: paramclass.hxx:25
@ Value
In array formula: single value to be passed.
Definition: paramclass.hxx:32
@ SuppressedReferenceOrForceArray
Same as ReferenceOrForceArray but suppressed / not inherited in the compiler's ForceArray context to ...
Definition: paramclass.hxx:70
@ ReferenceOrRefArray
Like Reference but the function accepts also a list of references (ocUnion svRefList) as one argument...
Definition: paramclass.hxx:45
@ ForceArray
Area reference must be converted to array in any case, and must also be propagated to subsequent oper...
Definition: paramclass.hxx:56
@ ReferenceOrForceArray
Area reference is not converted to array, but ForceArray must be propagated to subsequent operators a...
Definition: paramclass.hxx:63
@ ForceArrayReturn
A function return forces the caller into array mode for this one call, making it behave like it had F...
Definition: paramclass.hxx:75
@ Reference
In array formula: area reference must stay reference.
Definition: paramclass.hxx:37
@ Array
In array formula: convert area reference to array.
Definition: paramclass.hxx:51
@ svExternalDoubleRef
Definition: token.hxx:74
@ svDoubleRef
Definition: token.hxx:54
@ svFAP
Definition: token.hxx:59
FormulaDlgMode
Definition: formula.hxx:45
IMPL_LINK_NOARG(FormulaDlg_Impl, DblClkHdl, FuncPage &, void)
Definition: formula.cxx:1065
IMPL_LINK(FormulaDlg_Impl, BtnHdl, weld::Button &, rBtn, void)
Definition: formula.cxx:1022
int i
long Long
OpCode
Definition: opcode.hxx:29
@ ocAmpersand
Definition: opcode.hxx:85
@ ocAdd
Definition: opcode.hxx:81
@ ocPush
Definition: opcode.hxx:31
@ ocBad
Definition: opcode.hxx:53
@ ocMul
Definition: opcode.hxx:83
#define NOT_FOUND
Definition: parawin.hxx:30
#define SAL_MAX_INT32
sal_uInt16 sal_Unicode
Count
sal_Int32 nLength