/**************************************************************
 * 
 * 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 <cstdarg>
#include <cstdio>

#include <unotxdoc.hxx>
#include <com/sun/star/text/NotePrintMode.hpp>
#include <sfx2/app.hxx>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/sdb/XDocumentDataSource.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/lang/XEventListener.hpp>
#include <com/sun/star/util/XNumberFormatter.hpp>
#include <com/sun/star/sdb/XCompletedConnection.hpp>
#include <com/sun/star/sdb/XCompletedExecution.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/text/MailMergeEvent.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
#include <com/sun/star/ui/dialogs/XFilePicker.hpp>
#include <com/sun/star/ui/dialogs/XFilterManager.hpp>
#include <com/sun/star/uno/XNamingService.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <sfx2/fcontnr.hxx>
#include <sfx2/filedlghelper.hxx>
#include <sfx2/viewfrm.hxx>
#include <dbconfig.hxx>
#include <swdbtoolsclient.hxx>
#include <pagedesc.hxx>
#include <vcl/lstbox.hxx>
#include <unotools/tempfile.hxx>
#include <unotools/pathoptions.hxx>
#include <svl/urihelper.hxx>
#define _SVSTDARR_STRINGSDTOR
#include <svl/svstdarr.hxx>
#include <svl/zforlist.hxx>
#include <svl/zformat.hxx>
#include <svl/stritem.hxx>
#include <svl/eitem.hxx>
#include <vcl/oldprintadaptor.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/progress.hxx>
#include <sfx2/dispatch.hxx>
#include <svl/mailenum.hxx>
#include <cmdid.h>
#include <swmodule.hxx>
#include <view.hxx>
#include <docsh.hxx>
#include <edtwin.hxx>
#include <wrtsh.hxx>
#include <fldbas.hxx>
#include <initui.hxx>
#include <swundo.hxx>
#include <flddat.hxx>
#include <modcfg.hxx>
#include <shellio.hxx>
#include <dbui.hxx>
#include <dbmgr.hxx>
#include <doc.hxx>
#include <swwait.hxx>
#include <swunohelper.hxx>
#include <dbui.hrc>
#include <globals.hrc>
#include <statstr.hrc>
#include <mmconfigitem.hxx>
#include <sfx2/request.hxx>
#include <hintids.hxx>
#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
#include <com/sun/star/sdbc/XRowSet.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/sdb/XQueriesSupplier.hpp>
#include <com/sun/star/sdb/XColumn.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/sdbc/ResultSetType.hpp>
#include <com/sun/star/mail/MailAttachment.hpp>
#include <comphelper/processfactory.hxx>
#include <comphelper/types.hxx>
#include <comphelper/property.hxx>
#include <mailmergehelper.hxx>
#include <maildispatcher.hxx>
#include <svtools/htmlcfg.hxx>
#include <i18npool/mslangid.hxx>
#include <com/sun/star/util/XNumberFormatTypes.hpp>
#include <editeng/langitem.hxx>
#include <svl/numuno.hxx>

#include <unomailmerge.hxx>
#include <sfx2/event.hxx>
#include <vcl/msgbox.hxx>
#include <svx/dataaccessdescriptor.hxx>
#include <vos/mutex.hxx>
#include <rtl/textenc.h>
#include <ndindex.hxx>
#include <pam.hxx>
#include <swcrsr.hxx>
#include <swevent.hxx>
#include <osl/file.hxx>
#include <swabstdlg.hxx>
#include <fmthdft.hxx>
#include <dbui.hrc>
#include <envelp.hrc>
#include <memory>
#include <vector>
#include <unomid.h>
#include <section.hxx>

using namespace ::osl;
using namespace ::svx;
using namespace ::com::sun::star;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::ui::dialogs;

#define DB_SEP_SPACE  	0
#define DB_SEP_TAB  	1
#define DB_SEP_RETURN   2
#define DB_SEP_NEWLINE  3

SV_IMPL_PTRARR(SwDSParamArr, SwDSParamPtr);
const sal_Char cCursor[] = "Cursor";
const sal_Char cCommand[] = "Command";
const sal_Char cCommandType[] = "CommandType";
const sal_Char cDataSourceName[] = "DataSourceName";
const sal_Char cSelection[] = "Selection";
const sal_Char cActiveConnection[] = "ActiveConnection";

// -----------------------------------------------------------------------------
// Use nameless namespace to avoid to rubbish the global namespace
// -----------------------------------------------------------------------------
namespace
{

bool lcl_getCountFromResultSet( sal_Int32& rCount, const uno::Reference<XResultSet>& xResultSet )
{
    uno::Reference<XPropertySet> xPrSet(xResultSet, UNO_QUERY);
    if(xPrSet.is())
    {
        try
        {
            sal_Bool bFinal = sal_False;
            Any aFinal = xPrSet->getPropertyValue(C2U("IsRowCountFinal"));
            aFinal >>= bFinal;
            if(!bFinal)
            {
                xResultSet->last();
                xResultSet->first();
            }
            Any aCount = xPrSet->getPropertyValue(C2U("RowCount"));
            if( aCount >>= rCount )
                return true;
        }
        catch(Exception&)
        {
        }
    }
    return false;
}
// #122799# copy compatibility options
void lcl_CopyCompatibilityOptions( SwWrtShell& rSourceShell, SwWrtShell& rTargetShell)
{
    IDocumentSettingAccess* pIDsa = rSourceShell.getIDocumentSettingAccess();

    rTargetShell.SetParaSpaceMax( pIDsa->get(IDocumentSettingAccess::PARA_SPACE_MAX));
    rTargetShell.SetParaSpaceMaxAtPages(pIDsa->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES));
    rTargetShell.SetTabCompat( pIDsa->get(IDocumentSettingAccess::TAB_COMPAT));
    rTargetShell.SetAddExtLeading( pIDsa->get(IDocumentSettingAccess::ADD_EXT_LEADING));
    rTargetShell.SetUseVirDev( pIDsa->get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE));
    rTargetShell.SetAddParaSpacingToTableCells( pIDsa->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS));
    rTargetShell.SetUseFormerLineSpacing( pIDsa->get(IDocumentSettingAccess::OLD_LINE_SPACING));
    rTargetShell.SetUseFormerObjectPositioning( pIDsa->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS));
    rTargetShell.SetConsiderWrapOnObjPos( pIDsa->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION));
    rTargetShell.SetUseFormerTextWrapping( pIDsa->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING));
}
}
/* -----------------09.12.2002 12:35-----------------
 *
 * --------------------------------------------------*/

class SwConnectionDisposedListener_Impl : public cppu::WeakImplHelper1
< lang::XEventListener >
{
    SwNewDBMgr&     rDBMgr;

    virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
public:
    SwConnectionDisposedListener_Impl(SwNewDBMgr& rMgr);
    ~SwConnectionDisposedListener_Impl();

};
// -----------------------------------------------------------------------------
struct SwNewDBMgr_Impl
{
    SwDSParam*          pMergeData;
    AbstractMailMergeDlg*     pMergeDialog;
    uno::Reference<lang::XEventListener> xDisposeListener;

    SwNewDBMgr_Impl(SwNewDBMgr& rDBMgr)
       :pMergeData(0)
       ,pMergeDialog(0)
       ,xDisposeListener(new SwConnectionDisposedListener_Impl(rDBMgr))
        {}
};
/*-- 24.10.2003 15:54:18---------------------------------------------------

  -----------------------------------------------------------------------*/
void lcl_InitNumberFormatter(SwDSParam& rParam, uno::Reference<XDataSource> xSource)
{
    uno::Reference<XMultiServiceFactory> xMgr = ::comphelper::getProcessServiceFactory();
    if( xMgr.is() )
    {
        uno::Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.util.NumberFormatter" ));
        rParam.xFormatter = uno::Reference<util::XNumberFormatter>(xInstance, UNO_QUERY) ;
    }
    if(!xSource.is())
        xSource = SwNewDBMgr::getDataSourceAsParent(rParam.xConnection, rParam.sDataSource);

    uno::Reference<XPropertySet> xSourceProps(xSource, UNO_QUERY);
    if(xSourceProps.is())
    {
        Any aFormats = xSourceProps->getPropertyValue(C2U("NumberFormatsSupplier"));
        if(aFormats.hasValue())
        {
            uno::Reference<XNumberFormatsSupplier> xSuppl;
            aFormats >>= xSuppl;
            if(xSuppl.is())
            {
                uno::Reference< XPropertySet > xSettings = xSuppl->getNumberFormatSettings();
                Any aNull = xSettings->getPropertyValue(C2U("NullDate"));
                aNull >>= rParam.aNullDate;
				if(rParam.xFormatter.is())
					rParam.xFormatter->attachNumberFormatsSupplier(xSuppl);
            }
        }
    }
}
/* -----------------------------17.07.00 17:04--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool lcl_MoveAbsolute(SwDSParam* pParam, long nAbsPos)
{
	sal_Bool bRet = sal_False;
	try
	{
		if(pParam->bScrollable)
		{
			bRet = pParam->xResultSet->absolute( nAbsPos );
		}
		else
		{
            DBG_ERROR("no absolute positioning available");
        }
	}
	catch(Exception aExcept)
	{
	}
	return bRet;
}
/* -----------------------------17.07.00 17:23--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool lcl_GetColumnCnt(SwDSParam* pParam,
	const String& rColumnName, long nLanguage, String& rResult, double* pNumber)
{
    uno::Reference< XColumnsSupplier > xColsSupp( pParam->xResultSet, UNO_QUERY );
    uno::Reference<XNameAccess> xCols;
    try
    {
        xCols = xColsSupp->getColumns();
    }
    catch( lang::DisposedException& )
    {
    }
	if(!xCols.is() || !xCols->hasByName(rColumnName))
		return sal_False;
	Any aCol = xCols->getByName(rColumnName);
    uno::Reference< XPropertySet > xColumnProps;
    aCol >>= xColumnProps;

	SwDBFormatData aFormatData;
    if(!pParam->xFormatter.is())
	{
        uno::Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(
									pParam->xConnection,pParam->sDataSource);
        lcl_InitNumberFormatter(*pParam, xSource );
	}
    aFormatData.aNullDate = pParam->aNullDate;
	aFormatData.xFormatter = pParam->xFormatter;

    MsLangId::convertLanguageToLocale( (LanguageType)nLanguage, aFormatData.aLocale );

	rResult = SwNewDBMgr::GetDBField( xColumnProps, aFormatData, pNumber);
	return sal_True;
};
/*--------------------------------------------------------------------
	Beschreibung: Daten importieren
 --------------------------------------------------------------------*/
sal_Bool SwNewDBMgr::MergeNew(const SwMergeDescriptor& rMergeDesc )
{
    SetMergeType( rMergeDesc.nMergeType );

    DBG_ASSERT(!bInMerge && !pImpl->pMergeData, "merge already activated!");

    SwDBData aData;
    aData.nCommandType = CommandType::TABLE;
    uno::Reference<XResultSet>  xResSet;
    Sequence<Any> aSelection;
    uno::Reference< XConnection> xConnection;

    aData.sDataSource = rMergeDesc.rDescriptor.getDataSource();
    rMergeDesc.rDescriptor[daCommand]      >>= aData.sCommand;
    rMergeDesc.rDescriptor[daCommandType]  >>= aData.nCommandType;

    if ( rMergeDesc.rDescriptor.has(daCursor) )
        rMergeDesc.rDescriptor[daCursor] >>= xResSet;
    if ( rMergeDesc.rDescriptor.has(daSelection) )
        rMergeDesc.rDescriptor[daSelection] >>= aSelection;
    if ( rMergeDesc.rDescriptor.has(daConnection) )
        rMergeDesc.rDescriptor[daConnection] >>= xConnection;

    if(!aData.sDataSource.getLength() || !aData.sCommand.getLength() || !xResSet.is())
	{
		return sal_False;
	}

    pImpl->pMergeData = new SwDSParam(aData, xResSet, aSelection);
    SwDSParam*  pTemp = FindDSData(aData, sal_False);
	if(pTemp)
        *pTemp = *pImpl->pMergeData;
	else
	{
        //#94779# calls from the calculator may have added a connection with an invalid commandtype
        //"real" data base connections added here have to re-use the already available
        //DSData and set the correct CommandType
        SwDBData aTempData(aData);
		aData.nCommandType = -1;
		pTemp = FindDSData(aData, sal_False);
		if(pTemp)
			*pTemp = *pImpl->pMergeData;
		else
        {
			SwDSParam* pInsert = new SwDSParam(*pImpl->pMergeData);
			aDataSourceParams.Insert(pInsert, aDataSourceParams.Count());
			try
			{
                uno::Reference<XComponent> xComponent(pInsert->xConnection, UNO_QUERY);
				if(xComponent.is())
					xComponent->addEventListener(pImpl->xDisposeListener);
			}
			catch(Exception&)
			{
			}
        }
	}
    if(!pImpl->pMergeData->xConnection.is())
        pImpl->pMergeData->xConnection = xConnection;
    // add an XEventListener

	try{
		//set to start position
        if(pImpl->pMergeData->aSelection.getLength())
		{
			sal_Int32 nPos = 0;
			pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos;
            pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos );
            pImpl->pMergeData->CheckEndOfDB();
            if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength())
                pImpl->pMergeData->bEndOfDB = sal_True;
		}
		else
		{
            pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first();
            pImpl->pMergeData->CheckEndOfDB();
		}
	}
    catch(Exception&)
	{
        pImpl->pMergeData->bEndOfDB = sal_True;
        pImpl->pMergeData->CheckEndOfDB();
		DBG_ERROR("exception in MergeNew()");
	}

    uno::Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,aData.sDataSource);

	lcl_InitNumberFormatter(*pImpl->pMergeData, xSource);

    rMergeDesc.rSh.ChgDBData(aData);
	bInMerge = sal_True;

	if (IsInitDBFields())
	{
		// Bei Datenbankfeldern ohne DB-Name DB-Name von Dok einsetzen
		SvStringsDtor aDBNames(1, 1);
		aDBNames.Insert( new String(), 0);
        SwDBData aInsertData = rMergeDesc.rSh.GetDBData();
        String sDBName = aInsertData.sDataSource;
		sDBName += DB_DELIM;
        sDBName += (String)aInsertData.sCommand;
		sDBName += DB_DELIM;
        sDBName += String::CreateFromInt32(aInsertData.nCommandType);
        rMergeDesc.rSh.ChangeDBFields( aDBNames, sDBName);
		SetInitDBFields(sal_False);
	}

	sal_Bool bRet = sal_True;
    switch(rMergeDesc.nMergeType)
	{
		case DBMGR_MERGE:
            bRet = Merge(&rMergeDesc.rSh);   // Mischen
			break;

        case DBMGR_MERGE_MAILMERGE: // printing merge from 'old' merge dialog or from UNO-component
		case DBMGR_MERGE_MAILING:
        case DBMGR_MERGE_MAILFILES:
        case DBMGR_MERGE_SINGLE_FILE:
            // save files and send them as e-Mail if required
            bRet = MergeMailFiles(&rMergeDesc.rSh,
                    rMergeDesc);
			break;

		default:    	// Einfuegen der selektierten Eintraege
						// (war: InsertRecord)
            ImportFromConnection(&rMergeDesc.rSh);
			break;
	}

	EndMerge();
	return bRet;
}

