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>
61 ::std::pair<RefButton*, RefEdit*>
65 bool CalcValue(
const OUString& rStrExp, OUString& rStrResult,
bool bForceMatrixFormula =
false );
66 void CalcStruct(
const OUString& rStrExp,
bool bForceRecalcStruct =
false );
86 void Update(
const OUString& _sExp);
94 FormulaDlgMode SetMeText(
const OUString& _sText, sal_Int32 PrivStart, sal_Int32 PrivEnd,
bool bMatrix,
bool _bSelect,
bool _bUpdate);
103 void SetData( sal_Int32 nFStart, sal_Int32 nNextFStart, sal_Int32 nNextFEnd, sal_Int32& PrivStart, sal_Int32& PrivEnd);
196 bool _bSupportFunctionResult,
197 bool _bSupportResult,
198 bool _bSupportMatrix,
207 bool _bSupportFunctionResult,
208 bool _bSupportResult,
209 bool _bSupportMatrix,
213 : m_pFunctionOpCodesEnd(nullptr)
214 , m_pHelper(_pHelper)
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)
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")))
248 auto nWidth =
m_xMEdit->get_approximate_digit_width() * 62;
296 if ( _bSupportMatrix )
316 m_xParaWin->SetArgumentFonts( aFntBold, aFntLight);
332 int nStartPos, nEndPos;
333 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
334 if (nStartPos > nEndPos)
335 std::swap(nStartPos, nEndPos);
337 pData->SetFStart(nStartPos);
340 if (
m_xTabCtrl->get_current_page_ident() ==
"functiontab")
383 const sheet::FormulaToken* pIter =
m_aTokenList.getConstArray();
384 const sheet::FormulaToken* pEnd = pIter +
m_aTokenList.getLength();
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 )
397 const sal_Int32 eOp = pIter->OpCode;
399 const OUString aString = xParser->printFormula( aArgs, aRefPos);
400 const sheet::FormulaToken* pNextToken = pIter + 1;
407 if (eOp == nOpPush || eOp == nOpSpaces || eOp == nOpWhitespace)
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 )
420 if ( pNextToken != pEnd )
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)
431 nTokPos = nTokPos + aString.getLength();
443 nFuncPos = nPrevFuncPos;
447 [&eOp](
const sheet::FormulaOpCodeMapEntry& aEntry) { return aEntry.Token.OpCode == eOp; });
449 if ( bIsFunction && nOpSpaces != eOp && nOpWhitespace != eOp )
451 nPrevFuncPos = nFuncPos;
452 nFuncPos = nOldTokPos;
455 if ( nOldTokPos <=
nPos &&
nPos < nTokPos )
459 if ( nBracketCount < 1 )
461 nFuncPos =
m_xMEdit->get_text().getLength();
465 nFuncPos = nPrevFuncPos;
472 nOldTokPos = nTokPos;
475 catch (
const uno::Exception& )
487 if ( !rStrExp.isEmpty() )
509 bool bForceArray =
false;
519 if (pCompiler->GetCurrentOpCodeMap())
522 assert( 0 <=
nPos && nPos < m_pHelper->getCurrentFormula().
getLength());
527 pCompiler->CreateStringFromToken(
aBuf, pToken);
531 if (pToken &&
nPos <
aBuf.getLength())
556 sal_Int32
nLength = rStrExp.getLength();
563 OUString aString = rStrExp;
566 aString = aString.copy( 0,
nLength-1);
569 aString = aString.replaceAll(
"\n",
"");
586 if ( _pToken ==
nullptr ||
Count <= 0 )
594 ::std::map<const FormulaToken*, sheet::FormulaToken>::const_iterator itr =
m_aTokenMap.find(pOrigToken);
604 if ( nParas > 0 || (nParas == 0 && _pToken->
IsFunction()) )
606 std::unique_ptr<weld::TreeIter> xEntry;
609 bool bCalcSubformula =
false;
628 bCalcSubformula =
true;
637 pEntry = xEntry.get();
671 std::unique_ptr<weld::TreeIter> xEntry(
m_xStructPage->GetTlbStruct().make_iterator());
681 OUString aUnforcedResult;
684 if (bForceMatrix && pFuncToken)
693 eParamClass = pCompiler->GetForceArrayParameter( pFuncToken,
Count - 1);
700 if (
CalcValue(
"=" + aResult, aUnforcedResult,
false) && aUnforcedResult != aResult)
701 aUnforcedResult +=
" ";
703 aUnforcedResult.clear();
716 OUString aCellResult;
717 if (
CalcValue(
"=" + aResult, aCellResult, bForceMatrix) && aCellResult != aResult)
721 _pTree->
InsertEntry( aResult +
" = " + aUnforcedResult + aCellResult,
735 catch (
const uno::Exception&)
746 if ( pToken !=
nullptr)
748 MakeTree( _pTree,
nullptr,
nullptr, pToken, 1);
762 catch (
const uno::Exception&)
769 const sal_Int32 nLen =
static_cast<sal_Int32
>(
m_pTokenArray->GetLen());
781 pCompiler->EnableJumpCommandReorder(
false);
782 pCompiler->EnableStopOnError(
false);
783 pCompiler->SetComputeIIFlag(
true);
785 pCompiler->CompileTokenArray();
790 bool bNext =
true, bPrev =
true;
852 sal_Int32 nFStart =
pData->GetFStart();
854 sal_Int32 nNextFStart = nFStart;
855 sal_Int32 nNextFEnd = 0;
863 const bool bTestFlag = (pOldFuncDesc !=
m_pFuncDesc);
874 if ( !aHelpId.isEmpty() )
878 sal_Int32 nOldStart, nOldEnd;
880 if ( nOldStart != nNextFStart || nOldEnd != nNextFEnd )
889 sal_Int32 PrivStart, PrivEnd;
892 m_xMEdit->select_region(PrivStart, PrivEnd);
895 sal_uInt16 nOffset =
pData->GetOffset();
901 sal_uInt16 nActiv = 0;
904 int nStartPos, nEndPos;
905 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
906 if (nStartPos > nEndPos)
907 std::swap(nStartPos, nEndPos);
909 sal_Int32 nEditPos = nStartPos;
916 if (nArgPos <= nEditPos && nEditPos < nArgPos+
nLength)
942 int nStartPos, nEndPos;
943 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
944 if (nStartPos > nEndPos)
945 std::swap(nStartPos, nEndPos);
947 nTempStart = nStartPos;
948 pData->SetFStart(nTempStart);
976 OUString aResult(
'=');
992 catch (
const uno::Exception& )
1024 if (&rBtn == m_xBtnCancel.get())
1028 else if (&rBtn == m_xBtnEnd.get())
1032 else if (&rBtn == m_xBtnForward.get())
1035 sal_Int32 nSelFunc = m_xFuncPage->GetFunction();
1037 pDesc = m_xFuncPage->GetFuncDesc( nSelFunc );
1042 m_pFuncDesc = pDesc =
nullptr;
1045 if (pDesc == m_pFuncDesc || !m_xFuncPage->IsVisible())
1046 EditNextFunc(
true );
1049 DblClkHdl(*m_xFuncPage);
1050 m_xBtnForward->set_sensitive(
false);
1053 else if (&rBtn == m_xBtnBackward.get())
1055 m_bEditFlag =
false;
1056 m_xBtnForward->set_sensitive(
true);
1057 EditNextFunc(
false );
1067 sal_Int32 nFunc = m_xFuncPage->GetFunction();
1071 m_pHelper->insertEntryToLRUList(pDesc);
1073 OUString aFuncName = m_xFuncPage->GetSelFunctionName() +
"()";
1074 m_pHelper->setCurrentFormula(aFuncName);
1075 m_xMEdit->replace_selection(aFuncName);
1077 int nStartPos, nEndPos;
1078 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
1079 if (nStartPos > nEndPos)
1080 std::swap(nStartPos, nEndPos);
1082 nEndPos = nEndPos - 1;
1083 m_xMEdit->select_region(nStartPos, nEndPos);
1085 FormulaHdl(*m_xMEdit);
1087 nStartPos = nEndPos;
1088 m_xMEdit->select_region(nStartPos, nEndPos);
1092 BtnHdl(*m_xBtnBackward);
1095 m_xParaWin->SetEdFocus();
1096 m_xBtnForward->set_sensitive(
false);
1115 m_xMEdit->select_region(PrivStart, PrivEnd);
1120 pData->SetFStart( nNextFStart );
1121 pData->SetOffset( 0 );
1136 nFStart =
pData->GetFStart();
1140 pData->SetFStart(nFStart);
1143 sal_Int32 nNextFStart = nFStart;
1144 sal_Int32 nNextFEnd = 0;
1151 sal_Int32 PrivStart, PrivEnd;
1152 SetData( nFStart, nNextFStart, nNextFEnd, PrivStart, PrivEnd);
1171 nFStart =
pData->GetFStart();
1175 pData->SetFStart(nFStart);
1178 sal_Int32 nNextFStart = 0;
1179 sal_Int32 nNextFEnd = 0;
1189 nNextFStart = nFStart;
1195 sal_Int32 PrivStart, PrivEnd;
1196 SetData( nFStart, nNextFStart, nNextFEnd, PrivStart, PrivEnd);
1204 OUString aExpression;
1207 if (aFormula.isEmpty())
1214 sal_Int32 nFEnd = 0;
1217 aExpression = aFormula.copy( nFStart, nFEnd - nFStart);
1229 for (sal_uInt16
i = 0;
i <= nEd;
i++)
1237 sal_uInt16 nClearPos = nEd+1;
1246 for (sal_Int32
i = nClearPos;
i <
m_nArgs;
i++)
1254 if (&rPtr != m_xParaWin.get())
1257 m_xBtnForward->set_sensitive(
true);
1258 m_xTabCtrl->set_current_page(
"functiontab");
1260 OUString aUndoStr = m_pHelper->getCurrentFormula();
1265 sal_uInt16 nArgNo = m_xParaWin->GetActiveLine();
1266 sal_uInt16 nEdFocus = nArgNo;
1271 sal_Int32 nFormulaStrPos =
pData->GetFStart();
1273 OUString aFormula = m_pHelper->getCurrentFormula();
1274 sal_Int32
n1 = m_aFormulaHelper.GetArgStart( aFormula, nFormulaStrPos, nEdFocus +
pData->GetOffset() );
1276 pData->SaveValues();
1279 pData->SetUndoStr( aUndoStr );
1283 m_xFuncPage->SetFocus();
1288 if (&rPtr == m_xParaWin.get())
1290 SaveArg(m_xParaWin->GetActiveLine());
1294 CalcStruct(m_xMEdit->get_text());
1306 OUString aInputFormula = m_pHelper->getCurrentFormula();
1307 OUString aString = m_xMEdit->get_text();
1309 int nStartPos, nEndPos;
1310 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
1311 if (nStartPos > nEndPos)
1312 std::swap(nStartPos, nEndPos);
1314 if (aString.isEmpty())
1317 m_xMEdit->set_text(aString);
1320 m_xMEdit->select_region(nStartPos, nEndPos);
1322 else if (aString[0]!=
'=')
1324 aString =
"=" + aString;
1325 m_xMEdit->set_text(aString);
1328 m_xMEdit->select_region(nStartPos, nEndPos);
1331 m_pHelper->setSelection( 0, aInputFormula.getLength());
1332 m_pHelper->setCurrentFormula(aString);
1333 m_pHelper->setSelection(nStartPos, nEndPos);
1335 sal_Int32
nPos = nStartPos - 1;
1337 OUString aStrResult;
1339 if ( CalcValue( m_pHelper->getCurrentFormula(), aStrResult ) )
1340 m_xWndFormResult->set_text( aStrResult );
1344 m_xWndFormResult->set_text( aStrResult );
1346 CalcStruct(aString);
1350 if (
nPos < nStartPos - 1)
1352 sal_Int32 nPos1 = aString.indexOf(
'(',
nPos);
1353 EditNextFunc(
false, nPos1);
1360 m_pHelper->setSelection(nStartPos, nEndPos);
1361 m_bEditFlag =
false;
1372 OUString aString =
m_xMEdit->get_text();
1374 int nStartPos, nEndPos;
1375 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
1376 if (nStartPos > nEndPos)
1377 std::swap(nStartPos, nEndPos);
1384 m_xMEdit->select_region(nStartPos, nEndPos);
1386 if (nStartPos != aString.getLength())
1388 sal_Int32
nPos = nStartPos;
1406 if (aString[
n]==
')')
1408 else if (aString[
n]==
'(')
1444 int nStartPos, nEndPos;
1445 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
1446 if (nStartPos > nEndPos)
1447 std::swap(nStartPos, nEndPos);
1449 if (nStartPos != m_nSelectionStart || nEndPos != m_nSelectionEnd)
1451 m_nSelectionStart = nStartPos;
1452 m_nSelectionEnd = nEndPos;
1472 sal_Int32 PrivStart, PrivEnd;
1477 OUString aFormula =
m_xMEdit->get_text();
1483 SAL_WARN(
"formula.ui",
"FormulaDlg_Impl::UpdateSelection - shot in foot: nPos " <<
1485 " for aFormula '" << aFormula <<
"'");
1491 for (sal_uInt16
i = 0;
i <
nPos;
i++)
1517 m_xEdRef->GetWidget()->set_size_request(
m_xEdRef->GetWidget()->get_preferred_size().Width(), -1);
1523 m_xEdRef->SetSelection(aOrigSelection);
1527 m_xRefBtn->GetWidget()->set_visible(pButton !=
nullptr);
1529 ::std::pair<RefButton*, RefEdit*> aPair;
1530 aPair.first = pButton ?
m_xRefBtn.get() :
nullptr;
1557 if (!bForced &&
m_xRefBtn->GetWidget()->get_visible())
1570 sal_uInt16 nPrivActiv =
m_xParaWin->GetActiveLine();
1586 const OUString sExpression =
m_xMEdit->get_text();
1609 auto aSelection =
pData->GetSelection();
1610 m_xMEdit->select_region(aSelection.Min(), aSelection.Max());
1621 m_xMEdit->select_region(PrivStart, PrivEnd);
1625 int nStartPos, nEndPos;
1626 m_xMEdit->get_selection_bounds(nStartPos, nEndPos);
1627 if (nStartPos > nEndPos)
1628 std::swap(nStartPos, nEndPos);
1640 sal_Int32 nLen = aFormula.getLength();
1641 bool bMatrix = nLen > 3
1642 && aFormula[0] ==
'{'
1643 && aFormula[1] ==
'='
1644 && aFormula[nLen-1] ==
'}';
1647 aFormula = aFormula.copy( 1, aFormula.getLength()-2 );
1658 m_bStructUpdate =
false;
1659 if (m_xStructPage->IsVisible())
1660 m_xBtnForward->set_sensitive(
false);
1661 m_bStructUpdate =
true;
1666 m_bUserMatrixFlag =
true;
1672 if ( (m_xFuncPage->GetFunctionEntryCount() > 0)
1673 && (m_xFuncPage->GetFunction() != -1) )
1677 if (pDesc != m_pFuncDesc)
1678 m_xBtnForward->set_sensitive(
true);
1686 m_xFtFuncName->set_label( aSig );
1692 m_xFtHeadLine->set_label( OUString() );
1693 m_xFtFuncName->set_label( OUString() );
1694 m_xFtFuncDesc->set_label( OUString() );
1701 m_xEdRef->GetWidget()->replace_selection(_sRefStr);
1702 theSel.
Max() = theSel.
Min() + _sRefStr.getLength();
1708 sal_uInt16 nPrivActiv =
m_xParaWin->GetActiveLine();
1727 m_xEdRef->SetSelection( _rSelection );
1731 _rSelection =
m_xEdRef->GetSelection();
1755 : GenericDialogController(pParent,
"formula/ui/formuladialog.ui",
"FormulaDialog")
1758 this, _pFunctionMgr, _pDlg))
1777 m_pImpl->CheckMatrix(aFormula);
1787 return m_pImpl->RefInputStartBefore( pEdit, pButton );
1792 m_pImpl->RefInputStartAfter();
1797 m_pImpl->RefInputDoneAfter(
true );
1813 , this, _pFunctionMgr, _pDlg))
1834 return m_pImpl->SetMeText( _sText, PrivStart, PrivEnd, bMatrix, _bSelect, _bUpdate);
1839 return m_pImpl->CheckMatrix(aFormula);
1844 return m_pImpl->m_xMEdit->get_text();
1859 return m_pImpl->RefInputStartBefore( pEdit, pButton );
1864 m_pImpl->RefInputStartAfter();
1869 m_pImpl->RefInputDoneAfter( bForced );
1874 m_pImpl->m_xBtnEnd->set_sensitive(
false);
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());
1893 m_pImpl->UpdateParaWin( _rSelection, _sRefStr);
1898 return m_pImpl->UpdateParaWin(_rSelection);
1903 return m_pImpl->m_xParaWin->GetActiveEdit();
1908 return m_pImpl->GetFormulaHelper();
Reference< XExecutableDialog > m_xDialog
static bool AnyInput(VclInputFlags nType=VCL_INPUT_ANY)
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
static sal_Int32 GetRememeberdFunctionCategory()
OUString GetEntryText(const weld::TreeIter *pEntry) const
bool InsertEntry(const OUString &rText, const weld::TreeIter *pParent, sal_uInt16 nFlag, int nPos, const FormulaToken *pIFormulaToken, weld::TreeIter &rRet)
void SetWeight(FontWeight)
std::shared_ptr< weld::Dialog > m_xDialog
virtual void set_title(const OUString &rTitle)=0
#define SC_OPCODE_STOP_BIN_OP
#define SC_OPCODE_STOP_UN_OP
#define SC_OPCODE_START_UN_OP
#define SC_OPCODE_START_BIN_OP
OUString ForResId(TranslateId aId)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
#define LINK(Instance, Class, Member)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
std::unique_ptr< sal_Int32[]> pData
double getLength(const B2DPolygon &rCandidate)