/**************************************************************
 * 
 * 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"

#include <cmdid.h>
#include <hintids.hxx>
#include <svl/stritem.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/text/XDefaultNumberingProvider.hpp>
#include <com/sun/star/text/XNumberingTypeInfo.hpp>
#include <com/sun/star/style/NumberingType.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/sdbc/XDataSource.hpp>
#include <com/sun/star/uri/XUriReferenceFactory.hpp>
#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
#include <comphelper/processfactory.hxx>
#include <editeng/unolingu.hxx>
#include <unotools/localedatawrapper.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/linkmgr.hxx>
#include <sfx2/app.hxx>
#include <basic/basmgr.hxx>
#include <editeng/langitem.hxx>
#include <svl/macitem.hxx>
#include <basic/sbmod.hxx>
#include <fmtrfmrk.hxx>
#include <basic/sbmeth.hxx>
#include <basic/sbx.hxx>
#include <svl/zforlist.hxx>
#include <svl/zformat.hxx>
#include <vcl/mnemonic.hxx>
#include <view.hxx>
#include <wrtsh.hxx>		// Actives Fenster
#include <doc.hxx>		// Actives Fenster
#include <docsh.hxx>		// Actives Fenster
#include <swmodule.hxx>
#include <charatr.hxx>
#include <fmtinfmt.hxx>
#include <cellatr.hxx>
#include <dbmgr.hxx>
#include <shellres.hxx>
#include <fldbas.hxx>
#include <docufld.hxx>
#include <chpfld.hxx>
#include <ddefld.hxx>
#include <expfld.hxx>
#include <reffld.hxx>
#include <usrfld.hxx>
#include <dbfld.hxx>
#include <authfld.hxx>
#include <flddat.hxx>
#include <fldmgr.hxx>
#include <crsskip.hxx>
#include <flddropdown.hxx>
#include <fldui.hrc>
#include <tox.hxx>

using rtl::OUString;
using namespace com::sun::star::uno;
using namespace com::sun::star::container;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::text;
using namespace com::sun::star::style;
using namespace com::sun::star::sdbc;
using namespace ::com::sun::star;
using namespace nsSwDocInfoSubType;

/*--------------------------------------------------------------------
	Beschreibung: Gruppen der Felder
 --------------------------------------------------------------------*/
enum
{
	GRP_DOC_BEGIN	=  0,
	GRP_DOC_END   	=  GRP_DOC_BEGIN + 11,

	GRP_FKT_BEGIN 	=  GRP_DOC_END,
    GRP_FKT_END     =  GRP_FKT_BEGIN + 8,

	GRP_REF_BEGIN 	=  GRP_FKT_END,
	GRP_REF_END   	=  GRP_REF_BEGIN + 2,

	GRP_REG_BEGIN 	=  GRP_REF_END,
	GRP_REG_END     =  GRP_REG_BEGIN + 1,

	GRP_DB_BEGIN  	=  GRP_REG_END,
	GRP_DB_END    	=  GRP_DB_BEGIN  + 5,

	GRP_VAR_BEGIN 	=  GRP_DB_END,
	GRP_VAR_END   	=  GRP_VAR_BEGIN + 9
};

enum
{
	GRP_WEB_DOC_BEGIN	=  0,
	GRP_WEB_DOC_END   	=  GRP_WEB_DOC_BEGIN + 9,

	GRP_WEB_FKT_BEGIN 	=  GRP_WEB_DOC_END + 2,
	GRP_WEB_FKT_END   	=  GRP_WEB_FKT_BEGIN + 0,	// Die Gruppe ist leer!

	GRP_WEB_REF_BEGIN 	=  GRP_WEB_FKT_END + 6,		// Die Gruppe ist leer!
	GRP_WEB_REF_END   	=  GRP_WEB_REF_BEGIN + 0,

	GRP_WEB_REG_BEGIN 	=  GRP_WEB_REF_END + 2,
	GRP_WEB_REG_END     =  GRP_WEB_REG_BEGIN + 1,

	GRP_WEB_DB_BEGIN  	=  GRP_WEB_REG_END,			// Die Gruppe ist leer!
	GRP_WEB_DB_END    	=  GRP_WEB_DB_BEGIN  + 0,

	GRP_WEB_VAR_BEGIN 	=  GRP_WEB_DB_END + 5,
	GRP_WEB_VAR_END   	=  GRP_WEB_VAR_BEGIN + 1
};

/*--------------------------------------------------------------------
	Beschreibung: Formate in der richtigen Reihenfolge
 --------------------------------------------------------------------*/
static const sal_uInt16 __FAR_DATA aSetFmt[] =
{
// die Reihenfolge muss zu Beginn mit den ResourceIds fuer FMT_SETVAR_???
// uebereinstimmen
	0,
	0
};

static const sal_uInt16 __FAR_DATA aGetFmt[] =
{
// die Reihenfolge muss zu Beginn mit den ResourceIds fuer FMT_GETVAR_???
// uebereinstimmen
	0
};

static const sal_uInt16 __FAR_DATA aUsrFmt[] =
{
// die Reihenfolge muss zu Beginn mit den ResourceIds fuer FMT_SETVAR_???
// uebereinstimmen
	0,
	nsSwExtendedSubType::SUB_CMD
};

static const sal_uInt16 __FAR_DATA aDBFmt[] =
{
// die Reihenfolge muss zu Beginn mit den ResourceIds fuer FMT_DBFLD_???
// uebereinstimmen
	nsSwExtendedSubType::SUB_OWN_FMT
};

static const sal_uInt16 VF_COUNT		= sizeof(aGetFmt) / sizeof(sal_uInt16);
static const sal_uInt16 VF_USR_COUNT	= sizeof(aUsrFmt) / sizeof(sal_uInt16);
static const sal_uInt16 VF_DB_COUNT		= sizeof(aDBFmt)  / sizeof(sal_uInt16);

/*--------------------------------------------------------------------
	Beschreibung: Feldtypen und Subtypes
 --------------------------------------------------------------------*/
struct SwFldPack
{
	sal_uInt16  nTypeId;

	sal_uInt16	nSubTypeStart;
	sal_uInt16  nSubTypeEnd;

	sal_uLong	nFmtBegin;
	sal_uLong	nFmtEnd;
};

/*--------------------------------------------------------------------
	Beschreibung: Strings und Formate
 --------------------------------------------------------------------*/
static const SwFldPack __FAR_DATA aSwFlds[] =
{
	// Dokument
	{ TYP_EXTUSERFLD,	 	FLD_EU_BEGIN,	 	FLD_EU_END,	    0,     				0 },
	{ TYP_AUTHORFLD,	 	0,					0,				FMT_AUTHOR_BEGIN,	FMT_AUTHOR_END },
	{ TYP_DATEFLD,			FLD_DATE_BEGIN,		FLD_DATE_END,	0,					0 },
	{ TYP_TIMEFLD,			FLD_TIME_BEGIN,		FLD_TIME_END,	0,					0 },
	{ TYP_PAGENUMBERFLD,	0,					0,				FMT_NUM_BEGIN,   	FMT_NUM_END-1 },
	{ TYP_NEXTPAGEFLD,		0,					0,				FMT_NUM_BEGIN,		FMT_NUM_END },
	{ TYP_PREVPAGEFLD,		0,					0,				FMT_NUM_BEGIN,		FMT_NUM_END },
	{ TYP_FILENAMEFLD,		0,					0,				FMT_FF_BEGIN,    	FMT_FF_END },
	{ TYP_DOCSTATFLD,	 	FLD_STAT_BEGIN,		FLD_STAT_END,	FMT_NUM_BEGIN,		FMT_NUM_END-1 },

	{ TYP_CHAPTERFLD,	 	0,					0,				FMT_CHAPTER_BEGIN, 	FMT_CHAPTER_END },
	{ TYP_TEMPLNAMEFLD,		0,					0,				FMT_FF_BEGIN,    	FMT_FF_END },

	// Funktion
	{ TYP_CONDTXTFLD,	 	0,					0,				0,					0 },
    { TYP_DROPDOWN,       	0,                  0,              0,                  0 },
	{ TYP_INPUTFLD,			FLD_INPUT_BEGIN,	FLD_INPUT_END,	0,   				0 },
	{ TYP_MACROFLD,			0,					0,				0,					0 },
	{ TYP_JUMPEDITFLD, 		0,					0,				FMT_MARK_BEGIN,		FMT_MARK_END },
	{ TYP_COMBINED_CHARS,	0,					0,				0,					0 },
	{ TYP_HIDDENTXTFLD,		0,					0,				0,					0 },
	{ TYP_HIDDENPARAFLD, 	0,			   		0,				0,					0 },

	// Referenzen
	{ TYP_SETREFFLD,	 	0,					0,				0,					0 },
	{ TYP_GETREFFLD,	 	0,					0,				FMT_REF_BEGIN,		FMT_REF_END },

	// Ablage
	{ TYP_DOCINFOFLD,	 	0,					0,				FMT_REG_BEGIN, 		FMT_REG_END },

	// Datenbank
	{ TYP_DBFLD,		 	0,					0,				FMT_DBFLD_BEGIN,	FMT_DBFLD_END },
	{ TYP_DBNEXTSETFLD,		0,					0,				0,					0 },
	{ TYP_DBNUMSETFLD,		0,					0,				0,					0 },
	{ TYP_DBSETNUMBERFLD, 	0,					0,				FMT_NUM_BEGIN,	    FMT_NUM_END-2 },
	{ TYP_DBNAMEFLD, 	 	0,					0,				0,					0 },

	// Variablen
	{ TYP_SETFLD,		 	0,					0,				FMT_SETVAR_BEGIN,   FMT_SETVAR_END },

	{ TYP_GETFLD,		 	0,					0, 				FMT_GETVAR_BEGIN,	FMT_GETVAR_END },
	{ TYP_DDEFLD,		 	0,					0,				FMT_DDE_BEGIN, 		FMT_DDE_END },
	{ TYP_FORMELFLD,  		0,					0,				FMT_GETVAR_BEGIN,	FMT_GETVAR_END },
	{ TYP_INPUTFLD,			FLD_INPUT_BEGIN,	FLD_INPUT_END,	0,   				0 },
	{ TYP_SEQFLD,		 	0,					0,				FMT_NUM_BEGIN,		FMT_NUM_END-2 },
	{ TYP_SETREFPAGEFLD,	FLD_PAGEREF_BEGIN,	FLD_PAGEREF_END,0,   				0 },
	{ TYP_GETREFPAGEFLD,	0,					0,				FMT_NUM_BEGIN,   	FMT_NUM_END-1 },
	{ TYP_USERFLD,			0,					0,				FMT_USERVAR_BEGIN,	FMT_USERVAR_END }
};

/*--------------------------------------------------------------------
	Beschreibung: Zugriff auf die Shell
 --------------------------------------------------------------------*/

static SwWrtShell* lcl_GetShell()
{
	SwView* pView;
	if ( 0 != (pView = ::GetActiveView()) )
		return pView->GetWrtShellPtr();
	DBG_ERROR("no current shell found!");
	return 0;
}

inline sal_uInt16 GetPackCount() {	return sizeof(aSwFlds) / sizeof(SwFldPack); }

/*--------------------------------------------------------------------
	Beschreibung: FieldManager regelt das Einfuegen und Updaten
				  von Feldern
 --------------------------------------------------------------------*/

SwFldMgr::SwFldMgr(SwWrtShell* pSh ) :
	pModule(0),
	pMacroItem(0),
    pWrtShell(pSh),
    bEvalExp(sal_True)
{
	// aktuelles Feld ermitteln falls vorhanden
	GetCurFld();
}


SwFldMgr::~SwFldMgr()
{
}

/*--------------------------------------------------------------------
	Beschreibung: RefMark ueber Namen organisieren
 --------------------------------------------------------------------*/

sal_Bool  SwFldMgr::CanInsertRefMark( const String& rStr )
{
    sal_Bool bRet = sal_False;
    SwWrtShell *pSh = pWrtShell ? pWrtShell : lcl_GetShell();
    DBG_ASSERT(pSh, "no SwWrtShell found");
    if(pSh)
    {
        sal_uInt16 nCnt = pSh->GetCrsrCnt();

        // der letzte Crsr muss keine aufgespannte Selektion
        if( 1 < nCnt && !pSh->SwCrsrShell::HasSelection() )
            --nCnt;

        bRet =  2 > nCnt && 0 == pSh->GetRefMark( rStr );
    }
    return bRet;
}

/*--------------------------------------------------------------------
	Beschreibung: Zugriff ueber ResIds
 --------------------------------------------------------------------*/

void SwFldMgr::RemoveFldType(sal_uInt16 nResId, const String& rName )
{
    SwWrtShell * pSh = pWrtShell ? pWrtShell : lcl_GetShell();
    DBG_ASSERT(pSh, "no SwWrtShell found");
    if( pSh )
        pSh->RemoveFldType(nResId, rName);
}

sal_uInt16 SwFldMgr::GetFldTypeCount(sal_uInt16 nResId) const
{
    SwWrtShell * pSh = pWrtShell ? pWrtShell : lcl_GetShell();
    DBG_ASSERT(pSh, "no SwWrtShell found");
    return pSh ? pSh->GetFldTypeCount(nResId) : 0;
}


SwFieldType* SwFldMgr::GetFldType(sal_uInt16 nResId, sal_uInt16 nId) const
{
    SwWrtShell * pSh = pWrtShell ? pWrtShell : lcl_GetShell();
    DBG_ASSERT(pSh, "no SwWrtShell found");
    return pSh ? pSh->GetFldType(nId, nResId) : 0;
}


SwFieldType* SwFldMgr::GetFldType(sal_uInt16 nResId, const String& rName) const
{
    SwWrtShell * pSh = pWrtShell ? pWrtShell : lcl_GetShell();
    DBG_ASSERT(pSh, "no SwWrtShell found");
    return pSh ? pSh->GetFldType(nResId, rName) : 0;
}


/*--------------------------------------------------------------------
	Beschreibung: Aktuelles Feld ermitteln
 --------------------------------------------------------------------*/
SwField* SwFldMgr::GetCurFld()
{
	SwWrtShell *pSh = pWrtShell ? pWrtShell : ::lcl_GetShell();
	if ( pSh )
		pCurFld = pSh->GetCurFld( true );
	else
		pCurFld = NULL;

	// Strings und Format initialisieren
	//
	aCurPar1.Erase();
	aCurPar2.Erase();
	sCurFrame.Erase();
	nCurFmt = 0;

	if(!pCurFld)
		return 0;

	// Aktuelle Werte aufbereiten Parameter 1 und Parameter 2
	// als auch das Format ermitteln
	//
	const sal_uInt16 nTypeId = pCurFld->GetTypeId();

	nCurFmt  	= pCurFld->GetFormat();
	aCurPar1 	= pCurFld->GetPar1();
	aCurPar2 	= pCurFld->GetPar2();

	switch( nTypeId )
	{
		case TYP_PAGENUMBERFLD:
		case TYP_NEXTPAGEFLD:
		case TYP_PREVPAGEFLD:
		case TYP_GETREFPAGEFLD:
			if( nCurFmt == SVX_NUM_PAGEDESC )
				nCurFmt -= 2;
			break;
	}
	return pCurFld;
}

/*--------------------------------------------------------------------
	Beschreibung: Gruppen-Bereich liefern
 --------------------------------------------------------------------*/


const SwFldGroupRgn& SwFldMgr::GetGroupRange(sal_Bool bHtmlMode, sal_uInt16 nGrpId) const
{
static SwFldGroupRgn __READONLY_DATA aRanges[] =
{
	{ /* Dokument	*/ 	GRP_DOC_BEGIN, 	GRP_DOC_END },
	{ /* Funktionen	*/ 	GRP_FKT_BEGIN,  GRP_FKT_END },
	{ /* Referenzen	*/ 	GRP_REF_BEGIN,  GRP_REF_END },
	{ /* Ablage		*/ 	GRP_REG_BEGIN,  GRP_REG_END },
	{ /* DB			*/	GRP_DB_BEGIN,	GRP_DB_END },
	{ /* User		*/	GRP_VAR_BEGIN,	GRP_VAR_END }
};
static SwFldGroupRgn __READONLY_DATA aWebRanges[] =
{
	{ /* Dokument	*/ 	GRP_WEB_DOC_BEGIN, 	GRP_WEB_DOC_END },
	{ /* Funktionen	*/ 	GRP_WEB_FKT_BEGIN,  GRP_WEB_FKT_END },
	{ /* Referenzen	*/ 	GRP_WEB_REF_BEGIN,  GRP_WEB_REF_END },
	{ /* Ablage		*/ 	GRP_WEB_REG_BEGIN,  GRP_WEB_REG_END },
	{ /* DB			*/	GRP_WEB_DB_BEGIN,	GRP_WEB_DB_END },
	{ /* User		*/	GRP_WEB_VAR_BEGIN,	GRP_WEB_VAR_END }
};

	if (bHtmlMode)
		return aWebRanges[(sal_uInt16)nGrpId];
	else
		return aRanges[(sal_uInt16)nGrpId];
}

/*--------------------------------------------------------------------
	Beschreibung: GroupId bestimmen
 --------------------------------------------------------------------*/

