/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"

#include <textapi.hxx>

#include <tools/pstm.hxx>
#include <hintids.hxx>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/script/XTypeConverter.hpp>
#include <com/sun/star/text/SetVariableType.hpp>
#include <com/sun/star/text/XTextFieldsSupplier.hpp>
#include <com/sun/star/text/UserDataPart.hpp>
#include <com/sun/star/text/ChapterFormat.hpp>
#include <com/sun/star/text/XTextField.hpp>
#include <com/sun/star/text/PlaceholderType.hpp>
#include <com/sun/star/text/TemplateDisplayFormat.hpp>
#include <com/sun/star/text/UserFieldFormat.hpp>
#include <com/sun/star/text/PageNumberType.hpp>
#include <com/sun/star/text/ReferenceFieldPart.hpp>
#include <com/sun/star/text/FilenameDisplayFormat.hpp>
#include <com/sun/star/text/XDependentTextField.hpp>
#include <com/sun/star/text/DocumentStatistic.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/util/Duration.hpp>
#include <unotools/localedatawrapper.hxx>
#include <editeng/unolingu.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/types.hxx>
#include <comphelper/string.hxx>
#include <tools/urlobj.hxx>
#include <vcl/svapp.hxx>
#include <svl/urihelper.hxx>
#include <unotools/useroptions.hxx>
#include <unotools/syslocale.hxx>
#include <svl/zforlist.hxx>

#include <tools/time.hxx>
#include <tools/datetime.hxx>

#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/util/Time.hpp>

#include <tools/shl.hxx>
#include <swmodule.hxx>
#include <sfx2/app.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/doctempl.hxx>
#include <fmtfld.hxx>
#include <txtfld.hxx>
#include <charfmt.hxx>
#include <docstat.hxx>
#include <pagedesc.hxx>
#include <fmtpdsc.hxx>
#include <doc.hxx>
#include <rootfrm.hxx>		// AuthorField
#include <pagefrm.hxx>		//
#include <cntfrm.hxx>		//
#include <pam.hxx>
#include <viewsh.hxx>
#include <dbmgr.hxx>
#include <shellres.hxx>
#include <docufld.hxx>
#include <flddat.hxx>
#include <docfld.hxx>
#include <ndtxt.hxx>
#include <expfld.hxx>
#include <poolfmt.hxx>
#include <docsh.hxx>
#include <unofldmid.h>
#include <swunohelper.hxx>
#include <comcore.hrc>

#include <editeng/outliner.hxx>
#include <editeng/outlobj.hxx>
#include <switerator.hxx>

#define URL_DECODE 	INetURLObject::DECODE_UNAMBIGUOUS

using ::rtl::OUString;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace nsSwDocInfoSubType;

/*--------------------------------------------------------------------
	Beschreibung: SwPageNumberFieldType
 --------------------------------------------------------------------*/

SwPageNumberFieldType::SwPageNumberFieldType()
	: SwFieldType( RES_PAGENUMBERFLD ),
	nNumberingType( SVX_NUM_ARABIC ),
	nNum( 0 ),
	nMax( USHRT_MAX ),
	bVirtuell( sal_False )
{
}

String& SwPageNumberFieldType::Expand( sal_uInt32 nFmt, short nOff,
								const String& rUserStr, String& rRet ) const
{
	sal_uInt32 nTmpFmt = (SVX_NUM_PAGEDESC == nFmt) ? (sal_uInt32)nNumberingType : nFmt;
	long nTmp = nNum + nOff;

	if( 0 >= nTmp || SVX_NUM_NUMBER_NONE == nTmpFmt || (!bVirtuell && nTmp > nMax) )
		rRet = aEmptyStr;
	else if( SVX_NUM_CHAR_SPECIAL == nTmpFmt )
		rRet = rUserStr;
	else
		rRet = FormatNumber( (sal_uInt16)nTmp, nTmpFmt );
	return rRet;
}

SwFieldType* SwPageNumberFieldType::Copy() const
{
	SwPageNumberFieldType *pTmp = new SwPageNumberFieldType();

	pTmp->nNum 		 = nNum;
	pTmp->nMax 		 = nMax;
	pTmp->nNumberingType = nNumberingType;
	pTmp->bVirtuell  = bVirtuell;

	return pTmp;
}

/*--------------------------------------------------------------------
	Beschreibung: Verschiedene Expandierung
 --------------------------------------------------------------------*/

void SwPageNumberFieldType::ChangeExpansion( SwDoc* pDoc, sal_uInt16 nPage,
											sal_uInt16 nNumPages, sal_Bool bVirt,
											const sal_Int16* pNumFmt )
{
	nNum = nPage;
	nMax = nNumPages;
	if( pNumFmt )
		nNumberingType = *pNumFmt;

	bVirtuell = sal_False;
	if( bVirt )
	{
		// dann muss das Flag ueberprueft werden, denn das Layout setzt
		// es NIE zurueck
		const SfxItemPool &rPool = pDoc->GetAttrPool();
		const SwFmtPageDesc *pDesc;
		sal_uInt32 nMaxItems = rPool.GetItemCount2( RES_PAGEDESC );
		for( sal_uInt32 n = 0; n < nMaxItems; ++n )
			if( 0 != (pDesc = (SwFmtPageDesc*)rPool.GetItem2( RES_PAGEDESC, n ) )
				&& pDesc->GetNumOffset() && pDesc->GetDefinedIn() )
			{
                SwCntntNode* pNd = PTR_CAST( SwCntntNode, pDesc->GetDefinedIn() );
				if( pNd )
				{
                    if ( SwIterator<SwFrm,SwCntntNode>::FirstElement(*pNd) )
						bVirtuell = sal_True;
				}
				else if( pDesc->GetDefinedIn()->ISA( SwFmt ))
				{
					SwAutoFmtGetDocNode aGetHt( &pDoc->GetNodes() );
					bVirtuell = !pDesc->GetDefinedIn()->GetInfo( aGetHt );
					break;
				}
			}
	}
}

/*--------------------------------------------------------------------
	Beschreibung: SwPageNumberField
 --------------------------------------------------------------------*/

SwPageNumberField::SwPageNumberField(SwPageNumberFieldType* pTyp,
									 sal_uInt16 nSub, sal_uInt32 nFmt, short nOff)
	: SwField(pTyp, nFmt), nSubType(nSub), nOffset(nOff)
{
}

String SwPageNumberField::Expand() const
{
	String sRet;
	SwPageNumberFieldType* pFldType = (SwPageNumberFieldType*)GetTyp();

	if( PG_NEXT == nSubType && 1 != nOffset )
	{
		if( pFldType->Expand( GetFormat(), 1, sUserStr, sRet ).Len() )
			pFldType->Expand( GetFormat(), nOffset, sUserStr, sRet );
	}
	else if( PG_PREV == nSubType && -1 != nOffset )
	{
		if( pFldType->Expand( GetFormat(), -1, sUserStr, sRet ).Len() )
			pFldType->Expand( GetFormat(), nOffset, sUserStr, sRet );
	}
	else
		pFldType->Expand( GetFormat(), nOffset, sUserStr, sRet );
	return sRet;
}

SwField* SwPageNumberField::Copy() const
{
	SwPageNumberField *pTmp =
		new SwPageNumberField((SwPageNumberFieldType*)GetTyp(), nSubType, GetFormat(), nOffset);
	pTmp->SetLanguage( GetLanguage() );
	pTmp->SetUserString( sUserStr );
	return pTmp;
}

String SwPageNumberField::GetPar2() const
{
	return String::CreateFromInt32(nOffset);
}

void SwPageNumberField::SetPar2(const String& rStr)
{
	nOffset = (short)rStr.ToInt32();
}

sal_uInt16 SwPageNumberField::GetSubType() const
{
	return nSubType;
}

sal_Bool SwPageNumberField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
    switch( nWhichId )
	{
	case FIELD_PROP_FORMAT:
		rAny <<= (sal_Int16)GetFormat();
		break;
	case FIELD_PROP_USHORT1:
		rAny <<= nOffset;
		break;
	case FIELD_PROP_SUBTYPE:
		{
	 		text::PageNumberType eType;
			eType = text::PageNumberType_CURRENT;
			if(nSubType == PG_PREV)
				eType = text::PageNumberType_PREV;
			else if(nSubType == PG_NEXT)
				eType = text::PageNumberType_NEXT;
			rAny.setValue(&eType, ::getCppuType((const text::PageNumberType*)0));
		}
		break;
	case FIELD_PROP_PAR1:
		rAny <<= OUString(sUserStr);
		break;

	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

sal_Bool SwPageNumberField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
    sal_Bool bRet = sal_True;
	sal_Int16 nSet = 0;
    switch( nWhichId )
	{
	case FIELD_PROP_FORMAT:
		rAny >>= nSet;

		// TODO: woher kommen die defines?
		if(nSet <= SVX_NUM_PAGEDESC )
			SetFormat(nSet);
		else {
			//exception(wrong_value)
			;
        }
		break;
	case FIELD_PROP_USHORT1:
		rAny >>= nSet;
		nOffset = nSet;
		break;
	case FIELD_PROP_SUBTYPE:
        switch( SWUnoHelper::GetEnumAsInt32( rAny ) )
		{
			case text::PageNumberType_CURRENT:
				nSubType = PG_RANDOM;
			break;
			case text::PageNumberType_PREV:
				nSubType = PG_PREV;
			break;
            case text::PageNumberType_NEXT:
                nSubType = PG_NEXT;
			break;
			default:
                bRet = sal_False;
		}
		break;
	case FIELD_PROP_PAR1:
		::GetString( rAny, sUserStr );
		break;

	default:
		DBG_ERROR("illegal property");
	}
    return bRet;
}
/*--------------------------------------------------------------------
	Beschreibung: SwAuthorFieldType
 --------------------------------------------------------------------*/

SwAuthorFieldType::SwAuthorFieldType()
	: SwFieldType( RES_AUTHORFLD )
{
}

String SwAuthorFieldType::Expand(sal_uLong nFmt) const
{
	String sRet;
    SvtUserOptions&  rOpt = SW_MOD()->GetUserOptions();
	if((nFmt & 0xff) == AF_NAME)
        sRet = rOpt.GetFullName();
	else
        sRet = rOpt.GetID();
	return sRet;
}

SwFieldType* SwAuthorFieldType::Copy() const
{
	return new SwAuthorFieldType;
}

/*--------------------------------------------------------------------
	Beschreibung: SwAuthorField
 --------------------------------------------------------------------*/

SwAuthorField::SwAuthorField(SwAuthorFieldType* pTyp, sal_uInt32 nFmt)
	: SwField(pTyp, nFmt)
{
	aContent = ((SwAuthorFieldType*)GetTyp())->Expand(GetFormat());
}

String SwAuthorField::Expand() const
{
	if (!IsFixed())
		((SwAuthorField*)this)->aContent =
					((SwAuthorFieldType*)GetTyp())->Expand(GetFormat());

	return aContent;
}

SwField* SwAuthorField::Copy() const
{
	SwAuthorField *pTmp = new SwAuthorField( (SwAuthorFieldType*)GetTyp(),
												GetFormat());
	pTmp->SetExpansion(aContent);
	return pTmp;
}

sal_Bool SwAuthorField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
	sal_Bool bVal;
    switch( nWhichId )
	{
	case FIELD_PROP_BOOL1:
		bVal = (GetFormat() & 0xff) == AF_NAME;
		rAny.setValue(&bVal, ::getBooleanCppuType());
		break;

	case FIELD_PROP_BOOL2:
		bVal = IsFixed();
		rAny.setValue(&bVal, ::getBooleanCppuType());
		break;

	case FIELD_PROP_PAR1:
		rAny <<= rtl::OUString(GetContent());
		break;

	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

sal_Bool SwAuthorField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
    switch( nWhichId )
	{
	case FIELD_PROP_BOOL1:
		SetFormat( *(sal_Bool*)rAny.getValue() ? AF_NAME : AF_SHORTCUT );
		break;

	case FIELD_PROP_BOOL2:
		if( *(sal_Bool*)rAny.getValue() )
			SetFormat( GetFormat() | AF_FIXED);
		else
			SetFormat( GetFormat() & ~AF_FIXED);
		break;

	case FIELD_PROP_PAR1:
		::GetString( rAny, aContent );
		break;

	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

/*--------------------------------------------------------------------
	Beschreibung: SwFileNameFieldType
 --------------------------------------------------------------------*/

SwFileNameFieldType::SwFileNameFieldType(SwDoc *pDocument)
	: SwFieldType( RES_FILENAMEFLD )
{
	pDoc = pDocument;
}

String SwFileNameFieldType::Expand(sal_uLong nFmt) const
{
	String aRet;
	const SwDocShell* pDShell = pDoc->GetDocShell();
	if( pDShell && pDShell->HasName() )
	{
		const INetURLObject& rURLObj = pDShell->GetMedium()->GetURLObject();
		switch( nFmt & ~FF_FIXED )
		{
			case FF_PATH:
				{
					if( INET_PROT_FILE == rURLObj.GetProtocol() )
					{
						INetURLObject aTemp(rURLObj);
						aTemp.removeSegment();
                        // #101947# last slash should belong to the pathname
						aRet = aTemp.PathToFileName();//GetFull();
					}
					else
					{
						aRet = URIHelper::removePassword(
									rURLObj.GetMainURL( INetURLObject::NO_DECODE ),
									INetURLObject::WAS_ENCODED, URL_DECODE );
						aRet.Erase( aRet.Search( String(rURLObj.GetLastName(
													URL_DECODE )) ) );
					}
				}
				break;

			case FF_NAME:
				aRet = rURLObj.GetLastName( URL_DECODE );
				break;

			case FF_NAME_NOEXT:
				aRet = rURLObj.GetBase();
				break;

			default:
				if( INET_PROT_FILE == rURLObj.GetProtocol() )
					aRet = rURLObj.GetFull();
				else
					aRet = URIHelper::removePassword(
									rURLObj.GetMainURL( INetURLObject::NO_DECODE ),
									INetURLObject::WAS_ENCODED, URL_DECODE );
		}
	}
	return aRet;
}

SwFieldType* SwFileNameFieldType::Copy() const
{
	SwFieldType *pTmp = new SwFileNameFieldType(pDoc);
	return pTmp;
}
/*--------------------------------------------------------------------
	Beschreibung: SwFileNameField
 --------------------------------------------------------------------*/

SwFileNameField::SwFileNameField(SwFileNameFieldType* pTyp, sal_uInt32 nFmt)
	: SwField(pTyp, nFmt)
{
	aContent = ((SwFileNameFieldType*)GetTyp())->Expand(GetFormat());
}

String SwFileNameField::Expand() const
{
	if (!IsFixed())
		((SwFileNameField*)this)->aContent = ((SwFileNameFieldType*)GetTyp())->Expand(GetFormat());

	return aContent;
}

SwField* SwFileNameField::Copy() const
{
	SwFileNameField *pTmp =
		new SwFileNameField((SwFileNameFieldType*)GetTyp(), GetFormat());
	pTmp->SetExpansion(aContent);

	return pTmp;
}

sal_Bool SwFileNameField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
    switch( nWhichId )
	{
	case FIELD_PROP_FORMAT:
		{
        	sal_Int16 nRet;
			switch( GetFormat() &(~FF_FIXED) )
			{
				case FF_PATH:
					nRet = text::FilenameDisplayFormat::PATH;
				break;
				case FF_NAME_NOEXT:
					nRet = text::FilenameDisplayFormat::NAME;
				break;
				case FF_NAME:
					nRet = text::FilenameDisplayFormat::NAME_AND_EXT;
				break;
				default:	nRet = text::FilenameDisplayFormat::FULL;
			}
			rAny <<= nRet;
		}
		break;

	case FIELD_PROP_BOOL2:
		{
			sal_Bool bVal = IsFixed();
			rAny.setValue(&bVal, ::getBooleanCppuType());
		}
		break;

	case FIELD_PROP_PAR3:
		rAny <<= OUString(GetContent());
		break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

sal_Bool SwFileNameField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
    switch( nWhichId )
	{
	case FIELD_PROP_FORMAT:
		{
			//JP 24.10.2001: int32 because in UnoField.cxx a putvalue is
			//				called with a int32 value! But normally we need
			//				here only a int16
			sal_Int32 nType = 0;
			rAny >>= nType;
			sal_Bool bFixed = IsFixed();
			switch( nType )
			{
				case text::FilenameDisplayFormat::PATH:
					nType = FF_PATH;
				break;
				case text::FilenameDisplayFormat::NAME:
					nType = FF_NAME_NOEXT;
				break;
				case text::FilenameDisplayFormat::NAME_AND_EXT:
					nType = FF_NAME;
				break;
				default:	nType = FF_PATHNAME;
			}
			if(bFixed)
				nType |= FF_FIXED;
			SetFormat(nType);
		}
		break;

	case FIELD_PROP_BOOL2:
		if( *(sal_Bool*)rAny.getValue() )
			SetFormat( GetFormat() | FF_FIXED);
		else
			SetFormat( GetFormat() & ~FF_FIXED);
		break;

	case FIELD_PROP_PAR3:
		::GetString( rAny, aContent );
		break;

	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}
/*--------------------------------------------------------------------
	Beschreibung: SwTemplNameFieldType
 --------------------------------------------------------------------*/

SwTemplNameFieldType::SwTemplNameFieldType(SwDoc *pDocument)
	: SwFieldType( RES_TEMPLNAMEFLD )
{
	pDoc = pDocument;
}

String SwTemplNameFieldType::Expand(sal_uLong nFmt) const
{
	ASSERT( nFmt < FF_END, "Expand: kein guelt. Fmt!" );

	String aRet;
    SwDocShell *pDocShell(pDoc->GetDocShell());
    DBG_ASSERT(pDocShell, "no SwDocShell");
    if (pDocShell) {
        uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
            pDocShell->GetModel(), uno::UNO_QUERY_THROW);
        uno::Reference<document::XDocumentProperties> xDocProps(
            xDPS->getDocumentProperties());
        DBG_ASSERT(xDocProps.is(), "Doc has no DocumentProperties");

		if( FF_UI_NAME == nFmt )
			aRet = xDocProps->getTemplateName();
		else if( !xDocProps->getTemplateURL().equalsAscii("") )
		{
			if( FF_UI_RANGE == nFmt )
			{
				// fuers besorgen vom RegionNamen !!
				SfxDocumentTemplates aFac;
				aFac.Construct();
				String sTmp;
				aFac.GetLogicNames( xDocProps->getTemplateURL(), aRet, sTmp );
			}
			else
			{
				INetURLObject aPathName( xDocProps->getTemplateURL() );
				if( FF_NAME == nFmt )
					aRet = aPathName.GetName(URL_DECODE);
				else if( FF_NAME_NOEXT == nFmt )
					aRet = aPathName.GetBase();
				else
				{
					if( FF_PATH == nFmt )
					{
						aPathName.removeSegment();
						aRet = aPathName.GetFull();
					}
					else
						aRet = aPathName.GetFull();
				}
			}
		}
	}
	return aRet;
}

SwFieldType* SwTemplNameFieldType::Copy() const
{
	SwFieldType *pTmp = new SwTemplNameFieldType(pDoc);
	return pTmp;
}
/*--------------------------------------------------------------------
	Beschreibung: SwTemplNameField
 --------------------------------------------------------------------*/

SwTemplNameField::SwTemplNameField(SwTemplNameFieldType* pTyp, sal_uInt32 nFmt)
	: SwField(pTyp, nFmt)
{}

String SwTemplNameField::Expand() const
{
	return((SwTemplNameFieldType*)GetTyp())->Expand(GetFormat());
}

SwField* SwTemplNameField::Copy() const
{
	SwTemplNameField *pTmp =
		new SwTemplNameField((SwTemplNameFieldType*)GetTyp(), GetFormat());
	return pTmp;
}

sal_Bool SwTemplNameField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
    switch ( nWhichId )
	{
	case FIELD_PROP_FORMAT:
		{
        	sal_Int16 nRet;
			switch( GetFormat() )
			{
				case FF_PATH:		nRet = text::FilenameDisplayFormat::PATH; break;
				case FF_NAME_NOEXT: nRet = text::FilenameDisplayFormat::NAME; break;
				case FF_NAME: 		nRet = text::FilenameDisplayFormat::NAME_AND_EXT; break;
				case FF_UI_RANGE: 	nRet = text::TemplateDisplayFormat::AREA; break;
				case FF_UI_NAME:    nRet = text::TemplateDisplayFormat::TITLE;  break;
				default:	nRet = text::FilenameDisplayFormat::FULL;

			}
			rAny <<= nRet;
		}
		break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

sal_Bool SwTemplNameField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
    switch ( nWhichId )
	{
	case FIELD_PROP_FORMAT:
		{
			//JP 24.10.2001: int32 because in UnoField.cxx a putvalue is
			//				called with a int32 value! But normally we need
			//				here only a int16
			sal_Int32 nType = 0;
			rAny >>= nType;
			switch( nType )
			{
			case text::FilenameDisplayFormat::PATH:
				SetFormat(FF_PATH);
			break;
			case text::FilenameDisplayFormat::NAME:
				SetFormat(FF_NAME_NOEXT);
			break;
			case text::FilenameDisplayFormat::NAME_AND_EXT:
				SetFormat(FF_NAME);
			break;
			case text::TemplateDisplayFormat::AREA	:
				SetFormat(FF_UI_RANGE);
			break;
			case text::TemplateDisplayFormat::TITLE  :
				SetFormat(FF_UI_NAME);
			break;
			default:	SetFormat(FF_PATHNAME);
			}
		}
		break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}
/*--------------------------------------------------------------------
	Beschreibung: SwDocStatFieldType
 --------------------------------------------------------------------*/

SwDocStatFieldType::SwDocStatFieldType(SwDoc* pDocument)
	: SwFieldType( RES_DOCSTATFLD ), nNumberingType( SVX_NUM_ARABIC )
{
	pDoc = pDocument;
}

String SwDocStatFieldType::Expand(sal_uInt16 nSubType, sal_uInt32 nFmt) const
{
	sal_uInt32 nVal = 0;
	const SwDocStat& rDStat = pDoc->GetDocStat();
	switch( nSubType )
	{
		case DS_TBL:  nVal = rDStat.nTbl;   break;
		case DS_GRF:  nVal = rDStat.nGrf;   break;
		case DS_OLE:  nVal = rDStat.nOLE;   break;
		case DS_PARA: nVal = rDStat.nPara;  break;
		case DS_WORD: nVal = rDStat.nWord;  break;
		case DS_CHAR: nVal = rDStat.nChar;  break;
		case DS_PAGE:
			if( pDoc->GetCurrentLayout() )//swmod 080218
				((SwDocStat	&)rDStat).nPage = pDoc->GetCurrentLayout()->GetPageNum();	//swmod 080218
			nVal = rDStat.nPage;
			if( SVX_NUM_PAGEDESC == nFmt )
				nFmt = (sal_uInt32)nNumberingType;
			break;
		default:
			ASSERT( sal_False, "SwDocStatFieldType::Expand: unbekannter SubType" );
	}

	String sRet;
	if( nVal <= SHRT_MAX )
		sRet = FormatNumber( (sal_uInt16)nVal, nFmt );
	else
		sRet = String::CreateFromInt32( nVal );
	return sRet;
}

SwFieldType* SwDocStatFieldType::Copy() const
{
	SwDocStatFieldType *pTmp = new SwDocStatFieldType(pDoc);
	return pTmp;
}

/*--------------------------------------------------------------------
	Beschreibung: SwDocStatFieldType
				  Aus historischen Gruenden steht in nFormat der
				  SubType
 --------------------------------------------------------------------*/

SwDocStatField::SwDocStatField(SwDocStatFieldType* pTyp, sal_uInt16 nSub, sal_uInt32 nFmt)
	: SwField(pTyp, nFmt),
	nSubType(nSub)
{}

String SwDocStatField::Expand() const
{
	return((SwDocStatFieldType*)GetTyp())->Expand(nSubType, GetFormat());
}

SwField* SwDocStatField::Copy() const
{
	SwDocStatField *pTmp = new SwDocStatField(
					(SwDocStatFieldType*)GetTyp(), nSubType, GetFormat() );
	return pTmp;
}

sal_uInt16 SwDocStatField::GetSubType() const
{
	return nSubType;
}

void SwDocStatField::SetSubType(sal_uInt16 nSub)
{
	nSubType = nSub;
}

void SwDocStatField::ChangeExpansion( const SwFrm* pFrm )
{
	if( DS_PAGE == nSubType && SVX_NUM_PAGEDESC == GetFormat() )
		((SwDocStatFieldType*)GetTyp())->SetNumFormat(
				pFrm->FindPageFrm()->GetPageDesc()->GetNumType().GetNumberingType() );
}

sal_Bool SwDocStatField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
    switch ( nWhichId )
	{
	case FIELD_PROP_USHORT2:
		rAny <<= (sal_Int16)GetFormat();
		break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

sal_Bool SwDocStatField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
	sal_Bool bRet = sal_False;
    switch ( nWhichId )
	{
	case FIELD_PROP_USHORT2:
		{
			sal_Int16 nSet = 0;
			rAny >>= nSet;
			if(nSet <= SVX_NUM_CHARS_LOWER_LETTER_N &&
				nSet != SVX_NUM_CHAR_SPECIAL &&
					nSet != SVX_NUM_BITMAP)
			{
				SetFormat(nSet);
				bRet = sal_True;
			}
		}
		break;

	default:
		DBG_ERROR("illegal property");
	}
	return bRet;
}

/*--------------------------------------------------------------------
	Beschreibung: DokumentinfoFields
 --------------------------------------------------------------------*/

SwDocInfoFieldType::SwDocInfoFieldType(SwDoc* pDc)
	: SwValueFieldType( pDc, RES_DOCINFOFLD )
{
}

// ---------------------------------------------------------------------------
SwFieldType* SwDocInfoFieldType::Copy() const
{
	SwDocInfoFieldType* pTyp = new SwDocInfoFieldType(GetDoc());
	return pTyp;
}

void lcl_GetLocalDataWrapper( sal_uLong nLang,
							  const LocaleDataWrapper **ppAppLocalData,
							  const LocaleDataWrapper **ppLocalData )
{
    SvtSysLocale aLocale;
	*ppAppLocalData = &aLocale.GetLocaleData();
	*ppLocalData = *ppAppLocalData;
	if( nLang != SvxLocaleToLanguage( (*ppLocalData)->getLocale() ) )
		*ppLocalData = new LocaleDataWrapper(
						::comphelper::getProcessServiceFactory(),
						SvxCreateLocale( static_cast<LanguageType>(nLang) ) );
}

// ---------------------------------------------------------------------------
String SwDocInfoFieldType::Expand( sal_uInt16 nSub, sal_uInt32 nFormat,
									sal_uInt16 nLang, const String& rName ) const
{
	String aStr;
	const LocaleDataWrapper *pAppLocalData = 0, *pLocalData = 0;
    SwDocShell *pDocShell(GetDoc()->GetDocShell());
    DBG_ASSERT(pDocShell, "no SwDocShell");
    if (!pDocShell) { return aStr; }

    uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
        pDocShell->GetModel(), uno::UNO_QUERY_THROW);
    uno::Reference<document::XDocumentProperties> xDocProps(
        xDPS->getDocumentProperties());
    DBG_ASSERT(xDocProps.is(), "Doc has no DocumentProperties");

	sal_uInt16 nExtSub = nSub & 0xff00;
	nSub &= 0xff;	// ExtendedSubTypes nicht beachten

	switch(nSub)
	{
	case DI_TITEL:	aStr = xDocProps->getTitle();	    break;
	case DI_THEMA:	aStr = xDocProps->getSubject();	    break;
	case DI_KEYS:	aStr = ::comphelper::string::convertCommaSeparated(
                                xDocProps->getKeywords());
                    break;
	case DI_COMMENT:aStr = xDocProps->getDescription();	break;
	case DI_DOCNO:	aStr = String::CreateFromInt32(
										xDocProps->getEditingCycles() );
					break;
	case DI_EDIT:
		if ( !nFormat )
		{
			lcl_GetLocalDataWrapper( nLang, &pAppLocalData, &pLocalData );
            sal_Int32 dur = xDocProps->getEditingDuration();
			aStr = pLocalData->getTime( Time(dur/3600, (dur%3600)/60, dur%60),
                                        sal_False, sal_False);
		}
		else
		{
            sal_Int32 dur = xDocProps->getEditingDuration();
            double fVal = Time(dur/3600, (dur%3600)/60, dur%60).GetTimeInDays();
			aStr = ExpandValue(fVal, nFormat, nLang);
		}
		break;
	case DI_CUSTOM:
		{
			::rtl::OUString sVal;
			try
			{
				uno::Any aAny;
				uno::Reference < beans::XPropertySet > xSet(
                    xDocProps->getUserDefinedProperties(),
                    uno::UNO_QUERY_THROW);
				aAny = xSet->getPropertyValue( rName );

				uno::Reference < script::XTypeConverter > xConverter( comphelper::getProcessServiceFactory()
					->createInstance(::rtl::OUString::createFromAscii("com.sun.star.script.Converter")), uno::UNO_QUERY );
				uno::Any aNew;
					aNew = xConverter->convertToSimpleType( aAny, uno::TypeClass_STRING );
				aNew >>= sVal;
			}
			catch (uno::Exception&) {}
			return sVal;
		}

	default:
		{
			String aName( xDocProps->getAuthor() );
			util::DateTime uDT( xDocProps->getCreationDate() );
            Date aD(uDT.Day, uDT.Month, uDT.Year);
            Time aT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds);
            DateTime aDate(aD,aT);
			if( nSub == DI_CREATE )
				;		// das wars schon!!
			else if( nSub == DI_CHANGE )
			{
				aName = xDocProps->getModifiedBy();
				uDT = xDocProps->getModificationDate();
                Date bD(uDT.Day, uDT.Month, uDT.Year);
                Time bT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds);
                DateTime bDate(bD,bT);
                aDate = bDate;
            }
			else if( nSub == DI_PRINT )
			{
				aName = xDocProps->getPrintedBy();
				uDT = xDocProps->getPrintDate();
                Date bD(uDT.Day, uDT.Month, uDT.Year);
                Time bT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds);
                DateTime bDate(bD,bT);
                aDate = bDate;
			}
			else
				break;

			if (aDate.IsValid())
			{
				switch (nExtSub & ~DI_SUB_FIXED)
				{
				case DI_SUB_AUTHOR:
					aStr = aName;
					break;

				case DI_SUB_TIME:
					if (!nFormat)
					{
						lcl_GetLocalDataWrapper( nLang, &pAppLocalData,
														&pLocalData );
						aStr = pLocalData->getTime( aDate,
													sal_False, sal_False);
					}
					else
					{
						// Numberformatter anwerfen!
						double fVal = SwDateTimeField::GetDateTime( GetDoc(),
                                                    aDate);
						aStr = ExpandValue(fVal, nFormat, nLang);
					}
					break;

				case DI_SUB_DATE:
					if (!nFormat)
					{
						lcl_GetLocalDataWrapper( nLang, &pAppLocalData,
												 &pLocalData );
						aStr = pLocalData->getDate( aDate );
					}
					else
					{
						// Numberformatter anwerfen!
						double fVal = SwDateTimeField::GetDateTime( GetDoc(),
                                                    aDate);
						aStr = ExpandValue(fVal, nFormat, nLang);
					}
					break;
				}
			}
		}
		break;
	}

	if( pAppLocalData != pLocalData )
		delete pLocalData;

	return aStr;
}