/*--------------------------------------------------------------------
	Beschreibung: Daten importieren
 --------------------------------------------------------------------*/


sal_Bool SwNewDBMgr::Merge(SwWrtShell* pSh)
{
	pSh->StartAllAction();

	pSh->ViewShell::UpdateFlds(sal_True);
	pSh->SetModified();

	pSh->EndAllAction();

	return sal_True;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/
void SwNewDBMgr::ImportFromConnection(	SwWrtShell* pSh )
{
    if(pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB)
	{
		{
			pSh->StartAllAction();
            pSh->StartUndo(UNDO_EMPTY);
			sal_Bool bGroupUndo(pSh->DoesGroupUndo());
			pSh->DoGroupUndo(sal_False);

			if( pSh->HasSelection() )
				pSh->DelRight();

			SwWait *pWait = 0;

			{
				sal_uLong i = 0;
				do {

					ImportDBEntry(pSh);
					if( 10 == ++i )
						pWait = new SwWait( *pSh->GetView().GetDocShell(), true );

				} while(ToNextMergeRecord());
			}

			pSh->DoGroupUndo(bGroupUndo);
            pSh->EndUndo(UNDO_EMPTY);
			pSh->EndAllAction();
			delete pWait;
		}
	}
}
/*-----------------24.02.97 10.30-------------------

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

String 	lcl_FindColumn(const String& sFormatStr,sal_uInt16  &nUsedPos, sal_uInt8 &nSeparator)
{
	String sReturn;
	sal_uInt16 nLen = sFormatStr.Len();
	nSeparator = 0xff;
	while(nUsedPos < nLen && nSeparator == 0xff)
	{
		sal_Unicode cAkt = sFormatStr.GetChar(nUsedPos);
		switch(cAkt)
		{
			case ',':
				nSeparator = DB_SEP_SPACE;
			break;
			case ';':
				nSeparator = DB_SEP_RETURN;
			break;
			case ':':
				nSeparator = DB_SEP_TAB;
			break;
			case '#':
				nSeparator = DB_SEP_NEWLINE;
			break;
			default:
				sReturn += cAkt;
		}
		nUsedPos++;

	}
	return sReturn;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/
void SwNewDBMgr::ImportDBEntry(SwWrtShell* pSh)
{
    if(pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB)
	{
        uno::Reference< XColumnsSupplier > xColsSupp( pImpl->pMergeData->xResultSet, UNO_QUERY );
        uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
        String sFormatStr;
		sal_uInt16 nFmtLen = sFormatStr.Len();
		if( nFmtLen )
		{
			const char cSpace = ' ';
			const char cTab = '\t';
			sal_uInt16 nUsedPos = 0;
			sal_uInt8	nSeparator;
			String sColumn = lcl_FindColumn(sFormatStr, nUsedPos, nSeparator);
			while( sColumn.Len() )
			{
				if(!xCols->hasByName(sColumn))
					return;
				Any aCol = xCols->getByName(sColumn);
                uno::Reference< XPropertySet > xColumnProp;
                aCol >>= xColumnProp;
				if(xColumnProp.is())
				{
					SwDBFormatData aDBFormat;
					String sInsert = GetDBField( xColumnProp,	aDBFormat);
					if( DB_SEP_SPACE == nSeparator )
							sInsert += cSpace;
					else if( DB_SEP_TAB == nSeparator)
							sInsert += cTab;
					pSh->Insert(sInsert);
					if( DB_SEP_RETURN == nSeparator)
						pSh->SplitNode();
					else if(DB_SEP_NEWLINE == nSeparator)
							pSh->InsertLineBreak();
				}
				else
				{
					// Spalte nicht gefunden -> Fehler anzeigen
					String sInsert = '?';
					sInsert += sColumn;
					sInsert += '?';
					pSh->Insert(sInsert);
				}
				sColumn = lcl_FindColumn(sFormatStr, nUsedPos, nSeparator);
			}
			pSh->SplitNode();
		}
		else
		{
			String sStr;
            Sequence<rtl::OUString> aColNames = xCols->getElementNames();
            const rtl::OUString* pColNames = aColNames.getConstArray();
			long nLength = aColNames.getLength();
			for(long i = 0; i < nLength; i++)
			{
				Any aCol = xCols->getByName(pColNames[i]);
                uno::Reference< XPropertySet > xColumnProp;
                aCol >>= xColumnProp;
				SwDBFormatData aDBFormat;
				sStr += GetDBField( xColumnProp, aDBFormat);
				if (i < nLength - 1)
					sStr += '\t';
			}
            pSh->SwEditShell::Insert2(sStr);
			pSh->SwFEShell::SplitNode();	// Zeilenvorschub
		}
	}
}
/*--------------------------------------------------------------------
	Beschreibung: Listbox mit Tabellenliste fuellen
 --------------------------------------------------------------------*/
sal_Bool SwNewDBMgr::GetTableNames(ListBox* pListBox, const String& rDBName)
{
	sal_Bool bRet = sal_False;
    String sOldTableName(pListBox->GetSelectEntry());
	pListBox->Clear();
    SwDSParam* pParam = FindDSConnection(rDBName, sal_False);
    uno::Reference< XConnection> xConnection;
    if(pParam && pParam->xConnection.is())
        xConnection = pParam->xConnection;
    else
    {
        rtl::OUString sDBName(rDBName);
        if ( sDBName.getLength() )
            xConnection = RegisterConnection( sDBName );
    }
	if(xConnection.is())
	{
        uno::Reference<XTablesSupplier> xTSupplier = uno::Reference<XTablesSupplier>(xConnection, UNO_QUERY);
		if(xTSupplier.is())
		{
            uno::Reference<XNameAccess> xTbls = xTSupplier->getTables();
            Sequence<rtl::OUString> aTbls = xTbls->getElementNames();
            const rtl::OUString* pTbls = aTbls.getConstArray();
			for(long i = 0; i < aTbls.getLength(); i++)
            {
                sal_uInt16 nEntry = pListBox->InsertEntry(pTbls[i]);
                pListBox->SetEntryData(nEntry, (void*)0);
            }
		}
        uno::Reference<XQueriesSupplier> xQSupplier = uno::Reference<XQueriesSupplier>(xConnection, UNO_QUERY);
		if(xQSupplier.is())
		{
            uno::Reference<XNameAccess> xQueries = xQSupplier->getQueries();
            Sequence<rtl::OUString> aQueries = xQueries->getElementNames();
            const rtl::OUString* pQueries = aQueries.getConstArray();
			for(long i = 0; i < aQueries.getLength(); i++)
            {
                sal_uInt16 nEntry = pListBox->InsertEntry(pQueries[i]);
                pListBox->SetEntryData(nEntry, (void*)1);
            }
        }
		if (sOldTableName.Len())
			pListBox->SelectEntry(sOldTableName);
		bRet = sal_True;
	}
	return bRet;
}

/*--------------------------------------------------------------------
	Beschreibung: Listbox mit Spaltennamen einer Datenbank fuellen
 --------------------------------------------------------------------*/
sal_Bool SwNewDBMgr::GetColumnNames(ListBox* pListBox,
			const String& rDBName, const String& rTableName, sal_Bool bAppend)
{
	if (!bAppend)
		pListBox->Clear();
    SwDBData aData;
    aData.sDataSource = rDBName;
    aData.sCommand = rTableName;
    aData.nCommandType = -1;
    SwDSParam* pParam = FindDSData(aData, sal_False);
    uno::Reference< XConnection> xConnection;
    if(pParam && pParam->xConnection.is())
        xConnection = pParam->xConnection;
    else
    {
        rtl::OUString sDBName(rDBName);
        xConnection = RegisterConnection( sDBName );
    }
    uno::Reference< XColumnsSupplier> xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName);
	if(xColsSupp.is())
	{
        uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
        const Sequence<rtl::OUString> aColNames = xCols->getElementNames();
        const rtl::OUString* pColNames = aColNames.getConstArray();
		for(int nCol = 0; nCol < aColNames.getLength(); nCol++)
		{
			pListBox->InsertEntry(pColNames[nCol]);
		}
        ::comphelper::disposeComponent( xColsSupp );
    }
    return(sal_True);
}
/* -----------------------------08.06.01 15:11--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool SwNewDBMgr::GetColumnNames(ListBox* pListBox,
        uno::Reference< XConnection> xConnection,
        const String& rTableName, sal_Bool bAppend)
{
	if (!bAppend)
		pListBox->Clear();
    uno::Reference< XColumnsSupplier> xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName);
	if(xColsSupp.is())
	{
        uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
        const Sequence<rtl::OUString> aColNames = xCols->getElementNames();
        const rtl::OUString* pColNames = aColNames.getConstArray();
		for(int nCol = 0; nCol < aColNames.getLength(); nCol++)
		{
			pListBox->InsertEntry(pColNames[nCol]);
		}
        ::comphelper::disposeComponent( xColsSupp );
    }
	return(sal_True);
}

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

SwNewDBMgr::SwNewDBMgr() :
            nMergeType(DBMGR_INSERT),
            bInitDBFields(sal_False),
            bInMerge(sal_False),
            bMergeSilent(sal_False),
            bMergeLock(sal_False),
            pImpl(new SwNewDBMgr_Impl(*this)),
            pMergeEvtSrc(NULL)
{
}
/* -----------------------------18.07.00 08:56--------------------------------

 ---------------------------------------------------------------------------*/
SwNewDBMgr::~SwNewDBMgr()
{
    for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.Count(); nPos++)
    {
        SwDSParam* pParam = aDataSourceParams[nPos];
        if(pParam->xConnection.is())
        {
            try
            {
                uno::Reference<XComponent> xComp(pParam->xConnection, UNO_QUERY);
                if(xComp.is())
                    xComp->dispose();
            }
            catch(const RuntimeException& )
            {
                //may be disposed already since multiple entries may have used the same connection
            }
        }
    }
    delete pImpl;
}

/*--------------------------------------------------------------------
	Beschreibung:	Serienbriefe als einzelne Dokumente speichern
 --------------------------------------------------------------------*/
String lcl_FindUniqueName(SwWrtShell* pTargetShell, const String& rStartingPageDesc, sal_uLong nDocNo )
{
    do
    {
        String sTest = rStartingPageDesc;
        sTest += String::CreateFromInt32( nDocNo );
        if( !pTargetShell->FindPageDescByName( sTest ) )
            return sTest;
        ++nDocNo;
    }while(true);
}
void lcl_CopyDynamicDefaults( const SwDoc& rSource, SwDoc& rTarget )
{
    sal_uInt16 __FAR_DATA aRangeOfDefaults[] = {
        RES_FRMATR_BEGIN, RES_FRMATR_END-1,
        RES_CHRATR_BEGIN, RES_CHRATR_END-1,
        RES_PARATR_BEGIN, RES_PARATR_END-1,
        // --> OD 2008-02-25 #refactorlists##
        RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
        // <--
        RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
        0
    };

    SfxItemSet aNewDefaults( rTarget.GetAttrPool(), aRangeOfDefaults );

    sal_uInt16 nWhich;
    sal_uInt16 nRange = 0;
    while( aRangeOfDefaults[nRange] != 0)
    {
        for( nWhich = aRangeOfDefaults[nRange]; nWhich < aRangeOfDefaults[nRange + 1]; ++nWhich )
        {
            const SfxPoolItem& rSourceAttr = rSource.GetDefault( nWhich );
            if( rSourceAttr != rTarget.GetDefault( nWhich ) )
                aNewDefaults.Put( rSourceAttr );
        }
        nRange += 2;
    }
    if( aNewDefaults.Count() )
        rTarget.SetDefault( aNewDefaults );
}
void lcl_CopyFollowPageDesc(
                            SwWrtShell& rTargetShell,
                            const SwPageDesc& rSourcePageDesc,
                            const SwPageDesc& rTargetPageDesc,
                            const sal_uLong nDocNo )
{
    //now copy the follow page desc, too
    const SwPageDesc* pFollowPageDesc = rSourcePageDesc.GetFollow();
    String sFollowPageDesc = pFollowPageDesc->GetName();
    if( sFollowPageDesc != rSourcePageDesc.GetName() )
    {
        SwDoc* pTargetDoc = rTargetShell.GetDoc();
        String sNewFollowPageDesc = lcl_FindUniqueName(&rTargetShell, sFollowPageDesc, nDocNo );
        sal_uInt16 nNewDesc = pTargetDoc->MakePageDesc( sNewFollowPageDesc );
        SwPageDesc& rTargetFollowPageDesc = pTargetDoc->_GetPageDesc( nNewDesc );

        pTargetDoc->CopyPageDesc( *pFollowPageDesc, rTargetFollowPageDesc, sal_False );
        SwPageDesc aDesc( rTargetPageDesc );
        aDesc.SetFollow( &rTargetFollowPageDesc );
        pTargetDoc->ChgPageDesc( rTargetPageDesc.GetName(), aDesc );
    }
}

void lcl_RemoveSectionLinks( SwWrtShell& rWorkShell )
{
    //reset all links of the sections of synchronized labels
    sal_uInt16 nSections = rWorkShell.GetSectionFmtCount();
    for( sal_uInt16 nSection = 0; nSection < nSections; ++nSection )
    {
        SwSectionData aSectionData( *rWorkShell.GetSectionFmt( nSection ).GetSection() );
        if( aSectionData.GetType() == FILE_LINK_SECTION )
        {
            aSectionData.SetType( CONTENT_SECTION );
            aSectionData.SetLinkFileName( String() );
            rWorkShell.UpdateSection( nSection, aSectionData );
        }    
    }    
    rWorkShell.SetLabelDoc( sal_False );
}    

sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
        const SwMergeDescriptor& rMergeDescriptor)
{
	//check if the doc is synchronized and contains at least one linked section
    sal_Bool bSynchronizedDoc = pSourceShell->IsLabelDoc() && pSourceShell->GetSectionFmtCount() > 1;
	sal_Bool bLoop = sal_True;
    sal_Bool bEMail = rMergeDescriptor.nMergeType == DBMGR_MERGE_MAILING;
    const bool bAsSingleFile = rMergeDescriptor.nMergeType == DBMGR_MERGE_SINGLE_FILE;

    ::rtl::Reference< MailDispatcher >          xMailDispatcher;
    ::rtl::OUString sBodyMimeType;
    rtl_TextEncoding eEncoding = ::gsl_getSystemTextEncoding();

    if(bEMail)
    {
        xMailDispatcher.set( new MailDispatcher(rMergeDescriptor.xSmtpServer));
        if(!rMergeDescriptor.bSendAsAttachment && rMergeDescriptor.bSendAsHTML)
        {
            sBodyMimeType = ::rtl::OUString::createFromAscii("text/html; charset=");
            sBodyMimeType += ::rtl::OUString::createFromAscii(
                                rtl_getBestMimeCharsetFromTextEncoding( eEncoding ));
            SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get();
            eEncoding = pHtmlOptions->GetTextEncoding();
        }
        else
            sBodyMimeType =
                ::rtl::OUString::createFromAscii("text/plain; charset=UTF-8; format=flowed");
    }

    uno::Reference< XPropertySet > xColumnProp;
	{
		sal_Bool bColumnName = sEMailAddrFld.Len() > 0;

		if (bColumnName)
		{
            uno::Reference< XColumnsSupplier > xColsSupp( pImpl->pMergeData->xResultSet, UNO_QUERY );
            uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
			if(!xCols->hasByName(sEMailAddrFld))
				return sal_False;
			Any aCol = xCols->getByName(sEMailAddrFld);
            aCol >>= xColumnProp;
		}

        SfxDispatcher* pSfxDispatcher = pSourceShell->GetView().GetViewFrame()->GetDispatcher();
        SwDocShell* pSourrceDocSh = pSourceShell->GetView().GetDocShell();
        pSfxDispatcher->Execute( pSourrceDocSh->HasName() ? SID_SAVEDOC : SID_SAVEASDOC, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD);
        // has document been saved successfully?
        if( !pSourrceDocSh->IsModified() )
		{
            SfxMedium* pOrig = pSourceShell->GetView().GetDocShell()->GetMedium();
            String sSourceDocumentURL(pOrig->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ));
			const SfxFilter* pSfxFlt = SwIoSystem::GetFileFilter(
                                                    sSourceDocumentURL, ::aEmptyStr );
            const SfxFilter* pStoreToFilter = pSfxFlt;
            SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer();
            const String* pStoreToFilterOptions = 0;
            // if a save_to filter is set then use it - otherwise use the default
            if( bEMail && !rMergeDescriptor.bSendAsAttachment )
            {
                String sExtension( String::CreateFromAscii(
                        rMergeDescriptor.bSendAsHTML ? "html" : "txt" ));
                pStoreToFilter = pFilterContainer->GetFilter4Extension(sExtension, SFX_FILTER_EXPORT);
            }
            else if( rMergeDescriptor.sSaveToFilter.Len())
            {
                const SfxFilter* pFilter =
                        pFilterContainer->GetFilter4FilterName( rMergeDescriptor.sSaveToFilter );
                if(pFilter)
                {
                    pStoreToFilter = pFilter;
                    if(rMergeDescriptor.sSaveToFilterOptions.Len())
                        pStoreToFilterOptions = &rMergeDescriptor.sSaveToFilterOptions;
                }
            }
			bCancel = sal_False;

            // in case of creating a single resulting file this has to be created here
            SwWrtShell* pTargetShell = 0;

            // the shell will be explicitly closed at the end of the method, but it is
            // still more safe to use SfxObjectShellLock here
            SfxObjectShellLock xTargetDocShell;

            SwView* pTargetView = 0;
            std::auto_ptr< utl::TempFile > aTempFile;
            String sModifiedStartingPageDesc;
            String sStartingPageDesc;
            sal_uInt16 nStartingPageNo = 0;
            bool bPageStylesWithHeaderFooter = false;
            if(bAsSingleFile || rMergeDescriptor.bCreateSingleFile)
            {
                // create a target docshell to put the merged document into
                xTargetDocShell = new SwDocShell( SFX_CREATE_MODE_STANDARD );
                xTargetDocShell->DoInitNew( 0 );
                SfxViewFrame* pTargetFrame = SfxViewFrame::LoadHiddenDocument( *xTargetDocShell, 0 );

                pTargetView = static_cast<SwView*>( pTargetFrame->GetViewShell() );

                //initiate SelectShell() to create sub shells
                pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() );
                pTargetShell = pTargetView->GetWrtShellPtr();
                //copy the styles from the source to the target document
                SwgReaderOption aOpt;
                aOpt.SetTxtFmts( sal_True );
                aOpt.SetFrmFmts( sal_True );
                aOpt.SetPageDescs( sal_True );
                aOpt.SetNumRules( sal_True );
                aOpt.SetMerge( sal_False );
                pTargetView->GetDocShell()->LoadStylesFromFile(
                        sSourceDocumentURL, aOpt, sal_True );
                //determine the page style and number used at the start of the source document
                pSourceShell->SttEndDoc(sal_True);
                nStartingPageNo = pSourceShell->GetVirtPageNum();
                sStartingPageDesc = sModifiedStartingPageDesc = pSourceShell->GetPageDesc(
                                            pSourceShell->GetCurPageDesc()).GetName();
                // #122799# copy compatibility options
                lcl_CopyCompatibilityOptions( *pSourceShell, *pTargetShell);
                // #72821# copy dynamic defaults
                lcl_CopyDynamicDefaults( *pSourceShell->GetDoc(), *pTargetShell->GetDoc() );
                // #i72517#
                const SwPageDesc* pSourcePageDesc = pSourceShell->FindPageDescByName( sStartingPageDesc );
                const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster();
                bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive()  ||
                                                rMaster.GetFooter().IsActive();

            }

            PrintMonitor aPrtMonDlg(&pSourceShell->GetView().GetEditWin(), PrintMonitor::MONITOR_TYPE_PRINT);
            aPrtMonDlg.aDocName.SetText(pSourceShell->GetView().GetDocShell()->GetTitle(22));

			aPrtMonDlg.aCancel.SetClickHdl(LINK(this, SwNewDBMgr, PrtCancelHdl));
            if (!IsMergeSilent())
                aPrtMonDlg.Show();

			// Progress, um KeyInputs zu unterbinden
            SfxProgress aProgress(pSourrceDocSh, ::aEmptyStr, 1);

			// Alle Dispatcher sperren
            SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst(pSourrceDocSh);
			while (pViewFrm)
			{
				pViewFrm->GetDispatcher()->Lock(sal_True);
                pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourrceDocSh);
			}
			sal_uLong nDocNo = 1;

            long nStartRow, nEndRow;
            // collect temporary files
            ::std::vector< String> aFilesToRemove;
            do
            {
                nStartRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0;
                {
					String sPath(sSubject);

                    String sAddress;
                    if( !bEMail && bColumnName )
					{
						SwDBFormatData aDBFormat;
						aDBFormat.xFormatter = pImpl->pMergeData->xFormatter;
						aDBFormat.aNullDate = pImpl->pMergeData->aNullDate;
						sAddress = GetDBField( xColumnProp,	aDBFormat);
						if (!sAddress.Len())
							sAddress = '_';
						sPath += sAddress;
					}

                    // create a new temporary file name - only done once in case of bCreateSingleFile
                    if( 1 == nDocNo || (!rMergeDescriptor.bCreateSingleFile && !bAsSingleFile) )
                    {
                        INetURLObject aEntry(sPath);
                        String sLeading;
                        //#i97667# if the name is from a database field then it will be used _as is_
                        if( sAddress.Len() )
                            sLeading = sAddress;
                        else
                            sLeading = aEntry.GetBase();
                        aEntry.removeSegment();
                        sPath = aEntry.GetMainURL( INetURLObject::NO_DECODE );
                        String sExt( pStoreToFilter->GetDefaultExtension() );
                        sExt.EraseLeadingChars('*');
                        aTempFile = std::auto_ptr< utl::TempFile >(
                                new utl::TempFile(sLeading,&sExt,&sPath ));
                        if( bAsSingleFile )
                            aTempFile->EnableKillingFile();
                    }

                    if( !aTempFile->IsValid() )
					{
						ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED );
						bLoop = sal_False;
						bCancel = sal_True;
					}
					else
					{
                        INetURLObject aTempFileURL(aTempFile->GetURL());
                        aPrtMonDlg.aPrinter.SetText( aTempFileURL.GetBase() );
						String sStat(SW_RES(STR_STATSTR_LETTER));	// Brief
						sStat += ' ';
						sStat += String::CreateFromInt32( nDocNo );
						aPrtMonDlg.aPrintInfo.SetText(sStat);

						// Rechenzeit fuer Save-Monitor:
						for (sal_uInt16 i = 0; i < 10; i++)
							Application::Reschedule();

						// Create and save new document
                        // The SfxObjectShell will be closed explicitly later but it is more safe to use SfxObjectShellLock here
                        SfxObjectShellLock xWorkDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL ));
                        SfxMedium* pWorkMed = new SfxMedium( sSourceDocumentURL, STREAM_STD_READ, sal_True );
                        pWorkMed->SetFilter( pSfxFlt );

                        if (xWorkDocSh->DoLoad(pWorkMed))
						{
                            //create a view frame for the document
                            SfxViewFrame* pWorkFrame = SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 );
                            //request the layout calculation
                            SwWrtShell& rWorkShell =
                                    static_cast< SwView* >(pWorkFrame->GetViewShell())->GetWrtShell();
                            rWorkShell.CalcLayout();
                            SwDoc* pWorkDoc = ((SwDocShell*)(&xWorkDocSh))->GetDoc();
                            SwNewDBMgr* pOldDBMgr = pWorkDoc->GetNewDBMgr();
                            pWorkDoc->SetNewDBMgr( this );
                            SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), xWorkDocSh));
                            pWorkDoc->UpdateFlds(NULL, false);
                            SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), xWorkDocSh));

							// alle versteckten Felder/Bereiche entfernen
                            pWorkDoc->RemoveInvisibleContent();

                            // launch MailMergeEvent if required
                            const SwXMailMerge *pEvtSrc = GetMailMergeEvtSrc();
                            if(pEvtSrc)
                            {
                                uno::Reference< XInterface > xRef( (XMailMergeBroadcaster *) pEvtSrc );
                                text::MailMergeEvent aEvt( xRef, xWorkDocSh->GetModel() );
                                pEvtSrc->LaunchMailMergeEvent( aEvt );
                            }

                            if(rMergeDescriptor.bCreateSingleFile || bAsSingleFile )
                            {
                                DBG_ASSERT( pTargetShell, "no target shell available!" );
                                // copy created file into the target document
                                rWorkShell.ConvertFieldsToText();
                                rWorkShell.SetNumberingRestart();
                                if( bSynchronizedDoc )
                                {
                                    lcl_RemoveSectionLinks( rWorkShell );
                                }    

                                // insert the document into the target document
                                rWorkShell.SttEndDoc(sal_False);
                                rWorkShell.SttEndDoc(sal_True);
                                rWorkShell.SelAll();
                                pTargetShell->SwCrsrShell::SttEndDoc( sal_False );
                                //#i72517# the headers and footers are still those from the source - update in case of fields inside header/footer
                                if( !nDocNo && bPageStylesWithHeaderFooter )
                                    pTargetShell->GetView().GetDocShell()->_LoadStyles( *rWorkShell.GetView().GetDocShell(), sal_True );
                                //#i72517# put the styles to the target document
                                //if the source uses headers or footers each new copy need to copy a new page styles
                                if(bPageStylesWithHeaderFooter)
                                {
                                    //create a new pagestyle
                                    //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style

                                    SwDoc* pTargetDoc = pTargetShell->GetDoc();
                                    SwPageDesc* pSourcePageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc );
                                    String sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo );
                                    pTargetDoc->MakePageDesc( sNewPageDescName );
                                    SwPageDesc* pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName );
                                    if(pSourcePageDesc && pTargetPageDesc)
                                    {
                                        pTargetDoc->CopyPageDesc( *pSourcePageDesc, *pTargetPageDesc, sal_False );
                                        sModifiedStartingPageDesc = sNewPageDescName;
                                        lcl_CopyFollowPageDesc( *pTargetShell, *pSourcePageDesc, *pTargetPageDesc, nDocNo );
                                    }
                                }

                                if(nDocNo > 1)
                                    pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo );
                                else
                                    pTargetShell->SetPageStyle(sModifiedStartingPageDesc);
                                DBG_ASSERT(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended");
                                //#i51359# add a second paragraph in case there's only one
                                {
                                    SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 );
                                    SwPosition aTestPos( aIdx );
                                    SwCursor aTestCrsr(aTestPos,0,false);
                                    if(!aTestCrsr.MovePara(fnParaNext, fnParaStart))
                                    {
                                        //append a paragraph
                                        pWorkDoc->AppendTxtNode( aTestPos );
                                    }
                                }
                                pTargetShell->Paste( rWorkShell.GetDoc(), sal_True );

                                //convert fields in page styles (header/footer - has to be done after the first document has been pasted
                                if(1 == nDocNo)
                                {
                                    pTargetShell->CalcLayout();
                                    pTargetShell->ConvertFieldsToText();
                                }
                            }
                            else
                            {
                                String sFileURL =  aTempFileURL.GetMainURL( INetURLObject::NO_DECODE );
                                SfxMedium* pDstMed = new SfxMedium(
                                    sFileURL,
                                    STREAM_STD_READWRITE, sal_True );
                                pDstMed->SetFilter( pStoreToFilter );
                                if(pDstMed->GetItemSet())
                                {
                                    if(pStoreToFilterOptions )
                                        pDstMed->GetItemSet()->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, *pStoreToFilterOptions));
                                    if(rMergeDescriptor.aSaveToFilterData.getLength())
                                        pDstMed->GetItemSet()->Put(SfxUsrAnyItem(SID_FILTER_DATA, makeAny(rMergeDescriptor.aSaveToFilterData)));
                                }

                                //convert fields to text if we are exporting to PDF
                                //this prevents a second merge while updating the fields in SwXTextDocument::getRendererCount()
                                if( pStoreToFilter && pStoreToFilter->GetFilterName().EqualsAscii("writer_pdf_Export"))
                                    rWorkShell.ConvertFieldsToText();
                                xWorkDocSh->DoSaveAs(*pDstMed);
                                xWorkDocSh->DoSaveCompleted(pDstMed);
                                if( xWorkDocSh->GetError() )
                                {
                                    // error message ??
                                    ErrorHandler::HandleError( xWorkDocSh->GetError() );
                                    bCancel = sal_True;
                                    bLoop = sal_False;
                                }
                                if( bEMail )
                                {
                                    SwDBFormatData aDBFormat;
                                    aDBFormat.xFormatter = pImpl->pMergeData->xFormatter;
                                    aDBFormat.aNullDate = pImpl->pMergeData->aNullDate;
                                    String sMailAddress = GetDBField( xColumnProp, aDBFormat);
                                    if(!SwMailMergeHelper::CheckMailAddress( sMailAddress ))
                                    {
                                        DBG_ERROR("invalid e-Mail address in database column");
                                    }
                                    else
                                    {
                                        SwMailMessage* pMessage = 0;
                                        uno::Reference< mail::XMailMessage > xMessage =
                                                                pMessage = new SwMailMessage;
                                        if(rMergeDescriptor.pMailMergeConfigItem->IsMailReplyTo())
                                            pMessage->setReplyToAddress(rMergeDescriptor.pMailMergeConfigItem->GetMailReplyTo());
                                        pMessage->addRecipient( sMailAddress );
                                        pMessage->SetSenderAddress( rMergeDescriptor.pMailMergeConfigItem->GetMailAddress() );
                                        ::rtl::OUString sBody;
                                        if(rMergeDescriptor.bSendAsAttachment)
                                        {
                                            sBody = rMergeDescriptor.sMailBody;
                                            mail::MailAttachment aAttach;
                                            aAttach.Data = new SwMailTransferable(
                                                    sFileURL,
                                                    rMergeDescriptor.sAttachmentName,
                                                    pStoreToFilter->GetMimeType());
                                            aAttach.ReadableName = rMergeDescriptor.sAttachmentName;
                                            pMessage->addAttachment( aAttach );
                                        }
                                        else
                                        {
                                            {
                                                //read in the temporary file and use it as mail body
                                                SfxMedium aMedium( sFileURL, STREAM_READ, sal_True);
                                                SvStream* pInStream = aMedium.GetInStream();
                                                DBG_ASSERT(pInStream, "no output file created?");
                                                if(pInStream)
                                                {
                                                    pInStream->SetStreamCharSet( eEncoding );
                                                    ByteString sLine;
                                                    sal_Bool bDone = pInStream->ReadLine( sLine );
                                                    while ( bDone )
                                                    {
                                                        sBody += String(sLine, eEncoding);
                                                        sBody += ::rtl::OUString('\n');
                                                        bDone = pInStream->ReadLine( sLine );
                                                    }
                                                }
                                            }
                                        }
                                        pMessage->setSubject( rMergeDescriptor.sSubject );
                                        uno::Reference< datatransfer::XTransferable> xBody =
                                                    new SwMailTransferable(
                                                        sBody,
                                                        sBodyMimeType);
                                        pMessage->setBody( xBody );

                                        if(rMergeDescriptor.aCopiesTo.getLength())
                                        {
                                            const ::rtl::OUString* pCopies = rMergeDescriptor.aCopiesTo.getConstArray();
                                            for( sal_Int32 nToken = 0; nToken < rMergeDescriptor.aCopiesTo.getLength(); ++nToken)
                                                pMessage->addCcRecipient( pCopies[nToken] );
                                        }
                                        if(rMergeDescriptor.aBlindCopiesTo.getLength())
                                        {
                                            const ::rtl::OUString* pCopies = rMergeDescriptor.aBlindCopiesTo.getConstArray();
                                            for( sal_Int32 nToken = 0; nToken < rMergeDescriptor.aBlindCopiesTo.getLength(); ++nToken)
                                                pMessage->addBccRecipient( pCopies[nToken] );
                                        }
                                        xMailDispatcher->enqueueMailMessage( xMessage );
                                        if(!xMailDispatcher->isStarted())
                                                xMailDispatcher->start();
                                        //schedule for removal
                                        aFilesToRemove.push_back(sFileURL);
                                    }
                                }
                            }
                            pWorkDoc->SetNewDBMgr( pOldDBMgr );
						}
                        xWorkDocSh->DoClose();
					}
				}
                nDocNo++;
                nEndRow = pImpl->pMergeData ? pImpl->pMergeData->xResultSet->getRow() : 0;
            } while( !bCancel &&
                (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord()));
            
            aPrtMonDlg.Show( sal_False );
            
            // save the single output document
            if(rMergeDescriptor.bCreateSingleFile || bAsSingleFile)
            {
                if( rMergeDescriptor.nMergeType != DBMGR_MERGE_MAILMERGE )
                {
                    DBG_ASSERT( aTempFile.get(), "Temporary file not available" );
                    INetURLObject aTempFileURL(bAsSingleFile ? sSubject : aTempFile->GetURL());
                    SfxMedium* pDstMed = new SfxMedium(
                        aTempFileURL.GetMainURL( INetURLObject::NO_DECODE ),
                        STREAM_STD_READWRITE, sal_True );
                    pDstMed->SetFilter( pStoreToFilter );
                    if(pDstMed->GetItemSet())
                    {
                        if(pStoreToFilterOptions )
                            pDstMed->GetItemSet()->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, *pStoreToFilterOptions));
                        if(rMergeDescriptor.aSaveToFilterData.getLength())
                            pDstMed->GetItemSet()->Put(SfxUsrAnyItem(SID_FILTER_DATA, makeAny(rMergeDescriptor.aSaveToFilterData)));
                    }

                    xTargetDocShell->DoSaveAs(*pDstMed);
                    xTargetDocShell->DoSaveCompleted(pDstMed);
                    if( xTargetDocShell->GetError() )
                    {
                        // error message ??
                        ErrorHandler::HandleError( xTargetDocShell->GetError() );
                        bLoop = sal_False;
                    }
                }
                else if( pTargetView ) // must be available!
                {
                    //print the target document
        #if OSL_DEBUG_LEVEL > 1
                    sal_Bool  _bVal;
                    sal_Int16 _nVal;
                    rtl::OUString  _sVal;
                    const beans::PropertyValue* pDbgPrintOptions = rMergeDescriptor.aPrintOptions.getConstArray();
                    for( sal_Int32 nOption = 0; nOption < rMergeDescriptor.aPrintOptions.getLength(); ++nOption)
                    {
                        rtl::OUString aName( pDbgPrintOptions[nOption].Name );
                        uno::Any aVal( pDbgPrintOptions[nOption].Value );
                        aVal >>= _bVal;
                        aVal >>= _nVal;
                        aVal >>= _sVal;
                    }
        #endif
                    // printing should be done synchronously otherwise the document 
                    // might already become invalid during the process
                    uno::Sequence< beans::PropertyValue > aOptions( rMergeDescriptor.aPrintOptions );
                    const sal_Int32 nOpts = aOptions.getLength();
                    aOptions.realloc( nOpts + 1 );
                    aOptions[ nOpts ].Name = rtl::OUString::createFromAscii( "Wait" );
                    aOptions[ nOpts ].Value <<= sal_True ;
//                    aPrintArgs.Put(SfxBoolItem(FN_QRY_MERGE, sal_True) ); 
//                    // #i52629# aynchronous printing should only be done in silent mode - otherwise
//                    // the printer dialog does not come up
//                    aPrintArgs.Put( SfxBoolItem( SID_ASYNCHRON, rMergeDescriptor.bPrintAsync ));
                    // move print options 
                    const beans::PropertyValue* pPrintOptions = rMergeDescriptor.aPrintOptions.getConstArray();
                    for( sal_Int32 nOption = 0; nOption < rMergeDescriptor.aPrintOptions.getLength(); ++nOption)
                    {
                        if( pPrintOptions[nOption].Name.equalsAscii( "CopyCount" )
                            ||( pPrintOptions[nOption].Name.equalsAscii( "FileName" ))
                            ||( pPrintOptions[nOption].Name.equalsAscii( "Collate" ))
                            ||( pPrintOptions[nOption].Name.equalsAscii( "Pages" ))
                            ||( pPrintOptions[nOption].Name.equalsAscii( "Wait" )))
                        {
                            aOptions.realloc( nOpts + 1 );
                            aOptions[ nOpts ].Name = pPrintOptions[nOption].Name;
                            aOptions[ nOpts ].Value = pPrintOptions[nOption].Value ;
                        }
                    }

//                    const SwModuleOptions * pModOpt = SW_MOD()->GetModuleConfig();
//                    if (pModOpt->IsSinglePrintJob())
//                    {
//                    }    
//                    else
//                    {
                        pTargetView->ExecPrint( aOptions, IsMergeSilent(), rMergeDescriptor.bPrintAsync );
//                    }    
                }
                xTargetDocShell->DoClose();
            }

            //remove the temporary files
            ::std::vector<String>::iterator aFileIter;
            for(aFileIter = aFilesToRemove.begin();
                        aFileIter != aFilesToRemove.end(); aFileIter++)
                SWUnoHelper::UCB_DeleteFile( *aFileIter );

            // Alle Dispatcher freigeben
            pViewFrm = SfxViewFrame::GetFirst(pSourrceDocSh);
			while (pViewFrm)
			{
				pViewFrm->GetDispatcher()->Lock(sal_False);
                pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourrceDocSh);
			}

            SW_MOD()->SetView(&pSourceShell->GetView());
		}

		nMergeType = DBMGR_INSERT;
	}

    if(bEMail)
    {
        xMailDispatcher->stop();
        xMailDispatcher->shutdown();

    }

    return bLoop;
}

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

