/**************************************************************
 * 
 * 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_extensions.hxx"
#include <osl/mutex.hxx>
#include <tools/diagnose_ex.h>
#include <tools/urlobj.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/io/XPersistObject.hpp>
#include <com/sun/star/sdbc/ResultSetType.hpp>
#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
#include <com/sun/star/sdbcx/XRowLocate.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
#include <com/sun/star/sdb/XDatabaseEnvironment.hpp>
#include <com/sun/star/uno/XNamingService.hpp>
#include <com/sun/star/sdbc/XDataSource.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/sdb/XCompletedConnection.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/form/XLoadable.hpp>
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/form/XGridColumnFactory.hpp>
#include <com/sun/star/io/XDataInputStream.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/ucb/XContentProvider.hpp>
#include <com/sun/star/ucb/XContentAccess.hpp>
#include <ucbhelper/contentbroker.hxx>
#include <ucbhelper/content.hxx>
#include <ucbhelper/contentidentifier.hxx>
#include <comphelper/container.hxx>
#include <svl/urihelper.hxx>
#include <svtools/svtabbx.hxx>
#include <svtools/headbar.hxx>
#include <vcl/dialog.hxx>
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#include <vcl/lstbox.hxx>
#include <vcl/fixed.hxx>
#include <vcl/group.hxx>
#include <vcl/lstbox.hxx>
#include <vcl/edit.hxx>
#include <vcl/msgbox.hxx>
#include <tools/debug.hxx>
#include "datman.hxx"
#include "bibresid.hxx"
#include "bibmod.hxx"
#include "bibview.hxx"
// #100312# ---------
#include "bibbeam.hxx"
#include "bibprop.hrc"
#include "toolbar.hxx"
#include "toolbar.hrc"
#include "bibconfig.hxx"
#include "bibbeam.hxx"
#include "bib.hrc"
#include "datman.hrc"
#include "bibliography.hrc"
#include <connectivity/dbtools.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::lang;
using namespace ::ucb;

#define C2U(cChar) ::rtl::OUString::createFromAscii(cChar)
#define C2S(cChar) String::CreateFromAscii(cChar)
#define MAP_TOKEN ';'
#define PAIR_TOKEN ':'


/* -----------------17.01.00 14:38-------------------

 --------------------------------------------------*/
Reference< XConnection > getConnection(const ::rtl::OUString& _rURL)
{
	// first get the sdb::DataSource corresponding to the url
	Reference< XDataSource >	xDataSource;
	// is it a favorite title ?
	Reference< XMultiServiceFactory >  xMgr = comphelper::getProcessServiceFactory();
	Reference<XInterface> xNamingContextIfc = xMgr->createInstance(C2U("com.sun.star.sdb.DatabaseContext"));
	Reference< XNameAccess >  xNamingContext(xNamingContextIfc, UNO_QUERY);
	if (xNamingContext.is() && xNamingContext->hasByName(_rURL))
	{
		DBG_ASSERT(Reference< XNamingService > (xNamingContext, UNO_QUERY).is(), "::getDataSource : no NamingService interface on the sdb::DatabaseAccessContext !");
		try
        {
            xDataSource = Reference< XDataSource > (Reference< XNamingService > (xNamingContext, UNO_QUERY)->getRegisteredObject(_rURL), UNO_QUERY);
        }
        catch(Exception eEx)
        {
            (void) eEx;	// make compiler happy
            DBG_ERROR("Exception caught in ODatabaseContext::getRegisteredObject()");
        }
	}
	// build the connection from the data source
	Reference< XConnection >	xConn;
	if (xDataSource.is())
	{
		// need user/pwd for this
		::rtl::OUString sUser, sPwd;
		Reference< XPropertySet >  xDataSourceProps(xDataSource, UNO_QUERY);
		Reference< XCompletedConnection > xComplConn(xDataSource, UNO_QUERY);
/*		Reference< XPropertySetInfo >  xInfo = xDataSourceProps.is() ? xDataSourceProps->getPropertySetInfo() : Reference< XPropertySetInfo > ();
		if (xInfo.is() && xInfo->hasPropertyByName(C2U("User")))
			xDataSourceProps->getPropertyValue(C2U("User")) >>= sUser;
		if (xInfo.is() && xInfo->hasPropertyByName(C2U("Password")))
			xDataSourceProps->getPropertyValue(C2U("Password"))>>= sPwd;
*/
		try
		{

			Reference<XInterface> xHdl = xMgr->createInstance(C2U("com.sun.star.task.InteractionHandler"));
			Reference<task::XInteractionHandler> xIHdl(xHdl, UNO_QUERY);
			xConn = xComplConn->connectWithCompletion(xIHdl);
//			xConn = xDataSource->getConnection(sUser, sPwd);
		}
		catch(SQLException&)
		{
			// TODO : a real error handling
		}
		catch(Exception& e )
		{
            (void) e;	// make compiler happy
		}

	}
	return xConn;
}

/* -----------------17.01.00 14:46-------------------

 --------------------------------------------------*/
Reference< XConnection >	getConnection(const Reference< XInterface > & xRowSet)
{
	Reference< XConnection >	xConn;
	try
	{
		Reference< XPropertySet >  xFormProps(xRowSet, UNO_QUERY);
		if (!xFormProps.is())
			return xConn;

		xConn = Reference< XConnection > (*(Reference< XInterface > *)xFormProps->getPropertyValue(C2U("ActiveConnection")).getValue(), UNO_QUERY);
		if (!xConn.is())
		{
			DBG_WARNING("no active connection");
		}
	}
	catch(Exception& e )
	{
        (void) e;	// make compiler happy
		DBG_ERROR("exception in getConnection");
	}

	return xConn;
}
/* -----------------17.01.00 16:07-------------------

 --------------------------------------------------*/
Reference< XNameAccess >  getColumns(const Reference< XForm > & _rxForm)
{
	Reference< XNameAccess >  xReturn;
	// check if the form is alive
	Reference< XColumnsSupplier >  xSupplyCols( _rxForm, UNO_QUERY );
	if (xSupplyCols.is())
		xReturn = xSupplyCols->getColumns();

	if (!xReturn.is() || (xReturn->getElementNames().getLength() == 0))
	{	// no ....
		xReturn = NULL;
		// -> get the table the form is bound to and ask it for their columns
		Reference< XTablesSupplier >  xSupplyTables( getConnection( _rxForm ), UNO_QUERY );
		Reference< XPropertySet >  xFormProps( _rxForm, UNO_QUERY );
		if (xFormProps.is() && xSupplyTables.is())
		{
			try
			{
				DBG_ASSERT((*(sal_Int32*)xFormProps->getPropertyValue(C2U("CommandType")).getValue()) == CommandType::TABLE,
					"::getColumns : invalid form (has no table as data source) !");
				::rtl::OUString sTable;
				xFormProps->getPropertyValue(C2U("Command")) >>= sTable;
				Reference< XNameAccess >  xTables = xSupplyTables->getTables();
				if (xTables.is() && xTables->hasByName(sTable))
					xSupplyCols = Reference< XColumnsSupplier > (
						*(Reference< XInterface > *)xTables->getByName(sTable).getValue(), UNO_QUERY);
				if (xSupplyCols.is())
					xReturn = xSupplyCols->getColumns();
			}
#ifdef DBG_UTIL
			catch(Exception& e )
#else
			catch(Exception&)
#endif
			{
#ifdef DBG_UTIL
				String sMsg(String::CreateFromAscii("::getColumns : catched an exception ("));
				sMsg += String(e.Message);
				sMsg.AppendAscii(") ...");
				DBG_ERROR( ByteString(sMsg, RTL_TEXTENCODING_ASCII_US ).GetBuffer());
#endif
			}

		}
	}
	return xReturn;
}

/* -----------------11.11.99 15:54-------------------

 --------------------------------------------------*/
class MappingDialog_Impl : public ModalDialog
{
    BibDataManager* pDatMan;
	OKButton		aOKBT;
	CancelButton	aCancelBT;
    HelpButton		aHelpBT;
    FixedLine		aMapGB;
	FixedText		aIdentifierFT;
	ListBox 		aIdentifierLB;
	FixedText		aAuthorityTypeFT;
	ListBox 		aAuthorityTypeLB;
    FixedText       aAuthorFT;
	ListBox 		aAuthorLB;
	FixedText		aTitleFT;
	ListBox 		aTitleLB;
    FixedText       aMonthFT;
	ListBox 		aMonthLB;
    FixedText       aYearFT;
	ListBox 		aYearLB;
    FixedText       aISBNFT;
	ListBox 		aISBNLB;
    FixedText       aBooktitleFT;
	ListBox 		aBooktitleLB;
    FixedText       aChapterFT;
	ListBox 		aChapterLB;
    FixedText       aEditionFT;
	ListBox 		aEditionLB;
    FixedText       aEditorFT;
	ListBox 		aEditorLB;
    FixedText       aHowpublishedFT;
	ListBox 		aHowpublishedLB;
    FixedText       aInstitutionFT;
	ListBox 		aInstitutionLB;
    FixedText       aJournalFT;
	ListBox 		aJournalLB;
    FixedText       aNoteFT;
	ListBox 		aNoteLB;
    FixedText       aAnnoteFT;
	ListBox 		aAnnoteLB;
    FixedText       aNumberFT;
	ListBox 		aNumberLB;
    FixedText       aOrganizationsFT;
	ListBox 		aOrganizationsLB;
    FixedText       aPagesFT;
	ListBox 		aPagesLB;
    FixedText       aPublisherFT;
	ListBox 		aPublisherLB;
    FixedText       aAddressFT;
	ListBox 		aAddressLB;
    FixedText       aSchoolFT;
	ListBox 		aSchoolLB;
    FixedText       aSeriesFT;
	ListBox 		aSeriesLB;
    FixedText       aReportTypeFT;
	ListBox 		aReportTypeLB;
    FixedText       aVolumeFT;
	ListBox 		aVolumeLB;
    FixedText       aURLFT;
	ListBox 		aURLLB;
    FixedText       aCustom1FT;
	ListBox 		aCustom1LB;
	FixedText		aCustom2FT;
	ListBox 		aCustom2LB;
	FixedText		aCustom3FT;
	ListBox 		aCustom3LB;
	FixedText		aCustom4FT;
	ListBox 		aCustom4LB;
	FixedText		aCustom5FT;
	ListBox 		aCustom5LB;
	ListBox*		aListBoxes[COLUMN_COUNT];
	String			sNone;

	sal_Bool		bModified;

	

	DECL_LINK(OkHdl, OKButton*);
	DECL_LINK(ListBoxSelectHdl, ListBox*);

public:
	MappingDialog_Impl(Window* pParent, BibDataManager* pDatMan);
	~MappingDialog_Impl();

	void	SetModified() {bModified = sal_True;}

};
/* -----------------11.11.99 16:42-------------------

 --------------------------------------------------*/
sal_uInt16 lcl_FindLogicalName(BibConfig* pConfig ,
									const ::rtl::OUString& rLogicalColumnName)
{
	for(sal_uInt16 i = 0; i < COLUMN_COUNT; i++)
	{
		if(rLogicalColumnName == pConfig->GetDefColumnName(i))
			return i;
	}
	return USHRT_MAX;
}
//-----------------------------------------------------------------------------
MappingDialog_Impl::MappingDialog_Impl(Window* pParent, BibDataManager* pMan) :
	ModalDialog(pParent, BibResId(RID_DLG_MAPPING) ),
	pDatMan(pMan),
	aOKBT(this, 				BibResId( BT_OK			)),
	aCancelBT(this, 			BibResId( BT_CANCEL		)),
	aHelpBT(this,				BibResId( BT_HELP			)),

	aMapGB(this,				BibResId( GB_MAPPING		)),

	aIdentifierFT(this, 		BibResId( FT_IDENTIFIER	)),
	aIdentifierLB(this, 		BibResId( LB_IDENTIFIER	)),
	aAuthorityTypeFT(this,		BibResId( FT_AUTHORITYTYPE )),
	aAuthorityTypeLB(this,		BibResId( LB_AUTHORITYTYPE )),
	aAuthorFT(this, 			BibResId( FT_AUTHOR		)),
	aAuthorLB(this, 			BibResId( LB_AUTHOR		)),
	aTitleFT(this,				BibResId( FT_TITLE 		)),
	aTitleLB(this,				BibResId( LB_TITLE 		)),
	aMonthFT(this,				BibResId( FT_MONTH 		)),
	aMonthLB(this,				BibResId( LB_MONTH 		)),
	aYearFT(this,				BibResId( FT_YEAR			)),
	aYearLB(this,				BibResId( LB_YEAR			)),
	aISBNFT(this,				BibResId( FT_ISBN			)),
	aISBNLB(this,				BibResId( LB_ISBN			)),
	aBooktitleFT(this,			BibResId( FT_BOOKTITLE 	)),
	aBooktitleLB(this,			BibResId( LB_BOOKTITLE 	)),
	aChapterFT(this,			BibResId( FT_CHAPTER		)),
	aChapterLB(this,			BibResId( LB_CHAPTER		)),
	aEditionFT(this,			BibResId( FT_EDITION		)),
	aEditionLB(this,			BibResId( LB_EDITION		)),
	aEditorFT(this, 			BibResId( FT_EDITOR		)),
	aEditorLB(this, 			BibResId( LB_EDITOR		)),
	aHowpublishedFT(this,		BibResId( FT_HOWPUBLISHED	)),
	aHowpublishedLB(this,		BibResId( LB_HOWPUBLISHED	)),
	aInstitutionFT(this,		BibResId( FT_INSTITUTION	)),
	aInstitutionLB(this,		BibResId( LB_INSTITUTION	)),
	aJournalFT(this,			BibResId( FT_JOURNAL		)),
	aJournalLB(this,			BibResId( LB_JOURNAL		)),
	aNoteFT(this,				BibResId( FT_NOTE			)),
	aNoteLB(this,				BibResId( LB_NOTE			)),
	aAnnoteFT(this, 			BibResId( FT_ANNOTE		)),
	aAnnoteLB(this, 			BibResId( LB_ANNOTE		)),
	aNumberFT(this, 			BibResId( FT_NUMBER		)),
	aNumberLB(this, 			BibResId( LB_NUMBER		)),
	aOrganizationsFT(this,		BibResId( FT_ORGANIZATIONS )),
	aOrganizationsLB(this,		BibResId( LB_ORGANIZATIONS )),
	aPagesFT(this,				BibResId( FT_PAGES 		)),
	aPagesLB(this,				BibResId( LB_PAGES 		)),
	aPublisherFT(this,			BibResId( FT_PUBLISHER 	)),
	aPublisherLB(this,			BibResId( LB_PUBLISHER 	)),
	aAddressFT(this,			BibResId( FT_ADDRESS		)),
	aAddressLB(this,			BibResId( LB_ADDRESS		)),
	aSchoolFT(this, 			BibResId( FT_SCHOOL		)),
	aSchoolLB(this, 			BibResId( LB_SCHOOL		)),
	aSeriesFT(this, 			BibResId( FT_SERIES		)),
	aSeriesLB(this, 			BibResId( LB_SERIES		)),
	aReportTypeFT(this, 		BibResId( FT_REPORTTYPE	)),
	aReportTypeLB(this, 		BibResId( LB_REPORTTYPE	)),
	aVolumeFT(this, 			BibResId( FT_VOLUME		)),
	aVolumeLB(this, 			BibResId( LB_VOLUME		)),
	aURLFT(this,				BibResId( FT_URL			)),
	aURLLB(this,				BibResId( LB_URL			)),
	aCustom1FT(this,			BibResId( FT_CUSTOM1		)),
	aCustom1LB(this,			BibResId( LB_CUSTOM1		)),
	aCustom2FT(this,			BibResId( FT_CUSTOM2		)),
	aCustom2LB(this,			BibResId( LB_CUSTOM2		)),
	aCustom3FT(this,			BibResId( FT_CUSTOM3		)),
	aCustom3LB(this,			BibResId( LB_CUSTOM3		)),
	aCustom4FT(this,			BibResId( FT_CUSTOM4		)),
	aCustom4LB(this,			BibResId( LB_CUSTOM4		)),
	aCustom5FT(this,			BibResId( FT_CUSTOM5		)),
	aCustom5LB(this,			BibResId( LB_CUSTOM5		)),
	sNone(BibResId(ST_NONE)),
	bModified(sal_False)
{
	FreeResource();

	aIdentifierFT.SetText(String(		  BibResId( ST_IDENTIFIER	 )));
	aAuthorityTypeFT.SetText(String(	  BibResId( ST_AUTHTYPE )));
	aAuthorFT.SetText(String(			  BibResId( ST_AUTHOR		 )));
	aTitleFT.SetText(String(			  BibResId( ST_TITLE		 )));
	aMonthFT.SetText(String(			  BibResId( ST_MONTH		 )));
	aYearFT.SetText(String( 			  BibResId( ST_YEAR 		 )));
	aISBNFT.SetText(String( 			  BibResId( ST_ISBN 		 )));
	aBooktitleFT.SetText(String(		  BibResId( ST_BOOKTITLE	 )));
	aChapterFT.SetText(String(			  BibResId( ST_CHAPTER		 )));
	aEditionFT.SetText(String(			  BibResId( ST_EDITION		 )));
	aEditorFT.SetText(String(			  BibResId( ST_EDITOR		 )));
	aHowpublishedFT.SetText(String( 	  BibResId( ST_HOWPUBLISHED  )));
	aInstitutionFT.SetText(String(		  BibResId( ST_INSTITUTION	 )));
	aJournalFT.SetText(String(			  BibResId( ST_JOURNAL		 )));
	aNoteFT.SetText(String( 			  BibResId( ST_NOTE 		 )));
	aAnnoteFT.SetText(String(			  BibResId( ST_ANNOTE		 )));
	aNumberFT.SetText(String(			  BibResId( ST_NUMBER		 )));
	aOrganizationsFT.SetText(String(	  BibResId( ST_ORGANIZATION )));
	aPagesFT.SetText(String(			  BibResId( ST_PAGE 		)));
	aPublisherFT.SetText(String(		  BibResId( ST_PUBLISHER	 )));
	aAddressFT.SetText(String(			  BibResId( ST_ADDRESS		 )));
	aSchoolFT.SetText(String(			  BibResId( ST_SCHOOL		 )));
	aSeriesFT.SetText(String(			  BibResId( ST_SERIES		 )));
	aReportTypeFT.SetText(String(		  BibResId( ST_REPORT	 )));
	aVolumeFT.SetText(String(			  BibResId( ST_VOLUME		 )));
	aURLFT.SetText(String(				  BibResId( ST_URL			 )));
	aCustom1FT.SetText(String(			  BibResId( ST_CUSTOM1		 )));
	aCustom2FT.SetText(String(			  BibResId( ST_CUSTOM2		 )));
	aCustom3FT.SetText(String(			  BibResId( ST_CUSTOM3		 )));
	aCustom4FT.SetText(String(			  BibResId( ST_CUSTOM4		 )));
	aCustom5FT.SetText(String(			  BibResId( ST_CUSTOM5		 )));

	aOKBT.SetClickHdl(LINK(this, MappingDialog_Impl, OkHdl));
	String sTitle = GetText();
	sTitle.SearchAndReplace(C2S("%1"), pDatMan->getActiveDataTable(), 0);
	SetText(sTitle);

	aListBoxes[0] = &aIdentifierLB;
	aListBoxes[1] = &aAuthorityTypeLB;
	aListBoxes[2] = &aAuthorLB;
	aListBoxes[3] = &aTitleLB;
	aListBoxes[4] = &aYearLB;
	aListBoxes[5] = &aISBNLB;
	aListBoxes[6] = &aBooktitleLB;
	aListBoxes[7] = &aChapterLB;
	aListBoxes[8] = &aEditionLB;
	aListBoxes[9] = &aEditorLB;
	aListBoxes[10] = &aHowpublishedLB;
	aListBoxes[11] = &aInstitutionLB;
	aListBoxes[12] = &aJournalLB;
	aListBoxes[13] = &aMonthLB;
	aListBoxes[14] = &aNoteLB;
	aListBoxes[15] = &aAnnoteLB;
	aListBoxes[16] = &aNumberLB;
	aListBoxes[17] = &aOrganizationsLB;
	aListBoxes[18] = &aPagesLB;
	aListBoxes[19] = &aPublisherLB;
	aListBoxes[20] = &aAddressLB;
	aListBoxes[21] = &aSchoolLB;
	aListBoxes[22] = &aSeriesLB;
	aListBoxes[23] = &aReportTypeLB;
	aListBoxes[24] = &aVolumeLB;
	aListBoxes[25] = &aURLLB;
	aListBoxes[26] = &aCustom1LB;
	aListBoxes[27] = &aCustom2LB;
	aListBoxes[28] = &aCustom3LB;
	aListBoxes[29] = &aCustom4LB;
	aListBoxes[30] = &aCustom5LB;

	aListBoxes[0]->InsertEntry(sNone);
	Reference< XNameAccess >  xFields = getColumns( pDatMan->getForm() );
	DBG_ASSERT(xFields.is(), "MappingDialog_Impl::MappingDialog_Impl : gave me an invalid form !");
    if(xFields.is())
    {
	    Sequence< ::rtl::OUString > aNames = xFields->getElementNames();
	    sal_Int32 nFieldsCount = aNames.getLength();
	    const ::rtl::OUString* pNames = aNames.getConstArray();

	    for(sal_Int32 nField = 0; nField < nFieldsCount; nField++)
		    aListBoxes[0]->InsertEntry(pNames[nField]);
    }

	Link aLnk = LINK(this, MappingDialog_Impl, ListBoxSelectHdl);

	aListBoxes[0]->SelectEntryPos(0);
	aListBoxes[0]->SetSelectHdl(aLnk);
	for(sal_uInt16 i = 1; i < COLUMN_COUNT; i++)
	{
		for(sal_uInt16 j = 0; j < aListBoxes[0]->GetEntryCount();j++)
			aListBoxes[i]->InsertEntry(aListBoxes[0]->GetEntry(j));
		aListBoxes[i]->SelectEntryPos(0);
		aListBoxes[i]->SetSelectHdl(aLnk);
	}
	BibConfig* pConfig = BibModul::GetConfig();
	BibDBDescriptor aDesc;
	aDesc.sDataSource = pDatMan->getActiveDataSource();
	aDesc.sTableOrQuery = pDatMan->getActiveDataTable();
	aDesc.nCommandType = CommandType::TABLE;
	const Mapping* pMapping = pConfig->GetMapping(aDesc);
	if(pMapping)
	{
		for(sal_uInt16 nEntry = 0; nEntry < COLUMN_COUNT; nEntry++)
		{
			sal_uInt16 nListBoxIndex = lcl_FindLogicalName( pConfig, pMapping->aColumnPairs[nEntry].sLogicalColumnName);
			if(nListBoxIndex < COLUMN_COUNT)
			{
				aListBoxes[nListBoxIndex]->SelectEntry(pMapping->aColumnPairs[nEntry].sRealColumnName);
			}
		}
	}
}
/* -----------------11.11.99 16:44-------------------

 --------------------------------------------------*/
MappingDialog_Impl::~MappingDialog_Impl()
{}
/* -----------------15.11.99 10:38-------------------

 --------------------------------------------------*/
IMPL_LINK(MappingDialog_Impl, ListBoxSelectHdl, ListBox*, pListBox)
{
	sal_uInt16 nEntryPos = pListBox->GetSelectEntryPos();
	if(0 < nEntryPos)
	{
		for(sal_uInt16 i = 0; i < COLUMN_COUNT; i++)
		{
			if(pListBox != aListBoxes[i] && aListBoxes[i]->GetSelectEntryPos() == nEntryPos)
				aListBoxes[i]->SelectEntryPos(0);
		}
	}
	SetModified();
	return 0;
}
/* -----------------12.11.99 14:50-------------------

 --------------------------------------------------*/
IMPL_LINK(MappingDialog_Impl, OkHdl, OKButton*, EMPTYARG)
{
	if(bModified)
	{
		Mapping aNew;
		aNew.sTableName = String(pDatMan->getActiveDataTable());
		aNew.sURL = String(pDatMan->getActiveDataSource());

		sal_uInt16 nWriteIndex = 0;
		BibConfig* pConfig = BibModul::GetConfig();
		for(sal_uInt16 nEntry = 0; nEntry < COLUMN_COUNT; nEntry++)
		{
			String sSel = aListBoxes[nEntry]->GetSelectEntry();
			if(sSel != sNone)
			{
				aNew.aColumnPairs[nWriteIndex].sRealColumnName = sSel;
				aNew.aColumnPairs[nWriteIndex].sLogicalColumnName = pConfig->GetDefColumnName(nEntry);
				nWriteIndex++;
			}
		}
		BibDBDescriptor aDesc;
		aDesc.sDataSource = pDatMan->getActiveDataSource();
		aDesc.sTableOrQuery = pDatMan->getActiveDataTable();
		aDesc.nCommandType = CommandType::TABLE;
		pDatMan->ResetIdentifierMapping();
		pConfig->SetMapping(aDesc, &aNew);
	}
	EndDialog(bModified ? RET_OK : RET_CANCEL);
	return 0;
}
/* -----------------18.11.99 10:23-------------------

 --------------------------------------------------*/
class DBChangeDialog_Impl : public ModalDialog
{
	OKButton		aOKBT;
	CancelButton	aCancelBT;
	HelpButton		aHelpBT;
	FixedLine		aSelectionGB;
	SvTabListBox	aSelectionLB;
	HeaderBar		aSelectionHB;
	DBChangeDialogConfig_Impl	aConfig;
	String			aEntryST;
	String			aURLST;

	BibDataManager* pDatMan;

//	DECL_LINK(EndDragHdl, HeaderBar*);
	DECL_LINK(DoubleClickHdl, SvTabListBox*);
public:
	DBChangeDialog_Impl(Window* pParent, BibDataManager* pMan );
	~DBChangeDialog_Impl();

	String		GetCurrentURL()const;
};

/*-- 18.11.99 10:35:20---------------------------------------------------

  -----------------------------------------------------------------------*/
DBChangeDialog_Impl::DBChangeDialog_Impl(Window* pParent, BibDataManager* pMan ) :
	ModalDialog(pParent, BibResId(RID_DLG_DBCHANGE) ),
	aOKBT(this, 		BibResId( BT_OK		)),
	aCancelBT(this, 	BibResId( BT_CANCEL	)),
	aHelpBT(this,		BibResId( BT_HELP		)),
	aSelectionGB(this,	BibResId( GB_SELECTION )),
	aSelectionLB(this,	BibResId( LB_SELECTION )),
	aSelectionHB(this,	BibResId( HB_SELECTION )),
	aEntryST(BibResId(ST_ENTRY)),
	aURLST( BibResId(ST_URL)),
	pDatMan(pMan)
{
	FreeResource();
	aSelectionLB.SetDoubleClickHdl( LINK(this, DBChangeDialog_Impl, DoubleClickHdl));
	try
	{
		Reference< XMultiServiceFactory >  xMgr = comphelper::getProcessServiceFactory();

		::Size aSize = aSelectionHB.GetSizePixel();
		long nTabs[2];
		nTabs[0] = 1;// Number of Tabs
		nTabs[1] = aSize.Width() / 4;

		aSelectionHB.SetStyle(aSelectionHB.GetStyle()|WB_STDHEADERBAR);
		aSelectionHB.InsertItem( 1, aEntryST, aSize.Width());
		aSelectionHB.SetSizePixel(aSelectionHB.CalcWindowSizePixel());
		aSelectionHB.Show();

		aSelectionLB.SetTabs( &nTabs[0], MAP_PIXEL );
		aSelectionLB.SetStyle(aSelectionLB.GetStyle()|WB_CLIPCHILDREN|WB_SORT);
		aSelectionLB.GetModel()->SetSortMode(SortAscending);

		::rtl::OUString sActiveSource = pDatMan->getActiveDataSource();
		const Sequence< ::rtl::OUString >& rSources = aConfig.GetDataSourceNames();
		const ::rtl::OUString* pSourceNames = rSources.getConstArray();
		for(int i = 0; i < rSources.getLength(); i++)
		{
			SvLBoxEntry* pEntry = aSelectionLB.InsertEntry(pSourceNames[i]);
			if(pSourceNames[i] == sActiveSource)
			{
				aSelectionLB.Select(pEntry);
			}
		}
		aSelectionLB.GetModel()->Resort();
	}
	catch(Exception& e )
	{
		(void) e;	// make compiler happy
        DBG_ERROR("Exception in BibDataManager::DBChangeDialog_Impl::DBChangeDialog_Impl");
	}


}
/* -----------------06.12.99 12:09-------------------

 --------------------------------------------------*/
IMPL_LINK(DBChangeDialog_Impl, DoubleClickHdl, SvTabListBox*, /*pLB*/)
{
	EndDialog(RET_OK);
	return 0;
}
/* -----------------18.11.99 11:17-------------------

 --------------------------------------------------*/
/*IMPL_LINK(DBChangeDialog_Impl, EndDragHdl, HeaderBar*, pHB)
{
	long nTabs[3];
	nTabs[0] = 2;// Number of Tabs
	nTabs[1] = 0;
	nTabs[2] = pHB->GetItemSize( 1 );
	aSelectionLB.SetTabs( &nTabs[0], MAP_PIXEL );
	return 0;
};*/

/*-- 18.11.99 10:35:20---------------------------------------------------

  -----------------------------------------------------------------------*/
DBChangeDialog_Impl::~DBChangeDialog_Impl()
{
}
/* -----------------18.11.99 12:36-------------------

 --------------------------------------------------*/
String	DBChangeDialog_Impl::GetCurrentURL()const
{
	String sRet;
	SvLBoxEntry* pEntry = aSelectionLB.FirstSelected();
	if(pEntry)
	{
		sRet = aSelectionLB.GetEntryText(pEntry, 0);
	}
	return sRet;
}

// #100312# --------------------------------------------------------------------
// XDispatchProvider
BibInterceptorHelper::BibInterceptorHelper( ::bib::BibBeamer* pBibBeamer, ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDispatch)
{
	if( pBibBeamer )
	{
		xInterception = pBibBeamer->getDispatchProviderInterception();
		if( xInterception.is() )
			xInterception->registerDispatchProviderInterceptor( this );
	}
	if( xDispatch.is() )
		xFormDispatch = xDispatch;
}

BibInterceptorHelper::~BibInterceptorHelper( )
{
}

void BibInterceptorHelper::ReleaseInterceptor()
{
	if ( xInterception.is() )
		xInterception->releaseDispatchProviderInterceptor( this );
	xInterception.clear();
}

::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > SAL_CALL
	BibInterceptorHelper::queryDispatch( const ::com::sun::star::util::URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags ) throw (::com::sun::star::uno::RuntimeException)
{
	Reference< XDispatch > xReturn;

	String aCommand( aURL.Path );
	if ( aCommand.EqualsAscii("FormSlots/ConfirmDeletion") )
		xReturn = xFormDispatch;
	else
		if ( xSlaveDispatchProvider.is() )
			xReturn = xSlaveDispatchProvider->queryDispatch( aURL, aTargetFrameName, nSearchFlags);

	return xReturn;
}

::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > > SAL_CALL
	BibInterceptorHelper::queryDispatches( const ::com::sun::star::uno::Sequence< ::com::sun::star::frame::DispatchDescriptor >& aDescripts ) throw (::com::sun::star::uno::RuntimeException)
{
	Sequence< Reference< XDispatch> > aReturn( aDescripts.getLength() );
	Reference< XDispatch >* pReturn = aReturn.getArray();
	const DispatchDescriptor* pDescripts = aDescripts.getConstArray();
	for ( sal_Int16 i=0; i<aDescripts.getLength(); ++i, ++pReturn, ++pDescripts )
	{
		*pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags );
	}
	return aReturn;
}

// XDispatchProviderInterceptor
::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > SAL_CALL
	BibInterceptorHelper::getSlaveDispatchProvider(  ) throw (::com::sun::star::uno::RuntimeException)
{
	return xSlaveDispatchProvider;
}

void SAL_CALL BibInterceptorHelper::setSlaveDispatchProvider( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& xNewSlaveDispatchProvider ) throw (::com::sun::star::uno::RuntimeException)
{
	xSlaveDispatchProvider = xNewSlaveDispatchProvider;
}

::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > SAL_CALL
	BibInterceptorHelper::getMasterDispatchProvider(  ) throw (::com::sun::star::uno::RuntimeException)
{
	return xMasterDispatchProvider;
}

void SAL_CALL BibInterceptorHelper::setMasterDispatchProvider( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& xNewMasterDispatchProvider ) throw (::com::sun::star::uno::RuntimeException)
{
	xMasterDispatchProvider = xNewMasterDispatchProvider;
}

//-----------------------------------------------------------------------------
#define STR_UID "uid"
::rtl::OUString gGridName(C2U("theGrid"));
::rtl::OUString gViewName(C2U("theView"));
::rtl::OUString gGlobalName(C2U("theGlobals"));
::rtl::OUString gBeamerSize(C2U("theBeamerSize"));
::rtl::OUString gViewSize(C2U("theViewSize"));

BibDataManager::BibDataManager()
	:BibDataManager_Base( GetMutex() )
	// #100312# --------------
	,m_pInterceptorHelper( NULL )
    ,m_aLoadListeners(m_aMutex)
	,pBibView( NULL )
	,pToolbar(0)
{
}

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

 --------------------------------------------------*/
BibDataManager::~BibDataManager()
{
	Reference< XLoadable >		xLoad( m_xForm, UNO_QUERY );
	Reference< XPropertySet >	xPrSet( m_xForm, UNO_QUERY );
	Reference< XComponent > 	xComp( m_xForm, UNO_QUERY );
	if ( m_xForm.is() )
	{
		Reference< XComponent >  xConnection;
		xPrSet->getPropertyValue(C2U("ActiveConnection")) >>= xConnection;
		RemoveMeAsUidListener();
		if (xLoad.is())
			xLoad->unload();
		if (xComp.is())
			xComp->dispose();
		if(xConnection.is())
			xConnection->dispose();
		m_xForm = NULL;
	}
	// #100312# ----------------
	if( m_pInterceptorHelper )
	{
		m_pInterceptorHelper->ReleaseInterceptor();
		m_pInterceptorHelper->release();
		m_pInterceptorHelper = NULL;
	}
}
//------------------------------------------------------------------------
void BibDataManager::InsertFields(const Reference< XFormComponent > & _rxGrid)
{
	if ( !_rxGrid.is() )
		return;

	try
	{
		Reference< XNameContainer > xColContainer( _rxGrid, UNO_QUERY );
		// remove the old fields
		if ( xColContainer->hasElements() )
		{
			Sequence< ::rtl::OUString > aNames = xColContainer->getElementNames();
			const ::rtl::OUString* pNames = aNames.getConstArray();
			const ::rtl::OUString* pNamesEnd = pNames + aNames.getLength();
			for ( ; pNames != pNamesEnd; ++pNames )
				xColContainer->removeByName( *pNames );
		}

		Reference< XNameAccess >  xFields = getColumns( m_xForm );
		if (!xFields.is())
			return;

		Reference< XGridColumnFactory > xColFactory( _rxGrid, UNO_QUERY );

		Reference< XPropertySet >  xField;

		Sequence< ::rtl::OUString > aFields( xFields->getElementNames() );
		const ::rtl::OUString* pFields = aFields.getConstArray();
		const ::rtl::OUString* pFieldsEnd = pFields + aFields.getLength();

		for ( ; pFields != pFieldsEnd; ++pFields )
		{
			xFields->getByName( *pFields ) >>= xField;

			::rtl::OUString sCurrentModelType;
			const ::rtl::OUString sType(C2U("Type"));
			sal_Int32 nType = 0;
			sal_Bool bIsFormatted			= sal_False;
			sal_Bool bFormattedIsNumeric	= sal_True;
			xField->getPropertyValue(sType) >>= nType;
			switch(nType)
			{
				case DataType::BIT:
				case DataType::BOOLEAN:
					sCurrentModelType = C2U("CheckBox");
					break;

				case DataType::BINARY:
				case DataType::VARBINARY:
				case DataType::LONGVARBINARY:
				case DataType::BLOB:
					sCurrentModelType = C2U("TextField");
					break;

				case DataType::VARCHAR:
				case DataType::LONGVARCHAR:
				case DataType::CHAR:
				case DataType::CLOB:
					bFormattedIsNumeric = sal_False;
					// _NO_ break !
				default:
					sCurrentModelType = C2U("FormattedField");
					bIsFormatted = sal_True;
					break;
			}

			Reference< XPropertySet >  xCurrentCol = xColFactory->createColumn(sCurrentModelType);
			if (bIsFormatted)
			{
				::rtl::OUString sFormatKey(C2U("FormatKey"));
				xCurrentCol->setPropertyValue(sFormatKey, xField->getPropertyValue(sFormatKey));
				Any aFormatted(&bFormattedIsNumeric, ::getBooleanCppuType());
				xCurrentCol->setPropertyValue(C2U("TreatAsNumber"), aFormatted);
			}
			Any aColName = makeAny( *pFields );
			xCurrentCol->setPropertyValue(FM_PROP_CONTROLSOURCE,	aColName);
			xCurrentCol->setPropertyValue(FM_PROP_LABEL, aColName);

			xColContainer->insertByName( *pFields, makeAny( xCurrentCol ) );
		}
	}
	catch(Exception& e )
	{
		(void) e;	// make compiler happy
        DBG_ERROR("Exception in BibDataManager::InsertFields");
	}
}
/* --------------------------------------------------

 --------------------------------------------------*/
Reference< awt::XControlModel >	BibDataManager::updateGridModel()
{
	return updateGridModel( m_xForm );
}
/* --------------------------------------------------

 --------------------------------------------------*/
Reference< awt::XControlModel >	BibDataManager::updateGridModel(const Reference< XForm > & xDbForm)
{
	try
	{
		Reference< XPropertySet >  aFormPropSet( xDbForm, UNO_QUERY );
		::rtl::OUString sName;
		aFormPropSet->getPropertyValue(C2U("Command")) >>= sName;

		if ( !m_xGridModel.is() )
		{
			m_xGridModel = createGridModel( gGridName );

			Reference< XNameContainer >  xNameCont(xDbForm, UNO_QUERY);
//			if (xNameCont->hasByName(sName))
//				xNameCont->removeByName(sName);
//
			xNameCont->insertByName( sName, makeAny( m_xGridModel ) );
		}

		// insert the fields
		Reference< XFormComponent > xFormComp( m_xGridModel, UNO_QUERY );
		InsertFields( xFormComp );
	}
	catch(Exception& e )
	{
		(void) e;	// make compiler happy
        DBG_ERROR("::updateGridModel: something went wrong !");
	}


	return m_xGridModel;
}
/* --------------------------------------------------

 --------------------------------------------------*/
Reference< XForm >	BibDataManager::createDatabaseForm(BibDBDescriptor& rDesc)
{
	Reference< XForm >	xResult;
	try
	{
		Reference< XMultiServiceFactory >  xMgr = comphelper::getProcessServiceFactory();
		m_xForm = Reference< XForm > ( xMgr->createInstance( C2U("com.sun.star.form.component.Form") ), UNO_QUERY );

		Reference< XPropertySet >  aPropertySet( m_xForm, UNO_QUERY );

		aDataSourceURL = rDesc.sDataSource;
		if(aPropertySet.is())
		{
			Any aVal;
			aVal <<= (sal_Int32)ResultSetType::SCROLL_INSENSITIVE;
			aPropertySet->setPropertyValue(C2U("ResultSetType"),aVal );
			aVal <<= (sal_Int32)ResultSetConcurrency::READ_ONLY;
			aPropertySet->setPropertyValue(C2U("ResultSetConcurrency"), aVal);

			//Caching for Performance
			aVal <<= (sal_Int32)50;
			aPropertySet->setPropertyValue(C2U("FetchSize"), aVal);

			Reference< XConnection >	xConnection = getConnection(rDesc.sDataSource);
			aVal <<= xConnection;
			aPropertySet->setPropertyValue(C2U("ActiveConnection"), aVal);

			Reference< XTablesSupplier >  xSupplyTables(xConnection, UNO_QUERY);
			Reference< XNameAccess >  xTables = xSupplyTables.is() ?
								xSupplyTables->getTables() : Reference< XNameAccess > ();

			Sequence< ::rtl::OUString > aTableNameSeq;
			if (xTables.is())
				aTableNameSeq = xTables->getElementNames();

			if(aTableNameSeq.getLength() > 0)
			{
				const ::rtl::OUString* pTableNames = aTableNameSeq.getConstArray();
				if(rDesc.sTableOrQuery.getLength())
					aActiveDataTable = rDesc.sTableOrQuery;
				else
				{
					rDesc.sTableOrQuery = aActiveDataTable = pTableNames[0];
					rDesc.nCommandType = CommandType::TABLE;
				}

				aVal <<= aActiveDataTable;
				aPropertySet->setPropertyValue(C2U("Command"), aVal);
				aVal <<= rDesc.nCommandType;
				aPropertySet->setPropertyValue(C2U("CommandType"), aVal);


				Reference< XDatabaseMetaData >	xMetaData = xConnection->getMetaData();
				aQuoteChar = xMetaData->getIdentifierQuoteString();

				Reference< XMultiServiceFactory > xFactory(xConnection, UNO_QUERY);
                if ( xFactory.is() )
				    m_xParser.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ), UNO_QUERY );

				::rtl::OUString aString(C2U("SELECT * FROM "));

                ::rtl::OUString sCatalog, sSchema, sName;
                ::dbtools::qualifiedNameComponents( xMetaData, aActiveDataTable, sCatalog, sSchema, sName, ::dbtools::eInDataManipulation );
                aString += ::dbtools::composeTableNameForSelect( xConnection, sCatalog, sSchema, sName );

                m_xParser->setElementaryQuery(aString);
				BibConfig* pConfig = BibModul::GetConfig();
				pConfig->setQueryField(getQueryField());
				startQueryWith(pConfig->getQueryText());

				xResult = m_xForm;
			}
		}
	}
	catch(Exception& e )
	{
		(void) e;	// make compiler happy
        DBG_ERROR("::createDatabaseForm: something went wrong !");
	}


	return xResult;
}
//------------------------------------------------------------------------
Sequence< ::rtl::OUString > BibDataManager::getDataSources()
{
	Sequence< ::rtl::OUString > aTableNameSeq;

	try
	{
		Reference< XTablesSupplier >  xSupplyTables( getConnection( m_xForm ), UNO_QUERY );
		Reference< XNameAccess >  xTables;
		if (xSupplyTables.is())
			xTables = xSupplyTables->getTables();
		if (xTables.is())
			aTableNameSeq = xTables->getElementNames();
	}
	catch(Exception& e )
	{
		(void) e;	// make compiler happy
        DBG_ERROR("::getDataSources: something went wrong !");
	}


	return aTableNameSeq;
}
//------------------------------------------------------------------------
::rtl::OUString BibDataManager::getActiveDataTable()
{
	return aActiveDataTable;
}
//------------------------------------------------------------------------
void BibDataManager::setFilter(const ::rtl::OUString& rQuery)
{
	if(!m_xParser.is())
        return;
    try
	{
		m_xParser->setFilter( rQuery );
		::rtl::OUString aQuery = m_xParser->getFilter();
		Reference< XPropertySet >  xFormProps( m_xForm, UNO_QUERY_THROW );
		xFormProps->setPropertyValue( C2U( "Filter" ), makeAny( aQuery ) );
		xFormProps->setPropertyValue( C2U( "ApplyFilter" ), makeAny( sal_True ) );
		reload();
	}
	catch(Exception& e )
	{
        DBG_UNHANDLED_EXCEPTION();
	}


}
//------------------------------------------------------------------------
::rtl::OUString BibDataManager::getFilter()
{

	::rtl::OUString aQueryString;
	try
	{
		Reference< XPropertySet > xFormProps( m_xForm, UNO_QUERY_THROW );
        OSL_VERIFY( xFormProps->getPropertyValue( C2U( "Filter" ) ) >>= aQueryString );
	}
	catch( const Exception& )
	{
        DBG_UNHANDLED_EXCEPTION();
	}


	return aQueryString;

}
//------------------------------------------------------------------------
Sequence< ::rtl::OUString > BibDataManager::getQueryFields()
{
	Sequence< ::rtl::OUString > aFieldSeq;
	Reference< XNameAccess >  xFields = getColumns( m_xForm );
	if (xFields.is())
		aFieldSeq = xFields->getElementNames();
	return aFieldSeq;
}
//------------------------------------------------------------------------
::rtl::OUString BibDataManager::getQueryField()
{
	BibConfig* pConfig = BibModul::GetConfig();
	::rtl::OUString aFieldString = pConfig->getQueryField();
	if(!aFieldString.getLength())
	{
		Sequence< ::rtl::OUString > aSeq = getQueryFields();
		const ::rtl::OUString* pFields = aSeq.getConstArray();
		if(aSeq.getLength()>0)
		{
			aFieldString=pFields[0];
		}
	}
	return aFieldString;
}
//------------------------------------------------------------------------
void BibDataManager::startQueryWith(const ::rtl::OUString& rQuery)
{
	BibConfig* pConfig = BibModul::GetConfig();
	pConfig->setQueryText( rQuery );

	::rtl::OUString aQueryString;
	if(rQuery.getLength()>0)
	{
		aQueryString=aQuoteChar;
		aQueryString+=getQueryField();
		aQueryString+=aQuoteChar;
		aQueryString+=C2U(" like '");
		String sQuery(rQuery);
		sQuery.SearchAndReplaceAll('?','_');
		sQuery.SearchAndReplaceAll('*','%');
		aQueryString += sQuery;
		aQueryString+=C2U("%'");
	}
	setFilter(aQueryString);
}
/* -----------------03.12.99 15:05-------------------

 --------------------------------------------------*/
void BibDataManager::setActiveDataSource(const ::rtl::OUString& rURL)
{
	::rtl::OUString uTable;
	::rtl::OUString sTmp(aDataSourceURL);
	aDataSourceURL = rURL;

	Reference< XPropertySet >  aPropertySet( m_xForm, UNO_QUERY );
	if(aPropertySet.is())
	{
		unload();

		Reference< XComponent >  xOldConnection;
		aPropertySet->getPropertyValue(C2U("ActiveConnection")) >>= xOldConnection;

		Reference< XConnection >	xConnection = getConnection(rURL);
		if(!xConnection.is())
		{
			aDataSourceURL = sTmp;
			return;
		}
		Any aVal; aVal <<= xConnection;
		aPropertySet->setPropertyValue(C2U("ActiveConnection"), aVal);
		Reference< XMultiServiceFactory >   xFactory(xConnection, UNO_QUERY);
        if ( xFactory.is() )
			m_xParser.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ), UNO_QUERY );

		if(xOldConnection.is())
			xOldConnection->dispose();

		Sequence< ::rtl::OUString > aTableNameSeq;
		Reference< XTablesSupplier >  xSupplyTables(xConnection, UNO_QUERY);
		if(xSupplyTables.is())
		{
			Reference< XNameAccess >  xAccess = xSupplyTables->getTables();
			aTableNameSeq = xAccess->getElementNames();
		}
		if(aTableNameSeq.getLength() > 0)
		{
			const ::rtl::OUString* pTableNames = aTableNameSeq.getConstArray();
			aActiveDataTable = pTableNames[0];
			aVal <<= aActiveDataTable;
			aPropertySet->setPropertyValue(C2U("Command"), aVal);
            aPropertySet->setPropertyValue(C2U("CommandType"), makeAny(CommandType::TABLE));
            //Caching for Performance
            aVal <<= (sal_Int32)50;
            aPropertySet->setPropertyValue(C2U("FetchSize"), aVal);
            ::rtl::OUString aString(C2U("SELECT * FROM "));
			// quote the table name which may contain catalog.schema.table
			Reference<XDatabaseMetaData> xMetaData(xConnection->getMetaData(),UNO_QUERY);
			aQuoteChar = xMetaData->getIdentifierQuoteString();

            ::rtl::OUString sCatalog, sSchema, sName;
            ::dbtools::qualifiedNameComponents( xMetaData, aActiveDataTable, sCatalog, sSchema, sName, ::dbtools::eInDataManipulation );
            aString += ::dbtools::composeTableNameForSelect( xConnection, sCatalog, sSchema, sName );

            m_xParser->setElementaryQuery(aString);
			BibConfig* pConfig = BibModul::GetConfig();
			pConfig->setQueryField(getQueryField());
			startQueryWith(pConfig->getQueryText());
			setActiveDataTable(aActiveDataTable);
		}
		FeatureStateEvent aEvent;
		util::URL aURL;
		aEvent.IsEnabled  = sal_True;
		aEvent.Requery	  = sal_False;
		aEvent.FeatureDescriptor = getActiveDataTable();

		aEvent.State = makeAny( getDataSources() );

		if(pToolbar)
		{
			aURL.Complete =C2U(".uno:Bib/source");
			aEvent.FeatureURL = aURL;
			pToolbar->statusChanged( aEvent );
		}

        updateGridModel();
        load();
    }
}

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

 --------------------------------------------------*/
void BibDataManager::setActiveDataTable(const ::rtl::OUString& rTable)
{
	ResetIdentifierMapping();
	try
	{
		Reference< XPropertySet >  aPropertySet( m_xForm, UNO_QUERY );

		if(aPropertySet.is())
		{
			Reference< XConnection >	xConnection = getConnection( m_xForm );
			Reference< XTablesSupplier >  xSupplyTables(xConnection, UNO_QUERY);
			Reference< XNameAccess > xAccess = xSupplyTables->getTables();
			Sequence< ::rtl::OUString > aTableNameSeq = xAccess->getElementNames();
			sal_uInt32 nCount = aTableNameSeq.getLength();

			const ::rtl::OUString* pTableNames = aTableNameSeq.getConstArray();
			const ::rtl::OUString* pTableNamesEnd = pTableNames + nCount;

			for ( ; pTableNames != pTableNamesEnd; ++pTableNames )
			{
				if ( rTable == *pTableNames )
				{
					aActiveDataTable = rTable;
					Any aVal; aVal <<= rTable;
					aPropertySet->setPropertyValue( C2U("Command"), aVal );
					break;
				}
			}
			if (pTableNames != pTableNamesEnd)
			{
				Reference< XDatabaseMetaData >	xMetaData = xConnection->getMetaData();
				aQuoteChar = xMetaData->getIdentifierQuoteString();

				Reference< XMultiServiceFactory > xFactory(xConnection, UNO_QUERY);
                if ( xFactory.is() )
				    m_xParser.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ), UNO_QUERY );

				::rtl::OUString aString(C2U("SELECT * FROM "));

                ::rtl::OUString sCatalog, sSchema, sName;
                ::dbtools::qualifiedNameComponents( xMetaData, aActiveDataTable, sCatalog, sSchema, sName, ::dbtools::eInDataManipulation );
                aString += ::dbtools::composeTableNameForSelect( xConnection, sCatalog, sSchema, sName );

                m_xParser->setElementaryQuery(aString);

				BibConfig* pConfig = BibModul::GetConfig();
				pConfig->setQueryField(getQueryField());
				startQueryWith(pConfig->getQueryText());

				BibDBDescriptor aDesc;
				aDesc.sDataSource = aDataSourceURL;
				aDesc.sTableOrQuery = aActiveDataTable;
				aDesc.nCommandType = CommandType::TABLE;
				BibModul::GetConfig()->SetBibliographyURL(aDesc);
			}
		}
	}
	catch(Exception& e )
	{
		(void) e;	// make compiler happy
        DBG_ERROR("::setActiveDataTable: something went wrong !");
	}

}

