LibreOffice Module sw (master)  1
cellfml.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 <sal/config.h>
21 
22 #include <string_view>
23 
24 #include <float.h>
25 #include <hintids.hxx>
26 #include <hints.hxx>
27 #include <fmtfld.hxx>
28 #include <txtfld.hxx>
29 #include <frmfmt.hxx>
30 #include <layfrm.hxx>
31 #include <cntfrm.hxx>
32 #include <tabfrm.hxx>
33 #include <doc.hxx>
35 #include <docary.hxx>
36 #include <ndtxt.hxx>
37 #include <swtable.hxx>
38 #include <tblsel.hxx>
39 #include <cellfml.hxx>
40 #include <calc.hxx>
41 #include <expfld.hxx>
42 #include <usrfld.hxx>
43 #include <flddat.hxx>
44 #include <cellatr.hxx>
45 #include <ndindex.hxx>
46 #include <comphelper/string.hxx>
47 #include <o3tl/safeint.hxx>
48 
49 namespace
50 {
51 
52 const sal_Unicode cRelSeparator = ',';
53 const sal_Unicode cRelIdentifier = '\x12'; // CTRL-R
54 
55 enum
56 {
57  cMAXSTACKSIZE = 50
58 };
59 
60 }
61 
62 static const SwFrame* lcl_GetBoxFrame( const SwTableBox& rBox );
63 static sal_Int32 lcl_GetLongBoxNum( OUString& rStr );
64 static const SwTableBox* lcl_RelToBox( const SwTable& rTable,
65  const SwTableBox* pRefBox,
66  const OUString& sGetName);
67 static OUString lcl_BoxNmToRel( const SwTable& rTable,
68  const SwTableNode& rTableNd,
69  const OUString& sRefBoxNm,
70  const OUString& sGetStr,
71  bool bExtrnlNm);
72 
79 double SwTableBox::GetValue( SwTableCalcPara& rCalcPara ) const
80 {
81  double nRet = 0;
82 
83  if( rCalcPara.m_rCalc.IsCalcError() )
84  return nRet; // stop if there is already an error set
85 
86  rCalcPara.m_rCalc.SetCalcError( SwCalcError::Syntax ); // default: error
87 
88  // no content box?
89  if( !m_pStartNode )
90  return nRet;
91 
92  if( rCalcPara.IncStackCnt() )
93  return nRet;
94 
95  rCalcPara.SetLastTableBox( this );
96 
97  // Does it create a recursion?
98  SwTableBox* pBox = const_cast<SwTableBox*>(this);
99  if( rCalcPara.m_pBoxStack->find( pBox ) != rCalcPara.m_pBoxStack->end() )
100  return nRet; // already on the stack: error
101 
102  // re-start with this box
103  rCalcPara.SetLastTableBox( this );
104 
105  rCalcPara.m_pBoxStack->insert( pBox ); // add
106  do { // Middle-Check-Loop, so that we can jump from here. Used so that the box pointer
107  // will be removed from stack at the end.
108  SwDoc* pDoc = GetFrameFormat()->GetDoc();
109 
110  const SfxPoolItem* pItem;
111  if( SfxItemState::SET == GetFrameFormat()->GetItemState(
112  RES_BOXATR_FORMULA, false, &pItem ) )
113  {
114  rCalcPara.m_rCalc.SetCalcError( SwCalcError::NONE ); // reset status
115  if( !static_cast<const SwTableBoxFormula*>(pItem)->IsValid() )
116  {
117  // calculate
118  const SwTable* pTmp = rCalcPara.m_pTable;
119  rCalcPara.m_pTable = &pBox->GetSttNd()->FindTableNode()->GetTable();
120  const_cast<SwTableBoxFormula*>(static_cast<const SwTableBoxFormula*>(pItem))->Calc( rCalcPara, nRet );
121 
122  if( !rCalcPara.IsStackOverflow() )
123  {
124  SwFrameFormat* pFormat = pBox->ClaimFrameFormat();
125  SfxItemSet aTmp( pDoc->GetAttrPool(),
127  aTmp.Put( SwTableBoxValue( nRet ) );
128  if( SfxItemState::SET != pFormat->GetItemState( RES_BOXATR_FORMAT ))
129  aTmp.Put( SwTableBoxNumFormat( 0 ));
130  pFormat->SetFormatAttr( aTmp );
131  }
132  rCalcPara.m_pTable = pTmp;
133  }
134  else
136  break;
137  }
138  else if( SfxItemState::SET == pBox->GetFrameFormat()->GetItemState(
139  RES_BOXATR_VALUE, false, &pItem ) )
140  {
141  rCalcPara.m_rCalc.SetCalcError( SwCalcError::NONE ); // reset status
142  nRet = static_cast<const SwTableBoxValue*>(pItem)->GetValue();
143  break;
144  }
145 
146  SwTextNode* pTextNd = pDoc->GetNodes()[ m_pStartNode->GetIndex() + 1 ]->GetTextNode();
147  if( !pTextNd )
148  break;
149 
150  sal_Int32 nSttPos = 0;
151  OUString sText = pTextNd->GetText();
152  while ( nSttPos < sText.getLength() && ( sText[nSttPos]==' ' || sText[nSttPos]=='\t' ) )
153  ++nSttPos;
154 
155  // if there is a calculation field at position 1, get the value of it
156  const bool bOK = nSttPos<sText.getLength();
157  const sal_Unicode Char = bOK ? sText[nSttPos] : 0;
158  SwTextField * pTextField = nullptr;
159  if ( bOK && (Char==CH_TXTATR_BREAKWORD || Char==CH_TXTATR_INWORD) )
160  {
161  pTextField = static_txtattr_cast<SwTextField*>(pTextNd->GetTextAttrForCharAt(nSttPos, RES_TXTATR_FIELD));
162  }
163  if ( pTextField != nullptr )
164  {
165  rCalcPara.m_rCalc.SetCalcError( SwCalcError::NONE ); // reset status
166 
167  const SwField* pField = pTextField->GetFormatField().GetField();
168  switch ( pField->GetTyp()->Which() )
169  {
170  case SwFieldIds::SetExp:
171  nRet = static_cast<const SwSetExpField*>(pField)->GetValue(rCalcPara.m_pLayout);
172  break;
173  case SwFieldIds::User:
174  nRet = static_cast<const SwUserField*>(pField)->GetValue();
175  break;
176  case SwFieldIds::Table:
177  {
178  SwTableField* pTableField = const_cast<SwTableField*>(static_cast<const SwTableField*>(pField));
179  if( !pTableField->IsValid() )
180  {
181  // use the right table!
182  const SwTable* pTmp = rCalcPara.m_pTable;
183  rCalcPara.m_pTable = &pTextNd->FindTableNode()->GetTable();
184  pTableField->CalcField( rCalcPara );
185  rCalcPara.m_pTable = pTmp;
186  }
187  nRet = pTableField->GetValue();
188  }
189  break;
190 
192  nRet = static_cast<const SwDateTimeField*>( pField )->GetValue();
193  break;
194 
196  //JP 14.09.98: Bug 56112 - placeholder never have the right content!
197  nRet = 0;
198  break;
199 
200  default:
201  nRet = rCalcPara.m_rCalc.Calculate( pField->ExpandField(true, nullptr) ).GetDouble();
202  }
203  }
204  else if ( nSttPos < sText.getLength()
205  && Char == CH_TXT_ATR_INPUTFIELDSTART )
206  {
207  const SwTextInputField * pTextInputField =
208  dynamic_cast< const SwTextInputField* >(
209  pTextNd->GetTextAttrAt( nSttPos, RES_TXTATR_INPUTFIELD ) );
210  if ( pTextInputField == nullptr )
211  break;
212  nRet = rCalcPara.m_rCalc.Calculate( pTextInputField->GetFieldContent() ).GetDouble();
213  }
214  else if ( Char != CH_TXTATR_BREAKWORD )
215  {
216  // result is 0 but no error!
217  rCalcPara.m_rCalc.SetCalcError( SwCalcError::NONE ); // reset status
218 
219  double aNum = 0.0;
220  sText = bOK ? sText.copy( nSttPos ) : OUString();
221  sal_uInt32 nFormatIndex = GetFrameFormat()->GetTableBoxNumFormat().GetValue();
222 
223  SvNumberFormatter* pNumFormatr = pDoc->GetNumberFormatter();
224 
225  const SvNumFormatType nFormatType = pNumFormatr->GetType( nFormatIndex );
226  if( nFormatType == SvNumFormatType::TEXT )
227  nFormatIndex = 0;
228  // JP 22.04.98: Bug 49659 - special treatment for percentages
229  else if( !sText.isEmpty() &&
230  SvNumFormatType::PERCENT == nFormatType)
231  {
232  sal_uInt32 nTmpFormat = 0;
233  if( pDoc->IsNumberFormat( sText, nTmpFormat, aNum ) &&
234  SvNumFormatType::NUMBER == pNumFormatr->GetType( nTmpFormat ))
235  sText += "%";
236  }
237 
238  if( pDoc->IsNumberFormat( sText, nFormatIndex, aNum ))
239  nRet = aNum;
240  }
241  // ?? otherwise it is an error
242  } while( false );
243 
244  if( !rCalcPara.IsStackOverflow() )
245  {
246  rCalcPara.m_pBoxStack->erase( pBox ); // remove from stack
247  rCalcPara.DecStackCnt();
248  }
249 
250  //JP 12.01.99: error detection, Bug 60794
251  if( DBL_MAX == nRet )
252  rCalcPara.m_rCalc.SetCalcError( SwCalcError::Syntax ); // set error
253 
254  return nRet;
255 }
256 
257 // structure needed for calculation of tables
258 
259 SwTableCalcPara::SwTableCalcPara(SwCalc& rCalculator, const SwTable& rTable,
260  SwRootFrame const*const pLayout)
261  : m_pLastTableBox(nullptr)
262  , m_nStackCount( 0 )
263  , m_nMaxSize( cMAXSTACKSIZE )
264  , m_pLayout(pLayout)
265  , m_pBoxStack( new SwTableSortBoxes )
266  , m_rCalc( rCalculator )
267  , m_pTable( &rTable )
268 {
269 }
270 
272 {
273 }
274 
276 {
277  // If a stack overflow was detected, redo with last box.
278  sal_uInt16 nSaveMaxSize = m_nMaxSize;
279 
280  m_nMaxSize = cMAXSTACKSIZE - 5;
281  sal_uInt16 nCnt = 0;
282  SwTableBoxes aStackOverflows;
283  do {
284  SwTableBox* pBox = const_cast<SwTableBox*>(m_pLastTableBox);
285  m_nStackCount = 0;
287  aStackOverflows.insert( aStackOverflows.begin() + nCnt++, pBox );
288 
289  m_pBoxStack->erase( pBox );
290  pBox->GetValue( *this );
291  } while( IsStackOverflow() );
292 
293  m_nMaxSize = cMAXSTACKSIZE - 3; // decrease at least one level
294 
295  // if recursion was detected
296  m_nStackCount = 0;
298  m_pBoxStack->clear();
299 
300  while( !m_rCalc.IsCalcError() && nCnt )
301  {
302  aStackOverflows[ --nCnt ]->GetValue( *this );
304  break;
305  }
306 
307  m_nMaxSize = nSaveMaxSize;
308  aStackOverflows.clear();
309  return !m_rCalc.IsCalcError();
310 }
311 
312 SwTableFormula::SwTableFormula( const OUString& rFormula )
313 : m_sFormula( rFormula )
314 , m_eNmType( EXTRNL_NAME )
315 , m_bValidValue( false )
316 {
317 }
318 
320 {
321 }
322 
323 void SwTableFormula::MakeFormula_( const SwTable& rTable, OUStringBuffer& rNewStr,
324  OUString& rFirstBox, OUString* pLastBox, void* pPara ) const
325 {
326  SwTableCalcPara* pCalcPara = static_cast<SwTableCalcPara*>(pPara);
327  if( pCalcPara->m_rCalc.IsCalcError() ) // stop if there is already an error set
328  return;
329 
330  SwTableBox *pEndBox = nullptr;
331 
332  rFirstBox = rFirstBox.copy(1); // erase label of this box
333  // a region in this area?
334  if( pLastBox )
335  {
336  pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->toInt64()));
337 
338  // Is it actually a valid pointer?
339  if( rTable.GetTabSortBoxes().find( pEndBox ) == rTable.GetTabSortBoxes().end() )
340  pEndBox = nullptr;
341  rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
342  }
343  SwTableBox* pSttBox = reinterpret_cast<SwTableBox*>(
344  sal::static_int_cast<sal_IntPtr>(rFirstBox.toInt64()));
345  // Is it actually a valid pointer?
346  if( rTable.GetTabSortBoxes().find( pSttBox ) == rTable.GetTabSortBoxes().end() )
347  pSttBox = nullptr;
348 
349  rNewStr.append(" ");
350  if( pEndBox && pSttBox ) // area?
351  {
352  // get all selected boxes via layout and calculate their values
353  SwSelBoxes aBoxes;
354  GetBoxes( *pSttBox, *pEndBox, aBoxes );
355 
356  rNewStr.append("(");
357  bool bDelim = false;
358  for (size_t n = 0; n < aBoxes.size() &&
359  !pCalcPara->m_rCalc.IsCalcError(); ++n)
360  {
361  const SwTableBox* pTableBox = aBoxes[n];
362  if ( pTableBox->getRowSpan() >= 1 )
363  {
364  if( bDelim )
365  rNewStr.append(cListDelim);
366  bDelim = true;
367  rNewStr.append(pCalcPara->m_rCalc.GetStrResult(
368  pTableBox->GetValue( *pCalcPara ) ));
369  }
370  }
371  rNewStr.append(")");
372  }
373  else if( pSttBox && !pLastBox ) // only the StartBox?
374  {
375  // JP 12.01.99: and no EndBox in the formula!
376  // calculate the value of the box
377  if ( pSttBox->getRowSpan() >= 1 )
378  {
379  rNewStr.append("(");
380  rNewStr.append(pCalcPara->m_rCalc.GetStrResult(
381  pSttBox->GetValue( *pCalcPara ) ));
382  rNewStr.append(")");
383  }
384  }
385  else
386  pCalcPara->m_rCalc.SetCalcError( SwCalcError::Syntax ); // set error
387  rNewStr.append(" ");
388 }
389 
390 void SwTableFormula::RelNmsToBoxNms( const SwTable& rTable, OUStringBuffer& rNewStr,
391  OUString& rFirstBox, OUString* pLastBox, void* pPara ) const
392 {
393  // relative name w.r.t. box name (external presentation)
394  SwNode* pNd = static_cast<SwNode*>(pPara);
395  OSL_ENSURE( pNd, "Field isn't in any TextNode" );
396  const SwTableBox *pBox = rTable.GetTableBox(
397  pNd->FindTableBoxStartNode()->GetIndex() );
398 
399  rNewStr.append(rFirstBox[0]); // get label for the box
400  rFirstBox = rFirstBox.copy(1);
401  if( pLastBox )
402  {
403  const SwTableBox *pRelLastBox = lcl_RelToBox( rTable, pBox, *pLastBox );
404  if ( pRelLastBox )
405  rNewStr.append(pRelLastBox->GetName());
406  else
407  rNewStr.append("A1");
408  rNewStr.append(":");
409  rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
410  }
411 
412  const SwTableBox *pRelFirstBox = lcl_RelToBox( rTable, pBox, rFirstBox );
413 
414  if (pRelFirstBox)
415  rNewStr.append(pRelFirstBox->GetName());
416  else
417  rNewStr.append("A1");
418 
419  // get label for the box
420  rNewStr.append(rFirstBox[ rFirstBox.getLength()-1 ]);
421 }
422 
423 void SwTableFormula::RelBoxNmsToPtr( const SwTable& rTable, OUStringBuffer& rNewStr,
424  OUString& rFirstBox, OUString* pLastBox, void* pPara ) const
425 {
426  // relative name w.r.t. box name (internal presentation)
427  SwNode* pNd = static_cast<SwNode*>(pPara);
428  OSL_ENSURE( pNd, "Field not placed in any Node" );
429  const SwTableBox *pBox = rTable.GetTableBox(
430  pNd->FindTableBoxStartNode()->GetIndex() );
431 
432  rNewStr.append(rFirstBox[0]); // get label for the box
433  rFirstBox = rFirstBox.copy(1);
434  if( pLastBox )
435  {
436  const SwTableBox *pRelLastBox = lcl_RelToBox( rTable, pBox, *pLastBox );
437  if ( pRelLastBox )
438  rNewStr.append(OUString::number(reinterpret_cast<sal_PtrDiff>(pRelLastBox)));
439  else
440  rNewStr.append("0");
441  rNewStr.append(":");
442  rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
443  }
444 
445  const SwTableBox *pRelFirstBox = lcl_RelToBox( rTable, pBox, rFirstBox );
446  if ( pRelFirstBox )
447  rNewStr.append(OUString::number(reinterpret_cast<sal_PtrDiff>(pRelFirstBox)));
448  else
449  rNewStr.append("0");
450 
451  // get label for the box
452  rNewStr.append(rFirstBox[ rFirstBox.getLength()-1 ]);
453 }
454 
455 void SwTableFormula::BoxNmsToRelNm( const SwTable& rTable, OUStringBuffer& rNewStr,
456  OUString& rFirstBox, OUString* pLastBox, void* pPara ) const
457 {
458  // box name (external presentation) w.r.t. relative name
459  SwNode* pNd = static_cast<SwNode*>(pPara);
460  OSL_ENSURE( pNd, "Field not placed in any Node" );
461  const SwTableNode* pTableNd = pNd->FindTableNode();
462 
463  OUString sRefBoxNm;
464  if( &pTableNd->GetTable() == &rTable )
465  {
466  const SwTableBox *pBox = rTable.GetTableBox(
467  pNd->FindTableBoxStartNode()->GetIndex() );
468  OSL_ENSURE( pBox, "Field not placed in any Table" );
469  sRefBoxNm = pBox->GetName();
470  }
471 
472  rNewStr.append(rFirstBox[0]); // get label for the box
473  rFirstBox = rFirstBox.copy(1);
474  if( pLastBox )
475  {
476  rNewStr.append(lcl_BoxNmToRel( rTable, *pTableNd, sRefBoxNm, *pLastBox,
477  m_eNmType == EXTRNL_NAME ));
478  rNewStr.append(":");
479  rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
480  }
481 
482  rNewStr.append(lcl_BoxNmToRel( rTable, *pTableNd, sRefBoxNm, rFirstBox,
483  m_eNmType == EXTRNL_NAME ));
484 
485  // get label for the box
486  rNewStr.append(rFirstBox[ rFirstBox.getLength()-1 ]);
487 }
488 
489 void SwTableFormula::PtrToBoxNms( const SwTable& rTable, OUStringBuffer& rNewStr,
490  OUString& rFirstBox, OUString* pLastBox, void* ) const
491 {
492  // area in these parentheses?
493  SwTableBox* pBox;
494 
495  rNewStr.append(rFirstBox[0]); // get label for the box
496  rFirstBox = rFirstBox.copy(1);
497  if( pLastBox )
498  {
499  pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->toInt64()));
500 
501  // Is it actually a valid pointer?
502  if( rTable.GetTabSortBoxes().find( pBox ) != rTable.GetTabSortBoxes().end() )
503  rNewStr.append(pBox->GetName());
504  else
505  rNewStr.append("?");
506  rNewStr.append(":");
507  rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
508  }
509 
510  pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.toInt64()));
511  // Is it actually a valid pointer?
512  if( rTable.GetTabSortBoxes().find( pBox ) != rTable.GetTabSortBoxes().end() )
513  rNewStr.append(pBox->GetName());
514  else
515  rNewStr.append("?");
516 
517  // get label for the box
518  rNewStr.append(rFirstBox[ rFirstBox.getLength()-1 ]);
519 }
520 
521 void SwTableFormula::BoxNmsToPtr( const SwTable& rTable, OUStringBuffer& rNewStr,
522  OUString& rFirstBox, OUString* pLastBox, void* ) const
523 {
524  // area in these parentheses?
525  const SwTableBox* pBox;
526 
527  rNewStr.append(rFirstBox[0]); // get label for the box
528  rFirstBox = rFirstBox.copy(1);
529  if( pLastBox )
530  {
531  pBox = rTable.GetTableBox( *pLastBox );
532  rNewStr.append(OUString::number(reinterpret_cast<sal_PtrDiff>(pBox)))
533  .append(":");
534  rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
535  }
536 
537  pBox = rTable.GetTableBox( rFirstBox );
538  rNewStr.append(OUString::number(reinterpret_cast<sal_PtrDiff>(pBox)))
539  .append(rFirstBox[ rFirstBox.getLength()-1 ]); // get label for the box
540 }
541 
543 void SwTableFormula::PtrToBoxNm( const SwTable* pTable )
544 {
545  const SwNode* pNd = nullptr;
546  FnScanFormula fnFormula = nullptr;
547  switch (m_eNmType)
548  {
549  case INTRNL_NAME:
550  if( pTable )
551  fnFormula = &SwTableFormula::PtrToBoxNms;
552  break;
553  case REL_NAME:
554  if( pTable )
555  {
556  fnFormula = &SwTableFormula::RelNmsToBoxNms;
557  pNd = GetNodeOfFormula();
558  }
559  break;
560  case EXTRNL_NAME:
561  return;
562  }
563  m_sFormula = ScanString( fnFormula, *pTable, const_cast<void*>(static_cast<void const *>(pNd)) );
565 }
566 
568 void SwTableFormula::BoxNmToPtr( const SwTable* pTable )
569 {
570  const SwNode* pNd = nullptr;
571  FnScanFormula fnFormula = nullptr;
572  switch (m_eNmType)
573  {
574  case EXTRNL_NAME:
575  if( pTable )
576  fnFormula = &SwTableFormula::BoxNmsToPtr;
577  break;
578  case REL_NAME:
579  if( pTable )
580  {
581  fnFormula = &SwTableFormula::RelBoxNmsToPtr;
582  pNd = GetNodeOfFormula();
583  }
584  break;
585  case INTRNL_NAME:
586  return;
587  }
588  m_sFormula = ScanString( fnFormula, *pTable, const_cast<void*>(static_cast<void const *>(pNd)) );
590 }
591 
593 void SwTableFormula::ToRelBoxNm( const SwTable* pTable )
594 {
595  const SwNode* pNd = nullptr;
596  FnScanFormula fnFormula = nullptr;
597  switch (m_eNmType)
598  {
599  case INTRNL_NAME:
600  case EXTRNL_NAME:
601  if( pTable )
602  {
603  fnFormula = &SwTableFormula::BoxNmsToRelNm;
604  pNd = GetNodeOfFormula();
605  }
606  break;
607  case REL_NAME:
608  return;
609  }
610  m_sFormula = ScanString( fnFormula, *pTable, const_cast<void*>(static_cast<void const *>(pNd)) );
612 }
613 
614 OUString SwTableFormula::ScanString( FnScanFormula fnFormula, const SwTable& rTable,
615  void* pPara ) const
616 {
617  OUStringBuffer aStr;
618  sal_Int32 nFormula = 0;
619  sal_Int32 nEnd = 0;
620 
621  do {
622  // If the formula is preceded by a name, use this table!
623  const SwTable* pTable = &rTable;
624 
625  sal_Int32 nStt = m_sFormula.indexOf( '<', nFormula );
626  if ( nStt>=0 )
627  {
628  while ( nStt>=0 )
629  {
630  const sal_Int32 nNxt = nStt+1;
631  if (nNxt>=m_sFormula.getLength())
632  {
633  nStt = -1;
634  break;
635  }
636  if ( m_sFormula[nNxt]!=' ' && m_sFormula[nNxt]!='=' )
637  break;
638  nStt = m_sFormula.indexOf( '<', nNxt );
639  }
640 
641  if ( nStt>=0 )
642  // Start searching from current position, which is valid for sure
643  nEnd = m_sFormula.indexOf( '>', nStt );
644  }
645  if (nStt<0 || nEnd<0 )
646  {
647  // set the rest and finish
648  aStr.append(std::u16string_view(m_sFormula).substr(nFormula));
649  break;
650  }
651 
652  // write beginning
653  aStr.append(std::u16string_view(m_sFormula).substr(nFormula, nStt - nFormula));
654 
655  if (fnFormula)
656  {
657  sal_Int32 nSeparator = 0;
658  // Is a table name preceded?
659  // JP 16.02.99: SplitMergeBoxNm take care of the name themself
660  // JP 22.02.99: Linux compiler needs cast
661  // JP 28.06.99: rel. BoxName has no preceding tablename!
662  if( fnFormula != &SwTableFormula::SplitMergeBoxNm_ &&
663  m_sFormula.getLength()>(nStt+1) && cRelIdentifier != m_sFormula[nStt+1] &&
664  (nSeparator = m_sFormula.indexOf( '.', nStt ))>=0
665  && nSeparator < nEnd )
666  {
667  OUString sTableNm( m_sFormula.copy( nStt, nEnd - nStt ));
668 
669  // If there are dots in the name, then they appear in pairs (e.g. A1.1.1)!
670  if( (comphelper::string::getTokenCount(sTableNm, '.') - 1) & 1 )
671  {
672  sTableNm = sTableNm.copy( 0, nSeparator - nStt );
673 
674  // when creating a formula the table name is unwanted
675  if( fnFormula != &SwTableFormula::MakeFormula_ )
676  aStr.append(sTableNm);
677  nStt = nSeparator;
678 
679  sTableNm = sTableNm.copy( 1 ); // delete separator
680  if( sTableNm != rTable.GetFrameFormat()->GetName() )
681  {
682  // then search for table
683  const SwTable* pFnd = FindTable(
684  *rTable.GetFrameFormat()->GetDoc(),
685  sTableNm );
686  if( pFnd )
687  pTable = pFnd;
688  // ??
689  OSL_ENSURE( pFnd, "No table found. What now?" );
690  }
691  }
692  }
693 
694  OUString sBox( m_sFormula.copy( nStt, nEnd - nStt + 1 ));
695  // area in these parentheses?
696  nSeparator = m_sFormula.indexOf( ':', nStt );
697  if ( nSeparator>=0 && nSeparator<nEnd )
698  {
699  // without opening parenthesis
700  OUString aFirstBox( m_sFormula.copy( nStt+1, nSeparator - nStt - 1 ));
701  (this->*fnFormula)( *pTable, aStr, sBox, &aFirstBox, pPara );
702  }
703  else
704  (this->*fnFormula)( *pTable, aStr, sBox, nullptr, pPara );
705  }
706 
707  nFormula = nEnd+1;
708  } while( true );
709  return aStr.makeStringAndClear();
710 }
711 
712 const SwTable* SwTableFormula::FindTable( SwDoc& rDoc, const OUString& rNm )
713 {
714  const SwFrameFormats& rTableFormats = *rDoc.GetTableFrameFormats();
715  const SwTable* pTmpTable = nullptr, *pRet = nullptr;
716  for( auto nFormatCnt = rTableFormats.size(); nFormatCnt; )
717  {
718  SwFrameFormat* pFormat = rTableFormats[ --nFormatCnt ];
719  // if we are called from Sw3Writer, a number is dependent on the format name
720  SwTableBox* pFBox;
721  if ( rNm == pFormat->GetName().getToken(0, 0x0a) &&
722  nullptr != ( pTmpTable = SwTable::FindTable( pFormat ) ) &&
723  nullptr != (pFBox = pTmpTable->GetTabSortBoxes()[0] ) &&
724  pFBox->GetSttNd() &&
725  pFBox->GetSttNd()->GetNodes().IsDocNodes() )
726  {
727  // a table in the normal NodesArr
728  pRet = pTmpTable;
729  break;
730  }
731  }
732  return pRet;
733 }
734 
735 static const SwFrame* lcl_GetBoxFrame( const SwTableBox& rBox )
736 {
737  SwNodeIndex aIdx( *rBox.GetSttNd() );
738  SwContentNode* pCNd = aIdx.GetNodes().GoNext( &aIdx );
739  OSL_ENSURE( pCNd, "Box has no TextNode" );
740  Point aPt; // get the first frame of the layout - table headline
741  std::pair<Point, bool> const tmp(aPt, false);
742  return pCNd->getLayoutFrame(pCNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), nullptr, &tmp);
743 }
744 
745 static sal_Int32 lcl_GetLongBoxNum( OUString& rStr )
746 {
747  sal_Int32 nRet;
748  const sal_Int32 nPos = rStr.indexOf( cRelSeparator );
749  if ( nPos<0 )
750  {
751  nRet = rStr.toInt32();
752  rStr.clear();
753  }
754  else
755  {
756  nRet = rStr.copy( 0, nPos ).toInt32();
757  rStr = rStr.copy( nPos+1 );
758  }
759  return nRet;
760 }
761 
762 static const SwTableBox* lcl_RelToBox( const SwTable& rTable,
763  const SwTableBox* pRefBox,
764  const OUString& _sGetName )
765 {
766  // get line
767  const SwTableBox* pBox = nullptr;
768  OUString sGetName = _sGetName;
769 
770  // Is it really a relative value?
771  if ( cRelIdentifier == sGetName[0] ) // yes
772  {
773  if( !pRefBox )
774  return nullptr;
775 
776  sGetName = sGetName.copy( 1 );
777 
778  const SwTableLines* pLines = &rTable.GetTabLines();
779  const SwTableBoxes* pBoxes;
780  const SwTableLine* pLine;
781 
782  // determine starting values of the box,...
783  pBox = pRefBox;
784  pLine = pBox->GetUpper();
785  while( pLine->GetUpper() )
786  {
787  pBox = pLine->GetUpper();
788  pLine = pBox->GetUpper();
789  }
790  sal_uInt16 nSttBox = pLine->GetBoxPos( pBox );
791  sal_uInt16 nSttLine = rTable.GetTabLines().GetPos( pLine );
792 
793  const sal_Int32 nBoxOffset = lcl_GetLongBoxNum( sGetName ) + nSttBox;
794  const sal_Int32 nLineOffset = lcl_GetLongBoxNum( sGetName ) + nSttLine;
795 
796  if( nBoxOffset < 0 ||
797  nLineOffset < 0 )
798  return nullptr;
799 
800  if( o3tl::make_unsigned(nLineOffset) >= pLines->size() )
801  return nullptr;
802 
803  pLine = (*pLines)[ nLineOffset ];
804 
805  // ... then search the box
806  pBoxes = &pLine->GetTabBoxes();
807  if( o3tl::make_unsigned(nBoxOffset) >= pBoxes->size() )
808  return nullptr;
809  pBox = (*pBoxes)[ nBoxOffset ];
810 
811  while (!sGetName.isEmpty())
812  {
813  nSttBox = SwTable::GetBoxNum( sGetName );
814  pLines = &pBox->GetTabLines();
815  if( nSttBox )
816  --nSttBox;
817 
818  nSttLine = SwTable::GetBoxNum( sGetName );
819 
820  // determine line
821  if( !nSttLine || nSttLine > pLines->size() )
822  break;
823  pLine = (*pLines)[ nSttLine-1 ];
824 
825  // determine box
826  pBoxes = &pLine->GetTabBoxes();
827  if( nSttBox >= pBoxes->size() )
828  break;
829  pBox = (*pBoxes)[ nSttBox ];
830  }
831 
832  if( pBox )
833  {
834  if( !pBox->GetSttNd() )
835  // "bubble up" to first box
836  while( !pBox->GetTabLines().empty() )
837  pBox = pBox->GetTabLines().front()->GetTabBoxes().front();
838  }
839  }
840  else
841  {
842  // otherwise it is an absolute external presentation
843  pBox = rTable.GetTableBox( sGetName );
844  }
845  return pBox;
846 }
847 
848 static OUString lcl_BoxNmToRel( const SwTable& rTable, const SwTableNode& rTableNd,
849  const OUString& _sRefBoxNm, const OUString& _sTmp, bool bExtrnlNm )
850 {
851  OUString sTmp = _sTmp;
852  OUString sRefBoxNm = _sRefBoxNm;
853  if( !bExtrnlNm )
854  {
855  // convert into external presentation
856  SwTableBox* pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(sTmp.toInt64()));
857  if( rTable.GetTabSortBoxes().find( pBox ) == rTable.GetTabSortBoxes().end() )
858  return OUString('?');
859  sTmp = pBox->GetName();
860  }
861 
862  // If the formula is spanning over a table then keep external presentation
863  if( &rTable == &rTableNd.GetTable() )
864  {
865  long nBox = SwTable::GetBoxNum( sTmp, true );
866  nBox -= SwTable::GetBoxNum( sRefBoxNm, true );
867  long nLine = SwTable::GetBoxNum( sTmp );
868  nLine -= SwTable::GetBoxNum( sRefBoxNm );
869 
870  const OUString sCpy = sTmp; //JP 01.11.95: add rest from box name
871 
872  sTmp = OUStringChar(cRelIdentifier) + OUString::number( nBox )
873  + OUStringChar(cRelSeparator) + OUString::number( nLine );
874 
875  if (!sCpy.isEmpty())
876  {
877  sTmp += OUStringChar(cRelSeparator) + sCpy;
878  }
879  }
880 
881  if (sTmp.endsWith(">"))
882  return sTmp.copy(0, sTmp.getLength()-1 );
883 
884  return sTmp;
885 }
886 
888  SwSelBoxes& rBoxes )
889 {
890  rBoxes.clear();
891 
892  BoxNmToPtr( &rTable );
893  ScanString( &SwTableFormula::GetFormulaBoxes, rTable, &rBoxes );
894 }
895 
896 void SwTableFormula::GetFormulaBoxes( const SwTable& rTable, OUStringBuffer& ,
897  OUString& rFirstBox, OUString* pLastBox, void* pPara ) const
898 {
899  SwSelBoxes* pBoxes = static_cast<SwSelBoxes*>(pPara);
900  SwTableBox* pEndBox = nullptr;
901 
902  rFirstBox = rFirstBox.copy(1); // delete box label
903  // area in these parentheses?
904  if( pLastBox )
905  {
906  pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->toInt64()));
907 
908  // Is it actually a valid pointer?
909  if( rTable.GetTabSortBoxes().find( pEndBox ) == rTable.GetTabSortBoxes().end() )
910  pEndBox = nullptr;
911  rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
912  }
913 
914  SwTableBox *pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.toInt64()));
915  // Is it actually a valid pointer?
916  if( !pSttBox || rTable.GetTabSortBoxes().find( pSttBox ) == rTable.GetTabSortBoxes().end() )
917  return;
918 
919  if ( pEndBox ) // area?
920  {
921  // get all selected boxes via layout and calculate their values
922  SwSelBoxes aBoxes;
923  GetBoxes( *pSttBox, *pEndBox, aBoxes );
924  pBoxes->insert( aBoxes );
925  }
926  else // only the StartBox?
927  pBoxes->insert( pSttBox );
928 }
929 
931  const SwTableBox& rEndBox,
932  SwSelBoxes& rBoxes )
933 {
934  // get all selected boxes via layout
935  const SwLayoutFrame *pStt, *pEnd;
936  const SwFrame* pFrame = lcl_GetBoxFrame( rSttBox );
937  pStt = pFrame ? pFrame->GetUpper() : nullptr;
938  pFrame = lcl_GetBoxFrame( rEndBox );
939  pEnd = pFrame ? pFrame->GetUpper() : nullptr;
940  if( !pStt || !pEnd )
941  return ; // no valid selection
942 
943  GetTableSel( pStt, pEnd, rBoxes, nullptr );
944 
945  const SwTable* pTable = pStt->FindTabFrame()->GetTable();
946 
947  // filter headline boxes
948  if( pTable->GetRowsToRepeat() > 0 )
949  {
950  do { // middle-check loop
951  const SwTableLine* pLine = rSttBox.GetUpper();
952  while( pLine->GetUpper() )
953  pLine = pLine->GetUpper()->GetUpper();
954 
955  if( pTable->IsHeadline( *pLine ) )
956  break; // headline in this area!
957 
958  // maybe start and end are swapped
959  pLine = rEndBox.GetUpper();
960  while ( pLine->GetUpper() )
961  pLine = pLine->GetUpper()->GetUpper();
962 
963  if( pTable->IsHeadline( *pLine ) )
964  break; // headline in this area!
965 
966  const SwTabFrame *pStartTable = pStt->FindTabFrame();
967  const SwTabFrame *pEndTable = pEnd->FindTabFrame();
968 
969  if (pStartTable == pEndTable) // no split table
970  break;
971 
972  // then remove table headers
973  for (size_t n = 0; n < rBoxes.size(); ++n)
974  {
975  pLine = rBoxes[n]->GetUpper();
976  while( pLine->GetUpper() )
977  pLine = pLine->GetUpper()->GetUpper();
978 
979  if( pTable->IsHeadline( *pLine ) )
980  rBoxes.erase( rBoxes.begin() + n-- );
981  }
982  } while( false );
983  }
984 }
985 
987 void SwTableFormula::HasValidBoxes_( const SwTable& rTable, OUStringBuffer& ,
988  OUString& rFirstBox, OUString* pLastBox, void* pPara ) const
989 {
990  bool* pBValid = static_cast<bool*>(pPara);
991  if( *pBValid ) // wrong is wrong
992  {
993  SwTableBox* pSttBox = nullptr, *pEndBox = nullptr;
994  rFirstBox = rFirstBox.copy(1); // delete identifier of box
995 
996  // area in this parenthesis?
997  if( pLastBox )
998  rFirstBox = rFirstBox.copy( pLastBox->getLength()+1 );
999 
1000  switch (m_eNmType)
1001  {
1002  case INTRNL_NAME:
1003  if( pLastBox )
1004  pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->toInt64()));
1005  pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.toInt64()));
1006  break;
1007 
1008  case REL_NAME:
1009  {
1010  const SwNode* pNd = GetNodeOfFormula();
1011  const SwTableBox* pBox = !pNd ? nullptr
1012  : const_cast<SwTableBox *>(rTable.GetTableBox(
1013  pNd->FindTableBoxStartNode()->GetIndex() ));
1014  if( pLastBox )
1015  pEndBox = const_cast<SwTableBox*>(lcl_RelToBox( rTable, pBox, *pLastBox ));
1016  pSttBox = const_cast<SwTableBox*>(lcl_RelToBox( rTable, pBox, rFirstBox ));
1017  }
1018  break;
1019 
1020  case EXTRNL_NAME:
1021  if( pLastBox )
1022  pEndBox = const_cast<SwTableBox*>(rTable.GetTableBox( *pLastBox ));
1023  pSttBox = const_cast<SwTableBox*>(rTable.GetTableBox( rFirstBox ));
1024  break;
1025  }
1026 
1027  // Are these valid pointers?
1028  if( ( pLastBox &&
1029  ( !pEndBox || rTable.GetTabSortBoxes().find( pEndBox ) == rTable.GetTabSortBoxes().end() ) ) ||
1030  ( !pSttBox || rTable.GetTabSortBoxes().find( pSttBox ) == rTable.GetTabSortBoxes().end() ) )
1031  *pBValid = false;
1032  }
1033 }
1034 
1036 {
1037  bool bRet = true;
1038  const SwNode* pNd = GetNodeOfFormula();
1039  if( pNd && nullptr != ( pNd = pNd->FindTableNode() ) )
1041  static_cast<const SwTableNode*>(pNd)->GetTable(), &bRet );
1042  return bRet;
1043 }
1044 
1045 sal_uInt16 SwTableFormula::GetLnPosInTable( const SwTable& rTable, const SwTableBox* pBox )
1046 {
1047  sal_uInt16 nRet = USHRT_MAX;
1048  if( pBox )
1049  {
1050  const SwTableLine* pLn = pBox->GetUpper();
1051  while( pLn->GetUpper() )
1052  pLn = pLn->GetUpper()->GetUpper();
1053  nRet = rTable.GetTabLines().GetPos( pLn );
1054  }
1055  return nRet;
1056 }
1057 
1058 void SwTableFormula::SplitMergeBoxNm_( const SwTable& rTable, OUStringBuffer& rNewStr,
1059  OUString& rFirstBox, OUString* pLastBox, void* pPara ) const
1060 {
1061  SwTableFormulaUpdate& rTableUpd = *static_cast<SwTableFormulaUpdate*>(pPara);
1062 
1063  rNewStr.append(rFirstBox[0]); // get label for the box
1064  rFirstBox = rFirstBox.copy(1);
1065 
1066  OUString sTableNm;
1067  const SwTable* pTable = &rTable;
1068 
1069  OUString* pTableNmBox = pLastBox ? pLastBox : &rFirstBox;
1070 
1071  const sal_Int32 nLastBoxLen = pTableNmBox->getLength();
1072  const sal_Int32 nSeparator = pTableNmBox->indexOf('.');
1073  if ( nSeparator>=0 &&
1074  // If there are dots in the name, then these appear in pairs (e.g. A1.1.1)!
1075  (comphelper::string::getTokenCount(*pTableNmBox, '.') - 1) & 1 )
1076  {
1077  sTableNm = pTableNmBox->copy( 0, nSeparator );
1078  *pTableNmBox = pTableNmBox->copy( nSeparator + 1); // remove dot
1079  const SwTable* pFnd = FindTable( *rTable.GetFrameFormat()->GetDoc(), sTableNm );
1080  if( pFnd )
1081  pTable = pFnd;
1082 
1083  if( TBL_MERGETBL == rTableUpd.m_eFlags )
1084  {
1085  if( pFnd )
1086  {
1087  if( pFnd == rTableUpd.m_aData.pDelTable )
1088  {
1089  if( rTableUpd.m_pTable != &rTable ) // not the current one
1090  rNewStr.append(rTableUpd.m_pTable->GetFrameFormat()->GetName()).append("."); // set new table name
1091  rTableUpd.m_bModified = true;
1092  }
1093  else if( pFnd != rTableUpd.m_pTable ||
1094  ( rTableUpd.m_pTable != &rTable && &rTable != rTableUpd.m_aData.pDelTable))
1095  rNewStr.append(sTableNm).append("."); // keep table name
1096  else
1097  rTableUpd.m_bModified = true;
1098  }
1099  else
1100  rNewStr.append(sTableNm).append("."); // keep table name
1101  }
1102  }
1103  if( pTableNmBox == pLastBox )
1104  rFirstBox = rFirstBox.copy( nLastBoxLen + 1 );
1105 
1106  SwTableBox* pSttBox = nullptr, *pEndBox = nullptr;
1107  switch (m_eNmType)
1108  {
1109  case INTRNL_NAME:
1110  if( pLastBox )
1111  pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->toInt64()));
1112  pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.toInt64()));
1113  break;
1114 
1115  case REL_NAME:
1116  {
1117  const SwNode* pNd = GetNodeOfFormula();
1118  const SwTableBox* pBox = pNd ? pTable->GetTableBox(
1119  pNd->FindTableBoxStartNode()->GetIndex() ) : nullptr;
1120  if( pLastBox )
1121  pEndBox = const_cast<SwTableBox*>(lcl_RelToBox( *pTable, pBox, *pLastBox ));
1122  pSttBox = const_cast<SwTableBox*>(lcl_RelToBox( *pTable, pBox, rFirstBox ));
1123  }
1124  break;
1125 
1126  case EXTRNL_NAME:
1127  if( pLastBox )
1128  pEndBox = const_cast<SwTableBox*>(pTable->GetTableBox( *pLastBox ));
1129  pSttBox = const_cast<SwTableBox*>(pTable->GetTableBox( rFirstBox ));
1130  break;
1131  }
1132 
1133  if( pLastBox && pTable->GetTabSortBoxes().find( pEndBox ) == pTable->GetTabSortBoxes().end() )
1134  pEndBox = nullptr;
1135  if( pTable->GetTabSortBoxes().find( pSttBox ) == pTable->GetTabSortBoxes().end() )
1136  pSttBox = nullptr;
1137 
1138  if( TBL_SPLITTBL == rTableUpd.m_eFlags )
1139  {
1140  // Where are the boxes - in the old or in the new table?
1141  bool bInNewTable = false;
1142  if( pLastBox )
1143  {
1144  // It is the "first" box in this selection. It determines if the formula is placed in
1145  // the new or the old table.
1146  sal_uInt16 nEndLnPos = SwTableFormula::GetLnPosInTable( *pTable, pEndBox ),
1147  nSttLnPos = SwTableFormula::GetLnPosInTable( *pTable, pSttBox );
1148 
1149  if( USHRT_MAX != nSttLnPos && USHRT_MAX != nEndLnPos &&
1150  ((rTableUpd.m_nSplitLine <= nSttLnPos) ==
1151  (rTableUpd.m_nSplitLine <= nEndLnPos)) )
1152  {
1153  // stay in same table
1154  bInNewTable = rTableUpd.m_nSplitLine <= nEndLnPos &&
1155  pTable == rTableUpd.m_pTable;
1156  }
1157  else
1158  {
1159  // this is definitely an invalid formula, also mark as modified for Undo
1160  rTableUpd.m_bModified = true;
1161  if( pEndBox )
1162  bInNewTable = USHRT_MAX != nEndLnPos &&
1163  rTableUpd.m_nSplitLine <= nEndLnPos &&
1164  pTable == rTableUpd.m_pTable;
1165  }
1166  }
1167  else
1168  {
1169  sal_uInt16 nSttLnPos = SwTableFormula::GetLnPosInTable( *pTable, pSttBox );
1170  // Put it in the new table?
1171  bInNewTable = USHRT_MAX != nSttLnPos &&
1172  rTableUpd.m_nSplitLine <= nSttLnPos &&
1173  pTable == rTableUpd.m_pTable;
1174  }
1175 
1176  // formula goes into new table
1177  if( rTableUpd.m_bBehindSplitLine )
1178  {
1179  if( !bInNewTable )
1180  {
1181  rTableUpd.m_bModified = true;
1182  rNewStr.append(rTableUpd.m_pTable->GetFrameFormat()->GetName()).append(".");
1183  }
1184  else if( !sTableNm.isEmpty() )
1185  rNewStr.append(sTableNm).append(".");
1186  }
1187  else if( bInNewTable )
1188  {
1189  rTableUpd.m_bModified = true;
1190  rNewStr.append(*rTableUpd.m_aData.pNewTableNm).append(".");
1191  }
1192  else if( !sTableNm.isEmpty() )
1193  rNewStr.append(sTableNm).append(".");
1194  }
1195 
1196  if( pLastBox )
1197  rNewStr.append(OUString::number(reinterpret_cast<sal_PtrDiff>(pEndBox))).append(":");
1198 
1199  rNewStr.append(OUString::number(reinterpret_cast<sal_PtrDiff>(pSttBox)))
1200  .append(rFirstBox[ rFirstBox.getLength()-1] );
1201 }
1202 
1205 {
1206  const SwTable* pTable;
1207  const SwNode* pNd = GetNodeOfFormula();
1208  if( pNd && nullptr != ( pNd = pNd->FindTableNode() ))
1209  pTable = &static_cast<const SwTableNode*>(pNd)->GetTable();
1210  else
1211  pTable = rTableUpd.m_pTable;
1212 
1213  m_sFormula = ScanString( &SwTableFormula::SplitMergeBoxNm_, *pTable, static_cast<void*>(&rTableUpd) );
1215 }
1216 
1217 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SwTableBoxNumFormat & GetTableBoxNumFormat(bool=true) const
TableBox attributes - implemented in cellatr.hxx.
Definition: cellatr.hxx:105
Base class of the Writer layout elements.
Definition: frame.hxx:295
bool CalcWithStackOverflow()
Definition: cellfml.cxx:275
#define RES_BOXATR_BEGIN
Definition: hintids.hxx:355
Definition: calc.hxx:184
sal_uLong GetIndex() const
Definition: node.hxx:282
void CalcField(SwTableCalcPara &rCalcPara)
Definition: tblcalc.cxx:44
SwTableCalcPara(SwCalc &rCalculator, const SwTable &rTable, SwRootFrame const *pLayout)
Definition: cellfml.cxx:259
static const SwTableBox * lcl_RelToBox(const SwTable &rTable, const SwTableBox *pRefBox, const OUString &sGetName)
Definition: cellfml.cxx:762
void SetLastTableBox(const SwTableBox *pBox)
Definition: cellfml.hxx:55
const SwField * GetField() const
Definition: fmtfld.hxx:110
const SwTableBox * GetTableBox(const OUString &rName, const bool bPerformValidCheck=false) const
Definition: swtable.cxx:1343
union SwTableFormulaUpdate::@26 m_aData
void RelNmsToBoxNms(const SwTable &, OUStringBuffer &, OUString &, OUString *, void *pPara) const
Definition: cellfml.cxx:390
const OUString & GetText() const
Definition: ndtxt.hxx:210
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1407
const SwFrameFormats * GetTableFrameFormats() const
Definition: doc.hxx:810
const SwTable * GetTable() const
Definition: tabfrm.hxx:144
const SwTable * m_pTable
current table
Definition: cellfml.hxx:46
Base class of all fields.
Definition: fldbas.hxx:293
bool IsCalcError() const
Definition: calc.hxx:238
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:30
const SwTableBox * m_pLastTableBox
Definition: cellfml.hxx:39
sal_Int64 n
Definition: doc.hxx:186
SvNumFormatType GetType(sal_uInt32 nFIndex) const
const_iterator find(const Value &x) const
SwTableLine is one table row in the document model.
Definition: swtable.hxx:344
sal_uInt16 GetRowsToRepeat() const
Definition: swtable.hxx:193
double GetValue() const
Definition: cellatr.hxx:95
SwTextAttr * GetTextAttrAt(sal_Int32 const nIndex, sal_uInt16 const nWhich, enum GetTextAttrMode const eMode=DEFAULT) const
get the innermost text attribute covering position nIndex.
Definition: ndtxt.cxx:1720
SwTableLine * front() const
Definition: swtable.hxx:79
The root element of a Writer document layout.
Definition: rootfrm.hxx:79
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:201
sal_Int32 getTokenCount(const OString &rIn, char cTok)
void(SwTableFormula::* FnScanFormula)(const SwTable &, OUStringBuffer &, OUString &, OUString *, void *) const
Definition: cellfml.hxx:60
size_type size() const
Definition: swtable.hxx:74
OUString m_sFormula
current formula
Definition: cellfml.hxx:92
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...
Definition: ndtxt.cxx:3050
#define CH_TXTATR_BREAKWORD
Definition: hintids.hxx:136
bool HasValidBoxes() const
Definition: cellfml.cxx:1035
sal_uInt16 sal_Unicode
#define CH_TXTATR_INWORD
Definition: hintids.hxx:137
void BoxNmToPtr(const SwTable *pTable)
create from the external formula the internal
Definition: cellfml.cxx:568
sal_uInt16 m_nMaxSize
Definition: cellfml.hxx:40
sal_uInt16 m_nStackCount
Definition: cellfml.hxx:40
#define CH_TXT_ATR_INPUTFIELDSTART
Definition: hintids.hxx:140
const OUString & GetName() const
Definition: format.hxx:111
const SwTable * m_pTable
Pointer to the current table.
Definition: hints.hxx:201
SwTableFormula(const OUString &rFormula)
Definition: cellfml.cxx:312
const SwTable & GetTable() const
Definition: node.hxx:497
OUString ScanString(FnScanFormula fnFormula, const SwTable &rTable, void *) const
Definition: cellfml.cxx:614
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:191
size_type size() const
static sal_uInt16 GetLnPosInTable(const SwTable &rTable, const SwTableBox *pBox)
Definition: cellfml.cxx:1045
void PtrToBoxNms(const SwTable &, OUStringBuffer &, OUString &, OUString *, void *pPara) const
Definition: cellfml.cxx:489
void PtrToBoxNm(const SwTable *pTable)
create from the internal formula (for CORE) the external formula (for UI)
Definition: cellfml.cxx:543
Specific frame formats (frames, DrawObjects).
Definition: docary.hxx:201
const SwStartNode * m_pStartNode
Definition: swtable.hxx:396
void DecStackCnt()
Definition: cellfml.hxx:54
SwTableSortBoxes & GetTabSortBoxes()
Definition: swtable.hxx:259
double GetValue(SwTableCalcPara &rPara) const
Get value of this box.
Definition: cellfml.cxx:79
NameType m_eNmType
current display method
Definition: cellfml.hxx:93
OUString GetName() const
Definition: swtable.cxx:1827
bool IncStackCnt()
Definition: cellfml.hxx:53
OUString GetFieldContent() const
Definition: atrfld.cxx:646
static SwTable * FindTable(SwFrameFormat const *const pFormat)
Definition: swtable.cxx:1919
Style of a layout element.
Definition: frmfmt.hxx:57
The non-shared part of a user field.
Definition: usrfld.hxx:101
void GetTableSel(const SwCursorShell &rShell, SwSelBoxes &rBoxes, const SwTableSearchType eSearchType)
Definition: tblsel.cxx:148
bool IsValid() const
Definition: cellfml.hxx:133
bool empty() const
Definition: swtable.hxx:73
SwRootFrame const *const m_pLayout
layout to access text field results
Definition: cellfml.hxx:43
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
#define RES_BOXATR_END
Definition: hintids.hxx:359
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
virtual ~SwTableFormula()
Definition: cellfml.cxx:319
void SetCalcError(SwCalcError eErr)
Definition: calc.hxx:237
SvNumFormatType
static const SwTable * FindTable(SwDoc &rDoc, const OUString &rNm)
Definition: cellfml.cxx:712
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:396
static void GetBoxes(const SwTableBox &rStt, const SwTableBox &rEnd, SwSelBoxes &rBoxes)
Definition: cellfml.cxx:930
Marks a node in the document model.
Definition: ndindex.hxx:31
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:425
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:693
bool IsStackOverflow() const
Definition: cellfml.hxx:52
void ToSplitMergeBoxNm(SwTableFormulaUpdate &rTableUpd)
gets called before/after merging/splitting of tables
Definition: cellfml.cxx:1204
T static_txtattr_cast(S *s)
Definition: txatbase.hxx:237
void GetBoxesOfFormula(const SwTable &rTable, SwSelBoxes &rBoxes)
Definition: cellfml.cxx:887
const_iterator end() const
#define RES_BOXATR_VALUE
Definition: hintids.hxx:358
void MakeFormula_(const SwTable &, OUStringBuffer &, OUString &, OUString *, void *pPara) const
Definition: cellfml.cxx:323
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:119
void GetFormulaBoxes(const SwTable &, OUStringBuffer &, OUString &, OUString *, void *pPara) const
Definition: cellfml.cxx:896
static sal_uInt16 GetBoxNum(OUString &rStr, bool bFirst=false, const bool bPerformValidCheck=false)
Definition: swtable.cxx:1284
void BoxNmsToRelNm(const SwTable &, OUStringBuffer &, OUString &, OUString *, void *pPara) const
Definition: cellfml.cxx:455
sal_uInt16 GetBoxPos(const SwTableBox *pBox) const
Definition: swtable.hxx:356
SwTableLines & GetTabLines()
Definition: swtable.hxx:198
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:110
std::unique_ptr< SwTableSortBoxes > m_pBoxStack
stack for recognizing recursion
Definition: cellfml.hxx:44
SwTableLines & GetTabLines()
Definition: swtable.hxx:418
SwFieldType * GetTyp() const
Definition: fldbas.hxx:396
const_iterator begin() const
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:458
void RelBoxNmsToPtr(const SwTable &, OUStringBuffer &, OUString &, OUString *, void *pPara) const
Definition: cellfml.cxx:423
const SwTableBoxValue & GetTableBoxValue(bool=true) const
Definition: cellatr.hxx:109
SwSbxValue Calculate(const OUString &rStr)
Definition: calc.cxx:347
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
SwTableBoxes & GetTabBoxes()
Definition: swtable.hxx:354
static sal_Int32 lcl_GetLongBoxNum(OUString &rStr)
Definition: cellfml.cxx:745
OUString ExpandField(bool bCached, SwRootFrame const *pLayout) const
expand the field.
Definition: fldbas.cxx:443
std::vector< SwTableBox * > SwTableBoxes
Definition: swtable.hxx:103
#define RES_TXTATR_FIELD
Definition: hintids.hxx:244
void Calc(SwTableCalcPara &rCalcPara, double &rValue)
Definition: cellatr.cxx:186
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:439
long getRowSpan() const
Definition: swtable.cxx:101
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:253
void HasValidBoxes_(const SwTable &, OUStringBuffer &, OUString &, OUString *, void *pPara) const
Are all boxes valid that are referenced by the formula?
Definition: cellfml.cxx:987
void BoxNmsToPtr(const SwTable &, OUStringBuffer &, OUString &, OUString *, void *pPara) const
Definition: cellfml.cxx:521
SwNodes & GetNodes()
Definition: doc.hxx:404
void ToRelBoxNm(const SwTable *pTable)
create from the external/internal formula the relative formula
Definition: cellfml.cxx:593
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:386
static const SwFrame * lcl_GetBoxFrame(const SwTableBox &rBox)
Definition: cellfml.cxx:735
OUString GetStrResult(const SwSbxValue &rValue)
Definition: calc.cxx:370
SwFrameFormat * ClaimFrameFormat()
Definition: swtable.cxx:1705
const SwStartNode * FindTableBoxStartNode() const
Definition: node.hxx:196
bool IsHeadline(const SwTableLine &rLine) const
Definition: tabfrm.cxx:5430
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:349
SwTableBox * GetUpper()
Definition: swtable.hxx:362
bool IsNumberFormat(const OUString &rString, sal_uInt32 &F_Index, double &fOutNumber)
Definition: ndtbl.cxx:3993
void SplitMergeBoxNm_(const SwTable &, OUStringBuffer &, OUString &, OUString *, void *pPara) const
Definition: cellfml.cxx:1058
sal_uInt32 GetValue() const
bool IsDocNodes() const
Is the NodesArray the regular one of Doc? (and not the UndoNds, ...) Implementation in doc...
Definition: nodes.cxx:2313
sal_uInt16 GetPos(const SwTableLine *pBox) const
Definition: swtable.hxx:96
virtual const SwNode * GetNodeOfFormula() const =0
size_t size() const
Definition: docary.hxx:225
const SwTable * pDelTable
Merge: Pointer to the table to be removed.
Definition: hints.hxx:203
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
const sal_Unicode cListDelim
Definition: calc.hxx:39
TableFormulaUpdateFlags m_eFlags
Definition: hints.hxx:208
std::pair< const_iterator, bool > insert(Value &&x)
static OUString lcl_BoxNmToRel(const SwTable &rTable, const SwTableNode &rTableNd, const OUString &sRefBoxNm, const OUString &sGetStr, bool bExtrnlNm)
Definition: cellfml.cxx:848
const OUString * pNewTableNm
Split: the name of the new table.
Definition: hints.hxx:204
SwTableLine * GetUpper()
Definition: swtable.hxx:421
#define RES_TXTATR_INPUTFIELD
Definition: hintids.hxx:239
SwFieldIds Which() const
Definition: fldbas.hxx:272
virtual double GetValue() const
Definition: fldbas.cxx:706
aStr
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1277
SwCalc & m_rCalc
current Calculator
Definition: cellfml.hxx:45
sal_uInt16 nPos
#define RES_BOXATR_FORMAT
Definition: hintids.hxx:356
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1315
sal_uInt16 m_nSplitLine
Split: from this BaseLine on will be split.
Definition: hints.hxx:207
size_type erase(const Value &x)
#define RES_BOXATR_FORMULA
Definition: hintids.hxx:357
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1075
Base class of the Writer document model elements.
Definition: node.hxx:79