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