sal_uInt16 SwFldMgr::GetGroup(sal_Bool bHtmlMode, sal_uInt16 nTypeId, sal_uInt16 nSubType) const
{
	if (nTypeId == TYP_SETINPFLD)
		nTypeId = TYP_SETFLD;

	if (nTypeId == TYP_INPUTFLD && (nSubType & INP_USR))
		nTypeId = TYP_USERFLD;

	if (nTypeId == TYP_FIXDATEFLD)
		nTypeId = TYP_DATEFLD;

	if (nTypeId == TYP_FIXTIMEFLD)
		nTypeId = TYP_TIMEFLD;

	for (sal_uInt16 i = GRP_DOC; i <= GRP_VAR; i++)
	{
		const SwFldGroupRgn& rRange = GetGroupRange(bHtmlMode, i);
		for (sal_uInt16 nPos = rRange.nStart; nPos < rRange.nEnd; nPos++)
		{
			if (aSwFlds[nPos].nTypeId == nTypeId)
				return i;
		}
	}
	return USHRT_MAX;
}

/*--------------------------------------------------------------------
	Beschreibung: Namen zur TypeId ermitteln
				  ZUGRIFF ueber TYP_....
 --------------------------------------------------------------------*/


sal_uInt16 SwFldMgr::GetTypeId(sal_uInt16 nPos)
{
	ASSERT(nPos < ::GetPackCount(), "unzulaessige Pos");
	return aSwFlds[ nPos ].nTypeId;
}


const String& SwFldMgr::GetTypeStr(sal_uInt16 nPos)
{
	ASSERT(nPos < ::GetPackCount(), "unzulaessige TypeId");

	sal_uInt16 nFldWh = aSwFlds[ nPos ].nTypeId;

	// Sonderbehandlung fuer Datum/Zeit Felder (ohne var/fix)
	if( TYP_DATEFLD == nFldWh )
	{
		static String g_aDate( SW_RES( STR_DATEFLD ) );
		return g_aDate;
	}
	if( TYP_TIMEFLD == nFldWh )
	{
		static String g_aTime( SW_RES( STR_TIMEFLD ) );
		return g_aTime;
	}

	return SwFieldType::GetTypeStr( nFldWh );
}

/*--------------------------------------------------------------------
	Beschreibung: Pos in der Liste bestimmen
 --------------------------------------------------------------------*/


sal_uInt16 SwFldMgr::GetPos(sal_uInt16 nTypeId)
{
	switch( nTypeId )
	{
		case TYP_FIXDATEFLD:		nTypeId = TYP_DATEFLD;		break;
		case TYP_FIXTIMEFLD:      	nTypeId = TYP_TIMEFLD;		break;
		case TYP_SETINPFLD:      	nTypeId = TYP_SETFLD;		break;
		case TYP_USRINPFLD:      	nTypeId = TYP_USERFLD;		break;
	}

	for(sal_uInt16 i = 0; i < GetPackCount(); i++)
		if(aSwFlds[i].nTypeId == nTypeId)
			return i;

	return USHRT_MAX;
}

/*--------------------------------------------------------------------
	Beschreibung: Subtypen eines Feldes lokalisieren
 --------------------------------------------------------------------*/

sal_Bool SwFldMgr::GetSubTypes(sal_uInt16 nTypeId, SvStringsDtor& rToFill)
{
    sal_Bool bRet = sal_False;
    SwWrtShell *pSh = pWrtShell ? pWrtShell : lcl_GetShell();
    DBG_ASSERT(pSh, "no SwWrtShell found");
    if(pSh)
    {
        const sal_uInt16 nPos = GetPos(nTypeId);

        switch(nTypeId)
        {
            case TYP_SETREFFLD:
            case TYP_GETREFFLD:
            {
                // Referenzen sind keine Felder
                pSh->GetRefMarks( &rToFill );
                break;
            }
            case TYP_MACROFLD:
            {
                break;
            }
            case TYP_INPUTFLD:
            {   String* pNew = new SW_RESSTR(aSwFlds[nPos].nSubTypeStart);
                rToFill.Insert(pNew, rToFill.Count());
                // Weiter bei generischen Typen
            }
            case TYP_DDEFLD:
            case TYP_SEQFLD:
            case TYP_FORMELFLD:
            case TYP_GETFLD:
            case TYP_SETFLD:
            case TYP_USERFLD:
            {

                const sal_uInt16 nCount = pSh->GetFldTypeCount();
                for(sal_uInt16 i = 0; i < nCount; ++i)
                {
                    SwFieldType* pFldType = pSh->GetFldType( i );
                    const sal_uInt16 nWhich = pFldType->Which();

                    if((nTypeId == TYP_DDEFLD && pFldType->Which() == RES_DDEFLD) ||

                       (nTypeId == TYP_USERFLD && nWhich == RES_USERFLD) ||

                       (nTypeId == TYP_GETFLD && nWhich == RES_SETEXPFLD &&
                        !(((SwSetExpFieldType*)pFldType)->GetType() & nsSwGetSetExpType::GSE_SEQ)) ||

                       (nTypeId == TYP_SETFLD && nWhich == RES_SETEXPFLD &&
                        !(((SwSetExpFieldType*)pFldType)->GetType() & nsSwGetSetExpType::GSE_SEQ)) ||

                       (nTypeId == TYP_SEQFLD && nWhich == RES_SETEXPFLD  &&
                       (((SwSetExpFieldType*)pFldType)->GetType() & nsSwGetSetExpType::GSE_SEQ)) ||

                       ((nTypeId == TYP_INPUTFLD || nTypeId == TYP_FORMELFLD) &&
                         (nWhich == RES_USERFLD ||
                          (nWhich == RES_SETEXPFLD &&
                          !(((SwSetExpFieldType*)pFldType)->GetType() & nsSwGetSetExpType::GSE_SEQ))) ) )
                    {
                        String* pNew = new String(pFldType->GetName());
                        rToFill.Insert(pNew, rToFill.Count());
                    }
                }
                break;
            }
            case TYP_DBNEXTSETFLD:
            case TYP_DBNUMSETFLD:
            case TYP_DBNAMEFLD:
            case TYP_DBSETNUMBERFLD:
                break;

            default:
            {
                // statische SubTypes
                if(nPos != USHRT_MAX)
                {
                    sal_uInt16 nCount;
                    if (nTypeId == TYP_DOCINFOFLD)
                        nCount = DI_SUBTYPE_END - DI_SUBTYPE_BEGIN;
                    else
                        nCount = aSwFlds[nPos].nSubTypeEnd - aSwFlds[nPos].nSubTypeStart;

                    for(sal_uInt16 i = 0; i < nCount; ++i)
                    {
                        String* pNew;
                        if (nTypeId == TYP_DOCINFOFLD)
                        {
                            if ( i == DI_CUSTOM )
                                pNew = new String( String(SW_RES( STR_CUSTOM )) );
							else
                                pNew = new String(*ViewShell::GetShellRes()->aDocInfoLst[i]);
                        }
                        else
                            pNew = new SW_RESSTR(aSwFlds[nPos].nSubTypeStart + i);

                        rToFill.Insert(pNew, rToFill.Count());
                    }
                }
            }
        }
        bRet = sal_True;
    }
    return bRet;
}

/*--------------------------------------------------------------------
	Beschreibung: Format ermitteln
				  ZUGRIFF ueber TYP_....
 --------------------------------------------------------------------*/


sal_uInt16 SwFldMgr::GetFormatCount(sal_uInt16 nTypeId, sal_Bool bIsText, sal_Bool bHtmlMode) const
{
	ASSERT(nTypeId < TYP_END, "unzulaessige TypeId");

	{
		const sal_uInt16 nPos = GetPos(nTypeId);

		if(nPos == USHRT_MAX || (bHtmlMode && nTypeId == TYP_SETFLD))
			return 0;

		sal_uLong nStart = aSwFlds[nPos].nFmtBegin;
		sal_uLong nEnd   = aSwFlds[nPos].nFmtEnd;

		if (bIsText && nEnd - nStart >= 2)
			return 2;

		if (nTypeId == TYP_FILENAMEFLD)
			nEnd -= 2;	// Kein Bereich oder Vorlage

		switch(nStart)
		{
			case FMT_GETVAR_BEGIN:
			case FMT_SETVAR_BEGIN:	return VF_COUNT;
			case FMT_USERVAR_BEGIN:	return VF_USR_COUNT;
			case FMT_DBFLD_BEGIN:	return VF_DB_COUNT;
			case FMT_NUM_BEGIN:
			{
				sal_uInt16 nCount = (sal_uInt16)(nEnd - nStart);
				GetNumberingInfo();
                if(xNumberingInfo.is())
				{
					Sequence<sal_Int16> aTypes = xNumberingInfo->getSupportedNumberingTypes();
					const sal_Int16* pTypes = aTypes.getConstArray();
					for(sal_Int32 nType = 0; nType < aTypes.getLength(); nType++)
					{
						sal_Int16 nCurrent = pTypes[nType];
						//skip all values below or equal to CHARS_LOWER_LETTER_N
						if(nCurrent > NumberingType::CHARS_LOWER_LETTER_N)
						{
                            // #i28073# it's not necessarily a sorted sequence
                            ++nCount;
						}
					}
				}
				return nCount;
			}

		}
		return (sal_uInt16)(nEnd - nStart);
	}
}

