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