//------------------------------------------------------------------------
void SAL_CALL BibDataManager::load(  ) throw (RuntimeException)
{
	if ( isLoaded() )
		// nothing to do
		return;

	Reference< XLoadable > xFormAsLoadable( m_xForm, UNO_QUERY );
	DBG_ASSERT( xFormAsLoadable.is() || !m_xForm.is(), "BibDataManager::load: invalid form!");
	if ( xFormAsLoadable.is() )
	{
		xFormAsLoadable->load();
		SetMeAsUidListener();

		EventObject aEvt( static_cast< XWeak* >( this ) );
		m_aLoadListeners.notifyEach( &XLoadListener::loaded, aEvt );
	}
}

//------------------------------------------------------------------------
void SAL_CALL BibDataManager::unload(  ) throw (RuntimeException)
{
	if ( !isLoaded() )
		// nothing to do
		return;

	Reference< XLoadable >xFormAsLoadable( m_xForm, UNO_QUERY );
	DBG_ASSERT( xFormAsLoadable.is() || !m_xForm.is(), "BibDataManager::unload: invalid form!");
	if ( xFormAsLoadable.is() )
	{
		EventObject aEvt( static_cast< XWeak* >( this ) );

		{
			m_aLoadListeners.notifyEach( &XLoadListener::unloading, aEvt );
		}

		RemoveMeAsUidListener();
		xFormAsLoadable->unload();

		{
			m_aLoadListeners.notifyEach( &XLoadListener::unloaded, aEvt );
		}
	}
}

//------------------------------------------------------------------------
void SAL_CALL BibDataManager::reload(  ) throw (RuntimeException)
{
	if ( !isLoaded() )
		// nothing to do
		return;

	Reference< XLoadable >xFormAsLoadable( m_xForm, UNO_QUERY );
	DBG_ASSERT( xFormAsLoadable.is() || !m_xForm.is(), "BibDataManager::unload: invalid form!");
	if ( xFormAsLoadable.is() )
	{
		EventObject aEvt( static_cast< XWeak* >( this ) );

		{
			m_aLoadListeners.notifyEach( &XLoadListener::reloading, aEvt );
		}

		xFormAsLoadable->reload();

		{
			m_aLoadListeners.notifyEach( &XLoadListener::reloaded, aEvt );
		}
	}
}

//------------------------------------------------------------------------
sal_Bool SAL_CALL BibDataManager::isLoaded(  ) throw (RuntimeException)
{
	Reference< XLoadable >xFormAsLoadable( m_xForm, UNO_QUERY );
	DBG_ASSERT( xFormAsLoadable.is() || !m_xForm.is(), "BibDataManager::isLoaded: invalid form!");

	sal_Bool bLoaded = sal_False;
	if ( xFormAsLoadable.is() )
		bLoaded = xFormAsLoadable->isLoaded();
	return bLoaded;
}

//------------------------------------------------------------------------
void SAL_CALL BibDataManager::addLoadListener( const Reference< XLoadListener >& aListener ) throw (RuntimeException)
{
	m_aLoadListeners.addInterface( aListener );
}

//------------------------------------------------------------------------
void SAL_CALL BibDataManager::removeLoadListener( const Reference< XLoadListener >& aListener ) throw (RuntimeException)
{
	m_aLoadListeners.removeInterface( aListener );
}

//------------------------------------------------------------------------
Reference< awt::XControlModel >	BibDataManager::createGridModel(const ::rtl::OUString& rName)
{
	Reference< awt::XControlModel >	xModel;

	try
	{
		// create the control model
		Reference< XMultiServiceFactory >  xMgr = ::comphelper::getProcessServiceFactory();
		Reference< XInterface >  xObject = xMgr->createInstance(C2U("com.sun.star.form.component.GridControl"));
		xModel=Reference< awt::XControlModel > ( xObject, UNO_QUERY );

		// set the
		Reference< XPropertySet > xPropSet( xModel, UNO_QUERY );
		xPropSet->setPropertyValue( C2U("Name"), makeAny( rName ) );

		// set the name of the to-be-created control
		::rtl::OUString aControlName(C2U("com.sun.star.form.control.InteractionGridControl"));
		Any aAny; aAny <<= aControlName;
		xPropSet->setPropertyValue( C2U("DefaultControl"),aAny );

		// the the helpURL
		::rtl::OUString uProp(C2U("HelpURL"));
		Reference< XPropertySetInfo > xPropInfo = xPropSet->getPropertySetInfo();
		if (xPropInfo->hasPropertyByName(uProp))
		{
	        ::rtl::OUString sId = ::rtl::OUString::createFromAscii( INET_HID_SCHEME );
			sId += ::rtl::OUString::createFromAscii( HID_BIB_DB_GRIDCTRL );
			xPropSet->setPropertyValue( uProp, makeAny( sId ) );
		}
	}
	catch(Exception& e )
	{
		(void) e;	// make compiler happy
        DBG_ERROR("::createGridModel: something went wrong !");
	}


	return xModel;
}
//------------------------------------------------------------------------
::rtl::OUString BibDataManager::getControlName(sal_Int32 nFormatKey )
{
	::rtl::OUString aResStr;
	switch (nFormatKey)
	{
		case DataType::BIT:
		case DataType::BOOLEAN:
			aResStr=C2U("CheckBox");
			break;
		case DataType::TINYINT:
		case DataType::SMALLINT:
		case DataType::INTEGER:
			aResStr=C2U("NumericField");   ;
			break;
		case DataType::REAL:
		case DataType::DOUBLE:
		case DataType::NUMERIC:
		case DataType::DECIMAL:
			aResStr=C2U("FormattedField");
			break;
		case DataType::TIMESTAMP:
			aResStr=C2U("FormattedField");
			break;
		case DataType::DATE:
			aResStr=C2U("DateField");
			break;
		case DataType::TIME:
			aResStr=C2U("TimeField");
			break;
		case DataType::CHAR:
		case DataType::VARCHAR:
		case DataType::LONGVARCHAR:
		default:
			aResStr=C2U("TextField");
			break;
	}
	return aResStr;
}
//------------------------------------------------------------------------
Reference< awt::XControlModel >	BibDataManager::loadControlModel(
					const ::rtl::OUString& rName, sal_Bool bForceListBox)
{
	Reference< awt::XControlModel >	xModel;
	::rtl::OUString aName(C2U("View_"));
	aName += rName;

	try
	{
		Reference< XNameAccess >  xFields = getColumns( m_xForm );
		if (!xFields.is())
			return xModel;
		Reference< XPropertySet >  xField;

		Any aElement;

		if(xFields->hasByName(rName))
		{
			aElement = xFields->getByName(rName);
			aElement >>= xField;
			Reference< XPropertySetInfo >  xInfo = xField.is() ? xField->getPropertySetInfo() : Reference< XPropertySetInfo > ();

			::rtl::OUString sCurrentModelType;
			const ::rtl::OUString sType(C2U("Type"));
			sal_Int32 nFormatKey = 0;
			xField->getPropertyValue(sType) >>= nFormatKey;

			::rtl::OUString aInstanceName(C2U("com.sun.star.form.component."));

			if (bForceListBox)
				aInstanceName += C2U("ListBox");
			else
				aInstanceName += getControlName(nFormatKey);

			Reference< XMultiServiceFactory >  xMgr = comphelper::getProcessServiceFactory();
			Reference< XInterface >  xObject = xMgr->createInstance(aInstanceName);
			xModel=Reference< awt::XControlModel > ( xObject, UNO_QUERY );
			Reference< XPropertySet >  xPropSet( xModel, UNO_QUERY );
			Any aFieldName; aFieldName <<= aName;

            xPropSet->setPropertyValue( FM_PROP_NAME,aFieldName);
			xPropSet->setPropertyValue( FM_PROP_CONTROLSOURCE, makeAny( rName ) );
			xPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NativeWidgetLook" ) ), makeAny( (sal_Bool)sal_True ) );

			Reference< XFormComponent >  aFormComp(xModel,UNO_QUERY );

			Reference< XNameContainer >  xNameCont( m_xForm, UNO_QUERY );
			xNameCont->insertByName(aName, makeAny( aFormComp ) );

			// now if the form where we inserted the new model is already loaded, notify the model of this
			// Note that this implementation below is a HACK as it relies on the fact that the model adds itself
			// as load listener to it's parent, which is an implementation detail of the model.
			//
			// the better solution would be the following:
			// in the current scenario, we insert a control model into a form. This results in the control model
			// adding itself as load listener to the form. Now, the form should realize that it's already loaded
			// and notify the model (which it knows as XLoadListener only) immediately. This seems to make sense.
			// (as an anologon to the XStatusListener semantics).
			//
			// But this would be way too risky for this last-day fix here.
			// 97140 - 30.01.2002 - fs@openoffice.org
			Reference< XLoadable > xLoad( m_xForm, UNO_QUERY );
			if ( xLoad.is() && xLoad->isLoaded() )
			{
				Reference< XLoadListener > xListener( aFormComp, UNO_QUERY );
				if ( xListener.is() )
				{
					EventObject aLoadSource;
					aLoadSource.Source = xLoad;
					xListener->loaded( aLoadSource );
				}
			}
		}
	}
	catch(Exception& e )
	{
        (void) e;	// make compiler happy
        DBG_ERROR("::loadControlModel: something went wrong !");
	}
	return xModel;
}
//------------------------------------------------------------------------
void SAL_CALL BibDataManager::disposing()
{
    BibDataManager_Base::WeakComponentImplHelperBase::disposing();
}

