49#include <osl/diagnose.h>
70 const OUString& sGetName);
73 const OUString& sRefBoxNm,
74 const OUString& sGetStr,
118 if( !pFormulaItem->IsValid() )
144 nRet = pBoxValueItem->GetValue();
152 sal_Int32 nSttPos = 0;
153 OUString sText = pTextNd->
GetText();
156 if ( sText.getLength() > 0 &&
162 while ( nSttPos < sText.getLength() && ( sText[nSttPos]==
' ' || sText[nSttPos]==
'\t' ) )
166 const bool bOK = nSttPos<sText.getLength();
173 if ( pTextField !=
nullptr )
214 else if ( nSttPos < sText.getLength()
220 if ( pTextInputField ==
nullptr )
230 sText = bOK ? sText.copy( nSttPos ) : OUString();
236 if( nFormatType == SvNumFormatType::TEXT )
239 else if( !sText.isEmpty() &&
240 SvNumFormatType::PERCENT == nFormatType)
242 sal_uInt32 nTmpFormat = 0;
244 SvNumFormatType::NUMBER == pNumFormatr->
GetType( nTmpFormat ))
263 if( DBL_MAX == nRet )
273 : m_pLastTableBox(nullptr)
275 , m_nMaxSize( cMAXSTACKSIZE )
278 , m_rCalc( rCalculator )
279 , m_pTable( &rTable )
299 aStackOverflows.insert( aStackOverflows.begin() + nCnt++, pBox );
314 aStackOverflows[ --nCnt ]->GetValue( *
this );
320 aStackOverflows.clear();
325: m_sFormula(
std::move(aFormula) )
326, m_eNmType( EXTRNL_NAME )
327, m_bValidValue( false )
336 OUString& rFirstBox, OUString* pLastBox,
void* pPara )
const
344 rFirstBox = rFirstBox.copy(1);
348 pEndBox =
reinterpret_cast<SwTableBox*
>(sal::static_int_cast<sal_IntPtr>(pLastBox->toInt64()));
353 rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
356 sal::static_int_cast<sal_IntPtr>(rFirstBox.toInt64()));
362 if( pEndBox && pSttBox )
366 GetBoxes( *pSttBox, *pEndBox, aBoxes );
369 sal_Int16 nUseOnlyNumber = -1;
373 for (
size_t n = 0;
n < aBoxes.
size() &&
379 double fVal = pTableBox->
GetValue( *pCalcPara );
383 if ( nUseOnlyNumber == -1 )
385 OUString
sFormula = rNewStr.toString().toAsciiUpperCase();
386 nUseOnlyNumber = sal_Int16(
387 sFormula.lastIndexOf(
"AVERAGE") > -1 ||
388 sFormula.lastIndexOf(
"COUNT") > -1 ||
389 sFormula.lastIndexOf(
"PRODUCT") > -1 );
391 if ( nUseOnlyNumber > 0 )
403 else if( pSttBox && !pLastBox )
410 double fVal = pSttBox->
GetValue( *pCalcPara );
414 ( rNewStr.toString().toAsciiUpperCase().lastIndexOf(
"AVERAGE") == -1 &&
415 rNewStr.toString().toAsciiUpperCase().lastIndexOf(
"COUNT") == -1 ) )
428 OUString& rFirstBox, OUString* pLastBox,
void* pPara )
const
432 OSL_ENSURE( pNd,
"Field isn't in any TextNode" );
436 rNewStr.append(rFirstBox[0]);
437 rFirstBox = rFirstBox.copy(1);
442 rNewStr.append(pRelLastBox->
GetName());
444 rNewStr.append(
"A1");
446 rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
452 rNewStr.append(pRelFirstBox->
GetName());
454 rNewStr.append(
"A1");
457 rNewStr.append(rFirstBox[ rFirstBox.getLength()-1 ]);
461 OUString& rFirstBox, OUString* pLastBox,
void* pPara )
const
465 OSL_ENSURE( pNd,
"Field not placed in any Node" );
469 rNewStr.append(rFirstBox[0]);
470 rFirstBox = rFirstBox.copy(1);
475 rNewStr.append(
reinterpret_cast<sal_IntPtr
>(pRelLastBox));
479 rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
484 rNewStr.append(
reinterpret_cast<sal_IntPtr
>(pRelFirstBox));
489 rNewStr.append(rFirstBox[ rFirstBox.getLength()-1 ]);
493 OUString& rFirstBox, OUString* pLastBox,
void* pPara )
const
497 OSL_ENSURE( pNd,
"Field not placed in any Node" );
501 if( &pTableNd->
GetTable() == &rTable )
505 OSL_ENSURE( pBox,
"Field not placed in any Table" );
509 rNewStr.append(rFirstBox[0]);
510 rFirstBox = rFirstBox.copy(1);
513 rNewStr.append(
lcl_BoxNmToRel( rTable, *pTableNd, sRefBoxNm, *pLastBox,
516 rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
519 rNewStr.append(
lcl_BoxNmToRel( rTable, *pTableNd, sRefBoxNm, rFirstBox,
523 rNewStr.append(rFirstBox[ rFirstBox.getLength()-1 ]);
527 OUString& rFirstBox, OUString* pLastBox,
void* )
const
532 rNewStr.append(rFirstBox[0]);
533 rFirstBox = rFirstBox.copy(1);
536 pBox =
reinterpret_cast<SwTableBox*
>(sal::static_int_cast<sal_IntPtr>(pLastBox->toInt64()));
540 rNewStr.append(pBox->
GetName());
544 rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
547 pBox =
reinterpret_cast<SwTableBox*
>(sal::static_int_cast<sal_IntPtr>(rFirstBox.toInt64()));
550 rNewStr.append(pBox->
GetName());
555 rNewStr.append(rFirstBox[ rFirstBox.getLength()-1 ]);
559 OUString& rFirstBox, OUString* pLastBox,
void* )
const
564 rNewStr.append(rFirstBox[0]);
565 rFirstBox = rFirstBox.copy(1);
569 rNewStr.append(OUString::number(
reinterpret_cast<sal_IntPtr
>(pBox)) +
571 rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
575 rNewStr.append(OUString::number(
reinterpret_cast<sal_IntPtr
>(pBox))
576 + OUStringChar(rFirstBox[ rFirstBox.getLength()-1 ]));
582 const SwNode* pNd =
nullptr;
600 m_sFormula =
ScanString( fnFormula, *pTable,
const_cast<void*
>(
static_cast<void const *
>(pNd)) );
607 const SwNode* pNd =
nullptr;
625 m_sFormula =
ScanString( fnFormula, *pTable,
const_cast<void*
>(
static_cast<void const *
>(pNd)) );
632 const SwNode* pNd =
nullptr;
647 m_sFormula =
ScanString( fnFormula, *pTable,
const_cast<void*
>(
static_cast<void const *
>(pNd)) );
655 sal_Int32 nFormula = 0;
660 const SwTable* pTable = &rTable;
662 sal_Int32 nStt =
m_sFormula.indexOf(
'<', nFormula );
667 const sal_Int32 nNxt = nStt+1;
682 if (nStt<0 || nEnd<0 )
694 sal_Int32 nSeparator = 0;
701 (nSeparator =
m_sFormula.indexOf(
'.', nStt ))>=0
702 && nSeparator < nEnd )
704 OUString sTableNm(
m_sFormula.copy( nStt, nEnd - nStt ));
709 sTableNm = sTableNm.copy( 0, nSeparator - nStt );
713 aStr.append(sTableNm);
716 sTableNm = sTableNm.copy( 1 );
726 OSL_ENSURE( pFnd,
"No table found. What now?" );
731 OUString sBox(
m_sFormula.copy( nStt, nEnd - nStt + 1 ));
734 if ( nSeparator>=0 && nSeparator<nEnd )
737 OUString aFirstBox(
m_sFormula.copy( nStt+1, nSeparator - nStt - 1 ));
738 (this->*fnFormula)( *pTable,
aStr, sBox, &aFirstBox, pPara );
741 (this->*fnFormula)( *pTable,
aStr, sBox,
nullptr, pPara );
746 return aStr.makeStringAndClear();
752 const SwTable* pTmpTable =
nullptr, *pRet =
nullptr;
753 for(
auto nFormatCnt = rTableFormats.
size(); nFormatCnt; )
776 OSL_ENSURE( pCNd,
"Box has no TextNode" );
778 std::pair<Point, bool>
const tmp(aPt,
false);
785 const sal_Int32
nPos = rStr.indexOf( cRelSeparator );
788 nRet = rStr.toInt32();
794 rStr = rStr.copy(
nPos+1 );
801 const OUString& _sGetName )
805 OUString sGetName = _sGetName;
808 if ( cRelIdentifier == sGetName[0] )
813 sGetName = sGetName.copy( 1 );
827 sal_uInt16 nSttBox = pLine->
GetBoxPos( pBox );
833 if( nBoxOffset < 0 ||
840 pLine = (*pLines)[ nLineOffset ];
846 pBox = (*pBoxes)[ nBoxOffset ];
848 while (!sGetName.isEmpty())
858 if( !nSttLine || nSttLine > pLines->
size() )
860 pLine = (*pLines)[ nSttLine-1 ];
864 if( nSttBox >= pBoxes->size() )
866 pBox = (*pBoxes)[ nSttBox ];
886 const OUString& _sRefBoxNm,
const OUString& _sTmp,
bool bExtrnlNm )
888 OUString sTmp = _sTmp;
889 OUString sRefBoxNm = _sRefBoxNm;
893 SwTableBox* pBox =
reinterpret_cast<SwTableBox*
>(sal::static_int_cast<sal_IntPtr>(sTmp.toInt64()));
895 return OUString(
'?');
900 if( &rTable == &rTableNd.
GetTable() )
907 const OUString sCpy = sTmp;
909 sTmp = OUStringChar(cRelIdentifier) + OUString::number( nBox )
910 + OUStringChar(cRelSeparator) + OUString::number( nLine );
914 sTmp += OUStringChar(cRelSeparator) + sCpy;
918 if (sTmp.endsWith(
">"))
919 return sTmp.copy(0, sTmp.getLength()-1 );
934 OUString& rFirstBox, OUString* pLastBox,
void* pPara )
const
939 rFirstBox = rFirstBox.copy(1);
943 pEndBox =
reinterpret_cast<SwTableBox*
>(sal::static_int_cast<sal_IntPtr>(pLastBox->toInt64()));
948 rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
951 SwTableBox *pSttBox =
reinterpret_cast<SwTableBox*
>(sal::static_int_cast<sal_IntPtr>(rFirstBox.toInt64()));
960 GetBoxes( *pSttBox, *pEndBox, aBoxes );
964 pBoxes->
insert( pSttBox );
974 pStt = pFrame ? pFrame->
GetUpper() :
nullptr;
976 pEnd = pFrame ? pFrame->
GetUpper() :
nullptr;
1007 if (pStartTable == pEndTable)
1011 for (
size_t n = 0;
n < rBoxes.
size(); ++
n)
1013 pLine = rBoxes[
n]->GetUpper();
1025 OUString& rFirstBox, OUString* pLastBox,
void* pPara )
const
1027 bool* pBValid =
static_cast<bool*
>(pPara);
1031 SwTableBox* pSttBox =
nullptr, *pEndBox =
nullptr;
1032 rFirstBox = rFirstBox.copy(1);
1036 rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
1042 pEndBox =
reinterpret_cast<SwTableBox*
>(sal::static_int_cast<sal_IntPtr>(pLastBox->toInt64()));
1043 pSttBox =
reinterpret_cast<SwTableBox*
>(sal::static_int_cast<sal_IntPtr>(rFirstBox.toInt64()));
1078 static_cast<const SwTableNode*
>(pNd)->GetTable(), &bRet );
1084 sal_uInt16 nRet = USHRT_MAX;
1096 OUString& rFirstBox, OUString* pLastBox,
void* pPara )
const
1100 rNewStr.append(rFirstBox[0]);
1101 rFirstBox = rFirstBox.copy(1);
1104 const SwTable* pTable = &rTable;
1106 OUString* pTableNmBox = pLastBox ? pLastBox : &rFirstBox;
1108 const sal_Int32 nLastBoxLen = pTableNmBox->getLength();
1109 const sal_Int32 nSeparator = pTableNmBox->indexOf(
'.');
1110 if ( nSeparator>=0 &&
1114 sTableNm = pTableNmBox->copy( 0, nSeparator );
1115 *pTableNmBox = pTableNmBox->copy( nSeparator + 1);
1126 if( rTableUpd.
m_pTable != &rTable )
1130 else if( pFnd != rTableUpd.
m_pTable ||
1132 rNewStr.append(sTableNm +
".");
1137 rNewStr.append(sTableNm +
".");
1140 if( pTableNmBox == pLastBox )
1141 rFirstBox = rFirstBox.copy( nLastBoxLen + 1 );
1143 SwTableBox* pSttBox =
nullptr, *pEndBox =
nullptr;
1148 pEndBox =
reinterpret_cast<SwTableBox*
>(sal::static_int_cast<sal_IntPtr>(pLastBox->toInt64()));
1149 pSttBox =
reinterpret_cast<SwTableBox*
>(sal::static_int_cast<sal_IntPtr>(rFirstBox.toInt64()));
1178 bool bInNewTable =
false;
1186 if( USHRT_MAX != nSttLnPos && USHRT_MAX != nEndLnPos &&
1199 bInNewTable = USHRT_MAX != nEndLnPos &&
1208 bInNewTable = USHRT_MAX != nSttLnPos &&
1221 else if( !sTableNm.isEmpty() )
1222 rNewStr.append(sTableNm +
".");
1224 else if( bInNewTable )
1229 else if( !sTableNm.isEmpty() )
1230 rNewStr.append(sTableNm +
".");
1234 rNewStr.append(OUString::number(
reinterpret_cast<sal_IntPtr
>(pEndBox)) +
":");
1236 rNewStr.append(OUString::number(
reinterpret_cast<sal_IntPtr
>(pSttBox))
1237 + OUStringChar(rFirstBox[ rFirstBox.getLength()-1] ));
1246 pTable = &
static_cast<const SwTableNode*
>(pNd)->GetTable();
const sal_Unicode cListDelim
static OUString lcl_BoxNmToRel(const SwTable &rTable, const SwTableNode &rTableNd, const OUString &sRefBoxNm, const OUString &sGetStr, bool bExtrnlNm)
static const SwTableBox * lcl_RelToBox(const SwTable &rTable, const SwTableBox *pRefBox, const OUString &sGetName)
static sal_Int32 lcl_GetLongBoxNum(OUString &rStr)
static const SwFrame * lcl_GetBoxFrame(const SwTableBox &rBox)
sal_uInt32 GetValue() const
virtual const SwRootFrame * GetCurrentLayout() const =0
OUString GetStrResult(const SwSbxValue &rValue)
void SetCalcError(SwCalcError eErr)
SwSbxValue Calculate(const OUString &rStr)
bool IsCalcNotANumber() const
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
const sw::TableFrameFormats * GetTableFrameFormats() const
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
const SwAttrPool & GetAttrPool() const
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
bool IsNumberFormat(const OUString &aString, sal_uInt32 &F_Index, double &fOutNumber)
Base class of all fields.
OUString ExpandField(bool bCached, SwRootFrame const *pLayout) const
expand the field.
SwFieldType * GetTyp() const
Base class of the Writer layout elements.
SwTabFrame * FindTabFrame()
SwLayoutFrame * GetUpper()
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame.
Marks a node in the document model.
const SwNodes & GetNodes() const
Base class of the Writer document model elements.
SwNodeOffset GetIndex() const
const SwStartNode * FindTableBoxStartNode() const
SwNodes & GetNodes()
Node is in which nodes-array/doc?
SwTableNode * FindTableNode()
Search table node, in which it is.
bool IsDocNodes() const
Is the NodesArray the regular one of Doc? (and not the UndoNds, ...) Implementation in doc....
SwContentNode * GoNext(SwNodeIndex *) const
The root element of a Writer document layout.
SwTabFrame is one table in the document layout, containing rows (which contain cells).
const SwTable * GetTable() const
SwTableBox is one table cell in the document model.
sal_Int32 getRowSpan() const
const SwStartNode * m_pStartNode
SwFrameFormat * GetFrameFormat()
SwTableLines & GetTabLines()
const SwStartNode * GetSttNd() const
double GetValue(SwTableCalcPara &rPara) const
Get value of this box.
SwFrameFormat * ClaimFrameFormat()
SwCalc & m_rCalc
current Calculator
SwTableCalcPara(SwCalc &rCalculator, const SwTable &rTable, SwRootFrame const *pLayout)
void SetLastTableBox(const SwTableBox *pBox)
const SwTableBox * m_pLastTableBox
bool CalcWithStackOverflow()
std::unique_ptr< SwTableSortBoxes > m_pBoxStack
stack for recognizing recursion
const SwTable * m_pTable
current table
bool IsStackOverflow() const
SwRootFrame const *const m_pLayout
layout to access text field results
void CalcField(SwTableCalcPara &rCalcPara)
SwTableLine is one table row in the document model.
SwTableBoxes & GetTabBoxes()
sal_uInt16 GetBoxPos(const SwTableBox *pBox) const
SwTableLine * front() const
sal_uInt16 GetPos(const SwTableLine *pBox) const
const SwTable & GetTable() const
SwTable is one table in the document model, containing rows (which contain cells).
SwTableLines & GetTabLines()
bool IsHeadline(const SwTableLine &rLine) const
SwTableFormat * GetFrameFormat()
const SwTableBox * GetTableBox(const OUString &rName, const bool bPerformValidCheck=false) const
static SwTable * FindTable(SwFrameFormat const *const pFormat)
static sal_uInt16 GetBoxNum(OUString &rStr, bool bFirst=false, const bool bPerformValidCheck=false)
sal_uInt16 GetRowsToRepeat() const
SwTableSortBoxes & GetTabSortBoxes()
const SwFormatField & GetFormatField() const
OUString GetFieldContent() const
SwTextNode is a paragraph in the document model.
SwTextAttr * GetTextAttrAt(sal_Int32 const nIndex, sal_uInt16 const nWhich, ::sw::GetTextAttrMode const eMode=::sw::GetTextAttrMode::Default) const
get the innermost text attribute covering position nIndex.
const OUString & GetText() const
OUString GetRedlineText() const
SwTextAttr * GetTextAttrForCharAt(const sal_Int32 nIndex, const sal_uInt16 nWhich=RES_TXTATR_END) const
get the text attribute at position nIndex which owns the dummy character CH_TXTATR_* at that position...
The non-shared part of a user field.
virtual double GetValue() const
const_iterator begin() const
const_iterator find(const Value &x) const
size_type erase(const Value &x)
const_iterator end() const
std::pair< const_iterator, bool > insert(Value &&x)
#define CH_TXT_ATR_INPUTFIELDSTART
constexpr sal_uInt16 RES_BOXATR_END(159)
constexpr TypedWhichId< SwTableBoxValue > RES_BOXATR_VALUE(158)
constexpr TypedWhichId< SwTableBoxFormula > RES_BOXATR_FORMULA(157)
constexpr sal_uInt16 RES_BOXATR_BEGIN(RES_GRFATR_END)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
constexpr TypedWhichId< SwTableBoxNumFormat > RES_BOXATR_FORMAT(RES_BOXATR_BEGIN)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_INPUTFIELD(55)
#define CH_TXTATR_BREAKWORD
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
std::vector< SwTableBox * > SwTableBoxes
void GetTableSel(const SwCursorShell &rShell, SwSelBoxes &rBoxes, const SwTableSearchType eSearchType)