IMPL_LINK_INLINE_START( SwNewDBMgr, PrtCancelHdl, Button *, pButton )
{
	pButton->GetParent()->Hide();
	bCancel = sal_True;
	return 0;
}
IMPL_LINK_INLINE_END( SwNewDBMgr, PrtCancelHdl, Button *, pButton )


/*--------------------------------------------------------------------
	Beschreibung: Numberformat der Spalte ermitteln und ggfs. in
					den uebergebenen Formatter uebertragen
  --------------------------------------------------------------------*/

sal_uLong SwNewDBMgr::GetColumnFmt( const String& rDBName,
								const String& rTableName,
								const String& rColNm,
								SvNumberFormatter* pNFmtr,
								long nLanguage )
{
	sal_uLong nRet = 0;
	if(pNFmtr)
	{
        uno::Reference< XDataSource> xSource;
        uno::Reference< XConnection> xConnection;
        sal_Bool bUseMergeData = sal_False;
        uno::Reference< XColumnsSupplier> xColsSupp;
        bool bDisposeConnection = false;
        if(pImpl->pMergeData &&
            pImpl->pMergeData->sDataSource.equals(rDBName) && pImpl->pMergeData->sCommand.equals(rTableName))
		{
            xConnection = pImpl->pMergeData->xConnection;
            xSource = SwNewDBMgr::getDataSourceAsParent(xConnection,rDBName);
            bUseMergeData = sal_True;
            xColsSupp = xColsSupp.query( pImpl->pMergeData->xResultSet );
		}
        if(!xConnection.is())
        {
            SwDBData aData;
            aData.sDataSource = rDBName;
            aData.sCommand = rTableName;
            aData.nCommandType = -1;
            SwDSParam* pParam = FindDSData(aData, sal_False);
            if(pParam && pParam->xConnection.is())
            {
                xConnection = pParam->xConnection;
                xColsSupp = xColsSupp.query( pParam->xResultSet );
            }
            else
            {
                rtl::OUString sDBName(rDBName);
                xConnection = RegisterConnection( sDBName );
                bDisposeConnection = true;
            }
            if(bUseMergeData)
                pImpl->pMergeData->xConnection = xConnection;
        }
        bool bDispose = !xColsSupp.is();
        if(bDispose)
        {
            xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName);
        }
		if(xColsSupp.is())
		{
            uno::Reference<XNameAccess> xCols;
            try
            {
                xCols = xColsSupp->getColumns();
            }
            catch(Exception&)
            {
                DBG_ERROR("Exception in getColumns()");
            }
            if(!xCols.is() || !xCols->hasByName(rColNm))
				return nRet;
			Any aCol = xCols->getByName(rColNm);
            uno::Reference< XPropertySet > xColumn;
            aCol >>= xColumn;
            nRet = GetColumnFmt(xSource, xConnection, xColumn, pNFmtr, nLanguage);
            if(bDispose)
            {
                ::comphelper::disposeComponent( xColsSupp );
            }
            if(bDisposeConnection)
            {
                ::comphelper::disposeComponent( xConnection );
            }
        }
        else
			nRet = pNFmtr->GetFormatIndex( NF_NUMBER_STANDARD, LANGUAGE_SYSTEM );
	}
	return nRet;
}
/* -----------------------------07.06.01 15:43--------------------------------

 ---------------------------------------------------------------------------*/
sal_uLong SwNewDBMgr::GetColumnFmt( uno::Reference< XDataSource> xSource,
                        uno::Reference< XConnection> xConnection,
                        uno::Reference< XPropertySet> xColumn,
						SvNumberFormatter* pNFmtr,
                        long nLanguage )
{
	//JP 12.01.99: ggfs. das NumberFormat im Doc setzen
	sal_uLong nRet = 0;

    if(!xSource.is())
    {
        uno::Reference<XChild> xChild(xConnection, UNO_QUERY);
        if ( xChild.is() )
            xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY);
    }
    if(xSource.is() && xConnection.is() && xColumn.is() && pNFmtr)
	{
		SvNumberFormatsSupplierObj* pNumFmt = new SvNumberFormatsSupplierObj( pNFmtr );
        uno::Reference< util::XNumberFormatsSupplier >  xDocNumFmtsSupplier = pNumFmt;
        uno::Reference< XNumberFormats > xDocNumberFormats = xDocNumFmtsSupplier->getNumberFormats();
        uno::Reference< XNumberFormatTypes > xDocNumberFormatTypes(xDocNumberFormats, UNO_QUERY);

		Locale aLocale( MsLangId::convertLanguageToLocale( (LanguageType)nLanguage ));

		//get the number formatter of the data source
        uno::Reference<XPropertySet> xSourceProps(xSource, UNO_QUERY);
        uno::Reference< XNumberFormats > xNumberFormats;
		if(xSourceProps.is())
		{
			Any aFormats = xSourceProps->getPropertyValue(C2U("NumberFormatsSupplier"));
			if(aFormats.hasValue())
			{
                uno::Reference<XNumberFormatsSupplier> xSuppl;
                aFormats >>= xSuppl;
				if(xSuppl.is())
				{
					xNumberFormats = xSuppl->getNumberFormats();
				}
			}
		}
        bool bUseDefault = true;
        try
        {
            Any aFormatKey = xColumn->getPropertyValue(C2U("FormatKey"));
            if(aFormatKey.hasValue())
            {
                sal_Int32 nFmt = 0;
                aFormatKey >>= nFmt;
                if(xNumberFormats.is())
                {
                    try
                    {
                        uno::Reference<XPropertySet> xNumProps = xNumberFormats->getByKey( nFmt );
                        Any aFormatString = xNumProps->getPropertyValue(C2U("FormatString"));
                        Any aLocaleVal = xNumProps->getPropertyValue(C2U("Locale"));
                        rtl::OUString sFormat;
                        aFormatString >>= sFormat;
                        lang::Locale aLoc;
                        aLocaleVal >>= aLoc;
                        nFmt = xDocNumberFormats->queryKey( sFormat, aLoc, sal_False );
                        if(NUMBERFORMAT_ENTRY_NOT_FOUND == sal::static_int_cast< sal_uInt32, sal_Int32>(nFmt))
                            nFmt = xDocNumberFormats->addNew( sFormat, aLoc );
                        nRet = nFmt;
                        bUseDefault = false;
                    }
                    catch(const Exception&)
                    {
                        DBG_ERROR("illegal number format key");
                    }
                }
            }
        }
        catch( const Exception& )
        {
            DBG_ERROR("no FormatKey property found");
        }
        if(bUseDefault)
            nRet = SwNewDBMgr::GetDbtoolsClient().getDefaultNumberFormat(xColumn, xDocNumberFormatTypes,  aLocale);
	}
	return nRet;
}