// ---------------------------------------------------------------------------
SwDocInfoField::SwDocInfoField(SwDocInfoFieldType* pTyp, sal_uInt16 nSub, const String& rName, sal_uInt32 nFmt) :
	SwValueField(pTyp, nFmt), nSubType(nSub)
{
	aName = rName;
	aContent = ((SwDocInfoFieldType*)GetTyp())->Expand(nSubType, nFmt, GetLanguage(), aName);
}

SwDocInfoField::SwDocInfoField(SwDocInfoFieldType* pTyp, sal_uInt16 nSub, const String& rName, const String& rValue, sal_uInt32 nFmt) :
    SwValueField(pTyp, nFmt), nSubType(nSub)
{
    aName = rName;
    aContent = rValue;
}

// ---------------------------------------------------------------------------

template<class T>
double lcl_TimeToDouble( const T& rTime )
{
    const double fMilliSecondsPerDay = 86400000.0;
    return ((rTime.Hours*3600000)+(rTime.Minutes*60000)+(rTime.Seconds*1000)+(rTime.HundredthSeconds*10)) / fMilliSecondsPerDay;
}

template<class D>
double lcl_DateToDouble( const D& rDate, const Date& rNullDate )
{
    long nDate = Date::DateToDays( rDate.Day, rDate.Month, rDate.Year );
    long nNullDate = Date::DateToDays( rNullDate.GetDay(), rNullDate.GetMonth(), rNullDate.GetYear() );
    return double( nDate - nNullDate );
}

