1*2a97ec55SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*2a97ec55SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*2a97ec55SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*2a97ec55SAndrew Rist  * distributed with this work for additional information
6*2a97ec55SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*2a97ec55SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*2a97ec55SAndrew Rist  * "License"); you may not use this file except in compliance
9*2a97ec55SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*2a97ec55SAndrew Rist  *
11*2a97ec55SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*2a97ec55SAndrew Rist  *
13*2a97ec55SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*2a97ec55SAndrew Rist  * software distributed under the License is distributed on an
15*2a97ec55SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2a97ec55SAndrew Rist  * KIND, either express or implied.  See the License for the
17*2a97ec55SAndrew Rist  * specific language governing permissions and limitations
18*2a97ec55SAndrew Rist  * under the License.
19*2a97ec55SAndrew Rist  *
20*2a97ec55SAndrew Rist  *************************************************************/
21*2a97ec55SAndrew Rist 
22*2a97ec55SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_extensions.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "formlinkdialog.hxx"
28cdf0e10cSrcweir #include "formlinkdialog.hrc"
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_
31cdf0e10cSrcweir #include "modulepcr.hxx"
32cdf0e10cSrcweir #endif
33cdf0e10cSrcweir #ifndef _EXTENSIONS_FORMCTRLR_PROPRESID_HRC_
34cdf0e10cSrcweir #include "formresid.hrc"
35cdf0e10cSrcweir #endif
36cdf0e10cSrcweir #include "formstrings.hxx"
37cdf0e10cSrcweir #include <vcl/combobox.hxx>
38cdf0e10cSrcweir #include <vcl/msgbox.hxx>
39cdf0e10cSrcweir #include <vcl/waitobj.hxx>
40cdf0e10cSrcweir #include <svtools/localresaccess.hxx>
41cdf0e10cSrcweir #include <connectivity/dbtools.hxx>
42cdf0e10cSrcweir #include <connectivity/dbexception.hxx>
43cdf0e10cSrcweir #include <toolkit/helper/vclunohelper.hxx>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir /** === begin UNO includes === **/
46cdf0e10cSrcweir #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
47cdf0e10cSrcweir #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
48cdf0e10cSrcweir #include <com/sun/star/sdbcx/KeyType.hpp>
49cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
50cdf0e10cSrcweir #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
51cdf0e10cSrcweir #include <com/sun/star/sdbc/XRowSet.hpp>
52cdf0e10cSrcweir #include <com/sun/star/sdb/CommandType.hpp>
53cdf0e10cSrcweir #include <com/sun/star/sdb/SQLContext.hpp>
54cdf0e10cSrcweir /** === end UNO includes === **/
55cdf0e10cSrcweir 
56cdf0e10cSrcweir 
57cdf0e10cSrcweir //............................................................................
58cdf0e10cSrcweir namespace pcr
59cdf0e10cSrcweir {
60cdf0e10cSrcweir //............................................................................
61cdf0e10cSrcweir 
62cdf0e10cSrcweir     using namespace ::com::sun::star::uno;
63cdf0e10cSrcweir     using namespace ::com::sun::star::lang;
64cdf0e10cSrcweir     using namespace ::com::sun::star::form;
65cdf0e10cSrcweir     using namespace ::com::sun::star::sdb;
66cdf0e10cSrcweir     using namespace ::com::sun::star::sdbc;
67cdf0e10cSrcweir     using namespace ::com::sun::star::sdbcx;
68cdf0e10cSrcweir     using namespace ::com::sun::star::beans;
69cdf0e10cSrcweir     using namespace ::com::sun::star::container;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir     //========================================================================
72cdf0e10cSrcweir     //= FieldLinkRow
73cdf0e10cSrcweir     //========================================================================
74cdf0e10cSrcweir     class FieldLinkRow : public Window
75cdf0e10cSrcweir     {
76cdf0e10cSrcweir     private:
77cdf0e10cSrcweir         ComboBox    m_aDetailColumn;
78cdf0e10cSrcweir         FixedText   m_aEqualSign;
79cdf0e10cSrcweir         ComboBox    m_aMasterColumn;
80cdf0e10cSrcweir 
81cdf0e10cSrcweir         Link        m_aLinkChangeHandler;
82cdf0e10cSrcweir 
83cdf0e10cSrcweir     public:
84cdf0e10cSrcweir         FieldLinkRow( Window* _pParent, const ResId& _rId );
85cdf0e10cSrcweir 
SetLinkChangeHandler(const Link & _rHdl)86cdf0e10cSrcweir         inline void         SetLinkChangeHandler( const Link& _rHdl ) { m_aLinkChangeHandler = _rHdl; }
GetLinkChangeHandler() const87cdf0e10cSrcweir         inline const Link&  GetLinkChangeHandler( ) const             { return m_aLinkChangeHandler;  }
88cdf0e10cSrcweir 
89cdf0e10cSrcweir         enum LinkParticipant
90cdf0e10cSrcweir         {
91cdf0e10cSrcweir             eDetailField,
92cdf0e10cSrcweir             eMasterField
93cdf0e10cSrcweir         };
94cdf0e10cSrcweir         /** retrieves the selected field name for either the master or the detail field
95cdf0e10cSrcweir             @return <TRUE/> if and only a valid field is selected
96cdf0e10cSrcweir         */
97cdf0e10cSrcweir         bool    GetFieldName( LinkParticipant _eWhich, String& /* [out] */ _rName ) const;
98cdf0e10cSrcweir         void    SetFieldName( LinkParticipant _eWhich, const String& _rName );
99cdf0e10cSrcweir 
100cdf0e10cSrcweir         void    fillList( LinkParticipant _eWhich, const Sequence< ::rtl::OUString >& _rFieldNames );
101cdf0e10cSrcweir 
102cdf0e10cSrcweir     private:
103cdf0e10cSrcweir         DECL_LINK( OnFieldNameChanged, ComboBox* );
104cdf0e10cSrcweir     };
105cdf0e10cSrcweir 
106cdf0e10cSrcweir     //------------------------------------------------------------------------
FieldLinkRow(Window * _pParent,const ResId & _rId)107cdf0e10cSrcweir     FieldLinkRow::FieldLinkRow( Window* _pParent, const ResId& _rId )
108cdf0e10cSrcweir         :Window( _pParent, _rId )
109cdf0e10cSrcweir         ,m_aDetailColumn( this, ResId( 1, *_rId.GetResMgr() ) )
110cdf0e10cSrcweir         ,m_aEqualSign   ( this, ResId( 1, *_rId.GetResMgr() ) )
111cdf0e10cSrcweir         ,m_aMasterColumn( this, ResId( 2, *_rId.GetResMgr() ) )
112cdf0e10cSrcweir     {
113cdf0e10cSrcweir         FreeResource();
114cdf0e10cSrcweir 
115cdf0e10cSrcweir         m_aDetailColumn.SetDropDownLineCount( 10 );
116cdf0e10cSrcweir         m_aMasterColumn.SetDropDownLineCount( 10 );
117cdf0e10cSrcweir 
118cdf0e10cSrcweir         m_aDetailColumn.SetModifyHdl( LINK( this, FieldLinkRow, OnFieldNameChanged ) );
119cdf0e10cSrcweir         m_aMasterColumn.SetModifyHdl( LINK( this, FieldLinkRow, OnFieldNameChanged ) );
120cdf0e10cSrcweir     }
121cdf0e10cSrcweir 
122cdf0e10cSrcweir     //------------------------------------------------------------------------
fillList(LinkParticipant _eWhich,const Sequence<::rtl::OUString> & _rFieldNames)123cdf0e10cSrcweir     void FieldLinkRow::fillList( LinkParticipant _eWhich, const Sequence< ::rtl::OUString >& _rFieldNames )
124cdf0e10cSrcweir     {
125cdf0e10cSrcweir         ComboBox* pBox = ( _eWhich == eDetailField ) ? &m_aDetailColumn : &m_aMasterColumn;
126cdf0e10cSrcweir 
127cdf0e10cSrcweir         const ::rtl::OUString* pFieldName    = _rFieldNames.getConstArray();
128cdf0e10cSrcweir         const ::rtl::OUString* pFieldNameEnd = pFieldName + _rFieldNames.getLength();
129cdf0e10cSrcweir         for ( ; pFieldName != pFieldNameEnd; ++pFieldName )
130cdf0e10cSrcweir             pBox->InsertEntry( *pFieldName );
131cdf0e10cSrcweir     }
132cdf0e10cSrcweir 
133cdf0e10cSrcweir     //------------------------------------------------------------------------
GetFieldName(LinkParticipant _eWhich,String & _rName) const134cdf0e10cSrcweir     bool FieldLinkRow::GetFieldName( LinkParticipant _eWhich, String& /* [out] */ _rName ) const
135cdf0e10cSrcweir     {
136cdf0e10cSrcweir         const ComboBox* pBox = ( _eWhich == eDetailField ) ? &m_aDetailColumn : &m_aMasterColumn;
137cdf0e10cSrcweir         _rName = pBox->GetText();
138cdf0e10cSrcweir         return _rName.Len() != 0;
139cdf0e10cSrcweir     }
140cdf0e10cSrcweir 
141cdf0e10cSrcweir     //------------------------------------------------------------------------
SetFieldName(LinkParticipant _eWhich,const String & _rName)142cdf0e10cSrcweir     void FieldLinkRow::SetFieldName( LinkParticipant _eWhich, const String& _rName )
143cdf0e10cSrcweir     {
144cdf0e10cSrcweir         ComboBox* pBox = ( _eWhich == eDetailField ) ? &m_aDetailColumn : &m_aMasterColumn;
145cdf0e10cSrcweir         pBox->SetText( _rName );
146cdf0e10cSrcweir     }
147cdf0e10cSrcweir 
148cdf0e10cSrcweir     //------------------------------------------------------------------------
149cdf0e10cSrcweir     IMPL_LINK( FieldLinkRow, OnFieldNameChanged, ComboBox*, /*_pBox*/ )
150cdf0e10cSrcweir     {
151cdf0e10cSrcweir         if ( m_aLinkChangeHandler.IsSet() )
152cdf0e10cSrcweir             return m_aLinkChangeHandler.Call( this );
153cdf0e10cSrcweir 
154cdf0e10cSrcweir         return 0L;
155cdf0e10cSrcweir     }
156cdf0e10cSrcweir 
157cdf0e10cSrcweir     //========================================================================
158cdf0e10cSrcweir     //= FormLinkDialog
159cdf0e10cSrcweir     //========================================================================
160cdf0e10cSrcweir     //------------------------------------------------------------------------
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)161cdf0e10cSrcweir     FormLinkDialog::FormLinkDialog( Window* _pParent, const Reference< XPropertySet >& _rxDetailForm,
162cdf0e10cSrcweir             const Reference< XPropertySet >& _rxMasterForm, const Reference< XMultiServiceFactory >& _rxORB,
163cdf0e10cSrcweir             const ::rtl::OUString& _sExplanation,
164cdf0e10cSrcweir             const ::rtl::OUString& _sDetailLabel,
165cdf0e10cSrcweir             const ::rtl::OUString& _sMasterLabel)
166cdf0e10cSrcweir         :ModalDialog( _pParent, PcrRes( RID_DLG_FORMLINKS ) )
167cdf0e10cSrcweir         ,m_aExplanation( this, PcrRes( FT_EXPLANATION  ) )
168cdf0e10cSrcweir         ,m_aDetailLabel( this, PcrRes( FT_DETAIL_LABEL ) )
169cdf0e10cSrcweir         ,m_aMasterLabel( this, PcrRes( FT_MASTER_LABEL ) )
170cdf0e10cSrcweir         ,m_aRow1       ( new FieldLinkRow( this, PcrRes( 1 ) ) )
171cdf0e10cSrcweir         ,m_aRow2       ( new FieldLinkRow( this, PcrRes( 2 ) ) )
172cdf0e10cSrcweir         ,m_aRow3       ( new FieldLinkRow( this, PcrRes( 3 ) ) )
173cdf0e10cSrcweir         ,m_aRow4       ( new FieldLinkRow( this, PcrRes( 4 ) ) )
174cdf0e10cSrcweir         ,m_aOK         ( this, PcrRes( PB_OK           ) )
175cdf0e10cSrcweir         ,m_aCancel     ( this, PcrRes( PB_CANCEL       ) )
176cdf0e10cSrcweir         ,m_aHelp       ( this, PcrRes( PB_HELP         ) )
177cdf0e10cSrcweir         ,m_aSuggest    ( this, PcrRes( PB_SUGGEST      ) )
178cdf0e10cSrcweir         ,m_xORB       ( _rxORB        )
179cdf0e10cSrcweir         ,m_xDetailForm( _rxDetailForm )
180cdf0e10cSrcweir         ,m_xMasterForm( _rxMasterForm )
181cdf0e10cSrcweir         ,m_sDetailLabel(_sDetailLabel)
182cdf0e10cSrcweir         ,m_sMasterLabel(_sMasterLabel)
183cdf0e10cSrcweir     {
184cdf0e10cSrcweir         FreeResource();
185cdf0e10cSrcweir         if ( _sExplanation.getLength() )
186cdf0e10cSrcweir             m_aExplanation.SetText(_sExplanation);
187cdf0e10cSrcweir 
188cdf0e10cSrcweir         m_aSuggest.SetClickHdl       ( LINK( this, FormLinkDialog, OnSuggest      ) );
189cdf0e10cSrcweir         m_aRow1->SetLinkChangeHandler( LINK( this, FormLinkDialog, OnFieldChanged ) );
190cdf0e10cSrcweir         m_aRow2->SetLinkChangeHandler( LINK( this, FormLinkDialog, OnFieldChanged ) );
191cdf0e10cSrcweir         m_aRow3->SetLinkChangeHandler( LINK( this, FormLinkDialog, OnFieldChanged ) );
192cdf0e10cSrcweir         m_aRow4->SetLinkChangeHandler( LINK( this, FormLinkDialog, OnFieldChanged ) );
193cdf0e10cSrcweir 
194cdf0e10cSrcweir         PostUserEvent( LINK( this, FormLinkDialog, OnInitialize ) );
195cdf0e10cSrcweir 
196cdf0e10cSrcweir         updateOkButton();
197cdf0e10cSrcweir     }
198cdf0e10cSrcweir 
199cdf0e10cSrcweir     //------------------------------------------------------------------------
~FormLinkDialog()200cdf0e10cSrcweir     FormLinkDialog::~FormLinkDialog( )
201cdf0e10cSrcweir     {
202cdf0e10cSrcweir     }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir     //------------------------------------------------------------------------
commitLinkPairs()205cdf0e10cSrcweir     void FormLinkDialog::commitLinkPairs()
206cdf0e10cSrcweir     {
207cdf0e10cSrcweir         // collect the field lists from the rows
208cdf0e10cSrcweir         ::std::vector< ::rtl::OUString > aDetailFields; aDetailFields.reserve( 4 );
209cdf0e10cSrcweir         ::std::vector< ::rtl::OUString > aMasterFields; aMasterFields.reserve( 4 );
210cdf0e10cSrcweir 
211cdf0e10cSrcweir         const FieldLinkRow* aRows[] = {
212cdf0e10cSrcweir             m_aRow1.get(), m_aRow2.get(), m_aRow3.get(), m_aRow4.get()
213cdf0e10cSrcweir         };
214cdf0e10cSrcweir 
215cdf0e10cSrcweir         for ( sal_Int32 i = 0; i < 4; ++i )
216cdf0e10cSrcweir         {
217cdf0e10cSrcweir             String sDetailField, sMasterField;
218cdf0e10cSrcweir             aRows[ i ]->GetFieldName( FieldLinkRow::eDetailField, sDetailField );
219cdf0e10cSrcweir             aRows[ i ]->GetFieldName( FieldLinkRow::eMasterField, sMasterField );
220cdf0e10cSrcweir             if ( !sDetailField.Len() && !sMasterField.Len() )
221cdf0e10cSrcweir                 continue;
222cdf0e10cSrcweir 
223cdf0e10cSrcweir             aDetailFields.push_back( sDetailField );
224cdf0e10cSrcweir             aMasterFields.push_back( sMasterField );
225cdf0e10cSrcweir         }
226cdf0e10cSrcweir 
227cdf0e10cSrcweir         // and set as property values
228cdf0e10cSrcweir         try
229cdf0e10cSrcweir         {
230cdf0e10cSrcweir             Reference< XPropertySet > xDetailFormProps( m_xDetailForm, UNO_QUERY );
231cdf0e10cSrcweir             if ( xDetailFormProps.is() )
232cdf0e10cSrcweir             {
233cdf0e10cSrcweir 	    	    ::rtl::OUString *pFields = aDetailFields.empty() ? 0 : &aDetailFields[0];
234cdf0e10cSrcweir                 xDetailFormProps->setPropertyValue( PROPERTY_DETAILFIELDS, makeAny( Sequence< ::rtl::OUString >( pFields, aDetailFields.size() ) ) );
235cdf0e10cSrcweir 	    	    pFields = aMasterFields.empty() ? 0 : &aMasterFields[0];
236cdf0e10cSrcweir                 xDetailFormProps->setPropertyValue( PROPERTY_MASTERFIELDS, makeAny( Sequence< ::rtl::OUString >( pFields, aMasterFields.size() ) ) );
237cdf0e10cSrcweir             }
238cdf0e10cSrcweir         }
239cdf0e10cSrcweir         catch( const Exception& )
240cdf0e10cSrcweir         {
241cdf0e10cSrcweir             OSL_ENSURE( sal_False, "FormLinkDialog::commitLinkPairs: caught an exception while setting the properties!" );
242cdf0e10cSrcweir         }
243cdf0e10cSrcweir     }
244cdf0e10cSrcweir 
245cdf0e10cSrcweir     //------------------------------------------------------------------------
Execute()246cdf0e10cSrcweir     short FormLinkDialog::Execute()
247cdf0e10cSrcweir     {
248cdf0e10cSrcweir         short nResult = ModalDialog::Execute();
249cdf0e10cSrcweir 
250cdf0e10cSrcweir         if ( RET_OK == nResult )
251cdf0e10cSrcweir             commitLinkPairs();
252cdf0e10cSrcweir 
253cdf0e10cSrcweir         return nResult;
254cdf0e10cSrcweir     }
255cdf0e10cSrcweir 
256cdf0e10cSrcweir     //------------------------------------------------------------------------
initializeFieldLists()257cdf0e10cSrcweir     void FormLinkDialog::initializeFieldLists()
258cdf0e10cSrcweir     {
259cdf0e10cSrcweir         Sequence< ::rtl::OUString > sDetailFields;
260cdf0e10cSrcweir         getFormFields( m_xDetailForm, sDetailFields );
261cdf0e10cSrcweir 
262cdf0e10cSrcweir         Sequence< ::rtl::OUString > sMasterFields;
263cdf0e10cSrcweir         getFormFields( m_xMasterForm, sMasterFields );
264cdf0e10cSrcweir 
265cdf0e10cSrcweir         FieldLinkRow* aRows[] = {
266cdf0e10cSrcweir             m_aRow1.get(), m_aRow2.get(), m_aRow3.get(), m_aRow4.get()
267cdf0e10cSrcweir         };
268cdf0e10cSrcweir         for ( sal_Int32 i = 0; i < 4 ; ++i )
269cdf0e10cSrcweir         {
270cdf0e10cSrcweir             aRows[i]->fillList( FieldLinkRow::eDetailField, sDetailFields );
271cdf0e10cSrcweir             aRows[i]->fillList( FieldLinkRow::eMasterField, sMasterFields );
272cdf0e10cSrcweir         }
273cdf0e10cSrcweir 
274cdf0e10cSrcweir     }
275cdf0e10cSrcweir 
276cdf0e10cSrcweir     //------------------------------------------------------------------------
initializeColumnLabels()277cdf0e10cSrcweir     void FormLinkDialog::initializeColumnLabels()
278cdf0e10cSrcweir     {
279cdf0e10cSrcweir         // label for the detail form
280cdf0e10cSrcweir         String sDetailType = getFormDataSourceType( m_xDetailForm );
281cdf0e10cSrcweir         if ( !sDetailType.Len() )
282cdf0e10cSrcweir         {
283cdf0e10cSrcweir             if ( !m_sDetailLabel.getLength() )
284cdf0e10cSrcweir             {
285cdf0e10cSrcweir                 ::svt::OLocalResourceAccess aStringAccess( PcrRes( RID_DLG_FORMLINKS ), RSC_MODALDIALOG );
286cdf0e10cSrcweir                 m_sDetailLabel = String( PcrRes( STR_DETAIL_FORM ) );
287cdf0e10cSrcweir             }
288cdf0e10cSrcweir             sDetailType = m_sDetailLabel;
289cdf0e10cSrcweir         }
290cdf0e10cSrcweir         m_aDetailLabel.SetText( sDetailType );
291cdf0e10cSrcweir 
292cdf0e10cSrcweir         // label for the master form
293cdf0e10cSrcweir         String sMasterType = getFormDataSourceType( m_xMasterForm );
294cdf0e10cSrcweir         if ( !sMasterType.Len() )
295cdf0e10cSrcweir         {
296cdf0e10cSrcweir             if ( !m_sMasterLabel.getLength() )
297cdf0e10cSrcweir             {
298cdf0e10cSrcweir                 ::svt::OLocalResourceAccess aStringAccess( PcrRes( RID_DLG_FORMLINKS ), RSC_MODALDIALOG );
299cdf0e10cSrcweir                 m_sMasterLabel = String( PcrRes( STR_MASTER_FORM ) );
300cdf0e10cSrcweir             }
301cdf0e10cSrcweir             sMasterType = m_sMasterLabel;
302cdf0e10cSrcweir         }
303cdf0e10cSrcweir         m_aMasterLabel.SetText( sMasterType );
304cdf0e10cSrcweir     }
305cdf0e10cSrcweir 
306cdf0e10cSrcweir     //------------------------------------------------------------------------
initializeFieldRowsFrom(Sequence<::rtl::OUString> & _rDetailFields,Sequence<::rtl::OUString> & _rMasterFields)307cdf0e10cSrcweir     void FormLinkDialog::initializeFieldRowsFrom( Sequence< ::rtl::OUString >& _rDetailFields, Sequence< ::rtl::OUString >& _rMasterFields )
308cdf0e10cSrcweir     {
309cdf0e10cSrcweir         // our UI does allow 4 fields max
310cdf0e10cSrcweir         _rDetailFields.realloc( 4 );
311cdf0e10cSrcweir         _rMasterFields.realloc( 4 );
312cdf0e10cSrcweir 
313cdf0e10cSrcweir         const ::rtl::OUString* pDetailFields = _rDetailFields.getConstArray();
314cdf0e10cSrcweir         const ::rtl::OUString* pMasterFields = _rMasterFields.getConstArray();
315cdf0e10cSrcweir 
316cdf0e10cSrcweir         FieldLinkRow* aRows[] = {
317cdf0e10cSrcweir             m_aRow1.get(), m_aRow2.get(), m_aRow3.get(), m_aRow4.get()
318cdf0e10cSrcweir         };
319cdf0e10cSrcweir         for ( sal_Int32 i = 0; i < 4; ++i, ++pDetailFields, ++pMasterFields )
320cdf0e10cSrcweir         {
321cdf0e10cSrcweir             aRows[ i ]->SetFieldName( FieldLinkRow::eDetailField, *pDetailFields );
322cdf0e10cSrcweir             aRows[ i ]->SetFieldName( FieldLinkRow::eMasterField, *pMasterFields );
323cdf0e10cSrcweir         }
324cdf0e10cSrcweir     }
325cdf0e10cSrcweir 
326cdf0e10cSrcweir     //------------------------------------------------------------------------
initializeLinks()327cdf0e10cSrcweir     void FormLinkDialog::initializeLinks()
328cdf0e10cSrcweir     {
329cdf0e10cSrcweir         try
330cdf0e10cSrcweir         {
331cdf0e10cSrcweir             Sequence< ::rtl::OUString > aDetailFields;
332cdf0e10cSrcweir             Sequence< ::rtl::OUString > aMasterFields;
333cdf0e10cSrcweir 
334cdf0e10cSrcweir             Reference< XPropertySet > xDetailFormProps( m_xDetailForm, UNO_QUERY );
335cdf0e10cSrcweir             if ( xDetailFormProps.is() )
336cdf0e10cSrcweir             {
337cdf0e10cSrcweir                 xDetailFormProps->getPropertyValue( PROPERTY_DETAILFIELDS ) >>= aDetailFields;
338cdf0e10cSrcweir                 xDetailFormProps->getPropertyValue( PROPERTY_MASTERFIELDS ) >>= aMasterFields;
339cdf0e10cSrcweir             }
340cdf0e10cSrcweir 
341cdf0e10cSrcweir             initializeFieldRowsFrom( aDetailFields, aMasterFields );
342cdf0e10cSrcweir         }
343cdf0e10cSrcweir         catch( const Exception& )
344cdf0e10cSrcweir         {
345cdf0e10cSrcweir             OSL_ENSURE( sal_False, "FormLinkDialog::initializeLinks: caught an exception!" );
346cdf0e10cSrcweir         }
347cdf0e10cSrcweir     }
348cdf0e10cSrcweir 
349cdf0e10cSrcweir     //------------------------------------------------------------------------
updateOkButton()350cdf0e10cSrcweir     void FormLinkDialog::updateOkButton()
351cdf0e10cSrcweir     {
352cdf0e10cSrcweir         // in all rows, there must be either two valid selections, or none at all
353cdf0e10cSrcweir         // If there is at least one row with exactly one valid selection, then the
354cdf0e10cSrcweir         // OKButton needs to be disabled
355cdf0e10cSrcweir         sal_Bool bEnable = sal_True;
356cdf0e10cSrcweir 
357cdf0e10cSrcweir         const FieldLinkRow* aRows[] = {
358cdf0e10cSrcweir             m_aRow1.get(), m_aRow2.get(), m_aRow3.get(), m_aRow4.get()
359cdf0e10cSrcweir         };
360cdf0e10cSrcweir 
361cdf0e10cSrcweir         for ( sal_Int32 i = 0; ( i < 4 ) && bEnable; ++i )
362cdf0e10cSrcweir         {
363cdf0e10cSrcweir             String sNotInterestedInRightNow;
364cdf0e10cSrcweir             if  (  aRows[ i ]->GetFieldName( FieldLinkRow::eDetailField, sNotInterestedInRightNow )
365cdf0e10cSrcweir                 != aRows[ i ]->GetFieldName( FieldLinkRow::eMasterField, sNotInterestedInRightNow )
366cdf0e10cSrcweir                 )
367cdf0e10cSrcweir                 bEnable = sal_False;
368cdf0e10cSrcweir         }
369cdf0e10cSrcweir 
370cdf0e10cSrcweir         m_aOK.Enable( bEnable );
371cdf0e10cSrcweir     }
372cdf0e10cSrcweir 
373cdf0e10cSrcweir     //------------------------------------------------------------------------
getFormDataSourceType(const Reference<XPropertySet> & _rxForm) const374cdf0e10cSrcweir     String FormLinkDialog::getFormDataSourceType( const Reference< XPropertySet >& _rxForm ) const SAL_THROW(())
375cdf0e10cSrcweir     {
376cdf0e10cSrcweir         String sReturn;
377cdf0e10cSrcweir         Reference< XPropertySet > xFormProps( _rxForm, UNO_QUERY );
378cdf0e10cSrcweir         if ( !xFormProps.is() )
379cdf0e10cSrcweir             return sReturn;
380cdf0e10cSrcweir 
381cdf0e10cSrcweir         try
382cdf0e10cSrcweir         {
383cdf0e10cSrcweir             sal_Int32       nCommandType = CommandType::COMMAND;
384cdf0e10cSrcweir             ::rtl::OUString sCommand;
385cdf0e10cSrcweir 
386cdf0e10cSrcweir             xFormProps->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nCommandType;
387cdf0e10cSrcweir             xFormProps->getPropertyValue( PROPERTY_COMMAND     ) >>= sCommand;
388cdf0e10cSrcweir 
389cdf0e10cSrcweir             if  (  ( nCommandType == CommandType::TABLE )
390cdf0e10cSrcweir                 || ( nCommandType == CommandType::QUERY )
391cdf0e10cSrcweir                 )
392cdf0e10cSrcweir                 sReturn = sCommand;
393cdf0e10cSrcweir         }
394cdf0e10cSrcweir         catch( const Exception& )
395cdf0e10cSrcweir         {
396cdf0e10cSrcweir             OSL_ENSURE( sal_False, "FormLinkDialog::getFormDataSourceType: caught an exception!" );
397cdf0e10cSrcweir         }
398cdf0e10cSrcweir         return sReturn;
399cdf0e10cSrcweir     }
400cdf0e10cSrcweir 
401cdf0e10cSrcweir     //------------------------------------------------------------------------
getFormFields(const Reference<XPropertySet> & _rxForm,Sequence<::rtl::OUString> & _rNames) const402cdf0e10cSrcweir     void FormLinkDialog::getFormFields( const Reference< XPropertySet >& _rxForm, Sequence< ::rtl::OUString >& /* [out] */ _rNames ) const SAL_THROW(( ))
403cdf0e10cSrcweir     {
404cdf0e10cSrcweir         _rNames.realloc( 0 );
405cdf0e10cSrcweir 
406cdf0e10cSrcweir         ::dbtools::SQLExceptionInfo aErrorInfo;
407cdf0e10cSrcweir         ::rtl::OUString sCommand;
408cdf0e10cSrcweir         try
409cdf0e10cSrcweir         {
410cdf0e10cSrcweir             WaitObject aWaitCursor( const_cast< FormLinkDialog* >( this ) );
411cdf0e10cSrcweir 
412cdf0e10cSrcweir             Reference< XPropertySet > xFormProps( _rxForm, UNO_QUERY );
413cdf0e10cSrcweir             OSL_ENSURE( xFormProps.is(), "FormLinkDialog::getFormFields: invalid form!" );
414cdf0e10cSrcweir 
415cdf0e10cSrcweir             sal_Int32       nCommandType = CommandType::COMMAND;
416cdf0e10cSrcweir 
417cdf0e10cSrcweir             xFormProps->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nCommandType;
418cdf0e10cSrcweir             xFormProps->getPropertyValue( PROPERTY_COMMAND     ) >>= sCommand;
419cdf0e10cSrcweir 
420cdf0e10cSrcweir             Reference< XConnection > xConnection;
421cdf0e10cSrcweir             ensureFormConnection( xFormProps, xConnection );
422cdf0e10cSrcweir 
423cdf0e10cSrcweir             _rNames = ::dbtools::getFieldNamesByCommandDescriptor(
424cdf0e10cSrcweir                 xConnection,
425cdf0e10cSrcweir                 nCommandType,
426cdf0e10cSrcweir                 sCommand,
427cdf0e10cSrcweir                 &aErrorInfo
428cdf0e10cSrcweir             );
429cdf0e10cSrcweir         }
430cdf0e10cSrcweir 		catch (const SQLContext& e)    { aErrorInfo = e; }
431cdf0e10cSrcweir 		catch (const SQLWarning& e)    { aErrorInfo = e; }
432cdf0e10cSrcweir 		catch (const SQLException& e ) { aErrorInfo = e; }
433cdf0e10cSrcweir         catch( const Exception& )
434cdf0e10cSrcweir         {
435cdf0e10cSrcweir             OSL_ENSURE( sal_False, "FormLinkDialog::getFormFields: caught a non-SQL exception!" );
436cdf0e10cSrcweir         }
437cdf0e10cSrcweir 
438cdf0e10cSrcweir         if ( aErrorInfo.isValid() )
439cdf0e10cSrcweir         {
440cdf0e10cSrcweir             String sErrorMessage;
441cdf0e10cSrcweir             {
442cdf0e10cSrcweir                 ::svt::OLocalResourceAccess aStringAccess( PcrRes( RID_DLG_FORMLINKS ), RSC_MODALDIALOG );
443cdf0e10cSrcweir                 sErrorMessage = String( PcrRes( STR_ERROR_RETRIEVING_COLUMNS) );
444cdf0e10cSrcweir                 sErrorMessage.SearchAndReplace('#',sCommand);
445cdf0e10cSrcweir             }
446cdf0e10cSrcweir 
447cdf0e10cSrcweir             SQLContext aContext;
448cdf0e10cSrcweir             aContext.Message = sErrorMessage;
449cdf0e10cSrcweir 			aContext.NextException = aErrorInfo.get();
450cdf0e10cSrcweir             ::dbtools::showError( aContext, VCLUnoHelper::GetInterface( const_cast< FormLinkDialog* >( this ) ), m_xORB );
451cdf0e10cSrcweir         }
452cdf0e10cSrcweir     }
453cdf0e10cSrcweir 
454cdf0e10cSrcweir     //------------------------------------------------------------------------
ensureFormConnection(const Reference<XPropertySet> & _rxFormProps,Reference<XConnection> & _rxConnection) const455cdf0e10cSrcweir     void FormLinkDialog::ensureFormConnection( const Reference< XPropertySet >& _rxFormProps, Reference< XConnection >& /* [out] */ _rxConnection ) const SAL_THROW(( Exception ))
456cdf0e10cSrcweir     {
457cdf0e10cSrcweir         OSL_PRECOND( _rxFormProps.is(), "FormLinkDialog::ensureFormConnection: invalid form!" );
458cdf0e10cSrcweir         if ( !_rxFormProps.is() )
459cdf0e10cSrcweir             return;
460cdf0e10cSrcweir         if ( _rxFormProps->getPropertySetInfo()->hasPropertyByName(PROPERTY_ACTIVE_CONNECTION) )
461cdf0e10cSrcweir             _rxConnection.set(_rxFormProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY);
462cdf0e10cSrcweir 
463cdf0e10cSrcweir         if ( !_rxConnection.is() )
464cdf0e10cSrcweir             _rxConnection = ::dbtools::connectRowset( Reference< XRowSet >( _rxFormProps, UNO_QUERY ), m_xORB, sal_True );
465cdf0e10cSrcweir     }
466cdf0e10cSrcweir 
467cdf0e10cSrcweir     //------------------------------------------------------------------------
getConnectionMetaData(const Reference<XPropertySet> & _rxFormProps,Reference<XDatabaseMetaData> & _rxMeta) const468cdf0e10cSrcweir     void FormLinkDialog::getConnectionMetaData( const Reference< XPropertySet >& _rxFormProps, Reference< XDatabaseMetaData >& /* [out] */ _rxMeta ) const SAL_THROW(( Exception ))
469cdf0e10cSrcweir     {
470cdf0e10cSrcweir         if ( _rxFormProps.is() )
471cdf0e10cSrcweir         {
472cdf0e10cSrcweir             Reference< XConnection > xConnection;
473cdf0e10cSrcweir             if ( !::dbtools::isEmbeddedInDatabase( _rxFormProps, xConnection ) )
474cdf0e10cSrcweir                 _rxFormProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConnection;
475cdf0e10cSrcweir             if ( xConnection.is() )
476cdf0e10cSrcweir                 _rxMeta = xConnection->getMetaData();
477cdf0e10cSrcweir         }
478cdf0e10cSrcweir     }
479cdf0e10cSrcweir 
480cdf0e10cSrcweir     //------------------------------------------------------------------------
getCanonicUnderlyingTable(const Reference<XPropertySet> & _rxFormProps) const481cdf0e10cSrcweir     Reference< XPropertySet > FormLinkDialog::getCanonicUnderlyingTable( const Reference< XPropertySet >& _rxFormProps ) const
482cdf0e10cSrcweir     {
483cdf0e10cSrcweir         Reference< XPropertySet > xTable;
484cdf0e10cSrcweir         try
485cdf0e10cSrcweir         {
486cdf0e10cSrcweir             Reference< XTablesSupplier > xTablesInForm( ::dbtools::getCurrentSettingsComposer( _rxFormProps, m_xORB ), UNO_QUERY );
487cdf0e10cSrcweir             Reference< XNameAccess > xTables;
488cdf0e10cSrcweir             if ( xTablesInForm.is() )
489cdf0e10cSrcweir                 xTables = xTablesInForm->getTables();
490cdf0e10cSrcweir             Sequence< ::rtl::OUString > aTableNames;
491cdf0e10cSrcweir             if ( xTables.is() )
492cdf0e10cSrcweir                 aTableNames = xTables->getElementNames();
493cdf0e10cSrcweir 
494cdf0e10cSrcweir             if ( aTableNames.getLength() == 1 )
495cdf0e10cSrcweir             {
496cdf0e10cSrcweir                 xTables->getByName( aTableNames[ 0 ] ) >>= xTable;
497cdf0e10cSrcweir                 OSL_ENSURE( xTable.is(), "FormLinkDialog::getCanonicUnderlyingTable: invalid table!" );
498cdf0e10cSrcweir             }
499cdf0e10cSrcweir         }
500cdf0e10cSrcweir         catch( const Exception& )
501cdf0e10cSrcweir         {
502cdf0e10cSrcweir         	OSL_ENSURE( sal_False, "FormLinkDialog::getCanonicUnderlyingTable: caught an exception!" );
503cdf0e10cSrcweir         }
504cdf0e10cSrcweir         return xTable;
505cdf0e10cSrcweir     }
506cdf0e10cSrcweir 
507cdf0e10cSrcweir     //------------------------------------------------------------------------
getExistingRelation(const Reference<XPropertySet> & _rxLHS,const Reference<XPropertySet> &,Sequence<::rtl::OUString> & _rLeftFields,Sequence<::rtl::OUString> & _rRightFields) const508cdf0e10cSrcweir     sal_Bool FormLinkDialog::getExistingRelation( const Reference< XPropertySet >& _rxLHS, const Reference< XPropertySet >& /*_rxRHS*/,
509cdf0e10cSrcweir             // TODO: fix the usage of _rxRHS. This is issue #i81956#.
510cdf0e10cSrcweir         Sequence< ::rtl::OUString >& _rLeftFields, Sequence< ::rtl::OUString >& _rRightFields ) const
511cdf0e10cSrcweir     {
512cdf0e10cSrcweir         try
513cdf0e10cSrcweir         {
514cdf0e10cSrcweir             Reference< XKeysSupplier > xSuppKeys( _rxLHS, UNO_QUERY );
515cdf0e10cSrcweir             Reference< XIndexAccess >  xKeys;
516cdf0e10cSrcweir             if ( xSuppKeys.is() )
517cdf0e10cSrcweir                 xKeys = xSuppKeys->getKeys();
518cdf0e10cSrcweir 
519cdf0e10cSrcweir             if ( xKeys.is() )
520cdf0e10cSrcweir             {
521cdf0e10cSrcweir                 Reference< XPropertySet >     xKey;
522cdf0e10cSrcweir                 Reference< XColumnsSupplier > xKeyColSupp( xKey, UNO_QUERY );
523cdf0e10cSrcweir                 Reference< XIndexAccess >     xKeyColumns;
524cdf0e10cSrcweir                 Reference< XPropertySet >     xKeyColumn;
525cdf0e10cSrcweir                 ::rtl::OUString sColumnName, sRelatedColumnName;
526cdf0e10cSrcweir 
527cdf0e10cSrcweir                 const sal_Int32 keyCount = xKeys->getCount();
528cdf0e10cSrcweir                 for ( sal_Int32 key = 0; key < keyCount; ++key )
529cdf0e10cSrcweir                 {
530cdf0e10cSrcweir                     xKeys->getByIndex( key ) >>= xKey;
531cdf0e10cSrcweir                     sal_Int32 nKeyType = 0;
532cdf0e10cSrcweir                     xKey->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= nKeyType;
533cdf0e10cSrcweir                     if ( nKeyType != KeyType::FOREIGN )
534cdf0e10cSrcweir                         continue;
535cdf0e10cSrcweir 
536cdf0e10cSrcweir                     xKeyColumns.clear();
537cdf0e10cSrcweir                     xKeyColSupp = xKeyColSupp.query( xKey );
538cdf0e10cSrcweir                     if ( xKeyColSupp.is() )
539cdf0e10cSrcweir                         xKeyColumns = xKeyColumns.query( xKeyColSupp->getColumns() );
540cdf0e10cSrcweir                     OSL_ENSURE( xKeyColumns.is(), "FormLinkDialog::getExistingRelation: could not obtain the columns for the key!" );
541cdf0e10cSrcweir 
542cdf0e10cSrcweir                     if ( !xKeyColumns.is() )
543cdf0e10cSrcweir                         continue;
544cdf0e10cSrcweir 
545cdf0e10cSrcweir                     const sal_Int32 columnCount = xKeyColumns->getCount();
546cdf0e10cSrcweir                     _rLeftFields.realloc( columnCount );
547cdf0e10cSrcweir                     _rRightFields.realloc( columnCount );
548cdf0e10cSrcweir                     for ( sal_Int32 column = 0; column < columnCount; ++column )
549cdf0e10cSrcweir                     {
550cdf0e10cSrcweir                         xKeyColumn.clear();
551cdf0e10cSrcweir                         xKeyColumns->getByIndex( column ) >>= xKeyColumn;
552cdf0e10cSrcweir                         OSL_ENSURE( xKeyColumn.is(), "FormLinkDialog::getExistingRelation: invalid key column!" );
553cdf0e10cSrcweir                         if ( xKeyColumn.is() )
554cdf0e10cSrcweir                         {
555cdf0e10cSrcweir                             xKeyColumn->getPropertyValue( PROPERTY_NAME ) >>= sColumnName;
556cdf0e10cSrcweir                             xKeyColumn->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RelatedColumn" ) ) ) >>= sRelatedColumnName;
557cdf0e10cSrcweir 
558cdf0e10cSrcweir                             _rLeftFields[ column ]  = sColumnName;
559cdf0e10cSrcweir                             _rRightFields[ column ] = sRelatedColumnName;
560cdf0e10cSrcweir                         }
561cdf0e10cSrcweir                     }
562cdf0e10cSrcweir                 }
563cdf0e10cSrcweir             }
564cdf0e10cSrcweir         }
565cdf0e10cSrcweir         catch( const Exception& )
566cdf0e10cSrcweir         {
567cdf0e10cSrcweir         	OSL_ENSURE( sal_False, "FormLinkDialog::getExistingRelation: caught an exception!" );
568cdf0e10cSrcweir         }
569cdf0e10cSrcweir 
570cdf0e10cSrcweir         return ( _rLeftFields.getLength() > 0 ) && ( _rLeftFields[ 0 ].getLength() > 0 );
571cdf0e10cSrcweir     }
572cdf0e10cSrcweir 
573cdf0e10cSrcweir     //------------------------------------------------------------------------
initializeSuggest()574cdf0e10cSrcweir     void FormLinkDialog::initializeSuggest()
575cdf0e10cSrcweir     {
576cdf0e10cSrcweir         Reference< XPropertySet > xDetailFormProps( m_xDetailForm, UNO_QUERY );
577cdf0e10cSrcweir         Reference< XPropertySet > xMasterFormProps( m_xMasterForm, UNO_QUERY );
578cdf0e10cSrcweir         if ( !xDetailFormProps.is() || !xMasterFormProps.is() )
579cdf0e10cSrcweir             return;
580cdf0e10cSrcweir 
581cdf0e10cSrcweir         try
582cdf0e10cSrcweir         {
583cdf0e10cSrcweir             sal_Bool bEnable = sal_True;
584cdf0e10cSrcweir 
585cdf0e10cSrcweir             // only show the button when both forms are based on the same data source
586cdf0e10cSrcweir             if ( bEnable )
587cdf0e10cSrcweir             {
588cdf0e10cSrcweir                 ::rtl::OUString sMasterDS, sDetailDS;
589cdf0e10cSrcweir                 xMasterFormProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sMasterDS;
590cdf0e10cSrcweir                 xDetailFormProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sDetailDS;
591cdf0e10cSrcweir                 bEnable = ( sMasterDS == sDetailDS );
592cdf0e10cSrcweir             }
593cdf0e10cSrcweir 
594cdf0e10cSrcweir             // only show the button when the connection supports relations
595cdf0e10cSrcweir             if ( bEnable )
596cdf0e10cSrcweir             {
597cdf0e10cSrcweir                 Reference< XDatabaseMetaData > xMeta;
598cdf0e10cSrcweir                 getConnectionMetaData( xDetailFormProps, xMeta );
599cdf0e10cSrcweir                 OSL_ENSURE( xMeta.is(), "FormLinkDialog::initializeSuggest: unable to retrieve the meta data for the connection!" );
600cdf0e10cSrcweir                 try
601cdf0e10cSrcweir                 {
602cdf0e10cSrcweir                     bEnable = xMeta.is() && xMeta->supportsIntegrityEnhancementFacility();
603cdf0e10cSrcweir                 }
604cdf0e10cSrcweir                 catch(const Exception&)
605cdf0e10cSrcweir                 {
606cdf0e10cSrcweir                     bEnable = sal_False;
607cdf0e10cSrcweir                 }
608cdf0e10cSrcweir             }
609cdf0e10cSrcweir 
610cdf0e10cSrcweir             // only enable the button if there is a "canonic" table underlying both forms
611cdf0e10cSrcweir             Reference< XPropertySet > xDetailTable, xMasterTable;
612cdf0e10cSrcweir             if ( bEnable )
613cdf0e10cSrcweir             {
614cdf0e10cSrcweir                 xDetailTable = getCanonicUnderlyingTable( xDetailFormProps );
615cdf0e10cSrcweir                 xMasterTable = getCanonicUnderlyingTable( xMasterFormProps );
616cdf0e10cSrcweir                 bEnable = xDetailTable.is() && xMasterTable.is();
617cdf0e10cSrcweir             }
618cdf0e10cSrcweir 
619cdf0e10cSrcweir             // only enable the button if there is a relation between both tables
620cdf0e10cSrcweir             m_aRelationDetailColumns.realloc( 0 );
621cdf0e10cSrcweir             m_aRelationMasterColumns.realloc( 0 );
622cdf0e10cSrcweir             if ( bEnable )
623cdf0e10cSrcweir             {
624cdf0e10cSrcweir                 bEnable = getExistingRelation( xDetailTable, xMasterTable, m_aRelationDetailColumns, m_aRelationMasterColumns );
625cdf0e10cSrcweir                 OSL_POSTCOND( m_aRelationMasterColumns.getLength() == m_aRelationDetailColumns.getLength(), "FormLinkDialog::initializeSuggest: nonsense!" );
626cdf0e10cSrcweir                 if ( m_aRelationMasterColumns.getLength() == 0 )
627cdf0e10cSrcweir                 {   // okay, there is no relation "pointing" (via a foreign key) from the detail table to the master table
628cdf0e10cSrcweir                     // but perhaps the other way round (would make less sense, but who knows ...)
629cdf0e10cSrcweir                     bEnable = getExistingRelation( xMasterTable, xDetailTable, m_aRelationMasterColumns, m_aRelationDetailColumns );
630cdf0e10cSrcweir                 }
631cdf0e10cSrcweir             }
632cdf0e10cSrcweir 
633cdf0e10cSrcweir             // only enable the button if the relation contains at most 4 field pairs
634cdf0e10cSrcweir             if ( bEnable )
635cdf0e10cSrcweir             {
636cdf0e10cSrcweir                 bEnable = ( m_aRelationMasterColumns.getLength() <= 4 );
637cdf0e10cSrcweir             }
638cdf0e10cSrcweir 
639cdf0e10cSrcweir             m_aSuggest.Enable( bEnable );
640cdf0e10cSrcweir         }
641cdf0e10cSrcweir         catch( const Exception& )
642cdf0e10cSrcweir         {
643cdf0e10cSrcweir         	OSL_ENSURE( sal_False, "FormLinkDialog::initializeSuggest: caught an exception!" );
644cdf0e10cSrcweir         }
645cdf0e10cSrcweir     }
646cdf0e10cSrcweir 
647cdf0e10cSrcweir     //------------------------------------------------------------------------
648cdf0e10cSrcweir     IMPL_LINK( FormLinkDialog, OnSuggest, void*, /*_pNotInterestedIn*/ )
649cdf0e10cSrcweir     {
650cdf0e10cSrcweir         initializeFieldRowsFrom( m_aRelationDetailColumns, m_aRelationMasterColumns );
651cdf0e10cSrcweir         return 0L;
652cdf0e10cSrcweir     }
653cdf0e10cSrcweir 
654cdf0e10cSrcweir     //------------------------------------------------------------------------
655cdf0e10cSrcweir     IMPL_LINK( FormLinkDialog, OnFieldChanged, FieldLinkRow*, /*_pRow*/ )
656cdf0e10cSrcweir     {
657cdf0e10cSrcweir         updateOkButton();
658cdf0e10cSrcweir         return 0L;
659cdf0e10cSrcweir     }
660cdf0e10cSrcweir 
661cdf0e10cSrcweir     //------------------------------------------------------------------------
662cdf0e10cSrcweir     IMPL_LINK( FormLinkDialog, OnInitialize, void*, /*_pNotInterestedIn*/ )
663cdf0e10cSrcweir     {
664cdf0e10cSrcweir         initializeColumnLabels();
665cdf0e10cSrcweir         initializeFieldLists();
666cdf0e10cSrcweir         initializeLinks();
667cdf0e10cSrcweir         initializeSuggest();
668cdf0e10cSrcweir         return 0L;
669cdf0e10cSrcweir     }
670cdf0e10cSrcweir //............................................................................
671cdf0e10cSrcweir }   // namespace pcr
672cdf0e10cSrcweir //............................................................................
673