LibreOffice Module sw (master)  1
DocumentFieldsManager.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  */
20 #include <config_features.h>
21 #include <doc.hxx>
22 #include <IDocumentUndoRedo.hxx>
23 #include <IDocumentState.hxx>
26 #include <redline.hxx>
27 #include <rootfrm.hxx>
28 #include <dbmgr.hxx>
29 #include <chpfld.hxx>
30 #include <dbfld.hxx>
31 #include <reffld.hxx>
32 #include <flddropdown.hxx>
33 #include <strings.hrc>
34 #include <SwUndoField.hxx>
35 #include <flddat.hxx>
36 #include <cntfrm.hxx>
37 #include <section.hxx>
38 #include <docufld.hxx>
39 #include <calbck.hxx>
40 #include <cellatr.hxx>
41 #include <swtable.hxx>
42 #include <frmfmt.hxx>
43 #include <fmtfld.hxx>
44 #include <ndtxt.hxx>
45 #include <txtfld.hxx>
46 #include <docfld.hxx>
47 #include <hints.hxx>
48 #include <docary.hxx>
49 #include <fldbas.hxx>
50 #include <expfld.hxx>
51 #include <ddefld.hxx>
52 #include <authfld.hxx>
53 #include <usrfld.hxx>
54 #include <ndindex.hxx>
55 #include <pam.hxx>
56 #include <o3tl/deleter.hxx>
59 #include <com/sun/star/uno/Any.hxx>
60 
61 using namespace ::com::sun::star::uno;
62 
63 namespace sw
64 {
66  SwTextField const& rTextField)
67  {
69  SwPosition const pos(rTextField.GetTextNode(),
70  rTextField.GetStart());
71  SwRangeRedline const*const pRedline(rIDRA.GetRedline(pos, &tmp));
72  return (pRedline
73  && pRedline->GetType() == RedlineType::Delete
74  && *pRedline->GetPoint() != *pRedline->GetMark());
75  }
76 }
77 
78 namespace
79 {
80  #if HAVE_FEATURE_DBCONNECTIVITY
81 
82  OUString lcl_GetDBVarName( SwDoc& rDoc, SwDBNameInfField& rDBField )
83  {
84  SwDBData aDBData( rDBField.GetDBData( &rDoc ));
85  OUString sDBNumNm;
86  SwDBData aDocData = rDoc.GetDBData();
87 
88  if( aDBData != aDocData )
89  {
90  sDBNumNm = aDBData.sDataSource + OUStringLiteral1(DB_DELIM)
91  + aDBData.sCommand + OUStringLiteral1(DB_DELIM);
92  }
94 
95  return sDBNumNm;
96  }
97 
98  #endif
99 
100  bool IsFieldDeleted(IDocumentRedlineAccess const& rIDRA,
101  SwRootFrame const& rLayout, SwTextField const& rTextField)
102  {
103  SwTextNode const& rNode(rTextField.GetTextNode());
104  bool const isInBody(
105  rNode.GetNodes().GetEndOfExtras().GetIndex() < rNode.GetIndex());
106  if (!isInBody && nullptr == rNode.getLayoutFrame(&rLayout))
107  { // see SwDocUpdateField::GetBodyNode() - fields in hidden sections
108  // don't have layout frames but must be updated, so use the same
109  // check as there, but do it again because GetBodyNode() checks
110  // for *any* layout...
111  return true;
112  }
113  return sw::IsFieldDeletedInModel(rIDRA, rTextField);
114  }
115 
116  void lcl_CalcField( SwDoc& rDoc, SwCalc& rCalc, const SetGetExpField& rSGEField,
117  SwDBManager* pMgr, SwRootFrame const*const pLayout)
118  {
119  const SwTextField* pTextField = rSGEField.GetTextField();
120  if( !pTextField )
121  return ;
122 
123  if (pLayout && pLayout->IsHideRedlines()
124  && IsFieldDeleted(rDoc.getIDocumentRedlineAccess(), *pLayout, *pTextField))
125  {
126  return;
127  }
128 
129  const SwField* pField = pTextField->GetFormatField().GetField();
130  const SwFieldIds nFieldWhich = pField->GetTyp()->Which();
131 
132  if( SwFieldIds::SetExp == nFieldWhich )
133  {
134  SwSbxValue aValue;
135  if( nsSwGetSetExpType::GSE_EXPR & pField->GetSubType() )
136  aValue.PutDouble( static_cast<const SwSetExpField*>(pField)->GetValue(pLayout) );
137  else
138  // Extension to calculate with Strings
139  aValue.PutString( static_cast<const SwSetExpField*>(pField)->GetExpStr(pLayout) );
140 
141  // set the new value in Calculator
142  rCalc.VarChange( pField->GetTyp()->GetName(), aValue );
143  }
144  else if( pMgr )
145  {
146  #if !HAVE_FEATURE_DBCONNECTIVITY
147  (void) rDoc;
148  #else
149  switch( nFieldWhich )
150  {
152  {
153  SwDBNumSetField* pDBField = const_cast<SwDBNumSetField*>(static_cast<const SwDBNumSetField*>(pField));
154 
155  SwDBData aDBData(pDBField->GetDBData(&rDoc));
156 
157  if( pDBField->IsCondValid() &&
158  pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand ))
159  rCalc.VarChange( lcl_GetDBVarName( rDoc, *pDBField),
160  pDBField->GetFormat() );
161  }
162  break;
164  {
165  SwDBNextSetField* pDBField = const_cast<SwDBNextSetField*>(static_cast<const SwDBNextSetField*>(pField));
166  SwDBData aDBData(pDBField->GetDBData(&rDoc));
167  if( !pDBField->IsCondValid() ||
168  !pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand ))
169  break;
170 
171  OUString sDBNumNm(lcl_GetDBVarName( rDoc, *pDBField));
172  SwCalcExp* pExp = rCalc.VarLook( sDBNumNm );
173  if( pExp )
174  rCalc.VarChange( sDBNumNm, pExp->nValue.GetLong() + 1 );
175  }
176  break;
177 
178  default: break;
179  }
180  #endif
181  }
182  }
183 }
184 
185 namespace sw
186 {
187 
188 DocumentFieldsManager::DocumentFieldsManager( SwDoc& i_rSwdoc ) : m_rDoc( i_rSwdoc ),
189  mbNewFieldLst(true),
190  mpUpdateFields(new SwDocUpdateField(m_rDoc)),
191  mpFieldTypes( new SwFieldTypes ),
192  mnLockExpField( 0 )
193 {
194 }
195 
197 {
198  return mpFieldTypes.get();
199 }
200 
207 {
208  const SwFieldTypes::size_type nSize = mpFieldTypes->size();
209  const SwFieldIds nFieldWhich = rFieldTyp.Which();
210 
211  SwFieldTypes::size_type i = INIT_FLDTYPES;
212 
213  switch( nFieldWhich )
214  {
215  case SwFieldIds::SetExp:
216  //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!!
217  // Or we get doubble number circles!!
218  //MIB 14.03.95: From now on also the SW3-Reader relies on this, when
219  //constructing string pools and when reading SetExp fields
220  if( nsSwGetSetExpType::GSE_SEQ & static_cast<const SwSetExpFieldType&>(rFieldTyp).GetType() )
221  i -= INIT_SEQ_FLDTYPES;
222  [[fallthrough]];
224  case SwFieldIds::User:
225  case SwFieldIds::Dde:
226  {
227  const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
228  OUString sFieldNm( rFieldTyp.GetName() );
229  for( ; i < nSize; ++i )
230  if( nFieldWhich == (*mpFieldTypes)[i]->Which() &&
231  rSCmp.isEqual( sFieldNm, (*mpFieldTypes)[i]->GetName() ))
232  return (*mpFieldTypes)[i].get();
233  }
234  break;
235 
237  for( ; i < nSize; ++i )
238  if( nFieldWhich == (*mpFieldTypes)[i]->Which() )
239  return (*mpFieldTypes)[i].get();
240  break;
241 
242  default:
243  for( i = 0; i < nSize; ++i )
244  if( nFieldWhich == (*mpFieldTypes)[i]->Which() )
245  return (*mpFieldTypes)[i].get();
246  }
247 
248  std::unique_ptr<SwFieldType> pNew = rFieldTyp.Copy();
249  switch( nFieldWhich )
250  {
251  case SwFieldIds::Dde:
252  static_cast<SwDDEFieldType*>(pNew.get())->SetDoc( &m_rDoc );
253  break;
254 
256  case SwFieldIds::Table:
258  case SwFieldIds::GetExp:
259  static_cast<SwValueFieldType*>(pNew.get())->SetDoc( &m_rDoc );
260  break;
261 
262  case SwFieldIds::User:
263  case SwFieldIds::SetExp:
264  static_cast<SwValueFieldType*>(pNew.get())->SetDoc( &m_rDoc );
265  // JP 29.07.96: Optionally prepare FieldList for Calculator:
266  mpUpdateFields->InsertFieldType( *pNew );
267  break;
269  static_cast<SwAuthorityFieldType*>(pNew.get())->SetDoc( &m_rDoc );
270  break;
271  default: break;
272  }
273 
274  mpFieldTypes->insert( mpFieldTypes->begin() + nSize, std::move(pNew) );
276 
277  return (*mpFieldTypes)[ nSize ].get();
278 }
279 
282 {
283  for( SwFieldTypes::size_type i = 0; i < INIT_FLDTYPES; ++i )
284  if( eWhich == (*mpFieldTypes)[i]->Which() )
285  return (*mpFieldTypes)[i].get();
286  return nullptr;
287 }
288 
291  SwFieldIds nResId,
292  const OUString& rName,
293  bool bDbFieldMatching // used in some UNO calls for SwFieldIds::Database to use different string matching code #i51815#
294  ) const
295 {
296  const SwFieldTypes::size_type nSize = mpFieldTypes->size();
297  SwFieldTypes::size_type i {0};
298  const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
299 
300  switch( nResId )
301  {
302  case SwFieldIds::SetExp:
303  //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!!
304  // Or we get doubble number circles!!
305  //MIB 14.03.95: From now on also the SW3-Reader relies on this, when
306  //constructing string pools and when reading SetExp fields
308  break;
309 
311  case SwFieldIds::User:
312  case SwFieldIds::Dde:
314  i = INIT_FLDTYPES;
315  break;
316  default: break;
317  }
318 
319  SwFieldType* pRet = nullptr;
320  for( ; i < nSize; ++i )
321  {
322  SwFieldType* pFieldType = (*mpFieldTypes)[i].get();
323 
324  if (nResId == pFieldType->Which())
325  {
326  OUString aFieldName( pFieldType->GetName() );
327  if (bDbFieldMatching && nResId == SwFieldIds::Database) // #i51815#
328  aFieldName = aFieldName.replace(DB_DELIM, '.');
329 
330  if (rSCmp.isEqual( rName, aFieldName ))
331  {
332  pRet = pFieldType;
333  break;
334  }
335  }
336  }
337  return pRet;
338 }
339 
342 {
343  OSL_ENSURE( INIT_FLDTYPES <= nField, "don't remove InitFields" );
344  /*
345  * Dependent fields present -> ErrRaise
346  */
347  if(nField < mpFieldTypes->size())
348  {
349  SwFieldType* pTmp = (*mpFieldTypes)[nField].get();
350 
351  // JP 29.07.96: Optionally prepare FieldList for Calculator
352  SwFieldIds nWhich = pTmp->Which();
353  switch( nWhich )
354  {
355  case SwFieldIds::SetExp:
356  case SwFieldIds::User:
357  mpUpdateFields->RemoveFieldType( *pTmp );
358  [[fallthrough]];
359  case SwFieldIds::Dde:
360  if( pTmp->HasWriterListeners() && !m_rDoc.IsUsed( *pTmp ) )
361  {
362  if( SwFieldIds::SetExp == nWhich )
363  static_cast<SwSetExpFieldType*>(pTmp)->SetDeleted( true );
364  else if( SwFieldIds::User == nWhich )
365  static_cast<SwUserFieldType*>(pTmp)->SetDeleted( true );
366  else
367  static_cast<SwDDEFieldType*>(pTmp)->SetDeleted( true );
368  nWhich = SwFieldIds::Database;
369  }
370  break;
371  default: break;
372  }
373 
374  if( nWhich != SwFieldIds::Database )
375  {
376  OSL_ENSURE( !pTmp->HasWriterListeners(), "Dependent fields present!" );
377  // delete field type
378  delete pTmp;
379  }
380  else
381  (*mpFieldTypes)[nField].release(); // DB fields are ref-counted and delete themselves
382  mpFieldTypes->erase( mpFieldTypes->begin() + nField );
384  }
385 }
386 
387 // All have to be re-evaluated.
389 {
390  // Call Modify() for every field type,
391  // dependent SwTextField get notified ...
392 
393  for( auto const & pFieldType : *mpFieldTypes )
394  {
395  switch( pFieldType->Which() )
396  {
397  // Update table fields second to last
398  // Update references last
399  case SwFieldIds::GetRef:
400  case SwFieldIds::Table:
403  case SwFieldIds::RefPageSet: // are never expanded!
404  break;
405 
406  case SwFieldIds::Dde:
407  {
408  SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL );
409  pFieldType->ModifyNotification( nullptr, &aUpdateDDE );
410  break;
411  }
412  case SwFieldIds::GetExp:
413  case SwFieldIds::SetExp:
416  // Expression fields are treated separately
417  break;
418  default:
419  pFieldType->ModifyNotification ( nullptr, nullptr );
420  }
421  }
422 
423  if( !IsExpFieldsLocked() )
424  UpdateExpFields( nullptr, false ); // update expression fields
425 
426  // Tables
427  UpdateTableFields(nullptr);
428 
429  // References
430  UpdateRefFields();
431  if( bCloseDB )
432  {
433 #if HAVE_FEATURE_DBCONNECTIVITY
435 #endif
436  }
437  // Only evaluate on full update
439 }
440 
442 {
443  // The FieldType was marked as deleted and removed from the array.
444  // One has to look this up again, now.
445  // - If it's not present, it can be re-inserted.
446  // - If the same type is found, the deleted one has to be renamed.
447 
448  const SwFieldTypes::size_type nSize = mpFieldTypes->size();
449  const SwFieldIds nFieldWhich = rFieldTyp.Which();
450 
451  OSL_ENSURE( SwFieldIds::SetExp == nFieldWhich ||
452  SwFieldIds::User == nFieldWhich ||
453  SwFieldIds::Dde == nFieldWhich, "Wrong FieldType" );
454 
455  const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
456  const OUString& rFieldNm = rFieldTyp.GetName();
457 
458  for( SwFieldTypes::size_type i = INIT_FLDTYPES; i < nSize; ++i )
459  {
460  SwFieldType* pFnd = (*mpFieldTypes)[i].get();
461  if( nFieldWhich == pFnd->Which() &&
462  rSCmp.isEqual( rFieldNm, pFnd->GetName() ) )
463  {
464  // find new name
465  SwFieldTypes::size_type nNum = 1;
466  do {
467  OUString sSrch = rFieldNm + OUString::number( nNum );
468  for( i = INIT_FLDTYPES; i < nSize; ++i )
469  {
470  pFnd = (*mpFieldTypes)[i].get();
471  if( nFieldWhich == pFnd->Which() &&
472  rSCmp.isEqual( sSrch, pFnd->GetName() ) )
473  break;
474  }
475  if( i >= nSize ) // not found
476  {
477  const_cast<OUString&>(rFieldNm) = sSrch;
478  break; // exit while loop
479  }
480  ++nNum;
481  } while( true );
482  break;
483  }
484  }
485 
486  // not found, so insert, and updated deleted flag
487  mpFieldTypes->insert( mpFieldTypes->begin() + nSize, std::unique_ptr<SwFieldType>(&rFieldTyp) );
488  switch( nFieldWhich )
489  {
490  case SwFieldIds::SetExp:
491  static_cast<SwSetExpFieldType&>(rFieldTyp).SetDeleted( false );
492  break;
493  case SwFieldIds::User:
494  static_cast<SwUserFieldType&>(rFieldTyp).SetDeleted( false );
495  break;
496  case SwFieldIds::Dde:
497  static_cast<SwDDEFieldType&>(rFieldTyp).SetDeleted( false );
498  break;
499  default: break;
500  }
501 }
502 
504  const Any& rVal, sal_uInt16 nWhich)
505 {
506  Any aOldVal;
507  SwField * pField = GetFieldAtPos(rPos);
508 
510  pField->QueryValue(aOldVal, nWhich))
511  {
513  std::make_unique<SwUndoFieldFromAPI>(rPos, aOldVal, rVal, nWhich));
514  }
515 
516  pField->PutValue(rVal, nWhich);
517 }
518 
519 bool DocumentFieldsManager::UpdateField(SwTextField * pDstTextField, SwField & rSrcField,
520  SwMsgPoolItem * pMsgHint,
521  bool bUpdateFields)
522 {
523  OSL_ENSURE(pDstTextField, "no field to update!");
524 
525  bool bTableSelBreak = false;
526 
527  SwFormatField * pDstFormatField = const_cast<SwFormatField*>(&pDstTextField->GetFormatField());
528  SwField * pDstField = pDstFormatField->GetField();
529  SwFieldIds nFieldWhich = rSrcField.GetTyp()->Which();
530  SwNodeIndex aTableNdIdx(pDstTextField->GetTextNode());
531 
532  if (pDstField->GetTyp()->Which() ==
533  rSrcField.GetTyp()->Which())
534  {
536  {
537  SwPosition aPosition( pDstTextField->GetTextNode() );
538  aPosition.nContent = pDstTextField->GetStart();
539 
541  std::make_unique<SwUndoFieldFromDoc>( aPosition, *pDstField, rSrcField, pMsgHint, bUpdateFields) );
542  }
543 
544  pDstFormatField->SetField(rSrcField.CopyField());
545  SwField* pNewField = pDstFormatField->GetField();
546 
547  switch( nFieldWhich )
548  {
549  case SwFieldIds::SetExp:
550  case SwFieldIds::GetExp:
553  UpdateExpFields( pDstTextField, true );
554  break;
555 
556  case SwFieldIds::Table:
557  {
558  const SwTableNode* pTableNd =
559  m_rDoc.IsIdxInTable(aTableNdIdx);
560  if( pTableNd )
561  {
562  SwTableFormulaUpdate aTableUpdate( &pTableNd->
563  GetTable() );
564  if (bUpdateFields)
565  UpdateTableFields( &aTableUpdate );
566  else
567  pNewField->GetTyp()->ModifyNotification(nullptr, &aTableUpdate);
568 
569  if (! bUpdateFields)
570  bTableSelBreak = true;
571  }
572  }
573  break;
574 
575  case SwFieldIds::Macro:
576  if( bUpdateFields && pDstTextField->GetpTextNode() )
577  pDstTextField->GetpTextNode()->
578  ModifyNotification( nullptr, pDstFormatField );
579  break;
580 
585  m_rDoc.ChgDBData(static_cast<SwDBNameInfField*>( pNewField)->GetRealDBData());
586  pNewField->GetTyp()->UpdateFields();
587 
588  break;
589 
591 #if HAVE_FEATURE_DBCONNECTIVITY
592  {
593  // JP 10.02.96: call ChgValue, so that the style change sets the
594  // ContentString correctly
595  SwDBField* pDBField = static_cast<SwDBField*>(pNewField);
596  if (pDBField->IsInitialized())
597  pDBField->ChgValue( pDBField->GetValue(), true );
598 
599  pDBField->ClearInitialized();
600  pDBField->InitContent();
601  }
602 #endif
603  [[fallthrough]];
604 
605  default:
606  pDstFormatField->ModifyNotification( nullptr, pMsgHint );
607  }
608 
609  // The fields we can calculate here are being triggered for an update
610  // here explicitly.
611  if( nFieldWhich == SwFieldIds::User )
612  UpdateUsrFields();
613  }
614 
615  return bTableSelBreak;
616 }
617 
620 {
621  for( auto const & pFieldType : *mpFieldTypes )
622  if( SwFieldIds::GetRef == pFieldType->Which() )
623  pFieldType->ModifyNotification( nullptr, nullptr );
624 }
625 
627 {
628  OSL_ENSURE( !pHt || RES_TABLEFML_UPDATE == pHt->Which(),
629  "What MessageItem is this?" );
630 
631  SwFieldType* pFieldType(nullptr);
632 
633  for (auto const & pFieldTypeTmp : *mpFieldTypes)
634  {
635  if( SwFieldIds::Table == pFieldTypeTmp->Which() )
636  {
637  SwTableFormulaUpdate* pUpdateField = nullptr;
638  if( pHt && RES_TABLEFML_UPDATE == pHt->Which() )
639  pUpdateField = static_cast<SwTableFormulaUpdate*>(pHt);
640 
641  SwIterator<SwFormatField,SwFieldType> aIter( *pFieldTypeTmp );
642  for( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() )
643  {
644  if( pFormatField->GetTextField() )
645  {
646  SwTableField* pField = static_cast<SwTableField*>(pFormatField->GetField());
647 
648  if( pUpdateField )
649  {
650  // table where this field is located
651  const SwTableNode* pTableNd;
652  const SwTextNode& rTextNd = pFormatField->GetTextField()->GetTextNode();
653  if(!rTextNd.GetNodes().IsDocNodes())
654  continue;
655  pTableNd = rTextNd.FindTableNode();
656  if (pTableNd == nullptr)
657  continue;
658 
659  switch( pUpdateField->m_eFlags )
660  {
661  case TBL_CALC:
662  // re-set the value flag
663  // JP 17.06.96: internal representation of all formulas
664  // (reference to other table!!!)
665  if( nsSwExtendedSubType::SUB_CMD & pField->GetSubType() )
666  pField->PtrToBoxNm( pUpdateField->m_pTable );
667  else
668  pField->ChgValid( false );
669  break;
670  case TBL_BOXNAME:
671  // is this the wanted table?
672  if( &pTableNd->GetTable() == pUpdateField->m_pTable )
673  // to the external representation
674  pField->PtrToBoxNm( pUpdateField->m_pTable );
675  break;
676  case TBL_BOXPTR:
677  // to the internal representation
678  // JP 17.06.96: internal representation on all formulas
679  // (reference to other table!!!)
680  pField->BoxNmToPtr( pUpdateField->m_pTable );
681  break;
682  case TBL_RELBOXNAME:
683  // is this the wanted table?
684  if( &pTableNd->GetTable() == pUpdateField->m_pTable )
685  // to the relative representation
686  pField->ToRelBoxNm( pUpdateField->m_pTable );
687  break;
688  default:
689  break;
690  }
691  }
692  else
693  // reset the value flag for all
694  pField->ChgValid( false );
695  }
696  }
697  pFieldType = pFieldTypeTmp.get();
698  break;
699  }
700  }
701 
702  // process all table box formulas
704  {
705  auto pBoxFormula = dynamic_cast<const SwTableBoxFormula*>(pItem);
706  if( pBoxFormula && pBoxFormula->GetDefinedIn() )
707  {
708  const_cast<SwTableBoxFormula*>(pBoxFormula)->ChangeState( pHt );
709  }
710  }
711 
712  SwRootFrame const* pLayout(nullptr);
713  for (SwRootFrame const*const pLay : m_rDoc.GetAllLayouts())
714  {
715  assert(!pLayout || pLay->IsHideRedlines() == pLayout->IsHideRedlines()); // TODO
716  pLayout = pLay;
717  }
718 
719  // all fields/boxes are now invalid, so we can start to calculate
720  if( pHt && ( RES_TABLEFML_UPDATE != pHt->Which() ||
721  TBL_CALC != static_cast<SwTableFormulaUpdate*>(pHt)->m_eFlags ))
722  return ;
723 
724  std::unique_ptr<SwCalc, o3tl::default_delete<SwCalc>> pCalc;
725 
726  if( pFieldType )
727  {
728  SwIterator<SwFormatField,SwFieldType> aIter( *pFieldType );
729  for( SwFormatField* pFormatField = aIter.Last(); pFormatField; pFormatField = aIter.Previous() )
730  {
731  // start calculation at the end
732  // new fields are inserted at the beginning of the modify chain
733  // that gives faster calculation on import
734  // mba: do we really need this "optimization"? Is it still valid?
735  if (!pFormatField->GetTextField())
736  continue;
737  SwTableField *const pField(static_cast<SwTableField*>(pFormatField->GetField()));
739  continue;
740 
741  // needs to be recalculated
742  if( !pField->IsValid() )
743  {
744  // table where this field is located
745  const SwTextNode& rTextNd = pFormatField->GetTextField()->GetTextNode();
746  if( !rTextNd.GetNodes().IsDocNodes() )
747  continue;
748  const SwTableNode* pTableNd = rTextNd.FindTableNode();
749  if( !pTableNd )
750  continue;
751 
752  // if this field is not in the to-be-updated table, skip it
753  if( pHt && &pTableNd->GetTable() !=
754  static_cast<SwTableFormulaUpdate*>(pHt)->m_pTable )
755  continue;
756 
757  if( !pCalc )
758  pCalc.reset(new SwCalc( m_rDoc ));
759 
760  // get the values of all SetExpression fields that are valid
761  // until the table
762  SwFrame* pFrame = nullptr;
763  if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
764  {
765  // is in the special section, that's expensive!
766  Point aPt; // return the first frame of the layout - Tab.Headline!!
767  std::pair<Point, bool> const tmp(aPt, true);
768  pFrame = rTextNd.getLayoutFrame(pLayout, nullptr, &tmp);
769  if( pFrame )
770  {
771  SwPosition aPos( *pTableNd );
772  if( GetBodyTextNode( m_rDoc, aPos, *pFrame ) )
773  FieldsToCalc( *pCalc, SetGetExpField(
774  aPos.nNode, pFormatField->GetTextField(),
775  &aPos.nContent), pLayout);
776  else
777  pFrame = nullptr;
778  }
779  }
780  if( !pFrame )
781  {
782  // create index to determine the TextNode
783  SwNodeIndex aIdx( rTextNd );
784  FieldsToCalc( *pCalc,
785  SetGetExpField(aIdx, pFormatField->GetTextField()),
786  pLayout);
787  }
788 
789  SwTableCalcPara aPara(*pCalc, pTableNd->GetTable(), pLayout);
790  pField->CalcField( aPara );
791  if( aPara.IsStackOverflow() )
792  {
793  bool const bResult = aPara.CalcWithStackOverflow();
794  if (bResult)
795  {
796  pField->CalcField( aPara );
797  }
798  OSL_ENSURE(bResult,
799  "the chained formula could no be calculated");
800  }
801  pCalc->SetCalcError( SwCalcError::NONE );
802  }
803  pFormatField->ModifyNotification( nullptr, pHt );
804  }
805  }
806 
807  // calculate the formula at the boxes
809  {
810  auto pFormula = const_cast<SwTableBoxFormula*>(dynamic_cast<const SwTableBoxFormula*>(pItem));
811  if( pFormula && pFormula->GetDefinedIn() && !pFormula->IsValid() )
812  {
813  SwTableBox* pBox = pFormula->GetTableBox();
814  if( pBox && pBox->GetSttNd() &&
815  pBox->GetSttNd()->GetNodes().IsDocNodes() )
816  {
817  const SwTableNode* pTableNd = pBox->GetSttNd()->FindTableNode();
818  if( !pHt || &pTableNd->GetTable() ==
819  static_cast<SwTableFormulaUpdate*>(pHt)->m_pTable )
820  {
821  double nValue;
822  if( !pCalc )
823  pCalc.reset(new SwCalc( m_rDoc ));
824 
825  // get the values of all SetExpression fields that are valid
826  // until the table
827  SwFrame* pFrame = nullptr;
828  if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
829  {
830  // is in the special section, that's expensive!
831  Point aPt; // return the first frame of the layout - Tab.Headline!!
832  SwNodeIndex aCNdIdx( *pTableNd, +2 );
833  SwContentNode* pCNd = aCNdIdx.GetNode().GetContentNode();
834  if( !pCNd )
835  pCNd = m_rDoc.GetNodes().GoNext( &aCNdIdx );
836 
837  std::pair<Point, bool> const tmp(aPt, true);
838  if (pCNd && nullptr != (pFrame = pCNd->getLayoutFrame(
839  pLayout, nullptr, &tmp)))
840  {
841  SwPosition aPos( *pCNd );
842  if( GetBodyTextNode( m_rDoc, aPos, *pFrame ) )
843  FieldsToCalc(*pCalc, SetGetExpField(aPos.nNode),
844  pLayout);
845  else
846  pFrame = nullptr;
847  }
848  }
849  if( !pFrame )
850  {
851  // create index to determine the TextNode
852  SwNodeIndex aIdx( *pTableNd );
853  FieldsToCalc(*pCalc, SetGetExpField(aIdx), pLayout);
854  }
855 
856  SwTableCalcPara aPara(*pCalc, pTableNd->GetTable(), pLayout);
857  pFormula->Calc( aPara, nValue );
858 
859  if( aPara.IsStackOverflow() )
860  {
861  bool const bResult = aPara.CalcWithStackOverflow();
862  if (bResult)
863  {
864  pFormula->Calc( aPara, nValue );
865  }
866  OSL_ENSURE(bResult,
867  "the chained formula could no be calculated");
868  }
869 
870  SwFrameFormat* pFormat = pBox->ClaimFrameFormat();
871  SfxItemSet aTmp( m_rDoc.GetAttrPool(),
873 
874  if( pCalc->IsCalcError() )
875  nValue = DBL_MAX;
876  aTmp.Put( SwTableBoxValue( nValue ));
877  if( SfxItemState::SET != pFormat->GetItemState( RES_BOXATR_FORMAT ))
878  aTmp.Put( SwTableBoxNumFormat( 0 ));
879  pFormat->SetFormatAttr( aTmp );
880 
881  pCalc->SetCalcError( SwCalcError::NONE );
882  }
883  }
884  }
885  }
886 }
887 
888 void DocumentFieldsManager::UpdateExpFields( SwTextField* pUpdateField, bool bUpdRefFields )
889 {
891  return;
892 
893  bool bOldInUpdateFields = mpUpdateFields->IsInUpdateFields();
894  mpUpdateFields->SetInUpdateFields( true );
895 
896  mpUpdateFields->MakeFieldList( m_rDoc, true, GETFLD_ALL );
897  mbNewFieldLst = false;
898 
899  if (mpUpdateFields->GetSortList()->empty())
900  {
901  if( bUpdRefFields )
902  UpdateRefFields();
903 
904  mpUpdateFields->SetInUpdateFields( bOldInUpdateFields );
905  mpUpdateFields->SetFieldsDirty( false );
906  return ;
907  }
908 
909  SwRootFrame const* pLayout(nullptr);
910  SwRootFrame const* pLayoutRLHidden(nullptr);
911  for (SwRootFrame const*const pLay : m_rDoc.GetAllLayouts())
912  {
913  if (pLay->IsHideRedlines())
914  {
915  pLayoutRLHidden = pLay;
916  }
917  else
918  {
919  pLayout = pLay;
920  }
921  }
922  if (pLayout || !pLayoutRLHidden) // always calc *something*...
923  {
924  UpdateExpFieldsImpl(pUpdateField, pLayout);
925  }
926  if (pLayoutRLHidden)
927  {
928  UpdateExpFieldsImpl(pUpdateField, pLayoutRLHidden);
929  }
930 
931  // update reference fields
932  if( bUpdRefFields )
933  UpdateRefFields();
934 
935  mpUpdateFields->SetInUpdateFields( bOldInUpdateFields );
936  mpUpdateFields->SetFieldsDirty( false );
937 }
938 
940  SwTextField * pUpdateField, SwRootFrame const*const pLayout)
941 {
942  SwFieldIds nWhich;
943 
944  // Hash table for all string replacements is filled on-the-fly.
945  // Try to fabricate an uneven number.
946  const SwFieldTypes::size_type nHashSize {(( mpFieldTypes->size() / 7 ) + 1 ) * 7};
947  const sal_uInt16 nStrFormatCnt = static_cast<sal_uInt16>(nHashSize);
948  OSL_ENSURE( nStrFormatCnt == nHashSize, "Downcasting to sal_uInt16 lost information!" );
949  SwHashTable<HashStr> aHashStrTable(nStrFormatCnt);
950 
951  {
952  const SwFieldType* pFieldType;
953  // process separately:
954  for( auto n = mpFieldTypes->size(); n; )
955  {
956  pFieldType = (*mpFieldTypes)[ --n ].get();
957  switch( pFieldType->Which() )
958  {
959  case SwFieldIds::User:
960  {
961  // Entry present?
962  sal_uInt16 nPos;
963  const OUString& rNm = pFieldType->GetName();
964  OUString sExpand(const_cast<SwUserFieldType*>(static_cast<const SwUserFieldType*>(pFieldType))->Expand(nsSwGetSetExpType::GSE_STRING, 0, LANGUAGE_SYSTEM));
965  SwHash* pFnd = aHashStrTable.Find( rNm, &nPos );
966  if( pFnd )
967  // modify entry in the hash table
968  static_cast<HashStr*>(pFnd)->aSetStr = sExpand;
969  else
970  // insert the new entry
971  aHashStrTable[nPos].reset( new HashStr( rNm, sExpand,
972  aHashStrTable[nPos].release() ) );
973  }
974  break;
975  default: break;
976  }
977  }
978  }
979 
980  // The array is filled with all fields; start calculation.
981  SwCalc aCalc( m_rDoc );
982 
983 #if HAVE_FEATURE_DBCONNECTIVITY
984  OUString sDBNumNm( SwFieldType::GetTypeStr( TYP_DBSETNUMBERFLD ) );
985 
986  // already set the current record number
987  SwDBManager* pMgr = m_rDoc.GetDBManager();
988  pMgr->CloseAll( false );
989 
990  SvtSysLocale aSysLocale;
991  const LocaleDataWrapper* pLclData = aSysLocale.GetLocaleDataPtr();
992  const LanguageType nLang = pLclData->getLanguageTag().getLanguageType();
993  bool bCanFill = pMgr->FillCalcWithMergeData( m_rDoc.GetNumberFormatter(), nLang, aCalc );
994 #endif
995 
996  // Make sure we don't hide all content, which would lead to a crash. First, count how many visible sections we have.
997  int nShownSections = 0;
998  sal_uLong nContentStart = m_rDoc.GetNodes().GetEndOfContent().StartOfSectionIndex() + 1;
999  sal_uLong nContentEnd = m_rDoc.GetNodes().GetEndOfContent().GetIndex();
1000  SwSectionFormats& rSectFormats = m_rDoc.GetSections();
1001  for( SwSectionFormats::size_type n = 0; n<rSectFormats.size(); ++n )
1002  {
1003  SwSectionFormat& rSectFormat = *rSectFormats[ n ];
1004  SwSectionNode* pSectionNode = rSectFormat.GetSectionNode();
1005  SwSection* pSect = rSectFormat.GetSection();
1006 
1007  // Usually some of the content is not in a section: count that as a virtual section, so that all real sections can be hidden.
1008  // Only look for section gaps at the lowest level, ignoring sub-sections.
1009  if ( pSectionNode && !rSectFormat.GetParent() )
1010  {
1011  SwNodeIndex aNextIdx( *pSectionNode->EndOfSectionNode(), 1 );
1012  if ( n == 0 && pSectionNode->GetIndex() != nContentStart )
1013  nShownSections++; //document does not start with a section
1014  if ( n == rSectFormats.size() - 1 )
1015  {
1016  if ( aNextIdx.GetIndex() != nContentEnd )
1017  nShownSections++; //document does not end in a section
1018  }
1019  else if ( !aNextIdx.GetNode().IsSectionNode() )
1020  nShownSections++; //section is not immediately followed by another section
1021  }
1022 
1023  // count only visible sections
1024  if ( pSect && !pSect->CalcHiddenFlag())
1025  nShownSections++;
1026  }
1027 
1029  std::unordered_map<SwSetExpFieldType const*, SwTextNode const*> SetExpOutlineNodeMap;
1030 
1031  for (std::unique_ptr<SetGetExpField> const& it : *mpUpdateFields->GetSortList())
1032  {
1033  SwSection* pSect = const_cast<SwSection*>(it->GetSection());
1034  if( pSect )
1035  {
1036  SwSbxValue aValue = aCalc.Calculate(
1037  pSect->GetCondition() );
1038  if(!aValue.IsVoidValue())
1039  {
1040  // Do we want to hide this one?
1041  bool bHide = aValue.GetBool();
1042  if (bHide && !pSect->IsCondHidden())
1043  {
1044  // This section will be hidden, but it wasn't before
1045  if (nShownSections == 1)
1046  {
1047  // This would be the last section, so set its condition to false, and avoid hiding it.
1048  pSect->SetCondition("0");
1049  bHide = false;
1050  }
1051  nShownSections--;
1052  }
1053  pSect->SetCondHidden( bHide );
1054  }
1055  continue;
1056  }
1057 
1058  SwTextField* pTextField = const_cast<SwTextField*>(it->GetTextField());
1059  if( !pTextField )
1060  {
1061  OSL_ENSURE( false, "what's wrong now'" );
1062  continue;
1063  }
1064 
1065  if (pLayout && pLayout->IsHideRedlines()
1066  && IsFieldDeleted(rIDRA, *pLayout, *pTextField))
1067  {
1068  continue;
1069  }
1070 
1071  SwFormatField* pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
1072  const SwField* pField = pFormatField->GetField();
1073 
1074  nWhich = pField->GetTyp()->Which();
1075  switch( nWhich )
1076  {
1078  {
1079  SwHiddenTextField* pHField = const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField));
1080  SwSbxValue aValue = aCalc.Calculate( pHField->GetPar1() );
1081  bool bValue = !aValue.GetBool();
1082  if(!aValue.IsVoidValue())
1083  {
1084  pHField->SetValue( bValue );
1085  // evaluate field
1086  pHField->Evaluate(&m_rDoc);
1087  }
1088  }
1089  break;
1091  {
1092  SwHiddenParaField* pHPField = const_cast<SwHiddenParaField*>(static_cast<const SwHiddenParaField*>(pField));
1093  SwSbxValue aValue = aCalc.Calculate( pHPField->GetPar1() );
1094  bool bValue = aValue.GetBool();
1095  if(!aValue.IsVoidValue())
1096  pHPField->SetHidden( bValue );
1097  }
1098  break;
1100 #if HAVE_FEATURE_DBCONNECTIVITY
1101  {
1102  const_cast<SwDBSetNumberField*>(static_cast<const SwDBSetNumberField*>(pField))->Evaluate(&m_rDoc);
1103  aCalc.VarChange( sDBNumNm, static_cast<const SwDBSetNumberField*>(pField)->GetSetNumber());
1104  pField->ExpandField(m_rDoc.IsClipBoard(), nullptr);
1105  }
1106 #endif
1107  break;
1108  case SwFieldIds::DbNextSet:
1109  case SwFieldIds::DbNumSet:
1110 #if HAVE_FEATURE_DBCONNECTIVITY
1111  {
1112  UpdateDBNumFields( *const_cast<SwDBNameInfField*>(static_cast<const SwDBNameInfField*>(pField)), aCalc );
1113  if( bCanFill )
1114  bCanFill = pMgr->FillCalcWithMergeData( m_rDoc.GetNumberFormatter(), nLang, aCalc );
1115  }
1116 #endif
1117  break;
1118  case SwFieldIds::Database:
1119  {
1120 #if HAVE_FEATURE_DBCONNECTIVITY
1121  // evaluate field
1122  const_cast<SwDBField*>(static_cast<const SwDBField*>(pField))->Evaluate();
1123 
1124  SwDBData aTmpDBData(static_cast<const SwDBField*>(pField)->GetDBData());
1125 
1126  if( pMgr->IsDataSourceOpen(aTmpDBData.sDataSource, aTmpDBData.sCommand, false))
1127  aCalc.VarChange( sDBNumNm, pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType));
1128 
1129  const OUString& rName = pField->GetTyp()->GetName();
1130 
1131  // Add entry to hash table
1132  // Entry present?
1133  sal_uInt16 nPos;
1134  HashStr* pFnd = aHashStrTable.Find( rName, &nPos );
1135  OUString const value(pField->ExpandField(m_rDoc.IsClipBoard(), nullptr));
1136  if( pFnd )
1137  {
1138  // Modify entry in the hash table
1139  pFnd->aSetStr = value;
1140  }
1141  else
1142  {
1143  // insert new entry
1144  aHashStrTable[nPos].reset( new HashStr( rName,
1145  value, aHashStrTable[nPos].release()) );
1146  }
1147 #endif
1148  }
1149  break;
1150  case SwFieldIds::GetExp:
1151  case SwFieldIds::SetExp:
1152  {
1153  if( nsSwGetSetExpType::GSE_STRING & pField->GetSubType() ) // replace String
1154  {
1155  if( SwFieldIds::GetExp == nWhich )
1156  {
1157  SwGetExpField* pGField = const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
1158 
1159  if( (!pUpdateField || pUpdateField == pTextField )
1160  && pGField->IsInBodyText() )
1161  {
1162  OUString aNew = LookString( aHashStrTable, pGField->GetFormula() );
1163  pGField->ChgExpStr( aNew, pLayout );
1164  }
1165  }
1166  else
1167  {
1168  SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
1169  // is the "formula" a field?
1170  OUString aNew = LookString( aHashStrTable, pSField->GetFormula() );
1171 
1172  if( aNew.isEmpty() ) // nothing found then the formula is the new value
1173  aNew = pSField->GetFormula();
1174 
1175  // only update one field
1176  if( !pUpdateField || pUpdateField == pTextField )
1177  pSField->ChgExpStr( aNew, pLayout );
1178 
1179  // lookup the field's name
1180  aNew = static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName();
1181  // Entry present?
1182  sal_uInt16 nPos;
1183  HashStr* pFnd = aHashStrTable.Find( aNew, &nPos );
1184  if( pFnd )
1185  // Modify entry in the hash table
1186  pFnd->aSetStr = pSField->GetExpStr(pLayout);
1187  else
1188  {
1189  // insert new entry
1190  aHashStrTable[nPos].reset( new HashStr( aNew,
1191  pSField->GetExpStr(pLayout),
1192  aHashStrTable[nPos].release() ) );
1193  pFnd = aHashStrTable[nPos].get();
1194  }
1195 
1196  // Extension for calculation with Strings
1197  SwSbxValue aValue;
1198  aValue.PutString( pFnd->aSetStr );
1199  aCalc.VarChange( aNew, aValue );
1200  }
1201  }
1202  else // recalculate formula
1203  {
1204  if( SwFieldIds::GetExp == nWhich )
1205  {
1206  SwGetExpField* pGField = const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
1207 
1208  if( (!pUpdateField || pUpdateField == pTextField )
1209  && pGField->IsInBodyText() )
1210  {
1211  SwSbxValue aValue = aCalc.Calculate(
1212  pGField->GetFormula());
1213  if(!aValue.IsVoidValue())
1214  pGField->SetValue(aValue.GetDouble(), pLayout);
1215  }
1216  }
1217  else
1218  {
1219  SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
1220  SwSetExpFieldType* pSFieldTyp = static_cast<SwSetExpFieldType*>(pField->GetTyp());
1221  OUString aNew = pSFieldTyp->GetName();
1222 
1223  SwNode* pSeqNd = nullptr;
1224 
1225  if( pSField->IsSequenceField() )
1226  {
1227  const sal_uInt8 nLvl = pSFieldTyp->GetOutlineLvl();
1228  if( MAXLEVEL > nLvl )
1229  {
1230  // test if the Number needs to be updated
1231  pSeqNd = m_rDoc.GetNodes()[ it->GetNode() ];
1232 
1233  const SwTextNode* pOutlNd = pSeqNd->
1234  FindOutlineNodeOfLevel(nLvl, pLayout);
1235  auto const iter(SetExpOutlineNodeMap.find(pSFieldTyp));
1236  if (iter == SetExpOutlineNodeMap.end()
1237  || iter->second != pOutlNd)
1238  {
1239  SetExpOutlineNodeMap[pSFieldTyp] = pOutlNd;
1240  aCalc.VarChange( aNew, 0 );
1241  }
1242  }
1243  }
1244 
1245  aNew += "=";
1246  aNew += pSField->GetFormula();
1247 
1248  SwSbxValue aValue = aCalc.Calculate( aNew );
1249  double nErg = aValue.GetDouble();
1250  // only update one field
1251  if( !aValue.IsVoidValue() && (!pUpdateField || pUpdateField == pTextField) )
1252  {
1253  pSField->SetValue(nErg, pLayout);
1254 
1255  if( pSeqNd )
1256  pSFieldTyp->SetChapter(*pSField, *pSeqNd, pLayout);
1257  }
1258  }
1259  }
1260  }
1261  break;
1262  default: break;
1263  } // switch
1264 
1265  {
1266  // avoid calling ReplaceText() for input fields, it is pointless
1267  // here and moves the cursor if it's inside the field ...
1268  SwTextInputField *const pInputField(
1269  pUpdateField == pTextField // ... except once, when the dialog
1270  ? nullptr // is used to change content via UpdateOneField()
1271  : dynamic_cast<SwTextInputField *>(pTextField));
1272  if (pInputField)
1273  {
1274  bool const tmp = pInputField->LockNotifyContentChange();
1275  (void) tmp;
1276  assert(tmp && "should not be locked here?");
1277  }
1278  ::comphelper::ScopeGuard g([pInputField]()
1279  {
1280  if (pInputField)
1281  {
1282  pInputField->UnlockNotifyContentChange();
1283  }
1284  });
1285  pFormatField->ModifyNotification(nullptr, nullptr); // trigger formatting
1286  }
1287 
1288  if (pUpdateField == pTextField) // if only this one is updated
1289  {
1290  if( SwFieldIds::GetExp == nWhich || // only GetField or
1291  SwFieldIds::HiddenText == nWhich || // HiddenText?
1292  SwFieldIds::HiddenPara == nWhich) // HiddenParaField?
1293  break; // quit
1294  pUpdateField = nullptr; // update all from here on
1295  }
1296  }
1297 
1298 #if HAVE_FEATURE_DBCONNECTIVITY
1299  pMgr->CloseAll(false);
1300 #endif
1301 }
1302 
1305 {
1306  SwCalc* pCalc = nullptr;
1307  for( SwFieldTypes::size_type i = INIT_FLDTYPES; i < mpFieldTypes->size(); ++i )
1308  {
1309  const SwFieldType* pFieldType = (*mpFieldTypes)[i].get();
1310  if( SwFieldIds::User == pFieldType->Which() )
1311  {
1312  if( !pCalc )
1313  pCalc = new SwCalc( m_rDoc );
1314  const_cast<SwUserFieldType*>(static_cast<const SwUserFieldType*>(pFieldType))->GetValue( *pCalc );
1315  }
1316  }
1317 
1318  if( pCalc )
1319  {
1320  delete pCalc;
1322  }
1323 }
1324 
1326 {
1327  sal_Int32 nRecords = 1;
1328 
1329  mpUpdateFields->MakeFieldList( m_rDoc, true, GETFLD_ALL );
1330  if (mpUpdateFields->GetSortList()->empty())
1331  return nRecords;
1332 
1333  for (std::unique_ptr<SetGetExpField> const& it : *mpUpdateFields->GetSortList())
1334  {
1335  const SwTextField *pTextField = it->GetTextField();
1336  if( !pTextField )
1337  continue;
1338 
1339  const SwFormatField &pFormatField = pTextField->GetFormatField();
1340  const SwField* pField = pFormatField.GetField();
1341 
1342  switch( pField->GetTyp()->Which() )
1343  {
1344  case SwFieldIds::DbNextSet:
1345  case SwFieldIds::DbNumSet:
1346  nRecords++;
1347  break;
1348  default:
1349  break;
1350  }
1351  }
1352 
1353  return nRecords;
1354 }
1355 
1357 {
1358  for( SwFieldTypes::size_type i = 0; i < INIT_FLDTYPES; ++i )
1359  {
1360  SwFieldType* pFieldType = (*mpFieldTypes)[ i ].get();
1361  switch( pFieldType->Which() )
1362  {
1364  case SwFieldIds::Chapter:
1365  case SwFieldIds::GetExp:
1367  pFieldType->ModifyNotification( nullptr, pMsgHint );
1368  break;
1369  case SwFieldIds::DocStat:
1370  pFieldType->ModifyNotification( nullptr, nullptr );
1371  break;
1372  default: break;
1373  }
1374  }
1375  SetNewFieldLst(true);
1376 }
1377 
1379 {
1380  ++mnLockExpField;
1381 }
1382 
1384 {
1385  assert(mnLockExpField != 0);
1386  if( mnLockExpField )
1387  --mnLockExpField;
1388 }
1389 
1391 {
1392  return 0 != mnLockExpField;
1393 }
1394 
1396 {
1397  return *mpUpdateFields;
1398 }
1399 
1400 bool DocumentFieldsManager::SetFieldsDirty( bool b, const SwNode* pChk, sal_uLong nLen )
1401 {
1402  // See if the supplied nodes actually contain fields.
1403  // If they don't, the flag doesn't need to be changed.
1404  bool bFieldsFnd = false;
1405  if( b && pChk && !GetUpdateFields().IsFieldsDirty() && !m_rDoc.IsInDtor()
1406  // ?? what's up with Undo, this is also wanted there!
1407  /*&& &pChk->GetNodes() == &GetNodes()*/ )
1408  {
1409  b = false;
1410  if( !nLen )
1411  ++nLen;
1412  sal_uLong nStt = pChk->GetIndex();
1413  const SwNodes& rNds = pChk->GetNodes();
1414  while( nLen-- )
1415  {
1416  const SwTextNode* pTNd = rNds[ nStt++ ]->GetTextNode();
1417  if( pTNd )
1418  {
1419  if( pTNd->GetAttrOutlineLevel() != 0 )
1420  // update chapter fields
1421  b = true;
1422  else if( pTNd->GetpSwpHints() && pTNd->GetSwpHints().Count() )
1423  {
1424  const size_t nEnd = pTNd->GetSwpHints().Count();
1425  for( size_t n = 0 ; n < nEnd; ++n )
1426  {
1427  const SwTextAttr* pAttr = pTNd->GetSwpHints().Get(n);
1428  if ( pAttr->Which() == RES_TXTATR_FIELD
1429  || pAttr->Which() == RES_TXTATR_INPUTFIELD)
1430  {
1431  b = true;
1432  break;
1433  }
1434  }
1435  }
1436 
1437  if( b )
1438  break;
1439  }
1440  }
1441  bFieldsFnd = b;
1442  }
1444  return bFieldsFnd;
1445 }
1446 
1448 {
1449  bool bIsModified = m_rDoc.getIDocumentState().IsModified();
1450 
1451  sal_Int32 nDate;
1452  sal_Int64 nTime;
1453  if( pNewDateTime )
1454  {
1455  nDate = pNewDateTime->GetDate();
1456  nTime = pNewDateTime->GetTime();
1457  }
1458  else
1459  {
1460  DateTime aDateTime( DateTime::SYSTEM );
1461  nDate = aDateTime.GetDate();
1462  nTime = aDateTime.GetTime();
1463  }
1464 
1465  SwFieldIds const aTypes[] {
1466  /*0*/ SwFieldIds::DocInfo,
1467  /*1*/ SwFieldIds::Author,
1468  /*2*/ SwFieldIds::ExtUser,
1469  /*3*/ SwFieldIds::Filename,
1470  /*4*/ SwFieldIds::DateTime }; // MUST be at the end!
1471 
1472  for(SwFieldIds aType : aTypes)
1473  {
1474  SwFieldType* pFieldType = GetSysFieldType( aType );
1475  SwIterator<SwFormatField,SwFieldType> aIter( *pFieldType );
1476  for( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() )
1477  {
1478  if (pFormatField->GetTextField())
1479  {
1480  bool bChgd = false;
1481  switch( aType )
1482  {
1483  case SwFieldIds::DocInfo:
1484  if( static_cast<SwDocInfoField*>(pFormatField->GetField())->IsFixed() )
1485  {
1486  bChgd = true;
1487  SwDocInfoField* pDocInfField = static_cast<SwDocInfoField*>(pFormatField->GetField());
1488  pDocInfField->SetExpansion( static_cast<SwDocInfoFieldType*>(
1489  pDocInfField->GetTyp())->Expand(
1490  pDocInfField->GetSubType(),
1491  pDocInfField->GetFormat(),
1492  pDocInfField->GetLanguage(),
1493  pDocInfField->GetName() ) );
1494  }
1495  break;
1496 
1497  case SwFieldIds::Author:
1498  if( static_cast<SwAuthorField*>(pFormatField->GetField())->IsFixed() )
1499  {
1500  bChgd = true;
1501  SwAuthorField* pAuthorField = static_cast<SwAuthorField*>(pFormatField->GetField());
1502  pAuthorField->SetExpansion( SwAuthorFieldType::Expand( pAuthorField->GetFormat() ) );
1503  }
1504  break;
1505 
1506  case SwFieldIds::ExtUser:
1507  if( static_cast<SwExtUserField*>(pFormatField->GetField())->IsFixed() )
1508  {
1509  bChgd = true;
1510  SwExtUserField* pExtUserField = static_cast<SwExtUserField*>(pFormatField->GetField());
1511  pExtUserField->SetExpansion( SwExtUserFieldType::Expand(pExtUserField->GetSubType()) );
1512  }
1513  break;
1514 
1515  case SwFieldIds::DateTime:
1516  if( static_cast<SwDateTimeField*>(pFormatField->GetField())->IsFixed() )
1517  {
1518  bChgd = true;
1519  static_cast<SwDateTimeField*>(pFormatField->GetField())->SetDateTime(
1520  DateTime(Date(nDate), tools::Time(nTime)) );
1521  }
1522  break;
1523 
1524  case SwFieldIds::Filename:
1525  if( static_cast<SwFileNameField*>(pFormatField->GetField())->IsFixed() )
1526  {
1527  bChgd = true;
1528  SwFileNameField* pFileNameField =
1529  static_cast<SwFileNameField*>(pFormatField->GetField());
1530  pFileNameField->SetExpansion( static_cast<SwFileNameFieldType*>(
1531  pFileNameField->GetTyp())->Expand(
1532  pFileNameField->GetFormat() ) );
1533  }
1534  break;
1535  default: break;
1536  }
1537 
1538  // Trigger formatting
1539  if( bChgd )
1540  pFormatField->ModifyNotification( nullptr, nullptr );
1541  }
1542  }
1543  }
1544 
1545  if( !bIsModified )
1547 }
1548 
1550  const SetGetExpField& rToThisField, SwRootFrame const*const pLayout)
1551 {
1552  // create the sorted list of all SetFields
1553  mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_CALC );
1554  mbNewFieldLst = false;
1555 
1556 #if !HAVE_FEATURE_DBCONNECTIVITY
1557  SwDBManager* pMgr = NULL;
1558 #else
1559  SwDBManager* pMgr = m_rDoc.GetDBManager();
1560  pMgr->CloseAll(false);
1561 #endif
1562 
1563  if (!mpUpdateFields->GetSortList()->empty())
1564  {
1565  SetGetExpFields::const_iterator const itLast =
1566  mpUpdateFields->GetSortList()->upper_bound(
1567  &rToThisField);
1568  for (auto it = mpUpdateFields->GetSortList()->begin(); it != itLast; ++it)
1569  {
1570  lcl_CalcField(m_rDoc, rCalc, **it, pMgr, pLayout);
1571  }
1572  }
1573 #if HAVE_FEATURE_DBCONNECTIVITY
1574  pMgr->CloseAll(false);
1575 #endif
1576 }
1577 
1578 void DocumentFieldsManager::FieldsToCalc( SwCalc& rCalc, sal_uLong nLastNd, sal_uInt16 nLastCnt )
1579 {
1580  // create the sorted list of all SetFields
1581  mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_CALC );
1582  mbNewFieldLst = false;
1583 
1584 #if !HAVE_FEATURE_DBCONNECTIVITY
1585  SwDBManager* pMgr = NULL;
1586 #else
1587  SwDBManager* pMgr = m_rDoc.GetDBManager();
1588  pMgr->CloseAll(false);
1589 #endif
1590 
1591  SwRootFrame const* pLayout(nullptr);
1592  SwRootFrame const* pLayoutRLHidden(nullptr);
1593  for (SwRootFrame const*const pLay : m_rDoc.GetAllLayouts())
1594  {
1595  if (pLay->IsHideRedlines())
1596  {
1597  pLayoutRLHidden = pLay;
1598  }
1599  else
1600  {
1601  pLayout = pLay;
1602  }
1603  }
1604 
1605  // note this is not duplicate of the other FieldsToCalc because there is
1606  // (currently) no SetGetExpField that compares only a position
1607  for(auto it = mpUpdateFields->GetSortList()->begin();
1608  it != mpUpdateFields->GetSortList()->end() &&
1609  ( (*it)->GetNode() < nLastNd ||
1610  ( (*it)->GetNode() == nLastNd && (*it)->GetContent() <= nLastCnt )
1611  );
1612  ++it )
1613  {
1614  if (pLayout || !pLayoutRLHidden) // always calc *something*...
1615  {
1616  lcl_CalcField( m_rDoc, rCalc, **it, pMgr, pLayout );
1617  }
1618  if (pLayoutRLHidden)
1619  {
1620  lcl_CalcField( m_rDoc, rCalc, **it, pMgr, pLayoutRLHidden );
1621  }
1622  }
1623 
1624 #if HAVE_FEATURE_DBCONNECTIVITY
1625  pMgr->CloseAll(false);
1626 #endif
1627 }
1628 
1630  const SetGetExpField& rToThisField, SwRootFrame const& rLayout)
1631 {
1632  // create the sorted list of all SetFields
1633  mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_EXPAND );
1634  mbNewFieldLst = false;
1635 
1637 
1638  // Hash table for all string replacements is filled on-the-fly.
1639  // Try to fabricate an uneven number.
1640  sal_uInt16 nTableSize = ((mpUpdateFields->GetSortList()->size() / 7) + 1) * 7;
1641  rHashTable.resize(nTableSize);
1642 
1643  SetGetExpFields::const_iterator const itLast =
1644  mpUpdateFields->GetSortList()->upper_bound(&rToThisField);
1645 
1646  for (auto it = mpUpdateFields->GetSortList()->begin(); it != itLast; ++it)
1647  {
1648  const SwTextField* pTextField = (*it)->GetTextField();
1649  if( !pTextField )
1650  continue;
1651 
1652  if (rLayout.IsHideRedlines()
1653  && IsFieldDeleted(rIDRA, rLayout, *pTextField))
1654  {
1655  continue;
1656  }
1657 
1658  const SwField* pField = pTextField->GetFormatField().GetField();
1659  switch( pField->GetTyp()->Which() )
1660  {
1661  case SwFieldIds::SetExp:
1662  if( nsSwGetSetExpType::GSE_STRING & pField->GetSubType() )
1663  {
1664  // set the new value in the hash table
1665  // is the formula a field?
1666  SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
1667  OUString aNew = LookString( rHashTable, pSField->GetFormula() );
1668 
1669  if( aNew.isEmpty() ) // nothing found, then the formula is
1670  aNew = pSField->GetFormula(); // the new value
1671 
1672  // #i3141# - update expression of field as in method
1673  // <SwDoc::UpdateExpFields(..)> for string/text fields
1674  pSField->ChgExpStr(aNew, &rLayout);
1675 
1676  // look up the field's name
1677  aNew = static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName();
1678  // Entry present?
1679  sal_uInt16 nPos;
1680  SwHash* pFnd = rHashTable.Find( aNew, &nPos );
1681  if( pFnd )
1682  // modify entry in the hash table
1683  static_cast<HashStr*>(pFnd)->aSetStr = pSField->GetExpStr(&rLayout);
1684  else
1685  // insert the new entry
1686  rHashTable[nPos].reset( new HashStr( aNew,
1687  pSField->GetExpStr(&rLayout), rHashTable[nPos].release()));
1688  }
1689  break;
1690  case SwFieldIds::Database:
1691  {
1692  const OUString& rName = pField->GetTyp()->GetName();
1693 
1694  // Insert entry in the hash table
1695  // Entry present?
1696  sal_uInt16 nPos;
1697  HashStr* pFnd = rHashTable.Find( rName, &nPos );
1698  OUString const value(pField->ExpandField(m_rDoc.IsClipBoard(), nullptr));
1699  if( pFnd )
1700  {
1701  // modify entry in the hash table
1702  pFnd->aSetStr = value;
1703  }
1704  else
1705  {
1706  // insert the new entry
1707  rHashTable[nPos].reset( new HashStr( rName,
1708  value, rHashTable[nPos].release()) );
1709  }
1710  }
1711  break;
1712  default: break;
1713  }
1714  }
1715 }
1716 
1717 
1719 {
1720  return mbNewFieldLst;
1721 }
1722 
1724 {
1725  mbNewFieldLst = bFlag;
1726 }
1727 
1729 {
1730  if (!mbNewFieldLst && !m_rDoc.IsInDtor())
1731  mpUpdateFields->InsDelFieldInFieldLst( bIns, rField );
1732 }
1733 
1735 {
1736  SwTextField * const pAttr = GetTextFieldAtPos(rPos);
1737 
1738  return pAttr ? const_cast<SwField *>( pAttr->GetFormatField().GetField() ) : nullptr;
1739 }
1740 
1742 {
1743  SwTextNode * const pNode = rPos.nNode.GetNode().GetTextNode();
1744 
1745  return (pNode != nullptr)
1746  ? pNode->GetFieldTextAttrAt( rPos.nContent.GetIndex(), true )
1747  : nullptr;
1748 }
1749 
1753 {
1754  for (auto const & pFieldType : *mpFieldTypes)
1755  {
1756  SwIterator<SwFormatField,SwFieldType> aIter(*pFieldType);
1757  if (aIter.First())
1758  return true;
1759  }
1760  return false;
1761 }
1762 
1765 {
1766  for( auto n = mpFieldTypes->size(); n > INIT_FLDTYPES; )
1767  if( !(*mpFieldTypes)[ --n ]->HasWriterListeners() )
1768  RemoveFieldType( n );
1769 }
1770 
1771 void DocumentFieldsManager::InitFieldTypes() // is being called by the CTOR
1772 {
1773  // Field types
1774  mpFieldTypes->emplace_back( new SwDateTimeFieldType(&m_rDoc) );
1775  mpFieldTypes->emplace_back( new SwChapterFieldType );
1776  mpFieldTypes->emplace_back( new SwPageNumberFieldType );
1777  mpFieldTypes->emplace_back( new SwAuthorFieldType );
1778  mpFieldTypes->emplace_back( new SwFileNameFieldType(&m_rDoc) );
1779  mpFieldTypes->emplace_back( new SwDBNameFieldType(&m_rDoc) );
1780  mpFieldTypes->emplace_back( new SwGetExpFieldType(&m_rDoc) );
1781  mpFieldTypes->emplace_back( new SwGetRefFieldType( &m_rDoc ) );
1782  mpFieldTypes->emplace_back( new SwHiddenTextFieldType );
1783  mpFieldTypes->emplace_back( new SwPostItFieldType(&m_rDoc) );
1784  mpFieldTypes->emplace_back( new SwDocStatFieldType(&m_rDoc) );
1785  mpFieldTypes->emplace_back( new SwDocInfoFieldType(&m_rDoc) );
1786  mpFieldTypes->emplace_back( new SwInputFieldType( &m_rDoc ) );
1787  mpFieldTypes->emplace_back( new SwTableFieldType( &m_rDoc ) );
1788  mpFieldTypes->emplace_back( new SwMacroFieldType(&m_rDoc) );
1789  mpFieldTypes->emplace_back( new SwHiddenParaFieldType );
1790  mpFieldTypes->emplace_back( new SwDBNextSetFieldType );
1791  mpFieldTypes->emplace_back( new SwDBNumSetFieldType );
1792  mpFieldTypes->emplace_back( new SwDBSetNumberFieldType );
1793  mpFieldTypes->emplace_back( new SwTemplNameFieldType(&m_rDoc) );
1794  mpFieldTypes->emplace_back( new SwTemplNameFieldType(&m_rDoc) );
1795  mpFieldTypes->emplace_back( new SwExtUserFieldType );
1796  mpFieldTypes->emplace_back( new SwRefPageSetFieldType );
1797  mpFieldTypes->emplace_back( new SwRefPageGetFieldType( &m_rDoc ) );
1798  mpFieldTypes->emplace_back( new SwJumpEditFieldType( &m_rDoc ) );
1799  mpFieldTypes->emplace_back( new SwScriptFieldType( &m_rDoc ) );
1800  mpFieldTypes->emplace_back( new SwCombinedCharFieldType );
1801  mpFieldTypes->emplace_back( new SwDropDownFieldType );
1802 
1803  // Types have to be at the end!
1804  // We expect this in the InsertFieldType!
1805  // MIB 14.04.95: In Sw3StringPool::Setup (sw3imp.cxx) and
1806  // lcl_sw3io_InSetExpField (sw3field.cxx) now also
1807  mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
1808  SwResId(STR_POOLCOLL_LABEL_ABB), nsSwGetSetExpType::GSE_SEQ) );
1809  mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
1810  SwResId(STR_POOLCOLL_LABEL_TABLE), nsSwGetSetExpType::GSE_SEQ) );
1811  mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
1812  SwResId(STR_POOLCOLL_LABEL_FRAME), nsSwGetSetExpType::GSE_SEQ) );
1813  mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
1814  SwResId(STR_POOLCOLL_LABEL_DRAWING), nsSwGetSetExpType::GSE_SEQ) );
1815  mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
1816  SwResId(STR_POOLCOLL_LABEL_FIGURE), nsSwGetSetExpType::GSE_SEQ) );
1817 
1818  assert( mpFieldTypes->size() == INIT_FLDTYPES );
1819 }
1820 
1822 {
1823  mpFieldTypes->erase( mpFieldTypes->begin() + INIT_FLDTYPES, mpFieldTypes->end() );
1824 }
1825 
1827 {
1828 #if !HAVE_FEATURE_DBCONNECTIVITY
1829  (void) rDBField;
1830  (void) rCalc;
1831 #else
1832  SwDBManager* pMgr = m_rDoc.GetDBManager();
1833 
1834  SwFieldIds nFieldType = rDBField.Which();
1835 
1836  bool bPar1 = rCalc.Calculate( rDBField.GetPar1() ).GetBool();
1837 
1838  if( SwFieldIds::DbNextSet == nFieldType )
1839  static_cast<SwDBNextSetField&>(rDBField).SetCondValid( bPar1 );
1840  else
1841  static_cast<SwDBNumSetField&>(rDBField).SetCondValid( bPar1 );
1842 
1843  if( !rDBField.GetRealDBData().sDataSource.isEmpty() )
1844  {
1845  // Edit a certain database
1846  if( SwFieldIds::DbNextSet == nFieldType )
1847  static_cast<SwDBNextSetField&>(rDBField).Evaluate(&m_rDoc);
1848  else
1849  static_cast<SwDBNumSetField&>(rDBField).Evaluate(&m_rDoc);
1850 
1851  SwDBData aTmpDBData( rDBField.GetDBData(&m_rDoc) );
1852 
1853  if( pMgr->OpenDataSource( aTmpDBData.sDataSource, aTmpDBData.sCommand ))
1854  rCalc.VarChange( lcl_GetDBVarName( m_rDoc, rDBField),
1855  pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType) );
1856  }
1857  else
1858  {
1859  OSL_FAIL("TODO: what should happen with unnamed DBFields?");
1860  }
1861 #endif
1862 }
1863 
1865 {
1866  mpUpdateFields.reset();
1867  mpFieldTypes.reset();
1868 }
1869 
1870 }
1871 
1872 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool UpdateField(SwTextField *rDstFormatField, SwField &rSrcField, SwMsgPoolItem *pMsgHint, bool bUpdateTableFields) override
Updates a field.
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:233
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
void SetValue(bool bHidden)
Definition: docufld.hxx:325
Base class of the Writer layout elements.
Definition: frame.hxx:295
const ::utl::TransliterationWrapper & GetAppCmpStrIgnore()
Definition: init.cxx:834
bool CalcWithStackOverflow()
Definition: cellfml.cxx:274
std::unique_ptr< SwFieldTypes > mpFieldTypes
#define RES_BOXATR_BEGIN
Definition: hintids.hxx:260
virtual sal_uInt16 GetSubType() const override
Definition: tblcalc.cxx:127
Definition: calc.hxx:184
Definition: calc.hxx:124
void ChgValue(double d, bool bVal)
For calculations in expressions.
Definition: dbfld.cxx:250
bool IsCondValid() const
Definition: dbfld.hxx:181
sal_uLong GetIndex() const
Definition: node.hxx:282
virtual void UpdateExpFields(SwTextField *pField, bool bUpdateRefFields) override
sal_Int32 nCommandType
Definition: swdbdata.hxx:32
void CalcField(SwTableCalcPara &rCalcPara)
Definition: tblcalc.cxx:46
The shared part of a user field.
Definition: usrfld.hxx:35
void ChgDBData(const SwDBData &rNewData)
Definition: doc.cxx:485
Marks a position in the document model.
Definition: pam.hxx:35
virtual bool IsNewFieldLst() const override
IJScriptValueObject VARIANT value
virtual void UpdateRefFields() override
Update reference and table fields.
const SwField * GetField() const
Definition: fmtfld.hxx:71
const LocaleDataWrapper * GetLocaleDataPtr() const
LanguageType GetLanguage() const
Language at field position.
Definition: fldbas.hxx:392
sal_uLong StartOfSectionIndex() const
Definition: node.hxx:673
virtual void LockExpFields() override
virtual void SetNewFieldLst(bool bFlag) override
virtual SwFieldType * InsertFieldType(const SwFieldType &) override
Insert field types.
sal_uInt32 GetFormat() const
Query parameters for dialog and for BASIC.
Definition: fldbas.hxx:387
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:219
virtual sal_uInt16 GetSubType() const override
Definition: docufld.cxx:2000
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1399
void ChgExpStr(const OUString &rExpand, SwRootFrame const *pLayout)
Definition: expfld.cxx:540
SwNodeIndex nNode
Definition: pam.hxx:37
LanguageType getLanguageType(bool bResolveSystem=true) const
virtual std::unique_ptr< SwFieldType > Copy() const =0
const int GETFLD_ALL
Definition: docfld.hxx:127
const SwTextNode * GetBodyTextNode(const SwDoc &rDoc, SwPosition &rPos, const SwFrame &rFrame)
Forward declaration: get "BodyTextNode" for exp.fld in Fly's headers/footers/footnotes.
Definition: expfld.cxx:166
bool OpenDataSource(const OUString &rDataSource, const OUString &rTableOrQuery)
open the source while fields are updated - for the calculator only!
Definition: dbmgr.cxx:2377
virtual void SetModified()=0
Must be called manually at changes of format.
sal_uIntPtr sal_uLong
bool IsInitialized() const
Definition: dbfld.hxx:94
OUString sDataSource
Definition: swdbdata.hxx:30
virtual void SetValue(const double &rVal) override
Definition: expfld.cxx:944
const OUString & GetExpStr(SwRootFrame const *pLayout) const
Definition: expfld.cxx:535
Base class of all fields.
Definition: fldbas.hxx:279
virtual void SetFixFields(const DateTime *pNewDateTime) override
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1150
Definition: doc.hxx:185
TElementType * Next()
Definition: calbck.hxx:376
std::unique_ptr< SwField > CopyField() const
Definition: fldbas.cxx:432
sal_Int32 GetLong() const
SwNode & GetNode() const
Definition: ndindex.hxx:118
SwTextNode * GetpTextNode() const
Definition: txtfld.hxx:49
const SwDBData & GetDBData() const
Definition: dbfld.hxx:127
static SwField * GetFieldAtPos(const SwPosition &rPos)
Returns the field at a certain position.
Dialog to specify the properties of date form field.
Definition: accfrmobj.cxx:40
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:176
const OUString & GetName() const
Definition: docufld.hxx:525
sal_uInt16 Which() const
Definition: txatbase.hxx:110
OUString LookString(SwHashTable< HashStr > const &rTable, const OUString &rName)
Look up the Name, if it is present, return its String, otherwise return an empty String.
Definition: docfld.cxx:345
bool HasWriterListeners() const
Definition: calbck.hxx:211
The root element of a Writer document layout.
Definition: rootfrm.hxx:79
For old documents the Field-Which IDs must be preserved !!!
bool IsCondHidden() const
Definition: section.hxx:193
virtual void UpdatePageFields(SfxPoolItem *) override
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4030
OUString const & GetCondition() const
Definition: section.hxx:199
static LanguageType nLang
Definition: srtdlg.cxx:58
Array of Undo-history.
Definition: docary.hxx:299
void UpdateFields() const
Definition: fldbas.hxx:271
#define RES_UPDATEDDETBL
Definition: hintids.hxx:293
void SetChapter(SwSetExpField &rField, const SwNode &rNd, SwRootFrame const *pLayout)
Definition: expfld.cxx:648
void UpdateExpFieldsImpl(SwTextField *pField, SwRootFrame const *pLayout)
virtual OUString GetPar1() const
Definition: fldbas.cxx:271
return NULL
#define RES_TABLEFML_UPDATE
Definition: hintids.hxx:292
void BoxNmToPtr(const SwTable *pTable)
create from the external formula the internal
Definition: cellfml.cxx:567
SwIndex nContent
Definition: pam.hxx:38
void VarChange(const OUString &rStr, const SwSbxValue &rValue)
Definition: calc.cxx:577
virtual void UpdateFields(bool bCloseDB) override
SwSectionNode * GetSectionNode()
Definition: section.cxx:1007
void ChgExpStr(const OUString &rExpand, SwRootFrame const *pLayout)
Definition: expfld.cxx:296
virtual bool PutValue(const css::uno::Any &rVal, sal_uInt16 nWhichId)
Definition: fldbas.cxx:314
virtual sal_uInt16 GetSubType() const override
Definition: docufld.cxx:1138
const SwTable * m_pTable
Pointer to the current table.
Definition: hints.hxx:201
sal_Int32 GetStart() const
Definition: txatbase.hxx:82
Field type for dropdown boxes.
Definition: flddropdown.hxx:31
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
virtual void UpdateTableFields(SfxPoolItem *pHt) override
void SetField(std::unique_ptr< SwField > pField)
Sets current field.
Definition: atrfld.cxx:175
virtual void SetValue(const double &rVal) override
Definition: expfld.cxx:907
void SetExpansion(const OUString &rStr)
Definition: docufld.hxx:193
const SwTable & GetTable() const
Definition: node.hxx:497
virtual bool IsExpFieldsLocked() const override
Implementation in tblcalc.cxx.
Definition: expfld.hxx:367
sal_Int32 GetDate() const
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:191
void Evaluate(SwDoc const *)
Definition: dbfld.cxx:823
virtual bool DoesUndo() const =0
Is Undo enabled?
void SetExpansion(const OUString &rStr)
Definition: docufld.hxx:527
virtual SwDocUpdateField & GetUpdateFields() const override
const SwGetSetExpType GSE_EXPR
Expression.
Definition: fldbas.hxx:196
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt16 nWhichId) const
Definition: fldbas.cxx:301
void PtrToBoxNm(const SwTable *pTable)
create from the internal formula (for CORE) the external formula (for UI)
Definition: cellfml.cxx:542
void Evaluate(SwDoc *)
get current field value and cache it
Definition: docufld.cxx:1328
#define INIT_SEQ_FLDTYPES
Definition: swtypes.hxx:122
TElementType * Previous()
Definition: calbck.hxx:401
virtual void ModifyNotification(const SfxPoolItem *pOldValue, const SfxPoolItem *pNewValue)
Definition: calbck.hxx:154
static SwTextField * GetTextFieldAtPos(const SwPosition &rPos)
Returns the field at a certain position.
virtual OUString GetPar1() const override
Query, set condition.
Definition: docufld.cxx:1710
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:164
virtual void RemoveFieldType(size_t nField) override
Remove field type.
SwSbxValue nValue
Definition: calc.hxx:134
virtual void FieldsToCalc(SwCalc &rCalc, sal_uLong nLastNd, sal_uInt16 nLastCnt) override
double GetDouble() const
Definition: calc.cxx:1412
virtual void AppendUndo(std::unique_ptr< SwUndo > pUndo)=0
Add new Undo action.
Style of a layout element.
Definition: frmfmt.hxx:57
size_t Count() const
Definition: ndhints.hxx:142
void SetExpansion(const OUString &rStr)
Definition: docufld.hxx:219
virtual bool SetFieldsDirty(bool b, const SwNode *pChk, sal_uLong nLen) override
SwTextAttr * Get(size_t nPos) const
Definition: ndhints.hxx:144
SwDBData const & GetDBData()
Definition: docfld.cxx:354
const SwExtendedSubType SUB_CMD
Show command.
Definition: fldbas.hxx:204
std::vector< SwSectionFormat * >::size_type size_type
Definition: docary.hxx:70
void SetCondHidden(bool const bFlag)
Definition: section.cxx:538
bool IsValid() const
Definition: cellfml.hxx:133
virtual ~DocumentFieldsManager() override
virtual bool IsModified() const =0
Changes of document?
bool IsSequenceField() const
Definition: expfld.hxx:268
void Evaluate()
Get the evaluation via DBManager string.
Definition: dbfld.cxx:316
#define LANGUAGE_SYSTEM
TElementType * First()
Definition: calbck.hxx:345
int i
SwContentNode * GetContentNode()
Definition: node.hxx:615
vector_type::size_type size_type
Definition: docary.hxx:330
SwFieldIds
Definition: fldbas.hxx:38
#define RES_BOXATR_END
Definition: hintids.hxx:264
virtual void FieldsToExpand(SwHashTable< HashStr > &rTable, const SetGetExpField &rToThisField, SwRootFrame const &rLayout) override
bool IsInBodyText() const
Called by formatting.
Definition: expfld.hxx:135
size_t size() const
Definition: docary.hxx:91
void CloseAll(bool bIncludingMerge=true)
close all data sources - after fields were updated
Definition: dbmgr.cxx:2494
virtual SwFieldType * GetFieldType(SwFieldIds nResId, const OUString &rName, bool bDbFieldMatching) const override
Find first type with ResId and name.
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:426
virtual OUString GetFormula() const override
Definition: fldbas.cxx:696
std::set< SwRootFrame * > GetAllLayouts()
Definition: doclay.cxx:1673
size
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:398
double GetValue(SwCalc &rCalc)
Definition: usrfld.cxx:237
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:693
T * Find(const OUString &rStr, sal_uInt16 *pPos=nullptr) const
Definition: calc.hxx:152
SwpHints & GetSwpHints()
getters for SwpHints
Definition: ndtxt.hxx:809
OUString SwResId(const char *pId)
Definition: swmodule.cxx:191
SwTextField * GetFieldTextAttrAt(const sal_Int32 nIndex, const bool bIncludeInputFieldAtStart=false) const
Definition: ndtxt.cxx:1770
bool IsVoidValue()
Definition: calc.hxx:116
sal_uInt8 GetOutlineLvl() const
Definition: expfld.hxx:180
void InitContent()
Evaluation for header and footer.
Definition: dbfld.cxx:190
#define DB_DELIM
Definition: swtypes.hxx:141
virtual sal_uInt16 GetSubType() const
Definition: fldbas.cxx:292
bool IsInReading() const
Definition: doc.hxx:948
virtual SwFieldType * GetSysFieldType(const SwFieldIds eWhich) const override
virtual void UnlockExpFields() override
SwFieldType * GetTyp() const
Definition: fldbas.hxx:382
virtual OUString GetName() const override
Only in derived classes.
Definition: expfld.cxx:530
SwSectionFormat * GetParent() const
Definition: section.hxx:356
virtual const SwRangeRedline * GetRedline(const SwPosition &rPos, SwRedlineTable::size_type *pFndPos) const =0
bool CalcHiddenFlag() const
Definition: section.cxx:343
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:460
void resize(size_t nSize)
Definition: calc.hxx:150
void UpdateDBNumFields(SwDBNameInfField &rDBField, SwCalc &rCalc)
bool FillCalcWithMergeData(SvNumberFormatter *pDocFormatter, LanguageType nLanguage, SwCalc &aCalc)
Definition: dbmgr.cxx:2193
Fields containing values that have to be formatted via number formatter.
Definition: fldbas.hxx:398
SwSbxValue Calculate(const OUString &rStr)
Definition: calc.cxx:349
const int GETFLD_EXPAND
Definition: docfld.hxx:129
#define INIT_FLDTYPES
Definition: swtypes.hxx:118
TElementType * Last()
Definition: calbck.hxx:353
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
OUString ExpandField(bool bCached, SwRootFrame const *pLayout) const
expand the field.
Definition: fldbas.cxx:412
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:367
#define RES_TXTATR_FIELD
Definition: hintids.hxx:150
const SwGetSetExpType GSE_SEQ
Sequence.
Definition: fldbas.hxx:197
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:439
const LanguageTag & getLanguageTag() const
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:202
OUString aSetStr
Definition: docfld.hxx:111
void ChgValid(bool bNew)
Definition: cellfml.hxx:134
void SetFieldsDirty(bool b)
Definition: docfld.hxx:164
virtual OUString GetName() const
Only in derived classes.
Definition: fldbas.cxx:145
sal_uInt32 GetSelectedRecordId(const OUString &rDataSource, const OUString &rTableOrQuery, sal_Int32 nCommandType=-1)
Definition: dbmgr.cxx:2449
bool IsFieldDeletedInModel(IDocumentRedlineAccess const &rIDRA, SwTextField const &rTextField)
SwTableNode * IsIdxInTable(const SwNodeIndex &rIdx)
Definition: ndtbl.cxx:216
unsigned char sal_uInt8
static OUString GetTypeStr(sal_uInt16 nTypeId)
Definition: fldbas.cxx:128
static OUString Expand(sal_uInt16 nSubType)
Definition: docufld.cxx:1943
virtual const SwFieldTypes * GetFieldTypes() const override
static OUString Expand(sal_uLong)
Definition: docufld.cxx:317
sal_Int32 GetIndex() const
Definition: index.hxx:95
bool PutString(const OUString &)
bool IsUsed(const SwModify &) const
Definition: poolfmt.cxx:122
bool IsClipBoard() const
Definition: doc.hxx:954
SwNodes & GetNodes()
Definition: doc.hxx:403
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
bool PutDouble(double)
void ClearInitialized()
Definition: dbfld.hxx:95
bool LockNotifyContentChange()
Definition: atrfld.cxx:558
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
bool GetBool() const
Definition: calc.cxx:1406
sal_Int64 GetTime() const
virtual sal_Int32 GetRecordsPerDocument() const override
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:416
Get reference.
Definition: reffld.hxx:65
bool IsCondValid() const
Definition: dbfld.hxx:227
SwFrameFormat * ClaimFrameFormat()
Definition: swtable.cxx:1706
void SetExpansion(const OUString &rStr)
Definition: docufld.hxx:556
SwCalcExp * VarLook(const OUString &rStr, bool bIns=false)
Definition: calc.cxx:410
const SwDBData & GetRealDBData() const
DBName.
Definition: dbfld.hxx:134
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:351
bool IsDataSourceOpen(const OUString &rDataSource, const OUString &rTableOrQuery, bool bMergeShell)
check if a data source is open
Definition: dbmgr.cxx:2090
void UnlockNotifyContentChange()
Definition: atrfld.cxx:568
bool IsInDtor() const
Definition: doc.hxx:398
const SwTextField * GetTextField() const
Definition: docfld.hxx:83
bool IsDocNodes() const
Is the NodesArray the regular one of Doc? (and not the UndoNds, ...) Implementation in doc...
Definition: nodes.cxx:2336
const SwGetSetExpType GSE_STRING
String.
Definition: fldbas.hxx:195
virtual void PutValueToField(const SwPosition &rPos, const css::uno::Any &rVal, sal_uInt16 nWhich) override
Puts a value into a field at a certain position.
TableFormulaUpdateFlags m_eFlags
Definition: hints.hxx:208
std::unique_ptr< SwDocUpdateField > mpUpdateFields
SwTextNode & GetTextNode() const
Definition: txtfld.hxx:53
SwSection * GetSection() const
Definition: section.cxx:675
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:162
SwSectionFormats & GetSections()
Definition: doc.hxx:1326
sal_Int32 nPos
void GCFieldTypes()
Remove all unreferenced field types of a document.
void SetHidden(bool bHidden)
Definition: docufld.hxx:368
#define RES_TXTATR_INPUTFIELD
Definition: hintids.hxx:145
const int GETFLD_CALC
Definition: docfld.hxx:128
SwFieldIds Which() const
Definition: fldbas.hxx:265
virtual double GetValue() const
Definition: fldbas.cxx:675
OUString sCommand
Definition: swdbdata.hxx:31
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1273
sal_uInt16 Which() const
virtual void InsDeletedFieldType(SwFieldType &) override
T should be a subclass of SwHash.
Definition: calc.hxx:143
SwDBManager * GetDBManager() const
Definition: doc.hxx:664
virtual void InsDelFieldInFieldLst(bool bIns, const SwTextField &rField) override
#define RES_BOXATR_FORMAT
Definition: hintids.hxx:261
std::vector< std::unique_ptr< SetGetExpField > >::const_iterator const_iterator
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1307
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:843
void SetCondition(OUString const &rNew)
Definition: section.hxx:200
virtual OUString GetPar1() const override
Definition: docufld.cxx:1417
virtual void UpdateUsrFields() override
Insert field type that was marked as deleted.
#define RES_BOXATR_FORMULA
Definition: hintids.hxx:262
virtual void ResetModified()=0
Base class of the Writer document model elements.
Definition: node.hxx:79
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo