1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: formlinkdialog.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
34 #include "formlinkdialog.hxx"
35 #include "formlinkdialog.hrc"
37 #ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_
38 #include "modulepcr.hxx"
40 #ifndef _EXTENSIONS_FORMCTRLR_PROPRESID_HRC_
41 #include "formresid.hrc"
43 #include "formstrings.hxx"
44 #include <vcl/combobox.hxx>
45 #include <vcl/msgbox.hxx>
46 #include <vcl/waitobj.hxx>
47 #include <svtools/localresaccess.hxx>
48 #include <connectivity/dbtools.hxx>
49 #include <connectivity/dbexception.hxx>
50 #include <toolkit/helper/vclunohelper.hxx>
52 /** === begin UNO includes === **/
53 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
54 #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
55 #include <com/sun/star/sdbcx/KeyType.hpp>
56 #include <com/sun/star/container/XNameAccess.hpp>
57 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
58 #include <com/sun/star/sdbc/XRowSet.hpp>
59 #include <com/sun/star/sdb/CommandType.hpp>
60 #include <com/sun/star/sdb/SQLContext.hpp>
61 /** === end UNO includes === **/
64 //............................................................................
67 //............................................................................
69 using namespace ::com::sun::star::uno
;
70 using namespace ::com::sun::star::lang
;
71 using namespace ::com::sun::star::form
;
72 using namespace ::com::sun::star::sdb
;
73 using namespace ::com::sun::star::sdbc
;
74 using namespace ::com::sun::star::sdbcx
;
75 using namespace ::com::sun::star::beans
;
76 using namespace ::com::sun::star::container
;
78 //========================================================================
80 //========================================================================
81 class FieldLinkRow
: public Window
84 ComboBox m_aDetailColumn
;
85 FixedText m_aEqualSign
;
86 ComboBox m_aMasterColumn
;
88 Link m_aLinkChangeHandler
;
91 FieldLinkRow( Window
* _pParent
, const ResId
& _rId
);
93 inline void SetLinkChangeHandler( const Link
& _rHdl
) { m_aLinkChangeHandler
= _rHdl
; }
94 inline const Link
& GetLinkChangeHandler( ) const { return m_aLinkChangeHandler
; }
101 /** retrieves the selected field name for either the master or the detail field
102 @return <TRUE/> if and only a valid field is selected
104 bool GetFieldName( LinkParticipant _eWhich
, String
& /* [out] */ _rName
) const;
105 void SetFieldName( LinkParticipant _eWhich
, const String
& _rName
);
107 void fillList( LinkParticipant _eWhich
, const Sequence
< ::rtl::OUString
>& _rFieldNames
);
110 DECL_LINK( OnFieldNameChanged
, ComboBox
* );
113 //------------------------------------------------------------------------
114 FieldLinkRow::FieldLinkRow( Window
* _pParent
, const ResId
& _rId
)
115 :Window( _pParent
, _rId
)
116 ,m_aDetailColumn( this, ResId( 1, *_rId
.GetResMgr() ) )
117 ,m_aEqualSign ( this, ResId( 1, *_rId
.GetResMgr() ) )
118 ,m_aMasterColumn( this, ResId( 2, *_rId
.GetResMgr() ) )
122 m_aDetailColumn
.SetDropDownLineCount( 10 );
123 m_aMasterColumn
.SetDropDownLineCount( 10 );
125 m_aDetailColumn
.SetModifyHdl( LINK( this, FieldLinkRow
, OnFieldNameChanged
) );
126 m_aMasterColumn
.SetModifyHdl( LINK( this, FieldLinkRow
, OnFieldNameChanged
) );
129 //------------------------------------------------------------------------
130 void FieldLinkRow::fillList( LinkParticipant _eWhich
, const Sequence
< ::rtl::OUString
>& _rFieldNames
)
132 ComboBox
* pBox
= ( _eWhich
== eDetailField
) ? &m_aDetailColumn
: &m_aMasterColumn
;
134 const ::rtl::OUString
* pFieldName
= _rFieldNames
.getConstArray();
135 const ::rtl::OUString
* pFieldNameEnd
= pFieldName
+ _rFieldNames
.getLength();
136 for ( ; pFieldName
!= pFieldNameEnd
; ++pFieldName
)
137 pBox
->InsertEntry( *pFieldName
);
140 //------------------------------------------------------------------------
141 bool FieldLinkRow::GetFieldName( LinkParticipant _eWhich
, String
& /* [out] */ _rName
) const
143 const ComboBox
* pBox
= ( _eWhich
== eDetailField
) ? &m_aDetailColumn
: &m_aMasterColumn
;
144 _rName
= pBox
->GetText();
145 return _rName
.Len() != 0;
148 //------------------------------------------------------------------------
149 void FieldLinkRow::SetFieldName( LinkParticipant _eWhich
, const String
& _rName
)
151 ComboBox
* pBox
= ( _eWhich
== eDetailField
) ? &m_aDetailColumn
: &m_aMasterColumn
;
152 pBox
->SetText( _rName
);
155 //------------------------------------------------------------------------
156 IMPL_LINK( FieldLinkRow
, OnFieldNameChanged
, ComboBox
*, /*_pBox*/ )
158 if ( m_aLinkChangeHandler
.IsSet() )
159 return m_aLinkChangeHandler
.Call( this );
164 //========================================================================
166 //========================================================================
167 //------------------------------------------------------------------------
168 FormLinkDialog::FormLinkDialog( Window
* _pParent
, const Reference
< XPropertySet
>& _rxDetailForm
,
169 const Reference
< XPropertySet
>& _rxMasterForm
, const Reference
< XMultiServiceFactory
>& _rxORB
,
170 const ::rtl::OUString
& _sExplanation
,
171 const ::rtl::OUString
& _sDetailLabel
,
172 const ::rtl::OUString
& _sMasterLabel
)
173 :ModalDialog( _pParent
, PcrRes( RID_DLG_FORMLINKS
) )
174 ,m_aExplanation( this, PcrRes( FT_EXPLANATION
) )
175 ,m_aDetailLabel( this, PcrRes( FT_DETAIL_LABEL
) )
176 ,m_aMasterLabel( this, PcrRes( FT_MASTER_LABEL
) )
177 ,m_aRow1 ( new FieldLinkRow( this, PcrRes( 1 ) ) )
178 ,m_aRow2 ( new FieldLinkRow( this, PcrRes( 2 ) ) )
179 ,m_aRow3 ( new FieldLinkRow( this, PcrRes( 3 ) ) )
180 ,m_aRow4 ( new FieldLinkRow( this, PcrRes( 4 ) ) )
181 ,m_aOK ( this, PcrRes( PB_OK
) )
182 ,m_aCancel ( this, PcrRes( PB_CANCEL
) )
183 ,m_aHelp ( this, PcrRes( PB_HELP
) )
184 ,m_aSuggest ( this, PcrRes( PB_SUGGEST
) )
186 ,m_xDetailForm( _rxDetailForm
)
187 ,m_xMasterForm( _rxMasterForm
)
188 ,m_sDetailLabel(_sDetailLabel
)
189 ,m_sMasterLabel(_sMasterLabel
)
192 if ( _sExplanation
.getLength() )
193 m_aExplanation
.SetText(_sExplanation
);
195 m_aSuggest
.SetClickHdl ( LINK( this, FormLinkDialog
, OnSuggest
) );
196 m_aRow1
->SetLinkChangeHandler( LINK( this, FormLinkDialog
, OnFieldChanged
) );
197 m_aRow2
->SetLinkChangeHandler( LINK( this, FormLinkDialog
, OnFieldChanged
) );
198 m_aRow3
->SetLinkChangeHandler( LINK( this, FormLinkDialog
, OnFieldChanged
) );
199 m_aRow4
->SetLinkChangeHandler( LINK( this, FormLinkDialog
, OnFieldChanged
) );
201 PostUserEvent( LINK( this, FormLinkDialog
, OnInitialize
) );
206 //------------------------------------------------------------------------
207 FormLinkDialog::~FormLinkDialog( )
211 //------------------------------------------------------------------------
212 void FormLinkDialog::commitLinkPairs()
214 // collect the field lists from the rows
215 ::std::vector
< ::rtl::OUString
> aDetailFields
; aDetailFields
.reserve( 4 );
216 ::std::vector
< ::rtl::OUString
> aMasterFields
; aMasterFields
.reserve( 4 );
218 const FieldLinkRow
* aRows
[] = {
219 m_aRow1
.get(), m_aRow2
.get(), m_aRow3
.get(), m_aRow4
.get()
222 for ( sal_Int32 i
= 0; i
< 4; ++i
)
224 String sDetailField
, sMasterField
;
225 aRows
[ i
]->GetFieldName( FieldLinkRow::eDetailField
, sDetailField
);
226 aRows
[ i
]->GetFieldName( FieldLinkRow::eMasterField
, sMasterField
);
227 if ( !sDetailField
.Len() && !sMasterField
.Len() )
230 aDetailFields
.push_back( sDetailField
);
231 aMasterFields
.push_back( sMasterField
);
234 // and set as property values
237 Reference
< XPropertySet
> xDetailFormProps( m_xDetailForm
, UNO_QUERY
);
238 if ( xDetailFormProps
.is() )
240 ::rtl::OUString
*pFields
= aDetailFields
.empty() ? 0 : &aDetailFields
[0];
241 xDetailFormProps
->setPropertyValue( PROPERTY_DETAILFIELDS
, makeAny( Sequence
< ::rtl::OUString
>( pFields
, aDetailFields
.size() ) ) );
242 pFields
= aMasterFields
.empty() ? 0 : &aMasterFields
[0];
243 xDetailFormProps
->setPropertyValue( PROPERTY_MASTERFIELDS
, makeAny( Sequence
< ::rtl::OUString
>( pFields
, aMasterFields
.size() ) ) );
246 catch( const Exception
& )
248 OSL_ENSURE( sal_False
, "FormLinkDialog::commitLinkPairs: caught an exception while setting the properties!" );
252 //------------------------------------------------------------------------
253 short FormLinkDialog::Execute()
255 short nResult
= ModalDialog::Execute();
257 if ( RET_OK
== nResult
)
263 //------------------------------------------------------------------------
264 void FormLinkDialog::initializeFieldLists()
266 Sequence
< ::rtl::OUString
> sDetailFields
;
267 getFormFields( m_xDetailForm
, sDetailFields
);
269 Sequence
< ::rtl::OUString
> sMasterFields
;
270 getFormFields( m_xMasterForm
, sMasterFields
);
272 FieldLinkRow
* aRows
[] = {
273 m_aRow1
.get(), m_aRow2
.get(), m_aRow3
.get(), m_aRow4
.get()
275 for ( sal_Int32 i
= 0; i
< 4 ; ++i
)
277 aRows
[i
]->fillList( FieldLinkRow::eDetailField
, sDetailFields
);
278 aRows
[i
]->fillList( FieldLinkRow::eMasterField
, sMasterFields
);
283 //------------------------------------------------------------------------
284 void FormLinkDialog::initializeColumnLabels()
286 // label for the detail form
287 String sDetailType
= getFormDataSourceType( m_xDetailForm
);
288 if ( !sDetailType
.Len() )
290 if ( !m_sDetailLabel
.getLength() )
292 ::svt::OLocalResourceAccess
aStringAccess( PcrRes( RID_DLG_FORMLINKS
), RSC_MODALDIALOG
);
293 m_sDetailLabel
= String( PcrRes( STR_DETAIL_FORM
) );
295 sDetailType
= m_sDetailLabel
;
297 m_aDetailLabel
.SetText( sDetailType
);
299 // label for the master form
300 String sMasterType
= getFormDataSourceType( m_xMasterForm
);
301 if ( !sMasterType
.Len() )
303 if ( !m_sMasterLabel
.getLength() )
305 ::svt::OLocalResourceAccess
aStringAccess( PcrRes( RID_DLG_FORMLINKS
), RSC_MODALDIALOG
);
306 m_sMasterLabel
= String( PcrRes( STR_MASTER_FORM
) );
308 sMasterType
= m_sMasterLabel
;
310 m_aMasterLabel
.SetText( sMasterType
);
313 //------------------------------------------------------------------------
314 void FormLinkDialog::initializeFieldRowsFrom( Sequence
< ::rtl::OUString
>& _rDetailFields
, Sequence
< ::rtl::OUString
>& _rMasterFields
)
316 // our UI does allow 4 fields max
317 _rDetailFields
.realloc( 4 );
318 _rMasterFields
.realloc( 4 );
320 const ::rtl::OUString
* pDetailFields
= _rDetailFields
.getConstArray();
321 const ::rtl::OUString
* pMasterFields
= _rMasterFields
.getConstArray();
323 FieldLinkRow
* aRows
[] = {
324 m_aRow1
.get(), m_aRow2
.get(), m_aRow3
.get(), m_aRow4
.get()
326 for ( sal_Int32 i
= 0; i
< 4; ++i
, ++pDetailFields
, ++pMasterFields
)
328 aRows
[ i
]->SetFieldName( FieldLinkRow::eDetailField
, *pDetailFields
);
329 aRows
[ i
]->SetFieldName( FieldLinkRow::eMasterField
, *pMasterFields
);
333 //------------------------------------------------------------------------
334 void FormLinkDialog::initializeLinks()
338 Sequence
< ::rtl::OUString
> aDetailFields
;
339 Sequence
< ::rtl::OUString
> aMasterFields
;
341 Reference
< XPropertySet
> xDetailFormProps( m_xDetailForm
, UNO_QUERY
);
342 if ( xDetailFormProps
.is() )
344 xDetailFormProps
->getPropertyValue( PROPERTY_DETAILFIELDS
) >>= aDetailFields
;
345 xDetailFormProps
->getPropertyValue( PROPERTY_MASTERFIELDS
) >>= aMasterFields
;
348 initializeFieldRowsFrom( aDetailFields
, aMasterFields
);
350 catch( const Exception
& )
352 OSL_ENSURE( sal_False
, "FormLinkDialog::initializeLinks: caught an exception!" );
356 //------------------------------------------------------------------------
357 void FormLinkDialog::updateOkButton()
359 // in all rows, there must be either two valid selections, or none at all
360 // If there is at least one row with exactly one valid selection, then the
361 // OKButton needs to be disabled
364 const FieldLinkRow
* aRows
[] = {
365 m_aRow1
.get(), m_aRow2
.get(), m_aRow3
.get(), m_aRow4
.get()
368 for ( sal_Int32 i
= 0; ( i
< 4 ) && bEnable
; ++i
)
370 String sNotInterestedInRightNow
;
371 if ( aRows
[ i
]->GetFieldName( FieldLinkRow::eDetailField
, sNotInterestedInRightNow
)
372 != aRows
[ i
]->GetFieldName( FieldLinkRow::eMasterField
, sNotInterestedInRightNow
)
377 m_aOK
.Enable( bEnable
);
380 //------------------------------------------------------------------------
381 String
FormLinkDialog::getFormDataSourceType( const Reference
< XPropertySet
>& _rxForm
) const SAL_THROW(())
384 Reference
< XPropertySet
> xFormProps( _rxForm
, UNO_QUERY
);
385 if ( !xFormProps
.is() )
390 sal_Int32 nCommandType
= CommandType::COMMAND
;
391 ::rtl::OUString sCommand
;
393 xFormProps
->getPropertyValue( PROPERTY_COMMANDTYPE
) >>= nCommandType
;
394 xFormProps
->getPropertyValue( PROPERTY_COMMAND
) >>= sCommand
;
396 if ( ( nCommandType
== CommandType::TABLE
)
397 || ( nCommandType
== CommandType::QUERY
)
401 catch( const Exception
& )
403 OSL_ENSURE( sal_False
, "FormLinkDialog::getFormDataSourceType: caught an exception!" );
408 //------------------------------------------------------------------------
409 void FormLinkDialog::getFormFields( const Reference
< XPropertySet
>& _rxForm
, Sequence
< ::rtl::OUString
>& /* [out] */ _rNames
) const SAL_THROW(( ))
411 _rNames
.realloc( 0 );
413 ::dbtools::SQLExceptionInfo aErrorInfo
;
414 ::rtl::OUString sCommand
;
417 WaitObject
aWaitCursor( const_cast< FormLinkDialog
* >( this ) );
419 Reference
< XPropertySet
> xFormProps( _rxForm
, UNO_QUERY
);
420 OSL_ENSURE( xFormProps
.is(), "FormLinkDialog::getFormFields: invalid form!" );
422 sal_Int32 nCommandType
= CommandType::COMMAND
;
424 xFormProps
->getPropertyValue( PROPERTY_COMMANDTYPE
) >>= nCommandType
;
425 xFormProps
->getPropertyValue( PROPERTY_COMMAND
) >>= sCommand
;
427 Reference
< XConnection
> xConnection
;
428 ensureFormConnection( xFormProps
, xConnection
);
430 _rNames
= ::dbtools::getFieldNamesByCommandDescriptor(
437 catch (const SQLContext
& e
) { aErrorInfo
= e
; }
438 catch (const SQLWarning
& e
) { aErrorInfo
= e
; }
439 catch (const SQLException
& e
) { aErrorInfo
= e
; }
440 catch( const Exception
& )
442 OSL_ENSURE( sal_False
, "FormLinkDialog::getFormFields: caught a non-SQL exception!" );
445 if ( aErrorInfo
.isValid() )
447 String sErrorMessage
;
449 ::svt::OLocalResourceAccess
aStringAccess( PcrRes( RID_DLG_FORMLINKS
), RSC_MODALDIALOG
);
450 sErrorMessage
= String( PcrRes( STR_ERROR_RETRIEVING_COLUMNS
) );
451 sErrorMessage
.SearchAndReplace('#',sCommand
);
455 aContext
.Message
= sErrorMessage
;
456 aContext
.NextException
= aErrorInfo
.get();
457 ::dbtools::showError( aContext
, VCLUnoHelper::GetInterface( const_cast< FormLinkDialog
* >( this ) ), m_xORB
);
461 //------------------------------------------------------------------------
462 void FormLinkDialog::ensureFormConnection( const Reference
< XPropertySet
>& _rxFormProps
, Reference
< XConnection
>& /* [out] */ _rxConnection
) const SAL_THROW(( Exception
))
464 OSL_PRECOND( _rxFormProps
.is(), "FormLinkDialog::ensureFormConnection: invalid form!" );
465 if ( !_rxFormProps
.is() )
467 if ( _rxFormProps
->getPropertySetInfo()->hasPropertyByName(PROPERTY_ACTIVE_CONNECTION
) )
468 _rxConnection
.set(_rxFormProps
->getPropertyValue(PROPERTY_ACTIVE_CONNECTION
),UNO_QUERY
);
470 if ( !_rxConnection
.is() )
471 _rxConnection
= ::dbtools::connectRowset( Reference
< XRowSet
>( _rxFormProps
, UNO_QUERY
), m_xORB
, sal_True
);
474 //------------------------------------------------------------------------
475 void FormLinkDialog::getConnectionMetaData( const Reference
< XPropertySet
>& _rxFormProps
, Reference
< XDatabaseMetaData
>& /* [out] */ _rxMeta
) const SAL_THROW(( Exception
))
477 if ( _rxFormProps
.is() )
479 Reference
< XConnection
> xConnection
;
480 if ( !::dbtools::isEmbeddedInDatabase( _rxFormProps
, xConnection
) )
481 _rxFormProps
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xConnection
;
482 if ( xConnection
.is() )
483 _rxMeta
= xConnection
->getMetaData();
487 //------------------------------------------------------------------------
488 Reference
< XPropertySet
> FormLinkDialog::getCanonicUnderlyingTable( const Reference
< XPropertySet
>& _rxFormProps
) const
490 Reference
< XPropertySet
> xTable
;
493 Reference
< XTablesSupplier
> xTablesInForm( ::dbtools::getCurrentSettingsComposer( _rxFormProps
, m_xORB
), UNO_QUERY
);
494 Reference
< XNameAccess
> xTables
;
495 if ( xTablesInForm
.is() )
496 xTables
= xTablesInForm
->getTables();
497 Sequence
< ::rtl::OUString
> aTableNames
;
499 aTableNames
= xTables
->getElementNames();
501 if ( aTableNames
.getLength() == 1 )
503 xTables
->getByName( aTableNames
[ 0 ] ) >>= xTable
;
504 OSL_ENSURE( xTable
.is(), "FormLinkDialog::getCanonicUnderlyingTable: invalid table!" );
507 catch( const Exception
& )
509 OSL_ENSURE( sal_False
, "FormLinkDialog::getCanonicUnderlyingTable: caught an exception!" );
514 //------------------------------------------------------------------------
515 sal_Bool
FormLinkDialog::getExistingRelation( const Reference
< XPropertySet
>& _rxLHS
, const Reference
< XPropertySet
>& /*_rxRHS*/,
516 // TODO: fix the usage of _rxRHS. This is issue #i81956#.
517 Sequence
< ::rtl::OUString
>& _rLeftFields
, Sequence
< ::rtl::OUString
>& _rRightFields
) const
521 Reference
< XKeysSupplier
> xSuppKeys( _rxLHS
, UNO_QUERY
);
522 Reference
< XIndexAccess
> xKeys
;
523 if ( xSuppKeys
.is() )
524 xKeys
= xSuppKeys
->getKeys();
528 Reference
< XPropertySet
> xKey
;
529 Reference
< XColumnsSupplier
> xKeyColSupp( xKey
, UNO_QUERY
);
530 Reference
< XIndexAccess
> xKeyColumns
;
531 Reference
< XPropertySet
> xKeyColumn
;
532 ::rtl::OUString sColumnName
, sRelatedColumnName
;
534 const sal_Int32 keyCount
= xKeys
->getCount();
535 for ( sal_Int32 key
= 0; key
< keyCount
; ++key
)
537 xKeys
->getByIndex( key
) >>= xKey
;
538 sal_Int32 nKeyType
= 0;
539 xKey
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= nKeyType
;
540 if ( nKeyType
!= KeyType::FOREIGN
)
544 xKeyColSupp
= xKeyColSupp
.query( xKey
);
545 if ( xKeyColSupp
.is() )
546 xKeyColumns
= xKeyColumns
.query( xKeyColSupp
->getColumns() );
547 OSL_ENSURE( xKeyColumns
.is(), "FormLinkDialog::getExistingRelation: could not obtain the columns for the key!" );
549 if ( !xKeyColumns
.is() )
552 const sal_Int32 columnCount
= xKeyColumns
->getCount();
553 _rLeftFields
.realloc( columnCount
);
554 _rRightFields
.realloc( columnCount
);
555 for ( sal_Int32 column
= 0; column
< columnCount
; ++column
)
558 xKeyColumns
->getByIndex( column
) >>= xKeyColumn
;
559 OSL_ENSURE( xKeyColumn
.is(), "FormLinkDialog::getExistingRelation: invalid key column!" );
560 if ( xKeyColumn
.is() )
562 xKeyColumn
->getPropertyValue( PROPERTY_NAME
) >>= sColumnName
;
563 xKeyColumn
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RelatedColumn" ) ) ) >>= sRelatedColumnName
;
565 _rLeftFields
[ column
] = sColumnName
;
566 _rRightFields
[ column
] = sRelatedColumnName
;
572 catch( const Exception
& )
574 OSL_ENSURE( sal_False
, "FormLinkDialog::getExistingRelation: caught an exception!" );
577 return ( _rLeftFields
.getLength() > 0 ) && ( _rLeftFields
[ 0 ].getLength() > 0 );
580 //------------------------------------------------------------------------
581 void FormLinkDialog::initializeSuggest()
583 Reference
< XPropertySet
> xDetailFormProps( m_xDetailForm
, UNO_QUERY
);
584 Reference
< XPropertySet
> xMasterFormProps( m_xMasterForm
, UNO_QUERY
);
585 if ( !xDetailFormProps
.is() || !xMasterFormProps
.is() )
590 sal_Bool bEnable
= sal_True
;
592 // only show the button when both forms are based on the same data source
595 ::rtl::OUString sMasterDS
, sDetailDS
;
596 xMasterFormProps
->getPropertyValue( PROPERTY_DATASOURCE
) >>= sMasterDS
;
597 xDetailFormProps
->getPropertyValue( PROPERTY_DATASOURCE
) >>= sDetailDS
;
598 bEnable
= ( sMasterDS
== sDetailDS
);
601 // only show the button when the connection supports relations
604 Reference
< XDatabaseMetaData
> xMeta
;
605 getConnectionMetaData( xDetailFormProps
, xMeta
);
606 OSL_ENSURE( xMeta
.is(), "FormLinkDialog::initializeSuggest: unable to retrieve the meta data for the connection!" );
609 bEnable
= xMeta
.is() && xMeta
->supportsIntegrityEnhancementFacility();
611 catch(const Exception
&)
617 // only enable the button if there is a "canonic" table underlying both forms
618 Reference
< XPropertySet
> xDetailTable
, xMasterTable
;
621 xDetailTable
= getCanonicUnderlyingTable( xDetailFormProps
);
622 xMasterTable
= getCanonicUnderlyingTable( xMasterFormProps
);
623 bEnable
= xDetailTable
.is() && xMasterTable
.is();
626 // only enable the button if there is a relation between both tables
627 m_aRelationDetailColumns
.realloc( 0 );
628 m_aRelationMasterColumns
.realloc( 0 );
631 bEnable
= getExistingRelation( xDetailTable
, xMasterTable
, m_aRelationDetailColumns
, m_aRelationMasterColumns
);
632 OSL_POSTCOND( m_aRelationMasterColumns
.getLength() == m_aRelationDetailColumns
.getLength(), "FormLinkDialog::initializeSuggest: nonsense!" );
633 if ( m_aRelationMasterColumns
.getLength() == 0 )
634 { // okay, there is no relation "pointing" (via a foreign key) from the detail table to the master table
635 // but perhaps the other way round (would make less sense, but who knows ...)
636 bEnable
= getExistingRelation( xMasterTable
, xDetailTable
, m_aRelationMasterColumns
, m_aRelationDetailColumns
);
640 // only enable the button if the relation contains at most 4 field pairs
643 bEnable
= ( m_aRelationMasterColumns
.getLength() <= 4 );
646 m_aSuggest
.Enable( bEnable
);
648 catch( const Exception
& )
650 OSL_ENSURE( sal_False
, "FormLinkDialog::initializeSuggest: caught an exception!" );
654 //------------------------------------------------------------------------
655 IMPL_LINK( FormLinkDialog
, OnSuggest
, void*, /*_pNotInterestedIn*/ )
657 initializeFieldRowsFrom( m_aRelationDetailColumns
, m_aRelationMasterColumns
);
661 //------------------------------------------------------------------------
662 IMPL_LINK( FormLinkDialog
, OnFieldChanged
, FieldLinkRow
*, /*_pRow*/ )
668 //------------------------------------------------------------------------
669 IMPL_LINK( FormLinkDialog
, OnInitialize
, void*, /*_pNotInterestedIn*/ )
671 initializeColumnLabels();
672 initializeFieldLists();
677 //............................................................................
679 //............................................................................