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