//------------------------------------------------------------------------
void BibDataManager::disposing( const EventObject& /*Source*/ ) throw( ::com::sun::star::uno::RuntimeException )
{
	// not interested in
}

//------------------------------------------------------------------------
void BibDataManager::propertyChange(const beans::PropertyChangeEvent& evt) throw( RuntimeException )
{
	try
	{
		sal_Bool bFlag=sal_False;
		if(evt.PropertyName == FM_PROP_VALUE)
		{
			if( evt.NewValue.getValueType() == ::getCppuType((Reference<io::XInputStream>*)0) )
			{
				Reference< io::XDataInputStream >  xStream(
					*(const Reference< io::XInputStream > *)evt.NewValue.getValue(), UNO_QUERY );
				aUID <<= xStream->readUTF();
			}
			else
				aUID = evt.NewValue;

			Reference< XRowLocate > xLocate(xBibCursor, UNO_QUERY);
			DBG_ASSERT(xLocate.is(), "BibDataManager::propertyChange : invalid cursor !");
			bFlag = xLocate->moveToBookmark(aUID);
		}
	}
	catch(Exception& e )
	{
		(void) e;	// make compiler happy
        DBG_ERROR("::propertyChange: something went wrong !");
	}


}
//------------------------------------------------------------------------
void BibDataManager::SetMeAsUidListener()
{
try
{
	Reference< XNameAccess >  xFields = getColumns( m_xForm );
	if (!xFields.is())
		return;

	Sequence< ::rtl::OUString > aFields(xFields->getElementNames());
	const ::rtl::OUString* pFields = aFields.getConstArray();
	sal_Int32 nCount=aFields.getLength();
	String StrUID(C2S(STR_UID));
	::rtl::OUString theFieldName;
	for( sal_Int32 i=0; i<nCount; i++ )
	{
		String aName= pFields[i];

		if(aName.EqualsIgnoreCaseAscii(StrUID))
		{
			theFieldName=pFields[i];
			break;
		}
	}

	if(theFieldName.getLength()>0)
	{
		Reference< XPropertySet >  xPropSet;
		Any aElement;

		aElement = xFields->getByName(theFieldName);
		xPropSet = *(Reference< XPropertySet > *)aElement.getValue();

		xPropSet->addPropertyChangeListener(FM_PROP_VALUE, this);
	}

}
catch(Exception& e )
{
	(void) e;	// make compiler happy
    DBG_ERROR("Exception in BibDataManager::SetMeAsUidListener");
}


}
//------------------------------------------------------------------------
void BibDataManager::RemoveMeAsUidListener()
{
try
{
	Reference< XNameAccess >  xFields = getColumns( m_xForm );
	if (!xFields.is())
		return;


	Sequence< ::rtl::OUString > aFields(xFields->getElementNames());
	const ::rtl::OUString* pFields = aFields.getConstArray();
	sal_Int32 nCount=aFields.getLength();
	String StrUID(C2S(STR_UID));
	::rtl::OUString theFieldName;
	for( sal_Int32 i=0; i<nCount; i++ )
	{
		String aName= pFields[i];

		if(aName.EqualsIgnoreCaseAscii(StrUID))
		{
			theFieldName=pFields[i];
			break;
		}
	}

	if(theFieldName.getLength()>0)
	{
		Reference< XPropertySet >  xPropSet;
		Any aElement;

		aElement = xFields->getByName(theFieldName);
		xPropSet = *(Reference< XPropertySet > *)aElement.getValue();

		xPropSet->removePropertyChangeListener(FM_PROP_VALUE, this);
	}

}
catch(Exception& e )
{
	(void) e;	// make compiler happy
    DBG_ERROR("Exception in BibDataManager::RemoveMeAsUidListener");
}


}
/* -----------------11.11.99 15:51-------------------

 --------------------------------------------------*/
void BibDataManager::CreateMappingDialog(Window* pParent)
{
	MappingDialog_Impl* pDlg = new MappingDialog_Impl(pParent, this);
	if(RET_OK == pDlg->Execute() && pBibView)
	{
		reload();
//		unload();
//		pBibView->UpdatePages();
//		load();
	}
	delete pDlg;
}
/* --------------------------------------------------

 --------------------------------------------------*/
::rtl::OUString BibDataManager::CreateDBChangeDialog(Window* pParent)
{
	::rtl::OUString uRet;
	DBChangeDialog_Impl * pDlg = new DBChangeDialog_Impl(pParent, this );
	if(RET_OK == pDlg->Execute())
	{
		String sNewURL = pDlg->GetCurrentURL();
		if(sNewURL != String(getActiveDataSource()))
		{
			uRet = sNewURL;
		}
	}
	delete pDlg;
	return uRet;
}
/*-- 18.05.2004 15:20:15---------------------------------------------------

  -----------------------------------------------------------------------*/
void BibDataManager::DispatchDBChangeDialog()
{
    if(pToolbar)
        pToolbar->SendDispatch(TBC_BT_CHANGESOURCE, Sequence< PropertyValue >());
}
/* -----------------06.12.99 15:11-------------------

 --------------------------------------------------*/
const ::rtl::OUString& BibDataManager::GetIdentifierMapping()
{
	if(!sIdentifierMapping.getLength())
	{
		BibConfig* pConfig = BibModul::GetConfig();
		BibDBDescriptor aDesc;
		aDesc.sDataSource = getActiveDataSource();
		aDesc.sTableOrQuery = getActiveDataTable();
		aDesc.nCommandType = CommandType::TABLE;
		const Mapping* pMapping = pConfig->GetMapping(aDesc);
		sIdentifierMapping = pConfig->GetDefColumnName(IDENTIFIER_POS);
		if(pMapping)
		{
			for(sal_uInt16 nEntry = 0; nEntry < COLUMN_COUNT; nEntry++)
			{
				if(pMapping->aColumnPairs[nEntry].sLogicalColumnName == sIdentifierMapping)
				{
					sIdentifierMapping = pMapping->aColumnPairs[nEntry].sRealColumnName;
					break;
				}
			}
		}
	}
	return sIdentifierMapping;
}
/* -----------------------------20.11.00 10:31--------------------------------

 ---------------------------------------------------------------------------*/
void BibDataManager::SetToolbar(BibToolBar* pSet)
{
	pToolbar = pSet;
	if(pToolbar)
		pToolbar->SetDatMan(*this);
}
/* -----------------------------08.05.2002 09:26------------------------------

 ---------------------------------------------------------------------------*/
uno::Reference< form::runtime::XFormController > BibDataManager::GetFormController()
{
    if(!m_xFormCtrl.is())
    {
        Reference< lang::XMultiServiceFactory > xMgr = comphelper::getProcessServiceFactory();
        m_xFormCtrl = uno::Reference< form::runtime::XFormController > (
            xMgr->createInstance(C2U("com.sun.star.form.runtime.FormController")), UNO_QUERY);
        m_xFormCtrl->setModel(uno::Reference< awt::XTabControllerModel > (getForm(), UNO_QUERY));
        // #100312# -------------
        m_xFormDispatch = uno::Reference< frame::XDispatch > ( m_xFormCtrl, UNO_QUERY);
    }
    return m_xFormCtrl;
}

// #100312# ----------
void BibDataManager::RegisterInterceptor( ::bib::BibBeamer* pBibBeamer)
{
	DBG_ASSERT( !m_pInterceptorHelper, "BibDataManager::RegisterInterceptor: called twice!" );

	if( pBibBeamer )
		m_pInterceptorHelper = new BibInterceptorHelper( pBibBeamer, m_xFormDispatch);
	if( m_pInterceptorHelper )
		m_pInterceptorHelper->acquire();
}

/*-- 18.05.2004 17:04:20---------------------------------------------------

  -----------------------------------------------------------------------*/
sal_Bool BibDataManager::HasActiveConnection()const
{
    sal_Bool bRet = sal_False;
    Reference< XPropertySet >   xPrSet( m_xForm, UNO_QUERY );
    if( xPrSet.is() )
    {
        Reference< XComponent >  xConnection;
        xPrSet->getPropertyValue(C2U("ActiveConnection")) >>= xConnection;
        bRet = xConnection.is();
    }
    return bRet;
}
/*-- 04.06.2004 14:37:29---------------------------------------------------

  -----------------------------------------------------------------------*/
sal_Bool BibDataManager::HasActiveConnection()
{
    return getConnection( m_xForm ).is();
}
