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>
25 #include <redline.hxx>
26 #include <rootfrm.hxx>
27 #include <dbmgr.hxx>
28 #include <chpfld.hxx>
29 #include <dbfld.hxx>
30 #include <reffld.hxx>
31 #include <flddropdown.hxx>
32 #include <strings.hrc>
33 #include <SwUndoField.hxx>
34 #include <flddat.hxx>
35 #include <cntfrm.hxx>
36 #include <section.hxx>
37 #include <docufld.hxx>
38 #include <calbck.hxx>
39 #include <cellatr.hxx>
40 #include <swtable.hxx>
41 #include <frmfmt.hxx>
42 #include <fmtfld.hxx>
43 #include <ndtxt.hxx>
44 #include <txtfld.hxx>
45 #include <docfld.hxx>
46 #include <hints.hxx>
47 #include <docary.hxx>
48 #include <fldbas.hxx>
49 #include <expfld.hxx>
50 #include <ddefld.hxx>
51 #include <authfld.hxx>
52 #include <usrfld.hxx>
53 #include <ndindex.hxx>
54 #include <pam.hxx>
55 #include <o3tl/deleter.hxx>
56 #include <osl/diagnose.h>
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 + OUStringChar(DB_DELIM)
91  + aDBData.sCommand + OUStringChar(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 
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  return;
349 
350  SwFieldType* pTmp = (*mpFieldTypes)[nField].get();
351 
352  // JP 29.07.96: Optionally prepare FieldList for Calculator
353  SwFieldIds nWhich = pTmp->Which();
354  switch( nWhich )
355  {
356  case SwFieldIds::SetExp:
357  case SwFieldIds::User:
358  mpUpdateFields->RemoveFieldType( *pTmp );
359  [[fallthrough]];
360  case SwFieldIds::Dde:
361  if( pTmp->HasWriterListeners() && !m_rDoc.IsUsed( *pTmp ) )
362  {
363  if( SwFieldIds::SetExp == nWhich )
364  static_cast<SwSetExpFieldType*>(pTmp)->SetDeleted( true );
365  else if( SwFieldIds::User == nWhich )
366  static_cast<SwUserFieldType*>(pTmp)->SetDeleted( true );
367  else
368  static_cast<SwDDEFieldType*>(pTmp)->SetDeleted( true );
369  nWhich = SwFieldIds::Database;
370  }
371  break;
372  default: break;
373  }
374 
375  if( nWhich != SwFieldIds::Database )
376  {
377  OSL_ENSURE( !pTmp->HasWriterListeners(), "Dependent fields present!" );
378  }
379  else
380  (*mpFieldTypes)[nField].release(); // DB fields are ref-counted and delete themselves
381 
382  mpFieldTypes->erase( mpFieldTypes->begin() + nField );
384 }
385 
386 // All have to be re-evaluated.
388 {
389  // Call Modify() for every field type,
390  // dependent SwTextField get notified ...
391 
392  for( auto const & pFieldType : *mpFieldTypes )
393  {
394  switch( pFieldType->Which() )
395  {
396  // Update table fields second to last
397  // Update references last
398  case SwFieldIds::GetRef:
399  case SwFieldIds::Table:
402  case SwFieldIds::RefPageSet: // are never expanded!
403  break;
404 
405  case SwFieldIds::Dde:
406  {
407  SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL );
408  pFieldType->CallSwClientNotify(sw::LegacyModifyHint(nullptr, &aUpdateDDE));
409  break;
410  }
411  case SwFieldIds::GetExp:
412  case SwFieldIds::SetExp:
415  // Expression fields are treated separately
416  break;
417  default:
418  pFieldType->CallSwClientNotify(sw::LegacyModifyHint(nullptr, nullptr));
419  }
420  }
421 
422  if( !IsExpFieldsLocked() )
423  UpdateExpFields( nullptr, false ); // update expression fields
424 
425  // Tables
426  UpdateTableFields(nullptr);
427 
428  // References
429  UpdateRefFields();
430  if( bCloseDB )
431  {
432 #if HAVE_FEATURE_DBCONNECTIVITY
434 #endif
435  }
436  // Only evaluate on full update
438 }
439 
441 {
442  // The FieldType was marked as deleted and removed from the array.
443  // One has to look this up again, now.
444  // - If it's not present, it can be re-inserted.
445  // - If the same type is found, the deleted one has to be renamed.
446 
447  const SwFieldTypes::size_type nSize = mpFieldTypes->size();
448  const SwFieldIds nFieldWhich = rFieldTyp.Which();
449 
450  OSL_ENSURE( SwFieldIds::SetExp == nFieldWhich ||
451  SwFieldIds::User == nFieldWhich ||
452  SwFieldIds::Dde == nFieldWhich, "Wrong FieldType" );
453 
454  const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
455  const OUString& rFieldNm = rFieldTyp.GetName();
456 
457  for( SwFieldTypes::size_type i = INIT_FLDTYPES; i < nSize; ++i )
458  {
459  SwFieldType* pFnd = (*mpFieldTypes)[i].get();
460  if( nFieldWhich == pFnd->Which() &&
461  rSCmp.isEqual( rFieldNm, pFnd->GetName() ) )
462  {
463  // find new name
464  SwFieldTypes::size_type nNum = 1;
465  do {
466  OUString sSrch = rFieldNm + OUString::number( nNum );
467  for( i = INIT_FLDTYPES; i < nSize; ++i )
468  {
469  pFnd = (*mpFieldTypes)[i].get();
470  if( nFieldWhich == pFnd->Which() &&
471  rSCmp.isEqual( sSrch, pFnd->GetName() ) )
472  break;
473  }
474  if( i >= nSize ) // not found
475  {
476  const_cast<OUString&>(rFieldNm) = sSrch;
477  break; // exit while loop
478  }
479  ++nNum;
480  } while( true );
481  break;
482  }
483  }
484 
485  // not found, so insert, and updated deleted flag
486  mpFieldTypes->insert( mpFieldTypes->begin() + nSize, std::unique_ptr<SwFieldType>(&rFieldTyp) );
487  switch( nFieldWhich )
488  {
489  case SwFieldIds::SetExp:
490  static_cast<SwSetExpFieldType&>(rFieldTyp).SetDeleted( false );
491  break;
492  case SwFieldIds::User:
493  static_cast<SwUserFieldType&>(rFieldTyp).SetDeleted( false );
494  break;
495  case SwFieldIds::Dde:
496  static_cast<SwDDEFieldType&>(rFieldTyp).SetDeleted( false );
497  break;
498  default: break;
499  }
500 }
501 
503  const Any& rVal, sal_uInt16 nWhich)
504 {
505  Any aOldVal;
506  SwField * pField = GetFieldAtPos(rPos);
507 
509  pField->QueryValue(aOldVal, nWhich))
510  {
512  std::make_unique<SwUndoFieldFromAPI>(rPos, aOldVal, rVal, nWhich));
513  }
514 
515  pField->PutValue(rVal, nWhich);
516 }
517 
518 bool DocumentFieldsManager::UpdateField(SwTextField * pDstTextField, SwField & rSrcField,
519  SwMsgPoolItem * pMsgHint,
520  bool bUpdateFields)
521 {
522  OSL_ENSURE(pDstTextField, "no field to update!");
523 
524  bool bTableSelBreak = false;
525 
526  SwFormatField * pDstFormatField = const_cast<SwFormatField*>(&pDstTextField->GetFormatField());
527  SwField * pDstField = pDstFormatField->GetField();
528  SwFieldIds nFieldWhich = rSrcField.GetTyp()->Which();
529  SwNodeIndex aTableNdIdx(pDstTextField->GetTextNode());
530 
531  if (pDstField->GetTyp()->Which() ==
532  rSrcField.GetTyp()->Which())
533  {
535  {
536  SwPosition aPosition( pDstTextField->GetTextNode() );
537  aPosition.nContent = pDstTextField->GetStart();
538 
540  std::make_unique<SwUndoFieldFromDoc>( aPosition, *pDstField, rSrcField, pMsgHint, bUpdateFields) );
541  }
542 
543  pDstFormatField->SetField(rSrcField.CopyField());
544  SwField* pNewField = pDstFormatField->GetField();
545 
546  switch( nFieldWhich )
547  {
548  case SwFieldIds::SetExp:
549  case SwFieldIds::GetExp:
552  UpdateExpFields( pDstTextField, true );
553  break;
554 
555  case SwFieldIds::Table:
556  {
557  const SwTableNode* pTableNd =
558  m_rDoc.IsIdxInTable(aTableNdIdx);
559  if( pTableNd )
560  {
561  SwTableFormulaUpdate aTableUpdate( &pTableNd->
562  GetTable() );
563  if (bUpdateFields)
564  UpdateTableFields( &aTableUpdate );
565  else
566  pNewField->GetTyp()->CallSwClientNotify(sw::LegacyModifyHint(nullptr, &aTableUpdate));
567 
568  if (! bUpdateFields)
569  bTableSelBreak = true;
570  }
571  }
572  break;
573 
574  case SwFieldIds::Macro:
575  if( bUpdateFields && pDstTextField->GetpTextNode() )
576  pDstTextField->GetpTextNode()->TriggerNodeUpdate(sw::LegacyModifyHint(nullptr, pDstFormatField));
577  break;
578 
583  m_rDoc.ChgDBData(static_cast<SwDBNameInfField*>( pNewField)->GetRealDBData());
584  pNewField->GetTyp()->UpdateFields();
585 
586  break;
587 
589 #if HAVE_FEATURE_DBCONNECTIVITY
590  {
591  // JP 10.02.96: call ChgValue, so that the style change sets the
592  // ContentString correctly
593  SwDBField* pDBField = static_cast<SwDBField*>(pNewField);
594  if (pDBField->IsInitialized())
595  pDBField->ChgValue( pDBField->GetValue(), true );
596 
597  pDBField->ClearInitialized();
598  pDBField->InitContent();
599  }
600 #endif
601  [[fallthrough]];
602 
603  default:
604  pDstFormatField->UpdateTextNode(nullptr, pMsgHint);
605  }
606 
607  // The fields we can calculate here are being triggered for an update
608  // here explicitly.
609  if( nFieldWhich == SwFieldIds::User )
610  UpdateUsrFields();
611  }
612 
613  return bTableSelBreak;
614 }
615 
618 {
619  for(auto const& pFieldType: *mpFieldTypes)
620  if(SwFieldIds::GetRef == pFieldType->Which())
621  static_cast<SwGetRefFieldType*>(pFieldType.get())->UpdateGetReferences();
622 }
623 
625 {
626  OSL_ENSURE( !pHt || RES_TABLEFML_UPDATE == pHt->Which(),
627  "What MessageItem is this?" );
628 
629  auto pFieldType = GetFieldType( SwFieldIds::Table, OUString(), false );
630  if(pFieldType)
631  {
632  std::vector<SwFormatField*> vFields;
633  pFieldType->GatherFields(vFields);
634  SwTableFormulaUpdate* pUpdateField = nullptr;
635  if( pHt && RES_TABLEFML_UPDATE == pHt->Which() )
636  pUpdateField = static_cast<SwTableFormulaUpdate*>(pHt);
637  for(auto pFormatField : vFields)
638  {
639  SwTableField* pField = static_cast<SwTableField*>(pFormatField->GetField());
640  if( pUpdateField )
641  {
642  // table where this field is located
643  const SwTableNode* pTableNd;
644  const SwTextNode& rTextNd = pFormatField->GetTextField()->GetTextNode();
645  pTableNd = rTextNd.FindTableNode();
646  if (pTableNd == nullptr)
647  continue;
648 
649  switch( pUpdateField->m_eFlags )
650  {
651  case TBL_CALC:
652  // re-set the value flag
653  // JP 17.06.96: internal representation of all formulas
654  // (reference to other table!!!)
655  if( nsSwExtendedSubType::SUB_CMD & pField->GetSubType() )
656  pField->PtrToBoxNm( pUpdateField->m_pTable );
657  else
658  pField->ChgValid( false );
659  break;
660  case TBL_BOXNAME:
661  // is this the wanted table?
662  if( &pTableNd->GetTable() == pUpdateField->m_pTable )
663  // to the external representation
664  pField->PtrToBoxNm( pUpdateField->m_pTable );
665  break;
666  case TBL_BOXPTR:
667  // to the internal representation
668  // JP 17.06.96: internal representation on all formulas
669  // (reference to other table!!!)
670  pField->BoxNmToPtr( &pTableNd->GetTable() );
671  break;
672  case TBL_RELBOXNAME:
673  // is this the wanted table?
674  if( &pTableNd->GetTable() == pUpdateField->m_pTable )
675  // to the relative representation
676  pField->ToRelBoxNm( pUpdateField->m_pTable );
677  break;
678  default:
679  break;
680  }
681  }
682  else
683  // reset the value flag for all
684  pField->ChgValid( false );
685  }
686  }
687  // process all table box formulas
689  {
690  auto pBoxFormula = dynamic_cast<const SwTableBoxFormula*>(pItem);
691  if( pBoxFormula && pBoxFormula->GetDefinedIn() )
692  {
693  const_cast<SwTableBoxFormula*>(pBoxFormula)->ChangeState( pHt );
694  }
695  }
696 
697  SwRootFrame const* pLayout(nullptr);
698  for (SwRootFrame const*const pLay : m_rDoc.GetAllLayouts())
699  {
700  assert(!pLayout || pLay->IsHideRedlines() == pLayout->IsHideRedlines()); // TODO
701  pLayout = pLay;
702  }
703 
704  // all fields/boxes are now invalid, so we can start to calculate
705  if( pHt && ( RES_TABLEFML_UPDATE != pHt->Which() ||
706  TBL_CALC != static_cast<SwTableFormulaUpdate*>(pHt)->m_eFlags ))
707  return ;
708 
709  std::unique_ptr<SwCalc, o3tl::default_delete<SwCalc>> pCalc;
710 
711  if( pFieldType )
712  {
713  std::vector<SwFormatField*> vFields;
714  pFieldType->GatherFields(vFields);
715  for(SwFormatField* pFormatField: vFields)
716  {
717  // start calculation at the end
718  // new fields are inserted at the beginning of the modify chain
719  // that gives faster calculation on import
720  // mba: do we really need this "optimization"? Is it still valid?
721  SwTableField *const pField(static_cast<SwTableField*>(pFormatField->GetField()));
723  continue;
724 
725  // needs to be recalculated
726  if( !pField->IsValid() )
727  {
728  // table where this field is located
729  const SwTextNode& rTextNd = pFormatField->GetTextField()->GetTextNode();
730  const SwTableNode* pTableNd = rTextNd.FindTableNode();
731  if( !pTableNd )
732  continue;
733 
734  // if this field is not in the to-be-updated table, skip it
735  if( pHt && &pTableNd->GetTable() !=
736  static_cast<SwTableFormulaUpdate*>(pHt)->m_pTable )
737  continue;
738 
739  if( !pCalc )
740  pCalc.reset(new SwCalc( m_rDoc ));
741 
742  // get the values of all SetExpression fields that are valid
743  // until the table
744  SwFrame* pFrame = nullptr;
745  if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
746  {
747  // is in the special section, that's expensive!
748  Point aPt; // return the first frame of the layout - Tab.Headline!!
749  std::pair<Point, bool> const tmp(aPt, true);
750  pFrame = rTextNd.getLayoutFrame(pLayout, nullptr, &tmp);
751  if( pFrame )
752  {
753  SwPosition aPos( *pTableNd );
754  if( GetBodyTextNode( m_rDoc, aPos, *pFrame ) )
755  FieldsToCalc( *pCalc, SetGetExpField(
756  aPos.nNode, pFormatField->GetTextField(),
757  &aPos.nContent), pLayout);
758  else
759  pFrame = nullptr;
760  }
761  }
762  if( !pFrame )
763  {
764  // create index to determine the TextNode
765  SwNodeIndex aIdx( rTextNd );
766  FieldsToCalc( *pCalc,
767  SetGetExpField(aIdx, pFormatField->GetTextField()),
768  pLayout);
769  }
770 
771  SwTableCalcPara aPara(*pCalc, pTableNd->GetTable(), pLayout);
772  pField->CalcField( aPara );
773  if( aPara.IsStackOverflow() )
774  {
775  bool const bResult = aPara.CalcWithStackOverflow();
776  if (bResult)
777  {
778  pField->CalcField( aPara );
779  }
780  OSL_ENSURE(bResult,
781  "the chained formula could no be calculated");
782  }
783  pCalc->SetCalcError( SwCalcError::NONE );
784  }
785  pFormatField->UpdateTextNode(nullptr, pHt);
786  }
787  }
788 
789  // calculate the formula at the boxes
791  {
792  auto pFormula = const_cast<SwTableBoxFormula*>(dynamic_cast<const SwTableBoxFormula*>(pItem));
793  if( pFormula && pFormula->GetDefinedIn() && !pFormula->IsValid() )
794  {
795  SwTableBox* pBox = pFormula->GetTableBox();
796  if( pBox && pBox->GetSttNd() &&
797  pBox->GetSttNd()->GetNodes().IsDocNodes() )
798  {
799  const SwTableNode* pTableNd = pBox->GetSttNd()->FindTableNode();
800  if( !pHt || &pTableNd->GetTable() ==
801  static_cast<SwTableFormulaUpdate*>(pHt)->m_pTable )
802  {
803  double nValue;
804  if( !pCalc )
805  pCalc.reset(new SwCalc( m_rDoc ));
806 
807  // get the values of all SetExpression fields that are valid
808  // until the table
809  SwFrame* pFrame = nullptr;
810  if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
811  {
812  // is in the special section, that's expensive!
813  SwNodeIndex aCNdIdx( *pTableNd, +2 );
814  SwContentNode* pCNd = aCNdIdx.GetNode().GetContentNode();
815  if( !pCNd )
816  pCNd = m_rDoc.GetNodes().GoNext( &aCNdIdx );
817 
818  if (pCNd)
819  {
820  Point aPt; // return the first frame of the layout - Tab.Headline!!
821  std::pair<Point, bool> const tmp(aPt, true);
822  pFrame = pCNd->getLayoutFrame(pLayout, nullptr, &tmp);
823  if( pFrame )
824  {
825  SwPosition aPos( *pCNd );
826  if( GetBodyTextNode( m_rDoc, aPos, *pFrame ) )
827  FieldsToCalc(*pCalc, SetGetExpField(aPos.nNode),
828  pLayout);
829  else
830  pFrame = nullptr;
831  }
832  }
833  }
834  if( !pFrame )
835  {
836  // create index to determine the TextNode
837  SwNodeIndex aIdx( *pTableNd );
838  FieldsToCalc(*pCalc, SetGetExpField(aIdx), pLayout);
839  }
840 
841  SwTableCalcPara aPara(*pCalc, pTableNd->GetTable(), pLayout);
842  pFormula->Calc( aPara, nValue );
843 
844  if( aPara.IsStackOverflow() )
845  {
846  bool const bResult = aPara.CalcWithStackOverflow();
847  if (bResult)
848  {
849  pFormula->Calc( aPara, nValue );
850  }
851  OSL_ENSURE(bResult,
852  "the chained formula could no be calculated");
853  }
854 
855  SwFrameFormat* pFormat = pBox->ClaimFrameFormat();
856  SfxItemSet aTmp( m_rDoc.GetAttrPool(),
858 
859  if( pCalc->IsCalcError() )
860  nValue = DBL_MAX;
861  aTmp.Put( SwTableBoxValue( nValue ));
862  if( SfxItemState::SET != pFormat->GetItemState( RES_BOXATR_FORMAT ))
863  aTmp.Put( SwTableBoxNumFormat( 0 ));
864  pFormat->SetFormatAttr( aTmp );
865 
866  pCalc->SetCalcError( SwCalcError::NONE );
867  }
868  }
869  }
870  }
871 }
872 
873 void DocumentFieldsManager::UpdateExpFields( SwTextField* pUpdateField, bool bUpdRefFields )
874 {
876  return;
877 
878  bool bOldInUpdateFields = mpUpdateFields->IsInUpdateFields();
879  mpUpdateFields->SetInUpdateFields( true );
880 
881  mpUpdateFields->MakeFieldList( m_rDoc, true, GETFLD_ALL );
882  mbNewFieldLst = false;
883 
884  if (mpUpdateFields->GetSortList()->empty())
885  {
886  if( bUpdRefFields )
887  UpdateRefFields();
888 
889  mpUpdateFields->SetInUpdateFields( bOldInUpdateFields );
890  mpUpdateFields->SetFieldsDirty( false );
891  return ;
892  }
893 
894  SwRootFrame const* pLayout(nullptr);
895  SwRootFrame const* pLayoutRLHidden(nullptr);
896  for (SwRootFrame const*const pLay : m_rDoc.GetAllLayouts())
897  {
898  if (pLay->IsHideRedlines())
899  {
900  pLayoutRLHidden = pLay;
901  }
902  else
903  {
904  pLayout = pLay;
905  }
906  }
907  if (pLayout || !pLayoutRLHidden) // always calc *something*...
908  {
909  UpdateExpFieldsImpl(pUpdateField, pLayout);
910  }
911  if (pLayoutRLHidden)
912  {
913  UpdateExpFieldsImpl(pUpdateField, pLayoutRLHidden);
914  }
915 
916  // update reference fields
917  if( bUpdRefFields )
918  UpdateRefFields();
919 
920  mpUpdateFields->SetInUpdateFields( bOldInUpdateFields );
921  mpUpdateFields->SetFieldsDirty( false );
922 }
923 
925  SwTextField * pUpdateField, SwRootFrame const*const pLayout)
926 {
927  SwFieldIds nWhich;
928 
929  // Hash table for all string replacements is filled on-the-fly.
930  // Try to fabricate an uneven number.
931  const SwFieldTypes::size_type nHashSize {(( mpFieldTypes->size() / 7 ) + 1 ) * 7};
932  const sal_uInt16 nStrFormatCnt = o3tl::narrowing<sal_uInt16>(nHashSize);
933  OSL_ENSURE( nStrFormatCnt == nHashSize, "Downcasting to sal_uInt16 lost information!" );
934  SwHashTable<HashStr> aHashStrTable(nStrFormatCnt);
935 
936  {
937  const SwFieldType* pFieldType;
938  // process separately:
939  for( auto n = mpFieldTypes->size(); n; )
940  {
941  pFieldType = (*mpFieldTypes)[ --n ].get();
942  switch( pFieldType->Which() )
943  {
944  case SwFieldIds::User:
945  {
946  // Entry present?
947  sal_uInt16 nPos;
948  const OUString& rNm = pFieldType->GetName();
949  OUString sExpand(const_cast<SwUserFieldType*>(static_cast<const SwUserFieldType*>(pFieldType))->Expand(nsSwGetSetExpType::GSE_STRING, 0, LANGUAGE_SYSTEM));
950  SwHash* pFnd = aHashStrTable.Find( rNm, &nPos );
951  if( pFnd )
952  // modify entry in the hash table
953  static_cast<HashStr*>(pFnd)->aSetStr = sExpand;
954  else
955  // insert the new entry
956  aHashStrTable[nPos].reset( new HashStr( rNm, sExpand,
957  aHashStrTable[nPos].release() ) );
958  }
959  break;
960  default: break;
961  }
962  }
963  }
964 
965  // The array is filled with all fields; start calculation.
966  SwCalc aCalc( m_rDoc );
967 
968 #if HAVE_FEATURE_DBCONNECTIVITY
970 
971  // already set the current record number
972  SwDBManager* pMgr = m_rDoc.GetDBManager();
973  pMgr->CloseAll( false );
974 
975  SvtSysLocale aSysLocale;
976  const LocaleDataWrapper* pLclData = &aSysLocale.GetLocaleData();
977  const LanguageType nLang = pLclData->getLanguageTag().getLanguageType();
978  bool bCanFill = pMgr->FillCalcWithMergeData( m_rDoc.GetNumberFormatter(), nLang, aCalc );
979 #endif
980 
981  // Make sure we don't hide all content, which would lead to a crash. First, count how many visible sections we have.
982  int nShownSections = 0;
983  sal_uLong nContentStart = m_rDoc.GetNodes().GetEndOfContent().StartOfSectionIndex() + 1;
984  sal_uLong nContentEnd = m_rDoc.GetNodes().GetEndOfContent().GetIndex();
985  SwSectionFormats& rSectFormats = m_rDoc.GetSections();
986  for( SwSectionFormats::size_type n = 0; n<rSectFormats.size(); ++n )
987  {
988  SwSectionFormat& rSectFormat = *rSectFormats[ n ];
989  SwSectionNode* pSectionNode = rSectFormat.GetSectionNode();
990  SwSection* pSect = rSectFormat.GetSection();
991 
992  // Usually some of the content is not in a section: count that as a virtual section, so that all real sections can be hidden.
993  // Only look for section gaps at the lowest level, ignoring sub-sections.
994  if ( pSectionNode && !rSectFormat.GetParent() )
995  {
996  SwNodeIndex aNextIdx( *pSectionNode->EndOfSectionNode(), 1 );
997  if ( n == 0 && pSectionNode->GetIndex() != nContentStart )
998  nShownSections++; //document does not start with a section
999  if ( n == rSectFormats.size() - 1 )
1000  {
1001  if ( aNextIdx.GetIndex() != nContentEnd )
1002  nShownSections++; //document does not end in a section
1003  }
1004  else if ( !aNextIdx.GetNode().IsSectionNode() )
1005  nShownSections++; //section is not immediately followed by another section
1006  }
1007 
1008  // count only visible sections
1009  if ( pSect && !pSect->CalcHiddenFlag())
1010  nShownSections++;
1011  }
1012 
1014  std::unordered_map<SwSetExpFieldType const*, SwTextNode const*> SetExpOutlineNodeMap;
1015 
1016  for (std::unique_ptr<SetGetExpField> const& it : *mpUpdateFields->GetSortList())
1017  {
1018  SwSection* pSect = const_cast<SwSection*>(it->GetSection());
1019  if( pSect )
1020  {
1021  SwSbxValue aValue = aCalc.Calculate(
1022  pSect->GetCondition() );
1023  if(!aValue.IsVoidValue())
1024  {
1025  // Do we want to hide this one?
1026  bool bHide = aValue.GetBool();
1027  if (bHide && !pSect->IsCondHidden())
1028  {
1029  // This section will be hidden, but it wasn't before
1030  if (nShownSections == 1)
1031  {
1032  // This would be the last section, so set its condition to false, and avoid hiding it.
1033  pSect->SetCondition("0");
1034  bHide = false;
1035  }
1036  nShownSections--;
1037  }
1038  pSect->SetCondHidden( bHide );
1039  }
1040  continue;
1041  }
1042  ::sw::mark::IBookmark *const pBookmark(
1043  const_cast<::sw::mark::IBookmark *>(it->GetBookmark()));
1044  if (pBookmark)
1045  {
1046  SwSbxValue const aValue(aCalc.Calculate(pBookmark->GetHideCondition()));
1047  if (!aValue.IsVoidValue())
1048  {
1049  pBookmark->Hide(aValue.GetBool());
1050  }
1051  continue;
1052  }
1053 
1054  SwTextField* pTextField = const_cast<SwTextField*>(it->GetTextField());
1055  if( !pTextField )
1056  {
1057  OSL_ENSURE( false, "what's wrong now'" );
1058  continue;
1059  }
1060 
1061  if (pLayout && pLayout->IsHideRedlines()
1062  && IsFieldDeleted(rIDRA, *pLayout, *pTextField))
1063  {
1064  continue;
1065  }
1066 
1067  SwFormatField* pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
1068  const SwField* pField = pFormatField->GetField();
1069 
1070  nWhich = pField->GetTyp()->Which();
1071  switch( nWhich )
1072  {
1074  {
1075  SwHiddenTextField* pHField = const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField));
1076  SwSbxValue aValue = aCalc.Calculate( pHField->GetPar1() );
1077  bool bValue = !aValue.GetBool();
1078  if(!aValue.IsVoidValue())
1079  {
1080  pHField->SetValue( bValue );
1081  // evaluate field
1082  pHField->Evaluate(m_rDoc);
1083  }
1084  }
1085  break;
1087  {
1088  SwHiddenParaField* pHPField = const_cast<SwHiddenParaField*>(static_cast<const SwHiddenParaField*>(pField));
1089  SwSbxValue aValue = aCalc.Calculate( pHPField->GetPar1() );
1090  bool bValue = aValue.GetBool();
1091  if(!aValue.IsVoidValue())
1092  pHPField->SetHidden( bValue );
1093  }
1094  break;
1096 #if HAVE_FEATURE_DBCONNECTIVITY
1097  {
1098  const_cast<SwDBSetNumberField*>(static_cast<const SwDBSetNumberField*>(pField))->Evaluate(m_rDoc);
1099  aCalc.VarChange( sDBNumNm, static_cast<const SwDBSetNumberField*>(pField)->GetSetNumber());
1100  pField->ExpandField(m_rDoc.IsClipBoard(), nullptr);
1101  }
1102 #endif
1103  break;
1104  case SwFieldIds::DbNextSet:
1105  case SwFieldIds::DbNumSet:
1106 #if HAVE_FEATURE_DBCONNECTIVITY
1107  {
1108  UpdateDBNumFields( *const_cast<SwDBNameInfField*>(static_cast<const SwDBNameInfField*>(pField)), aCalc );
1109  if( bCanFill )
1110  bCanFill = pMgr->FillCalcWithMergeData( m_rDoc.GetNumberFormatter(), nLang, aCalc );
1111  }
1112 #endif
1113  break;
1114  case SwFieldIds::Database:
1115  {
1116 #if HAVE_FEATURE_DBCONNECTIVITY
1117  // evaluate field
1118  const_cast<SwDBField*>(static_cast<const SwDBField*>(pField))->Evaluate();
1119 
1120  SwDBData aTmpDBData(static_cast<const SwDBField*>(pField)->GetDBData());
1121 
1122  if( pMgr->IsDataSourceOpen(aTmpDBData.sDataSource, aTmpDBData.sCommand, false))
1123  aCalc.VarChange( sDBNumNm, pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType));
1124 
1125  const OUString& rName = pField->GetTyp()->GetName();
1126 
1127  // Add entry to hash table
1128  // Entry present?
1129  sal_uInt16 nPos;
1130  HashStr* pFnd = aHashStrTable.Find( rName, &nPos );
1131  OUString const value(pField->ExpandField(m_rDoc.IsClipBoard(), nullptr));
1132  if( pFnd )
1133  {
1134  // Modify entry in the hash table
1135  pFnd->aSetStr = value;
1136  }
1137  else
1138  {
1139  // insert new entry
1140  aHashStrTable[nPos].reset( new HashStr( rName,
1141  value, aHashStrTable[nPos].release()) );
1142  }
1143 #endif
1144  }
1145  break;
1146  case SwFieldIds::GetExp:
1147  case SwFieldIds::SetExp:
1148  {
1149  if( nsSwGetSetExpType::GSE_STRING & pField->GetSubType() ) // replace String
1150  {
1151  if( SwFieldIds::GetExp == nWhich )
1152  {
1153  SwGetExpField* pGField = const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
1154 
1155  if( (!pUpdateField || pUpdateField == pTextField )
1156  && pGField->IsInBodyText() )
1157  {
1158  OUString aNew = LookString( aHashStrTable, pGField->GetFormula() );
1159  pGField->ChgExpStr( aNew, pLayout );
1160  }
1161  }
1162  else
1163  {
1164  SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
1165  // is the "formula" a field?
1166  OUString aNew = LookString( aHashStrTable, pSField->GetFormula() );
1167 
1168  if( aNew.isEmpty() ) // nothing found then the formula is the new value
1169  aNew = pSField->GetFormula();
1170 
1171  // only update one field
1172  if( !pUpdateField || pUpdateField == pTextField )
1173  pSField->ChgExpStr( aNew, pLayout );
1174 
1175  // lookup the field's name
1176  aNew = static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName();
1177  // Entry present?
1178  sal_uInt16 nPos;
1179  HashStr* pFnd = aHashStrTable.Find( aNew, &nPos );
1180  if( pFnd )
1181  // Modify entry in the hash table
1182  pFnd->aSetStr = pSField->GetExpStr(pLayout);
1183  else
1184  {
1185  // insert new entry
1186  aHashStrTable[nPos].reset( new HashStr( aNew,
1187  pSField->GetExpStr(pLayout),
1188  aHashStrTable[nPos].release() ) );
1189  pFnd = aHashStrTable[nPos].get();
1190  }
1191 
1192  // Extension for calculation with Strings
1193  SwSbxValue aValue;
1194  aValue.PutString( pFnd->aSetStr );
1195  aCalc.VarChange( aNew, aValue );
1196  }
1197  }
1198  else // recalculate formula
1199  {
1200  if( SwFieldIds::GetExp == nWhich )
1201  {
1202  SwGetExpField* pGField = const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
1203 
1204  if( (!pUpdateField || pUpdateField == pTextField )
1205  && pGField->IsInBodyText() )
1206  {
1207  SwSbxValue aValue = aCalc.Calculate(
1208  pGField->GetFormula());
1209  if(!aValue.IsVoidValue())
1210  pGField->SetValue(aValue.GetDouble(), pLayout);
1211  }
1212  }
1213  else
1214  {
1215  SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
1216  SwSetExpFieldType* pSFieldTyp = static_cast<SwSetExpFieldType*>(pField->GetTyp());
1217  OUString aNew = pSFieldTyp->GetName();
1218 
1219  SwNode* pSeqNd = nullptr;
1220 
1221  if( pSField->IsSequenceField() )
1222  {
1223  const sal_uInt8 nLvl = pSFieldTyp->GetOutlineLvl();
1224  if( MAXLEVEL > nLvl )
1225  {
1226  // test if the Number needs to be updated
1227  pSeqNd = m_rDoc.GetNodes()[ it->GetNode() ];
1228 
1229  const SwTextNode* pOutlNd = pSeqNd->
1230  FindOutlineNodeOfLevel(nLvl, pLayout);
1231  auto const iter(SetExpOutlineNodeMap.find(pSFieldTyp));
1232  if (iter == SetExpOutlineNodeMap.end()
1233  || iter->second != pOutlNd)
1234  {
1235  SetExpOutlineNodeMap[pSFieldTyp] = pOutlNd;
1236  aCalc.VarChange( aNew, 0 );
1237  }
1238  }
1239  }
1240 
1241  aNew += "=" + pSField->GetFormula();
1242 
1243  SwSbxValue aValue = aCalc.Calculate( aNew );
1244  if (!aCalc.IsCalcError())
1245  {
1246  double nErg = aValue.GetDouble();
1247  // only update one field
1248  if( !aValue.IsVoidValue() && (!pUpdateField || pUpdateField == pTextField) )
1249  {
1250  pSField->SetValue(nErg, pLayout);
1251 
1252  if( pSeqNd )
1253  pSFieldTyp->SetChapter(*pSField, *pSeqNd, pLayout);
1254  }
1255  }
1256  }
1257  }
1258  }
1259  break;
1260  default: break;
1261  } // switch
1262 
1263  {
1264  // avoid calling ReplaceText() for input fields, it is pointless
1265  // here and moves the cursor if it's inside the field ...
1266  SwTextInputField *const pInputField(
1267  pUpdateField == pTextField // ... except once, when the dialog
1268  ? nullptr // is used to change content via UpdateOneField()
1269  : dynamic_cast<SwTextInputField *>(pTextField));
1270  if (pInputField)
1271  {
1272  bool const tmp = pInputField->LockNotifyContentChange();
1273  (void) tmp;
1274  assert(tmp && "should not be locked here?");
1275  }
1276  ::comphelper::ScopeGuard g([pInputField]()
1277  {
1278  if (pInputField)
1279  {
1280  pInputField->UnlockNotifyContentChange();
1281  }
1282  });
1283  pFormatField->UpdateTextNode(nullptr, nullptr); // trigger formatting
1284  }
1285 
1286  if (pUpdateField == pTextField) // if only this one is updated
1287  {
1288  if( SwFieldIds::GetExp == nWhich || // only GetField or
1289  SwFieldIds::HiddenText == nWhich || // HiddenText?
1290  SwFieldIds::HiddenPara == nWhich) // HiddenParaField?
1291  break; // quit
1292  pUpdateField = nullptr; // update all from here on
1293  }
1294  }
1295 
1296 #if HAVE_FEATURE_DBCONNECTIVITY
1297  pMgr->CloseAll(false);
1298 #endif
1299 }
1300 
1303 {
1304  SwCalc* pCalc = nullptr;
1305  for( SwFieldTypes::size_type i = INIT_FLDTYPES; i < mpFieldTypes->size(); ++i )
1306  {
1307  const SwFieldType* pFieldType = (*mpFieldTypes)[i].get();
1308  if( SwFieldIds::User == pFieldType->Which() )
1309  {
1310  if( !pCalc )
1311  pCalc = new SwCalc( m_rDoc );
1312  const_cast<SwUserFieldType*>(static_cast<const SwUserFieldType*>(pFieldType))->GetValue( *pCalc );
1313  }
1314  }
1315 
1316  if( pCalc )
1317  {
1318  delete pCalc;
1320  }
1321 }
1322 
1324 {
1325  sal_Int32 nRecords = 1;
1326 
1327  mpUpdateFields->MakeFieldList( m_rDoc, true, GETFLD_ALL );
1328  if (mpUpdateFields->GetSortList()->empty())
1329  return nRecords;
1330 
1331  for (std::unique_ptr<SetGetExpField> const& it : *mpUpdateFields->GetSortList())
1332  {
1333  const SwTextField *pTextField = it->GetTextField();
1334  if( !pTextField )
1335  continue;
1336 
1337  const SwFormatField &pFormatField = pTextField->GetFormatField();
1338  const SwField* pField = pFormatField.GetField();
1339 
1340  switch( pField->GetTyp()->Which() )
1341  {
1342  case SwFieldIds::DbNextSet:
1343  case SwFieldIds::DbNumSet:
1344  nRecords++;
1345  break;
1346  default:
1347  break;
1348  }
1349  }
1350 
1351  return nRecords;
1352 }
1353 
1355 {
1356  for( SwFieldTypes::size_type i = 0; i < INIT_FLDTYPES; ++i )
1357  {
1358  SwFieldType* pFieldType = (*mpFieldTypes)[ i ].get();
1359  switch( pFieldType->Which() )
1360  {
1362  case SwFieldIds::Chapter:
1363  case SwFieldIds::GetExp:
1365  pFieldType->CallSwClientNotify(sw::LegacyModifyHint(nullptr, pMsgHint));
1366  break;
1367  case SwFieldIds::DocStat:
1368  pFieldType->CallSwClientNotify(sw::LegacyModifyHint(nullptr, nullptr));
1369  break;
1370  default: break;
1371  }
1372  }
1373  SetNewFieldLst(true);
1374 }
1375 
1377 {
1378  ++mnLockExpField;
1379 }
1380 
1382 {
1383  assert(mnLockExpField != 0);
1384  if( mnLockExpField )
1385  --mnLockExpField;
1386 }
1387 
1389 {
1390  return 0 != mnLockExpField;
1391 }
1392 
1394 {
1395  return *mpUpdateFields;
1396 }
1397 
1398 bool DocumentFieldsManager::SetFieldsDirty( bool b, const SwNode* pChk, sal_uLong nLen )
1399 {
1400  // See if the supplied nodes actually contain fields.
1401  // If they don't, the flag doesn't need to be changed.
1402  bool bFieldsFnd = false;
1403  if( b && pChk && !GetUpdateFields().IsFieldsDirty() && !m_rDoc.IsInDtor()
1404  // ?? what's up with Undo, this is also wanted there!
1405  /*&& &pChk->GetNodes() == &GetNodes()*/ )
1406  {
1407  b = false;
1408  if( !nLen )
1409  ++nLen;
1410  sal_uLong nStt = pChk->GetIndex();
1411  const SwNodes& rNds = pChk->GetNodes();
1412  while( nLen-- )
1413  {
1414  const SwTextNode* pTNd = rNds[ nStt++ ]->GetTextNode();
1415  if( pTNd )
1416  {
1417  if( pTNd->GetAttrOutlineLevel() != 0 )
1418  // update chapter fields
1419  b = true;
1420  else if( pTNd->GetpSwpHints() && pTNd->GetSwpHints().Count() )
1421  {
1422  const size_t nEnd = pTNd->GetSwpHints().Count();
1423  for( size_t n = 0 ; n < nEnd; ++n )
1424  {
1425  const SwTextAttr* pAttr = pTNd->GetSwpHints().Get(n);
1426  if ( pAttr->Which() == RES_TXTATR_FIELD
1427  || pAttr->Which() == RES_TXTATR_INPUTFIELD)
1428  {
1429  b = true;
1430  break;
1431  }
1432  }
1433  }
1434 
1435  if( b )
1436  break;
1437  }
1438  }
1439  bFieldsFnd = b;
1440  }
1442  return bFieldsFnd;
1443 }
1444 
1446 {
1447  bool bIsModified = m_rDoc.getIDocumentState().IsModified();
1448 
1449  sal_Int32 nDate;
1450  sal_Int64 nTime;
1451  if( pNewDateTime )
1452  {
1453  nDate = pNewDateTime->GetDate();
1454  nTime = pNewDateTime->GetTime();
1455  }
1456  else
1457  {
1458  DateTime aDateTime( DateTime::SYSTEM );
1459  nDate = aDateTime.GetDate();
1460  nTime = aDateTime.GetTime();
1461  }
1462 
1463  SwFieldIds const aTypes[] {
1464  /*0*/ SwFieldIds::DocInfo,
1465  /*1*/ SwFieldIds::Author,
1466  /*2*/ SwFieldIds::ExtUser,
1467  /*3*/ SwFieldIds::Filename,
1468  /*4*/ SwFieldIds::DateTime }; // MUST be at the end!
1469 
1470  for(SwFieldIds aType : aTypes)
1471  {
1472  std::vector<SwFormatField*> vFields;
1473  GetSysFieldType(aType)->GatherFields(vFields);
1474  for(auto pFormatField: vFields)
1475  {
1476  if (pFormatField->GetTextField())
1477  {
1478  bool bChgd = false;
1479  switch( aType )
1480  {
1481  case SwFieldIds::DocInfo:
1482  if( static_cast<SwDocInfoField*>(pFormatField->GetField())->IsFixed() )
1483  {
1484  bChgd = true;
1485  SwDocInfoField* pDocInfField = static_cast<SwDocInfoField*>(pFormatField->GetField());
1486  pDocInfField->SetExpansion( static_cast<SwDocInfoFieldType*>(
1487  pDocInfField->GetTyp())->Expand(
1488  pDocInfField->GetSubType(),
1489  pDocInfField->GetFormat(),
1490  pDocInfField->GetLanguage(),
1491  pDocInfField->GetName() ) );
1492  }
1493  break;
1494 
1495  case SwFieldIds::Author:
1496  if( static_cast<SwAuthorField*>(pFormatField->GetField())->IsFixed() )
1497  {
1498  bChgd = true;
1499  SwAuthorField* pAuthorField = static_cast<SwAuthorField*>(pFormatField->GetField());
1500  pAuthorField->SetExpansion( SwAuthorFieldType::Expand( pAuthorField->GetFormat() ) );
1501  }
1502  break;
1503 
1504  case SwFieldIds::ExtUser:
1505  if( static_cast<SwExtUserField*>(pFormatField->GetField())->IsFixed() )
1506  {
1507  bChgd = true;
1508  SwExtUserField* pExtUserField = static_cast<SwExtUserField*>(pFormatField->GetField());
1509  pExtUserField->SetExpansion( SwExtUserFieldType::Expand(pExtUserField->GetSubType()) );
1510  }
1511  break;
1512 
1513  case SwFieldIds::DateTime:
1514  if( static_cast<SwDateTimeField*>(pFormatField->GetField())->IsFixed() )
1515  {
1516  bChgd = true;
1517  static_cast<SwDateTimeField*>(pFormatField->GetField())->SetDateTime(
1518  DateTime(Date(nDate), tools::Time(nTime)) );
1519  }
1520  break;
1521 
1522  case SwFieldIds::Filename:
1523  if( static_cast<SwFileNameField*>(pFormatField->GetField())->IsFixed() )
1524  {
1525  bChgd = true;
1526  SwFileNameField* pFileNameField =
1527  static_cast<SwFileNameField*>(pFormatField->GetField());
1528  pFileNameField->SetExpansion( static_cast<SwFileNameFieldType*>(
1529  pFileNameField->GetTyp())->Expand(
1530  pFileNameField->GetFormat() ) );
1531  }
1532  break;
1533  default: break;
1534  }
1535 
1536  // Trigger formatting
1537  if( bChgd )
1538  pFormatField->UpdateTextNode(nullptr, nullptr);
1539  }
1540  }
1541  }
1542 
1543  if( !bIsModified )
1545 }
1546 
1548  const SetGetExpField& rToThisField, SwRootFrame const*const pLayout)
1549 {
1550  // create the sorted list of all SetFields
1551  mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_CALC );
1552  mbNewFieldLst = false;
1553 
1554 #if !HAVE_FEATURE_DBCONNECTIVITY
1555  SwDBManager* pMgr = NULL;
1556 #else
1557  SwDBManager* pMgr = m_rDoc.GetDBManager();
1558  pMgr->CloseAll(false);
1559 #endif
1560 
1561  if (!mpUpdateFields->GetSortList()->empty())
1562  {
1563  SetGetExpFields::const_iterator const itLast =
1564  mpUpdateFields->GetSortList()->upper_bound(
1565  &rToThisField);
1566  for (auto it = mpUpdateFields->GetSortList()->begin(); it != itLast; ++it)
1567  {
1568  lcl_CalcField(m_rDoc, rCalc, **it, pMgr, pLayout);
1569  }
1570  }
1571 #if HAVE_FEATURE_DBCONNECTIVITY
1572  pMgr->CloseAll(false);
1573 #endif
1574 }
1575 
1577  sal_uLong const nLastNd, sal_Int32 const nLastCnt)
1578 {
1579  // create the sorted list of all SetFields
1580  mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_CALC );
1581  mbNewFieldLst = false;
1582 
1583 #if !HAVE_FEATURE_DBCONNECTIVITY
1584  SwDBManager* pMgr = NULL;
1585 #else
1586  SwDBManager* pMgr = m_rDoc.GetDBManager();
1587  pMgr->CloseAll(false);
1588 #endif
1589 
1590  SwRootFrame const* pLayout(nullptr);
1591  SwRootFrame const* pLayoutRLHidden(nullptr);
1592  for (SwRootFrame const*const pLay : m_rDoc.GetAllLayouts())
1593  {
1594  if (pLay->IsHideRedlines())
1595  {
1596  pLayoutRLHidden = pLay;
1597  }
1598  else
1599  {
1600  pLayout = pLay;
1601  }
1602  }
1603 
1604  // note this is not duplicate of the other FieldsToCalc because there is
1605  // (currently) no SetGetExpField that compares only a position
1606  for(auto it = mpUpdateFields->GetSortList()->begin();
1607  it != mpUpdateFields->GetSortList()->end() &&
1608  ( (*it)->GetNode() < nLastNd ||
1609  ( (*it)->GetNode() == nLastNd && (*it)->GetContent() <= nLastCnt )
1610  );
1611  ++it )
1612  {
1613  if (pLayout || !pLayoutRLHidden) // always calc *something*...
1614  {
1615  lcl_CalcField( m_rDoc, rCalc, **it, pMgr, pLayout );
1616  }
1617  if (pLayoutRLHidden)
1618  {
1619  lcl_CalcField( m_rDoc, rCalc, **it, pMgr, pLayoutRLHidden );
1620  }
1621  }
1622 
1623 #if HAVE_FEATURE_DBCONNECTIVITY
1624  pMgr->CloseAll(false);
1625 #endif
1626 }
1627 
1629  const SetGetExpField& rToThisField, SwRootFrame const& rLayout)
1630 {
1631  // create the sorted list of all SetFields
1632  mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_EXPAND );
1633  mbNewFieldLst = false;
1634 
1636 
1637  // Hash table for all string replacements is filled on-the-fly.
1638  // Try to fabricate an uneven number.
1639  sal_uInt16 nTableSize = ((mpUpdateFields->GetSortList()->size() / 7) + 1) * 7;
1640  rHashTable.resize(nTableSize);
1641 
1642  SetGetExpFields::const_iterator const itLast =
1643  mpUpdateFields->GetSortList()->upper_bound(&rToThisField);
1644 
1645  for (auto it = mpUpdateFields->GetSortList()->begin(); it != itLast; ++it)
1646  {
1647  const SwTextField* pTextField = (*it)->GetTextField();
1648  if( !pTextField )
1649  continue;
1650 
1651  if (rLayout.IsHideRedlines()
1652  && IsFieldDeleted(rIDRA, rLayout, *pTextField))
1653  {
1654  continue;
1655  }
1656 
1657  const SwField* pField = pTextField->GetFormatField().GetField();
1658  switch( pField->GetTyp()->Which() )
1659  {
1660  case SwFieldIds::SetExp:
1661  if( nsSwGetSetExpType::GSE_STRING & pField->GetSubType() )
1662  {
1663  // set the new value in the hash table
1664  // is the formula a field?
1665  SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
1666  OUString aNew = LookString( rHashTable, pSField->GetFormula() );
1667 
1668  if( aNew.isEmpty() ) // nothing found, then the formula is
1669  aNew = pSField->GetFormula(); // the new value
1670 
1671  // #i3141# - update expression of field as in method
1672  // <SwDoc::UpdateExpFields(..)> for string/text fields
1673  pSField->ChgExpStr(aNew, &rLayout);
1674 
1675  // look up the field's name
1676  aNew = static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName();
1677  // Entry present?
1678  sal_uInt16 nPos;
1679  SwHash* pFnd = rHashTable.Find( aNew, &nPos );
1680  if( pFnd )
1681  // modify entry in the hash table
1682  static_cast<HashStr*>(pFnd)->aSetStr = pSField->GetExpStr(&rLayout);
1683  else
1684  // insert the new entry
1685  rHashTable[nPos].reset( new HashStr( aNew,
1686  pSField->GetExpStr(&rLayout), rHashTable[nPos].release()));
1687  }
1688  break;
1689  case SwFieldIds::Database:
1690  {
1691  const OUString& rName = pField->GetTyp()->GetName();
1692 
1693  // Insert entry in the hash table
1694  // Entry present?
1695  sal_uInt16 nPos;
1696  HashStr* pFnd = rHashTable.Find( rName, &nPos );
1697  OUString const value(pField->ExpandField(m_rDoc.IsClipBoard(), nullptr));
1698  if( pFnd )
1699  {
1700  // modify entry in the hash table
1701  pFnd->aSetStr = value;
1702  }
1703  else
1704  {
1705  // insert the new entry
1706  rHashTable[nPos].reset( new HashStr( rName,
1707  value, rHashTable[nPos].release()) );
1708  }
1709  }
1710  break;
1711  default: break;
1712  }
1713  }
1714 }
1715 
1716 
1718 {
1719  return mbNewFieldLst;
1720 }
1721 
1723 {
1724  mbNewFieldLst = bFlag;
1725 }
1726 
1728 {
1729  if (!mbNewFieldLst && !m_rDoc.IsInDtor())
1730  mpUpdateFields->InsDelFieldInFieldLst( bIns, rField );
1731 }
1732 
1734 {
1735  SwTextField * const pAttr = GetTextFieldAtPos(rPos);
1736 
1737  return pAttr ? const_cast<SwField *>( pAttr->GetFormatField().GetField() ) : nullptr;
1738 }
1739 
1741 {
1742  SwTextNode * const pNode = rPos.nNode.GetNode().GetTextNode();
1743 
1744  return (pNode != nullptr)
1745  ? pNode->GetFieldTextAttrAt( rPos.nContent.GetIndex(), true )
1746  : nullptr;
1747 }
1748 
1752 {
1753  std::vector<SwFormatField*> vFields;
1754  for (auto const& pFieldType: *mpFieldTypes)
1755  {
1756  pFieldType->GatherFields(vFields);
1757  if(vFields.size()>0)
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:240
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:683
void SetValue(bool bHidden)
Definition: docufld.hxx:330
Base class of the Writer layout elements.
Definition: frame.hxx:315
const ::utl::TransliterationWrapper & GetAppCmpStrIgnore()
Definition: init.cxx:786
bool CalcWithStackOverflow()
Definition: cellfml.cxx:279
std::unique_ptr< SwFieldTypes > mpFieldTypes
virtual sal_uInt16 GetSubType() const override
Definition: tblcalc.cxx:118
Definition: calc.hxx:192
Definition: calc.hxx:132
void ChgValue(double d, bool bVal)
For calculations in expressions.
Definition: dbfld.cxx:237
bool IsCondValid() const
Definition: dbfld.hxx:181
sal_uLong GetIndex() const
Definition: node.hxx:291
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:35
virtual bool IsNewFieldLst() const override
virtual void UpdateRefFields() override
Update reference and table fields.
const SwField * GetField() const
Definition: fmtfld.hxx:110
LanguageType GetLanguage() const
Language at field position.
Definition: fldbas.hxx:402
sal_uLong StartOfSectionIndex() const
Definition: node.hxx:674
virtual void LockExpFields() override
constexpr TypedWhichId< SwTableBoxNumFormat > RES_BOXATR_FORMAT(RES_BOXATR_BEGIN)
virtual void SetNewFieldLst(bool bFlag) override
static constexpr auto Items
virtual SwFieldType * InsertFieldType(const SwFieldType &) override
Insert field types.
sal_uInt32 GetFormat() const
Query parameters for dialog and for BASIC.
Definition: fldbas.hxx:397
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:223
virtual sal_uInt16 GetSubType() const override
Definition: docufld.cxx:2018
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1411
constexpr TypedWhichId< SwMsgPoolItem > RES_UPDATEDDETBL(171)
void TriggerNodeUpdate(const sw::LegacyModifyHint &)
for hanging TextFormatCollections somewhere else (Outline-Numbering!)
Definition: ndtxt.cxx:5236
void ChgExpStr(const OUString &rExpand, SwRootFrame const *pLayout)
Definition: expfld.cxx:541
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:134
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:2285
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:939
const OUString & GetExpStr(SwRootFrame const *pLayout) const
Definition: expfld.cxx:536
Base class of all fields.
Definition: fldbas.hxx:289
bool IsCalcError() const
Definition: calc.hxx:246
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:1213
OUString LookString(SwHashTable< HashStr > const &rTable, std::u16string_view rName)
Look up the Name, if it is present, return its String, otherwise return an empty String.
Definition: docfld.cxx:361
sal_Int64 n
Definition: doc.hxx:188
constexpr sal_uInt16 RES_BOXATR_END(153)
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:93
std::unique_ptr< SwField > CopyField() const
Definition: fldbas.cxx:485
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:127
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:536
sal_uInt16 Which() const
Definition: txatbase.hxx:114
static const OUString & GetTypeStr(SwFieldTypesEnum nTypeId)
Definition: fldbas.cxx:122
bool HasWriterListeners() const
Definition: calbck.hxx:203
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
For old documents the Field-Which IDs must be preserved !!!
bool IsCondHidden() const
Definition: section.hxx:192
virtual void UpdatePageFields(SfxPoolItem *) override
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4015
OUString const & GetCondition() const
Definition: section.hxx:198
static LanguageType nLang
Definition: srtdlg.cxx:51
void GatherFields(std::vector< SwFormatField * > &rvFormatFields, bool bCollectOnlyInDocNodes=true) const
Definition: fldbas.cxx:208
Array of Undo-history.
Definition: docary.hxx:192
void UpdateFields() const
Definition: fldbas.cxx:149
void SetChapter(SwSetExpField &rField, const SwNode &rNd, SwRootFrame const *pLayout)
Definition: expfld.cxx:643
void UpdateExpFieldsImpl(SwTextField *pField, SwRootFrame const *pLayout)
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:165
virtual OUString GetPar1() const
Definition: fldbas.cxx:316
SwDoc & m_rDoc
Definition: docbm.cxx:1204
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:597
SwIndex nContent
Definition: pam.hxx:38
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:952
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:41
virtual bool PutValue(const css::uno::Any &rVal, sal_uInt16 nWhichId)
Definition: fldbas.cxx:359
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:86
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:902
void SetExpansion(const OUString &rStr)
Definition: docufld.hxx:198
const SwTable & GetTable() const
Definition: node.hxx:499
virtual bool IsExpFieldsLocked() const override
Implementation in tblcalc.cxx.
Definition: expfld.hxx:366
sal_Int32 GetDate() const
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:195
o3tl::sorted_vector< SwRootFrame * > GetAllLayouts()
Definition: doclay.cxx:1670
virtual bool DoesUndo() const =0
Is Undo enabled?
void SetExpansion(const OUString &rStr)
Definition: docufld.hxx:538
virtual SwDocUpdateField & GetUpdateFields() const override
const SwGetSetExpType GSE_EXPR
Expression.
Definition: fldbas.hxx:203
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt16 nWhichId) const
Definition: fldbas.cxx:346
void PtrToBoxNm(const SwTable *pTable)
create from the internal formula (for CORE) the external formula (for UI)
Definition: cellfml.cxx:572
#define INIT_SEQ_FLDTYPES
Definition: swtypes.hxx:110
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:163
virtual void RemoveFieldType(size_t nField) override
Remove field type.
SwSbxValue nValue
Definition: calc.hxx:142
double GetDouble() const
Definition: calc.cxx:1447
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
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:370
int i
const SwExtendedSubType SUB_CMD
Show command.
Definition: fldbas.hxx:211
std::vector< SwSectionFormat * >::size_type size_type
Definition: docary.hxx:67
void SetCondHidden(bool const bFlag)
Definition: section.cxx:532
bool IsValid() const
Definition: cellfml.hxx:135
virtual ~DocumentFieldsManager() override
virtual bool IsModified() const =0
Changes of document?
bool IsSequenceField() const
Definition: expfld.hxx:267
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:616
vector_type::size_type size_type
Definition: docary.hxx:223
SwFieldIds
Definition: fldbas.hxx:44
virtual void FieldsToExpand(SwHashTable< HashStr > &rTable, const SetGetExpField &rToThisField, SwRootFrame const &rLayout) override
bool IsVoidValue() const
Definition: calc.hxx:124
virtual void FieldsToCalc(SwCalc &rCalc, sal_uLong nLastNd, sal_Int32 nLastCnt) override
bool IsInBodyText() const
Called by formatting.
Definition: expfld.hxx:135
size_t size() const
Definition: docary.hxx:88
void CloseAll(bool bIncludingMerge=true)
close all data sources - after fields were updated
Definition: dbmgr.cxx:2398
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:747
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:388
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:31
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:694
T * Find(const OUString &rStr, sal_uInt16 *pPos=nullptr) const
Definition: calc.hxx:160
SwpHints & GetSwpHints()
getters for SwpHints
Definition: ndtxt.hxx:816
SwTextField * GetFieldTextAttrAt(const sal_Int32 nIndex, const bool bIncludeInputFieldAtStart=false) const
Definition: ndtxt.cxx:1761
sal_uInt8 GetOutlineLvl() const
Definition: expfld.hxx:179
void InitContent()
Evaluation for header and footer.
Definition: dbfld.cxx:177
const SvXMLTokenMapEntry aTypes[]
#define DB_DELIM
Definition: swtypes.hxx:131
virtual sal_uInt16 GetSubType() const
Definition: fldbas.cxx:337
bool IsInReading() const
Definition: doc.hxx:954
virtual SwFieldType * GetSysFieldType(const SwFieldIds eWhich) const override
virtual void UnlockExpFields() override
SwFieldType * GetTyp() const
Definition: fldbas.hxx:392
virtual OUString GetName() const override
Only in derived classes.
Definition: expfld.cxx:531
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:332
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:450
void resize(size_t nSize)
Definition: calc.hxx:158
void UpdateDBNumFields(SwDBNameInfField &rDBField, SwCalc &rCalc)
bool FillCalcWithMergeData(SvNumberFormatter *pDocFormatter, LanguageType nLanguage, SwCalc &aCalc)
Definition: dbmgr.cxx:2101
Fields containing values that have to be formatted via number formatter.
Definition: fldbas.hxx:408
SwSbxValue Calculate(const OUString &rStr)
Definition: calc.cxx:355
const int GETFLD_EXPAND
Definition: docfld.hxx:136
#define INIT_FLDTYPES
Definition: swtypes.hxx:106
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
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:465
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
const SwGetSetExpType GSE_SEQ
Sequence.
Definition: fldbas.hxx:204
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:448
const LanguageTag & getLanguageTag() const
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:245
OUString aSetStr
Definition: docfld.hxx:118
void ChgValid(bool bNew)
Definition: cellfml.hxx:136
void SetFieldsDirty(bool b)
Definition: docfld.hxx:172
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:2353
bool IsFieldDeletedInModel(IDocumentRedlineAccess const &rIDRA, SwTextField const &rTextField)
SwTableNode * IsIdxInTable(const SwNodeIndex &rIdx)
Definition: ndtbl.cxx:214
unsigned char sal_uInt8
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:963
SwNodes & GetNodes()
Definition: doc.hxx:409
constexpr TypedWhichId< SwTableBoxFormula > RES_BOXATR_FORMULA(151)
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
bool PutDouble(double)
void ClearInitialized()
Definition: dbfld.hxx:95
bool LockNotifyContentChange()
Definition: atrfld.cxx:647
void ToRelBoxNm(const SwTable *pTable)
create from the external/internal formula the relative formula
Definition: cellfml.cxx:622
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:395
bool GetBool() const
Definition: calc.cxx:1441
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:422
Get reference.
Definition: reffld.hxx:65
bool IsCondValid() const
Definition: dbfld.hxx:227
SwFrameFormat * ClaimFrameFormat()
Definition: swtable.cxx:1674
constexpr TypedWhichId< SwFormatField > RES_TXTATR_INPUTFIELD(55)
void SetExpansion(const OUString &rStr)
Definition: docufld.hxx:567
SwCalcExp * VarLook(const OUString &rStr, bool bIns=false)
Definition: calc.cxx:421
const SwDBData & GetRealDBData() const
DBName.
Definition: dbfld.hxx:134
virtual void CallSwClientNotify(const SfxHint &rHint) const override
Definition: calbck.cxx:326
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:357
bool IsDataSourceOpen(const OUString &rDataSource, const OUString &rTableOrQuery, bool bMergeShell)
check if a data source is open
Definition: dbmgr.cxx:1998
void UnlockNotifyContentChange()
Definition: atrfld.cxx:657
void Evaluate(const SwDoc &)
Definition: dbfld.cxx:809
bool IsInDtor() const
Definition: doc.hxx:404
const SwTextField * GetTextField() const
Definition: docfld.hxx:88
bool IsDocNodes() const
Is the NodesArray the regular one of Doc? (and not the UndoNds, ...) Implementation in doc...
Definition: nodes.cxx:2329
const SwGetSetExpType GSE_STRING
String.
Definition: fldbas.hxx:202
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:669
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:161
SwSectionFormats & GetSections()
Definition: doc.hxx:1338
void GCFieldTypes()
Remove all unreferenced field types of a document.
void SetHidden(bool bHidden)
Definition: docufld.hxx:373
const int GETFLD_CALC
Definition: docfld.hxx:135
SwFieldIds Which() const
Definition: fldbas.hxx:272
virtual double GetValue() const
Definition: fldbas.cxx:726
OUString sCommand
Definition: swdbdata.hxx:31
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1293
sal_uInt16 Which() const
virtual void InsDeletedFieldType(SwFieldType &) override
T should be a subclass of SwHash.
Definition: calc.hxx:151
SwDBManager * GetDBManager() const
Definition: doc.hxx:670
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:1319
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:850
void SetCondition(OUString const &rNew)
Definition: section.hxx:199
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:80
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo