summaryrefslogtreecommitdiffstats
path: root/sw/source/core/fields/expfld.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/fields/expfld.cxx')
-rw-r--r--sw/source/core/fields/expfld.cxx1445
1 files changed, 1445 insertions, 0 deletions
diff --git a/sw/source/core/fields/expfld.cxx b/sw/source/core/fields/expfld.cxx
new file mode 100644
index 000000000..e6d810506
--- /dev/null
+++ b/sw/source/core/fields/expfld.cxx
@@ -0,0 +1,1445 @@
+/* -*- 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 <sal/config.h>
+
+#include <limits>
+
+#include <UndoTable.hxx>
+#include <hintids.hxx>
+#include <o3tl/any.hxx>
+#include <osl/diagnose.h>
+#include <unotools/collatorwrapper.hxx>
+#include <unotools/charclass.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <com/sun/star/text/SetVariableType.hpp>
+#include <unofield.hxx>
+#include <frmfmt.hxx>
+#include <fmtfld.hxx>
+#include <txtfld.hxx>
+#include <fmtanchr.hxx>
+#include <txtftn.hxx>
+#include <doc.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <layfrm.hxx>
+#include <pagefrm.hxx>
+#include <cntfrm.hxx>
+#include <txtfrm.hxx>
+#include <rootfrm.hxx>
+#include <tabfrm.hxx>
+#include <flyfrm.hxx>
+#include <ftnfrm.hxx>
+#include <rowfrm.hxx>
+#include <expfld.hxx>
+#include <usrfld.hxx>
+#include <ndtxt.hxx>
+#include <calc.hxx>
+#include <pam.hxx>
+#include <docfld.hxx>
+#include <swtable.hxx>
+#include <breakit.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <unofldmid.h>
+#include <numrule.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::text;
+
+static sal_Int16 lcl_SubTypeToAPI(sal_uInt16 nSubType)
+{
+ sal_Int16 nRet = 0;
+ switch(nSubType)
+ {
+ case nsSwGetSetExpType::GSE_EXPR:
+ nRet = SetVariableType::VAR; // 0
+ break;
+ case nsSwGetSetExpType::GSE_SEQ:
+ nRet = SetVariableType::SEQUENCE; // 1
+ break;
+ case nsSwGetSetExpType::GSE_FORMULA:
+ nRet = SetVariableType::FORMULA; // 2
+ break;
+ case nsSwGetSetExpType::GSE_STRING:
+ nRet = SetVariableType::STRING; // 3
+ break;
+ }
+ return nRet;
+}
+
+static sal_Int32 lcl_APIToSubType(const uno::Any& rAny)
+{
+ sal_Int16 nVal = 0;
+ rAny >>= nVal;
+ sal_Int32 nSet = 0;
+ switch(nVal)
+ {
+ case SetVariableType::VAR: nSet = nsSwGetSetExpType::GSE_EXPR; break;
+ case SetVariableType::SEQUENCE: nSet = nsSwGetSetExpType::GSE_SEQ; break;
+ case SetVariableType::FORMULA: nSet = nsSwGetSetExpType::GSE_FORMULA; break;
+ case SetVariableType::STRING: nSet = nsSwGetSetExpType::GSE_STRING; break;
+ default:
+ OSL_FAIL("wrong value");
+ nSet = -1;
+ }
+ return nSet;
+}
+
+OUString ReplacePoint( const OUString& rTmpName, bool bWithCommandType )
+{
+ // replace first and last (if bWithCommandType: last two) dot
+ // since table names may contain dots
+
+ sal_Int32 nIndex = rTmpName.lastIndexOf('.');
+ if (nIndex<0)
+ {
+ return rTmpName;
+ }
+
+ OUString sRes = rTmpName.replaceAt(nIndex, 1, rtl::OUStringChar(DB_DELIM));
+
+ if (bWithCommandType)
+ {
+ nIndex = sRes.lastIndexOf('.', nIndex);
+ if (nIndex<0)
+ {
+ return sRes;
+ }
+ sRes = sRes.replaceAt(nIndex, 1, rtl::OUStringChar(DB_DELIM));
+ }
+
+ nIndex = sRes.indexOf('.');
+ if (nIndex>=0)
+ {
+ sRes = sRes.replaceAt(nIndex, 1, rtl::OUStringChar(DB_DELIM));
+ }
+ return sRes;
+}
+
+static SwTextNode* GetFirstTextNode( const SwDoc& rDoc, SwPosition& rPos,
+ const SwContentFrame *pCFrame, Point &rPt )
+{
+ SwTextNode* pTextNode = nullptr;
+ if ( !pCFrame )
+ {
+ const SwNodes& rNodes = rDoc.GetNodes();
+ rPos.nNode = *rNodes.GetEndOfContent().StartOfSectionNode();
+ SwContentNode* pCNd;
+ while( nullptr != (pCNd = rNodes.GoNext( &rPos.nNode ) ) &&
+ nullptr == ( pTextNode = pCNd->GetTextNode() ) )
+ ;
+ OSL_ENSURE( pTextNode, "Where is the 1. TextNode?" );
+ rPos.nContent.Assign( pTextNode, 0 );
+ }
+ else if ( !pCFrame->isFrameAreaDefinitionValid() )
+ {
+ assert(pCFrame->IsTextFrame());
+ rPos = static_cast<SwTextFrame const*>(pCFrame)->MapViewToModelPos(TextFrameIndex(0));
+ }
+ else
+ {
+ pCFrame->GetModelPositionForViewPoint( &rPos, rPt );
+ pTextNode = rPos.nNode.GetNode().GetTextNode();
+ }
+ return pTextNode;
+}
+
+const SwTextNode* GetBodyTextNode( const SwDoc& rDoc, SwPosition& rPos,
+ const SwFrame& rFrame )
+{
+ const SwLayoutFrame* pLayout = rFrame.GetUpper();
+ const SwTextNode* pTextNode = nullptr;
+
+ while( pLayout )
+ {
+ if( pLayout->IsFlyFrame() )
+ {
+ // get the FlyFormat
+ const SwFrameFormat* pFlyFormat = static_cast<const SwFlyFrame*>(pLayout)->GetFormat();
+ OSL_ENSURE( pFlyFormat, "Could not find FlyFormat, where is the field?" );
+
+ const SwFormatAnchor &rAnchor = pFlyFormat->GetAnchor();
+
+ if( RndStdIds::FLY_AT_FLY == rAnchor.GetAnchorId() )
+ {
+ // the fly needs to be attached somewhere, so ask it
+ pLayout = static_cast<const SwLayoutFrame*>(static_cast<const SwFlyFrame*>(pLayout)->GetAnchorFrame());
+ continue;
+ }
+ else if ((RndStdIds::FLY_AT_PARA == rAnchor.GetAnchorId()) ||
+ (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()) ||
+ (RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId()))
+ {
+ OSL_ENSURE( rAnchor.GetContentAnchor(), "no valid position" );
+ rPos = *rAnchor.GetContentAnchor();
+ pTextNode = rPos.nNode.GetNode().GetTextNode();
+ if ( RndStdIds::FLY_AT_PARA == rAnchor.GetAnchorId() )
+ {
+ const_cast<SwTextNode*>(pTextNode)->MakeStartIndex(
+ &rPos.nContent );
+ }
+
+ // do not break yet, might be as well in Header/Footer/Footnote/Fly
+ pLayout = static_cast<const SwFlyFrame*>(pLayout)->GetAnchorFrame()
+ ? static_cast<const SwFlyFrame*>(pLayout)->GetAnchorFrame()->GetUpper() : nullptr;
+ continue;
+ }
+ else
+ {
+ pLayout->FindPageFrame()->GetContentPosition(
+ pLayout->getFrameArea().Pos(), rPos );
+ pTextNode = rPos.nNode.GetNode().GetTextNode();
+ }
+ }
+ else if( pLayout->IsFootnoteFrame() )
+ {
+ // get the anchor's node
+ const SwTextFootnote* pFootnote = static_cast<const SwFootnoteFrame*>(pLayout)->GetAttr();
+ pTextNode = &pFootnote->GetTextNode();
+ rPos.nNode = *pTextNode;
+ rPos.nContent = pFootnote->GetStart();
+ }
+ else if( pLayout->IsHeaderFrame() || pLayout->IsFooterFrame() )
+ {
+ const SwContentFrame* pContentFrame;
+ const SwPageFrame* pPgFrame = pLayout->FindPageFrame();
+ if( pLayout->IsHeaderFrame() )
+ {
+ const SwTabFrame *pTab;
+ if( nullptr != ( pContentFrame = pPgFrame->FindFirstBodyContent()) &&
+ nullptr != (pTab = pContentFrame->FindTabFrame()) && pTab->IsFollow() &&
+ pTab->GetTable()->GetRowsToRepeat() > 0 &&
+ pTab->IsInHeadline( *pContentFrame ) )
+ {
+ // take the next line
+ const SwLayoutFrame* pRow = pTab->GetFirstNonHeadlineRow();
+ pContentFrame = pRow->ContainsContent();
+ }
+ }
+ else
+ pContentFrame = pPgFrame->FindLastBodyContent();
+
+ if( pContentFrame )
+ {
+ assert(pContentFrame->IsTextFrame());
+ SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(pContentFrame));
+ rPos = pFrame->MapViewToModelPos(TextFrameIndex(pFrame->GetText().getLength()));
+ pTextNode = rPos.nNode.GetNode().GetTextNode();
+ assert(pTextNode);
+ }
+ else
+ {
+ Point aPt( pLayout->getFrameArea().Pos() );
+ aPt.AdjustY( 1 ); // get out of the header
+ pContentFrame = pPgFrame->GetContentPos( aPt, false, true );
+ pTextNode = GetFirstTextNode( rDoc, rPos, pContentFrame, aPt );
+ }
+ }
+ else
+ {
+ pLayout = pLayout->GetUpper();
+ continue;
+ }
+ break; // found, so finish loop
+ }
+ return pTextNode;
+}
+
+SwGetExpFieldType::SwGetExpFieldType(SwDoc* pDc)
+ : SwValueFieldType( pDc, SwFieldIds::GetExp )
+{
+}
+
+std::unique_ptr<SwFieldType> SwGetExpFieldType::Copy() const
+{
+ return std::make_unique<SwGetExpFieldType>(GetDoc());
+}
+
+void SwGetExpFieldType::SwClientNotify(const SwModify&, const SfxHint& rHint)
+{
+ if (rHint.GetId() != SfxHintId::SwLegacyModify)
+ return;
+ auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+ // do not expand anything else
+ if(pLegacy->GetWhich() != RES_DOCPOS_UPDATE)
+ return;
+ CallSwClientNotify(rHint);
+}
+
+SwGetExpField::SwGetExpField(SwGetExpFieldType* pTyp, const OUString& rFormel,
+ sal_uInt16 nSub, sal_uLong nFormat)
+ : SwFormulaField( pTyp, nFormat, 0.0 )
+ , m_fValueRLHidden(0.0)
+ ,
+ m_bIsInBodyText( true ),
+ m_nSubType(nSub),
+ m_bLateInitialization( false )
+{
+ SetFormula( rFormel );
+}
+
+void SwGetExpField::ChgExpStr(const OUString& rExpand, SwRootFrame const*const pLayout)
+{
+ if (!pLayout || pLayout->IsHideRedlines())
+ {
+ m_sExpandRLHidden = rExpand;
+ }
+ if (!pLayout || !pLayout->IsHideRedlines())
+ {
+ m_sExpand = rExpand;
+ }
+}
+
+OUString SwGetExpField::ExpandImpl(SwRootFrame const*const pLayout) const
+{
+ if(m_nSubType & nsSwExtendedSubType::SUB_CMD)
+ return GetFormula();
+
+ return (pLayout && pLayout->IsHideRedlines()) ? m_sExpandRLHidden : m_sExpand;
+}
+
+OUString SwGetExpField::GetFieldName() const
+{
+ const SwFieldTypesEnum nType =
+ (nsSwGetSetExpType::GSE_FORMULA & m_nSubType)
+ ? SwFieldTypesEnum::Formel
+ : SwFieldTypesEnum::Get;
+
+ return SwFieldType::GetTypeStr(nType) + " " + GetFormula();
+}
+
+std::unique_ptr<SwField> SwGetExpField::Copy() const
+{
+ std::unique_ptr<SwGetExpField> pTmp(new SwGetExpField(static_cast<SwGetExpFieldType*>(GetTyp()),
+ GetFormula(), m_nSubType, GetFormat()));
+ pTmp->SetLanguage(GetLanguage());
+ pTmp->m_fValueRLHidden = m_fValueRLHidden;
+ pTmp->SwValueField::SetValue(GetValue());
+ pTmp->m_sExpand = m_sExpand;
+ pTmp->m_sExpandRLHidden = m_sExpandRLHidden;
+ pTmp->m_bIsInBodyText = m_bIsInBodyText;
+ pTmp->SetAutomaticLanguage(IsAutomaticLanguage());
+ if( m_bLateInitialization )
+ pTmp->SetLateInitialization();
+
+ return std::unique_ptr<SwField>(pTmp.release());
+}
+
+void SwGetExpField::ChangeExpansion( const SwFrame& rFrame, const SwTextField& rField )
+{
+ if( m_bIsInBodyText ) // only fields in Footer, Header, FootNote, Flys
+ return;
+
+ OSL_ENSURE( !rFrame.IsInDocBody(), "Flag incorrect, frame is in DocBody" );
+
+ // determine document (or is there an easier way?)
+ const SwTextNode* pTextNode = &rField.GetTextNode();
+ SwDoc& rDoc = const_cast<SwDoc&>(pTextNode->GetDoc());
+
+ // create index for determination of the TextNode
+ SwPosition aPos( SwNodeIndex( rDoc.GetNodes() ) );
+ pTextNode = GetBodyTextNode( rDoc, aPos, rFrame );
+
+ // If no layout exists, ChangeExpansion is called for header and
+ // footer lines via layout formatting without existing TextNode.
+ if(!pTextNode)
+ return;
+ // #i82544#
+ if( m_bLateInitialization )
+ {
+ SwFieldType* pSetExpField = rDoc.getIDocumentFieldsAccess().GetFieldType(SwFieldIds::SetExp, GetFormula(), false);
+ if( pSetExpField )
+ {
+ m_bLateInitialization = false;
+ if( !(GetSubType() & nsSwGetSetExpType::GSE_STRING) &&
+ static_cast< SwSetExpFieldType* >(pSetExpField)->GetType() == nsSwGetSetExpType::GSE_STRING )
+ SetSubType( nsSwGetSetExpType::GSE_STRING );
+ }
+ }
+
+ SwRootFrame const& rLayout(*rFrame.getRootFrame());
+ OUString & rExpand(rLayout.IsHideRedlines() ? m_sExpandRLHidden : m_sExpand);
+ // here a page number is needed to sort correctly
+ SetGetExpField aEndField(aPos.nNode, &rField, &aPos.nContent, rFrame.GetPhyPageNum());
+ if(GetSubType() & nsSwGetSetExpType::GSE_STRING)
+ {
+ SwHashTable<HashStr> aHashTable(0);
+ rDoc.getIDocumentFieldsAccess().FieldsToExpand(aHashTable, aEndField, rLayout);
+ rExpand = LookString( aHashTable, GetFormula() );
+ }
+ else
+ {
+ // fill calculator with values
+ SwCalc aCalc( rDoc );
+ rDoc.getIDocumentFieldsAccess().FieldsToCalc(aCalc, aEndField, &rLayout);
+
+ // calculate value
+ SetValue(aCalc.Calculate(GetFormula()).GetDouble(), &rLayout);
+
+ // analyse based on format
+ rExpand = static_cast<SwValueFieldType*>(GetTyp())->ExpandValue(
+ GetValue(&rLayout), GetFormat(), GetLanguage());
+ }
+}
+
+OUString SwGetExpField::GetPar2() const
+{
+ return GetFormula();
+}
+
+void SwGetExpField::SetPar2(const OUString& rStr)
+{
+ SetFormula(rStr);
+}
+
+sal_uInt16 SwGetExpField::GetSubType() const
+{
+ return m_nSubType;
+}
+
+void SwGetExpField::SetSubType(sal_uInt16 nType)
+{
+ m_nSubType = nType;
+}
+
+void SwGetExpField::SetLanguage(LanguageType nLng)
+{
+ if (m_nSubType & nsSwExtendedSubType::SUB_CMD)
+ SwField::SetLanguage(nLng);
+ else
+ SwValueField::SetLanguage(nLng);
+}
+
+bool SwGetExpField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
+{
+ switch( nWhichId )
+ {
+ case FIELD_PROP_DOUBLE:
+ rAny <<= GetValue();
+ break;
+ case FIELD_PROP_FORMAT:
+ rAny <<= static_cast<sal_Int32>(GetFormat());
+ break;
+ case FIELD_PROP_USHORT1:
+ rAny <<= static_cast<sal_Int16>(m_nSubType);
+ break;
+ case FIELD_PROP_PAR1:
+ rAny <<= GetFormula();
+ break;
+ case FIELD_PROP_SUBTYPE:
+ {
+ sal_Int16 nRet = lcl_SubTypeToAPI(GetSubType() & 0xff);
+ rAny <<= nRet;
+ }
+ break;
+ case FIELD_PROP_BOOL2:
+ rAny <<= 0 != (m_nSubType & nsSwExtendedSubType::SUB_CMD);
+ break;
+ case FIELD_PROP_PAR4:
+ rAny <<= m_sExpand;
+ break;
+ default:
+ return SwField::QueryValue(rAny, nWhichId);
+ }
+ return true;
+}
+
+bool SwGetExpField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
+{
+ sal_Int32 nTmp = 0;
+ switch( nWhichId )
+ {
+ case FIELD_PROP_DOUBLE:
+ SwValueField::SetValue(*o3tl::doAccess<double>(rAny));
+ m_fValueRLHidden = *o3tl::doAccess<double>(rAny);
+ break;
+ case FIELD_PROP_FORMAT:
+ rAny >>= nTmp;
+ SetFormat(nTmp);
+ break;
+ case FIELD_PROP_USHORT1:
+ rAny >>= nTmp;
+ m_nSubType = o3tl::narrowing<sal_uInt16>(nTmp);
+ break;
+ case FIELD_PROP_PAR1:
+ {
+ OUString sTmp;
+ rAny >>= sTmp;
+ SetFormula(sTmp);
+ break;
+ }
+ case FIELD_PROP_SUBTYPE:
+ nTmp = lcl_APIToSubType(rAny);
+ if( nTmp >=0 )
+ SetSubType( o3tl::narrowing<sal_uInt16>((GetSubType() & 0xff00) | nTmp));
+ break;
+ case FIELD_PROP_BOOL2:
+ if(*o3tl::doAccess<bool>(rAny))
+ m_nSubType |= nsSwExtendedSubType::SUB_CMD;
+ else
+ m_nSubType &= (~nsSwExtendedSubType::SUB_CMD);
+ break;
+ case FIELD_PROP_PAR4:
+ {
+ OUString sTmp;
+ rAny >>= sTmp;
+ ChgExpStr(sTmp, nullptr);
+ break;
+ }
+ default:
+ return SwField::PutValue(rAny, nWhichId);
+ }
+ return true;
+}
+
+SwSetExpFieldType::SwSetExpFieldType( SwDoc* pDc, const OUString& rName, sal_uInt16 nTyp )
+ : SwValueFieldType( pDc, SwFieldIds::SetExp ),
+ m_sName( rName ),
+ m_sDelim( "." ),
+ m_nType(nTyp), m_nLevel( UCHAR_MAX ),
+ m_bDeleted( false )
+{
+ if( ( nsSwGetSetExpType::GSE_SEQ | nsSwGetSetExpType::GSE_STRING ) & m_nType )
+ EnableFormat(false); // do not use Numberformatter
+}
+
+std::unique_ptr<SwFieldType> SwSetExpFieldType::Copy() const
+{
+ std::unique_ptr<SwSetExpFieldType> pNew(new SwSetExpFieldType(GetDoc(), m_sName, m_nType));
+ pNew->m_bDeleted = m_bDeleted;
+ pNew->m_sDelim = m_sDelim;
+ pNew->m_nLevel = m_nLevel;
+
+ return pNew;
+}
+
+OUString SwSetExpFieldType::GetName() const
+{
+ return m_sName;
+}
+
+const OUString& SwSetExpField::GetExpStr(SwRootFrame const*const pLayout) const
+{
+ return (pLayout && pLayout->IsHideRedlines()) ? msExpandRLHidden : msExpand;
+}
+
+void SwSetExpField::ChgExpStr(const OUString& rExpand, SwRootFrame const*const pLayout)
+{
+ if (!pLayout || pLayout->IsHideRedlines())
+ {
+ msExpandRLHidden = rExpand;
+ }
+ if (!pLayout || !pLayout->IsHideRedlines())
+ {
+ msExpand = rExpand;
+ }
+}
+
+void SwSetExpFieldType::SwClientNotify(const SwModify&, const SfxHint&)
+{
+ // do not expand further
+}
+
+void SwSetExpFieldType::SetSeqFormat(sal_uLong nFormat)
+{
+ std::vector<SwFormatField*> vFields;
+ GatherFields(vFields, false);
+ for(auto pFormatField: vFields)
+ pFormatField->GetField()->ChangeFormat(nFormat);
+}
+
+sal_uLong SwSetExpFieldType::GetSeqFormat() const
+{
+ if( !HasWriterListeners() )
+ return SVX_NUM_ARABIC;
+
+ std::vector<SwFormatField*> vFields;
+ GatherFields(vFields, false);
+ return vFields.front()->GetField()->GetFormat();
+}
+
+void SwSetExpFieldType::SetSeqRefNo( SwSetExpField& rField )
+{
+ if( !HasWriterListeners() || !(nsSwGetSetExpType::GSE_SEQ & m_nType) )
+ return;
+
+ std::vector<sal_uInt16> aArr;
+
+ // check if number is already used and if a new one needs to be created
+ std::vector<SwFormatField*> vFields;
+ GatherFields(vFields);
+ for(SwFormatField* pF: vFields)
+ if(pF->GetField() != &rField)
+ InsertSort(aArr, static_cast<SwSetExpField*>(pF->GetField())->GetSeqNumber());
+
+ // check first if number already exists
+ sal_uInt16 nNum = rField.GetSeqNumber();
+ if( USHRT_MAX != nNum )
+ {
+ std::vector<sal_uInt16>::size_type n {0};
+
+ for( n = 0; n < aArr.size(); ++n )
+ if( aArr[ n ] >= nNum )
+ break;
+
+ if( n == aArr.size() || aArr[ n ] > nNum )
+ return; // no -> use it
+ }
+
+ // flagged all numbers, so determine the right number
+ std::vector<sal_uInt16>::size_type n = aArr.size();
+ OSL_ENSURE( n <= std::numeric_limits<sal_uInt16>::max(), "Array is too big for using a sal_uInt16 index" );
+
+ if ( n > 0 && aArr[ n-1 ] != n-1 )
+ {
+ for( n = 0; n < aArr.size(); ++n )
+ if( n != aArr[ n ] )
+ break;
+ }
+
+ rField.SetSeqNumber( n );
+}
+
+size_t SwSetExpFieldType::GetSeqFieldList(SwSeqFieldList& rList,
+ SwRootFrame const*const pLayout)
+{
+ rList.Clear();
+
+ IDocumentRedlineAccess const& rIDRA(GetDoc()->getIDocumentRedlineAccess());
+
+ std::vector<SwFormatField*> vFields;
+ GatherFields(vFields);
+ for(SwFormatField* pF: vFields)
+ {
+ const SwTextNode* pNd;
+ if( nullptr != ( pNd = pF->GetTextField()->GetpTextNode() )
+ && (!pLayout || !pLayout->IsHideRedlines()
+ || !sw::IsFieldDeletedInModel(rIDRA, *pF->GetTextField())))
+ {
+ SeqFieldLstElem aNew(
+ pNd->GetExpandText(pLayout),
+ static_cast<SwSetExpField*>(pF->GetField())->GetSeqNumber() );
+ rList.InsertSort( aNew );
+ }
+ }
+ return rList.Count();
+}
+
+void SwSetExpFieldType::SetChapter(SwSetExpField& rField, const SwNode& rNd,
+ SwRootFrame const*const pLayout)
+{
+ const SwTextNode* pTextNd = rNd.FindOutlineNodeOfLevel(m_nLevel, pLayout);
+ if( !pTextNd )
+ return;
+
+ SwNumRule * pRule = pTextNd->GetNumRule();
+
+ if (!pRule)
+ return;
+
+ // --> OD 2005-11-02 #i51089 - TUNING#
+ if (SwNodeNum const*const pNum = pTextNd->GetNum(pLayout))
+ {
+ // only get the number, without pre-/post-fixstrings
+ OUString const sNumber(pRule->MakeNumString(*pNum, false));
+
+ if( !sNumber.isEmpty() )
+ rField.ChgExpStr(sNumber + m_sDelim + rField.GetExpStr(pLayout), pLayout);
+ }
+ else
+ {
+ OSL_ENSURE(pTextNd->GetNum(nullptr), "<SwSetExpFieldType::SetChapter(..)> - text node with numbering rule, but without number. This is a serious defect");
+ }
+}
+
+void SwSetExpFieldType::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
+{
+ switch( nWhichId )
+ {
+ case FIELD_PROP_SUBTYPE:
+ {
+ sal_Int16 nRet = lcl_SubTypeToAPI(GetType());
+ rAny <<= nRet;
+ }
+ break;
+ case FIELD_PROP_PAR2:
+ rAny <<= GetDelimiter();
+ break;
+ case FIELD_PROP_SHORT1:
+ {
+ sal_Int8 nRet = m_nLevel < MAXLEVEL? m_nLevel : -1;
+ rAny <<= nRet;
+ }
+ break;
+ default:
+ assert(false);
+ }
+}
+
+void SwSetExpFieldType::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
+{
+ switch( nWhichId )
+ {
+ case FIELD_PROP_SUBTYPE:
+ {
+ sal_Int32 nSet = lcl_APIToSubType(rAny);
+ if(nSet >=0)
+ SetType(o3tl::narrowing<sal_uInt16>(nSet));
+ }
+ break;
+ case FIELD_PROP_PAR2:
+ {
+ OUString sTmp;
+ rAny >>= sTmp;
+ if( !sTmp.isEmpty() )
+ SetDelimiter( sTmp );
+ else
+ SetDelimiter( " " );
+ }
+ break;
+ case FIELD_PROP_SHORT1:
+ {
+ sal_Int8 nLvl = 0;
+ rAny >>= nLvl;
+ if(nLvl < 0 || nLvl >= MAXLEVEL)
+ SetOutlineLvl(UCHAR_MAX);
+ else
+ SetOutlineLvl(nLvl);
+ }
+ break;
+ default:
+ assert(false);
+ }
+}
+
+bool SwSeqFieldList::InsertSort( SeqFieldLstElem aNew )
+{
+ OUStringBuffer aBuf(aNew.sDlgEntry);
+ const sal_Int32 nLen = aBuf.getLength();
+ for (sal_Int32 i = 0; i < nLen; ++i)
+ {
+ if (aBuf[i]<' ')
+ {
+ aBuf[i]=' ';
+ }
+ }
+ aNew.sDlgEntry = aBuf.makeStringAndClear();
+
+ size_t nPos = 0;
+ bool bRet = SeekEntry( aNew, &nPos );
+ if( !bRet )
+ maData.insert( maData.begin() + nPos, aNew );
+ return bRet;
+}
+
+bool SwSeqFieldList::SeekEntry( const SeqFieldLstElem& rNew, size_t* pP ) const
+{
+ size_t nO = maData.size();
+ size_t nU = 0;
+ if( nO > 0 )
+ {
+ CollatorWrapper & rCaseColl = ::GetAppCaseCollator(),
+ & rColl = ::GetAppCollator();
+ const CharClass& rCC = GetAppCharClass();
+
+ //#59900# Sorting should sort number correctly (e.g. "10" after "9" not after "1")
+ const OUString rTmp2 = rNew.sDlgEntry;
+ sal_Int32 nFndPos2 = 0;
+ const OUString sNum2( rTmp2.getToken( 0, ' ', nFndPos2 ));
+ bool bIsNum2IsNumeric = CharClass::isAsciiNumeric( sNum2 );
+ sal_Int32 nNum2 = bIsNum2IsNumeric ? sNum2.toInt32() : 0;
+
+ nO--;
+ while( nU <= nO )
+ {
+ const size_t nM = nU + ( nO - nU ) / 2;
+
+ //#59900# Sorting should sort number correctly (e.g. "10" after "9" not after "1")
+ const OUString rTmp1 = maData[nM].sDlgEntry;
+ sal_Int32 nFndPos1 = 0;
+ const OUString sNum1( rTmp1.getToken( 0, ' ', nFndPos1 ));
+ sal_Int32 nCmp;
+
+ if( bIsNum2IsNumeric && rCC.isNumeric( sNum1 ) )
+ {
+ sal_Int32 nNum1 = sNum1.toInt32();
+ nCmp = nNum2 - nNum1;
+ if( 0 == nCmp )
+ {
+ OUString aTmp1 = nFndPos1 != -1 ? rTmp1.copy(nFndPos1) : OUString();
+ OUString aTmp2 = nFndPos2 != -1 ? rTmp2.copy(nFndPos2) : OUString();
+ nCmp = rCaseColl.compareString(aTmp2, aTmp1);
+ }
+ }
+ else
+ nCmp = rColl.compareString( rTmp2, rTmp1 );
+
+ if( 0 == nCmp )
+ {
+ if( pP ) *pP = nM;
+ return true;
+ }
+ else if( 0 < nCmp )
+ nU = nM + 1;
+ else if( nM == 0 )
+ break;
+ else
+ nO = nM - 1;
+ }
+ }
+ if( pP ) *pP = nU;
+ return false;
+}
+
+SwSetExpField::SwSetExpField(SwSetExpFieldType* pTyp, const OUString& rFormel,
+ sal_uLong nFormat)
+ : SwFormulaField( pTyp, nFormat, 0.0 )
+ , m_fValueRLHidden(0.0)
+ , mnSeqNo( USHRT_MAX )
+ , mnSubType(0)
+ , mpFormatField(nullptr)
+{
+ SetFormula(rFormel);
+ // ignore SubType
+ mbInput = false;
+ if( IsSequenceField() )
+ {
+ SwValueField::SetValue(1.0);
+ m_fValueRLHidden = 1.0;
+ if( rFormel.isEmpty() )
+ {
+ SetFormula(pTyp->GetName() + "+1");
+ }
+ }
+}
+
+void SwSetExpField::SetFormatField(SwFormatField & rFormatField)
+{
+ mpFormatField = &rFormatField;
+}
+
+OUString SwSetExpField::ExpandImpl(SwRootFrame const*const pLayout) const
+{
+ if (mnSubType & nsSwExtendedSubType::SUB_CMD)
+ { // we need the CommandString
+ return GetTyp()->GetName() + " = " + GetFormula();
+ }
+ if(!(mnSubType & nsSwExtendedSubType::SUB_INVISIBLE))
+ { // value is visible
+ return (pLayout && pLayout->IsHideRedlines()) ? msExpandRLHidden : msExpand;
+ }
+ return OUString();
+}
+
+/// @return the field name
+OUString SwSetExpField::GetFieldName() const
+{
+ SwFieldTypesEnum const nStrType( (IsSequenceField())
+ ? SwFieldTypesEnum::Sequence
+ : mbInput
+ ? SwFieldTypesEnum::SetInput
+ : SwFieldTypesEnum::Set );
+
+ OUString aStr(
+ SwFieldType::GetTypeStr( nStrType )
+ + " "
+ + GetTyp()->GetName() );
+
+ // Sequence: without formula
+ if (SwFieldTypesEnum::Sequence != nStrType)
+ {
+ aStr += " = " + GetFormula();
+ }
+ return aStr;
+}
+
+std::unique_ptr<SwField> SwSetExpField::Copy() const
+{
+ std::unique_ptr<SwSetExpField> pTmp(new SwSetExpField(static_cast<SwSetExpFieldType*>(GetTyp()),
+ GetFormula(), GetFormat()));
+ pTmp->SwValueField::SetValue(GetValue());
+ pTmp->m_fValueRLHidden = m_fValueRLHidden;
+ pTmp->msExpand = msExpand;
+ pTmp->msExpandRLHidden = msExpandRLHidden;
+ pTmp->SetAutomaticLanguage(IsAutomaticLanguage());
+ pTmp->SetLanguage(GetLanguage());
+ pTmp->maPText = maPText;
+ pTmp->mbInput = mbInput;
+ pTmp->mnSeqNo = mnSeqNo;
+ pTmp->SetSubType(GetSubType());
+
+ return std::unique_ptr<SwField>(pTmp.release());
+}
+
+void SwSetExpField::SetSubType(sal_uInt16 nSub)
+{
+ static_cast<SwSetExpFieldType*>(GetTyp())->SetType(nSub & 0xff);
+ mnSubType = nSub & 0xff00;
+
+ OSL_ENSURE( (nSub & 0xff) != 3, "SubType is illegal!" );
+}
+
+sal_uInt16 SwSetExpField::GetSubType() const
+{
+ return static_cast<SwSetExpFieldType*>(GetTyp())->GetType() | mnSubType;
+}
+
+void SwSetExpField::SetValue( const double& rAny )
+{
+ SwValueField::SetValue(rAny);
+
+ if( IsSequenceField() )
+ msExpand = FormatNumber( GetValue(), static_cast<SvxNumType>(GetFormat()), GetLanguage() );
+ else
+ msExpand = static_cast<SwValueFieldType*>(GetTyp())->ExpandValue( rAny,
+ GetFormat(), GetLanguage());
+}
+
+void SwSetExpField::SetValue(const double& rValue, SwRootFrame const*const pLayout)
+{
+ if (!pLayout || !pLayout->IsHideRedlines())
+ {
+ SetValue(rValue);
+ }
+ if (pLayout && !pLayout->IsHideRedlines())
+ return;
+
+ m_fValueRLHidden = rValue;
+ if (IsSequenceField())
+ {
+ msExpandRLHidden = FormatNumber(rValue, static_cast<SvxNumType>(GetFormat()), GetLanguage());
+ }
+ else
+ {
+ msExpandRLHidden = static_cast<SwValueFieldType*>(GetTyp())->ExpandValue(
+ rValue, GetFormat(), GetLanguage());
+ }
+}
+
+double SwSetExpField::GetValue(SwRootFrame const* pLayout) const
+{
+ return (pLayout && pLayout->IsHideRedlines()) ? m_fValueRLHidden : GetValue();
+}
+
+void SwGetExpField::SetValue( const double& rAny )
+{
+ SwValueField::SetValue(rAny);
+ m_sExpand = static_cast<SwValueFieldType*>(GetTyp())->ExpandValue( rAny, GetFormat(),
+ GetLanguage());
+}
+
+void SwGetExpField::SetValue(const double& rValue, SwRootFrame const*const pLayout)
+{
+ if (!pLayout || !pLayout->IsHideRedlines())
+ {
+ SetValue(rValue);
+ }
+ if (!pLayout || pLayout->IsHideRedlines())
+ {
+ m_fValueRLHidden = rValue;
+ m_sExpandRLHidden = static_cast<SwValueFieldType*>(GetTyp())->ExpandValue(
+ rValue, GetFormat(), GetLanguage());
+ }
+}
+
+double SwGetExpField::GetValue(SwRootFrame const* pLayout) const
+{
+ return (pLayout && pLayout->IsHideRedlines()) ? m_fValueRLHidden : GetValue();
+}
+
+/** Find the index of the reference text following the current field
+ *
+ * @param rFormat
+ * @param rDoc
+ * @param nHint search starting position after the current field (or 0 if default)
+ * @return
+ */
+sal_Int32 SwGetExpField::GetReferenceTextPos( const SwFormatField& rFormat, SwDoc& rDoc, sal_Int32 nHint)
+{
+
+ const SwTextField* pTextField = rFormat.GetTextField();
+ const SwTextNode& rTextNode = pTextField->GetTextNode();
+
+ sal_Int32 nRet = nHint ? nHint : pTextField->GetStart() + 1;
+ OUString sNodeText = rTextNode.GetText();
+
+ if(nRet<sNodeText.getLength())
+ {
+ sNodeText = sNodeText.copy(nRet);
+
+ // now check if sNodeText starts with a non-alphanumeric character plus blanks
+ sal_uInt16 nSrcpt = g_pBreakIt->GetRealScriptOfText( sNodeText, 0 );
+
+ static const WhichRangesContainer nIds(svl::Items<
+ RES_CHRATR_FONT, RES_CHRATR_FONT,
+ RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE,
+ RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT,
+ RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE,
+ RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONT,
+ RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE
+ >);
+ SwAttrSet aSet(rDoc.GetAttrPool(), nIds);
+ rTextNode.GetParaAttr(aSet, nRet, nRet+1);
+
+ TypedWhichId<SvxFontItem> nFontWhich = GetWhichOfScript( RES_CHRATR_FONT, nSrcpt );
+ if( RTL_TEXTENCODING_SYMBOL != aSet.Get( nFontWhich ).GetCharSet() )
+ {
+ TypedWhichId<SvxLanguageItem> nLangWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, nSrcpt ) ;
+ LanguageType eLang = aSet.Get(nLangWhich).GetLanguage();
+ CharClass aCC(( LanguageTag(eLang) ));
+ sal_Unicode c0 = sNodeText[0];
+ bool bIsAlphaNum = aCC.isAlphaNumeric( sNodeText, 0 );
+ if( !bIsAlphaNum ||
+ (c0 == ' ' || c0 == '\t'))
+ {
+ // ignoring blanks
+ nRet++;
+ const sal_Int32 nLen = sNodeText.getLength();
+ for (sal_Int32 i = 1;
+ i<nLen && (sNodeText[i]==' ' || sNodeText[i]=='\t');
+ ++i
+ )
+ ++nRet;
+ }
+ }
+ }
+ return nRet;
+}
+
+OUString SwSetExpField::GetPar1() const
+{
+ return static_cast<const SwSetExpFieldType*>(GetTyp())->GetName();
+}
+
+OUString SwSetExpField::GetPar2() const
+{
+ sal_uInt16 nType = static_cast<SwSetExpFieldType*>(GetTyp())->GetType();
+
+ if (nType & nsSwGetSetExpType::GSE_STRING)
+ return GetFormula();
+ return GetExpandedFormula();
+}
+
+void SwSetExpField::SetPar2(const OUString& rStr)
+{
+ sal_uInt16 nType = static_cast<SwSetExpFieldType*>(GetTyp())->GetType();
+
+ if( !(nType & nsSwGetSetExpType::GSE_SEQ) || !rStr.isEmpty() )
+ {
+ if (nType & nsSwGetSetExpType::GSE_STRING)
+ SetFormula(rStr);
+ else
+ SetExpandedFormula(rStr);
+ }
+}
+
+bool SwSetExpField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
+{
+ sal_Int32 nTmp32 = 0;
+ sal_Int16 nTmp16 = 0;
+ switch( nWhichId )
+ {
+ case FIELD_PROP_BOOL2:
+ if(*o3tl::doAccess<bool>(rAny))
+ mnSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
+ else
+ mnSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
+ break;
+ case FIELD_PROP_FORMAT:
+ rAny >>= nTmp32;
+ SetFormat(nTmp32);
+ break;
+ case FIELD_PROP_USHORT2:
+ {
+ rAny >>= nTmp16;
+ if(nTmp16 <= css::style::NumberingType::NUMBER_NONE )
+ SetFormat(nTmp16);
+ else {
+ //exception(wrong_value)
+ ;
+ }
+ }
+ break;
+ case FIELD_PROP_USHORT1:
+ rAny >>= nTmp16;
+ mnSeqNo = nTmp16;
+ break;
+ case FIELD_PROP_PAR1:
+ {
+ OUString sTmp;
+ rAny >>= sTmp;
+ SetPar1( SwStyleNameMapper::GetUIName( sTmp, SwGetPoolIdFromName::TxtColl ) );
+ }
+ break;
+ case FIELD_PROP_PAR2:
+ {
+ OUString uTmp;
+ rAny >>= uTmp;
+ //I18N - if the formula contains only "TypeName+1"
+ //and it's one of the initially created sequence fields
+ //then the localized names has to be replaced by a programmatic name
+ OUString sMyFormula = SwXFieldMaster::LocalizeFormula(*this, uTmp, false);
+ SetFormula( sMyFormula );
+ }
+ break;
+ case FIELD_PROP_DOUBLE:
+ {
+ double fVal = 0.0;
+ rAny >>= fVal;
+ SetValue(fVal);
+ m_fValueRLHidden = fVal;
+ }
+ break;
+ case FIELD_PROP_SUBTYPE:
+ nTmp32 = lcl_APIToSubType(rAny);
+ if(nTmp32 >= 0)
+ SetSubType(o3tl::narrowing<sal_uInt16>((GetSubType() & 0xff00) | nTmp32));
+ break;
+ case FIELD_PROP_PAR3:
+ rAny >>= maPText;
+ break;
+ case FIELD_PROP_BOOL3:
+ if(*o3tl::doAccess<bool>(rAny))
+ mnSubType |= nsSwExtendedSubType::SUB_CMD;
+ else
+ mnSubType &= (~nsSwExtendedSubType::SUB_CMD);
+ break;
+ case FIELD_PROP_BOOL1:
+ {
+ bool newInput(*o3tl::doAccess<bool>(rAny));
+ if (newInput != GetInputFlag())
+ {
+ if (static_cast<SwSetExpFieldType*>(GetTyp())->GetType()
+ & nsSwGetSetExpType::GSE_STRING)
+ {
+ SwXTextField::TransmuteLeadToInputField(*this);
+ }
+ else
+ {
+ SetInputFlag(newInput);
+ }
+ }
+ }
+ break;
+ case FIELD_PROP_PAR4:
+ {
+ OUString sTmp;
+ rAny >>= sTmp;
+ ChgExpStr(sTmp, nullptr);
+ }
+ break;
+ default:
+ return SwField::PutValue(rAny, nWhichId);
+ }
+ return true;
+}
+
+bool SwSetExpField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
+{
+ switch( nWhichId )
+ {
+ case FIELD_PROP_BOOL2:
+ rAny <<= 0 == (mnSubType & nsSwExtendedSubType::SUB_INVISIBLE);
+ break;
+ case FIELD_PROP_FORMAT:
+ rAny <<= static_cast<sal_Int32>(GetFormat());
+ break;
+ case FIELD_PROP_USHORT2:
+ rAny <<= static_cast<sal_Int16>(GetFormat());
+ break;
+ case FIELD_PROP_USHORT1:
+ rAny <<= static_cast<sal_Int16>(mnSeqNo);
+ break;
+ case FIELD_PROP_PAR1:
+ rAny <<= SwStyleNameMapper::GetProgName(GetPar1(), SwGetPoolIdFromName::TxtColl );
+ break;
+ case FIELD_PROP_PAR2:
+ {
+ //I18N - if the formula contains only "TypeName+1"
+ //and it's one of the initially created sequence fields
+ //then the localized names has to be replaced by a programmatic name
+ OUString sMyFormula = SwXFieldMaster::LocalizeFormula(*this, GetFormula(), true);
+ rAny <<= sMyFormula;
+ }
+ break;
+ case FIELD_PROP_DOUBLE:
+ rAny <<= GetValue();
+ break;
+ case FIELD_PROP_SUBTYPE:
+ {
+ sal_Int16 nRet = lcl_SubTypeToAPI(GetSubType() & 0xff);
+ rAny <<= nRet;
+ }
+ break;
+ case FIELD_PROP_PAR3:
+ rAny <<= maPText;
+ break;
+ case FIELD_PROP_BOOL3:
+ rAny <<= 0 != (mnSubType & nsSwExtendedSubType::SUB_CMD);
+ break;
+ case FIELD_PROP_BOOL1:
+ rAny <<= GetInputFlag();
+ break;
+ case FIELD_PROP_PAR4:
+ rAny <<= GetExpStr(nullptr);
+ break;
+ default:
+ return SwField::QueryValue(rAny, nWhichId);
+ }
+ return true;
+}
+
+SwInputFieldType::SwInputFieldType( SwDoc* pD )
+ : SwFieldType( SwFieldIds::Input )
+ , mpDoc( pD )
+{
+}
+
+std::unique_ptr<SwFieldType> SwInputFieldType::Copy() const
+{
+ return std::make_unique<SwInputFieldType>( mpDoc );
+}
+
+SwInputField::SwInputField( SwInputFieldType* pFieldType,
+ const OUString& rContent,
+ const OUString& rPrompt,
+ sal_uInt16 nSub,
+ sal_uLong nFormat,
+ bool bIsFormField )
+ : SwField( pFieldType, nFormat, LANGUAGE_SYSTEM, false )
+ , maContent(rContent)
+ , maPText(rPrompt)
+ , mnSubType(nSub)
+ , mbIsFormField( bIsFormField )
+ , mpFormatField( nullptr )
+{
+}
+
+SwInputField::~SwInputField()
+{
+}
+
+void SwInputField::SetFormatField( SwFormatField& rFormatField )
+{
+ mpFormatField = &rFormatField;
+}
+
+
+void SwInputField::applyFieldContent( const OUString& rNewFieldContent )
+{
+ if ( (mnSubType & 0x00ff) == INP_TXT )
+ {
+ maContent = rNewFieldContent;
+ }
+ else if( (mnSubType & 0x00ff) == INP_USR )
+ {
+ SwUserFieldType* pUserTyp = static_cast<SwUserFieldType*>(
+ static_cast<SwInputFieldType*>(GetTyp())->GetDoc()->getIDocumentFieldsAccess().GetFieldType( SwFieldIds::User, getContent(), false ) );
+ if( pUserTyp )
+ {
+ pUserTyp->SetContent( rNewFieldContent );
+ if (!pUserTyp->IsModifyLocked())
+ {
+ // trigger update of the corresponding User Fields and other
+ // related Input Fields
+ bool bUnlock(false);
+ if (GetFormatField() != nullptr)
+ {
+ SwTextInputField *const pTextInputField =
+ dynamic_cast<SwTextInputField*>(GetFormatField()->GetTextField());
+ if (pTextInputField != nullptr)
+ {
+ bUnlock = pTextInputField->LockNotifyContentChange();
+ }
+ }
+ pUserTyp->UpdateFields();
+ if (bUnlock)
+ {
+ SwTextInputField *const pTextInputField =
+ dynamic_cast<SwTextInputField*>(GetFormatField()->GetTextField());
+ if (pTextInputField != nullptr)
+ {
+ pTextInputField->UnlockNotifyContentChange();
+ }
+ }
+ }
+ }
+ }
+}
+
+OUString SwInputField::GetFieldName() const
+{
+ OUString aStr(SwField::GetFieldName());
+ if ((mnSubType & 0x00ff) == INP_USR)
+ {
+ aStr += GetTyp()->GetName() + " " + getContent();
+ }
+ return aStr;
+}
+
+std::unique_ptr<SwField> SwInputField::Copy() const
+{
+ std::unique_ptr<SwInputField> pField(
+ new SwInputField(
+ static_cast<SwInputFieldType*>(GetTyp()),
+ getContent(),
+ maPText,
+ GetSubType(),
+ GetFormat(),
+ mbIsFormField ));
+
+ pField->SetHelp( maHelp );
+ pField->SetToolTip( maToolTip );
+ pField->maGrabBag = maGrabBag;
+
+ pField->SetAutomaticLanguage(IsAutomaticLanguage());
+ return std::unique_ptr<SwField>(pField.release());
+}
+
+OUString SwInputField::ExpandImpl(SwRootFrame const*const) const
+{
+ if((mnSubType & 0x00ff) == INP_TXT)
+ {
+ return getContent();
+ }
+
+ if( (mnSubType & 0x00ff) == INP_USR )
+ {
+ SwUserFieldType* pUserTyp = static_cast<SwUserFieldType*>(
+ static_cast<SwInputFieldType*>(GetTyp())->GetDoc()->getIDocumentFieldsAccess().GetFieldType( SwFieldIds::User, getContent(), false ) );
+ if( pUserTyp )
+ return pUserTyp->GetContent();
+ }
+
+ return OUString();
+}
+
+bool SwInputField::isFormField() const
+{
+ return mbIsFormField
+ || !maHelp.isEmpty()
+ || !maToolTip.isEmpty();
+}
+
+bool SwInputField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
+{
+ switch( nWhichId )
+ {
+ case FIELD_PROP_PAR1:
+ rAny <<= getContent();
+ break;
+ case FIELD_PROP_PAR2:
+ rAny <<= maPText;
+ break;
+ case FIELD_PROP_PAR3:
+ rAny <<= maHelp;
+ break;
+ case FIELD_PROP_PAR4:
+ rAny <<= maToolTip;
+ break;
+ case FIELD_PROP_GRABBAG:
+ rAny <<= maGrabBag;
+ break;
+ case FIELD_PROP_TITLE:
+ break;
+ default:
+ assert(false);
+ }
+ return true;
+}
+
+bool SwInputField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
+{
+ switch( nWhichId )
+ {
+ case FIELD_PROP_PAR1:
+ rAny >>= maContent;
+ break;
+ case FIELD_PROP_PAR2:
+ rAny >>= maPText;
+ break;
+ case FIELD_PROP_PAR3:
+ rAny >>= maHelp;
+ break;
+ case FIELD_PROP_PAR4:
+ rAny >>= maToolTip;
+ break;
+ case FIELD_PROP_GRABBAG:
+ rAny >>= maGrabBag;
+ break;
+ case FIELD_PROP_TITLE:
+ break;
+ default:
+ assert(false);
+ }
+ return true;
+}
+
+/// set condition
+void SwInputField::SetPar1(const OUString& rStr)
+{
+ maContent = rStr;
+}
+
+OUString SwInputField::GetPar1() const
+{
+ return getContent();
+}
+
+void SwInputField::SetPar2(const OUString& rStr)
+{
+ maPText = rStr;
+}
+
+OUString SwInputField::GetPar2() const
+{
+ return maPText;
+}
+
+void SwInputField::SetHelp(const OUString & rStr)
+{
+ maHelp = rStr;
+}
+
+const OUString& SwInputField::GetHelp() const
+{
+ return maHelp;
+}
+
+void SwInputField::SetToolTip(const OUString & rStr)
+{
+ maToolTip = rStr;
+}
+
+const OUString& SwInputField::GetToolTip() const
+{
+ return maToolTip;
+}
+
+sal_uInt16 SwInputField::GetSubType() const
+{
+ return mnSubType;
+}
+
+void SwInputField::SetSubType(sal_uInt16 nSub)
+{
+ mnSubType = nSub;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */