1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
31 #include "formlinkdialog.hxx"
32 #include "formlinkdialog.hrc"
34 #ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_
35 #include "modulepcr.hxx"
37 #ifndef _EXTENSIONS_FORMCTRLR_PROPRESID_HRC_
38 #include "formresid.hrc"
40 #include "formstrings.hxx"
41 #include <vcl/combobox.hxx>
42 #include <vcl/msgbox.hxx>
43 #include <vcl/waitobj.hxx>
44 #include <svtools/localresaccess.hxx>
45 #include <connectivity/dbtools.hxx>
46 #include <connectivity/dbexception.hxx>
47 #include <toolkit/helper/vclunohelper.hxx>
49 /** === begin UNO includes === **/
50 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
51 #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
52 #include <com/sun/star/sdbcx/KeyType.hpp>
53 #include <com/sun/star/container/XNameAccess.hpp>
54 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
55 #include <com/sun/star/sdbc/XRowSet.hpp>
56 #include <com/sun/star/sdb/CommandType.hpp>
57 #include <com/sun/star/sdb/SQLContext.hpp>
58 /** === end UNO includes === **/
61 //............................................................................
64 //............................................................................
66 using namespace ::com::sun::star::uno
;
67 using namespace ::com::sun::star::lang
;
68 using namespace ::com::sun::star::form
;
69 using namespace ::com::sun::star::sdb
;
70 using namespace ::com::sun::star::sdbc
;
71 using namespace ::com::sun::star::sdbcx
;
72 using namespace ::com::sun::star::beans
;
73 using namespace ::com::sun::star::container
;
75 //========================================================================
77 //========================================================================
78 class FieldLinkRow
: public Window
81 ComboBox m_aDetailColumn
;
82 FixedText m_aEqualSign
;
83 ComboBox m_aMasterColumn
;
85 Link m_aLinkChangeHandler
;
88 FieldLinkRow( Window
* _pParent
, const ResId
& _rId
);
90 inline void SetLinkChangeHandler( const Link
& _rHdl
) { m_aLinkChangeHandler
= _rHdl
; }
91 inline const Link
& GetLinkChangeHandler( ) const { return m_aLinkChangeHandler
; }
98 /** retrieves the selected field name for either the master or the detail field
99 @return <TRUE/> if and only a valid field is selected
101 bool GetFieldName( LinkParticipant _eWhich
, String
& /* [out] */ _rName
) const;
102 void SetFieldName( LinkParticipant _eWhich
, const String
& _rName
);
104 void fillList( LinkParticipant _eWhich
, const Sequence
< ::rtl::OUString
>& _rFieldNames
);
107 DECL_LINK( OnFieldNameChanged
, ComboBox
* );
110 //------------------------------------------------------------------------
111 FieldLinkRow::FieldLinkRow( Window
* _pParent
, const ResId
& _rId
)
112 :Window( _pParent
, _rId
)
113 ,m_aDetailColumn( this, ResId( 1, *_rId
.GetResMgr() ) )
114 ,m_aEqualSign ( this, ResId( 1, *_rId
.GetResMgr() ) )
115 ,m_aMasterColumn( this, ResId( 2, *_rId
.GetResMgr() ) )
119 m_aDetailColumn
.SetDropDownLineCount( 10 );
120 m_aMasterColumn
.SetDropDownLineCount( 10 );
122 m_aDetailColumn
.SetModifyHdl( LINK( this, FieldLinkRow
, OnFieldNameChanged
) );
123 m_aMasterColumn
.SetModifyHdl( LINK( this, FieldLinkRow
, OnFieldNameChanged
) );
126 //------------------------------------------------------------------------
127 void FieldLinkRow::fillList( LinkParticipant _eWhich
, const Sequence
< ::rtl::OUString
>& _rFieldNames
)
129 ComboBox
* pBox
= ( _eWhich
== eDetailField
) ? &m_aDetailColumn
: &m_aMasterColumn
;
131 const ::rtl::OUString
* pFieldName
= _rFieldNames
.getConstArray();
132 const ::rtl::OUString
* pFieldNameEnd
= pFieldName
+ _rFieldNames
.getLength();
133 for ( ; pFieldName
!= pFieldNameEnd
; ++pFieldName
)
134 pBox
->InsertEntry( *pFieldName
);
137 //------------------------------------------------------------------------
138 bool FieldLinkRow::GetFieldName( LinkParticipant _eWhich
, String
& /* [out] */ _rName
) const
140 const ComboBox
* pBox
= ( _eWhich
== eDetailField
) ? &m_aDetailColumn
: &m_aMasterColumn
;
141 _rName
= pBox
->GetText();
142 return _rName
.Len() != 0;
145 //------------------------------------------------------------------------
146 void FieldLinkRow::SetFieldName( LinkParticipant _eWhich
, const String
& _rName
)
148 ComboBox
* pBox
= ( _eWhich
== eDetailField
) ? &m_aDetailColumn
: &m_aMasterColumn
;
149 pBox
->SetText( _rName
);
152 //------------------------------------------------------------------------
153 IMPL_LINK( FieldLinkRow
, OnFieldNameChanged
, ComboBox
*, /*_pBox*/ )
155 if ( m_aLinkChangeHandler
.IsSet() )
156 return m_aLinkChangeHandler
.Call( this );
161 //========================================================================
163 //========================================================================
164 //------------------------------------------------------------------------
165 FormLinkDialog::FormLinkDialog( Window
* _pParent
, const Reference
< XPropertySet
>& _rxDetailForm
,
166 const Reference
< XPropertySet
>& _rxMasterForm
, const Reference
< XMultiServiceFactory
>& _rxORB
,
167 const ::rtl::OUString
& _sExplanation
,
168 const ::rtl::OUString
& _sDetailLabel
,
169 const ::rtl::OUString
& _sMasterLabel
)
170 :ModalDialog( _pParent
, PcrRes( RID_DLG_FORMLINKS
) )
171 ,m_aExplanation( this, PcrRes( FT_EXPLANATION
) )
172 ,m_aDetailLabel( this, PcrRes( FT_DETAIL_LABEL
) )
173 ,m_aMasterLabel( this, PcrRes( FT_MASTER_LABEL
) )
174 ,m_aRow1 ( new FieldLinkRow( this, PcrRes( 1 ) ) )
175 ,m_aRow2 ( new FieldLinkRow( this, PcrRes( 2 ) ) )
176 ,m_aRow3 ( new FieldLinkRow( this, PcrRes( 3 ) ) )
177 ,m_aRow4 ( new FieldLinkRow( this, PcrRes( 4 ) ) )
178 ,m_aOK ( this, PcrRes( PB_OK
) )
179 ,m_aCancel ( this, PcrRes( PB_CANCEL
) )
180 ,m_aHelp ( this, PcrRes( PB_HELP
) )
181 ,m_aSuggest ( this, PcrRes( PB_SUGGEST
) )
183 ,m_xDetailForm( _rxDetailForm
)
184 ,m_xMasterForm( _rxMasterForm
)
185 ,m_sDetailLabel(_sDetailLabel
)
186 ,m_sMasterLabel(_sMasterLabel
)
189 if ( _sExplanation
.getLength() )
190 m_aExplanation
.SetText(_sExplanation
);
192 m_aSuggest
.SetClickHdl ( LINK( this, FormLinkDialog
, OnSuggest
) );
193 m_aRow1
->SetLinkChangeHandler( LINK( this, FormLinkDialog
, OnFieldChanged
) );
194 m_aRow2
->SetLinkChangeHandler( LINK( this, FormLinkDialog
, OnFieldChanged
) );
195 m_aRow3
->SetLinkChangeHandler( LINK( this, FormLinkDialog
, OnFieldChanged
) );
196 m_aRow4
->SetLinkChangeHandler( LINK( this, FormLinkDialog
, OnFieldChanged
) );
198 PostUserEvent( LINK( this, FormLinkDialog
, OnInitialize
) );
203 //------------------------------------------------------------------------
204 FormLinkDialog::~FormLinkDialog( )
208 //------------------------------------------------------------------------
209 void FormLinkDialog::commitLinkPairs()
211 // collect the field lists from the rows
212 ::std::vector
< ::rtl::OUString
> aDetailFields
; aDetailFields
.reserve( 4 );
213 ::std::vector
< ::rtl::OUString
> aMasterFields
; aMasterFields
.reserve( 4 );
215 const FieldLinkRow
* aRows
[] = {
216 m_aRow1
.get(), m_aRow2
.get(), m_aRow3
.get(), m_aRow4
.get()
219 for ( sal_Int32 i
= 0; i
< 4; ++i
)
221 String sDetailField
, sMasterField
;
222 aRows
[ i
]->GetFieldName( FieldLinkRow::eDetailField
, sDetailField
);
223 aRows
[ i
]->GetFieldName( FieldLinkRow::eMasterField
, sMasterField
);
224 if ( !sDetailField
.Len() && !sMasterField
.Len() )
227 aDetailFields
.push_back( sDetailField
);
228 aMasterFields
.push_back( sMasterField
);
231 // and set as property values
234 Reference
< XPropertySet
> xDetailFormProps( m_xDetailForm
, UNO_QUERY
);
235 if ( xDetailFormProps
.is() )
237 ::rtl::OUString
*pFields
= aDetailFields
.empty() ? 0 : &aDetailFields
[0];
238 xDetailFormProps
->setPropertyValue( PROPERTY_DETAILFIELDS
, makeAny( Sequence
< ::rtl::OUString
>( pFields
, aDetailFields
.size() ) ) );
239 pFields
= aMasterFields
.empty() ? 0 : &aMasterFields
[0];
240 xDetailFormProps
->setPropertyValue( PROPERTY_MASTERFIELDS
, makeAny( Sequence
< ::rtl::OUString
>( pFields
, aMasterFields
.size() ) ) );
243 catch( const Exception
& )
245 OSL_ENSURE( sal_False
, "FormLinkDialog::commitLinkPairs: caught an exception while setting the properties!" );
249 //------------------------------------------------------------------------
250 short FormLinkDialog::Execute()
252 short nResult
= ModalDialog::Execute();
254 if ( RET_OK
== nResult
)
260 //------------------------------------------------------------------------
261 void FormLinkDialog::initializeFieldLists()
263 Sequence
< ::rtl::OUString
> sDetailFields
;
264 getFormFields( m_xDetailForm
, sDetailFields
);
266 Sequence
< ::rtl::OUString
> sMasterFields
;
267 getFormFields( m_xMasterForm
, sMasterFields
);
269 FieldLinkRow
* aRows
[] = {
270 m_aRow1
.get(), m_aRow2
.get(), m_aRow3
.get(), m_aRow4
.get()
272 for ( sal_Int32 i
= 0; i
< 4 ; ++i
)
274 aRows
[i
]->fillList( FieldLinkRow::eDetailField
, sDetailFields
);
275 aRows
[i
]->fillList( FieldLinkRow::eMasterField
, sMasterFields
);
280 //------------------------------------------------------------------------
281 void FormLinkDialog::initializeColumnLabels()
283 // label for the detail form
284 String sDetailType
= getFormDataSourceType( m_xDetailForm
);
285 if ( !sDetailType
.Len() )
287 if ( !m_sDetailLabel
.getLength() )
289 ::svt::OLocalResourceAccess
aStringAccess( PcrRes( RID_DLG_FORMLINKS
), RSC_MODALDIALOG
);
290 m_sDetailLabel
= String( PcrRes( STR_DETAIL_FORM
) );
292 sDetailType
= m_sDetailLabel
;
294 m_aDetailLabel
.SetText( sDetailType
);
296 // label for the master form
297 String sMasterType
= getFormDataSourceType( m_xMasterForm
);
298 if ( !sMasterType
.Len() )
300 if ( !m_sMasterLabel
.getLength() )
302 ::svt::OLocalResourceAccess
aStringAccess( PcrRes( RID_DLG_FORMLINKS
), RSC_MODALDIALOG
);
303 m_sMasterLabel
= String( PcrRes( STR_MASTER_FORM
) );
305 sMasterType
= m_sMasterLabel
;
307 m_aMasterLabel
.SetText( sMasterType
);
310 //------------------------------------------------------------------------
311 void FormLinkDialog::initializeFieldRowsFrom( Sequence
< ::rtl::OUString
>& _rDetailFields
, Sequence
< ::rtl::OUString
>& _rMasterFields
)
313 // our UI does allow 4 fields max
314 _rDetailFields
.realloc( 4 );
315 _rMasterFields
.realloc( 4 );
317 const ::rtl::OUString
* pDetailFields
= _rDetailFields
.getConstArray();
318 const ::rtl::OUString
* pMasterFields
= _rMasterFields
.getConstArray();
320 FieldLinkRow
* aRows
[] = {
321 m_aRow1
.get(), m_aRow2
.get(), m_aRow3
.get(), m_aRow4
.get()
323 for ( sal_Int32 i
= 0; i
< 4; ++i
, ++pDetailFields
, ++pMasterFields
)
325 aRows
[ i
]->SetFieldName( FieldLinkRow::eDetailField
, *pDetailFields
);
326 aRows
[ i
]->SetFieldName( FieldLinkRow::eMasterField
, *pMasterFields
);
330 //------------------------------------------------------------------------
331 void FormLinkDialog::initializeLinks()
335 Sequence
< ::rtl::OUString
> aDetailFields
;
336 Sequence
< ::rtl::OUString
> aMasterFields
;
338 Reference
< XPropertySet
> xDetailFormProps( m_xDetailForm
, UNO_QUERY
);
339 if ( xDetailFormProps
.is() )
341 xDetailFormProps
->getPropertyValue( PROPERTY_DETAILFIELDS
) >>= aDetailFields
;
342 xDetailFormProps
->getPropertyValue( PROPERTY_MASTERFIELDS
) >>= aMasterFields
;
345 initializeFieldRowsFrom( aDetailFields
, aMasterFields
);
347 catch( const Exception
& )
349 OSL_ENSURE( sal_False
, "FormLinkDialog::initializeLinks: caught an exception!" );
353 //------------------------------------------------------------------------
354 void FormLinkDialog::updateOkButton()
356 // in all rows, there must be either two valid selections, or none at all
357 // If there is at least one row with exactly one valid selection, then the
358 // OKButton needs to be disabled
361 const FieldLinkRow
* aRows
[] = {
362 m_aRow1
.get(), m_aRow2
.get(), m_aRow3
.get(), m_aRow4
.get()
365 for ( sal_Int32 i
= 0; ( i
< 4 ) && bEnable
; ++i
)
367 String sNotInterestedInRightNow
;
368 if ( aRows
[ i
]->GetFieldName( FieldLinkRow::eDetailField
, sNotInterestedInRightNow
)
369 != aRows
[ i
]->GetFieldName( FieldLinkRow::eMasterField
, sNotInterestedInRightNow
)
374 m_aOK
.Enable( bEnable
);
377 //------------------------------------------------------------------------
378 String
FormLinkDialog::getFormDataSourceType( const Reference
< XPropertySet
>& _rxForm
) const SAL_THROW(())
381 Reference
< XPropertySet
> xFormProps( _rxForm
, UNO_QUERY
);
382 if ( !xFormProps
.is() )
387 sal_Int32 nCommandType
= CommandType::COMMAND
;
388 ::rtl::OUString sCommand
;
390 xFormProps
->getPropertyValue( PROPERTY_COMMANDTYPE
) >>= nCommandType
;
391 xFormProps
->getPropertyValue( PROPERTY_COMMAND
) >>= sCommand
;
393 if ( ( nCommandType
== CommandType::TABLE
)
394 || ( nCommandType
== CommandType::QUERY
)
398 catch( const Exception
& )
400 OSL_ENSURE( sal_False
, "FormLinkDialog::getFormDataSourceType: caught an exception!" );
405 //------------------------------------------------------------------------
406 void FormLinkDialog::getFormFields( const Reference
< XPropertySet
>& _rxForm
, Sequence
< ::rtl::OUString
>& /* [out] */ _rNames
) const SAL_THROW(( ))
408 _rNames
.realloc( 0 );
410 ::dbtools::SQLExceptionInfo aErrorInfo
;
411 ::rtl::OUString sCommand
;
414 WaitObject
aWaitCursor( const_cast< FormLinkDialog
* >( this ) );
416 Reference
< XPropertySet
> xFormProps( _rxForm
, UNO_QUERY
);
417 OSL_ENSURE( xFormProps
.is(), "FormLinkDialog::getFormFields: invalid form!" );
419 sal_Int32 nCommandType
= CommandType::COMMAND
;
421 xFormProps
->getPropertyValue( PROPERTY_COMMANDTYPE
) >>= nCommandType
;
422 xFormProps
->getPropertyValue( PROPERTY_COMMAND
) >>= sCommand
;
424 Reference
< XConnection
> xConnection
;
425 ensureFormConnection( xFormProps
, xConnection
);
427 _rNames
= ::dbtools::getFieldNamesByCommandDescriptor(
434 catch (const SQLContext
& e
) { aErrorInfo
= e
; }
435 catch (const SQLWarning
& e
) { aErrorInfo
= e
; }
436 catch (const SQLException
& e
) { aErrorInfo
= e
; }
437 catch( const Exception
& )
439 OSL_ENSURE( sal_False
, "FormLinkDialog::getFormFields: caught a non-SQL exception!" );
442 if ( aErrorInfo
.isValid() )
444 String sErrorMessage
;
446 ::svt::OLocalResourceAccess
aStringAccess( PcrRes( RID_DLG_FORMLINKS
), RSC_MODALDIALOG
);
447 sErrorMessage
= String( PcrRes( STR_ERROR_RETRIEVING_COLUMNS
) );
448 sErrorMessage
.SearchAndReplace('#',sCommand
);
452 aContext
.Message
= sErrorMessage
;
453 aContext
.NextException
= aErrorInfo
.get();
454 ::dbtools::showError( aContext
, VCLUnoHelper::GetInterface( const_cast< FormLinkDialog
* >( this ) ), m_xORB
);
458 //------------------------------------------------------------------------
459 void FormLinkDialog::ensureFormConnection( const Reference
< XPropertySet
>& _rxFormProps
, Reference
< XConnection
>& /* [out] */ _rxConnection
) const SAL_THROW(( Exception
))
461 OSL_PRECOND( _rxFormProps
.is(), "FormLinkDialog::ensureFormConnection: invalid form!" );
462 if ( !_rxFormProps
.is() )
464 if ( _rxFormProps
->getPropertySetInfo()->hasPropertyByName(PROPERTY_ACTIVE_CONNECTION
) )
465 _rxConnection
.set(_rxFormProps
->getPropertyValue(PROPERTY_ACTIVE_CONNECTION
),UNO_QUERY
);
467 if ( !_rxConnection
.is() )
468 _rxConnection
= ::dbtools::connectRowset( Reference
< XRowSet
>( _rxFormProps
, UNO_QUERY
), m_xORB
, sal_True
);
471 //------------------------------------------------------------------------
472 void FormLinkDialog::getConnectionMetaData( const Reference
< XPropertySet
>& _rxFormProps
, Reference
< XDatabaseMetaData
>& /* [out] */ _rxMeta
) const SAL_THROW(( Exception
))
474 if ( _rxFormProps
.is() )
476 Reference
< XConnection
> xConnection
;
477 if ( !::dbtools::isEmbeddedInDatabase( _rxFormProps
, xConnection
) )
478 _rxFormProps
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xConnection
;
479 if ( xConnection
.is() )
480 _rxMeta
= xConnection
->getMetaData();
484 //------------------------------------------------------------------------
485 Reference
< XPropertySet
> FormLinkDialog::getCanonicUnderlyingTable( const Reference
< XPropertySet
>& _rxFormProps
) const
487 Reference
< XPropertySet
> xTable
;
490 Reference
< XTablesSupplier
> xTablesInForm( ::dbtools::getCurrentSettingsComposer( _rxFormProps
, m_xORB
), UNO_QUERY
);
491 Reference
< XNameAccess
> xTables
;
492 if ( xTablesInForm
.is() )
493 xTables
= xTablesInForm
->getTables();
494 Sequence
< ::rtl::OUString
> aTableNames
;
496 aTableNames
= xTables
->getElementNames();
498 if ( aTableNames
.getLength() == 1 )
500 xTables
->getByName( aTableNames
[ 0 ] ) >>= xTable
;
501 OSL_ENSURE( xTable
.is(), "FormLinkDialog::getCanonicUnderlyingTable: invalid table!" );
504 catch( const Exception
& )
506 OSL_ENSURE( sal_False
, "FormLinkDialog::getCanonicUnderlyingTable: caught an exception!" );
511 //------------------------------------------------------------------------
512 sal_Bool
FormLinkDialog::getExistingRelation( const Reference
< XPropertySet
>& _rxLHS
, const Reference
< XPropertySet
>& /*_rxRHS*/,
513 // TODO: fix the usage of _rxRHS. This is issue #i81956#.
514 Sequence
< ::rtl::OUString
>& _rLeftFields
, Sequence
< ::rtl::OUString
>& _rRightFields
) const
518 Reference
< XKeysSupplier
> xSuppKeys( _rxLHS
, UNO_QUERY
);
519 Reference
< XIndexAccess
> xKeys
;
520 if ( xSuppKeys
.is() )
521 xKeys
= xSuppKeys
->getKeys();
525 Reference
< XPropertySet
> xKey
;
526 Reference
< XColumnsSupplier
> xKeyColSupp( xKey
, UNO_QUERY
);
527 Reference
< XIndexAccess
> xKeyColumns
;
528 Reference
< XPropertySet
> xKeyColumn
;
529 ::rtl::OUString sColumnName
, sRelatedColumnName
;
531 const sal_Int32 keyCount
= xKeys
->getCount();
532 for ( sal_Int32 key
= 0; key
< keyCount
; ++key
)
534 xKeys
->getByIndex( key
) >>= xKey
;
535 sal_Int32 nKeyType
= 0;
536 xKey
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= nKeyType
;
537 if ( nKeyType
!= KeyType::FOREIGN
)
541 xKeyColSupp
= xKeyColSupp
.query( xKey
);
542 if ( xKeyColSupp
.is() )
543 xKeyColumns
= xKeyColumns
.query( xKeyColSupp
->getColumns() );
544 OSL_ENSURE( xKeyColumns
.is(), "FormLinkDialog::getExistingRelation: could not obtain the columns for the key!" );
546 if ( !xKeyColumns
.is() )
549 const sal_Int32 columnCount
= xKeyColumns
->getCount();
550 _rLeftFields
.realloc( columnCount
);
551 _rRightFields
.realloc( columnCount
);
552 for ( sal_Int32 column
= 0; column
< columnCount
; ++column
)
555 xKeyColumns
->getByIndex( column
) >>= xKeyColumn
;
556 OSL_ENSURE( xKeyColumn
.is(), "FormLinkDialog::getExistingRelation: invalid key column!" );
557 if ( xKeyColumn
.is() )
559 xKeyColumn
->getPropertyValue( PROPERTY_NAME
) >>= sColumnName
;
560 xKeyColumn
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RelatedColumn" ) ) ) >>= sRelatedColumnName
;
562 _rLeftFields
[ column
] = sColumnName
;
563 _rRightFields
[ column
] = sRelatedColumnName
;
569 catch( const Exception
& )
571 OSL_ENSURE( sal_False
, "FormLinkDialog::getExistingRelation: caught an exception!" );
574 return ( _rLeftFields
.getLength() > 0 ) && ( _rLeftFields
[ 0 ].getLength() > 0 );
577 //------------------------------------------------------------------------
578 void FormLinkDialog::initializeSuggest()
580 Reference
< XPropertySet
> xDetailFormProps( m_xDetailForm
, UNO_QUERY
);
581 Reference
< XPropertySet
> xMasterFormProps( m_xMasterForm
, UNO_QUERY
);
582 if ( !xDetailFormProps
.is() || !xMasterFormProps
.is() )
587 sal_Bool bEnable
= sal_True
;
589 // only show the button when both forms are based on the same data source
592 ::rtl::OUString sMasterDS
, sDetailDS
;
593 xMasterFormProps
->getPropertyValue( PROPERTY_DATASOURCE
) >>= sMasterDS
;
594 xDetailFormProps
->getPropertyValue( PROPERTY_DATASOURCE
) >>= sDetailDS
;
595 bEnable
= ( sMasterDS
== sDetailDS
);
598 // only show the button when the connection supports relations
601 Reference
< XDatabaseMetaData
> xMeta
;
602 getConnectionMetaData( xDetailFormProps
, xMeta
);
603 OSL_ENSURE( xMeta
.is(), "FormLinkDialog::initializeSuggest: unable to retrieve the meta data for the connection!" );
606 bEnable
= xMeta
.is() && xMeta
->supportsIntegrityEnhancementFacility();
608 catch(const Exception
&)
614 // only enable the button if there is a "canonic" table underlying both forms
615 Reference
< XPropertySet
> xDetailTable
, xMasterTable
;
618 xDetailTable
= getCanonicUnderlyingTable( xDetailFormProps
);
619 xMasterTable
= getCanonicUnderlyingTable( xMasterFormProps
);
620 bEnable
= xDetailTable
.is() && xMasterTable
.is();
623 // only enable the button if there is a relation between both tables
624 m_aRelationDetailColumns
.realloc( 0 );
625 m_aRelationMasterColumns
.realloc( 0 );
628 bEnable
= getExistingRelation( xDetailTable
, xMasterTable
, m_aRelationDetailColumns
, m_aRelationMasterColumns
);
629 OSL_POSTCOND( m_aRelationMasterColumns
.getLength() == m_aRelationDetailColumns
.getLength(), "FormLinkDialog::initializeSuggest: nonsense!" );
630 if ( m_aRelationMasterColumns
.getLength() == 0 )
631 { // okay, there is no relation "pointing" (via a foreign key) from the detail table to the master table
632 // but perhaps the other way round (would make less sense, but who knows ...)
633 bEnable
= getExistingRelation( xMasterTable
, xDetailTable
, m_aRelationMasterColumns
, m_aRelationDetailColumns
);
637 // only enable the button if the relation contains at most 4 field pairs
640 bEnable
= ( m_aRelationMasterColumns
.getLength() <= 4 );
643 m_aSuggest
.Enable( bEnable
);
645 catch( const Exception
& )
647 OSL_ENSURE( sal_False
, "FormLinkDialog::initializeSuggest: caught an exception!" );
651 //------------------------------------------------------------------------
652 IMPL_LINK( FormLinkDialog
, OnSuggest
, void*, /*_pNotInterestedIn*/ )
654 initializeFieldRowsFrom( m_aRelationDetailColumns
, m_aRelationMasterColumns
);
658 //------------------------------------------------------------------------
659 IMPL_LINK( FormLinkDialog
, OnFieldChanged
, FieldLinkRow
*, /*_pRow*/ )
665 //------------------------------------------------------------------------
666 IMPL_LINK( FormLinkDialog
, OnInitialize
, void*, /*_pNotInterestedIn*/ )
668 initializeColumnLabels();
669 initializeFieldLists();
674 //............................................................................
676 //............................................................................