/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/ #include <DocumentFieldsManager.hxx> #include <config_features.h> #include <config_fuzzers.h> #include <doc.hxx> #include <IDocumentUndoRedo.hxx> #include <IDocumentState.hxx> #include <IDocumentRedlineAccess.hxx> #include <redline.hxx> #include <rootfrm.hxx> #include <dbmgr.hxx> #include <chpfld.hxx> #include <dbfld.hxx> #include <reffld.hxx> #include <flddropdown.hxx> #include <strings.hrc> #include <SwUndoField.hxx> #include <flddat.hxx> #include <cntfrm.hxx> #include <node2lay.hxx> #include <section.hxx> #include <docufld.hxx> #include <calbck.hxx> #include <cellatr.hxx> #include <swtable.hxx> #include <frmfmt.hxx> #include <fmtfld.hxx> #include <ndtxt.hxx> #include <txtfld.hxx> #include <docfld.hxx> #include <hints.hxx> #include <docary.hxx> #include <fldbas.hxx> #include <expfld.hxx> #include <ddefld.hxx> #include <authfld.hxx> #include <usrfld.hxx> #include <ndindex.hxx> #include <pam.hxx> #include <o3tl/deleter.hxx> #include <osl/diagnose.h> #include <unotools/transliterationwrapper.hxx> #include <comphelper/scopeguard.hxx> #include <com/sun/star/uno/Any.hxx>
bool IsFieldDeleted(IDocumentRedlineAccess const& rIDRA,
SwRootFrame const& rLayout, SwTextField const& rTextField)
{
SwTextNode const& rNode(rTextField.GetTextNode()); boolconst isInBody(
rNode.GetNodes().GetEndOfExtras().GetIndex() < rNode.GetIndex()); if (!isInBody && nullptr == rNode.getLayoutFrame(&rLayout))
{ // see SwDocUpdateField::GetBodyNode() - fields in hidden sections // don't have layout frames but must be updated, so use the same // check as there, but do it again because GetBodyNode() checks // for *any* layout... returntrue;
} return sw::IsFieldDeletedInModel(rIDRA, rTextField);
}
/** Insert field types * * @param rFieldTyp ??? * @return Always returns a pointer to the type, if it's new or already added.
*/
SwFieldType* DocumentFieldsManager::InsertFieldType(const SwFieldType &rFieldTyp)
{ const SwFieldTypes::size_type nSize = mpFieldTypes->size(); const SwFieldIds nFieldWhich = rFieldTyp.Which();
SwFieldTypes::size_type i = INIT_FLDTYPES;
switch( nFieldWhich )
{ case SwFieldIds::SetExp: //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!! // Or we get doubble number circles!! //MIB 14.03.95: From now on also the SW3-Reader relies on this, when //constructing string pools and when reading SetExp fields if( nsSwGetSetExpType::GSE_SEQ & static_cast<const SwSetExpFieldType&>(rFieldTyp).GetType() )
i -= INIT_SEQ_FLDTYPES;
[[fallthrough]]; case SwFieldIds::Database: case SwFieldIds::User: case SwFieldIds::Dde:
{ const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
OUString sFieldNm( rFieldTyp.GetName().toString() ); for( ; i < nSize; ++i ) if( nFieldWhich == (*mpFieldTypes)[i]->Which() &&
rSCmp.isEqual( sFieldNm, (*mpFieldTypes)[i]->GetName().toString() )) return (*mpFieldTypes)[i].get();
} break;
case SwFieldIds::TableOfAuthorities: for( ; i < nSize; ++i ) if( nFieldWhich == (*mpFieldTypes)[i]->Which() ) return (*mpFieldTypes)[i].get(); break;
default: for( i = 0; i < nSize; ++i ) if( nFieldWhich == (*mpFieldTypes)[i]->Which() ) return (*mpFieldTypes)[i].get();
}
case SwFieldIds::Database: case SwFieldIds::Table: case SwFieldIds::DateTime: case SwFieldIds::GetExp: static_cast<SwValueFieldType*>(pNew.get())->SetDoc( &m_rDoc ); break;
case SwFieldIds::User: case SwFieldIds::SetExp: static_cast<SwValueFieldType*>(pNew.get())->SetDoc( &m_rDoc ); // JP 29.07.96: Optionally prepare FieldList for Calculator:
mpUpdateFields->InsertFieldType( *pNew ); break; case SwFieldIds::TableOfAuthorities : static_cast<SwAuthorityFieldType*>(pNew.get())->SetDoc( &m_rDoc ); break; default: break;
}
/// @returns the field type of the Doc
SwFieldType *DocumentFieldsManager::GetSysFieldType( const SwFieldIds eWhich ) const
{ for( SwFieldTypes::size_type i = 0; i < INIT_FLDTYPES; ++i ) if( eWhich == (*mpFieldTypes)[i]->Which() ) return (*mpFieldTypes)[i].get(); return nullptr;
}
/// Find first type with ResId and name
SwFieldType* DocumentFieldsManager::GetFieldType(
SwFieldIds nResId, const OUString& rName, bool bDbFieldMatching // used in some UNO calls for SwFieldIds::Database to use different string matching code #i51815#
) const
{ const SwFieldTypes::size_type nSize = mpFieldTypes->size();
SwFieldTypes::size_type i {0}; const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
switch( nResId )
{ case SwFieldIds::SetExp: //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!! // Or we get doubble number circles!! //MIB 14.03.95: From now on also the SW3-Reader relies on this, when //constructing string pools and when reading SetExp fields
i = INIT_FLDTYPES - INIT_SEQ_FLDTYPES; break;
case SwFieldIds::Database: case SwFieldIds::User: case SwFieldIds::Dde: case SwFieldIds::TableOfAuthorities:
i = INIT_FLDTYPES; break; default: break;
}
SwFieldType* pRet = nullptr; for( ; i < nSize; ++i )
{
SwFieldType* pFieldType = (*mpFieldTypes)[i].get();
if( nWhich != SwFieldIds::Database )
{
OSL_ENSURE( !pTmp->HasWriterListeners(), "Dependent fields present!" );
} else
{ // coverity[leaked_storage] - at this point DB fields are ref-counted and delete themselves
(*mpFieldTypes)[nField].release();
}
// All have to be re-evaluated. void DocumentFieldsManager::UpdateFields(bool bCloseDB, bool bSetModified)
{ // Tell all types to update their fields for(autoconst& pFieldType: *mpFieldTypes)
pFieldType->UpdateFields();
// References
UpdateRefFields(); if(bCloseDB)
{ #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
m_rDoc.GetDBManager()->CloseAll(); #endif
} if (bSetModified)
{ // Only evaluate on full update
m_rDoc.getIDocumentState().SetModified();
}
}
void DocumentFieldsManager::InsDeletedFieldType( SwFieldType& rFieldTyp )
{ // The FieldType was marked as deleted and removed from the array. // One has to look this up again, now. // - If it's not present, it can be re-inserted. // - If the same type is found, the deleted one has to be renamed.
switch( nFieldWhich )
{ case SwFieldIds::SetExp: case SwFieldIds::GetExp: case SwFieldIds::HiddenText: case SwFieldIds::HiddenPara:
UpdateExpFields( pDstTextField, true ); break;
case SwFieldIds::Table:
{ const SwTableNode* pTableNd =
SwDoc::IsIdxInTable(aTableNdIdx); if( pTableNd )
{ if (bUpdateFields)
UpdateTableFields(&pTableNd->GetTable()); else
pNewField->GetTyp()->CallSwClientNotify(sw::LegacyModifyHint(nullptr, nullptr));
if (! bUpdateFields)
bTableSelBreak = true;
}
} break;
case SwFieldIds::Macro: if( bUpdateFields && pDstTextField->GetpTextNode() )
pDstTextField->GetpTextNode()->TriggerNodeUpdate(sw::LegacyModifyHint(nullptr, pDstFormatField)); break;
case SwFieldIds::DatabaseName: case SwFieldIds::DbNextSet: case SwFieldIds::DbNumSet: case SwFieldIds::DbSetNumber:
m_rDoc.ChgDBData(static_cast<SwDBNameInfField*>( pNewField)->GetRealDBData());
pNewField->GetTyp()->UpdateFields();
break;
case SwFieldIds::Database: #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
{ // JP 10.02.96: call ChgValue, so that the style change sets the // ContentString correctly
SwDBField* pDBField = static_cast<SwDBField*>(pNewField); if (pDBField->IsInitialized())
pDBField->ChgValue( pDBField->GetValue(), true );
void DocumentFieldsManager::UpdateTableFields(const SwTable* pTable)
{ auto pFieldType = GetFieldType( SwFieldIds::Table, OUString(), false ); if(pFieldType)
{
std::vector<SwFormatField*> vFields;
pFieldType->GatherFields(vFields); for(auto pFormatField : vFields)
{ if(!pFormatField->GetTextField()->GetTextNode().FindTableNode()) continue;
SwTableField* pField = static_cast<SwTableField*>(pFormatField->GetField()); // re-set the value flag // JP 17.06.96: internal representation of all formulas // (reference to other table!!!) if(pTable && nsSwExtendedSubType::SUB_CMD & pField->GetSubType())
pField->PtrToBoxNm(pTable); else // reset the value flag for all
pField->ChgValid(false);
}
} // process all table box formulas
std::vector<SwTableBoxFormula*> aTableBoxFormulas;
SwTable::GatherFormulas(m_rDoc, aTableBoxFormulas); for (SwTableBoxFormula* pBoxFormula : aTableBoxFormulas)
{ if(pBoxFormula->GetDefinedIn())
pBoxFormula->ChangeState();
}
SwRootFrame const* pLayout(nullptr); for (SwRootFrame const*const pLay : m_rDoc.GetAllLayouts())
{
assert(!pLayout || pLay->IsHideRedlines() == pLayout->IsHideRedlines()); // TODO
pLayout = pLay;
}
std::optional<SwCalc> oCalc;
if( pFieldType )
{
std::vector<SwFormatField*> vFields;
pFieldType->GatherFields(vFields); for(SwFormatField* pFormatField: vFields)
{ // start calculation at the end // new fields are inserted at the beginning of the modify chain // that gives faster calculation on import // mba: do we really need this "optimization"? Is it still valid?
SwTableField *const pField(static_cast<SwTableField*>(pFormatField->GetField())); if (nsSwExtendedSubType::SUB_CMD & pField->GetSubType()) continue;
// needs to be recalculated if( !pField->IsValid() )
{ // table where this field is located const SwTextNode& rTextNd = pFormatField->GetTextField()->GetTextNode(); const SwTableNode* pTableNd = rTextNd.FindTableNode(); if( !pTableNd ) continue;
// if this field is not in the to-be-updated table, skip it if(pTable && &pTableNd->GetTable() != pTable) continue;
if( !oCalc )
oCalc.emplace( m_rDoc );
// get the values of all SetExpression fields that are valid // until the table
SwFrame* pFrame = nullptr; if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
{ // is in the special section, that's expensive!
Point aPt; // return the first frame of the layout - Tab.Headline!!
std::pair<Point, bool> const tmp(aPt, true);
pFrame = rTextNd.getLayoutFrame(pLayout, nullptr, &tmp); if( pFrame )
{
SwPosition aPos( *pTableNd ); if( GetBodyTextNode( m_rDoc, aPos, *pFrame ) )
{
FieldsToCalc( *oCalc, SetGetExpField(
aPos.GetNode(), pFormatField->GetTextField(),
aPos.GetContentIndex(), pFrame->GetPhyPageNum()),
pLayout);
} else
pFrame = nullptr;
}
} if( !pFrame )
{ // create index to determine the TextNode
SwFrame const*const pFrame2 = ::sw::FindNeighbourFrameForNode(rTextNd);
FieldsToCalc( *oCalc,
SetGetExpField(rTextNd, pFormatField->GetTextField(),
std::nullopt,
pFrame2 ? pFrame2->GetPhyPageNum() : 0),
pLayout);
}
SwTableCalcPara aPara(*oCalc, pTableNd->GetTable(), pLayout);
pField->CalcField( aPara ); if( aPara.IsStackOverflow() )
{ boolconst bResult = aPara.CalcWithStackOverflow(); if (bResult)
{
pField->CalcField( aPara );
}
OSL_ENSURE(bResult, "the chained formula could no be calculated");
}
oCalc->SetCalcError( SwCalcError::NONE );
}
pFormatField->ForceUpdateTextNode();
}
}
// calculate the formula at the boxes
SwTable::GatherFormulas(m_rDoc, aTableBoxFormulas); for (SwTableBoxFormula* pItem : aTableBoxFormulas)
{ auto & rFormula = *pItem; if(!rFormula.GetDefinedIn() || rFormula.IsValid()) continue;
SwTableBox* pBox = rFormula.GetTableBox(); if(!pBox || !pBox->GetSttNd() || !pBox->GetSttNd()->GetNodes().IsDocNodes()) continue; const SwTableNode* pTableNd = pBox->GetSttNd()->FindTableNode(); if(pTable && &pTableNd->GetTable() != pTable) continue; double nValue; if( !oCalc )
oCalc.emplace( m_rDoc );
// get the values of all SetExpression fields that are valid // until the table
SwFrame* pFrame = nullptr; if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
{ // is in the special section, that's expensive!
SwNodeIndex aCNdIdx( *pTableNd, +2 );
SwContentNode* pCNd = aCNdIdx.GetNode().GetContentNode(); if( !pCNd )
pCNd = SwNodes::GoNext(&aCNdIdx);
if (pCNd)
{
Point aPt; // return the first frame of the layout - Tab.Headline!!
std::pair<Point, bool> const tmp(aPt, true);
pFrame = pCNd->getLayoutFrame(pLayout, nullptr, &tmp); if( pFrame )
{
SwPosition aPos( *pCNd ); if( GetBodyTextNode( m_rDoc, aPos, *pFrame ) )
{
FieldsToCalc(*oCalc, SetGetExpField(aPos.GetNode(),
nullptr, std::nullopt, pFrame->GetPhyPageNum()),
pLayout);
} else
pFrame = nullptr;
}
}
} if( !pFrame )
{ // create index to determine the TextNode
SwFrame const*const pFrame2 = ::sw::FindNeighbourFrameForNode(*pTableNd);
FieldsToCalc(*oCalc, SetGetExpField(*pTableNd, nullptr, std::nullopt,
pFrame2 ? pFrame2->GetPhyPageNum() : 0),
pLayout);
}
if( aPara.IsStackOverflow() )
{ boolconst bResult = aPara.CalcWithStackOverflow(); if (bResult)
{
rFormula.Calc( aPara, nValue );
}
OSL_ENSURE(bResult, "the chained formula could no be calculated");
}
// Make sure we don't hide all content, which would lead to a crash. First, count how many visible sections we have. int nShownSections = 0;
SwNodeOffset nContentStart = m_rDoc.GetNodes().GetEndOfContent().StartOfSectionIndex() + 1;
SwNodeOffset nContentEnd = m_rDoc.GetNodes().GetEndOfContent().GetIndex();
SwSectionFormats& rSectFormats = m_rDoc.GetSections(); for( SwSectionFormats::size_type n = 0; n<rSectFormats.size(); ++n )
{
SwSectionFormat& rSectFormat = *rSectFormats[ n ];
SwSectionNode* pSectionNode = rSectFormat.GetSectionNode();
SwSection* pSect = rSectFormat.GetSection();
// Usually some of the content is not in a section: count that as a virtual section, so that all real sections can be hidden. // Only look for section gaps at the lowest level, ignoring sub-sections. if ( pSectionNode && !rSectFormat.GetParent() )
{
SwNodeIndex aNextIdx( *pSectionNode->EndOfSectionNode(), 1 ); if ( n == 0 && pSectionNode->GetIndex() != nContentStart )
nShownSections++; //document does not start with a section if ( n == rSectFormats.size() - 1 )
{ if ( aNextIdx.GetIndex() != nContentEnd )
nShownSections++; //document does not end in a section
} elseif ( !aNextIdx.GetNode().IsSectionNode() )
nShownSections++; //section is not immediately followed by another section
}
// count only visible sections if ( pSect && !pSect->CalcHiddenFlag())
nShownSections++;
}
for (std::unique_ptr<SetGetExpField> const& it : *mpUpdateFields->GetSortList())
{
SwSection* pSect = const_cast<SwSection*>(it->GetSection()); if( pSect )
{
SwSbxValue aValue = aCalc.Calculate(
pSect->GetCondition() ); if(!aValue.IsVoidValue())
{ // Do we want to hide this one? bool bHide = aValue.GetBool(); if (bHide && !pSect->IsCondHidden())
{ // This section will be hidden, but it wasn't before if (nShownSections == 1)
{ // This would be the last section, so set its condition to false, and avoid hiding it.
pSect->SetCondition(u"0"_ustr);
bHide = false;
}
nShownSections--;
}
pSect->SetCondHidden( bHide );
} continue;
}
::sw::mark::Bookmark *const pBookmark( const_cast<::sw::mark::Bookmark *>(it->GetBookmark())); if (pBookmark)
{
SwSbxValue const aValue(aCalc.Calculate(pBookmark->GetHideCondition())); if (!aValue.IsVoidValue())
{
pBookmark->Hide(aValue.GetBool());
} continue;
}
if( pSField->IsSequenceField() )
{ const sal_uInt8 nLvl = pSFieldTyp->GetOutlineLvl(); if( MAXLEVEL > nLvl )
{ // test if the Number needs to be updated
pSeqNd = m_rDoc.GetNodes()[ it->GetNode() ];
{ // avoid calling ReplaceText() for input fields, it is pointless // here and moves the cursor if it's inside the field ...
SwTextInputField *const pInputField(
pUpdateField == pTextField // ... except once, when the dialog
? nullptr // is used to change content via UpdateOneField()
: dynamic_cast<SwTextInputField *>(pTextField)); if (pInputField)
{ boolconst tmp = pInputField->LockNotifyContentChange();
(void) tmp;
assert(tmp && "should not be locked here?");
}
::comphelper::ScopeGuard g([pInputField]()
{ if (pInputField)
{
pInputField->UnlockNotifyContentChange();
}
});
pFormatField->ForceUpdateTextNode();
}
if (pUpdateField == pTextField) // if only this one is updated
{ if( SwFieldIds::GetExp == nWhich || // only GetField or
SwFieldIds::HiddenText == nWhich || // HiddenText?
SwFieldIds::HiddenPara == nWhich) // HiddenParaField? break; // quit
pUpdateField = nullptr; // update all from here on
}
}
switch( pField->GetTyp()->Which() )
{ case SwFieldIds::DbNextSet: case SwFieldIds::DbNumSet:
nRecords++; break; default: break;
}
}
return nRecords;
}
void DocumentFieldsManager::UpdatePageFields(const SwTwips nDocPos)
{ for(SwFieldTypes::size_type i = 0; i < INIT_FLDTYPES; ++i)
{
SwFieldType* pFieldType = (*mpFieldTypes)[i].get(); switch(pFieldType->Which())
{ case SwFieldIds::PageNumber: case SwFieldIds::Chapter: case SwFieldIds::GetExp: case SwFieldIds::RefPageGet:
pFieldType->UpdateDocPos(nDocPos); break; case SwFieldIds::DocStat:
{
pFieldType->CallSwClientNotify(sw::LegacyModifyHint(nullptr, nullptr));
SwRootFrame const* pLayout(nullptr); for (SwRootFrame const*const pLay : m_rDoc.GetAllLayouts())
{ if (!pLay->IsHideRedlines())
pLayout = pLay;
} static_cast<SwDocStatFieldType*>(pFieldType)->UpdateRangeFields(pLayout);
} break; case SwFieldIds::GetRef: static_cast<SwGetRefFieldType*>(pFieldType)->UpdateStyleReferences(); // Style references can vary across different pages (e.g. in header/footer) // so they must be updated when page fields are break; default: break;
}
}
SetNewFieldLst(true);
}
SwRootFrame const* pLayout(nullptr);
SwRootFrame const* pLayoutRLHidden(nullptr); for (SwRootFrame const*const pLay : m_rDoc.GetAllLayouts())
{ if (pLay->IsHideRedlines())
{
pLayoutRLHidden = pLay;
} else
{
pLayout = pLay;
}
}
// note this is not duplicate of the other FieldsToCalc because there is // (currently) no SetGetExpField that compares only a position for(auto it = mpUpdateFields->GetSortList()->begin();
it != mpUpdateFields->GetSortList()->end() &&
( (*it)->GetNode() < nLastNd ||
( (*it)->GetNode() == nLastNd && (*it)->GetContent() <= nLastCnt )
);
++it )
{ if (pLayout || !pLayoutRLHidden) // always calc *something*...
{
lcl_CalcField( m_rDoc, rCalc, **it, pMgr, pLayout );
} if (pLayoutRLHidden)
{
lcl_CalcField( m_rDoc, rCalc, **it, pMgr, pLayoutRLHidden );
}
}
for (auto it = mpUpdateFields->GetSortList()->begin(); it != itLast; ++it)
{ const SwTextField* pTextField = (*it)->GetTextField(); if( !pTextField ) continue;
if (rLayout.IsHideRedlines()
&& IsFieldDeleted(rIDRA, rLayout, *pTextField))
{ continue;
}
const SwField* pField = pTextField->GetFormatField().GetField(); switch( pField->GetTyp()->Which() )
{ case SwFieldIds::SetExp: if( nsSwGetSetExpType::GSE_STRING & pField->GetSubType() )
{ // set the new value in the hash table // is the formula a field?
SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
OUString aNew = LookString( rHashTable, pSField->GetFormula() );
if( aNew.isEmpty() ) // nothing found, then the formula is
aNew = pSField->GetFormula(); // the new value
// #i3141# - update expression of field as in method // <SwDoc::UpdateExpFields(..)> for string/text fields
pSField->ChgExpStr(aNew, &rLayout);
// look up the field's name
aNew = static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName().toString(); // Entry present? auto pFnd = rHashTable.find( aNew ); if( pFnd != rHashTable.end() ) // modify entry in the hash table
pFnd->second = pSField->GetExpStr(&rLayout); else // insert the new entry
rHashTable.insert( { aNew, pSField->GetExpStr(&rLayout) } );
} break; case SwFieldIds::Database:
{ const OUString aName = pField->GetTyp()->GetName().toString();
// Insert entry in the hash table // Entry present? auto pFnd = rHashTable.find( aName );
OUString const value(pField->ExpandField(m_rDoc.IsClipBoard(), nullptr)); if( pFnd != rHashTable.end() ) // modify entry in the hash table
pFnd->second = value; else // insert the new entry
rHashTable.insert( { aName, value } );
} break; default: break;
}
}
}
/// @note For simplicity assume that all field types have updatable contents so /// optimization currently only available when no fields exist. bool DocumentFieldsManager::containsUpdatableFields()
{
std::vector<SwFormatField*> vFields; for (autoconst& pFieldType: *mpFieldTypes)
{
pFieldType->GatherFields(vFields); if(vFields.size()>0) returntrue;
} returnfalse;
}
/// Remove all unreferenced field types of a document void DocumentFieldsManager::GCFieldTypes()
{ for( auto n = mpFieldTypes->size(); n > INIT_FLDTYPES; ) if( !(*mpFieldTypes)[ --n ]->HasWriterListeners() )
RemoveFieldType( n );
}
void DocumentFieldsManager::InitFieldTypes() // is being called by the CTOR
{ // Field types
mpFieldTypes->emplace_back( new SwDateTimeFieldType(&m_rDoc) );
mpFieldTypes->emplace_back( new SwChapterFieldType );
mpFieldTypes->emplace_back( new SwPageNumberFieldType );
mpFieldTypes->emplace_back( new SwAuthorFieldType );
mpFieldTypes->emplace_back( new SwFileNameFieldType(m_rDoc) );
mpFieldTypes->emplace_back( new SwDBNameFieldType(&m_rDoc) );
mpFieldTypes->emplace_back( new SwGetExpFieldType(&m_rDoc) );
mpFieldTypes->emplace_back( new SwGetRefFieldType(m_rDoc) );
mpFieldTypes->emplace_back( new SwHiddenTextFieldType );
mpFieldTypes->emplace_back( new SwPostItFieldType(m_rDoc) );
mpFieldTypes->emplace_back( new SwDocStatFieldType(m_rDoc) );
mpFieldTypes->emplace_back( new SwDocInfoFieldType(&m_rDoc) );
mpFieldTypes->emplace_back( new SwInputFieldType( &m_rDoc ) );
mpFieldTypes->emplace_back( new SwTableFieldType( &m_rDoc ) );
mpFieldTypes->emplace_back( new SwMacroFieldType(m_rDoc) );
mpFieldTypes->emplace_back( new SwHiddenParaFieldType );
mpFieldTypes->emplace_back( new SwDBNextSetFieldType );
mpFieldTypes->emplace_back( new SwDBNumSetFieldType );
mpFieldTypes->emplace_back( new SwDBSetNumberFieldType );
mpFieldTypes->emplace_back( new SwTemplNameFieldType(m_rDoc) );
mpFieldTypes->emplace_back( new SwTemplNameFieldType(m_rDoc) );
mpFieldTypes->emplace_back( new SwExtUserFieldType );
mpFieldTypes->emplace_back( new SwRefPageSetFieldType );
mpFieldTypes->emplace_back( new SwRefPageGetFieldType(m_rDoc) );
mpFieldTypes->emplace_back( new SwJumpEditFieldType(m_rDoc) );
mpFieldTypes->emplace_back( new SwScriptFieldType(m_rDoc) );
mpFieldTypes->emplace_back( new SwCombinedCharFieldType );
mpFieldTypes->emplace_back( new SwDropDownFieldType );
// Types have to be at the end! // We expect this in the InsertFieldType! // MIB 14.04.95: In Sw3StringPool::Setup (sw3imp.cxx) and // lcl_sw3io_InSetExpField (sw3field.cxx) now also
mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
UIName(SwResId(STR_POOLCOLL_LABEL_ABB)), nsSwGetSetExpType::GSE_SEQ) );
mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
UIName(SwResId(STR_POOLCOLL_LABEL_TABLE)), nsSwGetSetExpType::GSE_SEQ) );
mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
UIName(SwResId(STR_POOLCOLL_LABEL_FRAME)), nsSwGetSetExpType::GSE_SEQ) );
mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
UIName(SwResId(STR_POOLCOLL_LABEL_DRAWING)), nsSwGetSetExpType::GSE_SEQ) );
mpFieldTypes->emplace_back( new SwSetExpFieldType(&m_rDoc,
UIName(SwResId(STR_POOLCOLL_LABEL_FIGURE)), nsSwGetSetExpType::GSE_SEQ) );
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.