/**************************************************************
 * 
 * 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_svtools.hxx"

#include <stdio.h>
#include <svtools/addresstemplate.hxx>
#include "addresstemplate.hrc"
#include <svtools/svtools.hrc>
#include <svtools/helpid.hrc>
#include <svtools/svtdata.hxx>
#include <tools/debug.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/stl_types.hxx>
#include <vcl/stdtext.hxx>
#include <vcl/waitobj.hxx>
#include <vcl/msgbox.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <comphelper/extract.hxx>
#include <comphelper/interaction.hxx>
#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/sdb/XCompletedConnection.hpp>
#include <com/sun/star/sdb/SQLContext.hpp>
#include <com/sun/star/sdbc/SQLWarning.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <svtools/localresaccess.hxx>
#include "svl/filenotation.hxx"
#include <tools/urlobj.hxx>
#include <algorithm>

// .......................................................................
namespace svt
{
// .......................................................................

	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::container;
	using namespace ::com::sun::star::ui::dialogs;
	using namespace ::com::sun::star::util;
	using namespace ::com::sun::star::beans;
	using namespace ::com::sun::star::sdb;
	using namespace ::com::sun::star::sdbc;
	using namespace ::com::sun::star::sdbcx;
	using namespace ::com::sun::star::task;
	using namespace ::comphelper;
	using namespace ::utl;

	DECLARE_STL_VECTOR( String, StringArray );
	DECLARE_STL_STDKEY_SET( ::rtl::OUString, StringBag );
	DECLARE_STL_USTRINGACCESS_MAP( ::rtl::OUString, MapString2String );

    namespace
    {
        String lcl_getSelectedDataSource( const ComboBox& _dataSourceCombo )
        {
            String selectedDataSource = _dataSourceCombo.GetText();
            if ( _dataSourceCombo.GetEntryPos( selectedDataSource ) == LISTBOX_ENTRY_NOTFOUND )
            {
                // none of the pre-selected entries -> assume a path to a database document
	            OFileNotation aFileNotation( selectedDataSource, OFileNotation::N_SYSTEM );
	            selectedDataSource = aFileNotation.get( OFileNotation::N_URL );
            }
            return selectedDataSource;
        }
    }

    // ===================================================================
	// = IAssigmentData
	// ===================================================================
	class IAssigmentData
	{
	public:
		virtual ~IAssigmentData();

		/// the data source to use for the address book
		virtual ::rtl::OUString getDatasourceName() const = 0;

		/// the command to use for the address book
		virtual ::rtl::OUString getCommand() const = 0;

		/** the command type to use for the address book
			@return
				a <type scope="com.sun.star.sdb">CommandType</type> value
		*/
		virtual sal_Int32		getCommandType() const = 0;

		/// checks whether or not there is an assignment for a given logical field
		virtual sal_Bool		hasFieldAssignment(const ::rtl::OUString& _rLogicalName) = 0;
		/// retrieves the assignment for a given logical field
		virtual ::rtl::OUString getFieldAssignment(const ::rtl::OUString& _rLogicalName) = 0;

		/// set the assignment for a given logical field
		virtual void			setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment) = 0;
		/// clear the assignment for a given logical field
		virtual void			clearFieldAssignment(const ::rtl::OUString& _rLogicalName) = 0;

		virtual void	setDatasourceName(const ::rtl::OUString& _rName) = 0;
		virtual void	setCommand(const ::rtl::OUString& _rCommand) = 0;
	};

	// -------------------------------------------------------------------
	IAssigmentData::~IAssigmentData()
	{
	}

	// ===================================================================
	// = AssigmentTransientData
	// ===================================================================
	class AssigmentTransientData : public IAssigmentData
	{
	protected:
        Reference< XDataSource >    m_xDataSource;
		::rtl::OUString			    m_sDSName;
		::rtl::OUString			    m_sTableName;
		MapString2String		    m_aAliases;

public:
		AssigmentTransientData(
			const Reference< XDataSource >& _rxDataSource,
			const ::rtl::OUString& _rDataSourceName,
			const ::rtl::OUString& _rTableName,
			const Sequence< AliasProgrammaticPair >& _rFields
		);

		// IAssigmentData overridables
		virtual ::rtl::OUString getDatasourceName() const;
		virtual ::rtl::OUString getCommand() const;
		virtual sal_Int32		getCommandType() const;

		virtual sal_Bool		hasFieldAssignment(const ::rtl::OUString& _rLogicalName);
		virtual ::rtl::OUString getFieldAssignment(const ::rtl::OUString& _rLogicalName);
		virtual void			setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment);
		virtual void			clearFieldAssignment(const ::rtl::OUString& _rLogicalName);

		virtual void	setDatasourceName(const ::rtl::OUString& _rName);
		virtual void	setCommand(const ::rtl::OUString& _rCommand);
	};

	// -------------------------------------------------------------------
	AssigmentTransientData::AssigmentTransientData( const Reference< XDataSource >& _rxDataSource,
			const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rTableName,
            const Sequence< AliasProgrammaticPair >& _rFields )
		:m_xDataSource( _rxDataSource )
        ,m_sDSName( _rDataSourceName )
        ,m_sTableName( _rTableName )
	{
        // fill our aliaes structure
		// first collect all known programmatic names
		StringBag aKnownNames;

		String sLogicalFieldNames( SvtResId( STR_LOCAGICAL_FIELD_NAMES ) );
		sal_Int32 nTokenCount = sLogicalFieldNames.GetTokenCount(';');
		for (sal_Int32 i = 0; i<nTokenCount; ++i)
			aKnownNames.insert(sLogicalFieldNames.GetToken((sal_uInt16)i, ';'));

		// loop throuzh the given names
		const AliasProgrammaticPair* pFields = _rFields.getConstArray();
		for (;pFields != pFields; ++pFields)
		{
			StringBagIterator aKnownPos = aKnownNames.find( pFields->ProgrammaticName );
			if ( aKnownNames.end() != aKnownPos )
			{
				m_aAliases[ pFields->ProgrammaticName ] = pFields->Alias;
			}
			else
			{
				DBG_ERROR	(	(	::rtl::OString("AssigmentTransientData::AssigmentTransientData: unknown programmatic name (")
								+=	::rtl::OString(pFields->ProgrammaticName.getStr(), pFields->ProgrammaticName.getLength(), RTL_TEXTENCODING_ASCII_US)
								+=	::rtl::OString(")!")
								).getStr()
							);
			}
		}
	}

	// -------------------------------------------------------------------
	::rtl::OUString AssigmentTransientData::getDatasourceName() const
	{
		return m_sDSName;
	}

	// -------------------------------------------------------------------
	::rtl::OUString AssigmentTransientData::getCommand() const
	{
		return m_sTableName;
	}

	// -------------------------------------------------------------------
	sal_Int32 AssigmentTransientData::getCommandType() const
	{
		return CommandType::TABLE;
	}

	// -------------------------------------------------------------------
	sal_Bool AssigmentTransientData::hasFieldAssignment(const ::rtl::OUString& _rLogicalName)
	{
		ConstMapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
		return	( m_aAliases.end() != aPos )
			&&	( aPos->second.getLength() );
	}

	// -------------------------------------------------------------------
	::rtl::OUString AssigmentTransientData::getFieldAssignment(const ::rtl::OUString& _rLogicalName)
	{
		::rtl::OUString sReturn;
		ConstMapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
		if ( m_aAliases.end() != aPos )
			sReturn = aPos->second;

		return sReturn;
	}

	// -------------------------------------------------------------------
	void AssigmentTransientData::setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment)
	{
		m_aAliases[ _rLogicalName ] = _rAssignment;
	}

	// -------------------------------------------------------------------
	void AssigmentTransientData::clearFieldAssignment(const ::rtl::OUString& _rLogicalName)
	{
		MapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
		if ( m_aAliases.end() != aPos )
			m_aAliases.erase( aPos );
	}

	// -------------------------------------------------------------------
	void AssigmentTransientData::setDatasourceName(const ::rtl::OUString&)
	{
        DBG_ERROR( "AssigmentTransientData::setDatasourceName: cannot be implemented for transient data!" );
	}

	// -------------------------------------------------------------------
	void AssigmentTransientData::setCommand(const ::rtl::OUString&)
	{
        DBG_ERROR( "AssigmentTransientData::setCommand: cannot be implemented for transient data!" );
	}

	// ===================================================================
	// = AssignmentPersistentData
	// ===================================================================
	class AssignmentPersistentData
			:public ::utl::ConfigItem
			,public IAssigmentData
	{
	protected:
		StringBag		m_aStoredFields;

	protected:
		::com::sun::star::uno::Any
						getProperty(const ::rtl::OUString& _rLocalName) const;
		::com::sun::star::uno::Any
						getProperty(const sal_Char* _pLocalName) const;

		::rtl::OUString	getStringProperty(const sal_Char* _pLocalName) const;
		sal_Int32		getInt32Property(const sal_Char* _pLocalName) const;

		::rtl::OUString	getStringProperty(const ::rtl::OUString& _rLocalName) const;

		void			setStringProperty(const sal_Char* _pLocalName, const ::rtl::OUString& _rValue);

	public:
		AssignmentPersistentData();
		~AssignmentPersistentData();

		// IAssigmentData overridables
		virtual ::rtl::OUString getDatasourceName() const;
		virtual ::rtl::OUString getCommand() const;
		virtual sal_Int32		getCommandType() const;

		virtual sal_Bool		hasFieldAssignment(const ::rtl::OUString& _rLogicalName);
		virtual ::rtl::OUString getFieldAssignment(const ::rtl::OUString& _rLogicalName);
		virtual void			setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment);
		virtual void			clearFieldAssignment(const ::rtl::OUString& _rLogicalName);

		virtual void	setDatasourceName(const ::rtl::OUString& _rName);
		virtual void	setCommand(const ::rtl::OUString& _rCommand);

        virtual void    Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames);
		virtual void	Commit();
	};


void AssignmentPersistentData::Notify( const com::sun::star::uno::Sequence<rtl::OUString>& )
{
}

void AssignmentPersistentData::Commit()
{
}

	// -------------------------------------------------------------------
	AssignmentPersistentData::AssignmentPersistentData()
		:ConfigItem( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Office.DataAccess/AddressBook" )))
	{
		Sequence< ::rtl::OUString > aStoredNames = GetNodeNames(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Fields")));
		const ::rtl::OUString* pStoredNames = aStoredNames.getConstArray();
		for (sal_Int32 i=0; i<aStoredNames.getLength(); ++i, ++pStoredNames)
			m_aStoredFields.insert(*pStoredNames);
	}

	// -------------------------------------------------------------------
	AssignmentPersistentData::~AssignmentPersistentData()
	{
	}

	// -------------------------------------------------------------------
	sal_Bool AssignmentPersistentData::hasFieldAssignment(const ::rtl::OUString& _rLogicalName)
	{
		return (m_aStoredFields.end() != m_aStoredFields.find(_rLogicalName));
	}

	// -------------------------------------------------------------------
	::rtl::OUString AssignmentPersistentData::getFieldAssignment(const ::rtl::OUString& _rLogicalName)
	{
		::rtl::OUString sAssignment;
		if (hasFieldAssignment(_rLogicalName))
		{
			::rtl::OUString sFieldPath(RTL_CONSTASCII_USTRINGPARAM("Fields/"));
			sFieldPath += _rLogicalName;
			sFieldPath += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/AssignedFieldName"));
			sAssignment = getStringProperty(sFieldPath);
		}
		return sAssignment;
	}

	// -------------------------------------------------------------------
	Any AssignmentPersistentData::getProperty(const sal_Char* _pLocalName) const
	{
		return getProperty(::rtl::OUString::createFromAscii(_pLocalName));
	}

	// -------------------------------------------------------------------
	Any AssignmentPersistentData::getProperty(const ::rtl::OUString& _rLocalName) const
	{
		Sequence< ::rtl::OUString > aProperties(&_rLocalName, 1);
		Sequence< Any > aValues = const_cast<AssignmentPersistentData*>(this)->GetProperties(aProperties);
		DBG_ASSERT(aValues.getLength() == 1, "AssignmentPersistentData::getProperty: invalid sequence length!");
		return aValues[0];
	}

	// -------------------------------------------------------------------
	::rtl::OUString	AssignmentPersistentData::getStringProperty(const ::rtl::OUString& _rLocalName) const
	{
		::rtl::OUString sReturn;
		getProperty( _rLocalName ) >>= sReturn;
		return sReturn;
	}

	// -------------------------------------------------------------------
	::rtl::OUString	AssignmentPersistentData::getStringProperty(const sal_Char* _pLocalName) const
	{
		::rtl::OUString sReturn;
		getProperty( _pLocalName ) >>= sReturn;
		return sReturn;
	}

	// -------------------------------------------------------------------
	sal_Int32 AssignmentPersistentData::getInt32Property(const sal_Char* _pLocalName) const
	{
		sal_Int32 nReturn = 0;
		getProperty( _pLocalName ) >>= nReturn;
		return nReturn;
	}

	// -------------------------------------------------------------------
	void AssignmentPersistentData::setStringProperty(const sal_Char* _pLocalName, const ::rtl::OUString& _rValue)
	{
		Sequence< ::rtl::OUString > aNames(1);
		Sequence< Any > aValues(1);
		aNames[0] = ::rtl::OUString::createFromAscii(_pLocalName);
		aValues[0] <<= _rValue;
		PutProperties(aNames, aValues);
	}

	// -------------------------------------------------------------------
	void AssignmentPersistentData::setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment)
	{
		if (!_rAssignment.getLength())
		{
			if (hasFieldAssignment(_rLogicalName))
				// the assignment exists but it should be reset
				clearFieldAssignment(_rLogicalName);
				return;
		}

		// Fields
		::rtl::OUString sDescriptionNodePath(RTL_CONSTASCII_USTRINGPARAM("Fields"));

		// Fields/<field>
		::rtl::OUString sFieldElementNodePath(sDescriptionNodePath);
		sFieldElementNodePath += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
		sFieldElementNodePath += _rLogicalName;

		Sequence< PropertyValue > aNewFieldDescription(2);
		// Fields/<field>/ProgrammaticFieldName
		aNewFieldDescription[0].Name = sFieldElementNodePath;
		aNewFieldDescription[0].Name += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/ProgrammaticFieldName"));
		aNewFieldDescription[0].Value <<= _rLogicalName;
		// Fields/<field>/AssignedFieldName
		aNewFieldDescription[1].Name = sFieldElementNodePath;
		aNewFieldDescription[1].Name += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/AssignedFieldName"));
		aNewFieldDescription[1].Value <<= _rAssignment;

		// just set the new value
#ifdef DBG_UTIL
		sal_Bool bSuccess =
#endif
		SetSetProperties(sDescriptionNodePath, aNewFieldDescription);
		DBG_ASSERT(bSuccess, "AssignmentPersistentData::setFieldAssignment: could not commit the changes a field!");
	}

	// -------------------------------------------------------------------
	void AssignmentPersistentData::clearFieldAssignment(const ::rtl::OUString& _rLogicalName)
	{
		if (!hasFieldAssignment(_rLogicalName))
			// nothing to do
			return;

		::rtl::OUString sDescriptionNodePath(RTL_CONSTASCII_USTRINGPARAM("Fields"));
		Sequence< ::rtl::OUString > aNames(&_rLogicalName, 1);
		ClearNodeElements(sDescriptionNodePath, aNames);
	}

	// -------------------------------------------------------------------
	::rtl::OUString AssignmentPersistentData::getDatasourceName() const
	{
		return getStringProperty( "DataSourceName" );
	}

	// -------------------------------------------------------------------
	::rtl::OUString AssignmentPersistentData::getCommand() const
	{
		return getStringProperty( "Command" );
	}

	// -------------------------------------------------------------------
	void AssignmentPersistentData::setDatasourceName(const ::rtl::OUString& _rName)
	{
		setStringProperty( "DataSourceName", _rName );
	}

	// -------------------------------------------------------------------
	void AssignmentPersistentData::setCommand(const ::rtl::OUString& _rCommand)
	{
		setStringProperty( "Command", _rCommand );
	}

	// -------------------------------------------------------------------
	sal_Int32 AssignmentPersistentData::getCommandType() const
	{
		return getInt32Property( "CommandType" );
	}

	// ===================================================================
	// = AddressBookSourceDialogData
	// ===================================================================
	struct AddressBookSourceDialogData
	{
		FixedText*		pFieldLabels[FIELD_PAIRS_VISIBLE * 2];
		ListBox*		pFields[FIELD_PAIRS_VISIBLE * 2];

        /// when working transient, we need the data source
        Reference< XDataSource >
                        m_xTransientDataSource;
		/// current scroll pos in the field list
		sal_Int32		nFieldScrollPos;
		/// the index within m_pFields of the last visible list box. This is redundant, it could be extracted from other members
		sal_Int32		nLastVisibleListIndex;
		/// indicates that we've an odd field number. This member is for efficiency only, it's redundant.
		sal_Bool		bOddFieldNumber : 1;
		/// indicates that we're working with the real persistent configuration
		sal_Bool		bWorkingPersistent : 1;

		/// the strings to use as labels for the field selection listboxes
		StringArray		aFieldLabels;
		// the current field assignment
		StringArray		aFieldAssignments;
		/// the logical field names
		StringArray		aLogicalFieldNames;

		IAssigmentData*	pConfigData;

		// ................................................................
		AddressBookSourceDialogData( )
			:nFieldScrollPos(0)
			,nLastVisibleListIndex(0)
			,bOddFieldNumber(sal_False)
			,bWorkingPersistent( sal_True )
			,pConfigData( new AssignmentPersistentData )
		{
		}

		// ................................................................
		AddressBookSourceDialogData( const Reference< XDataSource >& _rxTransientDS, const ::rtl::OUString& _rDataSourceName,
            const ::rtl::OUString& _rTableName, const Sequence< AliasProgrammaticPair >& _rFields )
			:m_xTransientDataSource( _rxTransientDS )
            ,nFieldScrollPos(0)
			,nLastVisibleListIndex(0)
			,bOddFieldNumber(sal_False)
			,bWorkingPersistent( sal_False )
			,pConfigData( new AssigmentTransientData( m_xTransientDataSource, _rDataSourceName, _rTableName, _rFields ) )
		{
		}

		~AddressBookSourceDialogData()
		{
			delete pConfigData;
		}

	};

	// ===================================================================
	// = AddressBookSourceDialog
	// ===================================================================
#define INIT_FIELDS()	\
		 ModalDialog(_pParent, SvtResId( DLG_ADDRESSBOOKSOURCE ))\
		,m_aDatasourceFrame			(this, SvtResId(FL_DATASOURCEFRAME))\
		,m_aDatasourceLabel			(this, SvtResId(FT_DATASOURCE))\
		,m_aDatasource				(this, SvtResId(CB_DATASOURCE))\
		,m_aAdministrateDatasources	(this, SvtResId(PB_ADMINISTATE_DATASOURCES))\
		,m_aTableLabel				(this, SvtResId(FT_TABLE))\
		,m_aTable					(this, SvtResId(CB_TABLE))\
		,m_aFieldsTitle				(this, SvtResId(FT_FIELDS))\
		,m_aFieldsFrame				(this, SvtResId(CT_BORDER))\
		,m_aFieldScroller			(&m_aFieldsFrame, SvtResId(SB_FIELDSCROLLER))\
		,m_aOK						(this, SvtResId(PB_OK))\
		,m_aCancel					(this, SvtResId(PB_CANCEL))\
		,m_aHelp					(this, SvtResId(PB_HELP))\
		,m_sNoFieldSelection(SvtResId(STR_NO_FIELD_SELECTION))\
		,m_xORB(_rxORB)

	// -------------------------------------------------------------------
	AddressBookSourceDialog::AddressBookSourceDialog(Window* _pParent,
			const Reference< XMultiServiceFactory >& _rxORB )
		:INIT_FIELDS()
		,m_pImpl( new AddressBookSourceDialogData )
	{
		implConstruct();
	}

	// -------------------------------------------------------------------
	AddressBookSourceDialog::AddressBookSourceDialog( Window* _pParent, const Reference< XMultiServiceFactory >& _rxORB,
		const Reference< XDataSource >& _rxTransientDS, const ::rtl::OUString& _rDataSourceName,
        const ::rtl::OUString& _rTable, const Sequence< AliasProgrammaticPair >& _rMapping )
		:INIT_FIELDS()
		,m_pImpl( new AddressBookSourceDialogData( _rxTransientDS, _rDataSourceName, _rTable, _rMapping ) )
	{
		implConstruct();
	}

	// -------------------------------------------------------------------
	void AddressBookSourceDialog::implConstruct()
	{
		for (sal_Int32 row=0; row<FIELD_PAIRS_VISIBLE; ++row)
		{
			for (sal_Int32 column=0; column<2; ++column)
			{
				// the label
				m_pImpl->pFieldLabels[row * 2 + column] = new FixedText(&m_aFieldsFrame, SvtResId((sal_uInt16)(FT_FIELD_BASE + row * 2 + column)));
				// the listbox
				m_pImpl->pFields[row * 2 + column] = new ListBox(&m_aFieldsFrame, SvtResId((sal_uInt16)(LB_FIELD_BASE + row * 2 + column)));
				m_pImpl->pFields[row * 2 + column]->SetDropDownLineCount(15);
				m_pImpl->pFields[row * 2 + column]->SetSelectHdl(LINK(this, AddressBookSourceDialog, OnFieldSelect));

				m_pImpl->pFields[row * 2 + column]->SetHelpId(HID_ADDRTEMPL_FIELD_ASSIGNMENT);
			}
		}

		m_aFieldsFrame.SetStyle((m_aFieldsFrame.GetStyle() | WB_TABSTOP | WB_DIALOGCONTROL) & ~WB_NODIALOGCONTROL);

		// correct the z-order
		m_aFieldScroller.SetZOrder(m_pImpl->pFields[FIELD_CONTROLS_VISIBLE - 1], WINDOW_ZORDER_BEHIND);
		m_aOK.SetZOrder(&m_aFieldsFrame, WINDOW_ZORDER_BEHIND);
		m_aCancel.SetZOrder(&m_aOK, WINDOW_ZORDER_BEHIND);

		initializeDatasources();

		// for the moment, we have a hard coded list of all known fields.
		// A better solution would be to store all known field translations in the configuration, which could be
		// extensible by the user in an arbitrary way.
		// But for the moment we need a quick solution ...
		// (the main thing would be to store the translations to use here in the user interface, besides that, the code
		// should be adjustable with a rather small effort.)

		// initialize the strings for the field labels
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_FIRSTNAME )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_LASTNAME )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_COMPANY)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_DEPARTMENT )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_STREET )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_ZIPCODE )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_CITY )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_STATE)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_COUNTRY )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_HOMETEL )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_WORKTEL )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_OFFICETEL)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_MOBILE)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_TELOTHER)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_PAGER)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_FAX )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_EMAIL )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_URL )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_TITLE )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_POSITION )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_INITIALS )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_ADDRFORM )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_SALUTATION )) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_ID)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_CALENDAR)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_INVITE)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_NOTE)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_USER1)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_USER2)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_USER3)) );
		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_USER4)) );

		// force a even number of known fields
		m_pImpl->bOddFieldNumber = (m_pImpl->aFieldLabels.size() % 2) != 0;
		if (m_pImpl->bOddFieldNumber)
			m_pImpl->aFieldLabels.push_back( String() );

		// limit the scrollbar range accordingly
		sal_Int32 nOverallFieldPairs = m_pImpl->aFieldLabels.size() / 2;
		m_aFieldScroller.SetRange( Range(0, nOverallFieldPairs - FIELD_PAIRS_VISIBLE) );
		m_aFieldScroller.SetLineSize(1);
		m_aFieldScroller.SetPageSize(FIELD_PAIRS_VISIBLE);

		// reset the current field assignments
		m_pImpl->aFieldAssignments.resize(m_pImpl->aFieldLabels.size());
			// (empty strings mean "no assignment")

		// some knittings
		m_aFieldScroller.SetScrollHdl(LINK(this, AddressBookSourceDialog, OnFieldScroll));
		m_aAdministrateDatasources.SetClickHdl(LINK(this, AddressBookSourceDialog, OnAdministrateDatasources));
		m_aDatasource.EnableAutocomplete(sal_True);
		m_aTable.EnableAutocomplete(sal_True);
		m_aTable.SetGetFocusHdl(LINK(this, AddressBookSourceDialog, OnComboGetFocus));
		m_aDatasource.SetGetFocusHdl(LINK(this, AddressBookSourceDialog, OnComboGetFocus));
		m_aTable.SetLoseFocusHdl(LINK(this, AddressBookSourceDialog, OnComboLoseFocus));
		m_aDatasource.SetLoseFocusHdl(LINK(this, AddressBookSourceDialog, OnComboLoseFocus));
		m_aTable.SetSelectHdl(LINK(this, AddressBookSourceDialog, OnComboSelect));
		m_aDatasource.SetSelectHdl(LINK(this, AddressBookSourceDialog, OnComboSelect));
		m_aOK.SetClickHdl(LINK(this, AddressBookSourceDialog, OnOkClicked));

		m_aDatasource.SetDropDownLineCount(15);

		// initialize the field controls
		resetFields();
		m_aFieldScroller.SetThumbPos(0);
		m_pImpl->nFieldScrollPos = -1;
		implScrollFields(0, sal_False, sal_False);

		// the logical names
		String sLogicalFieldNames(SvtResId(STR_LOCAGICAL_FIELD_NAMES));
		sal_Int32 nAdjustedTokenCount = sLogicalFieldNames.GetTokenCount(';') + (m_pImpl->bOddFieldNumber ? 1 : 0);
		DBG_ASSERT(nAdjustedTokenCount == (sal_Int32)m_pImpl->aFieldLabels.size(),
			"AddressBookSourceDialog::AddressBookSourceDialog: inconsistence between logical and UI field names!");
		m_pImpl->aLogicalFieldNames.reserve(nAdjustedTokenCount);
		for (sal_Int32 i = 0; i<nAdjustedTokenCount; ++i)
			m_pImpl->aLogicalFieldNames.push_back(sLogicalFieldNames.GetToken((sal_uInt16)i, ';'));

		PostUserEvent(LINK(this, AddressBookSourceDialog, OnDelayedInitialize));
			// so the dialog will at least show up before we do the loading of the
			// configuration data and the (maybe time consuming) analysis of the data source/table to select

		FreeResource();

		if ( !m_pImpl->bWorkingPersistent )
		{
			StyleSettings aSystemStyle = GetSettings().GetStyleSettings();
			const Color& rNewColor = aSystemStyle.GetDialogColor();

			m_aDatasource.SetReadOnly( sal_True );
			m_aDatasource.SetBackground( Wallpaper( rNewColor ) );
			m_aDatasource.SetControlBackground( rNewColor );

			m_aTable.SetReadOnly( sal_True );
			m_aTable.SetBackground( Wallpaper( rNewColor ) );
			m_aTable.SetControlBackground( rNewColor );

			m_aAdministrateDatasources.Hide( );
		}
	}

	// -------------------------------------------------------------------
	void AddressBookSourceDialog::getFieldMapping(Sequence< AliasProgrammaticPair >& _rMapping) const
	{
		_rMapping.realloc( m_pImpl->aLogicalFieldNames.size() );
		AliasProgrammaticPair* pPair = _rMapping.getArray();

		::rtl::OUString sCurrent;
		for	(	ConstStringArrayIterator aProgrammatic = m_pImpl->aLogicalFieldNames.begin();
				aProgrammatic != m_pImpl->aLogicalFieldNames.end();
				++aProgrammatic
			)
		{
			sCurrent = *aProgrammatic;
			if ( m_pImpl->pConfigData->hasFieldAssignment( sCurrent ) )
			{
				// the user gave us an assignment for this field
				pPair->ProgrammaticName = *aProgrammatic;
				pPair->Alias = m_pImpl->pConfigData->getFieldAssignment( *aProgrammatic );
				++pPair;
			}
		}

		_rMapping.realloc( pPair - _rMapping.getArray() );
	}

	// -------------------------------------------------------------------
	void AddressBookSourceDialog::loadConfiguration()
	{
        ::rtl::OUString sName = m_pImpl->pConfigData->getDatasourceName();
        INetURLObject aURL( sName );
        if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
		{
			OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
			sName = aFileNotation.get(OFileNotation::N_SYSTEM);
        }
        
		m_aDatasource.SetText(sName);
		m_aTable.SetText(m_pImpl->pConfigData->getCommand());
		// we ignore the CommandType: only tables are supported

		// the logical names for the fields
		DBG_ASSERT(m_pImpl->aLogicalFieldNames.size() == m_pImpl->aFieldAssignments.size(),
			"AddressBookSourceDialog::loadConfiguration: inconsistence between field names and field assignments!");

		ConstStringArrayIterator aLogical = m_pImpl->aLogicalFieldNames.begin();
		StringArrayIterator aAssignment = m_pImpl->aFieldAssignments.begin();
		for	(	;
				aLogical < m_pImpl->aLogicalFieldNames.end();
				++aLogical, ++aAssignment
			)
			*aAssignment = m_pImpl->pConfigData->getFieldAssignment(*aLogical);
	}

	// -------------------------------------------------------------------
	AddressBookSourceDialog::~AddressBookSourceDialog()
	{
		sal_Int32 i;
		for (i=0; i<FIELD_CONTROLS_VISIBLE; ++i)
		{
			delete m_pImpl->pFieldLabels[i];
			delete m_pImpl->pFields[i];
		}

		delete m_pImpl;
	}

	// -------------------------------------------------------------------
	void AddressBookSourceDialog::initializeDatasources()
	{
		if (!m_xDatabaseContext.is())
		{
			DBG_ASSERT(m_xORB.is(), "AddressBookSourceDialog::initializeDatasources: no service factory!");
			if (!m_xORB.is())
				return;

			const String sContextServiceName = String::CreateFromAscii("com.sun.star.sdb.DatabaseContext");
			try
			{
				m_xDatabaseContext = Reference< XNameAccess >(m_xORB->createInstance(sContextServiceName), UNO_QUERY);
			}
			catch(Exception&) { }
			if (!m_xDatabaseContext.is())
			{
				ShowServiceNotAvailableError( this, sContextServiceName, sal_False);
				return;
			}
		}
		m_aDatasource.Clear();

		// fill the datasources listbox
		Sequence< ::rtl::OUString > aDatasourceNames;
		try
		{
			aDatasourceNames = m_xDatabaseContext->getElementNames();
		}
		catch(Exception&)
		{
			DBG_ERROR("AddressBookSourceDialog::initializeDatasources: caught an exception while asking for the data source names!");
		}
		const ::rtl::OUString* pDatasourceNames = aDatasourceNames.getConstArray();
		const ::rtl::OUString* pEnd = pDatasourceNames + aDatasourceNames.getLength();
		for (; pDatasourceNames < pEnd; ++pDatasourceNames)
			m_aDatasource.InsertEntry(*pDatasourceNames);
	}

	// -------------------------------------------------------------------
	IMPL_LINK(AddressBookSourceDialog, OnFieldScroll, ScrollBar*, _pScrollBar)
	{
		implScrollFields( _pScrollBar->GetThumbPos(), sal_True, sal_True );
		return 0L;
	}

	// -------------------------------------------------------------------
	void AddressBookSourceDialog::resetTables()
	{
		if (!m_xDatabaseContext.is())
			return;

		WaitObject aWaitCursor(this);

		// no matter what we do here, we handled the currently selected data source (no matter if successfull or not)
		m_aDatasource.SaveValue();

		// create an interaction handler (may be needed for connecting)
		const String sInteractionHandlerServiceName = String::CreateFromAscii("com.sun.star.task.InteractionHandler");
		Reference< XInteractionHandler > xHandler;
		try
		{
			xHandler = Reference< XInteractionHandler >(m_xORB->createInstance(sInteractionHandlerServiceName), UNO_QUERY);
		}
		catch(Exception&) { }
		if (!xHandler.is())
		{
			ShowServiceNotAvailableError(this, sInteractionHandlerServiceName, sal_True);
			return;
		}

		// the currently selected table
		::rtl::OUString sOldTable = m_aTable.GetText();

		m_aTable.Clear();

		m_xCurrentDatasourceTables= NULL;

		// get the tables of the connection
		Sequence< ::rtl::OUString > aTableNames;
		Any aException;
		try
		{
			Reference< XCompletedConnection > xDS;
            if ( m_pImpl->bWorkingPersistent )
            {
                String sSelectedDS = lcl_getSelectedDataSource(  m_aDatasource );
                
			    // get the data source the user has chosen and let it build a connection
                INetURLObject aURL( sSelectedDS );
                if ( aURL.GetProtocol() != INET_PROT_NOT_VALID || m_xDatabaseContext->hasByName(sSelectedDS) )
				    m_xDatabaseContext->getByName( sSelectedDS ) >>= xDS;
            }
            else
            {
                xDS = xDS.query( m_pImpl->m_xTransientDataSource );
            }

			// build the connection
			Reference< XConnection > xConn;
            if (xDS.is())
				xConn = xDS->connectWithCompletion(xHandler);

			// get the table names
			Reference< XTablesSupplier > xSupplTables(xConn, UNO_QUERY);
			if (xSupplTables.is())
			{
				m_xCurrentDatasourceTables = Reference< XNameAccess >(xSupplTables->getTables(), UNO_QUERY);
				if (m_xCurrentDatasourceTables.is())
					aTableNames = m_xCurrentDatasourceTables->getElementNames();
			}
		}
		catch(SQLContext& e) { aException <<= e; }
		catch(SQLWarning& e) { aException <<= e; }
		catch(SQLException& e) { aException <<= e; }
		catch(Exception&)
		{
			DBG_ERROR("AddressBookSourceDialog::resetTables: could not retrieve the table!");
		}

		if (aException.hasValue())
		{
			Reference< XInteractionRequest > xRequest = new OInteractionRequest(aException);
			try
			{
				xHandler->handle(xRequest);
			}
			catch(Exception&) { }
			return;
		}

		sal_Bool bKnowOldTable = sal_False;
		// fill the table list
		const ::rtl::OUString* pTableNames = aTableNames.getConstArray();
		const ::rtl::OUString* pEnd = pTableNames + aTableNames.getLength();
		for (;pTableNames != pEnd; ++pTableNames)
		{
			m_aTable.InsertEntry(*pTableNames);
			if (0 == pTableNames->compareTo(sOldTable))
				bKnowOldTable = sal_True;
		}

		// set the old table, if the new data source knows a table with this name, too. Else reset the tables edit field.
		if (!bKnowOldTable)
			sOldTable = ::rtl::OUString();
		m_aTable.SetText(sOldTable);

		resetFields();
	}

	// -------------------------------------------------------------------
	void AddressBookSourceDialog::resetFields()
	{
		WaitObject aWaitCursor(this);

		// no matter what we do here, we handled the currently selected table (no matter if successfull or not)
		m_aDatasource.SaveValue();

		String sSelectedTable = m_aTable.GetText();
		Sequence< ::rtl::OUString > aColumnNames;
		try
		{
			if (m_xCurrentDatasourceTables.is())
			{
				// get the table and the columns
				Reference< XColumnsSupplier > xSuppTableCols;
				if (m_xCurrentDatasourceTables->hasByName(sSelectedTable))
					::cppu::extractInterface(xSuppTableCols, m_xCurrentDatasourceTables->getByName(sSelectedTable));
				Reference< XNameAccess > xColumns;
				if (xSuppTableCols.is())
					xColumns = xSuppTableCols->getColumns();
				if (xColumns.is())
					aColumnNames = xColumns->getElementNames();
			}
		}
		catch(Exception&)
		{
			DBG_ERROR("AddressBookSourceDialog::resetFields: could not retrieve the table columns!");
		}
		

		const ::rtl::OUString* pColumnNames = aColumnNames.getConstArray();
		const ::rtl::OUString* pEnd = pColumnNames + aColumnNames.getLength();

		// for quicker access
		::std::set< String > aColumnNameSet;
		for (pColumnNames = aColumnNames.getConstArray(); pColumnNames != pEnd; ++pColumnNames)
			aColumnNameSet.insert(*pColumnNames);

		std::vector<String>::iterator aInitialSelection = m_pImpl->aFieldAssignments.begin() + m_pImpl->nFieldScrollPos;

		ListBox** pListbox = m_pImpl->pFields;
		String sSaveSelection;
		for (sal_Int32 i=0; i<FIELD_CONTROLS_VISIBLE; ++i, ++pListbox, ++aInitialSelection)
		{
			sSaveSelection = (*pListbox)->GetSelectEntry();

			(*pListbox)->Clear();

			// the one entry for "no selection"
			(*pListbox)->InsertEntry(m_sNoFieldSelection, 0);
			// as it's entry data, set the index of the list box in our array
			(*pListbox)->SetEntryData(0, reinterpret_cast<void*>(i));

			// the field names
			for (pColumnNames = aColumnNames.getConstArray(); pColumnNames != pEnd; ++pColumnNames)
				(*pListbox)->InsertEntry(*pColumnNames);

			if (aInitialSelection->Len() && (aColumnNameSet.end() != aColumnNameSet.find(*aInitialSelection)))
				// we can select the entry as specified in our field assignment array
				(*pListbox)->SelectEntry(*aInitialSelection);
			else
				// try to restore the selection
				if (aColumnNameSet.end() != aColumnNameSet.find(sSaveSelection))
					// the old selection is a valid column name
					(*pListbox)->SelectEntry(sSaveSelection);
				else
					// select the <none> entry
					(*pListbox)->SelectEntryPos(0);
		}

		// adjust m_pImpl->aFieldAssignments
		for (	StringArrayIterator aAdjust = m_pImpl->aFieldAssignments.begin();
				aAdjust != m_pImpl->aFieldAssignments.end();
				++aAdjust
			)
			if (aAdjust->Len())
				if (aColumnNameSet.end() == aColumnNameSet.find(*aAdjust))
					aAdjust->Erase();
	}

	// -------------------------------------------------------------------
	IMPL_LINK(AddressBookSourceDialog, OnFieldSelect, ListBox*, _pListbox)
	{
		// the index of the affected list box in our array
		sal_IntPtr nListBoxIndex = reinterpret_cast<sal_IntPtr>(_pListbox->GetEntryData(0));
		DBG_ASSERT(nListBoxIndex >= 0 && nListBoxIndex < FIELD_CONTROLS_VISIBLE,
			"AddressBookSourceDialog::OnFieldScroll: invalid list box entry!");

		// update the array where we remember the field selections
		if (0 == _pListbox->GetSelectEntryPos())
			// it's the "no field selection" entry
			m_pImpl->aFieldAssignments[m_pImpl->nFieldScrollPos * 2 + nListBoxIndex] = String();
		else
			// it's a regular field entry
			m_pImpl->aFieldAssignments[m_pImpl->nFieldScrollPos * 2 + nListBoxIndex] = _pListbox->GetSelectEntry();

		return 0L;
	}

	// -------------------------------------------------------------------
	void AddressBookSourceDialog::implScrollFields(sal_Int32 _nPos, sal_Bool _bAdjustFocus, sal_Bool _bAdjustScrollbar)
	{
		if (_nPos == m_pImpl->nFieldScrollPos)
			// nothing to do
			return;

		// loop through our field control rows and do some adjustments
		// for the new texts
		FixedText** pLeftLabelControl = m_pImpl->pFieldLabels;
		FixedText** pRightLabelControl = pLeftLabelControl + 1;
		ConstStringArrayIterator pLeftColumnLabel = m_pImpl->aFieldLabels.begin() + 2 * _nPos;
		ConstStringArrayIterator pRightColumnLabel = pLeftColumnLabel + 1;

		// for the focus movement and the selection scroll
		ListBox** pLeftListControl = m_pImpl->pFields;
		ListBox** pRightListControl = pLeftListControl + 1;

		// for the focus movement
		sal_Int32 nOldFocusRow = -1;
		sal_Int32 nOldFocusColumn = 0;

		// for the selection scroll
		ConstStringArrayIterator pLeftAssignment = m_pImpl->aFieldAssignments.begin() + 2 * _nPos;
		ConstStringArrayIterator pRightAssignment = pLeftAssignment + 1;

		m_pImpl->nLastVisibleListIndex = -1;
		// loop
		for (sal_Int32 i=0; i<FIELD_PAIRS_VISIBLE; ++i)
		{
			if ((*pLeftListControl)->HasChildPathFocus())
			{
				nOldFocusRow = i;
				nOldFocusColumn = 0;
			}
			else if ((*pRightListControl)->HasChildPathFocus())
			{
				nOldFocusRow = i;
				nOldFocusColumn = 1;
			}

			// the new texts of the label controls
			(*pLeftLabelControl)->SetText(*pLeftColumnLabel);
			(*pRightLabelControl)->SetText(*pRightColumnLabel);

			// we may have to hide the controls in the right column, if we have no label text for it
			// (which means we have an odd number of fields, though we forced our internal arrays to
			// be even-sized for easier handling)
			// (If sometimes we support an arbitrary number of field assignments, we would have to care for
			// an invisible left hand side column, too. But right now, the left hand side controls are always
			// visible)
			sal_Bool bHideRightColumn = (0 == pRightColumnLabel->Len());
			(*pRightLabelControl)->Show(!bHideRightColumn);
			(*pRightListControl)->Show(!bHideRightColumn);
			// the new selections of the listboxes
			implSelectField(*pLeftListControl, *pLeftAssignment);
			implSelectField(*pRightListControl, *pRightAssignment);

			// the index of the last visible list box
			++m_pImpl->nLastVisibleListIndex;	// the left hand side box is always visible
			if (!bHideRightColumn)
				++m_pImpl->nLastVisibleListIndex;

		    // increment ...
            if ( i < FIELD_PAIRS_VISIBLE - 1 )
            {   // (not in the very last round, here the +=2 could result in an invalid
                // iterator position, which causes an abort in a non-product version
			    pLeftLabelControl += 2;
			    pRightLabelControl += 2;
			    pLeftColumnLabel += 2;
			    pRightColumnLabel += 2;

			    pLeftListControl += 2;
			    pRightListControl += 2;
			    pLeftAssignment += 2;
			    pRightAssignment += 2;
            }
		}

		if (_bAdjustFocus && (nOldFocusRow >= 0))
		{	// we have to adjust the focus and one of the list boxes has the focus
			sal_Int32 nDelta = m_pImpl->nFieldScrollPos - _nPos;
			// the new row for the focus
			sal_Int32 nNewFocusRow = nOldFocusRow + nDelta;
			// normalize
			nNewFocusRow = std::min(nNewFocusRow, (sal_Int32)(FIELD_PAIRS_VISIBLE - 1), ::std::less< sal_Int32 >());
			nNewFocusRow = std::max(nNewFocusRow, (sal_Int32)0, ::std::less< sal_Int32 >());
			// set the new focus (in the same column)
			m_pImpl->pFields[nNewFocusRow * 2 + nOldFocusColumn]->GrabFocus();
		}

		m_pImpl->nFieldScrollPos = _nPos;

		if (_bAdjustScrollbar)
			m_aFieldScroller.SetThumbPos(m_pImpl->nFieldScrollPos);
	}

	// -------------------------------------------------------------------
	void AddressBookSourceDialog::implSelectField(ListBox* _pBox, const String& _rText)
	{
		if (_rText.Len())
			// a valid field name
			_pBox->SelectEntry(_rText);
		else
			// no selection for this item
			_pBox->SelectEntryPos(0);
	}

	// -------------------------------------------------------------------
	IMPL_LINK(AddressBookSourceDialog, OnDelayedInitialize, void*, EMPTYARG)
	{
		// load the initial data from the configuration
		loadConfiguration();
		resetTables();
			// will reset the tables/fields implicitly

		if ( !m_pImpl->bWorkingPersistent )
			if ( m_pImpl->pFields[0] )
				m_pImpl->pFields[0]->GrabFocus();

		return 0L;
	}

	// -------------------------------------------------------------------
	IMPL_LINK(AddressBookSourceDialog, OnComboSelect, ComboBox*, _pBox)
	{
		if (_pBox == &m_aDatasource)
			resetTables();
		else
			resetFields();
		return 0;
	}

	// -------------------------------------------------------------------
	IMPL_LINK(AddressBookSourceDialog, OnComboGetFocus, ComboBox*, _pBox)
	{
		_pBox->SaveValue();
		return 0L;
	}

	// -------------------------------------------------------------------
	IMPL_LINK(AddressBookSourceDialog, OnComboLoseFocus, ComboBox*, _pBox)
	{
		if (_pBox->GetSavedValue() != _pBox->GetText())
		{
			if (_pBox == &m_aDatasource)
				resetTables();
			else
				resetFields();
		}
		return 0L;
	}

	// -------------------------------------------------------------------
	IMPL_LINK(AddressBookSourceDialog, OnOkClicked, Button*, EMPTYARG)
	{
        String sSelectedDS = lcl_getSelectedDataSource(  m_aDatasource );
        if ( m_pImpl->bWorkingPersistent )
        {
		    m_pImpl->pConfigData->setDatasourceName(sSelectedDS);
		    m_pImpl->pConfigData->setCommand(m_aTable.GetText());
        }

		// set the field assignments
		ConstStringArrayIterator aLogical = m_pImpl->aLogicalFieldNames.begin();
		ConstStringArrayIterator aAssignment = m_pImpl->aFieldAssignments.begin();
		for	(	;
				aLogical < m_pImpl->aLogicalFieldNames.end();
				++aLogical, ++aAssignment
			)
			m_pImpl->pConfigData->setFieldAssignment(*aLogical, *aAssignment);
		

		EndDialog(RET_OK);
		return 0L;
	}

	// -------------------------------------------------------------------
	IMPL_LINK(AddressBookSourceDialog, OnAdministrateDatasources, void*, EMPTYARG)
	{
		// collect some initial arguments for the dialog
		Sequence< Any > aArgs(1);
        aArgs[0] <<= PropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParentWindow")), 0, makeAny(VCLUnoHelper::GetInterface(this)), PropertyState_DIRECT_VALUE);

		// create the dialog object
		const String sDialogServiceName = String::CreateFromAscii("com.sun.star.ui.dialogs.AddressBookSourcePilot");
		Reference< XExecutableDialog > xAdminDialog;
		try
		{
			xAdminDialog = Reference< XExecutableDialog >(m_xORB->createInstanceWithArguments(sDialogServiceName, aArgs), UNO_QUERY);
		}
		catch(Exception&) { }
		if (!xAdminDialog.is())
		{
			ShowServiceNotAvailableError(this, sDialogServiceName, sal_True);
			return 1L;
		}

		// excute the dialog
		try
		{
            if ( xAdminDialog->execute() == RET_OK )
            {
                Reference<XPropertySet> xProp(xAdminDialog,UNO_QUERY);
				if ( xProp.is() )
				{
                    ::rtl::OUString sName;
                    xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataSourceName"))) >>= sName;
                    
                    INetURLObject aURL( sName );
                    if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
			        {
				        OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
				        sName = aFileNotation.get(OFileNotation::N_SYSTEM);
                    }
                    m_aDatasource.InsertEntry(sName);
					delete m_pImpl->pConfigData;
					m_pImpl->pConfigData = new AssignmentPersistentData();
					loadConfiguration();
                    resetTables();
			        // will reset the fields implicitly
                }
            }
		}
		catch(Exception&)
		{
			DBG_ERROR("AddressBookSourceDialog::OnAdministrateDatasources: an error occured while executing the administration dialog!");
		}

		// re-fill the data source list
		// try to preserve the current selection
		
//		initializeDatasources();

		return 0L;
	}

	// -------------------------------------------------------------------
	long AddressBookSourceDialog::PreNotify( NotifyEvent& _rNEvt )
	{
		switch (_rNEvt.GetType())
		{
			case EVENT_KEYINPUT:
			{
				const KeyEvent* pKeyEvent =	_rNEvt.GetKeyEvent();
				sal_uInt16 nCode  = pKeyEvent->GetKeyCode().GetCode();
				sal_Bool   bShift = pKeyEvent->GetKeyCode().IsShift();
				sal_Bool   bCtrl  = pKeyEvent->GetKeyCode().IsMod1();
				sal_Bool   bAlt =	pKeyEvent->GetKeyCode().IsMod2();

				if (KEY_TAB == nCode)
				{	// somebody pressed the tab key
					if (!bAlt && !bCtrl && !bShift)
					{	// it's really the only the key (no modifiers)
						if (m_pImpl->pFields[m_pImpl->nLastVisibleListIndex]->HasChildPathFocus())
							// the last of our visible list boxes has the focus
							if (m_pImpl->nFieldScrollPos < m_aFieldScroller.GetRangeMax())
							{	// we can still scroll down
								sal_Int32 nNextFocusList = m_pImpl->nLastVisibleListIndex + 1 - 2;
								// -> scroll down
								implScrollFields(m_pImpl->nFieldScrollPos + 1, sal_False, sal_True);
								// give the left control in the "next" line the focus
								m_pImpl->pFields[nNextFocusList]->GrabFocus();
								// return saying "have handled this"
								return 1;
							}
					}
					else if (!bAlt && !bCtrl && bShift)
					{	// it's shift-tab
						if (m_pImpl->pFields[0]->HasChildPathFocus())
							// our first list box has the focus
							if (m_pImpl->nFieldScrollPos > 0)
							{	// we can still scroll up
								// -> scroll up
								implScrollFields(m_pImpl->nFieldScrollPos - 1, sal_False, sal_True);
								// give the right control in the "prebious" line the focus
								m_pImpl->pFields[0 - 1 + 2]->GrabFocus();
								// return saying "have handled this"
								return 1;
							}
					}
				}
			}
			break;
		}
		return ModalDialog::PreNotify(_rNEvt);
	}

// .......................................................................
}	// namespace svt
// .......................................................................