/* -----------------------------17.07.00 09:47--------------------------------

 ---------------------------------------------------------------------------*/
sal_Int32 SwNewDBMgr::GetColumnType( const String& rDBName,
						  const String& rTableName,
						  const String& rColNm )
{
	sal_Int32 nRet = DataType::SQLNULL;
    SwDBData aData;
    aData.sDataSource = rDBName;
    aData.sCommand = rTableName;
    aData.nCommandType = -1;
    SwDSParam* pParam = FindDSData(aData, sal_False);
    uno::Reference< XConnection> xConnection;
    uno::Reference< XColumnsSupplier > xColsSupp;
    bool bDispose = false;
    if(pParam && pParam->xConnection.is())
    {
        xConnection = pParam->xConnection;
        xColsSupp = uno::Reference< XColumnsSupplier >( pParam->xResultSet, UNO_QUERY );
    }
    else
    {
        rtl::OUString sDBName(rDBName);
        xConnection = RegisterConnection( sDBName );
    }
    if( !xColsSupp.is() )
    {
        xColsSupp = SwNewDBMgr::GetColumnSupplier(xConnection, rTableName);
        bDispose = true;
    }
	if(xColsSupp.is())
	{
        uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
		if(xCols->hasByName(rColNm))
		{
			Any aCol = xCols->getByName(rColNm);
            uno::Reference<XPropertySet> xCol;
            aCol >>= xCol;
			Any aType = xCol->getPropertyValue(C2S("Type"));
			aType >>= nRet;
		}
        if(bDispose)
            ::comphelper::disposeComponent( xColsSupp );
    }
	return nRet;
}

/* -----------------------------03.07.00 17:12--------------------------------

 ---------------------------------------------------------------------------*/
uno::Reference< sdbc::XConnection> SwNewDBMgr::GetConnection(const String& rDataSource,
                                                    uno::Reference<XDataSource>& rxSource)
{
	Reference< sdbc::XConnection> xConnection;
	Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
	try
	{
		Reference<XCompletedConnection> xComplConnection(SwNewDBMgr::GetDbtoolsClient().getDataSource(rDataSource, xMgr),UNO_QUERY);
		if ( xComplConnection.is() )
		{
			rxSource.set(xComplConnection,UNO_QUERY);
			Reference< XInteractionHandler > xHandler(
					xMgr->createInstance( C2U( "com.sun.star.task.InteractionHandler" )), UNO_QUERY);
				xConnection = xComplConnection->connectWithCompletion( xHandler );
		}
	}
	catch(Exception&) {}

	return xConnection;
}
/* -----------------------------03.07.00 17:12--------------------------------

 ---------------------------------------------------------------------------*/
uno::Reference< sdbcx::XColumnsSupplier> SwNewDBMgr::GetColumnSupplier(uno::Reference<sdbc::XConnection> xConnection,
									const String& rTableOrQuery,
									sal_uInt8	eTableOrQuery)
{
    Reference< sdbcx::XColumnsSupplier> xRet;
    try
    {
        if(eTableOrQuery == SW_DB_SELECT_UNKNOWN)
        {
            //search for a table with the given command name
            Reference<XTablesSupplier> xTSupplier = Reference<XTablesSupplier>(xConnection, UNO_QUERY);
            if(xTSupplier.is())
            {
                Reference<XNameAccess> xTbls = xTSupplier->getTables();
                eTableOrQuery = xTbls->hasByName(rTableOrQuery) ?
                            SW_DB_SELECT_TABLE : SW_DB_SELECT_QUERY;
            }
        }
        sal_Int32 nCommandType = SW_DB_SELECT_TABLE == eTableOrQuery ?
                CommandType::TABLE : CommandType::QUERY;
        Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
        Reference<XRowSet> xRowSet(
                xMgr->createInstance(C2U("com.sun.star.sdb.RowSet")), UNO_QUERY);

        ::rtl::OUString sDataSource;
        Reference<XDataSource> xSource = SwNewDBMgr::getDataSourceAsParent(xConnection, sDataSource);
        Reference<XPropertySet> xSourceProperties(xSource, UNO_QUERY);
        if(xSourceProperties.is())
        {
            xSourceProperties->getPropertyValue(C2U("Name")) >>= sDataSource;
        }

        Reference<XPropertySet> xRowProperties(xRowSet, UNO_QUERY);
        xRowProperties->setPropertyValue(C2U("DataSourceName"), makeAny(sDataSource));
        xRowProperties->setPropertyValue(C2U("Command"), makeAny(::rtl::OUString(rTableOrQuery)));
        xRowProperties->setPropertyValue(C2U("CommandType"), makeAny(nCommandType));
        xRowProperties->setPropertyValue(C2U("FetchSize"), makeAny((sal_Int32)10));
        xRowProperties->setPropertyValue(C2U("ActiveConnection"), makeAny(xConnection));
        xRowSet->execute();
        xRet = Reference<XColumnsSupplier>( xRowSet, UNO_QUERY );
    }
    catch( const uno::Exception& )
    {
        DBG_ERROR("Exception in SwDBMgr::GetColumnSupplier");
    }

    return xRet;
}
/* -----------------------------05.07.00 13:44--------------------------------

 ---------------------------------------------------------------------------*/
String SwNewDBMgr::GetDBField(uno::Reference<XPropertySet> xColumnProps,
						const SwDBFormatData& rDBFormatData,
						double* pNumber)
{
    uno::Reference< XColumn > xColumn(xColumnProps, UNO_QUERY);
	String sRet;
	DBG_ASSERT(xColumn.is(), "SwNewDBMgr::::ImportDBField: illegal arguments");
	if(!xColumn.is())
		return sRet;

	Any aType = xColumnProps->getPropertyValue(C2U("Type"));
	sal_Int32 eDataType = 0;
	aType >>= eDataType;
	switch(eDataType)
	{
		case DataType::CHAR:
		case DataType::VARCHAR:
		case DataType::LONGVARCHAR:
            try
            {
			    sRet = xColumn->getString();
            }
            catch( SQLException& )
            {
            }
		break;
		case DataType::BIT:
		case DataType::BOOLEAN:
		case DataType::TINYINT:
		case DataType::SMALLINT:
		case DataType::INTEGER:
		case DataType::BIGINT:
		case DataType::FLOAT:
		case DataType::REAL:
		case DataType::DOUBLE:
		case DataType::NUMERIC:
		case DataType::DECIMAL:
		case DataType::DATE:
		case DataType::TIME:
		case DataType::TIMESTAMP:
		{
//			::Date aTempDate(rDBFormatData.aNullDate.Day,
//				rDBFormatData.aNullDate.Month, rDBFormatData.aNullDate.Year);

			try
			{
                SwDbtoolsClient& aClient = SwNewDBMgr::GetDbtoolsClient();
                sRet = aClient.getFormattedValue(
					xColumnProps,
					rDBFormatData.xFormatter,
					rDBFormatData.aLocale,
					rDBFormatData.aNullDate);
				if (pNumber)
                {
				    double fVal = xColumn->getDouble();
                    if(!xColumn->wasNull())
                    {
                        *pNumber = fVal;
                    }
                }
			}
            catch(Exception& )
			{
				DBG_ERROR("exception caught");
			}

		}
		break;

//		case DataType::BINARY:
//		case DataType::VARBINARY:
//		case DataType::LONGVARBINARY:
//		case DataType::SQLNULL:
//		case DataType::OTHER:
//		case DataType::OBJECT:
//		case DataType::DISTINCT:
//		case DataType::STRUCT:
//		case DataType::ARRAY:
//		case DataType::BLOB:
//		case DataType::CLOB:
//		case DataType::REF:
//		default:
	}
//	if (pFormat)
//	{
//		SFX_ITEMSET_GET(*pCol, pFormatItem, SfxUInt32Item, SBA_DEF_FMTVALUE, sal_True);
//		*pFormat = pFormatItem->GetValue();
//	}

	return sRet;
}
/* -----------------------------06.07.00 14:28--------------------------------
	releases the merge data source table or query after merge is completed
 ---------------------------------------------------------------------------*/
void	SwNewDBMgr::EndMerge()
{
	DBG_ASSERT(bInMerge, "merge is not active");
	bInMerge = sal_False;
    delete pImpl->pMergeData;
    pImpl->pMergeData = 0;
}
/* -----------------------------06.07.00 14:28--------------------------------
	checks if a desired data source table or query is open
 ---------------------------------------------------------------------------*/
sal_Bool    SwNewDBMgr::IsDataSourceOpen(const String& rDataSource,
            const String& rTableOrQuery, sal_Bool bMergeOnly)
{
    if(pImpl->pMergeData)
	{
        return !bMergeLock &&
                ((rDataSource == (String)pImpl->pMergeData->sDataSource &&
                    rTableOrQuery == (String)pImpl->pMergeData->sCommand)
                    ||(!rDataSource.Len() && !rTableOrQuery.Len()))
                    &&
                    pImpl->pMergeData->xResultSet.is();
	}
    else if(!bMergeOnly)
    {
        SwDBData aData;
        aData.sDataSource = rDataSource;
        aData.sCommand = rTableOrQuery;
        aData.nCommandType = -1;
        SwDSParam* pFound = FindDSData(aData, sal_False);
        return (pFound && pFound->xResultSet.is());
    }
    return sal_False;
}
/* -----------------------------17.07.00 16:44--------------------------------
	read column data a a specified position
 ---------------------------------------------------------------------------*/
sal_Bool SwNewDBMgr::GetColumnCnt(const String& rSourceName, const String& rTableName,
							const String& rColumnName, sal_uInt32 nAbsRecordId,
							long nLanguage,
							String& rResult, double* pNumber)
{
	sal_Bool bRet = sal_False;
    SwDSParam* pFound = 0;
    //check if it's the merge data source
    if(pImpl->pMergeData &&
        rSourceName == (String)pImpl->pMergeData->sDataSource &&
        rTableName == (String)pImpl->pMergeData->sCommand)
	{
        pFound = pImpl->pMergeData;
    }
    else
	{
        SwDBData aData;
        aData.sDataSource = rSourceName;
        aData.sCommand = rTableName;
        aData.nCommandType = -1;
        pFound = FindDSData(aData, sal_False);
    }
    //check validity of supplied record Id
    if(pFound->aSelection.getLength())
    {
        //the destination has to be an element of the selection
        const Any* pSelection = pFound->aSelection.getConstArray();
        sal_Bool bFound = sal_False;
        for(sal_Int32 nPos = 0; !bFound && nPos < pFound->aSelection.getLength(); nPos++)
        {
            sal_Int32 nSelection = 0;
            pSelection[nPos] >>= nSelection;
            if(nSelection == static_cast<sal_Int32>(nAbsRecordId))
                bFound = sal_True;
        }
        if(!bFound)
            return sal_False;
    }
    if(pFound && pFound->xResultSet.is() && !pFound->bAfterSelection)
    {
        sal_Int32 nOldRow = 0;
        try
        {
            nOldRow = pFound->xResultSet->getRow();
        }
        catch(const Exception& )
        {
			return sal_False;
        }
        //position to the desired index
        sal_Bool bMove = sal_True;
        if ( nOldRow != static_cast<sal_Int32>(nAbsRecordId) )
            bMove = lcl_MoveAbsolute(pFound, nAbsRecordId);
        if(bMove)
        {
            bRet = lcl_GetColumnCnt(pFound, rColumnName, nLanguage, rResult, pNumber);
        }
        if ( nOldRow != static_cast<sal_Int32>(nAbsRecordId) )
            bMove = lcl_MoveAbsolute(pFound, nOldRow);
    }
	return bRet;
}
/* -----------------------------06.07.00 16:47--------------------------------
	reads the column data at the current position
 ---------------------------------------------------------------------------*/
sal_Bool	SwNewDBMgr::GetMergeColumnCnt(const String& rColumnName, sal_uInt16 nLanguage,
                                String &rResult, double *pNumber, sal_uInt32 * /*pFormat*/)
{
    if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is() || pImpl->pMergeData->bAfterSelection )
	{
		rResult.Erase();
		return sal_False;
	}

    sal_Bool bRet = lcl_GetColumnCnt(pImpl->pMergeData, rColumnName, nLanguage, rResult, pNumber);
	return bRet;
}
/* -----------------------------07.07.00 14:28--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool SwNewDBMgr::ToNextMergeRecord()
{
    DBG_ASSERT(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge");
    return ToNextRecord(pImpl->pMergeData);
}
/* -----------------------------10.07.01 14:28--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool SwNewDBMgr::ToNextRecord(
    const String& rDataSource, const String& rCommand, sal_Int32 /*nCommandType*/)
{
    SwDSParam* pFound = 0;
    if(pImpl->pMergeData &&
        rDataSource == (String)pImpl->pMergeData->sDataSource &&
        rCommand == (String)pImpl->pMergeData->sCommand)
        pFound = pImpl->pMergeData;
    else
    {
        SwDBData aData;
        aData.sDataSource = rDataSource;
        aData.sCommand = rCommand;
        aData.nCommandType = -1;
        pFound = FindDSData(aData, sal_False);
    }
    return ToNextRecord(pFound);
}
/* -----------------------------10.07.01 14:38--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool SwNewDBMgr::ToNextRecord(SwDSParam* pParam)
{
    sal_Bool bRet = sal_True;
    if(!pParam || !pParam->xResultSet.is() || pParam->bEndOfDB ||
			(pParam->aSelection.getLength() && pParam->aSelection.getLength() <= pParam->nSelectionIndex))
	{
        if(pParam)
            pParam->CheckEndOfDB();
		return sal_False;
	}
	try
	{
        if(pParam->aSelection.getLength())
		{
			sal_Int32 nPos = 0;
			pParam->aSelection.getConstArray()[ pParam->nSelectionIndex++ ] >>= nPos;
            pParam->bEndOfDB = !pParam->xResultSet->absolute( nPos );
            pParam->CheckEndOfDB();
            bRet = !pParam->bEndOfDB;
            if(pParam->nSelectionIndex >= pParam->aSelection.getLength())
                pParam->bEndOfDB = sal_True;
		}
		else
		{
            sal_Int32 nBefore = pParam->xResultSet->getRow();
            pParam->bEndOfDB = !pParam->xResultSet->next();
            if( !pParam->bEndOfDB && nBefore == pParam->xResultSet->getRow())
            {
                //next returned true but it didn't move
                pParam->bEndOfDB = sal_True;
            }

            pParam->CheckEndOfDB();
            bRet = !pParam->bEndOfDB;
            ++pParam->nSelectionIndex;
		}
	}
    catch(Exception&)
	{
	}
    return bRet;
}

/* -----------------------------13.07.00 17:23--------------------------------
	synchronized labels contain a next record field at their end
	to assure that the next page can be created in mail merge
	the cursor position must be validated
 ---------------------------------------------------------------------------*/
sal_Bool SwNewDBMgr::ExistsNextRecord() const
{
    return pImpl->pMergeData && !pImpl->pMergeData->bEndOfDB;
}
/* -----------------------------13.07.00 10:41--------------------------------

 ---------------------------------------------------------------------------*/
sal_uInt32 	SwNewDBMgr::GetSelectedRecordId()
{
	sal_uInt32 	nRet = 0;
    DBG_ASSERT(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge");
    if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is())
		return sal_False;
	try
	{
        nRet = pImpl->pMergeData->xResultSet->getRow();
	}
    catch(Exception& )
	{
	}
	return nRet;
}
/* -----------------------------13.07.00 10:58--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool SwNewDBMgr::ToRecordId(sal_Int32 nSet)
{
    DBG_ASSERT(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is(), "no data source in merge");
    if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is()|| nSet < 0)
		return sal_False;
	sal_Bool bRet = sal_False;
    sal_Int32 nAbsPos = nSet;

	if(nAbsPos >= 0)
	{
        bRet = lcl_MoveAbsolute(pImpl->pMergeData, nAbsPos);
        pImpl->pMergeData->bEndOfDB = !bRet;
        pImpl->pMergeData->CheckEndOfDB();
	}
	return bRet;
}

/* -----------------------------17.07.00 14:17--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool SwNewDBMgr::OpenDataSource(const String& rDataSource, const String& rTableOrQuery,
            sal_Int32 nCommandType, bool bCreate)
{
    SwDBData aData;
    aData.sDataSource = rDataSource;
    aData.sCommand = rTableOrQuery;
    aData.nCommandType = nCommandType;

    SwDSParam* pFound = FindDSData(aData, sal_True);
    uno::Reference< XDataSource> xSource;
	if(pFound->xResultSet.is())
		return sal_True;
    SwDSParam* pParam = FindDSConnection(rDataSource, sal_False);
    uno::Reference< XConnection> xConnection;
    if(pParam && pParam->xConnection.is())
        pFound->xConnection = pParam->xConnection;
    else if(bCreate)
    {
        rtl::OUString sDataSource(rDataSource);
        pFound->xConnection = RegisterConnection( sDataSource );
    }
	if(pFound->xConnection.is())
	{
		try
		{
            uno::Reference< sdbc::XDatabaseMetaData >  xMetaData = pFound->xConnection->getMetaData();
            try
            {
                pFound->bScrollable = xMetaData
						->supportsResultSetType((sal_Int32)ResultSetType::SCROLL_INSENSITIVE);
            }
            catch(Exception&)
            {
                //#98373# DB driver may not be ODBC 3.0 compliant
                pFound->bScrollable = sal_True;
            }
			pFound->xStatement = pFound->xConnection->createStatement();
            rtl::OUString aQuoteChar = xMetaData->getIdentifierQuoteString();
            rtl::OUString sStatement(C2U("SELECT * FROM "));
            sStatement = C2U("SELECT * FROM ");
            sStatement += aQuoteChar;
            sStatement += rTableOrQuery;
            sStatement += aQuoteChar;
            pFound->xResultSet = pFound->xStatement->executeQuery( sStatement );

			//after executeQuery the cursor must be positioned
            pFound->bEndOfDB = !pFound->xResultSet->next();
            pFound->bAfterSelection = sal_False;
            pFound->CheckEndOfDB();
            ++pFound->nSelectionIndex;
		}
		catch (Exception&)
		{
			pFound->xResultSet = 0;
			pFound->xStatement = 0;
			pFound->xConnection = 0;
		}
	}
	return pFound->xResultSet.is();
}
/* -----------------------------14.08.2001 10:26------------------------------

 ---------------------------------------------------------------------------*/
uno::Reference< XConnection> SwNewDBMgr::RegisterConnection(rtl::OUString& rDataSource)
{
    SwDSParam* pFound = SwNewDBMgr::FindDSConnection(rDataSource, sal_True);
    uno::Reference< XDataSource> xSource;
    if(!pFound->xConnection.is())
	{
        pFound->xConnection = SwNewDBMgr::GetConnection(rDataSource, xSource );
        try
        {
            uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY);
            if(xComponent.is())
                xComponent->addEventListener(pImpl->xDisposeListener);
        }
        catch(Exception&)
        {
        }
	}
    return pFound->xConnection;
}
/* -----------------------------17.07.00 15:55--------------------------------

 ---------------------------------------------------------------------------*/
sal_uInt32      SwNewDBMgr::GetSelectedRecordId(
    const String& rDataSource, const String& rTableOrQuery, sal_Int32 nCommandType)
{
    sal_uInt32 nRet = 0xffffffff;
	//check for merge data source first
    if(pImpl->pMergeData && rDataSource == (String)pImpl->pMergeData->sDataSource &&
                    rTableOrQuery == (String)pImpl->pMergeData->sCommand &&
                    (nCommandType == -1 || nCommandType == pImpl->pMergeData->nCommandType) &&
                    pImpl->pMergeData->xResultSet.is())
		nRet = GetSelectedRecordId();
	else
	{
        SwDBData aData;
        aData.sDataSource = rDataSource;
        aData.sCommand = rTableOrQuery;
        aData.nCommandType = nCommandType;
        SwDSParam* pFound = FindDSData(aData, sal_False);
		if(pFound && pFound->xResultSet.is())
		{
			try
			{	//if a selection array is set the current row at the result set may not be set yet
				if(pFound->aSelection.getLength())
				{
					sal_Int32 nSelIndex = pFound->nSelectionIndex;
                    if(nSelIndex >= pFound->aSelection.getLength())
						nSelIndex = pFound->aSelection.getLength() -1;
					pFound->aSelection.getConstArray()[nSelIndex] >>= nRet;

				}
				else
					nRet = pFound->xResultSet->getRow();
			}
			catch(Exception&){}
		}
	}
	return nRet;
}

/* -----------------------------17.07.00 14:18--------------------------------
	close all data sources - after fields were updated
 ---------------------------------------------------------------------------*/
void	SwNewDBMgr::CloseAll(sal_Bool bIncludingMerge)
{
    //the only thing done here is to reset the selection index
	//all connections stay open
    for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.Count(); nPos++)
    {
        SwDSParam* pParam = aDataSourceParams[nPos];
        if(bIncludingMerge || pParam != pImpl->pMergeData)
        {
			pParam->nSelectionIndex = 0;
			pParam->bAfterSelection = sal_False;
            pParam->bEndOfDB = sal_False;
            try
            {
                if(!bInMerge && pParam->xResultSet.is())
                    pParam->xResultSet->first();
            }
            catch(Exception& )
            {}
        }
    }
}
/* -----------------------------17.07.00 14:54--------------------------------

 ---------------------------------------------------------------------------*/
SwDSParam* SwNewDBMgr::FindDSData(const SwDBData& rData, sal_Bool bCreate)
{
    //prefer merge data if available
    if(pImpl->pMergeData && rData.sDataSource == pImpl->pMergeData->sDataSource &&
        rData.sCommand == pImpl->pMergeData->sCommand &&
        (rData.nCommandType == -1 || rData.nCommandType == pImpl->pMergeData->nCommandType ||
        (bCreate && pImpl->pMergeData->nCommandType == -1)))
    {
         return pImpl->pMergeData;
    }

    SwDSParam* pFound = 0;
	for(sal_uInt16 nPos = aDataSourceParams.Count(); nPos; nPos--)
	{
		SwDSParam* pParam = aDataSourceParams[nPos - 1];
        if(rData.sDataSource == pParam->sDataSource &&
            rData.sCommand == pParam->sCommand &&
            (rData.nCommandType == -1 || rData.nCommandType == pParam->nCommandType ||
            (bCreate && pParam->nCommandType == -1)))
			{
                //#94779# calls from the calculator may add a connection with an invalid commandtype
                //later added "real" data base connections have to re-use the already available
                //DSData and set the correct CommandType
                if(bCreate && pParam->nCommandType == -1)
                    pParam->nCommandType = rData.nCommandType;
				pFound = pParam;
				break;
			}
	}
	if(bCreate)
	{
		if(!pFound)
		{
            pFound = new SwDSParam(rData);
            aDataSourceParams.Insert(pFound, aDataSourceParams.Count());
            try
            {
                uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY);
                if(xComponent.is())
                    xComponent->addEventListener(pImpl->xDisposeListener);
            }
            catch(Exception&)
            {
            }
        }
	}
	return pFound;
}
/* -----------------------------14.08.2001 10:27------------------------------

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

SwDSParam*  SwNewDBMgr::FindDSConnection(const rtl::OUString& rDataSource, sal_Bool bCreate)
{
    //prefer merge data if available
    if(pImpl->pMergeData && rDataSource == pImpl->pMergeData->sDataSource )
    {
         return pImpl->pMergeData;
    }
	SwDSParam* pFound = 0;
	for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.Count(); nPos++)
	{
		SwDSParam* pParam = aDataSourceParams[nPos];
        if(rDataSource == pParam->sDataSource)
        {
            pFound = pParam;
            break;
        }
	}
	if(bCreate && !pFound)
	{
        SwDBData aData;
        aData.sDataSource = rDataSource;
        pFound = new SwDSParam(aData);
		aDataSourceParams.Insert(pFound, aDataSourceParams.Count());
        try
        {
            uno::Reference<XComponent> xComponent(pFound->xConnection, UNO_QUERY);
            if(xComponent.is())
                xComponent->addEventListener(pImpl->xDisposeListener);
        }
        catch(Exception&)
        {
        }
    }
	return pFound;
}

/* -----------------------------17.07.00 14:34--------------------------------

 ---------------------------------------------------------------------------*/
const SwDBData&	SwNewDBMgr::GetAddressDBName()
{
	return SW_MOD()->GetDBConfig()->GetAddressSource();
}
/* -----------------------------18.07.00 13:13--------------------------------

 ---------------------------------------------------------------------------*/
Sequence<rtl::OUString> SwNewDBMgr::GetExistingDatabaseNames()
{
    uno::Reference<XNameAccess> xDBContext;
    uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
	if( xMgr.is() )
	{
        uno::Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.sdb.DatabaseContext" ));
        xDBContext = uno::Reference<XNameAccess>(xInstance, UNO_QUERY) ;
	}
	if(xDBContext.is())
	{
		return xDBContext->getElementNames();
	}
    return Sequence<rtl::OUString>();
}
/*-- 26.05.2004 14:33:13---------------------------------------------------

  -----------------------------------------------------------------------*/
String SwNewDBMgr::LoadAndRegisterDataSource()
{
    sfx2::FileDialogHelper aDlgHelper( TemplateDescription::FILEOPEN_SIMPLE, 0 );
    Reference < XFilePicker > xFP = aDlgHelper.GetFilePicker();

    String sHomePath(SvtPathOptions().GetWorkPath());
    aDlgHelper.SetDisplayDirectory( sHomePath );

    Reference<XFilterManager> xFltMgr(xFP, UNO_QUERY);

    String sFilterAll(SW_RES(STR_FILTER_ALL));
    String sFilterAllData(SW_RES(STR_FILTER_ALL_DATA));
    String sFilterSXB(SW_RES(STR_FILTER_SXB));
    String sFilterSXC(SW_RES(STR_FILTER_SXC));
    String sFilterDBF(SW_RES(STR_FILTER_DBF));
    String sFilterXLS(SW_RES(STR_FILTER_XLS));
    String sFilterTXT(SW_RES(STR_FILTER_TXT));
    String sFilterCSV(SW_RES(STR_FILTER_CSV));
#ifdef WNT
    String sFilterMDB(SW_RES(STR_FILTER_MDB));
    String sFilterACCDB(SW_RES(STR_FILTER_ACCDB));
#endif
    xFltMgr->appendFilter( sFilterAll, C2U("*") );
    xFltMgr->appendFilter( sFilterAllData, C2U("*.ods;*.sxc;*.dbf;*.xls;*.txt;*.csv"));

    xFltMgr->appendFilter( sFilterSXB, C2U("*.odb") );
    xFltMgr->appendFilter( sFilterSXC, C2U("*.ods;*.sxc") );
    xFltMgr->appendFilter( sFilterDBF, C2U("*.dbf") );
    xFltMgr->appendFilter( sFilterXLS, C2U("*.xls") );
    xFltMgr->appendFilter( sFilterTXT, C2U("*.txt") );
    xFltMgr->appendFilter( sFilterCSV, C2U("*.csv") );
#ifdef WNT
    xFltMgr->appendFilter( sFilterMDB, C2U("*.mdb") );
    xFltMgr->appendFilter( sFilterACCDB, C2U("*.accdb") );
#endif

    xFltMgr->setCurrentFilter( sFilterAll ) ;
    String sFind;
    bool bTextConnection = false;
    if( ERRCODE_NONE == aDlgHelper.Execute() )
    {
        String sURL = xFP->getFiles().getConstArray()[0];
        //data sources have to be registered depending on their extensions
        INetURLObject aURL( sURL );
        String sExt( aURL.GetExtension() );
        Any aURLAny;
        Any aTableFilterAny;
        Any aSuppressVersionsAny;
        Any aInfoAny;
        INetURLObject aTempURL(aURL);
        bool bStore = true;
        if(sExt.EqualsAscii("odb"))
        {
            bStore = false;
        }
        else if(sExt.EqualsIgnoreCaseAscii("sxc")
            || sExt.EqualsIgnoreCaseAscii("ods")
                || sExt.EqualsIgnoreCaseAscii("xls"))
        {
            rtl::OUString sDBURL(C2U("sdbc:calc:"));
            sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE);
            aURLAny <<= sDBURL;
        }
        else if(sExt.EqualsIgnoreCaseAscii("dbf"))
        {
            aTempURL.removeSegment();
            aTempURL.removeFinalSlash();
            rtl::OUString sDBURL(C2U("sdbc:dbase:"));
            sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE);
            aURLAny <<= sDBURL;
            //set the filter to the file name without extension
            Sequence<rtl::OUString> aFilters(1);
            rtl::OUString sTmp(aURL.getBase());
            aFilters[0] = aURL.getBase();
            aTableFilterAny <<= aFilters;
        }
        else if(sExt.EqualsIgnoreCaseAscii("csv") || sExt.EqualsIgnoreCaseAscii("txt"))
        {
            aTempURL.removeSegment();
            aTempURL.removeFinalSlash();
            rtl::OUString sDBURL(C2U("sdbc:flat:"));
            //only the 'path' has to be added
            sDBURL += aTempURL.GetMainURL(INetURLObject::NO_DECODE);
            aURLAny <<= sDBURL;

            bTextConnection = true;
            //set the filter to the file name without extension
            Sequence<rtl::OUString> aFilters(1);
            rtl::OUString sTmp(aURL.getBase());
            aFilters[0] = aURL.getBase();
            aTableFilterAny <<= aFilters;
        }
#ifdef WNT
        else if(sExt.EqualsIgnoreCaseAscii("mdb"))
        {
            rtl::OUString sDBURL(C2U("sdbc:ado:access:PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE="));
            sDBURL += aTempURL.PathToFileName();
            aURLAny <<= sDBURL;
            aSuppressVersionsAny <<= makeAny(true);
        }
        else if(sExt.EqualsIgnoreCaseAscii("accdb"))
        {
            rtl::OUString sDBURL(C2U("sdbc:ado:PROVIDER=Microsoft.ACE.OLEDB.12.0;DATA SOURCE="));
            sDBURL += aTempURL.PathToFileName();
            aURLAny <<= sDBURL;
            aSuppressVersionsAny <<= makeAny(true);
        }
#endif
        try
        {
            Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
            Reference<XInterface> xInstance = xMgr->createInstance( C2U( "com.sun.star.sdb.DatabaseContext" ));
            Reference<XNameAccess> xDBContext(xInstance, UNO_QUERY_THROW);
            Reference<XSingleServiceFactory> xFact( xDBContext, UNO_QUERY);

			String sNewName = INetURLObject::decode( aURL.getName(),
													 INET_HEX_ESCAPE,
													 INetURLObject::DECODE_UNAMBIGUOUS,
													 RTL_TEXTENCODING_UTF8 );
            xub_StrLen nExtLen = static_cast< xub_StrLen >(aURL.GetExtension().getLength());
            sNewName.Erase( sNewName.Len() - nExtLen - 1, nExtLen + 1 );

            //find a unique name if sNewName already exists
            sFind = sNewName;
            sal_Int32 nIndex = 0;
            while(xDBContext->hasByName(sFind))
            {
                sFind = sNewName;
                sFind += String::CreateFromInt32(++nIndex);
            }

            Reference<XInterface> xNewInstance;
            if(!bStore)
            {
                //odb-file
                Any aDataSource = xDBContext->getByName(aTempURL.GetMainURL(INetURLObject::NO_DECODE));
                aDataSource >>= xNewInstance;
            }
            else
            {
                xNewInstance = xFact->createInstance();
                Reference<XPropertySet> xDataProperties(xNewInstance, UNO_QUERY);

                if(aURLAny.hasValue())
                    xDataProperties->setPropertyValue(C2U("URL"), aURLAny);
                if(aTableFilterAny.hasValue())
                    xDataProperties->setPropertyValue(C2U("TableFilter"), aTableFilterAny);
                if(aSuppressVersionsAny.hasValue())
                    xDataProperties->setPropertyValue(C2U("SuppressVersionColumns"), aSuppressVersionsAny);
                if(aInfoAny.hasValue())
                    xDataProperties->setPropertyValue(C2U("Info"), aInfoAny);

                if( bTextConnection )
                {
                    uno::Reference < ui::dialogs::XExecutableDialog > xSettingsDlg(
                                xMgr->createInstance( C2U( "com.sun.star.sdb.TextConnectionSettings" ) ), uno::UNO_QUERY);
                    if( xSettingsDlg->execute() )
                    {
                        uno::Any aSettings = xDataProperties->getPropertyValue( C2U( "Settings" ) );
                        uno::Reference < beans::XPropertySet > xDSSettings;
                        aSettings >>= xDSSettings;
                        ::comphelper::copyProperties(
                            uno::Reference < beans::XPropertySet >( xSettingsDlg, uno::UNO_QUERY ),
                            xDSSettings );
                        xDSSettings->setPropertyValue( C2U("Extension"), uno::makeAny( ::rtl::OUString( sExt )));
                    }
                }

                Reference<XDocumentDataSource> xDS(xNewInstance, UNO_QUERY_THROW);
                Reference<XStorable> xStore(xDS->getDatabaseDocument(), UNO_QUERY_THROW);
                String sOutputExt = String::CreateFromAscii(".odb");
                String sTmpName;
                {
                    utl::TempFile aTempFile(sNewName , &sOutputExt, &sHomePath);
                    aTempFile.EnableKillingFile(sal_True);
                    sTmpName = aTempFile.GetURL();
                }
                xStore->storeAsURL(sTmpName, Sequence< PropertyValue >());
            }
            Reference<XNamingService> xNaming(xDBContext, UNO_QUERY);
            xNaming->registerObject( sFind, xNewInstance );

        }
        catch(Exception&)
        {
        }
    }
    return sFind;

}
/* -----------------------------10.11.00 17:10--------------------------------

 ---------------------------------------------------------------------------*/
void SwNewDBMgr::ExecuteFormLetter(	SwWrtShell& rSh,
                        const Sequence<PropertyValue>& rProperties,
                        sal_Bool bWithDataSourceBrowser)
{
	//prevent second call
    if(pImpl->pMergeDialog)
		return ;
    rtl::OUString sDataSource, sDataTableOrQuery;
    Sequence<Any> aSelection;

	sal_Int32 nCmdType = CommandType::TABLE;
    uno::Reference< XConnection> xConnection;

	ODataAccessDescriptor aDescriptor(rProperties);
	sDataSource = aDescriptor.getDataSource();
	aDescriptor[daCommand]		>>= sDataTableOrQuery;
	aDescriptor[daCommandType]	>>= nCmdType;

	if ( aDescriptor.has(daSelection) )
		aDescriptor[daSelection] >>= aSelection;
	if ( aDescriptor.has(daConnection) )
		aDescriptor[daConnection] >>= xConnection;

    if(!sDataSource.getLength() || !sDataTableOrQuery.getLength())
	{
		DBG_ERROR("PropertyValues missing or unset");
		return;
	}

    //always create a connection for the dialog and dispose it after the dialog has been closed
    SwDSParam* pFound = 0;
    if(!xConnection.is())
    {
        xConnection = SwNewDBMgr::RegisterConnection(sDataSource);
        pFound = FindDSConnection(sDataSource, sal_True);
    }
	SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
    DBG_ASSERT(pFact, "Dialogdiet fail!");
    pImpl->pMergeDialog = pFact->CreateMailMergeDlg( DLG_MAILMERGE,
														&rSh.GetView().GetViewFrame()->GetWindow(), rSh,
														sDataSource,
														sDataTableOrQuery,
														nCmdType,
														xConnection,
														bWithDataSourceBrowser ? 0 : &aSelection);
    DBG_ASSERT(pImpl->pMergeDialog, "Dialogdiet fail!");
    if(pImpl->pMergeDialog->Execute() == RET_OK)
	{
		aDescriptor[daSelection] <<= pImpl->pMergeDialog->GetSelection();

        uno::Reference<XResultSet> xResSet = pImpl->pMergeDialog->GetResultSet();
        if(xResSet.is())
			aDescriptor[daCursor] <<= xResSet;

        // SfxObjectShellRef is ok, since there should be no control over the document lifetime here
        SfxObjectShellRef xDocShell = rSh.GetView().GetViewFrame()->GetObjectShell();
        SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), xDocShell));
        {
            //copy rSh to aTempFile
            ::rtl::OUString sTempURL;
            const SfxFilter *pSfxFlt = SwIoSystem::GetFilterOfFormat(
                        String::CreateFromAscii( FILTER_XML ),
                        SwDocShell::Factory().GetFilterContainer() );
            try
            {

                uno::Sequence< beans::PropertyValue > aValues(1);
                beans::PropertyValue* pValues = aValues.getArray();
                pValues[0].Name = C2U("FilterName");
                pValues[0].Value <<= ::rtl::OUString(pSfxFlt->GetFilterName());
                uno::Reference< frame::XStorable > xStore( xDocShell->GetModel(), uno::UNO_QUERY);
                sTempURL = URIHelper::SmartRel2Abs( INetURLObject(), utl::TempFile::CreateTempName() );
                xStore->storeToURL( sTempURL, aValues );
            }
            catch( const uno::Exception& rEx )
            {
                (void) rEx;
            }
            if( xDocShell->GetError() )
            {
                // error message ??
                ErrorHandler::HandleError( xDocShell->GetError() );
            }
            else
            {
                // the shell will be explicitly closed, but it is more safe to use SfxObjectShellLock here
                // especially for the case that the loading has failed
                SfxObjectShellLock xWorkDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL ));
                SfxMedium* pWorkMed = new SfxMedium( sTempURL, STREAM_STD_READ, sal_True );
                pWorkMed->SetFilter( pSfxFlt );
                if( xWorkDocSh->DoLoad(pWorkMed) )
                {
                    SfxViewFrame *pFrame = SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 );
                    SwView *pView = (SwView*) pFrame->GetViewShell();
                    pView->AttrChangedNotify( &pView->GetWrtShell() );//Damit SelectShell gerufen wird.
                    //set the current DBMgr
                    SwDoc* pWorkDoc = pView->GetWrtShell().GetDoc();
                    SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr();
                    pWorkDoc->SetNewDBMgr( this );

                    SwMergeDescriptor aMergeDesc( pImpl->pMergeDialog->GetMergeType(), pView->GetWrtShell(), aDescriptor );
                    aMergeDesc.sSaveToFilter = pImpl->pMergeDialog->GetSaveFilter(); 
                    aMergeDesc.bCreateSingleFile = !pImpl->pMergeDialog->IsSaveIndividualDocs();
                    if( !aMergeDesc.bCreateSingleFile && pImpl->pMergeDialog->IsGenerateFromDataBase() )
                    {
                        aMergeDesc.sAddressFromColumn = pImpl->pMergeDialog->GetColumnName();
                        aMergeDesc.sSubject = pImpl->pMergeDialog->GetPath();
                    }

                    MergeNew(aMergeDesc);

                    pWorkDoc->SetNewDBMgr( pWorkDBMgr );
                    //close the temporary file
                    uno::Reference< util::XCloseable > xClose( xWorkDocSh->GetModel(), uno::UNO_QUERY );
                    if (xClose.is())
                    {
                        try
                        {
                            //! 'sal_True' -> transfer ownership to vetoing object if vetoed!
                            //! I.e. now that object is responsible for closing the model and doc shell.
                            xClose->close( sal_True );
                        }
                        catch ( const uno::Exception& )
                        {
                        }
                    }
                }
            }
            //remove the temporary file
            SWUnoHelper::UCB_DeleteFile( sTempURL );
        }
        SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE_END, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), rSh.GetView().GetViewFrame()->GetObjectShell()));

		// reset the cursor inside
		xResSet = NULL;
		aDescriptor[daCursor] <<= xResSet;
	}
    if(pFound)
    {
        for(sal_uInt16 nPos = 0; nPos < aDataSourceParams.Count(); nPos++)
        {
            SwDSParam* pParam = aDataSourceParams[nPos];
            if(pParam == pFound)
            {
                try
                {
                    uno::Reference<XComponent> xComp(pParam->xConnection, UNO_QUERY);
                    if(xComp.is())
                        xComp->dispose();
                }
                catch(const RuntimeException& )
                {
                    //may be disposed already since multiple entries may have used the same connection
                }
                break;
            }
            //pFound doesn't need to be removed/deleted -
            //this has been done by the SwConnectionDisposedListener_Impl already
        }
    }
    DELETEZ(pImpl->pMergeDialog);
}
/* -----------------------------13.11.00 08:20--------------------------------

 ---------------------------------------------------------------------------*/
void SwNewDBMgr::InsertText(SwWrtShell& rSh,
						const Sequence< PropertyValue>& rProperties)
{
    rtl::OUString sDataSource, sDataTableOrQuery;
    uno::Reference<XResultSet>  xResSet;
    Sequence<Any> aSelection;
	sal_Bool bHasSelectionProperty = sal_False;
	sal_Int32 nSelectionPos = 0;
	sal_Int16 nCmdType = CommandType::TABLE;
	const PropertyValue* pValues = rProperties.getConstArray();
    uno::Reference< XConnection> xConnection;
    for(sal_Int32 nPos = 0; nPos < rProperties.getLength(); nPos++)
	{
        if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cDataSourceName)))
			pValues[nPos].Value >>= sDataSource;
        else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cCommand)))
			pValues[nPos].Value >>= sDataTableOrQuery;
        else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cCursor)))
			pValues[nPos].Value >>= xResSet;
        else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cSelection)))
		{
			bHasSelectionProperty = sal_True;
			nSelectionPos = nPos;
			pValues[nPos].Value >>= aSelection;
		}
        else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cCommandType)))
			pValues[nPos].Value >>= nCmdType;
        else if(pValues[nPos].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cActiveConnection)))
            pValues[nPos].Value >>= xConnection;
    }
	if(!sDataSource.getLength() || !sDataTableOrQuery.getLength() || !xResSet.is())
	{
		DBG_ERROR("PropertyValues missing or unset");
		return;
	}
    uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
    uno::Reference<XDataSource> xSource;
    uno::Reference<XChild> xChild(xConnection, UNO_QUERY);
    if(xChild.is())
        xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY);
    if(!xSource.is())
        xSource = SwNewDBMgr::GetDbtoolsClient().getDataSource(sDataSource, xMgr);
    uno::Reference< XColumnsSupplier > xColSupp( xResSet, UNO_QUERY );
	SwDBData aDBData;
	aDBData.sDataSource = sDataSource;
	aDBData.sCommand = sDataTableOrQuery;
	aDBData.nCommandType = nCmdType;

    SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
    DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");

	AbstractSwInsertDBColAutoPilot* pDlg = pFact->CreateSwInsertDBColAutoPilot( rSh.GetView(),
																				xSource,
																				xColSupp,
																				aDBData,
                                                                                DLG_AP_INSERT_DB_SEL );
    DBG_ASSERT(pDlg, "Dialogdiet fail!");
	if( RET_OK == pDlg->Execute() )
	{
        rtl::OUString sDummy;
        if(!xConnection.is())
            xConnection = xSource->getConnection(sDummy, sDummy);
        try
        {
            pDlg->DataToDoc( aSelection , xSource, xConnection, xResSet);
        }
        catch(Exception& )
        {
            DBG_ERROR("exception caught");
        }
    }
	delete pDlg;

}
/* -----------------------------30.08.2001 12:00------------------------------

 ---------------------------------------------------------------------------*/
SwDbtoolsClient* SwNewDBMgr::pDbtoolsClient = NULL;

SwDbtoolsClient& SwNewDBMgr::GetDbtoolsClient()
{
    if ( !pDbtoolsClient )
        pDbtoolsClient = new SwDbtoolsClient;
    return *pDbtoolsClient;
}
/* -----------------13.05.2003 15:34-----------------

 --------------------------------------------------*/
void SwNewDBMgr::RemoveDbtoolsClient()
{
    delete pDbtoolsClient;
    pDbtoolsClient = 0;
}
/* -----------------------------20.08.2002 12:00------------------------------

 ---------------------------------------------------------------------------*/
uno::Reference<XDataSource> SwNewDBMgr::getDataSourceAsParent(const uno::Reference< XConnection>& _xConnection,const ::rtl::OUString& _sDataSourceName)
{
    uno::Reference<XDataSource> xSource;
	try
	{
        uno::Reference<XChild> xChild(_xConnection, UNO_QUERY);
		if ( xChild.is() )
            xSource = uno::Reference<XDataSource>(xChild->getParent(), UNO_QUERY);
		if ( !xSource.is() )
			xSource = SwNewDBMgr::GetDbtoolsClient().getDataSource(_sDataSourceName, ::comphelper::getProcessServiceFactory());
	}
	catch(const Exception&)
	{
		DBG_ERROR("exception in getDataSourceAsParent caught");
	}
	return xSource;
}
/* -----------------------------20.08.2002 12:00------------------------------

 ---------------------------------------------------------------------------*/
uno::Reference<XResultSet> SwNewDBMgr::createCursor(const ::rtl::OUString& _sDataSourceName,
									   const ::rtl::OUString& _sCommand,
									   sal_Int32 _nCommandType,
                                       const uno::Reference<XConnection>& _xConnection
									  )
{
    uno::Reference<XResultSet> xResultSet;
	try
	{
        uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
		if( xMgr.is() )
		{
            uno::Reference<XInterface> xInstance = xMgr->createInstance(
				C2U( "com.sun.star.sdb.RowSet" ));
            uno::Reference<XPropertySet> xRowSetPropSet(xInstance, UNO_QUERY);
			if(xRowSetPropSet.is())
			{
				xRowSetPropSet->setPropertyValue(C2U("DataSourceName"), makeAny(_sDataSourceName));
				xRowSetPropSet->setPropertyValue(C2U("ActiveConnection"), makeAny(_xConnection));
				xRowSetPropSet->setPropertyValue(C2U("Command"), makeAny(_sCommand));
				xRowSetPropSet->setPropertyValue(C2U("CommandType"), makeAny(_nCommandType));

                uno::Reference< XCompletedExecution > xRowSet(xInstance, UNO_QUERY);

				if ( xRowSet.is() )
				{
                    uno::Reference< XInteractionHandler > xHandler(xMgr->createInstance(C2U("com.sun.star.task.InteractionHandler")), UNO_QUERY);
					xRowSet->executeWithCompletion(xHandler);
				}
                xResultSet = uno::Reference<XResultSet>(xRowSet, UNO_QUERY);
			}
		}
	}
	catch(const Exception&)
	{
		DBG_ASSERT(0,"Caught exception while creating a new RowSet!");
	}
	return xResultSet;
}
/*-- 13.05.2004 16:14:15---------------------------------------------------
    merge all data into one resulting document and return the number of
    merged documents
  -----------------------------------------------------------------------*/

sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                            SwView& rSourceView )
{
    // check the availability of all data in the config item
    uno::Reference< XResultSet> xResultSet = rMMConfig.GetResultSet();
    if(!xResultSet.is())
        return false;
    bInMerge = sal_True;
    sal_Int32 nRet  = 0;
    pImpl->pMergeData = new SwDSParam(
                rMMConfig.GetCurrentDBData(), xResultSet, rMMConfig.GetSelection());

    try{
        //set to start position
        if(pImpl->pMergeData->aSelection.getLength())
        {
            sal_Int32 nPos = 0;
            pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos;
            pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos );
            pImpl->pMergeData->CheckEndOfDB();
            if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength())
                pImpl->pMergeData->bEndOfDB = sal_True;
        }
        else
        {
            pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first();
            pImpl->pMergeData->CheckEndOfDB();
        }
    }
    catch(Exception&)
    {
        pImpl->pMergeData->bEndOfDB = sal_True;
        pImpl->pMergeData->CheckEndOfDB();
        DBG_ERROR("exception in MergeNew()");
    }

    //bCancel is set from the PrintMonitor
    bCancel = sal_False;

    CreateMonitor aMonitorDlg(&rSourceView.GetEditWin());
    aMonitorDlg.SetCancelHdl(LINK(this, SwNewDBMgr, PrtCancelHdl));
    if (!IsMergeSilent())
    {
        aMonitorDlg.Show();
        aMonitorDlg.Invalidate();
        aMonitorDlg.Update();
        // the print monitor needs some time to act
        for( sal_uInt16 i = 0; i < 25; i++)
            Application::Reschedule();
    }

    SwWrtShell& rSourceShell = rSourceView.GetWrtShell();
    sal_Bool bSynchronizedDoc = rSourceShell.IsLabelDoc() && rSourceShell.GetSectionFmtCount() > 1;
    //save the settings of the first
    rSourceShell.SttEndDoc(sal_True);
    sal_uInt16 nStartingPageNo = rSourceShell.GetVirtPageNum();
    String sModifiedStartingPageDesc;
    String sStartingPageDesc = sModifiedStartingPageDesc = rSourceShell.GetPageDesc(
                                rSourceShell.GetCurPageDesc()).GetName();

    try
    {
        // create a target docshell to put the merged document into
        SfxObjectShellRef xTargetDocShell( new SwDocShell( SFX_CREATE_MODE_STANDARD ) );
        xTargetDocShell->DoInitNew( 0 );
        SfxViewFrame* pTargetFrame = SfxViewFrame::LoadHiddenDocument( *xTargetDocShell, 0 );

        //the created window has to be located at the same position as the source window
        Window& rTargetWindow = pTargetFrame->GetFrame().GetWindow();
        Window& rSourceWindow = rSourceView.GetViewFrame()->GetFrame().GetWindow();
        rTargetWindow.SetPosPixel(rSourceWindow.GetPosPixel());

//        pTargetFrame->GetFrame().Appear();
        SwView* pTargetView = static_cast<SwView*>( pTargetFrame->GetViewShell() );
        rMMConfig.SetTargetView(pTargetView);
        //initiate SelectShell() to create sub shells
        pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() );
        SwWrtShell* pTargetShell = pTargetView->GetWrtShellPtr();
        // #i63806#
        const SwPageDesc* pSourcePageDesc = rSourceShell.FindPageDescByName( sStartingPageDesc );
        const SwFrmFmt& rMaster = pSourcePageDesc->GetMaster();
        bool bPageStylesWithHeaderFooter = rMaster.GetHeader().IsActive()  ||
                                        rMaster.GetFooter().IsActive();


        // #122799# copy compatibility options
        lcl_CopyCompatibilityOptions( rSourceShell, *pTargetShell);
        // #72821# copy dynamic defaults
        lcl_CopyDynamicDefaults( *rSourceShell.GetDoc(), *pTargetShell->GetDoc() );


        long nStartRow, nEndRow;
        sal_uLong nDocNo = 1;
        sal_Int32 nDocCount = 0;
        if( !IsMergeSilent() && lcl_getCountFromResultSet( nDocCount, pImpl->pMergeData->xResultSet ) )
            aMonitorDlg.SetTotalCount( nDocCount );

        do
        {
            nStartRow = pImpl->pMergeData->xResultSet->getRow();
            if (!IsMergeSilent())
            {
                aMonitorDlg.SetCurrentPosition( nDocNo );
                aMonitorDlg.Invalidate();
                aMonitorDlg.Update();
                // the print monitor needs some time to act
                for( sal_uInt16 i = 0; i < 25; i++)
                    Application::Reschedule();
            }

            // copy the source document
            // the copy will be closed later, but it is more safe to use SfxObjectShellLock here
            SfxObjectShellLock xWorkDocSh;
            if(nDocNo == 1 )
            {
                uno::Reference< util::XCloneable > xClone( rSourceView.GetDocShell()->GetModel(), uno::UNO_QUERY);
                uno::Reference< lang::XUnoTunnel > xWorkDocShell( xClone->createClone(), uno::UNO_QUERY);
                SwXTextDocument* pWorkModel = reinterpret_cast<SwXTextDocument*>(xWorkDocShell->getSomething(SwXTextDocument::getUnoTunnelId()));
                xWorkDocSh = pWorkModel->GetDocShell();
            }
            else
            {
                xWorkDocSh = rSourceView.GetDocShell()->GetDoc()->CreateCopy(true);
            }
            //create a ViewFrame
            SwView* pWorkView = static_cast< SwView* >( SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 )->GetViewShell() );
            SwWrtShell& rWorkShell = pWorkView->GetWrtShell();
            pWorkView->AttrChangedNotify( &rWorkShell );//Damit SelectShell gerufen wird.

                // merge the data
                SwDoc* pWorkDoc = rWorkShell.GetDoc();
                SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr();
                pWorkDoc->SetNewDBMgr( this );
                pWorkDoc->EmbedAllLinks();
                SwUndoId nLastUndoId(UNDO_EMPTY);
                if (rWorkShell.GetLastUndoInfo(0, & nLastUndoId))
                {
                    if (UNDO_UI_DELETE_INVISIBLECNTNT == nLastUndoId)
                    {
                        rWorkShell.Undo();
                    }
                }
                // #i69485# lock fields to prevent access to the result set while calculating layout
	            rWorkShell.LockExpFlds();
                // create a layout
                rWorkShell.CalcLayout();
                rWorkShell.UnlockExpFlds();
                SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE), rWorkShell.GetView().GetViewFrame()->GetObjectShell()));
            rWorkShell.ViewShell::UpdateFlds();
                SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_FIELD_MERGE_FINISHED), rWorkShell.GetView().GetViewFrame()->GetObjectShell()));

            // strip invisible content and convert fields to text
            rWorkShell.RemoveInvisibleContent();
            rWorkShell.ConvertFieldsToText();
            rWorkShell.SetNumberingRestart();
            if( bSynchronizedDoc )
            {
                lcl_RemoveSectionLinks( rWorkShell );
            }    

            // insert the document into the target document
            rWorkShell.SttEndDoc(sal_False);
            rWorkShell.SttEndDoc(sal_True);
            rWorkShell.SelAll();
            pTargetShell->SttEndDoc(sal_False);

            //#i63806# put the styles to the target document
            //if the source uses headers or footers each new copy need to copy a new page styles
            if(bPageStylesWithHeaderFooter)
            {
                //create a new pagestyle
                //copy the pagedesc from the current document to the new document and change the name of the to-be-applied style

                SwDoc* pTargetDoc = pTargetShell->GetDoc();
                String sNewPageDescName = lcl_FindUniqueName(pTargetShell, sStartingPageDesc, nDocNo );
                pTargetShell->GetDoc()->MakePageDesc( sNewPageDescName );
                SwPageDesc* pTargetPageDesc = pTargetShell->FindPageDescByName( sNewPageDescName );
                const SwPageDesc* pWorkPageDesc = rWorkShell.FindPageDescByName( sStartingPageDesc );

                if(pWorkPageDesc && pTargetPageDesc)
                {
                    pTargetDoc->CopyPageDesc( *pWorkPageDesc, *pTargetPageDesc, sal_False );
                    sModifiedStartingPageDesc = sNewPageDescName;
                    lcl_CopyFollowPageDesc( *pTargetShell, *pWorkPageDesc, *pTargetPageDesc, nDocNo );
                }
            }
            if(nDocNo == 1 || bPageStylesWithHeaderFooter)
            {
                pTargetView->GetDocShell()->_LoadStyles( *rSourceView.GetDocShell(), sal_True );
            }
            if(nDocNo > 1)
            {
                pTargetShell->InsertPageBreak( &sModifiedStartingPageDesc, nStartingPageNo );
            }
            else
            {
                pTargetShell->SetPageStyle(sModifiedStartingPageDesc);
            }
            sal_uInt16 nPageCountBefore = pTargetShell->GetPageCnt();
            DBG_ASSERT(!pTargetShell->GetTableFmt(),"target document ends with a table - paragraph should be appended");
            //#i51359# add a second paragraph in case there's only one
            {
                SwNodeIndex aIdx( pWorkDoc->GetNodes().GetEndOfExtras(), 2 );
              SwPosition aTestPos( aIdx );
              SwCursor aTestCrsr(aTestPos,0,false);
                if(!aTestCrsr.MovePara(fnParaNext, fnParaStart))
                {
                    //append a paragraph
                    pWorkDoc->AppendTxtNode( aTestPos );
                }
            }
            pTargetShell->Paste( rWorkShell.GetDoc(), sal_True );
            //convert fields in page styles (header/footer - has to be done after the first document has been pasted
            if(1 == nDocNo)
            {
                pTargetShell->CalcLayout();
                pTargetShell->ConvertFieldsToText();
            }
            //add the document info to the config item
            SwDocMergeInfo aMergeInfo;
            aMergeInfo.nStartPageInTarget = nPageCountBefore;
            //#i72820# calculate layout to be able to find the correct page index
            pTargetShell->CalcLayout();
            aMergeInfo.nEndPageInTarget = pTargetShell->GetPageCnt();
            aMergeInfo.nDBRow = nStartRow;
            rMMConfig.AddMergedDocument( aMergeInfo );
            ++nRet;

            // the print monitor needs some time to act
            for( sal_uInt16 i = 0; i < 25; i++)
                Application::Reschedule();

            //restore the ole DBMgr
            pWorkDoc->SetNewDBMgr( pWorkDBMgr );
            //now the temporary document should be closed
            SfxObjectShellRef xDocSh(pWorkView->GetDocShell());
            xDocSh->DoClose();
            nEndRow = pImpl->pMergeData->xResultSet->getRow();
            ++nDocNo;
        } while( !bCancel &&
                (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord()));

        //deselect all, go out of the frame and go to the beginning of the document
        Point aPt(LONG_MIN, LONG_MIN);
        pTargetShell->SelectObj(aPt, SW_LEAVE_FRAME);
        if (pTargetShell->IsSelFrmMode())
        {
            pTargetShell->UnSelectFrm();
            pTargetShell->LeaveSelFrmMode();
        }
        pTargetShell->EnterStdMode();
        pTargetShell->SttDoc();
        //
    }
    catch( Exception& rEx)
    {
        (void)rEx;
        DBG_ERROR("exception caught in SwNewDBMgr::MergeDocuments");
    }
    DELETEZ(pImpl->pMergeData);
    bInMerge = sal_False;
    return nRet;
}
/* -----------------09.12.2002 12:38-----------------
 *
 * --------------------------------------------------*/
SwConnectionDisposedListener_Impl::SwConnectionDisposedListener_Impl(SwNewDBMgr& rMgr) :
    rDBMgr(rMgr)
{};
/* -----------------09.12.2002 12:39-----------------
 *
 * --------------------------------------------------*/
SwConnectionDisposedListener_Impl::~SwConnectionDisposedListener_Impl()
{};
/* -----------------09.12.2002 12:39-----------------
 *
 * --------------------------------------------------*/
void SwConnectionDisposedListener_Impl::disposing( const EventObject& rSource )
        throw (RuntimeException)
{
    ::vos::OGuard aGuard(Application::GetSolarMutex());
    uno::Reference<XConnection> xSource(rSource.Source, UNO_QUERY);
    for(sal_uInt16 nPos = rDBMgr.aDataSourceParams.Count(); nPos; nPos--)
    {
        SwDSParam* pParam = rDBMgr.aDataSourceParams[nPos - 1];
        if(pParam->xConnection.is() &&
                (xSource == pParam->xConnection))
        {
            rDBMgr.aDataSourceParams.DeleteAndDestroy(nPos - 1);
        }
    }
}
