/**************************************************************
 * 
 * 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 "formlinkdialog.hxx"
#include "formlinkdialog.hrc"

#ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_
#include "modulepcr.hxx"
#endif
#ifndef _EXTENSIONS_FORMCTRLR_PROPRESID_HRC_
#include "formresid.hrc"
#endif
#include "formstrings.hxx"
#include <vcl/combobox.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/waitobj.hxx>
#include <svtools/localresaccess.hxx>
#include <connectivity/dbtools.hxx>
#include <connectivity/dbexception.hxx>
#include <toolkit/helper/vclunohelper.hxx>

/** === begin UNO includes === **/
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
#include <com/sun/star/sdbcx/KeyType.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdbc/XRowSet.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/sdb/SQLContext.hpp>
/** === end UNO includes === **/


//............................................................................
namespace pcr
{
//............................................................................

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

    //========================================================================
    //= FieldLinkRow
    //========================================================================
    class FieldLinkRow : public Window
    {
    private:
        ComboBox    m_aDetailColumn;
        FixedText   m_aEqualSign;
        ComboBox    m_aMasterColumn;

        Link        m_aLinkChangeHandler;

    public:
        FieldLinkRow( Window* _pParent, const ResId& _rId );

        inline void         SetLinkChangeHandler( const Link& _rHdl ) { m_aLinkChangeHandler = _rHdl; }
        inline const Link&  GetLinkChangeHandler( ) const             { return m_aLinkChangeHandler;  }

        enum LinkParticipant
        {
            eDetailField,
            eMasterField
        };
        /** retrieves the selected field name for either the master or the detail field
            @return <TRUE/> if and only a valid field is selected
        */
        bool    GetFieldName( LinkParticipant _eWhich, String& /* [out] */ _rName ) const;
        void    SetFieldName( LinkParticipant _eWhich, const String& _rName );

        void    fillList( LinkParticipant _eWhich, const Sequence< ::rtl::OUString >& _rFieldNames );

    private:
        DECL_LINK( OnFieldNameChanged, ComboBox* );
    };

    //------------------------------------------------------------------------
    FieldLinkRow::FieldLinkRow( Window* _pParent, const ResId& _rId )
        :Window( _pParent, _rId )
        ,m_aDetailColumn( this, ResId( 1, *_rId.GetResMgr() ) )
        ,m_aEqualSign   ( this, ResId( 1, *_rId.GetResMgr() ) )
        ,m_aMasterColumn( this, ResId( 2, *_rId.GetResMgr() ) )
    {
        FreeResource();

        m_aDetailColumn.SetDropDownLineCount( 10 );
        m_aMasterColumn.SetDropDownLineCount( 10 );

        m_aDetailColumn.SetModifyHdl( LINK( this, FieldLinkRow, OnFieldNameChanged ) );
        m_aMasterColumn.SetModifyHdl( LINK( this, FieldLinkRow, OnFieldNameChanged ) );
    }

    //------------------------------------------------------------------------
    void FieldLinkRow::fillList( LinkParticipant _eWhich, const Sequence< ::rtl::OUString >& _rFieldNames )
    {
        ComboBox* pBox = ( _eWhich == eDetailField ) ? &m_aDetailColumn : &m_aMasterColumn;

        const ::rtl::OUString* pFieldName    = _rFieldNames.getConstArray();
        const ::rtl::OUString* pFieldNameEnd = pFieldName + _rFieldNames.getLength();
        for ( ; pFieldName != pFieldNameEnd; ++pFieldName )
            pBox->InsertEntry( *pFieldName );
    }

    //------------------------------------------------------------------------
    bool FieldLinkRow::GetFieldName( LinkParticipant _eWhich, String& /* [out] */ _rName ) const
    {
        const ComboBox* pBox = ( _eWhich == eDetailField ) ? &m_aDetailColumn : &m_aMasterColumn;
        _rName = pBox->GetText();
        return _rName.Len() != 0;
    }

    //------------------------------------------------------------------------
    void FieldLinkRow::SetFieldName( LinkParticipant _eWhich, const String& _rName )
    {
        ComboBox* pBox = ( _eWhich == eDetailField ) ? &m_aDetailColumn : &m_aMasterColumn;
        pBox->SetText( _rName );
    }

    //------------------------------------------------------------------------
    IMPL_LINK( FieldLinkRow, OnFieldNameChanged, ComboBox*, /*_pBox*/ )
    {
        if ( m_aLinkChangeHandler.IsSet() )
            return m_aLinkChangeHandler.Call( this );

        return 0L;
    }

    //========================================================================
    //= FormLinkDialog
    //========================================================================
    //------------------------------------------------------------------------
    FormLinkDialog::FormLinkDialog( Window* _pParent, const Reference< XPropertySet >& _rxDetailForm,
            const Reference< XPropertySet >& _rxMasterForm, const Reference< XMultiServiceFactory >& _rxORB,
            const ::rtl::OUString& _sExplanation,
            const ::rtl::OUString& _sDetailLabel,
            const ::rtl::OUString& _sMasterLabel)
        :ModalDialog( _pParent, PcrRes( RID_DLG_FORMLINKS ) )
        ,m_aExplanation( this, PcrRes( FT_EXPLANATION  ) )
        ,m_aDetailLabel( this, PcrRes( FT_DETAIL_LABEL ) )
        ,m_aMasterLabel( this, PcrRes( FT_MASTER_LABEL ) )
        ,m_aRow1       ( new FieldLinkRow( this, PcrRes( 1 ) ) )
        ,m_aRow2       ( new FieldLinkRow( this, PcrRes( 2 ) ) )
        ,m_aRow3       ( new FieldLinkRow( this, PcrRes( 3 ) ) )
        ,m_aRow4       ( new FieldLinkRow( this, PcrRes( 4 ) ) )
        ,m_aOK         ( this, PcrRes( PB_OK           ) )
        ,m_aCancel     ( this, PcrRes( PB_CANCEL       ) )
        ,m_aHelp       ( this, PcrRes( PB_HELP         ) )
        ,m_aSuggest    ( this, PcrRes( PB_SUGGEST      ) )
        ,m_xORB       ( _rxORB        )
        ,m_xDetailForm( _rxDetailForm )
        ,m_xMasterForm( _rxMasterForm )
        ,m_sDetailLabel(_sDetailLabel)
        ,m_sMasterLabel(_sMasterLabel)
    {
        FreeResource();
        if ( _sExplanation.getLength() )
            m_aExplanation.SetText(_sExplanation);

        m_aSuggest.SetClickHdl       ( LINK( this, FormLinkDialog, OnSuggest      ) );
        m_aRow1->SetLinkChangeHandler( LINK( this, FormLinkDialog, OnFieldChanged ) );
        m_aRow2->SetLinkChangeHandler( LINK( this, FormLinkDialog, OnFieldChanged ) );
        m_aRow3->SetLinkChangeHandler( LINK( this, FormLinkDialog, OnFieldChanged ) );
        m_aRow4->SetLinkChangeHandler( LINK( this, FormLinkDialog, OnFieldChanged ) );

        PostUserEvent( LINK( this, FormLinkDialog, OnInitialize ) );

        updateOkButton();
    }

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

    //------------------------------------------------------------------------
    void FormLinkDialog::commitLinkPairs()
    {
        // collect the field lists from the rows
        ::std::vector< ::rtl::OUString > aDetailFields; aDetailFields.reserve( 4 );
        ::std::vector< ::rtl::OUString > aMasterFields; aMasterFields.reserve( 4 );

        const FieldLinkRow* aRows[] = {
            m_aRow1.get(), m_aRow2.get(), m_aRow3.get(), m_aRow4.get()
        };

        for ( sal_Int32 i = 0; i < 4; ++i )
        {
            String sDetailField, sMasterField;
            aRows[ i ]->GetFieldName( FieldLinkRow::eDetailField, sDetailField );
            aRows[ i ]->GetFieldName( FieldLinkRow::eMasterField, sMasterField );
            if ( !sDetailField.Len() && !sMasterField.Len() )
                continue;

            aDetailFields.push_back( sDetailField );
            aMasterFields.push_back( sMasterField );
        }

        // and set as property values
        try
        {
            Reference< XPropertySet > xDetailFormProps( m_xDetailForm, UNO_QUERY );
            if ( xDetailFormProps.is() )
            {
	    	    ::rtl::OUString *pFields = aDetailFields.empty() ? 0 : &aDetailFields[0];
                xDetailFormProps->setPropertyValue( PROPERTY_DETAILFIELDS, makeAny( Sequence< ::rtl::OUString >( pFields, aDetailFields.size() ) ) );
	    	    pFields = aMasterFields.empty() ? 0 : &aMasterFields[0];
                xDetailFormProps->setPropertyValue( PROPERTY_MASTERFIELDS, makeAny( Sequence< ::rtl::OUString >( pFields, aMasterFields.size() ) ) );
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "FormLinkDialog::commitLinkPairs: caught an exception while setting the properties!" );
        }
    }

    //------------------------------------------------------------------------
    short FormLinkDialog::Execute()
    {
        short nResult = ModalDialog::Execute();

        if ( RET_OK == nResult )
            commitLinkPairs();

        return nResult;
    }

    //------------------------------------------------------------------------
    void FormLinkDialog::initializeFieldLists()
    {
        Sequence< ::rtl::OUString > sDetailFields;
        getFormFields( m_xDetailForm, sDetailFields );

        Sequence< ::rtl::OUString > sMasterFields;
        getFormFields( m_xMasterForm, sMasterFields );

        FieldLinkRow* aRows[] = {
            m_aRow1.get(), m_aRow2.get(), m_aRow3.get(), m_aRow4.get()
        };
        for ( sal_Int32 i = 0; i < 4 ; ++i )
        {
            aRows[i]->fillList( FieldLinkRow::eDetailField, sDetailFields );
            aRows[i]->fillList( FieldLinkRow::eMasterField, sMasterFields );
        }

    }

    //------------------------------------------------------------------------
    void FormLinkDialog::initializeColumnLabels()
    {
        // label for the detail form
        String sDetailType = getFormDataSourceType( m_xDetailForm );
        if ( !sDetailType.Len() )
        {
            if ( !m_sDetailLabel.getLength() )
            {
                ::svt::OLocalResourceAccess aStringAccess( PcrRes( RID_DLG_FORMLINKS ), RSC_MODALDIALOG );
                m_sDetailLabel = String( PcrRes( STR_DETAIL_FORM ) );
            }
            sDetailType = m_sDetailLabel;
        }
        m_aDetailLabel.SetText( sDetailType );

        // label for the master form
        String sMasterType = getFormDataSourceType( m_xMasterForm );
        if ( !sMasterType.Len() )
        {
            if ( !m_sMasterLabel.getLength() )
            {
                ::svt::OLocalResourceAccess aStringAccess( PcrRes( RID_DLG_FORMLINKS ), RSC_MODALDIALOG );
                m_sMasterLabel = String( PcrRes( STR_MASTER_FORM ) );
            }
            sMasterType = m_sMasterLabel;
        }
        m_aMasterLabel.SetText( sMasterType );
    }

    //------------------------------------------------------------------------
    void FormLinkDialog::initializeFieldRowsFrom( Sequence< ::rtl::OUString >& _rDetailFields, Sequence< ::rtl::OUString >& _rMasterFields )
    {
        // our UI does allow 4 fields max
        _rDetailFields.realloc( 4 );
        _rMasterFields.realloc( 4 );

        const ::rtl::OUString* pDetailFields = _rDetailFields.getConstArray();
        const ::rtl::OUString* pMasterFields = _rMasterFields.getConstArray();

        FieldLinkRow* aRows[] = {
            m_aRow1.get(), m_aRow2.get(), m_aRow3.get(), m_aRow4.get()
        };
        for ( sal_Int32 i = 0; i < 4; ++i, ++pDetailFields, ++pMasterFields )
        {
            aRows[ i ]->SetFieldName( FieldLinkRow::eDetailField, *pDetailFields );
            aRows[ i ]->SetFieldName( FieldLinkRow::eMasterField, *pMasterFields );
        }
    }

    //------------------------------------------------------------------------
    void FormLinkDialog::initializeLinks()
    {
        try
        {
            Sequence< ::rtl::OUString > aDetailFields;
            Sequence< ::rtl::OUString > aMasterFields;

            Reference< XPropertySet > xDetailFormProps( m_xDetailForm, UNO_QUERY );
            if ( xDetailFormProps.is() )
            {
                xDetailFormProps->getPropertyValue( PROPERTY_DETAILFIELDS ) >>= aDetailFields;
                xDetailFormProps->getPropertyValue( PROPERTY_MASTERFIELDS ) >>= aMasterFields;
            }

            initializeFieldRowsFrom( aDetailFields, aMasterFields );
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "FormLinkDialog::initializeLinks: caught an exception!" );
        }
    }

    //------------------------------------------------------------------------
    void FormLinkDialog::updateOkButton()
    {
        // in all rows, there must be either two valid selections, or none at all
        // If there is at least one row with exactly one valid selection, then the
        // OKButton needs to be disabled
        sal_Bool bEnable = sal_True;

        const FieldLinkRow* aRows[] = {
            m_aRow1.get(), m_aRow2.get(), m_aRow3.get(), m_aRow4.get()
        };

        for ( sal_Int32 i = 0; ( i < 4 ) && bEnable; ++i )
        {
            String sNotInterestedInRightNow;
            if  (  aRows[ i ]->GetFieldName( FieldLinkRow::eDetailField, sNotInterestedInRightNow )
                != aRows[ i ]->GetFieldName( FieldLinkRow::eMasterField, sNotInterestedInRightNow )
                )
                bEnable = sal_False;
        }

        m_aOK.Enable( bEnable );
    }

    //------------------------------------------------------------------------
    String FormLinkDialog::getFormDataSourceType( const Reference< XPropertySet >& _rxForm ) const SAL_THROW(())
    {
        String sReturn;
        Reference< XPropertySet > xFormProps( _rxForm, UNO_QUERY );
        if ( !xFormProps.is() )
            return sReturn;

        try
        {
            sal_Int32       nCommandType = CommandType::COMMAND;
            ::rtl::OUString sCommand;

            xFormProps->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nCommandType;
            xFormProps->getPropertyValue( PROPERTY_COMMAND     ) >>= sCommand;

            if  (  ( nCommandType == CommandType::TABLE )
                || ( nCommandType == CommandType::QUERY )
                )
                sReturn = sCommand;
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "FormLinkDialog::getFormDataSourceType: caught an exception!" );
        }
        return sReturn;
    }

    //------------------------------------------------------------------------
    void FormLinkDialog::getFormFields( const Reference< XPropertySet >& _rxForm, Sequence< ::rtl::OUString >& /* [out] */ _rNames ) const SAL_THROW(( ))
    {
        _rNames.realloc( 0 );

        ::dbtools::SQLExceptionInfo aErrorInfo;
        ::rtl::OUString sCommand;
        try
        {
            WaitObject aWaitCursor( const_cast< FormLinkDialog* >( this ) );

            Reference< XPropertySet > xFormProps( _rxForm, UNO_QUERY );
            OSL_ENSURE( xFormProps.is(), "FormLinkDialog::getFormFields: invalid form!" );

            sal_Int32       nCommandType = CommandType::COMMAND;

            xFormProps->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nCommandType;
            xFormProps->getPropertyValue( PROPERTY_COMMAND     ) >>= sCommand;

            Reference< XConnection > xConnection;
            ensureFormConnection( xFormProps, xConnection );

            _rNames = ::dbtools::getFieldNamesByCommandDescriptor(
                xConnection,
                nCommandType,
                sCommand,
                &aErrorInfo
            );
        }
		catch (const SQLContext& e)    { aErrorInfo = e; }
		catch (const SQLWarning& e)    { aErrorInfo = e; }
		catch (const SQLException& e ) { aErrorInfo = e; }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "FormLinkDialog::getFormFields: caught a non-SQL exception!" );
        }

        if ( aErrorInfo.isValid() )
        {
            String sErrorMessage;
            {
                ::svt::OLocalResourceAccess aStringAccess( PcrRes( RID_DLG_FORMLINKS ), RSC_MODALDIALOG );
                sErrorMessage = String( PcrRes( STR_ERROR_RETRIEVING_COLUMNS) );
                sErrorMessage.SearchAndReplace('#',sCommand);
            }

            SQLContext aContext;
            aContext.Message = sErrorMessage;
			aContext.NextException = aErrorInfo.get();
            ::dbtools::showError( aContext, VCLUnoHelper::GetInterface( const_cast< FormLinkDialog* >( this ) ), m_xORB );
        }
    }

    //------------------------------------------------------------------------
    void FormLinkDialog::ensureFormConnection( const Reference< XPropertySet >& _rxFormProps, Reference< XConnection >& /* [out] */ _rxConnection ) const SAL_THROW(( Exception ))
    {
        OSL_PRECOND( _rxFormProps.is(), "FormLinkDialog::ensureFormConnection: invalid form!" );
        if ( !_rxFormProps.is() )
            return;
        if ( _rxFormProps->getPropertySetInfo()->hasPropertyByName(PROPERTY_ACTIVE_CONNECTION) )
            _rxConnection.set(_rxFormProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY);

        if ( !_rxConnection.is() )
            _rxConnection = ::dbtools::connectRowset( Reference< XRowSet >( _rxFormProps, UNO_QUERY ), m_xORB, sal_True );
    }

    //------------------------------------------------------------------------
    void FormLinkDialog::getConnectionMetaData( const Reference< XPropertySet >& _rxFormProps, Reference< XDatabaseMetaData >& /* [out] */ _rxMeta ) const SAL_THROW(( Exception ))
    {
        if ( _rxFormProps.is() )
        {
            Reference< XConnection > xConnection;
            if ( !::dbtools::isEmbeddedInDatabase( _rxFormProps, xConnection ) )
                _rxFormProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConnection;
            if ( xConnection.is() )
                _rxMeta = xConnection->getMetaData();
        }
    }

    //------------------------------------------------------------------------
    Reference< XPropertySet > FormLinkDialog::getCanonicUnderlyingTable( const Reference< XPropertySet >& _rxFormProps ) const
    {
        Reference< XPropertySet > xTable;
        try
        {
            Reference< XTablesSupplier > xTablesInForm( ::dbtools::getCurrentSettingsComposer( _rxFormProps, m_xORB ), UNO_QUERY );
            Reference< XNameAccess > xTables;
            if ( xTablesInForm.is() )
                xTables = xTablesInForm->getTables();
            Sequence< ::rtl::OUString > aTableNames;
            if ( xTables.is() )
                aTableNames = xTables->getElementNames();

            if ( aTableNames.getLength() == 1 )
            {
                xTables->getByName( aTableNames[ 0 ] ) >>= xTable;
                OSL_ENSURE( xTable.is(), "FormLinkDialog::getCanonicUnderlyingTable: invalid table!" );
            }
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "FormLinkDialog::getCanonicUnderlyingTable: caught an exception!" );
        }
        return xTable;
    }

    //------------------------------------------------------------------------
    sal_Bool FormLinkDialog::getExistingRelation( const Reference< XPropertySet >& _rxLHS, const Reference< XPropertySet >& /*_rxRHS*/,
            // TODO: fix the usage of _rxRHS. This is issue #i81956#.
        Sequence< ::rtl::OUString >& _rLeftFields, Sequence< ::rtl::OUString >& _rRightFields ) const
    {
        try
        {
            Reference< XKeysSupplier > xSuppKeys( _rxLHS, UNO_QUERY );
            Reference< XIndexAccess >  xKeys;
            if ( xSuppKeys.is() )
                xKeys = xSuppKeys->getKeys();

            if ( xKeys.is() )
            {
                Reference< XPropertySet >     xKey;
                Reference< XColumnsSupplier > xKeyColSupp( xKey, UNO_QUERY );
                Reference< XIndexAccess >     xKeyColumns;
                Reference< XPropertySet >     xKeyColumn;
                ::rtl::OUString sColumnName, sRelatedColumnName;

                const sal_Int32 keyCount = xKeys->getCount();
                for ( sal_Int32 key = 0; key < keyCount; ++key )
                {
                    xKeys->getByIndex( key ) >>= xKey;
                    sal_Int32 nKeyType = 0;
                    xKey->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= nKeyType;
                    if ( nKeyType != KeyType::FOREIGN )
                        continue;

                    xKeyColumns.clear();
                    xKeyColSupp = xKeyColSupp.query( xKey );
                    if ( xKeyColSupp.is() )
                        xKeyColumns = xKeyColumns.query( xKeyColSupp->getColumns() );
                    OSL_ENSURE( xKeyColumns.is(), "FormLinkDialog::getExistingRelation: could not obtain the columns for the key!" );

                    if ( !xKeyColumns.is() )
                        continue;

                    const sal_Int32 columnCount = xKeyColumns->getCount();
                    _rLeftFields.realloc( columnCount );
                    _rRightFields.realloc( columnCount );
                    for ( sal_Int32 column = 0; column < columnCount; ++column )
                    {
                        xKeyColumn.clear();
                        xKeyColumns->getByIndex( column ) >>= xKeyColumn;
                        OSL_ENSURE( xKeyColumn.is(), "FormLinkDialog::getExistingRelation: invalid key column!" );
                        if ( xKeyColumn.is() )
                        {
                            xKeyColumn->getPropertyValue( PROPERTY_NAME ) >>= sColumnName;
                            xKeyColumn->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RelatedColumn" ) ) ) >>= sRelatedColumnName;

                            _rLeftFields[ column ]  = sColumnName;
                            _rRightFields[ column ] = sRelatedColumnName;
                        }
                    }
                }
            }
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "FormLinkDialog::getExistingRelation: caught an exception!" );
        }

        return ( _rLeftFields.getLength() > 0 ) && ( _rLeftFields[ 0 ].getLength() > 0 );
    }

    //------------------------------------------------------------------------
    void FormLinkDialog::initializeSuggest()
    {
        Reference< XPropertySet > xDetailFormProps( m_xDetailForm, UNO_QUERY );
        Reference< XPropertySet > xMasterFormProps( m_xMasterForm, UNO_QUERY );
        if ( !xDetailFormProps.is() || !xMasterFormProps.is() )
            return;

        try
        {
            sal_Bool bEnable = sal_True;

            // only show the button when both forms are based on the same data source
            if ( bEnable )
            {
                ::rtl::OUString sMasterDS, sDetailDS;
                xMasterFormProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sMasterDS;
                xDetailFormProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sDetailDS;
                bEnable = ( sMasterDS == sDetailDS );
            }

            // only show the button when the connection supports relations
            if ( bEnable )
            {
                Reference< XDatabaseMetaData > xMeta;
                getConnectionMetaData( xDetailFormProps, xMeta );
                OSL_ENSURE( xMeta.is(), "FormLinkDialog::initializeSuggest: unable to retrieve the meta data for the connection!" );
                try
                {
                    bEnable = xMeta.is() && xMeta->supportsIntegrityEnhancementFacility();
                }
                catch(const Exception&)
                {
                    bEnable = sal_False;
                }
            }

            // only enable the button if there is a "canonic" table underlying both forms
            Reference< XPropertySet > xDetailTable, xMasterTable;
            if ( bEnable )
            {
                xDetailTable = getCanonicUnderlyingTable( xDetailFormProps );
                xMasterTable = getCanonicUnderlyingTable( xMasterFormProps );
                bEnable = xDetailTable.is() && xMasterTable.is();
            }

            // only enable the button if there is a relation between both tables
            m_aRelationDetailColumns.realloc( 0 );
            m_aRelationMasterColumns.realloc( 0 );
            if ( bEnable )
            {
                bEnable = getExistingRelation( xDetailTable, xMasterTable, m_aRelationDetailColumns, m_aRelationMasterColumns );
                OSL_POSTCOND( m_aRelationMasterColumns.getLength() == m_aRelationDetailColumns.getLength(), "FormLinkDialog::initializeSuggest: nonsense!" );
                if ( m_aRelationMasterColumns.getLength() == 0 )
                {   // okay, there is no relation "pointing" (via a foreign key) from the detail table to the master table
                    // but perhaps the other way round (would make less sense, but who knows ...)
                    bEnable = getExistingRelation( xMasterTable, xDetailTable, m_aRelationMasterColumns, m_aRelationDetailColumns );
                }
            }

            // only enable the button if the relation contains at most 4 field pairs
            if ( bEnable )
            {
                bEnable = ( m_aRelationMasterColumns.getLength() <= 4 );
            }

            m_aSuggest.Enable( bEnable );
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "FormLinkDialog::initializeSuggest: caught an exception!" );
        }
    }

    //------------------------------------------------------------------------
    IMPL_LINK( FormLinkDialog, OnSuggest, void*, /*_pNotInterestedIn*/ )
    {
        initializeFieldRowsFrom( m_aRelationDetailColumns, m_aRelationMasterColumns );
        return 0L;
    }

    //------------------------------------------------------------------------
    IMPL_LINK( FormLinkDialog, OnFieldChanged, FieldLinkRow*, /*_pRow*/ )
    {
        updateOkButton();
        return 0L;
    }

    //------------------------------------------------------------------------
    IMPL_LINK( FormLinkDialog, OnInitialize, void*, /*_pNotInterestedIn*/ )
    {
        initializeColumnLabels();
        initializeFieldLists();
        initializeLinks();
        initializeSuggest();
        return 0L;
    }
//............................................................................
}   // namespace pcr
//............................................................................