/*--------------------------------------------------------------------
	Beschreibung:	FormatString zu einem Typ ermitteln
 --------------------------------------------------------------------*/


String SwFldMgr::GetFormatStr(sal_uInt16 nTypeId, sal_uLong nFormatId) const
{
	String aRet;
	ASSERT(nTypeId < TYP_END, "unzulaessige TypeId");

	const sal_uInt16 nPos = GetPos(nTypeId);

	if(nPos == USHRT_MAX)
		return aRet;

	sal_uLong nStart;

	nStart = aSwFlds[nPos].nFmtBegin;

	if (TYP_AUTHORFLD == nTypeId|| TYP_FILENAMEFLD == nTypeId)
		nFormatId &= ~FF_FIXED;		// Fixed-Flag ausmaskieren

	if((nStart + nFormatId) < aSwFlds[nPos].nFmtEnd)
		aRet = SW_RESSTR((sal_uInt16)(nStart + nFormatId));
	else if( FMT_NUM_BEGIN == nStart)
	{
		if(xNumberingInfo.is())
		{
			Sequence<sal_Int16> aTypes = xNumberingInfo->getSupportedNumberingTypes();
			const sal_Int16* pTypes = aTypes.getConstArray();
            sal_Int32 nOffset = aSwFlds[nPos].nFmtEnd - nStart;
            sal_Int32 nValidEntry = 0;
            for(sal_Int32 nType = 0; nType < aTypes.getLength(); nType++)
			{
				sal_Int16 nCurrent = pTypes[nType];
				if(nCurrent > NumberingType::CHARS_LOWER_LETTER_N)
				{
                    if(nValidEntry == ((sal_Int32)nFormatId) - nOffset)
                    {
                        aRet = xNumberingInfo->getNumberingIdentifier( pTypes[nType] );
                        break;
                    }
                    ++nValidEntry;
				}
			}
		}
	}

	return aRet;
}

/*--------------------------------------------------------------------
	Beschreibung:	FormatId aus Pseudo-ID ermitteln
 --------------------------------------------------------------------*/

sal_uInt16 SwFldMgr::GetFormatId(sal_uInt16 nTypeId, sal_uLong nFormatId) const
{
	sal_uInt16 nId = (sal_uInt16)nFormatId;

	switch( nTypeId )
	{
	case TYP_DOCINFOFLD:
		switch( aSwFlds[ GetPos( nTypeId ) ].nFmtBegin + nFormatId )
		{
		case FMT_REG_AUTHOR:	nId = DI_SUB_AUTHOR;	break;
		case FMT_REG_TIME:		nId = DI_SUB_TIME;		break;
		case FMT_REG_DATE:		nId = DI_SUB_DATE;		break;
		}
		break;

	case TYP_PAGENUMBERFLD:
	case TYP_NEXTPAGEFLD:
	case TYP_PREVPAGEFLD:
	case TYP_DOCSTATFLD:
	case TYP_DBSETNUMBERFLD:
	case TYP_SEQFLD:
	case TYP_GETREFPAGEFLD:
	{
		sal_uInt16 nPos = GetPos( nTypeId );
		sal_uLong nBegin = aSwFlds[ nPos ].nFmtBegin;
		sal_uLong nEnd = aSwFlds[nPos].nFmtEnd;
		if((nBegin + nFormatId) < nEnd)
		{
			switch( nBegin + nFormatId )
			{
			case FMT_NUM_ABC:				nId = SVX_NUM_CHARS_UPPER_LETTER;	break;
			case FMT_NUM_SABC:				nId = SVX_NUM_CHARS_LOWER_LETTER;	break;
			case FMT_NUM_ROMAN:             nId = SVX_NUM_ROMAN_UPPER;			break;
			case FMT_NUM_SROMAN:			nId = SVX_NUM_ROMAN_LOWER;			break;
			case FMT_NUM_ARABIC:            nId = SVX_NUM_ARABIC;				break;
			case FMT_NUM_PAGEDESC: 			nId = SVX_NUM_PAGEDESC; 			break;
			case FMT_NUM_PAGESPECIAL:		nId = SVX_NUM_CHAR_SPECIAL;			break;
			case FMT_NUM_ABC_N:				nId = SVX_NUM_CHARS_UPPER_LETTER_N; break;
			case FMT_NUM_SABC_N:			nId = SVX_NUM_CHARS_LOWER_LETTER_N;	break;
			}
		}
		else if(xNumberingInfo.is())
		{
			Sequence<sal_Int16> aTypes = xNumberingInfo->getSupportedNumberingTypes();
			const sal_Int16* pTypes = aTypes.getConstArray();
            sal_Int32 nOffset = nEnd - nBegin;
            sal_Int32 nValidEntry = 0;
            for(sal_Int32 nType = 0; nType < aTypes.getLength(); nType++)
            {
                sal_Int16 nCurrent = pTypes[nType];
                if(nCurrent > NumberingType::CHARS_LOWER_LETTER_N)
                {
                    if(nValidEntry == ((sal_Int32)nFormatId) - nOffset)
                    {
                        nId = pTypes[nType];
                        break;
                    }
                    ++nValidEntry;
                }
            }
        }
	}
	break;
	case TYP_DDEFLD:
		switch ( aSwFlds[ GetPos( nTypeId ) ].nFmtBegin + nFormatId )
		{
        case FMT_DDE_NORMAL:    nId = sfx2::LINKUPDATE_ONCALL; break;
        case FMT_DDE_HOT:       nId = sfx2::LINKUPDATE_ALWAYS; break;
		}
		break;
	}

	return nId;

}

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


sal_Bool SwFldMgr::GoNextPrev( sal_Bool bNext, SwFieldType* pTyp )
{
	SwWrtShell* pSh = pWrtShell ? pWrtShell : ::lcl_GetShell();
    if(!pSh)
        return sal_False;

	if( !pTyp && pCurFld )
	{
		const sal_uInt16 nTypeId = pCurFld->GetTypeId();
		if( TYP_SETINPFLD == nTypeId || TYP_USRINPFLD == nTypeId )
			pTyp = pSh->GetFldType( 0, RES_INPUTFLD );
		else
			pTyp = pCurFld->GetTyp();
	}

	if (pTyp && pTyp->Which() == RES_DBFLD)
	{
		// Fuer Feldbefehl-bearbeiten (alle DB-Felder anspringen)
		return pSh->MoveFldType( 0, (bNext ? true : false), RES_DBFLD );
	}

    return (pTyp && pSh)
           ? pSh->MoveFldType( pTyp, (bNext ? true : false) )
           : sal_False;
}

/*--------------------------------------------------------------------
	Beschreibung: Feldtypen einfuegen
 --------------------------------------------------------------------*/


void SwFldMgr::InsertFldType(SwFieldType& rType)
{
    SwWrtShell* pSh = pWrtShell ? pWrtShell : ::lcl_GetShell();
    DBG_ASSERT(pSh, "no SwWrtShell found");
    if(pSh)
        pSh->InsertFldType(rType);
}

/*--------------------------------------------------------------------
	Beschreibung: Aktuelle TypeId ermitteln
 --------------------------------------------------------------------*/


sal_uInt16 SwFldMgr::GetCurTypeId() const
{
    return pCurFld ? pCurFld->GetTypeId() : USHRT_MAX;
}

/*--------------------------------------------------------------------
	Beschreibung: Ueber String  Feld einfuegen oder Update
 --------------------------------------------------------------------*/


