update credits
[LibreOffice.git] / extensions / source / propctrlr / formlinkdialog.cxx
blob2fdf007266d1452c0ad54fcda40091ab031d4ce4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "formlinkdialog.hxx"
22 #include "formlinkdialog.hrc"
24 #include "modulepcr.hxx"
25 #include "formresid.hrc"
26 #include "formstrings.hxx"
27 #include <vcl/combobox.hxx>
28 #include <vcl/msgbox.hxx>
29 #include <vcl/waitobj.hxx>
30 #include <svtools/localresaccess.hxx>
31 #include <connectivity/dbtools.hxx>
32 #include <connectivity/dbexception.hxx>
33 #include <toolkit/helper/vclunohelper.hxx>
34 #include <comphelper/processfactory.hxx>
36 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
37 #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
38 #include <com/sun/star/sdbcx/KeyType.hpp>
39 #include <com/sun/star/container/XNameAccess.hpp>
40 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
41 #include <com/sun/star/sdbc/XRowSet.hpp>
42 #include <com/sun/star/sdb/CommandType.hpp>
43 #include <com/sun/star/sdb/SQLContext.hpp>
46 //............................................................................
47 namespace pcr
49 //............................................................................
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::lang;
53 using namespace ::com::sun::star::form;
54 using namespace ::com::sun::star::sdb;
55 using namespace ::com::sun::star::sdbc;
56 using namespace ::com::sun::star::sdbcx;
57 using namespace ::com::sun::star::beans;
58 using namespace ::com::sun::star::container;
60 //========================================================================
61 //= FieldLinkRow
62 //========================================================================
63 class FieldLinkRow : public Window
65 private:
66 ComboBox m_aDetailColumn;
67 FixedText m_aEqualSign;
68 ComboBox m_aMasterColumn;
70 Link m_aLinkChangeHandler;
72 public:
73 FieldLinkRow( Window* _pParent, const ResId& _rId );
75 inline void SetLinkChangeHandler( const Link& _rHdl ) { m_aLinkChangeHandler = _rHdl; }
76 inline const Link& GetLinkChangeHandler( ) const { return m_aLinkChangeHandler; }
78 enum LinkParticipant
80 eDetailField,
81 eMasterField
83 /** retrieves the selected field name for either the master or the detail field
84 @return <TRUE/> if and only a valid field is selected
86 bool GetFieldName( LinkParticipant _eWhich, String& /* [out] */ _rName ) const;
87 void SetFieldName( LinkParticipant _eWhich, const String& _rName );
89 void fillList( LinkParticipant _eWhich, const Sequence< OUString >& _rFieldNames );
91 private:
92 DECL_LINK( OnFieldNameChanged, ComboBox* );
95 //------------------------------------------------------------------------
96 FieldLinkRow::FieldLinkRow( Window* _pParent, const ResId& _rId )
97 :Window( _pParent, _rId )
98 ,m_aDetailColumn( this, ResId( 1, *_rId.GetResMgr() ) )
99 ,m_aEqualSign ( this, ResId( 1, *_rId.GetResMgr() ) )
100 ,m_aMasterColumn( this, ResId( 2, *_rId.GetResMgr() ) )
102 FreeResource();
104 m_aDetailColumn.SetDropDownLineCount( 10 );
105 m_aMasterColumn.SetDropDownLineCount( 10 );
107 m_aDetailColumn.SetModifyHdl( LINK( this, FieldLinkRow, OnFieldNameChanged ) );
108 m_aMasterColumn.SetModifyHdl( LINK( this, FieldLinkRow, OnFieldNameChanged ) );
111 //------------------------------------------------------------------------
112 void FieldLinkRow::fillList( LinkParticipant _eWhich, const Sequence< OUString >& _rFieldNames )
114 ComboBox* pBox = ( _eWhich == eDetailField ) ? &m_aDetailColumn : &m_aMasterColumn;
116 const OUString* pFieldName = _rFieldNames.getConstArray();
117 const OUString* pFieldNameEnd = pFieldName + _rFieldNames.getLength();
118 for ( ; pFieldName != pFieldNameEnd; ++pFieldName )
119 pBox->InsertEntry( *pFieldName );
122 //------------------------------------------------------------------------
123 bool FieldLinkRow::GetFieldName( LinkParticipant _eWhich, String& /* [out] */ _rName ) const
125 const ComboBox* pBox = ( _eWhich == eDetailField ) ? &m_aDetailColumn : &m_aMasterColumn;
126 _rName = pBox->GetText();
127 return _rName.Len() != 0;
130 //------------------------------------------------------------------------
131 void FieldLinkRow::SetFieldName( LinkParticipant _eWhich, const String& _rName )
133 ComboBox* pBox = ( _eWhich == eDetailField ) ? &m_aDetailColumn : &m_aMasterColumn;
134 pBox->SetText( _rName );
137 //------------------------------------------------------------------------
138 IMPL_LINK( FieldLinkRow, OnFieldNameChanged, ComboBox*, /*_pBox*/ )
140 if ( m_aLinkChangeHandler.IsSet() )
141 return m_aLinkChangeHandler.Call( this );
143 return 0L;
146 //========================================================================
147 //= FormLinkDialog
148 //========================================================================
149 //------------------------------------------------------------------------
150 FormLinkDialog::FormLinkDialog( Window* _pParent, const Reference< XPropertySet >& _rxDetailForm,
151 const Reference< XPropertySet >& _rxMasterForm, const Reference< XComponentContext >& _rxContext,
152 const OUString& _sExplanation,
153 const OUString& _sDetailLabel,
154 const OUString& _sMasterLabel)
155 :ModalDialog( _pParent, PcrRes( RID_DLG_FORMLINKS ) )
156 ,m_aExplanation( this, PcrRes( FT_EXPLANATION ) )
157 ,m_aDetailLabel( this, PcrRes( FT_DETAIL_LABEL ) )
158 ,m_aMasterLabel( this, PcrRes( FT_MASTER_LABEL ) )
159 ,m_aRow1 ( new FieldLinkRow( this, PcrRes( 1 ) ) )
160 ,m_aRow2 ( new FieldLinkRow( this, PcrRes( 2 ) ) )
161 ,m_aRow3 ( new FieldLinkRow( this, PcrRes( 3 ) ) )
162 ,m_aRow4 ( new FieldLinkRow( this, PcrRes( 4 ) ) )
163 ,m_aOK ( this, PcrRes( PB_OK ) )
164 ,m_aCancel ( this, PcrRes( PB_CANCEL ) )
165 ,m_aHelp ( this, PcrRes( PB_HELP ) )
166 ,m_aSuggest ( this, PcrRes( PB_SUGGEST ) )
167 ,m_xContext ( _rxContext )
168 ,m_xDetailForm( _rxDetailForm )
169 ,m_xMasterForm( _rxMasterForm )
170 ,m_sDetailLabel(_sDetailLabel)
171 ,m_sMasterLabel(_sMasterLabel)
173 FreeResource();
174 if ( !_sExplanation.isEmpty() )
175 m_aExplanation.SetText(_sExplanation);
177 m_aSuggest.SetClickHdl ( LINK( this, FormLinkDialog, OnSuggest ) );
178 m_aRow1->SetLinkChangeHandler( LINK( this, FormLinkDialog, OnFieldChanged ) );
179 m_aRow2->SetLinkChangeHandler( LINK( this, FormLinkDialog, OnFieldChanged ) );
180 m_aRow3->SetLinkChangeHandler( LINK( this, FormLinkDialog, OnFieldChanged ) );
181 m_aRow4->SetLinkChangeHandler( LINK( this, FormLinkDialog, OnFieldChanged ) );
183 PostUserEvent( LINK( this, FormLinkDialog, OnInitialize ) );
185 updateOkButton();
188 //------------------------------------------------------------------------
189 FormLinkDialog::~FormLinkDialog( )
193 //------------------------------------------------------------------------
194 void FormLinkDialog::commitLinkPairs()
196 // collect the field lists from the rows
197 ::std::vector< OUString > aDetailFields; aDetailFields.reserve( 4 );
198 ::std::vector< OUString > aMasterFields; aMasterFields.reserve( 4 );
200 const FieldLinkRow* aRows[] = {
201 m_aRow1.get(), m_aRow2.get(), m_aRow3.get(), m_aRow4.get()
204 for ( sal_Int32 i = 0; i < 4; ++i )
206 String sDetailField, sMasterField;
207 aRows[ i ]->GetFieldName( FieldLinkRow::eDetailField, sDetailField );
208 aRows[ i ]->GetFieldName( FieldLinkRow::eMasterField, sMasterField );
209 if ( !sDetailField.Len() && !sMasterField.Len() )
210 continue;
212 aDetailFields.push_back( sDetailField );
213 aMasterFields.push_back( sMasterField );
216 // and set as property values
219 Reference< XPropertySet > xDetailFormProps( m_xDetailForm, UNO_QUERY );
220 if ( xDetailFormProps.is() )
222 OUString *pFields = aDetailFields.empty() ? 0 : &aDetailFields[0];
223 xDetailFormProps->setPropertyValue( PROPERTY_DETAILFIELDS, makeAny( Sequence< OUString >( pFields, aDetailFields.size() ) ) );
224 pFields = aMasterFields.empty() ? 0 : &aMasterFields[0];
225 xDetailFormProps->setPropertyValue( PROPERTY_MASTERFIELDS, makeAny( Sequence< OUString >( pFields, aMasterFields.size() ) ) );
228 catch( const Exception& )
230 OSL_FAIL( "FormLinkDialog::commitLinkPairs: caught an exception while setting the properties!" );
234 //------------------------------------------------------------------------
235 short FormLinkDialog::Execute()
237 short nResult = ModalDialog::Execute();
239 if ( RET_OK == nResult )
240 commitLinkPairs();
242 return nResult;
245 //------------------------------------------------------------------------
246 void FormLinkDialog::initializeFieldLists()
248 Sequence< OUString > sDetailFields;
249 getFormFields( m_xDetailForm, sDetailFields );
251 Sequence< OUString > sMasterFields;
252 getFormFields( m_xMasterForm, sMasterFields );
254 FieldLinkRow* aRows[] = {
255 m_aRow1.get(), m_aRow2.get(), m_aRow3.get(), m_aRow4.get()
257 for ( sal_Int32 i = 0; i < 4 ; ++i )
259 aRows[i]->fillList( FieldLinkRow::eDetailField, sDetailFields );
260 aRows[i]->fillList( FieldLinkRow::eMasterField, sMasterFields );
265 //------------------------------------------------------------------------
266 void FormLinkDialog::initializeColumnLabels()
268 // label for the detail form
269 String sDetailType = getFormDataSourceType( m_xDetailForm );
270 if ( !sDetailType.Len() )
272 if ( m_sDetailLabel.isEmpty() )
274 ::svt::OLocalResourceAccess aStringAccess( PcrRes( RID_DLG_FORMLINKS ), RSC_MODALDIALOG );
275 m_sDetailLabel = String( PcrRes( STR_DETAIL_FORM ) );
277 sDetailType = m_sDetailLabel;
279 m_aDetailLabel.SetText( sDetailType );
281 // label for the master form
282 String sMasterType = getFormDataSourceType( m_xMasterForm );
283 if ( !sMasterType.Len() )
285 if ( m_sMasterLabel.isEmpty() )
287 ::svt::OLocalResourceAccess aStringAccess( PcrRes( RID_DLG_FORMLINKS ), RSC_MODALDIALOG );
288 m_sMasterLabel = String( PcrRes( STR_MASTER_FORM ) );
290 sMasterType = m_sMasterLabel;
292 m_aMasterLabel.SetText( sMasterType );
295 //------------------------------------------------------------------------
296 void FormLinkDialog::initializeFieldRowsFrom( Sequence< OUString >& _rDetailFields, Sequence< OUString >& _rMasterFields )
298 // our UI does allow 4 fields max
299 _rDetailFields.realloc( 4 );
300 _rMasterFields.realloc( 4 );
302 const OUString* pDetailFields = _rDetailFields.getConstArray();
303 const OUString* pMasterFields = _rMasterFields.getConstArray();
305 FieldLinkRow* aRows[] = {
306 m_aRow1.get(), m_aRow2.get(), m_aRow3.get(), m_aRow4.get()
308 for ( sal_Int32 i = 0; i < 4; ++i, ++pDetailFields, ++pMasterFields )
310 aRows[ i ]->SetFieldName( FieldLinkRow::eDetailField, *pDetailFields );
311 aRows[ i ]->SetFieldName( FieldLinkRow::eMasterField, *pMasterFields );
315 //------------------------------------------------------------------------
316 void FormLinkDialog::initializeLinks()
320 Sequence< OUString > aDetailFields;
321 Sequence< OUString > aMasterFields;
323 Reference< XPropertySet > xDetailFormProps( m_xDetailForm, UNO_QUERY );
324 if ( xDetailFormProps.is() )
326 xDetailFormProps->getPropertyValue( PROPERTY_DETAILFIELDS ) >>= aDetailFields;
327 xDetailFormProps->getPropertyValue( PROPERTY_MASTERFIELDS ) >>= aMasterFields;
330 initializeFieldRowsFrom( aDetailFields, aMasterFields );
332 catch( const Exception& )
334 OSL_FAIL( "FormLinkDialog::initializeLinks: caught an exception!" );
338 //------------------------------------------------------------------------
339 void FormLinkDialog::updateOkButton()
341 // in all rows, there must be either two valid selections, or none at all
342 // If there is at least one row with exactly one valid selection, then the
343 // OKButton needs to be disabled
344 sal_Bool bEnable = sal_True;
346 const FieldLinkRow* aRows[] = {
347 m_aRow1.get(), m_aRow2.get(), m_aRow3.get(), m_aRow4.get()
350 for ( sal_Int32 i = 0; ( i < 4 ) && bEnable; ++i )
352 String sNotInterestedInRightNow;
353 if ( aRows[ i ]->GetFieldName( FieldLinkRow::eDetailField, sNotInterestedInRightNow )
354 != aRows[ i ]->GetFieldName( FieldLinkRow::eMasterField, sNotInterestedInRightNow )
356 bEnable = sal_False;
359 m_aOK.Enable( bEnable );
362 //------------------------------------------------------------------------
363 String FormLinkDialog::getFormDataSourceType( const Reference< XPropertySet >& _rxForm ) const SAL_THROW(())
365 String sReturn;
366 Reference< XPropertySet > xFormProps( _rxForm, UNO_QUERY );
367 if ( !xFormProps.is() )
368 return sReturn;
372 sal_Int32 nCommandType = CommandType::COMMAND;
373 OUString sCommand;
375 xFormProps->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nCommandType;
376 xFormProps->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand;
378 if ( ( nCommandType == CommandType::TABLE )
379 || ( nCommandType == CommandType::QUERY )
381 sReturn = sCommand;
383 catch( const Exception& )
385 OSL_FAIL( "FormLinkDialog::getFormDataSourceType: caught an exception!" );
387 return sReturn;
390 //------------------------------------------------------------------------
391 void FormLinkDialog::getFormFields( const Reference< XPropertySet >& _rxForm, Sequence< OUString >& /* [out] */ _rNames ) const SAL_THROW(( ))
393 _rNames.realloc( 0 );
395 ::dbtools::SQLExceptionInfo aErrorInfo;
396 OUString sCommand;
399 WaitObject aWaitCursor( const_cast< FormLinkDialog* >( this ) );
401 Reference< XPropertySet > xFormProps( _rxForm, UNO_QUERY );
402 OSL_ENSURE( xFormProps.is(), "FormLinkDialog::getFormFields: invalid form!" );
404 sal_Int32 nCommandType = CommandType::COMMAND;
406 xFormProps->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nCommandType;
407 xFormProps->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand;
409 Reference< XConnection > xConnection;
410 ensureFormConnection( xFormProps, xConnection );
412 _rNames = ::dbtools::getFieldNamesByCommandDescriptor(
413 xConnection,
414 nCommandType,
415 sCommand,
416 &aErrorInfo
419 catch (const SQLContext& e) { aErrorInfo = e; }
420 catch (const SQLWarning& e) { aErrorInfo = e; }
421 catch (const SQLException& e ) { aErrorInfo = e; }
422 catch( const Exception& )
424 OSL_FAIL( "FormLinkDialog::getFormFields: caught a non-SQL exception!" );
427 if ( aErrorInfo.isValid() )
429 String sErrorMessage;
431 ::svt::OLocalResourceAccess aStringAccess( PcrRes( RID_DLG_FORMLINKS ), RSC_MODALDIALOG );
432 sErrorMessage = PcrRes(STR_ERROR_RETRIEVING_COLUMNS).toString();
433 sErrorMessage.SearchAndReplace(OUString('#'), sCommand);
436 SQLContext aContext;
437 aContext.Message = sErrorMessage;
438 aContext.NextException = aErrorInfo.get();
439 ::dbtools::showError( aContext, VCLUnoHelper::GetInterface( const_cast< FormLinkDialog* >( this ) ), m_xContext );
443 //------------------------------------------------------------------------
444 void FormLinkDialog::ensureFormConnection( const Reference< XPropertySet >& _rxFormProps, Reference< XConnection >& /* [out] */ _rxConnection ) const SAL_THROW(( Exception ))
446 OSL_PRECOND( _rxFormProps.is(), "FormLinkDialog::ensureFormConnection: invalid form!" );
447 if ( !_rxFormProps.is() )
448 return;
449 if ( _rxFormProps->getPropertySetInfo()->hasPropertyByName(PROPERTY_ACTIVE_CONNECTION) )
450 _rxConnection.set(_rxFormProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY);
452 if ( !_rxConnection.is() )
453 _rxConnection = ::dbtools::connectRowset( Reference< XRowSet >( _rxFormProps, UNO_QUERY ), m_xContext, sal_True );
456 //------------------------------------------------------------------------
457 void FormLinkDialog::getConnectionMetaData( const Reference< XPropertySet >& _rxFormProps, Reference< XDatabaseMetaData >& /* [out] */ _rxMeta ) const SAL_THROW(( Exception ))
459 if ( _rxFormProps.is() )
461 Reference< XConnection > xConnection;
462 if ( !::dbtools::isEmbeddedInDatabase( _rxFormProps, xConnection ) )
463 _rxFormProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConnection;
464 if ( xConnection.is() )
465 _rxMeta = xConnection->getMetaData();
469 //------------------------------------------------------------------------
470 Reference< XPropertySet > FormLinkDialog::getCanonicUnderlyingTable( const Reference< XPropertySet >& _rxFormProps ) const
472 Reference< XPropertySet > xTable;
475 Reference< XTablesSupplier > xTablesInForm( ::dbtools::getCurrentSettingsComposer( _rxFormProps, m_xContext ), UNO_QUERY );
476 Reference< XNameAccess > xTables;
477 if ( xTablesInForm.is() )
478 xTables = xTablesInForm->getTables();
479 Sequence< OUString > aTableNames;
480 if ( xTables.is() )
481 aTableNames = xTables->getElementNames();
483 if ( aTableNames.getLength() == 1 )
485 xTables->getByName( aTableNames[ 0 ] ) >>= xTable;
486 OSL_ENSURE( xTable.is(), "FormLinkDialog::getCanonicUnderlyingTable: invalid table!" );
489 catch( const Exception& )
491 OSL_FAIL( "FormLinkDialog::getCanonicUnderlyingTable: caught an exception!" );
493 return xTable;
496 //------------------------------------------------------------------------
497 sal_Bool FormLinkDialog::getExistingRelation( const Reference< XPropertySet >& _rxLHS, const Reference< XPropertySet >& /*_rxRHS*/,
498 // TODO: fix the usage of _rxRHS. This is issue #i81956#.
499 Sequence< OUString >& _rLeftFields, Sequence< OUString >& _rRightFields ) const
503 Reference< XKeysSupplier > xSuppKeys( _rxLHS, UNO_QUERY );
504 Reference< XIndexAccess > xKeys;
505 if ( xSuppKeys.is() )
506 xKeys = xSuppKeys->getKeys();
508 if ( xKeys.is() )
510 Reference< XPropertySet > xKey;
511 Reference< XColumnsSupplier > xKeyColSupp( xKey, UNO_QUERY );
512 Reference< XIndexAccess > xKeyColumns;
513 Reference< XPropertySet > xKeyColumn;
514 OUString sColumnName, sRelatedColumnName;
516 const sal_Int32 keyCount = xKeys->getCount();
517 for ( sal_Int32 key = 0; key < keyCount; ++key )
519 xKeys->getByIndex( key ) >>= xKey;
520 sal_Int32 nKeyType = 0;
521 xKey->getPropertyValue( OUString( "Type" ) ) >>= nKeyType;
522 if ( nKeyType != KeyType::FOREIGN )
523 continue;
525 xKeyColumns.clear();
526 xKeyColSupp = xKeyColSupp.query( xKey );
527 if ( xKeyColSupp.is() )
528 xKeyColumns = xKeyColumns.query( xKeyColSupp->getColumns() );
529 OSL_ENSURE( xKeyColumns.is(), "FormLinkDialog::getExistingRelation: could not obtain the columns for the key!" );
531 if ( !xKeyColumns.is() )
532 continue;
534 const sal_Int32 columnCount = xKeyColumns->getCount();
535 _rLeftFields.realloc( columnCount );
536 _rRightFields.realloc( columnCount );
537 for ( sal_Int32 column = 0; column < columnCount; ++column )
539 xKeyColumn.clear();
540 xKeyColumns->getByIndex( column ) >>= xKeyColumn;
541 OSL_ENSURE( xKeyColumn.is(), "FormLinkDialog::getExistingRelation: invalid key column!" );
542 if ( xKeyColumn.is() )
544 xKeyColumn->getPropertyValue( PROPERTY_NAME ) >>= sColumnName;
545 xKeyColumn->getPropertyValue( OUString( "RelatedColumn" ) ) >>= sRelatedColumnName;
547 _rLeftFields[ column ] = sColumnName;
548 _rRightFields[ column ] = sRelatedColumnName;
554 catch( const Exception& )
556 OSL_FAIL( "FormLinkDialog::getExistingRelation: caught an exception!" );
559 return ( _rLeftFields.getLength() > 0 ) && ( !_rLeftFields[ 0 ].isEmpty() );
562 //------------------------------------------------------------------------
563 void FormLinkDialog::initializeSuggest()
565 Reference< XPropertySet > xDetailFormProps( m_xDetailForm, UNO_QUERY );
566 Reference< XPropertySet > xMasterFormProps( m_xMasterForm, UNO_QUERY );
567 if ( !xDetailFormProps.is() || !xMasterFormProps.is() )
568 return;
572 sal_Bool bEnable = sal_True;
574 // only show the button when both forms are based on the same data source
575 if ( bEnable )
577 OUString sMasterDS, sDetailDS;
578 xMasterFormProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sMasterDS;
579 xDetailFormProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sDetailDS;
580 bEnable = ( sMasterDS == sDetailDS );
583 // only show the button when the connection supports relations
584 if ( bEnable )
586 Reference< XDatabaseMetaData > xMeta;
587 getConnectionMetaData( xDetailFormProps, xMeta );
588 OSL_ENSURE( xMeta.is(), "FormLinkDialog::initializeSuggest: unable to retrieve the meta data for the connection!" );
591 bEnable = xMeta.is() && xMeta->supportsIntegrityEnhancementFacility();
593 catch(const Exception&)
595 bEnable = sal_False;
599 // only enable the button if there is a "canonic" table underlying both forms
600 Reference< XPropertySet > xDetailTable, xMasterTable;
601 if ( bEnable )
603 xDetailTable = getCanonicUnderlyingTable( xDetailFormProps );
604 xMasterTable = getCanonicUnderlyingTable( xMasterFormProps );
605 bEnable = xDetailTable.is() && xMasterTable.is();
608 // only enable the button if there is a relation between both tables
609 m_aRelationDetailColumns.realloc( 0 );
610 m_aRelationMasterColumns.realloc( 0 );
611 if ( bEnable )
613 bEnable = getExistingRelation( xDetailTable, xMasterTable, m_aRelationDetailColumns, m_aRelationMasterColumns );
614 OSL_POSTCOND( m_aRelationMasterColumns.getLength() == m_aRelationDetailColumns.getLength(), "FormLinkDialog::initializeSuggest: nonsense!" );
615 if ( m_aRelationMasterColumns.getLength() == 0 )
616 { // okay, there is no relation "pointing" (via a foreign key) from the detail table to the master table
617 // but perhaps the other way round (would make less sense, but who knows ...)
618 bEnable = getExistingRelation( xMasterTable, xDetailTable, m_aRelationMasterColumns, m_aRelationDetailColumns );
622 // only enable the button if the relation contains at most 4 field pairs
623 if ( bEnable )
625 bEnable = ( m_aRelationMasterColumns.getLength() <= 4 );
628 m_aSuggest.Enable( bEnable );
630 catch( const Exception& )
632 OSL_FAIL( "FormLinkDialog::initializeSuggest: caught an exception!" );
636 //------------------------------------------------------------------------
637 IMPL_LINK( FormLinkDialog, OnSuggest, void*, /*_pNotInterestedIn*/ )
639 initializeFieldRowsFrom( m_aRelationDetailColumns, m_aRelationMasterColumns );
640 return 0L;
643 //------------------------------------------------------------------------
644 IMPL_LINK( FormLinkDialog, OnFieldChanged, FieldLinkRow*, /*_pRow*/ )
646 updateOkButton();
647 return 0L;
650 //------------------------------------------------------------------------
651 IMPL_LINK( FormLinkDialog, OnInitialize, void*, /*_pNotInterestedIn*/ )
653 initializeColumnLabels();
654 initializeFieldLists();
655 initializeLinks();
656 initializeSuggest();
657 return 0L;
659 //............................................................................
660 } // namespace pcr
661 //............................................................................
663 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */