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
495 SwMsgPoolItem * pMsgHint,
496 bool bUpdateFields)
497{
498 OSL_ENSURE(pDstTextField, "no field to update!");
499
500 bool bTableSelBreak = false;
501
502 SwFormatField * pDstFormatField = const_cast<SwFormatField*>(&pDstTextField->GetFormatField());
503 SwField * pDstField = pDstFormatField->GetField();
504 SwFieldIds nFieldWhich = rSrcField.GetTyp()->Which();
505 SwNodeIndex aTableNdIdx(pDstTextField->GetTextNode());
506
507 if (pDstField->GetTyp()->Which() ==
508 rSrcField.GetTyp()->Which())
509 {
510 if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
511 {
512 SwPosition aPosition( pDstTextField->GetTextNode(), pDstTextField->GetStart() );
513
514 m_rDoc.GetIDocumentUndoRedo().AppendUndo(
515 std::make_unique<SwUndoFieldFromDoc>( aPosition, *pDstField, rSrcField, pMsgHint, bUpdateFields) );
516 }
517
518 pDstFormatField->SetField(rSrcField.CopyField());
519 SwField* pNewField = pDstFormatField->GetField();
520
521 switch( nFieldWhich )
522 {
527 UpdateExpFields( pDstTextField, true );
528 break;
529
531 {
532 const SwTableNode* pTableNd =
533 SwDoc::IsIdxInTable(aTableNdIdx);
534 if( pTableNd )
535 {
536 SwTableFormulaUpdate aTableUpdate( &pTableNd->
537 GetTable() );
538 if (bUpdateFields)
539 UpdateTableFields( &aTableUpdate );
540 else
541 pNewField->GetTyp()->CallSwClientNotify(sw::LegacyModifyHint(nullptr, &aTableUpdate));
542
543 if (! bUpdateFields)
544 bTableSelBreak = true;
545 }
546 }
547 break;
548
550 if( bUpdateFields && pDstTextField->GetpTextNode() )
551 pDstTextField->GetpTextNode()->TriggerNodeUpdate(sw::LegacyModifyHint(nullptr, pDstFormatField));
552 break;
553
558 m_rDoc.ChgDBData(static_cast<SwDBNameInfField*>( pNewField)->GetRealDBData());
559 pNewField->GetTyp()->UpdateFields();
560
561 break;
562
564#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
565 {
566 // JP 10.02.96: call ChgValue, so that the style change sets the
567 // ContentString correctly
568 SwDBField* pDBField = static_cast<SwDBField*>(pNewField);
569 if (pDBField->IsInitialized())
570 pDBField->ChgValue( pDBField->GetValue(), true );
571
572 pDBField->ClearInitialized();
573 pDBField->InitContent();
574 }
575#endif
576 [[fallthrough]];
577
578 default:
579 pDstFormatField->UpdateTextNode(nullptr, pMsgHint);
580 }
581
582 // The fields we can calculate here are being triggered for an update
583 // here explicitly.
584 if( nFieldWhich == SwFieldIds::User )
586 }
587
588 return bTableSelBreak;
589}
590
593{
594 for(auto const& pFieldType: *mpFieldTypes)
595 if(SwFieldIds::GetRef == pFieldType->Which())
596 static_cast<SwGetRefFieldType*>(pFieldType.get())->UpdateGetReferences();
597}
598
600{
601 OSL_ENSURE( !pHt || RES_TABLEFML_UPDATE == pHt->Which(),
602 "What MessageItem is this?" );
603
604 auto pFieldType = GetFieldType( SwFieldIds::Table, OUString(), false );
605 if(pFieldType)
606 {
607 std::vector<SwFormatField*> vFields;
608 pFieldType->GatherFields(vFields);
609 SwTableFormulaUpdate* pUpdateField = nullptr;
610 if( pHt && RES_TABLEFML_UPDATE == pHt->Which() )
611 pUpdateField = static_cast<SwTableFormulaUpdate*>(pHt);
612 for(auto pFormatField : vFields)
613 {
614 SwTableField* pField = static_cast<SwTableField*>(pFormatField->GetField());
615 if( pUpdateField )
616 {
617 // table where this field is located
618 const SwTableNode* pTableNd;
619 const SwTextNode& rTextNd = pFormatField->GetTextField()->GetTextNode();
620 pTableNd = rTextNd.FindTableNode();
621 if (pTableNd == nullptr)
622 continue;
623
624 switch( pUpdateField->m_eFlags )
625 {
626 case TBL_CALC:
627 // re-set the value flag
628 // JP 17.06.96: internal representation of all formulas
629 // (reference to other table!!!)
631 pField->PtrToBoxNm( pUpdateField->m_pTable );
632 else
633 pField->ChgValid( false );
634 break;
635 case TBL_BOXNAME:
636 // is this the wanted table?
637 if( &pTableNd->GetTable() == pUpdateField->m_pTable )
638 // to the external representation
639 pField->PtrToBoxNm( pUpdateField->m_pTable );
640 break;
641 case TBL_BOXPTR:
642 // to the internal representation
643 // JP 17.06.96: internal representation on all formulas
644 // (reference to other table!!!)
645 pField->BoxNmToPtr( &pTableNd->GetTable() );
646 break;
647 case TBL_RELBOXNAME:
648 // is this the wanted table?
649 if( &pTableNd->GetTable() == pUpdateField->m_pTable )
650 // to the relative representation
651 pField->ToRelBoxNm( pUpdateField->m_pTable );
652 break;
653 default:
654 break;
655 }
656 }
657 else
658 // reset the value flag for all
659 pField->ChgValid( false );
660 }
661 }
662 // process all table box formulas
664 {
665 auto pBoxFormula = dynamic_cast<const SwTableBoxFormula*>(pItem);
666 if( pBoxFormula && pBoxFormula->GetDefinedIn() )
667 {
668 const_cast<SwTableBoxFormula*>(pBoxFormula)->ChangeState( pHt );
669 }
670 }
671
672 SwRootFrame const* pLayout(nullptr);
673 for (SwRootFrame const*const pLay : m_rDoc.GetAllLayouts())
674 {
675 assert(!pLayout || pLay->IsHideRedlines() == pLayout->IsHideRedlines()); // TODO
676 pLayout = pLay;
677 }
678
679 // all fields/boxes are now invalid, so we can start to calculate
680 if( pHt && ( RES_TABLEFML_UPDATE != pHt->Which() ||
681 TBL_CALC != static_cast<SwTableFormulaUpdate*>(pHt)->m_eFlags ))
682 return ;
683
684 std::optional<SwCalc> oCalc;
685
686 if( pFieldType )
687 {
688 std::vector<SwFormatField*> vFields;
689 pFieldType->GatherFields(vFields);
690 for(SwFormatField* pFormatField: vFields)
691 {
692 // start calculation at the end
693 // new fields are inserted at the beginning of the modify chain
694 // that gives faster calculation on import
695 // mba: do we really need this "optimization"? Is it still valid?
696 SwTableField *const pField(static_cast<SwTableField*>(pFormatField->GetField()));
698 continue;
699
700 // needs to be recalculated
701 if( !pField->IsValid() )
702 {
703 // table where this field is located
704 const SwTextNode& rTextNd = pFormatField->GetTextField()->GetTextNode();
705 const SwTableNode* pTableNd = rTextNd.FindTableNode();
706 if( !pTableNd )
707 continue;
708
709 // if this field is not in the to-be-updated table, skip it
710 if( pHt && &pTableNd->GetTable() !=
711 static_cast<SwTableFormulaUpdate*>(pHt)->m_pTable )
712 continue;
713
714 if( !oCalc )
715 oCalc.emplace( m_rDoc );
716
717 // get the values of all SetExpression fields that are valid
718 // until the table
719 SwFrame* pFrame = nullptr;
720 if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
721 {
722 // is in the special section, that's expensive!
723 Point aPt; // return the first frame of the layout - Tab.Headline!!
724 std::pair<Point, bool> const tmp(aPt, true);
725 pFrame = rTextNd.getLayoutFrame(pLayout, nullptr, &tmp);
726 if( pFrame )
727 {
728 SwPosition aPos( *pTableNd );
729 if( GetBodyTextNode( m_rDoc, aPos, *pFrame ) )
730 {
732 aPos.GetNode(), pFormatField->GetTextField(),
733 aPos.GetContentIndex(), pFrame->GetPhyPageNum()),
734 pLayout);
735 }
736 else
737 pFrame = nullptr;
738 }
739 }
740 if( !pFrame )
741 {
742 // create index to determine the TextNode
743 SwFrame const*const pFrame2 = ::sw::FindNeighbourFrameForNode(rTextNd);
744 FieldsToCalc( *oCalc,
745 SetGetExpField(rTextNd, pFormatField->GetTextField(),
746 std::nullopt,
747 pFrame2 ? pFrame2->GetPhyPageNum() : 0),
748 pLayout);
749 }
750
751 SwTableCalcPara aPara(*oCalc, pTableNd->GetTable(), pLayout);
752 pField->CalcField( aPara );
753 if( aPara.IsStackOverflow() )
754 {
755 bool const bResult = aPara.CalcWithStackOverflow();
756 if (bResult)
757 {
758 pField->CalcField( aPara );
759 }
760 OSL_ENSURE(bResult,
761 "the chained formula could no be calculated");
762 }
763 oCalc->SetCalcError( SwCalcError::NONE );
764 }
765 pFormatField->UpdateTextNode(nullptr, pHt);
766 }
767 }
768
769 // calculate the formula at the boxes
771 {
772 auto pFormula = const_cast<SwTableBoxFormula*>(dynamic_cast<const SwTableBoxFormula*>(pItem));
773 if( pFormula && pFormula->GetDefinedIn() && !pFormula->IsValid() )
774 {
775 SwTableBox* pBox = pFormula->GetTableBox();
776 if( pBox && pBox->GetSttNd() &&
777 pBox->GetSttNd()->GetNodes().IsDocNodes() )
778 {
779 const SwTableNode* pTableNd = pBox->GetSttNd()->FindTableNode();
780 if( !pHt || &pTableNd->GetTable() ==
781 static_cast<SwTableFormulaUpdate*>(pHt)->m_pTable )
782 {
783 double nValue;
784 if( !oCalc )
785 oCalc.emplace( m_rDoc );
786
787 // get the values of all SetExpression fields that are valid
788 // until the table
789 SwFrame* pFrame = nullptr;
790 if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
791 {
792 // is in the special section, that's expensive!
793 SwNodeIndex aCNdIdx( *pTableNd, +2 );
794 SwContentNode* pCNd = aCNdIdx.GetNode().GetContentNode();
795 if( !pCNd )
796 pCNd = m_rDoc.GetNodes().GoNext( &aCNdIdx );
797
798 if (pCNd)
799 {
800 Point aPt; // return the first frame of the layout - Tab.Headline!!
801 std::pair<Point, bool> const tmp(aPt, true);
802 pFrame = pCNd->getLayoutFrame(pLayout, nullptr, &tmp);
803 if( pFrame )
804 {
805 SwPosition aPos( *pCNd );
806 if( GetBodyTextNode( m_rDoc, aPos, *pFrame ) )
807 {
808 FieldsToCalc(*oCalc, SetGetExpField(aPos.GetNode(),
809 nullptr, std::nullopt, pFrame->GetPhyPageNum()),
810 pLayout);
811 }
812 else
813 pFrame = nullptr;
814 }
815 }
816 }
817 if( !pFrame )
818 {
819 // create index to determine the TextNode
820 SwFrame const*const pFrame2 = ::sw::FindNeighbourFrameForNode(*pTableNd);
821 FieldsToCalc(*oCalc, SetGetExpField(*pTableNd, nullptr, std::nullopt,
822 pFrame2 ? pFrame2->GetPhyPageNum() : 0),
823 pLayout);
824 }
825
826 SwTableCalcPara aPara(*oCalc, pTableNd->GetTable(), pLayout);
827 pFormula->Calc( aPara, nValue );
828
829 if( aPara.IsStackOverflow() )
830 {
831 bool const bResult = aPara.CalcWithStackOverflow();
832 if (bResult)
833 {
834 pFormula->Calc( aPara, nValue );
835 }
836 OSL_ENSURE(bResult,
837 "the chained formula could no be calculated");
838 }
839
840 SwFrameFormat* pFormat = pBox->ClaimFrameFormat();
842
843 if( oCalc->IsCalcError() )
844 nValue = DBL_MAX;
845 aTmp.Put( SwTableBoxValue( nValue ));
846 if( SfxItemState::SET != pFormat->GetItemState( RES_BOXATR_FORMAT ))
847 aTmp.Put( SwTableBoxNumFormat( 0 ));
848 pFormat->SetFormatAttr( aTmp );
849
850 oCalc->SetCalcError( SwCalcError::NONE );
851 }
852 }
853 }
854 }
855}
856
857void DocumentFieldsManager::UpdateExpFields( SwTextField* pUpdateField, bool bUpdRefFields )
858{
860 return;
861
862 bool bOldInUpdateFields = mpUpdateFields->IsInUpdateFields();
863 mpUpdateFields->SetInUpdateFields( true );
864
865 mpUpdateFields->MakeFieldList( m_rDoc, true, GETFLD_ALL );
866 mbNewFieldLst = false;
867
868 if (mpUpdateFields->GetSortList()->empty())
869 {
870 if( bUpdRefFields )
872
873 mpUpdateFields->SetInUpdateFields( bOldInUpdateFields );
874 mpUpdateFields->SetFieldsDirty( false );
875 return ;
876 }
877
878 SwRootFrame const* pLayout(nullptr);
879 SwRootFrame const* pLayoutRLHidden(nullptr);
880 for (SwRootFrame const*const pLay : m_rDoc.GetAllLayouts())
881 {
882 if (pLay->IsHideRedlines())
883 {
884 pLayoutRLHidden = pLay;
885 }
886 else
887 {
888 pLayout = pLay;
889 }
890 }
891 if (pLayout || !pLayoutRLHidden) // always calc *something*...
892 {
893 UpdateExpFieldsImpl(pUpdateField, pLayout);
894 }
895 if (pLayoutRLHidden)
896 {
897 UpdateExpFieldsImpl(pUpdateField, pLayoutRLHidden);
898 }
899
900 // update reference fields
901 if( bUpdRefFields )
903
904 mpUpdateFields->SetInUpdateFields( bOldInUpdateFields );
905 mpUpdateFields->SetFieldsDirty( false );
906}
907
909 SwTextField * pUpdateField, SwRootFrame const*const pLayout)
910{
911 SwFieldIds nWhich;
912
913 // Hash table for all string replacements is filled on-the-fly.
914 // Try to fabricate an uneven number.
915 const SwFieldTypes::size_type nHashSize {(( mpFieldTypes->size() / 7 ) + 1 ) * 7};
916 const sal_uInt16 nStrFormatCnt = o3tl::narrowing<sal_uInt16>(nHashSize);
917 OSL_ENSURE( nStrFormatCnt == nHashSize, "Downcasting to sal_uInt16 lost information!" );
918 SwHashTable<HashStr> aHashStrTable(nStrFormatCnt);
919
920 {
921 const SwFieldType* pFieldType;
922 // process separately:
923 for( auto n = mpFieldTypes->size(); n; )
924 {
925 pFieldType = (*mpFieldTypes)[ --n ].get();
926 switch( pFieldType->Which() )
927 {
928 case SwFieldIds::User:
929 {
930 // Entry present?
931 sal_uInt32 nPos;
932 const OUString& rNm = pFieldType->GetName();
933 OUString sExpand(const_cast<SwUserFieldType*>(static_cast<const SwUserFieldType*>(pFieldType))->Expand(nsSwGetSetExpType::GSE_STRING, 0, LANGUAGE_SYSTEM));
934 SwHash* pFnd = aHashStrTable.Find( rNm, &nPos );
935 if( pFnd )
936 // modify entry in the hash table
937 static_cast<HashStr*>(pFnd)->aSetStr = sExpand;
938 else
939 // insert the new entry
940 aHashStrTable[nPos].reset( new HashStr( rNm, sExpand,
941 aHashStrTable[nPos].release() ) );
942 }
943 break;
944 default: break;
945 }
946 }
947 }
948
949 // The array is filled with all fields; start calculation.
950 SwCalc aCalc( m_rDoc );
951
952#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
954
955 // already set the current record number
957 pMgr->CloseAll( false );
958
959 SvtSysLocale aSysLocale;
960 const LocaleDataWrapper* pLclData = &aSysLocale.GetLocaleData();
961 const LanguageType nLang = pLclData->getLanguageTag().getLanguageType();
962 bool bCanFill = pMgr->FillCalcWithMergeData( m_rDoc.GetNumberFormatter(), nLang, aCalc );
963#endif
964
965 // Make sure we don't hide all content, which would lead to a crash. First, count how many visible sections we have.
966 int nShownSections = 0;
969 SwSectionFormats& rSectFormats = m_rDoc.GetSections();
970 for( SwSectionFormats::size_type n = 0; n<rSectFormats.size(); ++n )
971 {
972 SwSectionFormat& rSectFormat = *rSectFormats[ n ];
973 SwSectionNode* pSectionNode = rSectFormat.GetSectionNode();
974 SwSection* pSect = rSectFormat.GetSection();
975
976 // Usually some of the content is not in a section: count that as a virtual section, so that all real sections can be hidden.
977 // Only look for section gaps at the lowest level, ignoring sub-sections.
978 if ( pSectionNode && !rSectFormat.GetParent() )
979 {
980 SwNodeIndex aNextIdx( *pSectionNode->EndOfSectionNode(), 1 );
981 if ( n == 0 && pSectionNode->GetIndex() != nContentStart )
982 nShownSections++; //document does not start with a section
983 if ( n == rSectFormats.size() - 1 )
984 {
985 if ( aNextIdx.GetIndex() != nContentEnd )
986 nShownSections++; //document does not end in a section
987 }
988 else if ( !aNextIdx.GetNode().IsSectionNode() )
989 nShownSections++; //section is not immediately followed by another section
990 }
991
992 // count only visible sections
993 if ( pSect && !pSect->CalcHiddenFlag())
994 nShownSections++;
995 }
996
998 std::unordered_map<SwSetExpFieldType const*, SwTextNode const*> SetExpOutlineNodeMap;
999
1000 for (std::unique_ptr<SetGetExpField> const& it : *mpUpdateFields->GetSortList())
1001 {
1002 SwSection* pSect = const_cast<SwSection*>(it->GetSection());
1003 if( pSect )
1004 {
1005 SwSbxValue aValue = aCalc.Calculate(
1006 pSect->GetCondition() );
1007 if(!aValue.IsVoidValue())
1008 {
1009 // Do we want to hide this one?
1010 bool bHide = aValue.GetBool();
1011 if (bHide && !pSect->IsCondHidden())
1012 {
1013 // This section will be hidden, but it wasn't before
1014 if (nShownSections == 1)
1015 {
1016 // This would be the last section, so set its condition to false, and avoid hiding it.
1017 pSect->SetCondition("0");
1018 bHide = false;
1019 }
1020 nShownSections--;
1021 }
1022 pSect->SetCondHidden( bHide );
1023 }
1024 continue;
1025 }
1026 ::sw::mark::IBookmark *const pBookmark(
1027 const_cast<::sw::mark::IBookmark *>(it->GetBookmark()));
1028 if (pBookmark)
1029 {
1030 SwSbxValue const aValue(aCalc.Calculate(pBookmark->GetHideCondition()));
1031 if (!aValue.IsVoidValue())
1032 {
1033 pBookmark->Hide(aValue.GetBool());
1034 }
1035 continue;
1036 }
1037
1038 SwTextField* pTextField = const_cast<SwTextField*>(it->GetTextField());
1039 if( !pTextField )
1040 {
1041 OSL_ENSURE( false, "what's wrong now'" );
1042 continue;
1043 }
1044
1045 if (pLayout && pLayout->IsHideRedlines()
1046 && IsFieldDeleted(rIDRA, *pLayout, *pTextField))
1047 {
1048 continue;
1049 }
1050
1051 SwFormatField* pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
1052 const SwField* pField = pFormatField->GetField();
1053
1054 nWhich = pField->GetTyp()->Which();
1055 switch( nWhich )
1056 {
1058 {
1059 SwHiddenTextField* pHField = const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField));
1060 SwSbxValue aValue = aCalc.Calculate( pHField->GetPar1() );
1061 bool bValue = !aValue.GetBool();
1062 if(!aValue.IsVoidValue())
1063 {
1064 pHField->SetValue( bValue );
1065 // evaluate field
1066 pHField->Evaluate(m_rDoc);
1067 }
1068 }
1069 break;
1071 {
1072 SwHiddenParaField* pHPField = const_cast<SwHiddenParaField*>(static_cast<const SwHiddenParaField*>(pField));
1073 SwSbxValue aValue = aCalc.Calculate( pHPField->GetPar1() );
1074 bool bValue = aValue.GetBool();
1075 if(!aValue.IsVoidValue())
1076 pHPField->SetHidden( bValue );
1077 }
1078 break;
1080#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1081 {
1082 const_cast<SwDBSetNumberField*>(static_cast<const SwDBSetNumberField*>(pField))->Evaluate(m_rDoc);
1083 aCalc.VarChange( sDBNumNm, static_cast<const SwDBSetNumberField*>(pField)->GetSetNumber());
1084 pField->ExpandField(m_rDoc.IsClipBoard(), nullptr);
1085 }
1086#endif
1087 break;
1090#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1091 {
1092 UpdateDBNumFields( *const_cast<SwDBNameInfField*>(static_cast<const SwDBNameInfField*>(pField)), aCalc );
1093 if( bCanFill )
1094 bCanFill = pMgr->FillCalcWithMergeData( m_rDoc.GetNumberFormatter(), nLang, aCalc );
1095 }
1096#endif
1097 break;
1099 {
1100#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1101 // evaluate field
1102 const_cast<SwDBField*>(static_cast<const SwDBField*>(pField))->Evaluate();
1103
1104 SwDBData aTmpDBData(static_cast<const SwDBField*>(pField)->GetDBData());
1105
1106 if( pMgr->IsDataSourceOpen(aTmpDBData.sDataSource, aTmpDBData.sCommand, false))
1107 aCalc.VarChange( sDBNumNm, pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType));
1108
1109 const OUString& rName = pField->GetTyp()->GetName();
1110
1111 // Add entry to hash table
1112 // Entry present?
1113 sal_uInt32 nPos;
1114 HashStr* pFnd = aHashStrTable.Find( rName, &nPos );
1115 OUString const value(pField->ExpandField(m_rDoc.IsClipBoard(), nullptr));
1116 if( pFnd )
1117 {
1118 // Modify entry in the hash table
1119 pFnd->aSetStr = value;
1120 }
1121 else
1122 {
1123 // insert new entry
1124 aHashStrTable[nPos].reset( new HashStr( rName,
1125 value, aHashStrTable[nPos].release()) );
1126 }
1127#endif
1128 }
1129 break;
1130 case SwFieldIds::GetExp:
1131 case SwFieldIds::SetExp:
1132 {
1133 if( nsSwGetSetExpType::GSE_STRING & pField->GetSubType() ) // replace String
1134 {
1135 if( SwFieldIds::GetExp == nWhich )
1136 {
1137 SwGetExpField* pGField = const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
1138
1139 if( (!pUpdateField || pUpdateField == pTextField )
1140 && pGField->IsInBodyText() )
1141 {
1142 OUString aNew = LookString( aHashStrTable, pGField->GetFormula() );
1143 pGField->ChgExpStr( aNew, pLayout );
1144 }
1145 }
1146 else
1147 {
1148 SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
1149 // is the "formula" a field?
1150 OUString aNew = LookString( aHashStrTable, pSField->GetFormula() );
1151
1152 if( aNew.isEmpty() ) // nothing found then the formula is the new value
1153 aNew = pSField->GetFormula();
1154
1155 // only update one field
1156 if( !pUpdateField || pUpdateField == pTextField )
1157 pSField->ChgExpStr( aNew, pLayout );
1158
1159 // lookup the field's name
1160 aNew = static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName();
1161 // Entry present?
1162 sal_uInt32 nPos;
1163 HashStr* pFnd = aHashStrTable.Find( aNew, &nPos );
1164 if( pFnd )
1165 // Modify entry in the hash table
1166 pFnd->aSetStr = pSField->GetExpStr(pLayout);
1167 else
1168 {
1169 // insert new entry
1170 aHashStrTable[nPos].reset( new HashStr( aNew,
1171 pSField->GetExpStr(pLayout),
1172 aHashStrTable[nPos].release() ) );
1173 pFnd = aHashStrTable[nPos].get();
1174 }
1175
1176 // Extension for calculation with Strings
1177 SwSbxValue aValue;
1178 aValue.PutString( pFnd->aSetStr );
1179 aCalc.VarChange( aNew, aValue );
1180 }
1181 }
1182 else // recalculate formula
1183 {
1184 if( SwFieldIds::GetExp == nWhich )
1185 {
1186 SwGetExpField* pGField = const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
1187
1188 if( (!pUpdateField || pUpdateField == pTextField )
1189 && pGField->IsInBodyText() )
1190 {
1191 SwSbxValue aValue = aCalc.Calculate(
1192 pGField->GetFormula());
1193 if(!aValue.IsVoidValue())
1194 pGField->SetValue(aValue.GetDouble(), pLayout);
1195 }
1196 }
1197 else
1198 {
1199 SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
1200 SwSetExpFieldType* pSFieldTyp = static_cast<SwSetExpFieldType*>(pField->GetTyp());
1201 OUString aNew = pSFieldTyp->GetName();
1202
1203 SwNode* pSeqNd = nullptr;
1204
1205 if( pSField->IsSequenceField() )
1206 {
1207 const sal_uInt8 nLvl = pSFieldTyp->GetOutlineLvl();
1208 if( MAXLEVEL > nLvl )
1209 {
1210 // test if the Number needs to be updated
1211 pSeqNd = m_rDoc.GetNodes()[ it->GetNode() ];
1212
1213 const SwTextNode* pOutlNd = pSeqNd->
1214 FindOutlineNodeOfLevel(nLvl, pLayout);
1215 auto const iter(SetExpOutlineNodeMap.find(pSFieldTyp));
1216 if (iter == SetExpOutlineNodeMap.end()
1217 || iter->second != pOutlNd)
1218 {
1219 SetExpOutlineNodeMap[pSFieldTyp] = pOutlNd;
1220 aCalc.VarChange( aNew, 0 );
1221 }
1222 }
1223 }
1224
1225 aNew += "=" + pSField->GetFormula();
1226
1227 SwSbxValue aValue = aCalc.Calculate( aNew );
1228 if (!aCalc.IsCalcError())
1229 {
1230 double nErg = aValue.GetDouble();
1231 // only update one field
1232 if( !aValue.IsVoidValue() && (!pUpdateField || pUpdateField == pTextField) )
1233 {
1234 pSField->SetValue(nErg, pLayout);
1235
1236 if( pSeqNd )
1237 pSFieldTyp->SetChapter(*pSField, *pSeqNd, pLayout);
1238 }
1239 }
1240 }
1241 }
1242 }
1243 break;
1244 default: break;
1245 } // switch
1246
1247 {
1248 // avoid calling ReplaceText() for input fields, it is pointless
1249 // here and moves the cursor if it's inside the field ...
1250 SwTextInputField *const pInputField(
1251 pUpdateField == pTextField // ... except once, when the dialog
1252 ? nullptr // is used to change content via UpdateOneField()
1253 : dynamic_cast<SwTextInputField *>(pTextField));
1254 if (pInputField)
1255 {
1256 bool const tmp = pInputField->LockNotifyContentChange();
1257 (void) tmp;
1258 assert(tmp && "should not be locked here?");
1259 }
1260 ::comphelper::ScopeGuard g([pInputField]()
1261 {
1262 if (pInputField)
1263 {
1264 pInputField->UnlockNotifyContentChange();
1265 }
1266 });
1267 pFormatField->UpdateTextNode(nullptr, nullptr); // trigger formatting
1268 }
1269
1270 if (pUpdateField == pTextField) // if only this one is updated
1271 {
1272 if( SwFieldIds::GetExp == nWhich || // only GetField or
1273 SwFieldIds::HiddenText == nWhich || // HiddenText?
1274 SwFieldIds::HiddenPara == nWhich) // HiddenParaField?
1275 break; // quit
1276 pUpdateField = nullptr; // update all from here on
1277 }
1278 }
1279
1280#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1281 pMgr->CloseAll(false);
1282#endif
1283}
1284
1287{
1288 SwCalc* pCalc = nullptr;
1289 for( SwFieldTypes::size_type i = INIT_FLDTYPES; i < mpFieldTypes->size(); ++i )
1290 {
1291 const SwFieldType* pFieldType = (*mpFieldTypes)[i].get();
1292 if( SwFieldIds::User == pFieldType->Which() )
1293 {
1294 if( !pCalc )
1295 pCalc = new SwCalc( m_rDoc );
1296 const_cast<SwUserFieldType*>(static_cast<const SwUserFieldType*>(pFieldType))->GetValue( *pCalc );
1297 }
1298 }
1299
1300 if( pCalc )
1301 {
1302 delete pCalc;
1304 }
1305}
1306
1308{
1309 sal_Int32 nRecords = 1;
1310
1311 mpUpdateFields->MakeFieldList( m_rDoc, true, GETFLD_ALL );
1312 if (mpUpdateFields->GetSortList()->empty())
1313 return nRecords;
1314
1315 for (std::unique_ptr<SetGetExpField> const& it : *mpUpdateFields->GetSortList())
1316 {
1317 const SwTextField *pTextField = it->GetTextField();
1318 if( !pTextField )
1319 continue;
1320
1321 const SwFormatField &pFormatField = pTextField->GetFormatField();
1322 const SwField* pField = pFormatField.GetField();
1323
1324 switch( pField->GetTyp()->Which() )
1325 {
1328 nRecords++;
1329 break;
1330 default:
1331 break;
1332 }
1333 }
1334
1335 return nRecords;
1336}
1337
1339{
1340 for( SwFieldTypes::size_type i = 0; i < INIT_FLDTYPES; ++i )
1341 {
1342 SwFieldType* pFieldType = (*mpFieldTypes)[ i ].get();
1343 switch( pFieldType->Which() )
1344 {
1347 case SwFieldIds::GetExp:
1349 pFieldType->CallSwClientNotify(sw::LegacyModifyHint(nullptr, pMsgHint));
1350 break;
1352 pFieldType->CallSwClientNotify(sw::LegacyModifyHint(nullptr, nullptr));
1353 break;
1354 default: break;
1355 }
1356 }
1357 SetNewFieldLst(true);
1358}
1359
1361{
1363}
1364
1366{
1367 assert(mnLockExpField != 0);
1368 if( mnLockExpField )
1370}
1371
1373{
1374 return 0 != mnLockExpField;
1375}
1376
1378{
1379 return *mpUpdateFields;
1380}
1381
1383{
1384 // See if the supplied nodes actually contain fields.
1385 // If they don't, the flag doesn't need to be changed.
1386 bool bFieldsFnd = false;
1387 if( b && pChk && !GetUpdateFields().IsFieldsDirty() && !m_rDoc.IsInDtor()
1388 // ?? what's up with Undo, this is also wanted there!
1389 /*&& &pChk->GetNodes() == &GetNodes()*/ )
1390 {
1391 b = false;
1392 if( !nLen )
1393 ++nLen;
1394 SwNodeOffset nStt = pChk->GetIndex();
1395 const SwNodes& rNds = pChk->GetNodes();
1396 while( nLen-- )
1397 {
1398 const SwTextNode* pTNd = rNds[ nStt++ ]->GetTextNode();
1399 if( pTNd )
1400 {
1401 if( pTNd->GetAttrOutlineLevel() != 0 )
1402 // update chapter fields
1403 b = true;
1404 else if( pTNd->GetpSwpHints() && pTNd->GetSwpHints().Count() )
1405 {
1406 const size_t nEnd = pTNd->GetSwpHints().Count();
1407 for( size_t n = 0 ; n < nEnd; ++n )
1408 {
1409 const SwTextAttr* pAttr = pTNd->GetSwpHints().Get(n);
1410 if ( pAttr->Which() == RES_TXTATR_FIELD
1411 || pAttr->Which() == RES_TXTATR_INPUTFIELD)
1412 {
1413 b = true;
1414 break;
1415 }
1416 }
1417 }
1418
1419 if( b )
1420 break;
1421 }
1422 }
1423 bFieldsFnd = b;
1424 }
1426 return bFieldsFnd;
1427}
1428
1430{
1431 bool bIsModified = m_rDoc.getIDocumentState().IsModified();
1432
1433 sal_Int32 nDate;
1434 sal_Int64 nTime;
1435 if( pNewDateTime )
1436 {
1437 nDate = pNewDateTime->GetDate();
1438 nTime = pNewDateTime->GetTime();
1439 }
1440 else
1441 {
1442 DateTime aDateTime( DateTime::SYSTEM );
1443 nDate = aDateTime.GetDate();
1444 nTime = aDateTime.GetTime();
1445 }
1446
1447 SwFieldIds const aTypes[] {
1448 /*0*/ SwFieldIds::DocInfo,
1449 /*1*/ SwFieldIds::Author,
1450 /*2*/ SwFieldIds::ExtUser,
1452 /*4*/ SwFieldIds::DateTime }; // MUST be at the end!
1453
1454 for(SwFieldIds aType : aTypes)
1455 {
1456 std::vector<SwFormatField*> vFields;
1457 GetSysFieldType(aType)->GatherFields(vFields);
1458 for(auto pFormatField: vFields)
1459 {
1460 if (pFormatField->GetTextField())
1461 {
1462 bool bChgd = false;
1463 switch( aType )
1464 {
1466 if( static_cast<SwDocInfoField*>(pFormatField->GetField())->IsFixed() )
1467 {
1468 bChgd = true;
1469 SwDocInfoField* pDocInfField = static_cast<SwDocInfoField*>(pFormatField->GetField());
1470 pDocInfField->SetExpansion( static_cast<SwDocInfoFieldType*>(
1471 pDocInfField->GetTyp())->Expand(
1472 pDocInfField->GetSubType(),
1473 pDocInfField->GetFormat(),
1474 pDocInfField->GetLanguage(),
1475 pDocInfField->GetName() ) );
1476 }
1477 break;
1478
1479 case SwFieldIds::Author:
1480 if( static_cast<SwAuthorField*>(pFormatField->GetField())->IsFixed() )
1481 {
1482 bChgd = true;
1483 SwAuthorField* pAuthorField = static_cast<SwAuthorField*>(pFormatField->GetField());
1484 pAuthorField->SetExpansion( SwAuthorFieldType::Expand( pAuthorField->GetFormat() ) );
1485 }
1486 break;
1487
1489 if( static_cast<SwExtUserField*>(pFormatField->GetField())->IsFixed() )
1490 {
1491 bChgd = true;
1492 SwExtUserField* pExtUserField = static_cast<SwExtUserField*>(pFormatField->GetField());
1493 pExtUserField->SetExpansion( SwExtUserFieldType::Expand(pExtUserField->GetSubType()) );
1494 }
1495 break;
1496
1498 if( static_cast<SwDateTimeField*>(pFormatField->GetField())->IsFixed() )
1499 {
1500 bChgd = true;
1501 static_cast<SwDateTimeField*>(pFormatField->GetField())->SetDateTime(
1502 DateTime(Date(nDate), tools::Time(nTime)) );
1503 }
1504 break;
1505
1507 if( static_cast<SwFileNameField*>(pFormatField->GetField())->IsFixed() )
1508 {
1509 bChgd = true;
1510 SwFileNameField* pFileNameField =
1511 static_cast<SwFileNameField*>(pFormatField->GetField());
1512 pFileNameField->SetExpansion( static_cast<SwFileNameFieldType*>(
1513 pFileNameField->GetTyp())->Expand(
1514 pFileNameField->GetFormat() ) );
1515 }
1516 break;
1517 default: break;
1518 }
1519
1520 // Trigger formatting
1521 if( bChgd )
1522 pFormatField->UpdateTextNode(nullptr, nullptr);
1523 }
1524 }
1525 }
1526
1527 if( !bIsModified )
1529}
1530
1532 const SetGetExpField& rToThisField, SwRootFrame const*const pLayout)
1533{
1534 // create the sorted list of all SetFields
1535 mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_CALC );
1536 mbNewFieldLst = false;
1537
1538#if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
1539 SwDBManager* pMgr = NULL;
1540#else
1542 pMgr->CloseAll(false);
1543#endif
1544
1545 if (!mpUpdateFields->GetSortList()->empty())
1546 {
1547 SetGetExpFields::const_iterator const itLast =
1548 mpUpdateFields->GetSortList()->upper_bound(
1549 &rToThisField);
1550 for (auto it = mpUpdateFields->GetSortList()->begin(); it != itLast; ++it)
1551 {
1552 lcl_CalcField(m_rDoc, rCalc, **it, pMgr, pLayout);
1553 }
1554 }
1555#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1556 pMgr->CloseAll(false);
1557#endif
1558}
1559
1561 SwNodeOffset const nLastNd, sal_Int32 const nLastCnt)
1562{
1563 // create the sorted list of all SetFields
1564 mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_CALC );
1565 mbNewFieldLst = false;
1566
1567#if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
1568 SwDBManager* pMgr = NULL;
1569#else
1571 pMgr->CloseAll(false);
1572#endif
1573
1574 SwRootFrame const* pLayout(nullptr);
1575 SwRootFrame const* pLayoutRLHidden(nullptr);
1576 for (SwRootFrame const*const pLay : m_rDoc.GetAllLayouts())
1577 {
1578 if (pLay->IsHideRedlines())
1579 {
1580 pLayoutRLHidden = pLay;
1581 }
1582 else
1583 {
1584 pLayout = pLay;
1585 }
1586 }
1587
1588 // note this is not duplicate of the other FieldsToCalc because there is
1589 // (currently) no SetGetExpField that compares only a position
1590 for(auto it = mpUpdateFields->GetSortList()->begin();
1591 it != mpUpdateFields->GetSortList()->end() &&
1592 ( (*it)->GetNode() < nLastNd ||
1593 ( (*it)->GetNode() == nLastNd && (*it)->GetContent() <= nLastCnt )
1594 );
1595 ++it )
1596 {
1597 if (pLayout || !pLayoutRLHidden) // always calc *something*...
1598 {
1599 lcl_CalcField( m_rDoc, rCalc, **it, pMgr, pLayout );
1600 }
1601 if (pLayoutRLHidden)
1602 {
1603 lcl_CalcField( m_rDoc, rCalc, **it, pMgr, pLayoutRLHidden );
1604 }
1605 }
1606
1607#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1608 pMgr->CloseAll(false);
1609#endif
1610}
1611
1613 const SetGetExpField& rToThisField, SwRootFrame const& rLayout)
1614{
1615 // create the sorted list of all SetFields
1617 mbNewFieldLst = false;
1618
1620
1621 // Hash table for all string replacements is filled on-the-fly.
1622 // Try to fabricate an uneven number.
1623 sal_uInt16 nTableSize = ((mpUpdateFields->GetSortList()->size() / 7) + 1) * 7;
1624 rHashTable.resize(nTableSize);
1625
1626 SetGetExpFields::const_iterator const itLast =
1627 mpUpdateFields->GetSortList()->upper_bound(&rToThisField);
1628
1629 for (auto it = mpUpdateFields->GetSortList()->begin(); it != itLast; ++it)
1630 {
1631 const SwTextField* pTextField = (*it)->GetTextField();
1632 if( !pTextField )
1633 continue;
1634
1635 if (rLayout.IsHideRedlines()
1636 && IsFieldDeleted(rIDRA, rLayout, *pTextField))
1637 {
1638 continue;
1639 }
1640
1641 const SwField* pField = pTextField->GetFormatField().GetField();
1642 switch( pField->GetTyp()->Which() )
1643 {
1644 case SwFieldIds::SetExp:
1646 {
1647 // set the new value in the hash table
1648 // is the formula a field?
1649 SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
1650 OUString aNew = LookString( rHashTable, pSField->GetFormula() );
1651
1652 if( aNew.isEmpty() ) // nothing found, then the formula is
1653 aNew = pSField->GetFormula(); // the new value
1654
1655 // #i3141# - update expression of field as in method
1656 // <SwDoc::UpdateExpFields(..)> for string/text fields
1657 pSField->ChgExpStr(aNew, &rLayout);
1658
1659 // look up the field's name
1660 aNew = static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName();
1661 // Entry present?
1662 sal_uInt32 nPos;
1663 SwHash* pFnd = rHashTable.Find( aNew, &nPos );
1664 if( pFnd )
1665 // modify entry in the hash table
1666 static_cast<HashStr*>(pFnd)->aSetStr = pSField->GetExpStr(&rLayout);
1667 else
1668 // insert the new entry
1669 rHashTable[nPos].reset( new HashStr( aNew,
1670 pSField->GetExpStr(&rLayout), rHashTable[nPos].release()));
1671 }
1672 break;
1674 {
1675 const OUString& rName = pField->GetTyp()->GetName();
1676
1677 // Insert entry in the hash table
1678 // Entry present?
1679 sal_uInt32 nPos;
1680 HashStr* pFnd = rHashTable.Find( rName, &nPos );
1681 OUString const value(pField->ExpandField(m_rDoc.IsClipBoard(), nullptr));
1682 if( pFnd )
1683 {
1684 // modify entry in the hash table
1685 pFnd->aSetStr = value;
1686 }
1687 else
1688 {
1689 // insert the new entry
1690 rHashTable[nPos].reset( new HashStr( rName,
1691 value, rHashTable[nPos].release()) );
1692 }
1693 }
1694 break;
1695 default: break;
1696 }
1697 }
1698}
1699
1700
1702{
1703 return mbNewFieldLst;
1704}
1705
1707{
1708 mbNewFieldLst = bFlag;
1709}
1710
1712{
1713 if (!mbNewFieldLst && !m_rDoc.IsInDtor())
1714 mpUpdateFields->InsDelFieldInFieldLst( bIns, rField );
1715}
1716
1718{
1719 SwTextField * const pAttr = GetTextFieldAtPos(rPos);
1720
1721 return pAttr ? const_cast<SwField *>( pAttr->GetFormatField().GetField() ) : nullptr;
1722}
1723
1725{
1726 SwTextNode * const pNode = rPos.GetNode().GetTextNode();
1727
1728 return (pNode != nullptr)
1730 : nullptr;
1731}
1732
1736{
1737 std::vector<SwFormatField*> vFields;
1738 for (auto const& pFieldType: *mpFieldTypes)
1739 {
1740 pFieldType->GatherFields(vFields);
1741 if(vFields.size()>0)
1742 return true;
1743 }
1744 return false;
1745}
1746
1749{
1750 for( auto n = mpFieldTypes->size(); n > INIT_FLDTYPES; )
1751 if( !(*mpFieldTypes)[ --n ]->HasWriterListeners() )
1752 RemoveFieldType( n );
1753}
1754
1755void DocumentFieldsManager::InitFieldTypes() // is being called by the CTOR
1756{
1757 // Field types
1758 mpFieldTypes->emplace_back( new SwDateTimeFieldType(&m_rDoc) );
1759 mpFieldTypes->emplace_back( new SwChapterFieldType );
1760 mpFieldTypes->emplace_back( new SwPageNumberFieldType );
1761 mpFieldTypes->emplace_back( new SwAuthorFieldType );
1762 mpFieldTypes->emplace_back( new SwFileNameFieldType(m_rDoc) );
1763 mpFieldTypes->emplace_back( new SwDBNameFieldType(&m_rDoc) );
1764 mpFieldTypes->emplace_back( new SwGetExpFieldType(&m_rDoc) );
1765 mpFieldTypes->emplace_back( new SwGetRefFieldType(m_rDoc) );
1766 mpFieldTypes->emplace_back( new SwHiddenTextFieldType );
1767 mpFieldTypes->emplace_back( new SwPostItFieldType(m_rDoc) );
1768 mpFieldTypes->emplace_back( new SwDocStatFieldType(m_rDoc) );
1769 mpFieldTypes->emplace_back( new SwDocInfoFieldType(&m_rDoc) );
1770 mpFieldTypes->emplace_back( new SwInputFieldType( &m_rDoc ) );
1771 mpFieldTypes->emplace_back( new SwTableFieldType( &m_rDoc ) );
1772 mpFieldTypes->emplace_back( new SwMacroFieldType(m_rDoc) );
1773 mpFieldTypes->emplace_back( new SwHiddenParaFieldType );
1774 mpFieldTypes->emplace_back( new SwDBNextSetFieldType );
1775 mpFieldTypes->emplace_back( new SwDBNumSetFieldType );
1776 mpFieldTypes->emplace_back( new SwDBSetNumberFieldType );
1777 mpFieldTypes->emplace_back( new SwTemplNameFieldType(m_rDoc) );
1778 mpFieldTypes->emplace_back( new SwTemplNameFieldType(m_rDoc) );
1779 mpFieldTypes->emplace_back( new SwExtUserFieldType );
1780 mpFieldTypes->emplace_back( new SwRefPageSetFieldType );
1781 mpFieldTypes->emplace_back( new SwRefPageGetFieldType(m_rDoc) );
1782 mpFieldTypes->emplace_back( new SwJumpEditFieldType(m_rDoc) );
1783 mpFieldTypes->emplace_back( new SwScriptFieldType(m_rDoc) );
1784 mpFieldTypes->emplace_back( new SwCombinedCharFieldType );
1785 mpFieldTypes->emplace_back( new SwDropDownFieldType );
1786
1787 // Types have to be at the end!
1788 // We expect this in the InsertFieldType!
1789 // MIB 14.04.95: In Sw3StringPool::Setup (sw3imp.cxx) and
1790 // lcl_sw3io_InSetExpField (sw3field.cxx) now also
1791 mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
1792 SwResId(STR_POOLCOLL_LABEL_ABB), nsSwGetSetExpType::GSE_SEQ) );
1793 mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
1794 SwResId(STR_POOLCOLL_LABEL_TABLE), nsSwGetSetExpType::GSE_SEQ) );
1795 mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
1796 SwResId(STR_POOLCOLL_LABEL_FRAME), nsSwGetSetExpType::GSE_SEQ) );
1797 mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
1798 SwResId(STR_POOLCOLL_LABEL_DRAWING), nsSwGetSetExpType::GSE_SEQ) );
1799 mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
1800 SwResId(STR_POOLCOLL_LABEL_FIGURE), nsSwGetSetExpType::GSE_SEQ) );
1801
1802 assert( mpFieldTypes->size() == INIT_FLDTYPES );
1803}
1804
1806{
1807 mpFieldTypes->erase( mpFieldTypes->begin() + INIT_FLDTYPES, mpFieldTypes->end() );
1808}
1809
1811{
1812#if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
1813 (void) rDBField;
1814 (void) rCalc;
1815#else
1817
1818 SwFieldIds nFieldType = rDBField.Which();
1819
1820 bool bPar1 = rCalc.Calculate( rDBField.GetPar1() ).GetBool();
1821
1822 if( SwFieldIds::DbNextSet == nFieldType )
1823 static_cast<SwDBNextSetField&>(rDBField).SetCondValid( bPar1 );
1824 else
1825 static_cast<SwDBNumSetField&>(rDBField).SetCondValid( bPar1 );
1826
1827 if( !rDBField.GetRealDBData().sDataSource.isEmpty() )
1828 {
1829 // Edit a certain database
1830 if( SwFieldIds::DbNextSet == nFieldType )
1831 static_cast<SwDBNextSetField&>(rDBField).Evaluate(m_rDoc);
1832 else
1833 static_cast<SwDBNumSetField&>(rDBField).Evaluate(m_rDoc);
1834
1835 SwDBData aTmpDBData( rDBField.GetDBData(&m_rDoc) );
1836
1837 if( pMgr->OpenDataSource( aTmpDBData.sDataSource, aTmpDBData.sCommand ))
1838 rCalc.VarChange( lcl_GetDBVarName( m_rDoc, rDBField),
1839 pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType) );
1840 }
1841 else
1842 {
1843 OSL_FAIL("TODO: what should happen with unnamed DBFields?");
1844 }
1845#endif
1846}
1847
1849{
1850 mpUpdateFields.reset();
1851 mpFieldTypes.reset();
1852}
1853
1854}
1855
1856/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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
sal_uInt16 Which() 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:199
void VarChange(const OUString &rStr, const SwSbxValue &rValue)
Definition: calc.cxx:596
SwSbxValue Calculate(const OUString &rStr)
Definition: calc.cxx:362
SwCalcExp * VarLook(const OUString &rStr, bool bIns=false)
Definition: calc.cxx:428
bool IsCalcError() const
Definition: calc.hxx:255
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1230
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:2021
void CloseAll(bool bIncludingMerge=true)
close all data sources - after fields were updated
Definition: dbmgr.cxx:2421
bool FillCalcWithMergeData(SvNumberFormatter *pDocFormatter, LanguageType nLanguage, SwCalc &aCalc)
Definition: dbmgr.cxx:2124
bool OpenDataSource(const OUString &rDataSource, const OUString &rTableOrQuery)
open the source while fields are updated - for the calculator only!
Definition: dbmgr.cxx:2308
sal_uInt32 GetSelectedRecordId(const OUString &rDataSource, const OUString &rTableOrQuery, sal_Int32 nCommandType=-1)
Definition: dbmgr.cxx:2376
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:858
void SetExpansion(const OUString &rStr)
Definition: docufld.hxx:541
const OUString & GetName() const
Definition: docufld.hxx:539
virtual sal_uInt16 GetSubType() const override
Definition: docufld.cxx:1142
void SetFieldsDirty(bool b)
Definition: docfld.hxx:178
Definition: doc.hxx:194
bool IsInReading() const
Definition: doc.hxx:962
SwDBData const & GetDBData()
Definition: docfld.cxx:383
SwSectionFormats & GetSections()
Definition: doc.hxx:1345
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:400
bool IsInDtor() const
Definition: doc.hxx:412
o3tl::sorted_vector< SwRootFrame * > GetAllLayouts()
Definition: doclay.cxx:1683
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:971
SwDBManager * GetDBManager() const
Definition: doc.hxx:678
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:150
SwNodes & GetNodes()
Definition: doc.hxx:417
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:341
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1326
void ChgDBData(const SwDBData &rNewData)
Definition: doc.cxx:459
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1418
Field type for dropdown boxes.
Definition: flddropdown.hxx:32
static OUString Expand(sal_uInt16 nSubType)
Definition: docufld.cxx:1969
virtual sal_uInt16 GetSubType() const override
Definition: docufld.cxx:2026
void SetExpansion(const OUString &rStr)
Definition: docufld.hxx:570
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:242
virtual void UpdateFields()
Definition: fldbas.cxx:213
virtual OUString GetName() const
Only in derived classes.
Definition: fldbas.cxx:137
SwFieldIds Which() const
Definition: fldbas.hxx:273
static const OUString & GetTypeStr(SwFieldTypesEnum nTypeId)
Definition: fldbas.cxx:122
void GatherFields(std::vector< SwFormatField * > &rvFormatFields, bool bCollectOnlyInDocNodes=true) const
Definition: fldbas.cxx:203
virtual std::unique_ptr< SwFieldType > Copy() const =0
Base class of all fields.
Definition: fldbas.hxx:292
virtual OUString GetPar1() const
Definition: fldbas.cxx:321
std::unique_ptr< SwField > CopyField() const
Definition: fldbas.cxx:504
virtual sal_uInt16 GetSubType() const
Definition: fldbas.cxx:342
sal_uInt32 GetFormat() const
Query parameters for dialog and for BASIC.
Definition: fldbas.hxx:403
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt16 nWhichId) const
Definition: fldbas.cxx:351
OUString ExpandField(bool bCached, SwRootFrame const *pLayout) const
expand the field.
Definition: fldbas.cxx:484
virtual bool PutValue(const css::uno::Any &rVal, sal_uInt16 nWhichId)
Definition: fldbas.cxx:369
SwFieldType * GetTyp() const
Definition: fldbas.hxx:398
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:250
LanguageType GetLanguage() const
Language at field position.
Definition: fldbas.hxx:408
bool IsFixed() const
Definition: fldbas.cxx:452
void SetExpansion(const OUString &rStr)
Definition: docufld.hxx:224
const SwField * GetField() const
Definition: fmtfld.hxx:130
void SetField(std::unique_ptr< SwField > pField)
Sets current field.
Definition: atrfld.cxx:176
void UpdateTextNode(const SfxPoolItem *pOld, const SfxPoolItem *pNew)
Definition: atrfld.cxx:308
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:766
Style of a layout element.
Definition: frmfmt.hxx:62
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:295
bool IsInBodyText() const
Called by formatting.
Definition: expfld.hxx:139
virtual void SetValue(const double &rVal) override
Definition: expfld.cxx:938
Get reference.
Definition: reffld.hxx:66
T should be a subclass of SwHash.
Definition: calc.hxx:154
T * Find(std::u16string_view aStr, sal_uInt32 *pPos=nullptr) const
Definition: calc.hxx:165
void resize(size_t nSize)
Definition: calc.hxx:163
void SetHidden(bool bHidden)
Definition: docufld.hxx:375
virtual OUString GetPar1() const override
Query, set condition.
Definition: docufld.cxx:1707
void Evaluate(SwDoc &rDoc)
get current field value and cache it
Definition: docufld.cxx:1332
virtual OUString GetPar1() const override
Definition: docufld.cxx:1419
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:136
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:171
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:897
SwNodeOffset GetIndex() const
Definition: node.hxx:312
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:742
SwNodeOffset StartOfSectionIndex() const
Definition: node.hxx:722
bool IsSectionNode() const
Definition: node.hxx:693
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:380
SwContentNode * GetContentNode()
Definition: node.hxx:664
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:731
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:2522
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1294
const SwPosition * GetMark() const
Definition: pam.hxx:263
const SwPosition * GetPoint() const
Definition: pam.hxx:261
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1940
vector_type::size_type size_type
Definition: docary.hxx:222
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding).
Definition: rootfrm.hxx:421
bool IsVoidValue() const
Definition: calc.hxx:126
bool GetBool() const
Definition: calc.cxx:1461
double GetDouble() const
Definition: calc.cxx:1467
SwSection * GetSection() const
Definition: section.cxx:638
SwSectionFormat * GetParent() const
Definition: section.hxx:356
SwSectionNode * GetSectionNode()
Definition: section.cxx:923
Array of Undo-history.
Definition: docary.hxx:192
OUString const & GetCondition() const
Definition: section.hxx:199
void SetCondHidden(bool const bFlag)
Definition: section.cxx:501
bool IsCondHidden() const
Definition: section.hxx:193
void SetCondition(OUString const &rNew)
Definition: section.hxx:200
bool CalcHiddenFlag() const
Definition: section.cxx:315
virtual OUString GetName() const override
Only in derived classes.
Definition: expfld.cxx:530
void SetChapter(SwSetExpField &rField, const SwNode &rNd, SwRootFrame const *pLayout)
Definition: expfld.cxx:642
sal_uInt8 GetOutlineLvl() const
Definition: expfld.hxx:183
virtual void SetValue(const double &rVal) override
Definition: expfld.cxx:901
void ChgExpStr(const OUString &rExpand, SwRootFrame const *pLayout)
Definition: expfld.cxx:540
bool IsSequenceField() const
Definition: expfld.hxx:272
const OUString & GetExpStr(SwRootFrame const *pLayout) const
Definition: expfld.cxx:535
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:426
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:478
SwFrameFormat * ClaimFrameFormat()
Definition: swtable.cxx:1917
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
TableFormulaUpdateFlags m_eFlags
Definition: hints.hxx:286
const SwTable * m_pTable
Pointer to the current table.
Definition: hints.hxx:279
void ChgValid(bool bNew)
Definition: cellfml.hxx:136
void ToRelBoxNm(const SwTable *pTable)
create from the external/internal formula the relative formula
Definition: cellfml.cxx:630
void BoxNmToPtr(const SwTable *pTable)
create from the external formula the internal
Definition: cellfml.cxx:605
bool IsValid() const
Definition: cellfml.hxx:135
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
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:673
bool LockNotifyContentChange()
Definition: atrfld.cxx:663
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:111
SwTextField * GetFieldTextAttrAt(const sal_Int32 nIndex, ::sw::GetTextAttrMode const eMode=::sw::GetTextAttrMode::Expand) const
Definition: ndtxt.cxx:1835
SwpHints & GetSwpHints()
getters for SwpHints
Definition: ndtxt.hxx:863
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4148
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:250
void TriggerNodeUpdate(const sw::LegacyModifyHint &)
for hanging TextFormatCollections somewhere else (Outline-Numbering!)
Definition: ndtxt.cxx:5412
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:415
virtual double GetValue() const
Definition: fldbas.cxx:745
std::vector< SwSectionFormat * >::size_type size_type
Definition: docary.hxx:66
size_t size() const
Definition: docary.hxx:87
SwTextAttr * Get(size_t nPos) const
Definition: ndhints.hxx:144
size_t Count() const
Definition: ndhints.hxx:142
virtual bool UpdateField(SwTextField *rDstFormatField, SwField &rSrcField, SwMsgPoolItem *pMsgHint, bool bUpdateTableFields) override
Updates a field.
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 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 UpdateTableFields(SfxPoolItem *pHt) override
virtual void InsDelFieldInFieldLst(bool bIns, const SwTextField &rField) override
virtual SwFieldType * GetSysFieldType(const SwFieldIds eWhich) const override
std::unique_ptr< SwFieldTypes > mpFieldTypes
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 void UpdatePageFields(SfxPoolItem *) 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 Hide(bool hide)=0
virtual const OUString & GetHideCondition() const =0
sal_Int64 GetTime() const
Any value
SwDoc & m_rDoc
Definition: docbm.cxx:1202
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:374
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:45
@ Database
For old documents the Field-Which IDs must be preserved !!!
@ TableOfAuthorities
sal_Int16 nValue
constexpr sal_uInt16 RES_BOXATR_END(153)
constexpr sal_uInt16 RES_BOXATR_BEGIN(RES_GRFATR_END)
constexpr TypedWhichId< SwTableBoxFormula > RES_BOXATR_FORMULA(151)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
constexpr TypedWhichId< SwTableBoxNumFormat > RES_BOXATR_FORMAT(RES_BOXATR_BEGIN)
constexpr TypedWhichId< SwTableFormulaUpdate > RES_TABLEFML_UPDATE(170)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_INPUTFIELD(55)
@ TBL_BOXPTR
Definition: hints.hxx:271
@ TBL_CALC
Definition: hints.hxx:269
@ TBL_BOXNAME
Definition: hints.hxx:270
@ TBL_RELBOXNAME
Definition: hints.hxx:272
const ::utl::TransliterationWrapper & GetAppCmpStrIgnore()
Definition: init.cxx:786
sal_Int64 n
#define LANGUAGE_SYSTEM
sal_uInt16 nPos
return NULL
int i
const SwExtendedSubType SUB_CMD
Show command.
Definition: fldbas.hxx:212
const SwGetSetExpType GSE_SEQ
Sequence.
Definition: fldbas.hxx:205
const SwGetSetExpType GSE_EXPR
Expression.
Definition: fldbas.hxx:204
const SwGetSetExpType GSE_STRING
String.
Definition: fldbas.hxx:203
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:144
sal_Int32 nCommandType
Definition: swdbdata.hxx:32
OUString sDataSource
Definition: swdbdata.hxx:30
OUString sCommand
Definition: swdbdata.hxx:31
Definition: calc.hxx:135
Marks a position in the document model.
Definition: pam.hxx:37
SwNode & GetNode() const
Definition: pam.hxx:80
sal_Int32 GetContentIndex() const
Definition: pam.hxx:84
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:165
#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[]