sal_Bool SwFldMgr::InsertFld(
    const SwInsertFld_Data& rData )
{
    SwField* pFld   = 0;
    sal_Bool bExp = sal_False;
    sal_Bool bTbl = sal_False;
    sal_Bool bPageVar = sal_False;
    sal_uLong nFormatId = rData.nFormatId;
    sal_uInt16 nSubType = rData.nSubType;
    sal_Unicode cSeparator = rData.cSeparator;
    SwWrtShell* pCurShell = rData.pSh;
    if(!pCurShell)
        pCurShell = pWrtShell ? pWrtShell : ::lcl_GetShell();
    DBG_ASSERT(pCurShell, "no SwWrtShell found");
    if(!pCurShell)
        return sal_False;

    switch(rData.nTypeId)
    {
    case TYP_POSTITFLD:
        {
            SwPostItFieldType* pType = (SwPostItFieldType*)pCurShell->GetFldType(0, RES_POSTITFLD);
            SwPostItField* pPostItField =
                new SwPostItField(
                    pType,
                    rData.sPar2, // content
                    rData.sPar1, // author
                    aEmptyStr, // author's initials
                    aEmptyStr, // name
                    DateTime() );
            pFld = pPostItField;
        }
        break;

    case TYP_SCRIPTFLD:
        {
            SwScriptFieldType* pType =
                (SwScriptFieldType*)pCurShell->GetFldType(0, RES_SCRIPTFLD);
            pFld = new SwScriptField(pType, rData.sPar1, rData.sPar2, (sal_Bool)nFormatId);
            break;
        }

    case TYP_COMBINED_CHARS:
        {
            SwCombinedCharFieldType* pType = (SwCombinedCharFieldType*)
                pCurShell->GetFldType( 0, RES_COMBINED_CHARS );
            pFld = new SwCombinedCharField( pType, rData.sPar1 );
        }
        break;

    case TYP_AUTHORITY:
        {
            SwAuthorityFieldType* pType =
                (SwAuthorityFieldType*)pCurShell->GetFldType(0, RES_AUTHORITY);
            if(!pType)
            {
                pType =
                    (SwAuthorityFieldType*)pCurShell->InsertFldType(
                    SwAuthorityFieldType(pCurShell->GetDoc()));
            }
            pFld = new SwAuthorityField(pType, rData.sPar1);
        }
        break;

    case TYP_DATEFLD:
    case TYP_TIMEFLD:
        {
            sal_uInt16 nSub = static_cast< sal_uInt16 >(rData.nTypeId == TYP_DATEFLD ? DATEFLD : TIMEFLD);
            nSub |= nSubType == DATE_VAR ? 0 : FIXEDFLD;

            SwDateTimeFieldType* pTyp =
                (SwDateTimeFieldType*)pCurShell->GetFldType(0, RES_DATETIMEFLD);
            pFld = new SwDateTimeField(pTyp, nSub, nFormatId);
            pFld->SetPar2(rData.sPar2);
            break;
        }

    case TYP_FILENAMEFLD:
        {
            SwFileNameFieldType* pTyp =
                (SwFileNameFieldType*)pCurShell->GetFldType(0, RES_FILENAMEFLD);
            pFld = new SwFileNameField(pTyp, nFormatId);
            break;
        }

    case TYP_TEMPLNAMEFLD:
        {
            SwTemplNameFieldType* pTyp =
                (SwTemplNameFieldType*)pCurShell->GetFldType(0, RES_TEMPLNAMEFLD);
            pFld = new SwTemplNameField(pTyp, nFormatId);
            break;
        }

    case TYP_CHAPTERFLD:
        {
            sal_uInt16 nByte = (sal_uInt16)rData.sPar2.ToInt32();
            SwChapterFieldType* pTyp =
                (SwChapterFieldType*)pCurShell->GetFldType(0, RES_CHAPTERFLD);
            pFld = new SwChapterField(pTyp, nFormatId);
            nByte = Max(sal_uInt16(1), nByte);
            nByte = Min(nByte, sal_uInt16(MAXLEVEL));
            nByte -= 1;
            ((SwChapterField*)pFld)->SetLevel((sal_uInt8)nByte);
            break;
        }

    case TYP_NEXTPAGEFLD:
    case TYP_PREVPAGEFLD:
    case TYP_PAGENUMBERFLD:
        {
            short nOff  = (short)rData.sPar2.ToInt32();

            if(rData.nTypeId == TYP_NEXTPAGEFLD)
            {
                if( SVX_NUM_CHAR_SPECIAL == nFormatId )
                    nOff = 1;
                else
                    nOff += 1;
                nSubType = PG_NEXT;
            }
            else if(rData.nTypeId == TYP_PREVPAGEFLD)
            {
                if( SVX_NUM_CHAR_SPECIAL == nFormatId )
                    nOff = -1;
                else
                    nOff -= 1;
                nSubType =  PG_PREV;
            }
            else
                nSubType = PG_RANDOM;

            SwPageNumberFieldType* pTyp =
                (SwPageNumberFieldType*)pCurShell->GetFldType(0, RES_PAGENUMBERFLD);
            pFld = new SwPageNumberField(pTyp, nSubType, nFormatId, nOff);

            if( SVX_NUM_CHAR_SPECIAL == nFormatId &&
                ( PG_PREV == nSubType || PG_NEXT == nSubType ) )
                ((SwPageNumberField*)pFld)->SetUserString( rData.sPar2 );
            break;
        }

    case TYP_DOCSTATFLD:
        {
            SwDocStatFieldType* pTyp =
                (SwDocStatFieldType*)pCurShell->GetFldType(0, RES_DOCSTATFLD);
            pFld = new SwDocStatField(pTyp, nSubType, nFormatId);
            break;
        }

    case TYP_AUTHORFLD:
        {
            SwAuthorFieldType* pTyp =
                (SwAuthorFieldType*)pCurShell->GetFldType(0, RES_AUTHORFLD);
            pFld = new SwAuthorField(pTyp, nFormatId);
            break;
        }

    case TYP_CONDTXTFLD:
    case TYP_HIDDENTXTFLD:
        {
            SwHiddenTxtFieldType* pTyp =
                (SwHiddenTxtFieldType*)pCurShell->GetFldType(0, RES_HIDDENTXTFLD);
            pFld = new SwHiddenTxtField(pTyp, sal_True, rData.sPar1, rData.sPar2, sal_False, rData.nTypeId);
            bExp = sal_True;
            break;
        }

    case TYP_HIDDENPARAFLD:
        {
            SwHiddenParaFieldType* pTyp =
                (SwHiddenParaFieldType*)pCurShell->GetFldType(0, RES_HIDDENPARAFLD);
            pFld = new SwHiddenParaField(pTyp, rData.sPar1);
            bExp = sal_True;
            break;
        }

    case TYP_SETREFFLD:
        {
            if( rData.sPar1.Len() > 0 && CanInsertRefMark( rData.sPar1 ) )
            {
                pCurShell->SetAttrItem( SwFmtRefMark( rData.sPar1 ) );
                return sal_True;
            }
            return sal_False;
        }

    case TYP_GETREFFLD:
        {
            SwGetRefFieldType* pTyp =
                (SwGetRefFieldType*)pCurShell->GetFldType(0, RES_GETREFFLD);
            sal_uInt16 nSeqNo = (sal_uInt16)rData.sPar2.ToInt32();
            pFld = new SwGetRefField(pTyp, rData.sPar1, nSubType, nSeqNo, nFormatId);
            bExp = sal_True;
            break;
        }

    case TYP_DDEFLD:
        {
            //JP 28.08.95: DDE-Topics/-Items koennen Blanks in ihren
            //				Namen haben! Wird hier noch nicht beachtet.
            String sCmd( rData.sPar2 );
            sal_uInt16 nTmpPos = sCmd.SearchAndReplace( ' ', sfx2::cTokenSeperator );
            sCmd.SearchAndReplace( ' ', sfx2::cTokenSeperator, nTmpPos );

            SwDDEFieldType aType( rData.sPar1, sCmd, (sal_uInt16) nFormatId );
            SwDDEFieldType* pTyp = (SwDDEFieldType*) pCurShell->InsertFldType( aType );
            pFld = new SwDDEField( pTyp );
            break;
        }

    case TYP_MACROFLD:
        {
            SwMacroFieldType* pTyp =
                (SwMacroFieldType*)pCurShell->GetFldType(0, RES_MACROFLD);

            pFld = new SwMacroField(pTyp, rData.sPar1, rData.sPar2);

            break;
        }

    case TYP_INTERNETFLD:
        {
            SwFmtINetFmt aFmt( rData.sPar1, sCurFrame );
            if( pMacroItem )
                aFmt.SetMacroTbl( &pMacroItem->GetMacroTable() );
            return pCurShell->InsertURL( aFmt, rData.sPar2 );
        }

    case TYP_JUMPEDITFLD:
        {
            SwJumpEditFieldType* pTyp =
                (SwJumpEditFieldType*)pCurShell->GetFldType(0, RES_JUMPEDITFLD);

            pFld = new SwJumpEditField(pTyp, nFormatId, rData.sPar1, rData.sPar2 );
            break;
        }

    case TYP_DOCINFOFLD:
        {
            SwDocInfoFieldType* pTyp = (SwDocInfoFieldType*)pCurShell->GetFldType(
                0, RES_DOCINFOFLD );
            pFld = new SwDocInfoField(pTyp, nSubType, rData.sPar1, nFormatId);
            break;
        }

    case TYP_EXTUSERFLD:
        {
            SwExtUserFieldType* pTyp = (SwExtUserFieldType*)pCurShell->GetFldType(
                0, RES_EXTUSERFLD);
            pFld = new SwExtUserField(pTyp, nSubType, nFormatId);
            break;
        }

    case TYP_DBFLD:
        {
            SwDBData aDBData;
            String sPar1;

            if (rData.sPar1.Search(DB_DELIM) == STRING_NOTFOUND)
            {
                aDBData = pCurShell->GetDBData();
                sPar1 = rData.sPar1;
            }
            else
            {
                aDBData.sDataSource = rData.sPar1.GetToken(0, DB_DELIM);
                aDBData.sCommand = rData.sPar1.GetToken(1, DB_DELIM);
                aDBData.nCommandType = rData.sPar1.GetToken(2, DB_DELIM).ToInt32();
                sPar1 = rData.sPar1.GetToken(3, DB_DELIM);
            }

            if(aDBData.sDataSource.getLength() && pCurShell->GetDBData() != aDBData)
                pCurShell->ChgDBData(aDBData);

            SwDBFieldType* pTyp = (SwDBFieldType*)pCurShell->InsertFldType(
                SwDBFieldType(pCurShell->GetDoc(), sPar1, aDBData) );
            pFld = new SwDBField(pTyp);
            pFld->SetSubType(nSubType);

            if( !(nSubType & nsSwExtendedSubType::SUB_OWN_FMT) ) // Datenbankformat ermitteln
            {
                Reference< XDataSource> xSource;
                rData.aDBDataSource >>= xSource;
                Reference<XConnection> xConnection;
                rData.aDBConnection >>= xConnection;
                Reference<XPropertySet> xColumn;
                rData.aDBColumn >>= xColumn;
                if(xColumn.is())
                {
                    nFormatId = pCurShell->GetNewDBMgr()->GetColumnFmt(xSource, xConnection, xColumn,
                        pCurShell->GetNumberFormatter(), GetCurrLanguage() );
                }
                else
                    nFormatId = pCurShell->GetNewDBMgr()->GetColumnFmt(
                    aDBData.sDataSource, aDBData.sCommand, sPar1,
                    pCurShell->GetNumberFormatter(), GetCurrLanguage() );
            }
            pFld->ChangeFormat( nFormatId );

            bExp = sal_True;
            break;
        }

    case TYP_DBSETNUMBERFLD:
    case TYP_DBNUMSETFLD:
    case TYP_DBNEXTSETFLD:
    case TYP_DBNAMEFLD:
        {
            sal_uInt16 nPos, nTablePos, nCmdTypePos, nExpPos;
            String sPar1;
            SwDBData aDBData;

            // DBName aus rData.sPar1 extrahieren. Format: DBName.TableName.CommandType.ExpStrg
            if ((nTablePos = rData.sPar1.Search(DB_DELIM)) != STRING_NOTFOUND)
                aDBData.sDataSource = rData.sPar1.Copy(0, nTablePos++);
            if ((nCmdTypePos = rData.sPar1.Search(DB_DELIM, nTablePos)) != STRING_NOTFOUND)
            {
                aDBData.sCommand = rData.sPar1.Copy(nTablePos, nCmdTypePos++ - nTablePos);
            }
            if ((nExpPos = rData.sPar1.Search(DB_DELIM, nCmdTypePos)) != STRING_NOTFOUND)
            {
                aDBData.nCommandType = rData.sPar1.Copy(nCmdTypePos, nExpPos++ - nCmdTypePos).ToInt32();
            }
            if (nExpPos != STRING_NOTFOUND)
                nPos = nExpPos;
            else if (nTablePos != STRING_NOTFOUND)
                nPos = nTablePos;
            else
                nPos = 0;
            sPar1 = rData.sPar1.Copy(nPos);

            if (aDBData.sDataSource.getLength() && pCurShell->GetDBData() != aDBData)
                pCurShell->ChgDBData(aDBData);

            switch(rData.nTypeId)
            {
            case TYP_DBNAMEFLD:
                {
                    SwDBNameFieldType* pTyp =
                        (SwDBNameFieldType*)pCurShell->GetFldType(0, RES_DBNAMEFLD);
                    pFld = new SwDBNameField(pTyp, aDBData);

                    break;
                }
            case TYP_DBNEXTSETFLD:
                {
                    SwDBNextSetFieldType* pTyp = (SwDBNextSetFieldType*)pCurShell->GetFldType(
                        0, RES_DBNEXTSETFLD);
                    pFld = new SwDBNextSetField(pTyp, sPar1, rData.sPar2, aDBData);
                    bExp = sal_True;
                    break;
                }
            case TYP_DBNUMSETFLD:
                {
                    SwDBNumSetFieldType* pTyp = (SwDBNumSetFieldType*)pCurShell->GetFldType(
                        0, RES_DBNUMSETFLD);
                    pFld = new SwDBNumSetField( pTyp, sPar1, rData.sPar2, aDBData);
                    bExp = sal_True;
                    break;
                }
            case TYP_DBSETNUMBERFLD:
                {
                    SwDBSetNumberFieldType* pTyp = (SwDBSetNumberFieldType*)
                        pCurShell->GetFldType(0, RES_DBSETNUMBERFLD);
                    pFld = new SwDBSetNumberField( pTyp, aDBData, nFormatId);
                    bExp = sal_True;
                    break;	
                }
            }
            break;
        }

    case TYP_USERFLD:
        {
            SwUserFieldType* pTyp =
                (SwUserFieldType*)pCurShell->GetFldType(RES_USERFLD, rData.sPar1);

            // nur wenn vorhanden
            if(!pTyp)
            {
                pTyp = (SwUserFieldType*)pCurShell->InsertFldType(
                    SwUserFieldType(pCurShell->GetDoc(), rData.sPar1));
            }
            if (pTyp->GetContent(nFormatId) != rData.sPar2)
                pTyp->SetContent(rData.sPar2, nFormatId);
            pFld = new SwUserField(pTyp, 0, nFormatId);
            if (pFld->GetSubType() != nSubType)
                pFld->SetSubType(nSubType);
            bTbl = sal_True;
            break;
        }

    case TYP_INPUTFLD:
        {
            if ((nSubType & 0x00ff) == INP_VAR)
            {
                SwSetExpFieldType* pTyp = (SwSetExpFieldType*)
                    pCurShell->GetFldType(RES_SETEXPFLD, rData.sPar1);

                // kein Experssion Type mit dem Namen vorhanden -> anlegen
                if(pTyp)
                {
                    SwSetExpField* pExpFld =
                        new SwSetExpField(pTyp, aEmptyStr, nFormatId);

                    // Typ vom SwSetExpFieldType nicht veraendern:
                    sal_uInt16 nOldSubType = pExpFld->GetSubType();
                    pExpFld->SetSubType(nOldSubType | (nSubType & 0xff00));

                    pExpFld->SetPromptText(rData.sPar2);
                    pExpFld->SetInputFlag(sal_True) ;
                    bExp = sal_True;
                    pFld = pExpFld;
                }
                else
                    return sal_False;
            }
            else
            {
                SwInputFieldType* pTyp =
                    (SwInputFieldType*)pCurShell->GetFldType(0, RES_INPUTFLD);

                SwInputField* pInpFld =
                    new SwInputField( pTyp, rData.sPar1, rData.sPar2, nSubType|nsSwExtendedSubType::SUB_INVISIBLE, nFormatId);
                pFld = pInpFld;
            }

            // Dialog starten
            //
            pCurShell->StartInputFldDlg(pFld, sal_False, rData.pParent);
            break;
        }

    case TYP_SETFLD:
        {
            if (!rData.sPar2.Len())   // Leere Variablen sind nicht erlaubt
                return sal_False;

            SwSetExpFieldType* pTyp = (SwSetExpFieldType*)pCurShell->InsertFldType(
                SwSetExpFieldType(pCurShell->GetDoc(), rData.sPar1) );

            SwSetExpField* pExpFld = new SwSetExpField( pTyp, rData.sPar2, nFormatId);
            pExpFld->SetSubType(nSubType);
            pExpFld->SetPar2(rData.sPar2);
            bExp = sal_True;
            pFld = pExpFld;
            break;
        }

    case TYP_SEQFLD:
        {
            SwSetExpFieldType* pTyp = (SwSetExpFieldType*)pCurShell->InsertFldType(
                SwSetExpFieldType(pCurShell->GetDoc(), rData.sPar1, nsSwGetSetExpType::GSE_SEQ));

            sal_uInt8 nLevel = static_cast< sal_uInt8 >(nSubType & 0xff);

            pTyp->SetOutlineLvl(nLevel);
            if (nLevel != 0x7f && cSeparator == 0)
                cSeparator = '.';

            pTyp->SetDelimiter(cSeparator);
            SwSetExpField* pExpFld = new SwSetExpField(pTyp, rData.sPar2, nFormatId);
            bExp = sal_True;
            pFld = pExpFld;
            nSubType = nsSwGetSetExpType::GSE_SEQ;
            break;
        }

    case TYP_GETFLD:
        {
            // gibt es ein entprechendes SetField
            SwSetExpFieldType* pSetTyp = (SwSetExpFieldType*)
                pCurShell->GetFldType(RES_SETEXPFLD, rData.sPar1);

            if(pSetTyp)
            {
                SwGetExpFieldType* pTyp = (SwGetExpFieldType*)pCurShell->GetFldType(
                    0, RES_GETEXPFLD);
                pFld = new SwGetExpField(pTyp, rData.sPar1, pSetTyp->GetType(), nFormatId);
                pFld->SetSubType(nSubType | pSetTyp->GetType());
                bExp = sal_True;
            }
            else
                return sal_False;
            break;
        }

    case TYP_FORMELFLD:
        {
            if(pCurShell->GetFrmType(0,sal_False) & FRMTYPE_TABLE)
            {
                pCurShell->StartAllAction();

                SvNumberFormatter* pFormatter = pCurShell->GetDoc()->GetNumberFormatter();
                const SvNumberformat* pEntry = pFormatter->GetEntry(nFormatId);

                if (pEntry)
                {
                    SfxStringItem aFormat(FN_NUMBER_FORMAT, pEntry->GetFormatstring());
                    pCurShell->GetView().GetViewFrame()->GetDispatcher()->
                        Execute(FN_NUMBER_FORMAT, SFX_CALLMODE_SYNCHRON, &aFormat, 0L);
                }

                SfxItemSet aBoxSet( pCurShell->GetAttrPool(),
                    RES_BOXATR_FORMULA, RES_BOXATR_FORMULA );

                String sFml( rData.sPar2 );
                if( sFml.EraseLeadingChars().Len() &&
                    '=' == sFml.GetChar( 0 ) )
                    sFml.Erase( 0, 1 );

                aBoxSet.Put( SwTblBoxFormula( sFml ));
                pCurShell->SetTblBoxFormulaAttrs( aBoxSet );
                pCurShell->UpdateTable();

                pCurShell->EndAllAction();
                return sal_True;

                /*				// In der Tabelle Tabellenformeln einfuegen
                SwTblFieldType* pTyp = (SwTblFieldType*)pCurShell->GetFldType(
                0, RES_TABLEFLD);
                pFld = new SwTblField(pTyp, rData.sPar2, nsSwGetSetExpType::GSE_EXPR, nFormatId);
                bTbl = sal_True;*/
            }
            else
            {
                SwGetExpFieldType* pTyp = (SwGetExpFieldType*)
                    pCurShell->GetFldType(0, RES_GETEXPFLD);
                pFld = new SwGetExpField(pTyp, rData.sPar2, nsSwGetSetExpType::GSE_FORMULA, nFormatId);
                pFld->SetSubType(nSubType);
                bExp = sal_True;
            }
            break;
        }

    case TYP_SETREFPAGEFLD:
        pFld = new SwRefPageSetField( (SwRefPageSetFieldType*)
            pCurShell->GetFldType( 0, RES_REFPAGESETFLD ),
            (short)rData.sPar2.ToInt32(), 0 != nSubType  );
        bPageVar = sal_True;
        break;

    case TYP_GETREFPAGEFLD:
        pFld = new SwRefPageGetField( (SwRefPageGetFieldType*)
            pCurShell->GetFldType( 0, RES_REFPAGEGETFLD ), nFormatId );
        bPageVar = sal_True;
        break;

    case TYP_DROPDOWN :
        {
            pFld = new SwDropDownField(pCurShell->GetFldType( 0, RES_DROPDOWN ));
            xub_StrLen nTokenCount = rData.sPar2.Len() ? rData.sPar2.GetTokenCount(DB_DELIM) : 0;
            Sequence<OUString> aEntries(nTokenCount);
            OUString* pArray = aEntries.getArray();
            for(xub_StrLen nToken = 0; nToken < nTokenCount; nToken++)
                pArray[nToken] = rData.sPar2.GetToken(nToken, DB_DELIM);
            ((SwDropDownField*)pFld)->SetItems(aEntries);
            ((SwDropDownField*)pFld)->SetName(rData.sPar1);
        }
        break;

    default:
        {
            ASSERT(!this, "Falscher Feldtyp");
            return sal_False;
        }
    }
    ASSERT(pFld, "Feld nicht vorhanden");


    //the auto language flag has to be set prior to the language!
    pFld->SetAutomaticLanguage(rData.bIsAutomaticLanguage);
    sal_uInt16 nLang = GetCurrLanguage();
    pFld->SetLanguage(nLang);

    // Einfuegen
    pCurShell->StartAllAction();

    pCurShell->Insert( *pFld );

    if(bExp && bEvalExp)
        pCurShell->UpdateExpFlds(sal_True);

    if(bTbl)
    {
        pCurShell->Left(CRSR_SKIP_CHARS, sal_False, 1, sal_False );
        pCurShell->UpdateFlds(*pFld);
        pCurShell->Right(CRSR_SKIP_CHARS, sal_False, 1, sal_False );
    }
    else if( bPageVar )
        ((SwRefPageGetFieldType*)pCurShell->GetFldType( 0, RES_REFPAGEGETFLD ))->UpdateFlds();
    else if( TYP_GETREFFLD == rData.nTypeId )
        pFld->GetTyp()->ModifyNotification( 0, 0 );

    // temporaeres Feld loeschen
    delete pFld;

    pCurShell->EndAllAction();
    return sal_True;
}

