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