/**************************************************************
 * 
 * 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
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



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


#include <vcl/svapp.hxx>
#include <flddat.hxx>
#include <docufld.hxx>
#ifndef _GLOBALS_HRC
#include <globals.hrc>
#endif
#include <chpfld.hxx>
#ifndef _FLDTDLG_HRC
#include <fldtdlg.hrc>
#endif
#ifndef _FLDUI_HRC
#include <fldui.hrc>
#endif
#ifndef _FLDDOK_HXX
#include <flddok.hxx>
#endif
#include <swmodule.hxx>
#ifndef _VIEW_HXX
#include <view.hxx>
#endif
#include <wrtsh.hxx>
#include <svl/zformat.hxx>

#include <index.hrc>

#define USER_DATA_VERSION_1 "1"
#define USER_DATA_VERSION USER_DATA_VERSION_1

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

SwFldDokPage::SwFldDokPage(Window* pWindow, const SfxItemSet& rCoreSet ) :
	SwFldPage( pWindow, SW_RES( TP_FLD_DOK ), rCoreSet ),

	aTypeFT			(this, SW_RES(FT_DOKTYPE)),
	aTypeLB			(this, SW_RES(LB_DOKTYPE)),
	aSelectionFT	(this, SW_RES(FT_DOKSELECTION)),
	aSelectionLB	(this, SW_RES(LB_DOKSELECTION)),
	aValueFT		(this, SW_RES(FT_DOKVALUE)),
	aValueED		(this, SW_RES(ED_DOKVALUE)),
	aLevelED		(this, SW_RES(ED_DOKLEVEL)),
	aDateOffsetED   (this, SW_RES(ED_DOKDATEOFF)),

	aFormatFT		(this, SW_RES(FT_DOKFORMAT)),
	aFormatLB		(this, SW_RES(LB_DOKFORMAT)),
	aNumFormatLB	(this, SW_RES(LB_DOKNUMFORMAT)),
	aFixedCB		(this, SW_RES(CB_DOKFIXEDCONTENT)),

	sDateOffset		(SW_RES(STR_DOKDATEOFF)),
	sTimeOffset		(SW_RES(STR_DOKTIMEOFF)),
	aRootOpened		(SW_RES(BMP_DOKROOT_OPENED)),
	aRootClosed		(SW_RES(BMP_DOKROOT_CLOSED))
{
	FreeResource();

	aSelectionLB.SetDoubleClickHdl(LINK(this, SwFldDokPage, InsertHdl));
	aFormatLB.SetDoubleClickHdl(LINK(this, SwFldDokPage, InsertHdl));
	aNumFormatLB.SetDoubleClickHdl(LINK(this, SwFldDokPage, NumFormatHdl));

	aLevelED.SetMax(MAXLEVEL);
	aDateOffsetED.SetMin(LONG_MIN);
	aDateOffsetED.SetMax(LONG_MAX);
    //enable 'active' language selection
    aNumFormatLB.SetShowLanguageControl(sal_True);
}

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

__EXPORT SwFldDokPage::~SwFldDokPage()
{
}

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

void __EXPORT SwFldDokPage::Reset(const SfxItemSet& )
{
	SavePos(&aTypeLB);
	Init();	// Allgemeine initialisierung

	// TypeListBox initialisieren
	const SwFldGroupRgn& rRg = GetFldMgr().GetGroupRange(IsFldDlgHtmlMode(), GetGroup());

	aTypeLB.SetUpdateMode(sal_False);
	aTypeLB.Clear();

	sal_uInt16 nPos, nTypeId;
	sal_Bool bPage = sal_False;

	if (!IsFldEdit())
	{
		// Typ-Listbox fuellen
		for(short i = rRg.nStart; i < rRg.nEnd; ++i)
		{
			nTypeId = GetFldMgr().GetTypeId(i);

			switch (nTypeId)
			{
				case TYP_PREVPAGEFLD:
				case TYP_NEXTPAGEFLD:
				case TYP_PAGENUMBERFLD:
					if (!bPage)
					{
						nPos = aTypeLB.InsertEntry(SW_RESSTR(FMT_REF_PAGE));
						aTypeLB.SetEntryData(nPos, (void*)USHRT_MAX);
						bPage = sal_True;
					}
					break;

				default:
					nPos = aTypeLB.InsertEntry(GetFldMgr().GetTypeStr(i));
                    aTypeLB.SetEntryData(nPos, reinterpret_cast<void*>(nTypeId));
					break;
			}
		}
	}
	else
	{
		const SwField* pCurField = GetCurField();
		nTypeId = pCurField->GetTypeId();
		if (nTypeId == TYP_FIXDATEFLD)
			nTypeId = TYP_DATEFLD;
		if (nTypeId == TYP_FIXTIMEFLD)
			nTypeId = TYP_TIMEFLD;
		nPos = aTypeLB.InsertEntry(GetFldMgr().GetTypeStr(GetFldMgr().GetPos(nTypeId)));
        aTypeLB.SetEntryData(nPos, reinterpret_cast<void*>(nTypeId));
		aNumFormatLB.SetAutomaticLanguage(pCurField->IsAutomaticLanguage());
        SwWrtShell *pSh = GetWrtShell();
        if(!pSh)
            pSh = ::GetActiveWrtShell();
        if(pSh)
        {
            const SvNumberformat* pFormat = pSh->GetNumberFormatter()->GetEntry(pCurField->GetFormat());
            if(pFormat)
                aNumFormatLB.SetLanguage(pFormat->GetLanguage());
        }
	}

	// alte Pos selektieren
	RestorePos(&aTypeLB);

	aTypeLB.SetUpdateMode(sal_True);
	aTypeLB.SetDoubleClickHdl(LINK(this, SwFldDokPage, InsertHdl));
	aTypeLB.SetSelectHdl(LINK(this, SwFldDokPage, TypeHdl));
	aFormatLB.SetSelectHdl(LINK(this, SwFldDokPage, FormatHdl));

	if( !IsRefresh() )
	{
		String sUserData = GetUserData();
		if( sUserData.GetToken(0, ';').EqualsIgnoreCaseAscii(USER_DATA_VERSION_1 ))
		{
			String sVal = sUserData.GetToken(1, ';');
            sal_uInt16 nVal = static_cast< sal_uInt16 >(sVal.ToInt32());
			if(nVal != USHRT_MAX)
			{
				for(sal_uInt16 i = 0; i < aTypeLB.GetEntryCount(); i++)
					if(nVal == (sal_uInt16)(sal_uLong)aTypeLB.GetEntryData(i))
					{
						aTypeLB.SelectEntryPos(i);
						break;
					}
			}
		}
	}
	TypeHdl(0);

	if (IsFldEdit())
	{
		nOldSel = aSelectionLB.GetSelectEntryPos();
		nOldFormat = GetCurField()->GetFormat();
		aFixedCB.SaveValue();
		aValueED.SaveValue();
		aLevelED.SaveValue();
		aDateOffsetED.SaveValue();
	}
}

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

IMPL_LINK( SwFldDokPage, TypeHdl, ListBox *, EMPTYARG )
{
	// Alte ListBoxPos sichern
	const sal_uInt16 nOld = GetTypeSel();

	// Aktuelle ListBoxPos
	SetTypeSel(aTypeLB.GetSelectEntryPos());

	if(GetTypeSel() == LISTBOX_ENTRY_NOTFOUND)
	{
		SetTypeSel(0);
		aTypeLB.SelectEntryPos(0);
	}

	sal_uInt16 nCount;

	if (nOld != GetTypeSel())
	{
		sal_uInt16 nTypeId = (sal_uInt16)(sal_uLong)aTypeLB.GetEntryData(GetTypeSel());

		// Auswahl-Listbox fuellen
		aSelectionLB.Clear();

		if (nTypeId != USHRT_MAX)
		{
            SvStringsDtor aLst;
            GetFldMgr().GetSubTypes(nTypeId, aLst);

			if (nTypeId != TYP_AUTHORFLD)
                nCount = aLst.Count();
			else
				nCount = GetFldMgr().GetFormatCount(nTypeId, sal_False, IsFldDlgHtmlMode());

			sal_uInt16 nPos;

			for (sal_uInt16 i = 0; i < nCount; ++i)
			{
				if (!IsFldEdit())
				{
					if (nTypeId != TYP_AUTHORFLD)
                        nPos = aSelectionLB.InsertEntry(*aLst[i]);
					else
						nPos = aSelectionLB.InsertEntry(GetFldMgr().GetFormatStr(nTypeId, i));

                    aSelectionLB.SetEntryData(nPos, reinterpret_cast<void*>(i));
				}
				else
				{
					sal_Bool bInsert = sal_False;

					switch (nTypeId)
					{
						case TYP_DATEFLD:
						case TYP_TIMEFLD:
                            nPos = aSelectionLB.InsertEntry(*aLst[i]);
                            aSelectionLB.SetEntryData(nPos, reinterpret_cast<void*>(i));
							if (((SwDateTimeField*)GetCurField())->IsFixed() && !i)
								aSelectionLB.SelectEntryPos(nPos);
							if (!((SwDateTimeField*)GetCurField())->IsFixed() && i)
								aSelectionLB.SelectEntryPos(nPos);
							break;

						case TYP_EXTUSERFLD:
						case TYP_DOCSTATFLD:
                            nPos = aSelectionLB.InsertEntry(*aLst[i]);
                            aSelectionLB.SetEntryData(nPos, reinterpret_cast<void*>(i));
							if (GetCurField()->GetSubType() == i)
								aSelectionLB.SelectEntryPos(nPos);
							break;

						case TYP_AUTHORFLD:
						{
							String sFmt(GetFldMgr().GetFormatStr(nTypeId, i));
							nPos = aSelectionLB.InsertEntry(sFmt);
                            aSelectionLB.SetEntryData(nPos, reinterpret_cast<void*>(i));
							aSelectionLB.SelectEntry(GetFldMgr().GetFormatStr(nTypeId, GetCurField()->GetFormat()));
							break;
						}

						default:
                            if (*aLst[i] == GetCurField()->GetPar1())
								bInsert = sal_True;
							break;
					}
					if (bInsert)
					{
                        nPos = aSelectionLB.InsertEntry(*aLst[i]);
                        aSelectionLB.SetEntryData(nPos, reinterpret_cast<void*>(i));
						break;
					}
				}
			}
			aSelectionLB.SetSelectHdl(Link());
		}
		else
		{
			AddSubType(TYP_PAGENUMBERFLD);
			AddSubType(TYP_PREVPAGEFLD);
			AddSubType(TYP_NEXTPAGEFLD);
			nTypeId = (sal_uInt16)(sal_uLong)aSelectionLB.GetEntryData(0);
			nCount = 3;
			aSelectionLB.SetSelectHdl(LINK(this, SwFldDokPage, SubTypeHdl));
		}

		sal_Bool bEnable = nCount != 0;

		if (bEnable && !aSelectionLB.GetSelectEntryCount())
			aSelectionLB.SelectEntryPos(0);

		aSelectionLB.Enable( bEnable );
		aSelectionFT.Enable( bEnable );

		// Format-Listbox fuellen
		sal_uInt16 nSize = FillFormatLB(nTypeId);

		sal_Bool bValue = sal_False, bLevel = sal_False, bNumFmt = sal_False, bOffset = sal_False;
		sal_Bool bFormat = nSize != 0;
		sal_Bool bOneArea = sal_False;
		sal_Bool bFixed = sal_False;
		sal_uInt16 nFmtType = 0;

		switch (nTypeId)
		{
			case TYP_DATEFLD:
				bFormat = bNumFmt = bOneArea = bOffset = sal_True;

				nFmtType = NUMBERFORMAT_DATE;
				aValueFT.SetText(sDateOffset);
				aDateOffsetED.SetFirst(-31);	// Ein Monat
				aDateOffsetED.SetLast(31);

				if (IsFldEdit())
					aDateOffsetED.SetValue( ((SwDateTimeField*)GetCurField())->GetOffset() / 24 / 60);
				break;

			case TYP_TIMEFLD:
				bFormat = bNumFmt = bOneArea = bOffset = sal_True;

				nFmtType = NUMBERFORMAT_TIME;
				aValueFT.SetText(sTimeOffset);
				aDateOffsetED.SetFirst(-1440);	// Ein Tag
				aDateOffsetED.SetLast(1440);

				if (IsFldEdit())
					aDateOffsetED.SetValue( ((SwDateTimeField*)GetCurField())->GetOffset() );
				break;

			case TYP_PREVPAGEFLD:
			case TYP_NEXTPAGEFLD:
				if (IsFldEdit())
				{
					sal_uInt16 nTmp = (sal_uInt16)(sal_uLong)aFormatLB.GetEntryData(
											aFormatLB.GetSelectEntryPos() );
					String sOldTxt(aValueFT.GetText());

                    if(SVX_NUM_CHAR_SPECIAL != nTmp)
					{
                        sal_Int32 nOff = GetCurField()->GetPar2().ToInt32();
						if( TYP_NEXTPAGEFLD == nTypeId && 1 != nOff )
							aValueED.SetText(
                                String::CreateFromInt32(nOff - 1) );
						else if( TYP_PREVPAGEFLD == nTypeId && -1 != nOff )
							aValueED.SetText(
                                String::CreateFromInt32(nOff + 1) );
						else
							aValueED.SetText(aEmptyStr);
					}
					else
						aValueED.SetText(((SwPageNumberField*)GetCurField())->GetUserString());
				}
				bValue = sal_True;
				break;

			case TYP_CHAPTERFLD:
				aValueFT.SetText(SW_RESSTR(STR_LEVEL));
				if (IsFldEdit())
					aLevelED.SetText(String::CreateFromInt32(((SwChapterField*)GetCurField())->GetLevel() + 1));
				bLevel = sal_True;
				break;

			case TYP_PAGENUMBERFLD:
				aValueFT.SetText( SW_RESSTR( STR_OFFSET ));
				if (IsFldEdit())
					aValueED.SetText(GetCurField()->GetPar2());
				bValue = sal_True;
				break;

			case TYP_EXTUSERFLD:
			case TYP_AUTHORFLD:
			case TYP_FILENAMEFLD:
				bFixed = sal_True;
				break;

			default:
				break;
		}

		if (bNumFmt)
		{
			if (IsFldEdit())
			{
				aNumFormatLB.SetDefFormat(GetCurField()->GetFormat());

				if (aNumFormatLB.GetFormatType() == (NUMBERFORMAT_DATE|NUMBERFORMAT_TIME))
				{
					// Format-Typ immer einstellen, da sonst bei kombinierten Datum/Zeitformaten
					// beide Formate gleichzeitig angezeigt werden wuerden
					aNumFormatLB.SetFormatType(0);
					aNumFormatLB.SetFormatType(nFmtType);
					// Nochmal richtiges Format einstellen
					aNumFormatLB.SetDefFormat(GetCurField()->GetFormat());
				}
			}
			else
				aNumFormatLB.SetFormatType(nFmtType);

			aNumFormatLB.SetOneArea(bOneArea);
		}

		aFormatLB.Show(!bNumFmt);
		aNumFormatLB.Show(bNumFmt);

		Size aSz(aFormatLB.GetSizePixel());

		if (bValue | bLevel | bOffset)
			aSz.Height() = aFormatLB.LogicToPixel(Size(1, 137), MAP_APPFONT).Height();
		else
			aSz.Height() = aFormatLB.LogicToPixel(Size(1, 152), MAP_APPFONT).Height();

		aValueFT.Show(bValue | bLevel | bOffset);
		aValueED.Show(bValue);
		aLevelED.Show(bLevel);
		aDateOffsetED.Show(bOffset);
		aFixedCB.Show(!bValue && !bLevel && !bOffset);

		aFormatLB.SetSizePixel(aSz);
		aNumFormatLB.SetSizePixel(aSz);

		aFormatLB.Enable(bFormat);
		aFormatFT.Enable(bFormat);
		aFixedCB.Enable(bFixed);

		if (IsFldEdit())
            aFixedCB.Check( static_cast< sal_Bool >(((GetCurField()->GetFormat() & AF_FIXED) != 0) & bFixed));

		if (aNumFormatLB.GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND)
			aNumFormatLB.SelectEntryPos(0);
		aValueFT.Enable(bValue | bLevel | bOffset);
		aValueED.Enable(bValue);
	}

	return 0;
}

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

void SwFldDokPage::AddSubType(sal_uInt16 nTypeId)
{
	sal_uInt16 nPos = aSelectionLB.InsertEntry(SwFieldType::GetTypeStr(nTypeId));
    aSelectionLB.SetEntryData(nPos, reinterpret_cast<void*>(nTypeId));
}

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

IMPL_LINK( SwFldDokPage, SubTypeHdl, ListBox *, EMPTYARG )
{
	sal_uInt16 nPos = aSelectionLB.GetSelectEntryPos();
	if(nPos == LISTBOX_ENTRY_NOTFOUND)
		nPos = 0;

	sal_uInt16 nTypeId = (sal_uInt16)(sal_uLong)aSelectionLB.GetEntryData(nPos);
	FillFormatLB(nTypeId);

	sal_uInt16 nTextRes = 0;
	switch (nTypeId)
	{
	case TYP_CHAPTERFLD:
		nTextRes = STR_LEVEL;
		break;

	case TYP_PREVPAGEFLD:
	case TYP_NEXTPAGEFLD:
		nTextRes = SVX_NUM_CHAR_SPECIAL == (sal_uInt16)(sal_uLong)aFormatLB.GetEntryData(
										aFormatLB.GetSelectEntryPos() )
						? STR_VALUE : STR_OFFSET;
		break;

	case TYP_PAGENUMBERFLD:
		nTextRes = STR_OFFSET;
		break;
	}

	if( nTextRes )
		aValueFT.SetText( SW_RESSTR( nTextRes ));

	return 0;
}

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

sal_uInt16 SwFldDokPage::FillFormatLB(sal_uInt16 nTypeId)
{
	// Format-Listbox fuellen
	aFormatLB.Clear();

	if (nTypeId == TYP_AUTHORFLD)
		return aFormatLB.GetEntryCount();

	sal_uInt16 nSize = GetFldMgr().GetFormatCount(nTypeId, sal_False, IsFldDlgHtmlMode());

	for( sal_uInt16 i = 0; i < nSize; ++i )
	{
		sal_uInt16 nPos = aFormatLB.InsertEntry(GetFldMgr().GetFormatStr(nTypeId, i));
		sal_uInt16 nFmtId = GetFldMgr().GetFormatId( nTypeId, i );
        aFormatLB.SetEntryData( nPos, reinterpret_cast<void*>( nFmtId ));
		if (IsFldEdit() && nFmtId == (GetCurField()->GetFormat() & ~AF_FIXED))
			aFormatLB.SelectEntryPos( nPos );
	}

	if( nSize && !aFormatLB.GetSelectEntryCount() )
	{
		aFormatLB.SelectEntry( SW_RESSTR(FMT_NUM_PAGEDESC) );
		if( !aFormatLB.GetSelectEntryCount() )
		{
			aFormatLB.SelectEntry( SW_RESSTR(FMT_NUM_ARABIC) );
			if( !aFormatLB.GetSelectEntryCount() )
				aFormatLB.SelectEntryPos( 0 );
		}
	}

	FormatHdl();

	return nSize;
}

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

IMPL_LINK( SwFldDokPage, FormatHdl, ListBox *, EMPTYARG )
{
	sal_uInt16 nTypeId = (sal_uInt16)(sal_uLong)aTypeLB.GetEntryData(GetTypeSel());

	if (nTypeId == USHRT_MAX)
	{
		sal_uInt16 nPos = aSelectionLB.GetSelectEntryPos();
		if(nPos == LISTBOX_ENTRY_NOTFOUND)
			nPos = 0;

		nTypeId = (sal_uInt16)(sal_uLong)aSelectionLB.GetEntryData(nPos);
	}

	if (nTypeId == TYP_NEXTPAGEFLD || nTypeId == TYP_PREVPAGEFLD)
	{
		// Prev/Next - PageNumFelder Sonderbehandlung:
		sal_uInt16 nTmp = (sal_uInt16)(sal_uLong)aFormatLB.GetEntryData(
										aFormatLB.GetSelectEntryPos() );
		String sOldTxt( aValueFT.GetText() );
		String sNewTxt( SW_RES( SVX_NUM_CHAR_SPECIAL == nTmp  ? STR_VALUE
														 : STR_OFFSET ));

		if( sOldTxt != sNewTxt )
			aValueFT.SetText( sNewTxt );

		if (sOldTxt != aValueFT.GetText())
			aValueED.SetText( aEmptyStr );
	}

	return 0;
}

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

sal_Bool __EXPORT SwFldDokPage::FillItemSet(SfxItemSet& )
{
	sal_Bool bPage = sal_False;
	sal_uInt16 nTypeId = (sal_uInt16)(sal_uLong)aTypeLB.GetEntryData(GetTypeSel());

	if (nTypeId == USHRT_MAX)
	{
		sal_uInt16 nPos = aSelectionLB.GetSelectEntryPos();
		if(nPos == LISTBOX_ENTRY_NOTFOUND)
			nPos = 0;
		nTypeId = (sal_uInt16)(sal_uLong)aSelectionLB.GetEntryData(nPos);
		bPage = sal_True;
	}

	String aVal(aValueED.GetText());
	sal_uLong nFormat = 0;
	sal_uInt16 nSubType = 0;

	if (aFormatLB.IsEnabled())
	{
		sal_uInt16 nPos = aFormatLB.GetSelectEntryPos();
		if(nPos != LISTBOX_ENTRY_NOTFOUND)
			nFormat = (sal_uInt16)(sal_uLong)aFormatLB.GetEntryData(nPos);
	}

	if (aSelectionLB.IsEnabled())
	{
		sal_uInt16 nPos = aSelectionLB.GetSelectEntryPos();
		if(nPos != LISTBOX_ENTRY_NOTFOUND)
			nSubType = (sal_uInt16)(sal_uLong)aSelectionLB.GetEntryData(nPos);
	}

	switch (nTypeId)
	{
		case TYP_AUTHORFLD:
			nFormat = nSubType;
			nSubType = 0;
			// kein break!
		case TYP_EXTUSERFLD:
			nFormat |= aFixedCB.IsChecked() ? AF_FIXED : 0;
			break;

		case TYP_FILENAMEFLD:
			nFormat |= aFixedCB.IsChecked() ? FF_FIXED : 0;
			break;

		case TYP_DATEFLD:
		case TYP_TIMEFLD:
		{
			nFormat = aNumFormatLB.GetFormat();
            long nVal = static_cast< long >(aDateOffsetED.GetValue());
			if (nTypeId == TYP_DATEFLD)
				aVal = String::CreateFromInt32(nVal * 60 * 24);
			else
				aVal = String::CreateFromInt32(nVal);
			break;
		}

		case TYP_NEXTPAGEFLD:
		case TYP_PREVPAGEFLD:
		case TYP_PAGENUMBERFLD:
		case TYP_GETREFPAGEFLD:
		{
			if( SVX_NUM_CHAR_SPECIAL != nFormat &&
				(TYP_PREVPAGEFLD == nTypeId || TYP_NEXTPAGEFLD == nTypeId))
			{
                sal_Int32 nVal = aValueED.GetText().ToInt32();
				aVal = String::CreateFromInt32(nVal);
			}
			break;
		}

		case TYP_CHAPTERFLD:
			aVal = aLevelED.GetText();
			break;

		default:
			break;
	}

	if (!IsFldEdit() ||
		nOldSel != aSelectionLB.GetSelectEntryPos() ||
		nOldFormat != nFormat ||
		aFixedCB.GetState() != aFixedCB.GetSavedValue() ||
		aValueED.GetText() != aValueED.GetSavedValue() ||
		aLevelED.GetText() != aLevelED.GetSavedValue() ||
		aDateOffsetED.GetText() != aDateOffsetED.GetSavedValue())
	{
		InsertFld( nTypeId, nSubType, aEmptyStr, aVal, nFormat, ' ', aNumFormatLB.IsAutomaticLanguage() );
	}

	return sal_False;
}

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

SfxTabPage* __EXPORT SwFldDokPage::Create( 	Window* pParent,
						const SfxItemSet& rAttrSet )
{
	return ( new SwFldDokPage( pParent, rAttrSet ) );
}

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

sal_uInt16 SwFldDokPage::GetGroup()
{
	return GRP_DOC;
}

/* -----------------12.01.99 10:09-------------------
 *
 * --------------------------------------------------*/
void	SwFldDokPage::FillUserData()
{
	String sData( String::CreateFromAscii(
						RTL_CONSTASCII_STRINGPARAM( USER_DATA_VERSION )));
	sData += ';';
	sal_uInt16 nTypeSel = aTypeLB.GetSelectEntryPos();
	if( LISTBOX_ENTRY_NOTFOUND == nTypeSel )
		nTypeSel = USHRT_MAX;
	else
        nTypeSel = sal::static_int_cast< sal_uInt16 >(reinterpret_cast< sal_uIntPtr >(aTypeLB.GetEntryData( nTypeSel )));
	sData += String::CreateFromInt32( nTypeSel );
	SetUserData(sData);
}