/*--------------------------------------------------------------------
	Beschreibung: Felder Update
 --------------------------------------------------------------------*/


void SwFldMgr::UpdateCurFld(sal_uLong nFormat,
							const String& rPar1,
							const String& rPar2,
                            SwField * _pTmpFld) // #111840#
{
	// Format aendern
	ASSERT(pCurFld, "kein Feld an der CursorPos");

    bool bDelete = false;
    SwField *pTmpFld;		// mb: fixed memory leak
    if (NULL != _pTmpFld)
    {
        pTmpFld = _pTmpFld;
    }
    else
    {
        pTmpFld = pCurFld->CopyField();
        bDelete = true;
    }

	SwFieldType* pType   = pTmpFld->GetTyp();
	const sal_uInt16 nTypeId = pTmpFld->GetTypeId();

    SwWrtShell* pSh = pWrtShell ? pWrtShell : ::lcl_GetShell();
    DBG_ASSERT(pSh, "no SwWrtShell found");
    if(!pSh)
        return;
    pSh->StartAllAction();

	sal_Bool bSetPar2 = sal_True;
	sal_Bool bSetPar1 = sal_True;
	String sPar1( rPar1 );
	String sPar2( rPar2 );

	// Order to Format
	switch( nTypeId )
	{
		case TYP_DDEFLD:
		{
			//JP 28.08.95: DDE-Topics/-Items koennen Blanks in ihren
			//				Namen haben! Wird hier noch nicht beachtet.
            sal_uInt16 nTmpPos = sPar2.SearchAndReplace( ' ', sfx2::cTokenSeperator );
            sPar2.SearchAndReplace( ' ', sfx2::cTokenSeperator, nTmpPos );
			break;
		}

		case TYP_CHAPTERFLD:
		{
            sal_uInt16 nByte = (sal_uInt16)rPar2.ToInt32();
			nByte = Max(sal_uInt16(1), nByte);
			nByte = Min(nByte, sal_uInt16(MAXLEVEL));
			nByte -= 1;
			((SwChapterField*)pTmpFld)->SetLevel((sal_uInt8)nByte);
			bSetPar2 = sal_False;
			break;
		}

		case TYP_SCRIPTFLD:
			((SwScriptField*)pTmpFld)->SetCodeURL((sal_Bool)nFormat);
			break;

		case TYP_NEXTPAGEFLD:
			if( SVX_NUM_CHAR_SPECIAL == nFormat )
			{
				((SwPageNumberField*)pCurFld)->SetUserString( sPar2 );
				sPar2 = '1';
			}
			else
			{
				if( nFormat + 2 == SVX_NUM_PAGEDESC )
					nFormat = SVX_NUM_PAGEDESC;
                short nOff = (short)sPar2.ToInt32();
				nOff += 1;
				sPar2 = String::CreateFromInt32(nOff);
			}
			break;

		case TYP_PREVPAGEFLD:
			if( SVX_NUM_CHAR_SPECIAL == nFormat )
			{
				((SwPageNumberField*)pCurFld)->SetUserString( sPar2 );
				sPar2 = String::CreateFromAscii(
                    RTL_CONSTASCII_STRINGPARAM("-1"));
			}
			else
			{
				if( nFormat + 2 == SVX_NUM_PAGEDESC )
					nFormat = SVX_NUM_PAGEDESC;
                short nOff = (short)sPar2.ToInt32();
				nOff -= 1;
				sPar2 = String::CreateFromInt32(nOff);
			}
			break;

		case TYP_PAGENUMBERFLD:
		case TYP_GETREFPAGEFLD:
			if( nFormat + 2 == SVX_NUM_PAGEDESC )
				nFormat = SVX_NUM_PAGEDESC;
			break;

		case TYP_GETREFFLD:
			{
				bSetPar2 = sal_False;
                ((SwGetRefField*)pTmpFld)->SetSubType( (sal_uInt16)rPar2.ToInt32() );
				sal_uInt16 nPos = rPar2.Search( '|' );
				if( STRING_NOTFOUND != nPos )
                    ((SwGetRefField*)pTmpFld)->SetSeqNo( (sal_uInt16)rPar2.Copy( nPos + 1 ).ToInt32());
			}
			break;
		case TYP_DROPDOWN:
		{
            xub_StrLen nTokenCount = sPar2.Len() ? sPar2.GetTokenCount(DB_DELIM) : 0;
            Sequence<OUString> aEntries(nTokenCount);
            OUString* pArray = aEntries.getArray();
            for(xub_StrLen nToken = 0; nToken < nTokenCount; nToken++)
                pArray[nToken] = sPar2.GetToken(nToken, DB_DELIM);
            ((SwDropDownField*)pTmpFld)->SetItems(aEntries);
            ((SwDropDownField*)pTmpFld)->SetName(sPar1);
			bSetPar1 = bSetPar2 = sal_False;
		}
		break;
        case TYP_AUTHORITY :
        {    
            //#i99069# changes to a bibliography field should change the field type
            SwAuthorityField* pAuthorityField = static_cast<SwAuthorityField*>(pTmpFld);
            SwAuthorityFieldType* pAuthorityType = static_cast<SwAuthorityFieldType*>(pType);
            SwAuthEntry aTempEntry;
            for( sal_uInt16 i = 0; i < AUTH_FIELD_END; ++i )
                aTempEntry.SetAuthorField( (ToxAuthorityField)i,
                                rPar1.GetToken( i, TOX_STYLE_DELIMITER ));
            if( pAuthorityType->ChangeEntryContent( &aTempEntry ) )
            {
                pType->UpdateFlds();
                pSh->SetModified();
            }
        
            if( aTempEntry.GetAuthorField( AUTH_FIELD_IDENTIFIER ) == 
                pAuthorityField->GetFieldText( AUTH_FIELD_IDENTIFIER ) ) 
                bSetPar1 = sal_False; //otherwise it's a new or changed entry, the field needs to be updated    
            bSetPar2 = sal_False;
        }
        break;
	}

	// Format setzen
	// Format wegen NumberFormatter vor SetPar2 einstellen!
	pTmpFld->ChangeFormat(nFormat);

	if(bSetPar1)
		pTmpFld->SetPar1( sPar1 );
	if( bSetPar2 )
		pTmpFld->SetPar2( sPar2 );

	// Update anschmeissen
	if(nTypeId == TYP_DDEFLD ||
	   nTypeId == TYP_USERFLD ||
	   nTypeId == TYP_USRINPFLD)
	{
		pType->UpdateFlds();
        pSh->SetModified();
	}
	else {
		// mb: #32157
        pSh->SwEditShell::UpdateFlds(*pTmpFld);
		GetCurFld();
	}

    if (bDelete)
        delete pTmpFld;

    pSh->EndAllAction();
}