String SwDocInfoField::Expand() const
{
    if ( ( nSubType & 0xFF ) == DI_CUSTOM )
    {
         // custom properties currently need special treatment
         // we don't have a secure way to detect "real" custom properties in Word  Import of text fields
        // so we treat *every* unknown property as a custom property, even the "built-in" section in Word's document summary information stream
        // as these properties have not been inserted when the document summary information was imported, we do it here
        // this approach is still a lot better than the old one to import such fields as "user fields" and simple text
        SwDocShell* pDocShell = GetDoc()->GetDocShell();
        if( !pDocShell )
            return aContent;
        try
        {
            uno::Reference<document::XDocumentPropertiesSupplier> xDPS( pDocShell->GetModel(), uno::UNO_QUERY_THROW);
            uno::Reference<document::XDocumentProperties> xDocProps( xDPS->getDocumentProperties());
            uno::Reference < beans::XPropertySet > xSet( xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
            uno::Reference < beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo();

            uno::Any aAny;
            if( xSetInfo->hasPropertyByName( aName ) )
                aAny = xSet->getPropertyValue( aName );
            if ( aAny.getValueType() != ::getVoidCppuType() )
            {
                // "void" type means that the property has not been inserted until now
                if ( !IsFixed() )
                {
                    // if the field is "fixed" we don't update it from the property
                    ::rtl::OUString sVal;
                    uno::Reference < script::XTypeConverter > xConverter( comphelper::getProcessServiceFactory()
                        ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.script.Converter")), uno::UNO_QUERY );
                    util::Date aDate;
                    util::DateTime aDateTime;
                    util::Duration aDuration;
                    if( aAny >>= aDate) 
                    {
                        SvNumberFormatter* pFormatter = pDocShell->GetDoc()->GetNumberFormatter();
                        Date* pNullDate = pFormatter->GetNullDate();
                        sVal = ExpandValue( lcl_DateToDouble<util::Date>( aDate, *pNullDate ), GetFormat(), GetLanguage());
                    }
                    else if( aAny >>= aDateTime )
                    {
                        double fDateTime = lcl_TimeToDouble<util::DateTime>( aDateTime );
                        SvNumberFormatter* pFormatter = pDocShell->GetDoc()->GetNumberFormatter();
                        Date* pNullDate = pFormatter->GetNullDate();
                        fDateTime += lcl_DateToDouble<util::DateTime>( aDateTime, *pNullDate );
                        sVal = ExpandValue( fDateTime, GetFormat(), GetLanguage());
                    }
                    else if( aAny >>= aDuration )
                    {
                        String sText(aDuration.Negative ? '-' : '+');
                        sText += ViewShell::GetShellRes()->sDurationFormat;
                        sText.SearchAndReplace(String::CreateFromAscii( "%1"), String::CreateFromInt32( aDuration.Years ) );
                        sText.SearchAndReplace(String::CreateFromAscii( "%2"), String::CreateFromInt32( aDuration.Months ) );
                        sText.SearchAndReplace(String::CreateFromAscii( "%3"), String::CreateFromInt32( aDuration.Days   ) );
                        sText.SearchAndReplace(String::CreateFromAscii( "%4"), String::CreateFromInt32( aDuration.Hours  ) );
                        sText.SearchAndReplace(String::CreateFromAscii( "%5"), String::CreateFromInt32( aDuration.Minutes) );
                        sText.SearchAndReplace(String::CreateFromAscii( "%6"), String::CreateFromInt32( aDuration.Seconds) );
                        sVal = sText;
                    }
                    else
                    {
                        uno::Any aNew = xConverter->convertToSimpleType( aAny, uno::TypeClass_STRING );
                        aNew >>= sVal;
                    }
                    ((SwDocInfoField*)this)->aContent = sVal;
                }
            }
        }
        catch (uno::Exception&) {}
    }
    else if ( !IsFixed() )
		((SwDocInfoField*)this)->aContent = ((SwDocInfoFieldType*)GetTyp())->Expand(nSubType, GetFormat(), GetLanguage(), aName);

	return aContent;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwDocInfoField::GetFieldName() const
{
    String aStr(SwFieldType::GetTypeStr(GetTypeId()));
    aStr += ':';

    sal_uInt16 const nSub = nSubType & 0xff;

    switch (nSub)
    {
        case DI_CUSTOM:
            aStr += aName;
            break;

        default:
            aStr += *ViewShell::GetShellRes()
                        ->aDocInfoLst[ nSub - DI_SUBTYPE_BEGIN ];
            break;
    }
    if (IsFixed())
    {
        aStr += ' ';
        aStr += ViewShell::GetShellRes()->aFixedStr;
    }
    return aStr;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwField* SwDocInfoField::Copy() const
{
	SwDocInfoField* pFld = new SwDocInfoField((SwDocInfoFieldType*)GetTyp(), nSubType, aName, GetFormat());
    pFld->SetAutomaticLanguage(IsAutomaticLanguage());
	pFld->aContent = aContent;

	return pFld;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
sal_uInt16 SwDocInfoField::GetSubType() const
{
	return nSubType;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
void SwDocInfoField::SetSubType(sal_uInt16 nSub)
{
	nSubType = nSub;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
void SwDocInfoField::SetLanguage(sal_uInt16 nLng)
{
	if (!GetFormat())
		SwField::SetLanguage(nLng);
	else
		SwValueField::SetLanguage(nLng);
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool SwDocInfoField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
    switch( nWhichId )
	{
	case FIELD_PROP_PAR1:
		rAny <<= OUString(aContent);
		break;

	case FIELD_PROP_PAR4:
		rAny <<= OUString(aName);
		break;

	case FIELD_PROP_USHORT1:
		rAny  <<= (sal_Int16)aContent.ToInt32();
		break;

	case FIELD_PROP_BOOL1:
		{
			sal_Bool bVal = 0 != (nSubType & DI_SUB_FIXED);
			rAny.setValue(&bVal, ::getBooleanCppuType());
		}
		break;
	case FIELD_PROP_FORMAT:
		rAny  <<= (sal_Int32)GetFormat();
		break;

	case FIELD_PROP_DOUBLE:
		{
			double fVal = GetValue();
			rAny.setValue(&fVal, ::getCppuType(&fVal));
		}
		break;
	case FIELD_PROP_PAR3:
		rAny <<= rtl::OUString(Expand());
		break;
	case FIELD_PROP_BOOL2:
		{
			sal_uInt16 nExtSub = (nSubType & 0xff00) & ~DI_SUB_FIXED;
			sal_Bool bVal = (nExtSub == DI_SUB_DATE);
			rAny.setValue(&bVal, ::getBooleanCppuType());
		}
		break;
	default:
        return SwField::QueryValue(rAny, nWhichId);
    }
	return sal_True;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool SwDocInfoField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
	sal_Int32 nValue = 0;
    switch( nWhichId )
	{
	case FIELD_PROP_PAR1:
		if( nSubType & DI_SUB_FIXED )
			::GetString( rAny, aContent );
		break;

	case FIELD_PROP_USHORT1:
		if( nSubType & DI_SUB_FIXED )
		{
			rAny >>= nValue;
			aContent = String::CreateFromInt32(nValue);
		}
		break;

	case FIELD_PROP_BOOL1:
		if(*(sal_Bool*)rAny.getValue())
			nSubType |= DI_SUB_FIXED;
		else
			nSubType &= ~DI_SUB_FIXED;
		break;
	case FIELD_PROP_FORMAT:
		{
			rAny >>= nValue;
			if( nValue >= 0)
				SetFormat(nValue);
		}
		break;

	case FIELD_PROP_PAR3:
		::GetString( rAny, aContent );
		break;
	case FIELD_PROP_BOOL2:
		nSubType &= 0xf0ff;
		if(*(sal_Bool*)rAny.getValue())
			nSubType |= DI_SUB_DATE;
		else
			nSubType |= DI_SUB_TIME;
		break;
	default:
        return SwField::PutValue(rAny, nWhichId);
    }
	return sal_True;
}

/*--------------------------------------------------------------------
	Beschreibung: SwHiddenTxtFieldType by JP
 --------------------------------------------------------------------*/

SwHiddenTxtFieldType::SwHiddenTxtFieldType( sal_Bool bSetHidden )
	: SwFieldType( RES_HIDDENTXTFLD ), bHidden( bSetHidden )
{
}

SwFieldType* SwHiddenTxtFieldType::Copy() const
{
	return new SwHiddenTxtFieldType( bHidden );
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
void SwHiddenTxtFieldType::SetHiddenFlag( sal_Bool bSetHidden )
{
	if( bHidden != bSetHidden )
	{
		bHidden = bSetHidden;
		UpdateFlds();		// alle HiddenText benachrichtigen
	}
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwHiddenTxtField::SwHiddenTxtField( SwHiddenTxtFieldType* pFldType,
									sal_Bool 	bConditional,
									const 	String& rCond,
									const	String& rStr,
									sal_Bool 	bHidden,
									sal_uInt16  nSub) :
	SwField( pFldType ), aCond(rCond), nSubType(nSub),
	bCanToggle(bConditional), bIsHidden(bHidden), bValid(sal_False)
{
	if(nSubType == TYP_CONDTXTFLD)
	{
		sal_uInt16 nPos = 0;
		aTRUETxt = rStr.GetToken(0, '|', nPos);

		if(nPos != STRING_NOTFOUND)
		{
			aFALSETxt = rStr.GetToken(0, '|', nPos);
			if(nPos != STRING_NOTFOUND)
			{
				aContent = rStr.GetToken(0, '|', nPos);
				bValid = sal_True;
			}
		}
	}
	else
		aTRUETxt = rStr;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwHiddenTxtField::SwHiddenTxtField( SwHiddenTxtFieldType* pFldType,
									const String& rCond,
									const String& rTrue,
									const String& rFalse,
									sal_uInt16 nSub)
	: SwField( pFldType ), aTRUETxt(rTrue), aFALSETxt(rFalse), aCond(rCond), nSubType(nSub),
	  bIsHidden(sal_True), bValid(sal_False)
{
	bCanToggle	= aCond.Len() > 0;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwHiddenTxtField::Expand() const
{
	// Type: !Hidden  -> immer anzeigen
	// 		  Hide	  -> Werte die Bedingung aus

	if( TYP_CONDTXTFLD == nSubType )
	{
		if( bValid )
			return aContent;

		if( bCanToggle && !bIsHidden )
			return aTRUETxt;
	}
	else if( !((SwHiddenTxtFieldType*)GetTyp())->GetHiddenFlag() ||
		( bCanToggle && bIsHidden ))
		return aTRUETxt;

	return aFALSETxt;
}

/*--------------------------------------------------------------------
	Beschreibung: Aktuellen Field-Value holen und cachen
 --------------------------------------------------------------------*/

void SwHiddenTxtField::Evaluate(SwDoc* pDoc)
{
	ASSERT(pDoc, Wo ist das Dokument Seniore);

	if( TYP_CONDTXTFLD == nSubType )
	{
		SwNewDBMgr* pMgr = pDoc->GetNewDBMgr();

		bValid = sal_False;
		String sTmpName;

		if (bCanToggle && !bIsHidden)
			sTmpName = aTRUETxt;
		else
			sTmpName = aFALSETxt;

// OS 21.08.97: #42943# Datenbankausdruecke muessen sich von
// 				einfachem Text unterscheiden. also wird der einfache Text
// 				bevorzugt in Anfuehrungszeichen gesetzt.
// 				Sind diese vorhanden werden umschliessende entfernt.
//				Wenn nicht, dann wird auf die Tauglichkeit als Datenbankname
//				geprueft. Nur wenn zwei oder mehr Punkte vorhanden sind und kein
//				Anfuehrungszeichen enthalten ist, gehen wir von einer DB aus.
		if(sTmpName.Len() > 1 && sTmpName.GetChar(0) == '\"' &&
			sTmpName.GetChar((sTmpName.Len() - 1))== '\"')
		{
			aContent = sTmpName.Copy(1, sTmpName.Len() - 2);
			bValid = sal_True;
		}
		else if(sTmpName.Search('\"') == STRING_NOTFOUND &&
			sTmpName.GetTokenCount('.') > 2)
		{
			::ReplacePoint(sTmpName);
			if(sTmpName.GetChar(0) == '[' && sTmpName.GetChar(sTmpName.Len()-1) == ']')
			{	// Eckige Klammern entfernen
				sTmpName.Erase(0, 1);
				sTmpName.Erase(sTmpName.Len()-1, 1);
			}

			if( pMgr)
			{
				String sDBName( GetDBName( sTmpName, pDoc ));
				String sDataSource(sDBName.GetToken(0, DB_DELIM));
				String sDataTableOrQuery(sDBName.GetToken(1, DB_DELIM));
				if( pMgr->IsInMerge() && sDBName.Len() &&
					pMgr->IsDataSourceOpen( sDataSource,
												sDataTableOrQuery, sal_False))
				{
					double fNumber;
					sal_uInt32 nTmpFormat;
					pMgr->GetMergeColumnCnt(GetColumnName( sTmpName ),
                        GetLanguage(), aContent, &fNumber, &nTmpFormat );
					bValid = sal_True;
				}
				else if( sDBName.Len() && sDataSource.Len() &&
						 sDataTableOrQuery.Len() )
					bValid = sal_True;
			}
		}
	}
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwHiddenTxtField::GetFieldName() const
{
    String aStr(SwFieldType::GetTypeStr(nSubType));
    aStr += ' ';
    aStr += aCond;
    aStr += ' ';
    aStr += aTRUETxt;

    if (nSubType == TYP_CONDTXTFLD)
    {
        aStr.AppendAscii(" : ");
        aStr += aFALSETxt;
    }
    return aStr;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwField* SwHiddenTxtField::Copy() const
{
	SwHiddenTxtField* pFld =
		new SwHiddenTxtField((SwHiddenTxtFieldType*)GetTyp(), aCond,
							  aTRUETxt, aFALSETxt);
	pFld->bIsHidden = bIsHidden;
	pFld->bValid	= bValid;
	pFld->aContent	= aContent;
	pFld->SetFormat(GetFormat());
	pFld->nSubType 	= nSubType;
	return pFld;
}


/*--------------------------------------------------------------------
	Beschreibung: Bedingung setzen
 --------------------------------------------------------------------*/

void SwHiddenTxtField::SetPar1(const String& rStr)
{
	aCond = rStr;
	bCanToggle = aCond.Len() > 0;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
const String& SwHiddenTxtField::GetPar1() const
{
	return aCond;
}

/*--------------------------------------------------------------------
	Beschreibung: True/False Text
 --------------------------------------------------------------------*/

void SwHiddenTxtField::SetPar2(const String& rStr)
{
	if(nSubType == TYP_CONDTXTFLD)
	{
		sal_uInt16 nPos = rStr.Search('|');
		aTRUETxt = rStr.Copy(0, nPos);

		if(nPos != STRING_NOTFOUND)
			aFALSETxt = rStr.Copy(nPos + 1);
	}
	else
		aTRUETxt = rStr;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwHiddenTxtField::GetPar2() const
{
	String aRet(aTRUETxt);
	if(nSubType == TYP_CONDTXTFLD)
	{
		aRet += '|';
		aRet += aFALSETxt;
	}
	return aRet;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
sal_uInt16 SwHiddenTxtField::GetSubType() const
{
	return nSubType;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool SwHiddenTxtField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
	const String* pOut = 0;
    switch( nWhichId )
	{
	case FIELD_PROP_PAR1:
		pOut = &aCond;
		break;
	case FIELD_PROP_PAR2:
		pOut = &aTRUETxt;
		break;
	case FIELD_PROP_PAR3:
		pOut = &aFALSETxt;
		break;
    case FIELD_PROP_PAR4 :
        pOut = &aContent;
    break;
    case FIELD_PROP_BOOL1:
		{
        	sal_Bool bHidden = bIsHidden;
        	rAny.setValue(&bHidden, ::getBooleanCppuType());
		}
		break;
	default:
		DBG_ERROR("illegal property");
	}
	if( pOut )
		rAny <<= OUString( *pOut );
	return sal_True;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool SwHiddenTxtField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
    switch( nWhichId )
	{
	case FIELD_PROP_PAR1:
		{
			String sVal;
			SetPar1(::GetString( rAny, sVal ));
		}
		break;
	case FIELD_PROP_PAR2:
		::GetString( rAny, aTRUETxt );
		break;
	case FIELD_PROP_PAR3:
		::GetString( rAny, aFALSETxt );
		break;
	case FIELD_PROP_BOOL1:
        bIsHidden = *(sal_Bool*)rAny.getValue();
		break;
    case FIELD_PROP_PAR4:
        ::GetString( rAny, aContent);
        bValid = sal_True;
    break;
    default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

//------------------------------------------------------------------------------

String SwHiddenTxtField::GetColumnName(const String& rName)
{
	sal_uInt16 nPos = rName.Search(DB_DELIM);
	if( STRING_NOTFOUND != nPos )
	{
		nPos = rName.Search(DB_DELIM, nPos + 1);

		if( STRING_NOTFOUND != nPos )
			return rName.Copy(nPos + 1);
	}
	return rName;
}

//------------------------------------------------------------------------------

String SwHiddenTxtField::GetDBName(const String& rName, SwDoc *pDoc)
{
	sal_uInt16 nPos = rName.Search(DB_DELIM);
	if( STRING_NOTFOUND != nPos )
	{
		nPos = rName.Search(DB_DELIM, nPos + 1);

		if( STRING_NOTFOUND != nPos )
			return rName.Copy( 0, nPos );
	}
	SwDBData aData = pDoc->GetDBData();
	String sRet = aData.sDataSource;
	sRet += DB_DELIM;
	sRet += String(aData.sCommand);
	return sRet;
}

/*--------------------------------------------------------------------
	Beschreibung: Der Feldtyp fuer Zeilenhoehe 0
 --------------------------------------------------------------------*/

SwHiddenParaFieldType::SwHiddenParaFieldType()
	: SwFieldType( RES_HIDDENPARAFLD )
{
}

SwFieldType* SwHiddenParaFieldType::Copy() const
{
	SwHiddenParaFieldType* pTyp = new SwHiddenParaFieldType();
	return pTyp;
}

/*--------------------------------------------------------------------
	Beschreibung: Das Feld Zeilenhoehe 0
 --------------------------------------------------------------------*/

SwHiddenParaField::SwHiddenParaField(SwHiddenParaFieldType* pTyp, const String& rStr)
	: SwField(pTyp), aCond(rStr)
{
	bIsHidden = sal_False;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwHiddenParaField::Expand() const
{
	return aEmptyStr;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwField* SwHiddenParaField::Copy() const
{
	SwHiddenParaField* pFld = new SwHiddenParaField((SwHiddenParaFieldType*)GetTyp(), aCond);
	pFld->bIsHidden = bIsHidden;

	return pFld;
}

sal_Bool SwHiddenParaField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
    switch ( nWhichId )
	{
	case FIELD_PROP_PAR1:
		rAny <<= OUString(aCond);
		break;
	case  FIELD_PROP_BOOL1:
		{
        	sal_Bool bHidden = bIsHidden;
        	rAny.setValue(&bHidden, ::getBooleanCppuType());
		}
		break;

	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

sal_Bool SwHiddenParaField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
    switch ( nWhichId )
	{
	case FIELD_PROP_PAR1:
		::GetString( rAny, aCond );
		break;
	case FIELD_PROP_BOOL1:
        bIsHidden = *(sal_Bool*)rAny.getValue();
		break;

	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

/*--------------------------------------------------------------------
	Beschreibung: Bedingung setzen
 --------------------------------------------------------------------*/

void SwHiddenParaField::SetPar1(const String& rStr)
{
	aCond = rStr;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
const String& SwHiddenParaField::GetPar1() const
{
	return aCond;
}

/*--------------------------------------------------------------------
	Beschreibung: PostIt
 --------------------------------------------------------------------*/

SwPostItFieldType::SwPostItFieldType(SwDoc *pDoc)
	: SwFieldType( RES_POSTITFLD ),mpDoc(pDoc)
{}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwFieldType* SwPostItFieldType::Copy() const
{
	return new SwPostItFieldType(mpDoc);
}


/*--------------------------------------------------------------------
	Beschreibung: SwPostItFieldType
 --------------------------------------------------------------------*/

SwPostItField::SwPostItField( SwPostItFieldType* pT,
		const String& rAuthor, const String& rTxt, const DateTime& rDateTime )
	: SwField( pT ), sTxt( rTxt ), sAuthor( rAuthor ), aDateTime( rDateTime ), mpText(0), m_pTextObject(0)
{
}


SwPostItField::~SwPostItField()
{
	if ( m_pTextObject )
	{
		m_pTextObject->DisposeEditSource();
		m_pTextObject->release();
	}
}

/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwPostItField::Expand() const
{
	return aEmptyStr;
}


String SwPostItField::GetDescription() const
{
    return SW_RES(STR_NOTE);
}

/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwField* SwPostItField::Copy() const
{
	SwPostItField* pRet = new SwPostItField( (SwPostItFieldType*)GetTyp(), sAuthor,
								sTxt, aDateTime);
	if (mpText)
		pRet->SetTextObject( new OutlinerParaObject(*mpText) );
	return pRet;
}
/*--------------------------------------------------------------------
	Beschreibung: Author setzen
 --------------------------------------------------------------------*/

void SwPostItField::SetPar1(const String& rStr)
{
	sAuthor = rStr;
}

const String& SwPostItField::GetPar1() const
{
	return sAuthor;
}

/*--------------------------------------------------------------------
	Beschreibung: Text fuers PostIt setzen
 --------------------------------------------------------------------*/

void SwPostItField::SetPar2(const String& rStr)
{
	sTxt = rStr;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwPostItField::GetPar2() const
{
		return sTxt;
}

const OutlinerParaObject* SwPostItField::GetTextObject() const
{
	return mpText;
}

void SwPostItField::SetTextObject( OutlinerParaObject* pText )
{
	delete mpText;
	mpText = pText;
}

sal_uInt32 SwPostItField::GetNumberOfParagraphs() const
{
    return (mpText) ? mpText->Count() : 1;
}

sal_Bool SwPostItField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
    switch( nWhichId )
	{
	case FIELD_PROP_PAR1:
		rAny <<= OUString(sAuthor);
		break;
	case FIELD_PROP_PAR2:
		{
		rAny <<= OUString(sTxt);
		break;
		}
	case FIELD_PROP_TEXT:
		{
			if ( !m_pTextObject )
			{
				SwPostItFieldType* pGetType = (SwPostItFieldType*)GetTyp();
				SwDoc* pDoc = pGetType->GetDoc();
				SwTextAPIEditSource* pObj = new SwTextAPIEditSource( pDoc );
				const_cast <SwPostItField*> (this)->m_pTextObject = new SwTextAPIObject( pObj );
				m_pTextObject->acquire();
			}

			if ( mpText )
				m_pTextObject->SetText( *mpText );
			else
				m_pTextObject->SetString( sTxt );

			uno::Reference < text::XText > xText( m_pTextObject );
			rAny <<= xText;
			break;
		}
	case FIELD_PROP_DATE:
		{
			util::Date aSetDate;
			aSetDate.Day = aDateTime.GetDay();
			aSetDate.Month = aDateTime.GetMonth();
			aSetDate.Year = aDateTime.GetYear();
			rAny.setValue(&aSetDate, ::getCppuType((util::Date*)0));
		}
		break;
	case FIELD_PROP_DATE_TIME:
		{
				util::DateTime DateTimeValue;
				DateTimeValue.HundredthSeconds = aDateTime.Get100Sec();
				DateTimeValue.Seconds = aDateTime.GetSec();
				DateTimeValue.Minutes = aDateTime.GetMin();
				DateTimeValue.Hours = aDateTime.GetHour();
				DateTimeValue.Day = aDateTime.GetDay();
				DateTimeValue.Month = aDateTime.GetMonth();
				DateTimeValue.Year = aDateTime.GetYear();
				rAny <<= DateTimeValue;
		}
		break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

sal_Bool SwPostItField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
    switch( nWhichId )
	{
	case FIELD_PROP_PAR1:
		::GetString( rAny, sAuthor );
		break;
	case FIELD_PROP_PAR2:
		::GetString( rAny, sTxt );
		//#i100374# new string via api, delete complex text object so SwPostItNote picks up the new string
		if (mpText)
		{
			delete mpText;
			mpText = 0;
		}
		break;
	case FIELD_PROP_TEXT:
		DBG_ERROR("Not implemented!");
		// ::GetString( rAny, sTxt );
		break;
	case FIELD_PROP_DATE:
		if( rAny.getValueType() == ::getCppuType((util::Date*)0) )
		{
			util::Date aSetDate = *(util::Date*)rAny.getValue();
			aDateTime = Date(aSetDate.Day, aSetDate.Month, aSetDate.Year);
		}
		break;
	case FIELD_PROP_DATE_TIME:
	{
		util::DateTime aDateTimeValue;
		if(!(rAny >>= aDateTimeValue))
			return sal_False;
		aDateTime.Set100Sec(aDateTimeValue.HundredthSeconds);
		aDateTime.SetSec(aDateTimeValue.Seconds);
		aDateTime.SetMin(aDateTimeValue.Minutes);
		aDateTime.SetHour(aDateTimeValue.Hours);
		aDateTime.SetDay(aDateTimeValue.Day);
		aDateTime.SetMonth(aDateTimeValue.Month);
		aDateTime.SetYear(aDateTimeValue.Year);
	}
	break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}
/*--------------------------------------------------------------------
	Beschreibung: DokumentinfoFields
 --------------------------------------------------------------------*/

SwExtUserFieldType::SwExtUserFieldType()
	: SwFieldType( RES_EXTUSERFLD )
{
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwFieldType* SwExtUserFieldType::Copy() const
{
	SwExtUserFieldType* pTyp = new SwExtUserFieldType;
	return pTyp;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwExtUserFieldType::Expand(sal_uInt16 nSub, sal_uInt32 ) const
{
    String aRet;
	sal_uInt16 nRet = USHRT_MAX;
	switch(nSub)
	{
    case EU_FIRSTNAME:      nRet = USER_OPT_FIRSTNAME; break;
    case EU_NAME:           nRet = USER_OPT_LASTNAME;  break;
    case EU_SHORTCUT:       nRet = USER_OPT_ID; break;

    case EU_COMPANY:        nRet = USER_OPT_COMPANY;        break;
    case EU_STREET:         nRet = USER_OPT_STREET;         break;
    case EU_TITLE:          nRet = USER_OPT_TITLE;          break;
    case EU_POSITION:       nRet = USER_OPT_POSITION;       break;
    case EU_PHONE_PRIVATE:  nRet = USER_OPT_TELEPHONEHOME;    break;
    case EU_PHONE_COMPANY:  nRet = USER_OPT_TELEPHONEWORK;    break;
    case EU_FAX:            nRet = USER_OPT_FAX;            break;
    case EU_EMAIL:          nRet = USER_OPT_EMAIL;          break;
    case EU_COUNTRY:        nRet = USER_OPT_COUNTRY;        break;
    case EU_ZIP:            nRet = USER_OPT_ZIP;            break;
    case EU_CITY:           nRet = USER_OPT_CITY;           break;
    case EU_STATE:          nRet = USER_OPT_STATE;          break;
    case EU_FATHERSNAME:    nRet = USER_OPT_FATHERSNAME;    break;
    case EU_APARTMENT:      nRet = USER_OPT_APARTMENT;      break;
	default:				ASSERT( !this, "Field unknown");
	}
	if( USHRT_MAX != nRet )
    {
        SvtUserOptions&  rUserOpt = SW_MOD()->GetUserOptions();
        aRet = rUserOpt.GetToken( nRet );
    }
	return aRet;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwExtUserField::SwExtUserField(SwExtUserFieldType* pTyp, sal_uInt16 nSubTyp, sal_uInt32 nFmt) :
	SwField(pTyp, nFmt), nType(nSubTyp)
{
	aContent = ((SwExtUserFieldType*)GetTyp())->Expand(nType, GetFormat());
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwExtUserField::Expand() const
{
	if (!IsFixed())
		((SwExtUserField*)this)->aContent = ((SwExtUserFieldType*)GetTyp())->Expand(nType, GetFormat());

	return aContent;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwField* SwExtUserField::Copy() const
{
	SwExtUserField* pFld = new SwExtUserField((SwExtUserFieldType*)GetTyp(), nType, GetFormat());
	pFld->SetExpansion(aContent);

	return pFld;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
sal_uInt16 SwExtUserField::GetSubType() const
{
	return nType;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
void SwExtUserField::SetSubType(sal_uInt16 nSub)
{
	nType = nSub;
}

sal_Bool SwExtUserField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
    switch( nWhichId )
	{
	case FIELD_PROP_PAR1:
		rAny <<= OUString(aContent);
		break;

	case FIELD_PROP_USHORT1:
		{
			sal_Int16 nTmp = nType;
			rAny <<= nTmp;
		}
		break;
	case FIELD_PROP_BOOL1:
		{
			sal_Bool bTmp = IsFixed();
			rAny.setValue(&bTmp, ::getBooleanCppuType());
		}
		break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

sal_Bool SwExtUserField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
    switch( nWhichId )
	{
	case FIELD_PROP_PAR1:
		::GetString( rAny, aContent );
		break;

	case FIELD_PROP_USHORT1:
		{
			sal_Int16 nTmp = 0;
			rAny >>= nTmp;
			nType = nTmp;
		}
		break;
	case FIELD_PROP_BOOL1:
		if( *(sal_Bool*)rAny.getValue() )
			SetFormat(GetFormat() | AF_FIXED);
		else
			SetFormat(GetFormat() & ~AF_FIXED);
		break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}
//-------------------------------------------------------------------------

/*--------------------------------------------------------------------
	Beschreibung: Relatives Seitennummern - Feld
 --------------------------------------------------------------------*/

SwRefPageSetFieldType::SwRefPageSetFieldType()
	: SwFieldType( RES_REFPAGESETFLD )
{
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwFieldType* SwRefPageSetFieldType::Copy() const
{
	return new SwRefPageSetFieldType;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
// ueberlagert, weil es nichts zum Updaten gibt!
void SwRefPageSetFieldType::Modify( const SfxPoolItem*, const SfxPoolItem * )
{
}

/*--------------------------------------------------------------------
	Beschreibung: Relative Seitennummerierung
 --------------------------------------------------------------------*/

SwRefPageSetField::SwRefPageSetField( SwRefPageSetFieldType* pTyp,
					short nOff, sal_Bool bFlag )
	: SwField( pTyp ), nOffset( nOff ), bOn( bFlag )
{
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwRefPageSetField::Expand() const
{
	return aEmptyStr;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwField* SwRefPageSetField::Copy() const
{
	return new SwRefPageSetField( (SwRefPageSetFieldType*)GetTyp(), nOffset, bOn );
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwRefPageSetField::GetPar2() const
{
	return String::CreateFromInt32( GetOffset() );
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
void SwRefPageSetField::SetPar2(const String& rStr)
{
	SetOffset( (short) rStr.ToInt32() );
}

sal_Bool SwRefPageSetField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
    switch( nWhichId )
	{
	case FIELD_PROP_BOOL1:
		rAny.setValue(&bOn, ::getBooleanCppuType());
		break;
	case FIELD_PROP_USHORT1:
		rAny <<= (sal_Int16)nOffset;
		break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

sal_Bool SwRefPageSetField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
    switch( nWhichId )
	{
	case FIELD_PROP_BOOL1:
		bOn = *(sal_Bool*)rAny.getValue();
		break;
	case FIELD_PROP_USHORT1:
		rAny >>=nOffset;
		break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}
/*--------------------------------------------------------------------
	Beschreibung: relatives Seitennummern - Abfrage Feld
 --------------------------------------------------------------------*/

SwRefPageGetFieldType::SwRefPageGetFieldType( SwDoc* pDc )
	: SwFieldType( RES_REFPAGEGETFLD ), pDoc( pDc ), nNumberingType( SVX_NUM_ARABIC )
{
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwFieldType* SwRefPageGetFieldType::Copy() const
{
	SwRefPageGetFieldType* pNew = new SwRefPageGetFieldType( pDoc );
	pNew->nNumberingType = nNumberingType;
	return pNew;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
void SwRefPageGetFieldType::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
{
	// Update auf alle GetReferenz-Felder
	if( !pNew && !pOld && GetDepends() )
	{
		// sammel erstmal alle SetPageRefFelder ein.
		_SetGetExpFlds aTmpLst( 10, 5 );
		if( MakeSetList( aTmpLst ) )
		{
			SwIterator<SwFmtFld,SwFieldType> aIter( *this );
            for ( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
					// nur die GetRef-Felder Updaten
					if( pFmtFld->GetTxtFld() )
						UpdateField( pFmtFld->GetTxtFld(), aTmpLst );
		}
	}

	// weiter an die Text-Felder, diese "Expandieren" den Text
	NotifyClients( pOld, pNew );
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
sal_uInt16 SwRefPageGetFieldType::MakeSetList( _SetGetExpFlds& rTmpLst )
{
	SwIterator<SwFmtFld,SwFieldType> aIter(*pDoc->GetSysFldType( RES_REFPAGESETFLD));
    for ( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
    {
			// nur die GetRef-Felder Updaten
			const SwTxtFld* pTFld = pFmtFld->GetTxtFld();
			if( pTFld )
			{
				const SwTxtNode& rTxtNd = pTFld->GetTxtNode();

				// immer den ersten !! (in Tab-Headline, Kopf-/Fuss )
				Point aPt;
				const SwCntntFrm* pFrm = rTxtNd.getLayoutFrm( rTxtNd.GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False );

				_SetGetExpFld* pNew;

                if( !pFrm ||
                     pFrm->IsInDocBody() ||
                    // --> FME 2004-07-27 #i31868#
                    // Check if pFrm is not yet connected to the layout.
                    !pFrm->FindPageFrm() )
                    // <--
                {
					// einen sdbcx::Index fuers bestimmen vom TextNode anlegen
					SwNodeIndex aIdx( rTxtNd );
					pNew = new _SetGetExpFld( aIdx, pTFld );
				}
				else
				{
					// einen sdbcx::Index fuers bestimmen vom TextNode anlegen
					SwPosition aPos( pDoc->GetNodes().GetEndOfPostIts() );
#ifdef DBG_UTIL
					ASSERT( GetBodyTxtNode( *pDoc, aPos, *pFrm ),
							"wo steht das Feld" );
#else
					GetBodyTxtNode( *pDoc, aPos, *pFrm );
#endif
					pNew = new _SetGetExpFld( aPos.nNode, pTFld,
												&aPos.nContent );
				}

				if( !rTmpLst.Insert( pNew ))
					delete pNew;
			}
	}

	return rTmpLst.Count();
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
void SwRefPageGetFieldType::UpdateField( SwTxtFld* pTxtFld,
										_SetGetExpFlds& rSetList )
{
	SwRefPageGetField* pGetFld = (SwRefPageGetField*)pTxtFld->GetFld().GetFld();
	pGetFld->SetText( aEmptyStr );

	// dann suche mal das richtige RefPageSet-Field
	SwTxtNode* pTxtNode = (SwTxtNode*)&pTxtFld->GetTxtNode();
	if( pTxtNode->StartOfSectionIndex() >
		pDoc->GetNodes().GetEndOfExtras().GetIndex() )
	{
		SwNodeIndex aIdx( *pTxtNode );
		_SetGetExpFld aEndFld( aIdx, pTxtFld );

		sal_uInt16 nLast;
		rSetList.Seek_Entry( &aEndFld, &nLast );

		if( nLast-- )
		{
			const SwTxtFld* pRefTxtFld = rSetList[ nLast ]->GetFld();
			const SwRefPageSetField* pSetFld =
						(SwRefPageSetField*)pRefTxtFld->GetFld().GetFld();
			if( pSetFld->IsOn() )
			{
				// dann bestimme mal den entsp. Offset
				Point aPt;
				const SwCntntFrm* pFrm = pTxtNode->getLayoutFrm( pTxtNode->GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False );
				const SwCntntFrm* pRefFrm = pRefTxtFld->GetTxtNode().getLayoutFrm( pRefTxtFld->GetTxtNode().GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False );
				const SwPageFrm* pPgFrm = 0;
				sal_uInt16 nDiff = ( pFrm && pRefFrm )
						? 	(pPgFrm = pFrm->FindPageFrm())->GetPhyPageNum() -
							pRefFrm->FindPageFrm()->GetPhyPageNum() + 1
						: 1;

				sal_uInt32 nTmpFmt = SVX_NUM_PAGEDESC == pGetFld->GetFormat()
						? ( !pPgFrm
								? (sal_uInt32)SVX_NUM_ARABIC
								: pPgFrm->GetPageDesc()->GetNumType().GetNumberingType() )
						: pGetFld->GetFormat();
				short nPageNum = static_cast<short>(Max(0, pSetFld->GetOffset() + (short)nDiff));
				pGetFld->SetText( FormatNumber( nPageNum, nTmpFmt ) );
			}
		}
	}
	// dann die Formatierung anstossen
	((SwFmtFld&)pTxtFld->GetFld()).ModifyNotification( 0, 0 );
}

/*--------------------------------------------------------------------
	Beschreibung: Relative Seitennummerierung Abfragen
 --------------------------------------------------------------------*/

SwRefPageGetField::SwRefPageGetField( SwRefPageGetFieldType* pTyp,
									sal_uInt32 nFmt )
	: SwField( pTyp, nFmt )
{
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwRefPageGetField::Expand() const
{
	return sTxt;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwField* SwRefPageGetField::Copy() const
{
	SwRefPageGetField* pCpy = new SwRefPageGetField(
						(SwRefPageGetFieldType*)GetTyp(), GetFormat() );
	pCpy->SetText( sTxt );
	return pCpy;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
void SwRefPageGetField::ChangeExpansion( const SwFrm* pFrm,
										const SwTxtFld* pFld )
{
	// nur Felder in Footer, Header, FootNote, Flys
	SwTxtNode* pTxtNode = (SwTxtNode*)&pFld->GetTxtNode();
	SwRefPageGetFieldType* pGetType = (SwRefPageGetFieldType*)GetTyp();
	SwDoc* pDoc = pGetType->GetDoc();
	if( pFld->GetTxtNode().StartOfSectionIndex() >
		pDoc->GetNodes().GetEndOfExtras().GetIndex() )
		return;

	sTxt.Erase();

	ASSERT( !pFrm->IsInDocBody(), "Flag ist nicht richtig, Frame steht im DocBody" );

	// sammel erstmal alle SetPageRefFelder ein.
	_SetGetExpFlds aTmpLst( 10, 5 );
	if( !pGetType->MakeSetList( aTmpLst ) )
		return ;

	// einen sdbcx::Index fuers bestimmen vom TextNode anlegen
	SwPosition aPos( SwNodeIndex( pDoc->GetNodes() ) );
	pTxtNode = (SwTxtNode*) GetBodyTxtNode( *pDoc, aPos, *pFrm );

	// Wenn kein Layout vorhanden, kommt es in Kopf und Fusszeilen dazu
	// das ChangeExpansion uebers Layout-Formatieren aufgerufen wird
	// aber kein TxtNode vorhanden ist
	//
	if(!pTxtNode)
		return;

	_SetGetExpFld aEndFld( aPos.nNode, pFld, &aPos.nContent );

	sal_uInt16 nLast;
	aTmpLst.Seek_Entry( &aEndFld, &nLast );

	if( !nLast-- )
		return ;		// es gibt kein entsprechendes Set - Feld vor mir

	const SwTxtFld* pRefTxtFld = aTmpLst[ nLast ]->GetFld();
	const SwRefPageSetField* pSetFld =
						(SwRefPageSetField*)pRefTxtFld->GetFld().GetFld();
    Point aPt;
    const SwCntntFrm* pRefFrm = pRefTxtFld ? pRefTxtFld->GetTxtNode().getLayoutFrm( pFrm->getRootFrm(), &aPt, 0, sal_False ) : 0;
    if( pSetFld->IsOn() && pRefFrm )
	{
		// dann bestimme mal den entsp. Offset
        const SwPageFrm* pPgFrm = pFrm->FindPageFrm();
		sal_uInt16 nDiff = pPgFrm->GetPhyPageNum() -
							pRefFrm->FindPageFrm()->GetPhyPageNum() + 1;

		SwRefPageGetField* pGetFld = (SwRefPageGetField*)pFld->GetFld().GetFld();
		sal_uInt32 nTmpFmt = SVX_NUM_PAGEDESC == pGetFld->GetFormat()
							? pPgFrm->GetPageDesc()->GetNumType().GetNumberingType()
							: pGetFld->GetFormat();
		short nPageNum = static_cast<short>(Max(0, pSetFld->GetOffset() + (short)nDiff ));
		pGetFld->SetText( FormatNumber( nPageNum, nTmpFmt ) );
	}
}

sal_Bool SwRefPageGetField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
    switch( nWhichId )
	{
        case FIELD_PROP_USHORT1:
            rAny <<= (sal_Int16)GetFormat();
        break;
        case FIELD_PROP_PAR1:
            rAny <<= OUString(sTxt);
        break;
        default:
            DBG_ERROR("illegal property");
	}
	return sal_True;
}

sal_Bool SwRefPageGetField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
    switch( nWhichId )
	{
        case FIELD_PROP_USHORT1:
		{
			sal_Int16 nSet = 0;
			rAny >>= nSet;
			if(nSet <= SVX_NUM_PAGEDESC )
				SetFormat(nSet);
			else {
				//exception(wrong_value)
				;
            }
		}
		break;
        case FIELD_PROP_PAR1:
        {
            OUString sTmp;
            rAny >>= sTmp;
            sTxt = sTmp;
        }
        break;
    default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

/*--------------------------------------------------------------------
	Beschreibung: Feld zum Anspringen und Editieren
 --------------------------------------------------------------------*/

SwJumpEditFieldType::SwJumpEditFieldType( SwDoc* pD )
	: SwFieldType( RES_JUMPEDITFLD ), pDoc( pD ), aDep( this, 0 )
{
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwFieldType* SwJumpEditFieldType::Copy() const
{
	return new SwJumpEditFieldType( pDoc );
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwCharFmt* SwJumpEditFieldType::GetCharFmt()
{
	SwCharFmt* pFmt = pDoc->GetCharFmtFromPool( RES_POOLCHR_JUMPEDIT );

	// noch nicht registriert ?
	if( !aDep.GetRegisteredIn() )
		pFmt->Add( &aDep );		// anmelden

	return pFmt;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwJumpEditField::SwJumpEditField( SwJumpEditFieldType* pTyp, sal_uInt32 nForm,
								const String& rTxt, const String& rHelp )
	: SwField( pTyp, nForm ), sTxt( rTxt ), sHelp( rHelp )
{
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwJumpEditField::Expand() const
{
	String sTmp( '<' );
	sTmp += sTxt;
	return sTmp += '>';
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SwField* SwJumpEditField::Copy() const
{
	return new SwJumpEditField( (SwJumpEditFieldType*)GetTyp(), GetFormat(),
								sTxt, sHelp );
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
// Platzhalter-Text

const String& SwJumpEditField::GetPar1() const
{
	return sTxt;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
void SwJumpEditField::SetPar1(const String& rStr)
{
	sTxt = rStr;
}

// HinweisText
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
String SwJumpEditField::GetPar2() const
{
	return sHelp;
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
void SwJumpEditField::SetPar2(const String& rStr)
{
	sHelp = rStr;
}

sal_Bool SwJumpEditField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
{
    switch( nWhichId )
	{
	case FIELD_PROP_USHORT1:
		{
			sal_Int16 nRet;
			switch( GetFormat() )
			{
			case JE_FMT_TABLE:  nRet = text::PlaceholderType::TABLE; break;
			case JE_FMT_FRAME:  nRet = text::PlaceholderType::TEXTFRAME; break;
			case JE_FMT_GRAPHIC:nRet = text::PlaceholderType::GRAPHIC; break;
			case JE_FMT_OLE:	nRet = text::PlaceholderType::OBJECT; break;
//			case JE_FMT_TEXT:
			default:
				nRet = text::PlaceholderType::TEXT; break;
			}
			rAny <<= nRet;
		}
		break;
	case FIELD_PROP_PAR1 :
		rAny <<= OUString(sHelp);
		break;
	case FIELD_PROP_PAR2 :
		 rAny <<= OUString(sTxt);
		 break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

sal_Bool SwJumpEditField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
{
    switch( nWhichId )
	{
	case FIELD_PROP_USHORT1:
		{
			//JP 24.10.2001: int32 because in UnoField.cxx a putvalue is
			//				called with a int32 value! But normally we need
			//				here only a int16
			sal_Int32 nSet = 0;
			rAny >>= nSet;
			switch( nSet )
			{
				case text::PlaceholderType::TEXT 	 : SetFormat(JE_FMT_TEXT); break;
				case text::PlaceholderType::TABLE 	 : SetFormat(JE_FMT_TABLE); break;
				case text::PlaceholderType::TEXTFRAME: SetFormat(JE_FMT_FRAME); break;
				case text::PlaceholderType::GRAPHIC  : SetFormat(JE_FMT_GRAPHIC); break;
				case text::PlaceholderType::OBJECT 	 : SetFormat(JE_FMT_OLE); break;
			}
		}
		break;
	case FIELD_PROP_PAR1 :
		::GetString( rAny, sHelp );
		break;
	case FIELD_PROP_PAR2 :
		 ::GetString( rAny, sTxt);
		 break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}


/*--------------------------------------------------------------------
	Beschreibung: Combined Character Fieldtype / Field
 --------------------------------------------------------------------*/

SwCombinedCharFieldType::SwCombinedCharFieldType()
	: SwFieldType( RES_COMBINED_CHARS )
{
}

SwFieldType* SwCombinedCharFieldType::Copy() const
{
	return new SwCombinedCharFieldType;
}

/* --------------------------------------------------------------------*/

SwCombinedCharField::SwCombinedCharField( SwCombinedCharFieldType* pFTyp,
											const String& rChars )
	: SwField( pFTyp, 0 ),
	sCharacters( rChars.Copy( 0, MAX_COMBINED_CHARACTERS ))
{
}

String	SwCombinedCharField::Expand() const
{
	return sCharacters;
}

SwField* SwCombinedCharField::Copy() const
{
	return new SwCombinedCharField( (SwCombinedCharFieldType*)GetTyp(),
										sCharacters );
}

const String& SwCombinedCharField::GetPar1() const
{
	return sCharacters;
}

void SwCombinedCharField::SetPar1(const String& rStr)
{
	sCharacters = rStr.Copy( 0, MAX_COMBINED_CHARACTERS );
}

sal_Bool SwCombinedCharField::QueryValue( uno::Any& rAny,
                                        sal_uInt16 nWhichId ) const
{
    switch( nWhichId )
	{
	case FIELD_PROP_PAR1:
		rAny <<= rtl::OUString( sCharacters );
		break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

sal_Bool SwCombinedCharField::PutValue( const uno::Any& rAny,
                                        sal_uInt16 nWhichId )
{
    switch( nWhichId )
	{
	case FIELD_PROP_PAR1:
		::GetString( rAny, sCharacters ).Erase( MAX_COMBINED_CHARACTERS );
		break;
	default:
		DBG_ERROR("illegal property");
	}
	return sal_True;
}