/*--------------------------------------------------------------------
	Beschreibung: ExpressionFields explizit evaluieren
 --------------------------------------------------------------------*/
void SwFldMgr::EvalExpFlds(SwWrtShell* pSh)
{
	if (pSh == NULL)
		pSh = pWrtShell ? pWrtShell : ::lcl_GetShell();

	if(pSh)
	{
		pSh->StartAllAction();
		pSh->UpdateExpFlds(sal_True);
		pSh->EndAllAction();
	}
}
sal_uInt16 SwFldMgr::GetCurrLanguage() const
{
	SwWrtShell* pSh = pWrtShell ? pWrtShell : ::lcl_GetShell();
	if( pSh )
		return pSh->GetCurLang();
	return SvxLocaleToLanguage( SvtSysLocale().GetLocaleData().getLocale() );
}

void SwFieldType::_GetFldName()
{
	// mba: this is an awful mess; a fix is available, but too much for 3.4 -> applay plaster
	static const sal_uInt16 coFldCnt = 43;

	static sal_uInt16 __READONLY_DATA coFldNms[ coFldCnt ] = {
		FLD_DATE_STD,
		FLD_TIME_STD,
		STR_FILENAMEFLD,
		STR_DBNAMEFLD,
		STR_CHAPTERFLD,
		STR_PAGENUMBERFLD,
		STR_DOCSTATFLD,
		STR_AUTHORFLD,
		STR_SETFLD,
		STR_GETFLD,
		STR_FORMELFLD,
		STR_HIDDENTXTFLD,
		STR_SETREFFLD,
		STR_GETREFFLD,
		STR_DDEFLD,
		STR_MACROFLD,
		STR_INPUTFLD,
		STR_HIDDENPARAFLD,
		STR_DOCINFOFLD,
		STR_DBFLD,
		STR_USERFLD,
		STR_POSTITFLD,
		STR_TEMPLNAMEFLD,
		STR_SEQFLD,
		STR_DBNEXTSETFLD,
		STR_DBNUMSETFLD,
		STR_DBSETNUMBERFLD,
		STR_CONDTXTFLD,
		STR_NEXTPAGEFLD,
		STR_PREVPAGEFLD,
		STR_EXTUSERFLD,
		FLD_DATE_FIX,
		FLD_TIME_FIX,
		STR_SETINPUTFLD,
		STR_USRINPUTFLD,
		STR_SETREFPAGEFLD,
		STR_GETREFPAGEFLD,
		STR_INTERNETFLD,
		STR_JUMPEDITFLD,
		STR_SCRIPTFLD,
		STR_AUTHORITY,
        STR_COMBINED_CHARS,
        STR_DROPDOWN
	};

	// Infos fuer Felder einfuegen
	SwFieldType::pFldNames = new SvStringsDtor( (sal_uInt8)coFldCnt, 2 );
	for( sal_uInt16 nIdx = 0; nIdx < coFldCnt; ++nIdx )
	{
		String* pTmp = new SW_RESSTR( coFldNms[ nIdx ] );
        pTmp->Assign( MnemonicGenerator::EraseAllMnemonicChars( *pTmp ) );
		SwFieldType::pFldNames->Insert(pTmp, nIdx );
	}
}

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

sal_Bool SwFldMgr::ChooseMacro(const String&)
{
    sal_Bool bRet = sal_False;

    // choose script dialog
    ::rtl::OUString aScriptURL = SfxApplication::ChooseScript();

    // the script selector dialog returns a valid script URL
    if ( aScriptURL.getLength() != 0 )
    {
        SetMacroPath( aScriptURL );
        bRet = sal_True;
    }

    return bRet;
}

void SwFldMgr::SetMacroPath(const String& rPath)
{
    sMacroPath = rPath;
    sMacroName = rPath;

    // try to set sMacroName member variable by parsing the macro path
    // using the new URI parsing services

    Reference< XMultiServiceFactory > xSMgr =
        ::comphelper::getProcessServiceFactory();

    Reference< uri::XUriReferenceFactory >
        xFactory( xSMgr->createInstance(
            ::rtl::OUString::createFromAscii(
                "com.sun.star.uri.UriReferenceFactory" ) ), UNO_QUERY );

    if ( xFactory.is() )
    {
        Reference< uri::XVndSunStarScriptUrl >
            xUrl( xFactory->parse( sMacroPath ), UNO_QUERY );

        if ( xUrl.is() )
        {
            sMacroName = xUrl->getName();
        }
    }
}

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

sal_uLong SwFldMgr::GetDefaultFormat(sal_uInt16 nTypeId, sal_Bool bIsText, SvNumberFormatter* pFormatter, double* pVal)
{
	double fValue;
	short  nDefFormat;

	switch (nTypeId)
	{
		case TYP_TIMEFLD:
		case TYP_DATEFLD:
		{
			Date aDate;
			Date* pNullDate = pFormatter->GetNullDate();

			fValue = aDate - *pNullDate;

			Time aTime;

			sal_uLong nNumFmtTime = (sal_uLong)aTime.GetSec() + (sal_uLong)aTime.GetMin() * 60L +
						  (sal_uLong)aTime.GetHour() * 3600L;

			fValue += (double)nNumFmtTime / 86400.0;

			nDefFormat = (nTypeId == TYP_DATEFLD) ? NUMBERFORMAT_DATE : NUMBERFORMAT_TIME;
		}
		break;

		default:
			if (bIsText)
			{
				fValue = 0.0;
				nDefFormat = NUMBERFORMAT_TEXT;
			}
			else
			{
				fValue = 0.0;
				nDefFormat = NUMBERFORMAT_ALL;
			}
			break;
	}

	if (pVal)
		*pVal = fValue;

	return pFormatter->GetStandardFormat(nDefFormat, GetCurrLanguage());
}

/* -----------------------------01.03.01 16:46--------------------------------

 ---------------------------------------------------------------------------*/
Reference<XNumberingTypeInfo> SwFldMgr::GetNumberingInfo() const
{
	if(!xNumberingInfo.is())
	{
		Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
		Reference < XInterface > xI = xMSF->createInstance(
			::rtl::OUString::createFromAscii(
							"com.sun.star.text.DefaultNumberingProvider" ));
		Reference<XDefaultNumberingProvider> xDefNum(xI, UNO_QUERY);
		DBG_ASSERT(xDefNum.is(), "service missing: \"com.sun.star.text.DefaultNumberingProvider\"");
		((SwFldMgr*)this)->xNumberingInfo = Reference<XNumberingTypeInfo>(xDefNum, UNO_QUERY);
	}
	return xNumberingInfo;
}
